[U-Boot] [PATCH v2 00/19] dm: exynos: Driver model improvements leading to spring support

This series adds a number of fixes and improvements to driver model as well as two new uclasses (video bridges and I2c muxes).
The series is aimed at adding support for spring (HP 11 Chromebook). Since it is very similar to other ARM Chromebooks, some effory is made to use common code rather than duplicating functionality. In fact spring uses the same code as several other boards, just with a different device tree and a few configuration changes.
Audio works correctly on pit, pi, spring and snow with this series. A bug in the I2C driver broken this recently.
The exynos implementation still has a few rough areas - e.g. some hard-coded GPIOs and the old-style SPL. Also it does not yet support CPU frequency scaling and power management.
Spring has some oddities and they are hard to handle with U-Boot's old way of doing drivers. With driver model these can be implemented cleanly and this sort of problem was the original motivation for my interest in driver model.
This series is available at u-boot-dm in branch spring-working. It is based on the previous set of driver model changes in branch clk-working.
Changes in v2: - Add a README explaining the algorithm and update the commit message - Add a comment about DVS in the driver - Add a new patch to hold off the need for driver model pinctrl - Add new patch to correct LDO and BUCK naming - Rebase to dm/master - Update commit message and header file to better explain select()/deselect()
Simon Glass (19): exynos: dts: Correct LDO and BUCK naming video: Work around lack of pinctrl dm: i2c: Add support for multiplexed I2C buses i2c: Add a mux for GPIO-based I2C bus arbitration dm: cros_ec: Convert the I2C tunnel code to use driver model cros_ec: Support the LDO access method used by spring dm: pmic: max77686: Support all BUCK regulators exynos: dts: Drop the old TPS65090 I2C node exynos: Add common board code for exynos5 boards that use device tree exynos: Enable new features for exynos5 boards exynos: config: Move common options to the common headers and tidy up exynos: Drop old exynos5420-specific board code exynos: Drop old exynos5250-specific board code power: Remove old TPS65090 drivers cros_ec: Remove the old tunnel code video: Remove the old parade driver dts: Drop unused compatible ID for the NXP video bridge exynos: video: Remove non-device-tree code exynos: Add support for spring
arch/arm/cpu/armv7/exynos/Kconfig | 6 + arch/arm/dts/Makefile | 1 + arch/arm/dts/exynos4412-odroid.dts | 56 +-- arch/arm/dts/exynos4412-trats2.dts | 70 ++-- arch/arm/dts/exynos5250-snow.dts | 16 - arch/arm/dts/exynos5250-spring.dts | 588 +++++++++++++++++++++++++++++ arch/arm/include/asm/arch-exynos/dp_info.h | 2 - board/samsung/common/Makefile | 1 + board/samsung/common/exynos5-dt.c | 362 ++++++++++++++++++ board/samsung/smdk5250/Kconfig | 13 + board/samsung/smdk5250/MAINTAINERS | 6 + board/samsung/smdk5250/Makefile | 4 - board/samsung/smdk5250/exynos5-dt.c | 306 --------------- board/samsung/smdk5420/Makefile | 4 - board/samsung/smdk5420/smdk5420.c | 143 ------- configs/arndale_defconfig | 2 + configs/odroid-xu3_defconfig | 6 + configs/peach-pi_defconfig | 19 + configs/peach-pit_defconfig | 19 + configs/smdk5250_defconfig | 10 + configs/smdk5420_defconfig | 6 + configs/snow_defconfig | 23 ++ configs/spring_defconfig | 42 +++ doc/README.i2c | 60 +++ doc/device-tree-bindings/i2c/i2c-mux.txt | 60 +++ drivers/i2c/Kconfig | 26 ++ drivers/i2c/Makefile | 4 + drivers/i2c/cros_ec_ldo.c | 77 ++++ drivers/i2c/cros_ec_tunnel.c | 41 ++ drivers/i2c/muxes/Kconfig | 17 + drivers/i2c/muxes/Makefile | 7 + drivers/i2c/muxes/i2c-arb-gpio-challenge.c | 147 ++++++++ drivers/i2c/muxes/i2c-mux-uclass.c | 198 ++++++++++ drivers/misc/cros_ec.c | 288 +++----------- drivers/power/pmic/Makefile | 2 - drivers/power/pmic/pmic_tps65090.c | 310 --------------- drivers/power/pmic/pmic_tps65090_ec.c | 218 ----------- drivers/power/regulator/max77686.c | 18 +- drivers/video/Makefile | 1 - drivers/video/bridge/video-bridge-uclass.c | 28 +- drivers/video/exynos_dp.c | 22 -- drivers/video/parade.c | 231 ------------ include/configs/arndale.h | 18 +- include/configs/exynos5-common.h | 13 +- include/configs/exynos5-dt-common.h | 21 +- include/configs/exynos5250-common.h | 16 +- include/configs/exynos5420-common.h | 9 +- include/configs/odroid_xu3.h | 2 + include/configs/peach-pi.h | 14 +- include/configs/peach-pit.h | 24 +- include/configs/smdk5250.h | 16 +- include/configs/smdk5420.h | 10 +- include/configs/snow.h | 15 +- include/configs/spring.h | 20 + include/cros_ec.h | 16 +- include/dm/uclass-id.h | 1 + include/fdtdec.h | 3 - include/i2c.h | 39 ++ include/parade.h | 18 - include/power/tps65090_pmic.h | 73 ---- lib/fdtdec.c | 3 - 61 files changed, 1997 insertions(+), 1794 deletions(-) create mode 100644 arch/arm/dts/exynos5250-spring.dts create mode 100644 board/samsung/common/exynos5-dt.c delete mode 100644 board/samsung/smdk5250/exynos5-dt.c delete mode 100644 board/samsung/smdk5420/smdk5420.c create mode 100644 configs/spring_defconfig create mode 100644 doc/README.i2c create mode 100644 doc/device-tree-bindings/i2c/i2c-mux.txt create mode 100644 drivers/i2c/cros_ec_ldo.c create mode 100644 drivers/i2c/cros_ec_tunnel.c create mode 100644 drivers/i2c/muxes/Kconfig create mode 100644 drivers/i2c/muxes/Makefile create mode 100644 drivers/i2c/muxes/i2c-arb-gpio-challenge.c create mode 100644 drivers/i2c/muxes/i2c-mux-uclass.c delete mode 100644 drivers/power/pmic/pmic_tps65090.c delete mode 100644 drivers/power/pmic/pmic_tps65090_ec.c delete mode 100644 drivers/video/parade.c create mode 100644 include/configs/spring.h delete mode 100644 include/parade.h delete mode 100644 include/power/tps65090_pmic.h

At present lower case is used for the regulator names in the device tree. The kernel uses upper case and U-Boot will require this also since it will move to a case-sensitive name check.
Signed-off-by: Simon Glass sjg@chromium.org ---
Changes in v2: - Add new patch to correct LDO and BUCK naming
arch/arm/dts/exynos4412-odroid.dts | 56 +++++++++++++++--------------- arch/arm/dts/exynos4412-trats2.dts | 70 +++++++++++++++++++------------------- 2 files changed, 63 insertions(+), 63 deletions(-)
diff --git a/arch/arm/dts/exynos4412-odroid.dts b/arch/arm/dts/exynos4412-odroid.dts index d572f1e..a63e8ab 100644 --- a/arch/arm/dts/exynos4412-odroid.dts +++ b/arch/arm/dts/exynos4412-odroid.dts @@ -42,103 +42,103 @@ #clock-cells = <1>;
voltage-regulators { - ldo1_reg: ldo1 { + ldo1_reg: LDO1 { regulator-name = "VDD_ALIVE_1.0V"; regulator-min-microvolt = <1000000>; regulator-max-microvolt = <1000000>; };
- ldo2_reg: ldo2 { + ldo2_reg: LDO2 { regulator-name = "VDDQ_VM1M2_1.2V"; regulator-min-microvolt = <1200000>; regulator-max-microvolt = <1200000>; };
- ldo3_reg: ldo3 { + ldo3_reg: LDO3 { regulator-name = "VCC_1.8V_AP"; regulator-min-microvolt = <1800000>; regulator-max-microvolt = <1800000>; };
- ldo4_reg: ldo4 { + ldo4_reg: LDO4 { regulator-name = "VDDQ_MMC2_2.8V"; regulator-min-microvolt = <2800000>; regulator-max-microvolt = <2800000>; };
- ldo5_reg: ldo5 { + ldo5_reg: LDO5 { regulator-name = "VDDQ_MMC0/1/3_1.8V"; regulator-min-microvolt = <1800000>; regulator-max-microvolt = <1800000>; };
- ldo6_reg: ldo6 { + ldo6_reg: LDO6 { regulator-name = "VMPLL_1.0V"; regulator-min-microvolt = <1100000>; regulator-max-microvolt = <1100000>; };
- ldo7_reg: ldo7 { + ldo7_reg: LDO7 { regulator-name = "VPLL_1.1V"; regulator-min-microvolt = <1100000>; regulator-max-microvolt = <1100000>; };
- ldo8_reg: ldo8 { + ldo8_reg: LDO8 { regulator-name = "VDD_MIPI/HDMI_1.0V"; regulator-min-microvolt = <1000000>; regulator-max-microvolt = <1000000>; };
- ldo10_reg: ldo10 { + ldo10_reg: LDO10 { regulator-name = "VDD_MIPI/HDMI_1.8V"; regulator-min-microvolt = <1800000>; regulator-max-microvolt = <1800000>; };
- ldo11_reg: ldo11 { + ldo11_reg: LDO11 { regulator-name = "VDD_ABB1_1.8V"; regulator-min-microvolt = <1800000>; regulator-max-microvolt = <1800000>; };
- ldo12_reg: ldo12 { + ldo12_reg: LDO12 { regulator-name = "VDD_UOTG_3.0V"; regulator-min-microvolt = <3000000>; regulator-max-microvolt = <3000000>; };
- ldo13_reg: ldo13 { + ldo13_reg: LDO13 { regulator-name = "VDD_C2C_1.8V"; regulator-min-microvolt = <1800000>; regulator-max-microvolt = <1800000>; };
- ldo14_reg: ldo14 { + ldo14_reg: LDO14 { regulator-name = "VDD_ABB02_1.8V"; regulator-min-microvolt = <1800000>; regulator-max-microvolt = <1800000>; };
- ldo15_reg: ldo15 { + ldo15_reg: LDO15 { regulator-name = "VDD_HSIC/OTG_1.0V"; regulator-min-microvolt = <1000000>; regulator-max-microvolt = <1000000>; };
- ldo16_reg: ldo16 { + ldo16_reg: LDO16 { regulator-name = "VDD_HSIC_1.8V"; regulator-min-microvolt = <1800000>; regulator-max-microvolt = <1800000>; };
- ldo17_reg: ldo17 { + ldo17_reg: LDO17 { regulator-name = "VDDQ_CAM_1.2V"; regulator-min-microvolt = <1200000>; regulator-max-microvolt = <1200000>; };
- ldo20_reg: ldo20 { + ldo20_reg: LDO20 { regulator-name = "VDDQ_EMMC_1.8V"; regulator-min-microvolt = <1800000>; regulator-max-microvolt = <1800000>; @@ -146,7 +146,7 @@ regulator-boot-on; };
- ldo21_reg: ldo21 { + ldo21_reg: LDO21 { regulator-name = "TFLASH_2.8V"; regulator-min-microvolt = <2800000>; regulator-max-microvolt = <2800000>; @@ -154,7 +154,7 @@ regulator-boot-on; };
- ldo22_reg: ldo22 { + ldo22_reg: LDO22 { regulator-name = "VDDQ_EMMC_2.8V"; regulator-min-microvolt = <2800000>; regulator-max-microvolt = <2800000>; @@ -162,56 +162,56 @@ regulator-boot-on; };
- ldo25_reg: ldo25 { + ldo25_reg: LDO25 { regulator-compatible = "LDO25"; regulator-name = "VDDQ_LCD_3.0V"; regulator-min-microvolt = <3000000>; regulator-max-microvolt = <3000000>; };
- buck1_reg: buck1 { + buck1_reg: BUCK1 { regulator-name = "VDD_MIF_1.0V"; regulator-min-microvolt = <8500000>; regulator-max-microvolt = <1100000>; };
- buck2_reg: buck2 { + buck2_reg: BUCK2 { regulator-name = "VDD_ARM_1.0V"; regulator-min-microvolt = <850000>; regulator-max-microvolt = <1500000>; };
- buck3_reg: buck3 { + buck3_reg: BUCK3 { regulator-name = "VDD_INT_1.1V"; regulator-min-microvolt = <850000>; regulator-max-microvolt = <1150000>; };
- buck4_reg: buck4 { + buck4_reg: BUCK4 { regulator-name = "VDD_G3D_1.0V"; regulator-min-microvolt = <850000>; regulator-max-microvolt = <1150000>; };
- buck5_reg: buck5 { + buck5_reg: BUCK5 { regulator-name = "VDDQ_AP_1.2V"; regulator-min-microvolt = <1200000>; regulator-max-microvolt = <1200000>; };
- buck6_reg: buck6 { + buck6_reg: BUCK6 { regulator-name = "VCC_INL1/7_1.35V"; regulator-min-microvolt = <1350000>; regulator-max-microvolt = <1350000>; };
- buck7_reg: buck7 { + buck7_reg: BUCK7 { regulator-name = "VCC_INL2/3/5_2.0V"; regulator-min-microvolt = <2000000>; regulator-max-microvolt = <2000000>; };
- buck8_reg: buck8 { + buck8_reg: BUCK8 { regulator-name = "VCC_P3V3_2.85V"; regulator-min-microvolt = <2850000>; regulator-max-microvolt = <3300000>; diff --git a/arch/arm/dts/exynos4412-trats2.dts b/arch/arm/dts/exynos4412-trats2.dts index 5c0bb91..2d4e522 100644 --- a/arch/arm/dts/exynos4412-trats2.dts +++ b/arch/arm/dts/exynos4412-trats2.dts @@ -47,7 +47,7 @@ #clock-cells = <1>;
voltage-regulators { - ldo1_reg: ldo1 { + ldo1_reg: LDO1 { regulator-compatible = "LDO1"; regulator-name = "VALIVE_1.0V_AP"; regulator-min-microvolt = <1000000>; @@ -56,7 +56,7 @@ regulator-mem-on; };
- ldo2_reg: ldo2 { + ldo2_reg: LDO2 { regulator-compatible = "LDO2"; regulator-name = "VM1M2_1.2V_AP"; regulator-min-microvolt = <1200000>; @@ -65,7 +65,7 @@ regulator-mem-on; };
- ldo3_reg: ldo3 { + ldo3_reg: LDO3 { regulator-compatible = "LDO3"; regulator-name = "VCC_1.8V_AP"; regulator-min-microvolt = <1800000>; @@ -74,7 +74,7 @@ regulator-mem-on; };
- ldo4_reg: ldo4 { + ldo4_reg: LDO4 { regulator-compatible = "LDO4"; regulator-name = "VCC_2.8V_AP"; regulator-min-microvolt = <2800000>; @@ -83,7 +83,7 @@ regulator-mem-on; };
- ldo5_reg: ldo5 { + ldo5_reg: LDO5 { regulator-compatible = "LDO5"; regulator-name = "VCC_1.8V_IO"; regulator-min-microvolt = <1800000>; @@ -92,7 +92,7 @@ regulator-mem-on; };
- ldo6_reg: ldo6 { + ldo6_reg: LDO6 { regulator-compatible = "LDO6"; regulator-name = "VMPLL_1.0V_AP"; regulator-min-microvolt = <1000000>; @@ -101,7 +101,7 @@ regulator-mem-on; };
- ldo7_reg: ldo7 { + ldo7_reg: LDO7 { regulator-compatible = "LDO7"; regulator-name = "VPLL_1.0V_AP"; regulator-min-microvolt = <1000000>; @@ -110,7 +110,7 @@ regulator-mem-on; };
- ldo8_reg: ldo8 { + ldo8_reg: LDO8 { regulator-compatible = "LDO8"; regulator-name = "VMIPI_1.0V"; regulator-min-microvolt = <1000000>; @@ -118,7 +118,7 @@ regulator-mem-off; };
- ldo9_reg: ldo9 { + ldo9_reg: LDO9 { regulator-compatible = "LDO9"; regulator-name = "CAM_ISP_MIPI_1.2V"; regulator-min-microvolt = <1200000>; @@ -126,7 +126,7 @@ regulator-mem-idle; };
- ldo10_reg: ldo10 { + ldo10_reg: LDO10 { regulator-compatible = "LDO10"; regulator-name = "VMIPI_1.8V"; regulator-min-microvolt = <1800000>; @@ -134,7 +134,7 @@ regulator-mem-off; };
- ldo11_reg: ldo11 { + ldo11_reg: LDO11 { regulator-compatible = "LDO11"; regulator-name = "VABB1_1.95V"; regulator-min-microvolt = <1950000>; @@ -143,7 +143,7 @@ regulator-mem-off; };
- ldo12_reg: ldo12 { + ldo12_reg: LDO12 { regulator-compatible = "LDO12"; regulator-name = "VUOTG_3.0V"; regulator-min-microvolt = <3000000>; @@ -151,7 +151,7 @@ regulator-mem-off; };
- ldo13_reg: ldo13 { + ldo13_reg: LDO13 { regulator-compatible = "LDO13"; regulator-name = "NFC_AVDD_1.8V"; regulator-min-microvolt = <1800000>; @@ -159,7 +159,7 @@ regulator-mem-idle; };
- ldo14_reg: ldo14 { + ldo14_reg: LDO14 { regulator-compatible = "LDO14"; regulator-name = "VABB2_1.95V"; regulator-min-microvolt = <1950000>; @@ -168,7 +168,7 @@ regulator-mem-off; };
- ldo15_reg: ldo15 { + ldo15_reg: LDO15 { regulator-compatible = "LDO15"; regulator-name = "VHSIC_1.0V"; regulator-min-microvolt = <1000000>; @@ -176,7 +176,7 @@ regulator-mem-off; };
- ldo16_reg: ldo16 { + ldo16_reg: LDO16 { regulator-compatible = "LDO16"; regulator-name = "VHSIC_1.8V"; regulator-min-microvolt = <1800000>; @@ -184,7 +184,7 @@ regulator-mem-off; };
- ldo17_reg: ldo17 { + ldo17_reg: LDO17 { regulator-compatible = "LDO17"; regulator-name = "CAM_SENSOR_CORE_1.2V"; regulator-min-microvolt = <1200000>; @@ -192,7 +192,7 @@ regulator-mem-idle; };
- ldo18_reg: ldo18 { + ldo18_reg: LDO18 { regulator-compatible = "LDO18"; regulator-name = "CAM_ISP_SEN_IO_1.8V"; regulator-min-microvolt = <1800000>; @@ -200,7 +200,7 @@ regulator-mem-idle; };
- ldo19_reg: ldo19 { + ldo19_reg: LDO19 { regulator-compatible = "LDO19"; regulator-name = "VT_CAM_1.8V"; regulator-min-microvolt = <1800000>; @@ -208,7 +208,7 @@ regulator-mem-idle; };
- ldo20_reg: ldo20 { + ldo20_reg: LDO20 { regulator-compatible = "LDO20"; regulator-name = "VDDQ_PRE_1.8V"; regulator-min-microvolt = <1800000>; @@ -216,7 +216,7 @@ regulator-mem-idle; };
- ldo21_reg: ldo21 { + ldo21_reg: LDO21 { regulator-compatible = "LDO21"; regulator-name = "VTF_2.8V"; regulator-min-microvolt = <2800000>; @@ -224,7 +224,7 @@ regulator-mem-idle; };
- ldo22_reg: ldo22 { + ldo22_reg: LDO22 { regulator-compatible = "LDO22"; regulator-name = "VMEM_VDD_2.8V"; regulator-min-microvolt = <2800000>; @@ -233,7 +233,7 @@ regulator-mem-off; };
- ldo23_reg: ldo23 { + ldo23_reg: LDO23 { regulator-compatible = "LDO23"; regulator-name = "TSP_AVDD_3.3V"; regulator-min-microvolt = <3300000>; @@ -241,7 +241,7 @@ regulator-mem-idle; };
- ldo24_reg: ldo24 { + ldo24_reg: LDO24 { regulator-compatible = "LDO24"; regulator-name = "TSP_VDD_1.8V"; regulator-min-microvolt = <1800000>; @@ -249,7 +249,7 @@ regulator-mem-idle; };
- ldo25_reg: ldo25 { + ldo25_reg: LDO25 { regulator-compatible = "LDO25"; regulator-name = "LCD_VCC_3.3V"; regulator-min-microvolt = <2800000>; @@ -257,7 +257,7 @@ regulator-mem-idle; };
- ldo26_reg: ldo26 { + ldo26_reg: LDO26 { regulator-compatible = "LDO26"; regulator-name = "MOTOR_VCC_3.0V"; regulator-min-microvolt = <3000000>; @@ -265,7 +265,7 @@ regulator-mem-idle; };
- buck1_reg: buck1 { + buck1_reg: BUCK1 { regulator-compatible = "BUCK1"; regulator-name = "vdd_mif"; regulator-min-microvolt = <850000>; @@ -275,7 +275,7 @@ regulator-mem-off; };
- buck2_reg: buck2 { + buck2_reg: BUCK2 { regulator-compatible = "BUCK2"; regulator-name = "vdd_arm"; regulator-min-microvolt = <850000>; @@ -285,7 +285,7 @@ regulator-mem-off; };
- buck3_reg: buck3 { + buck3_reg: BUCK3 { regulator-compatible = "BUCK3"; regulator-name = "vdd_int"; regulator-min-microvolt = <850000>; @@ -295,7 +295,7 @@ regulator-mem-off; };
- buck4_reg: buck4 { + buck4_reg: BUCK4 { regulator-compatible = "BUCK4"; regulator-name = "vdd_g3d"; regulator-min-microvolt = <850000>; @@ -304,7 +304,7 @@ regulator-mem-off; };
- buck5_reg: buck5 { + buck5_reg: BUCK5 { regulator-compatible = "BUCK5"; regulator-name = "VMEM_1.2V_AP"; regulator-min-microvolt = <1200000>; @@ -312,7 +312,7 @@ regulator-always-on; };
- buck6_reg: buck6 { + buck6_reg: BUCK6 { regulator-compatible = "BUCK6"; regulator-name = "VCC_SUB_1.35V"; regulator-min-microvolt = <1350000>; @@ -320,7 +320,7 @@ regulator-always-on; };
- buck7_reg: buck7 { + buck7_reg: BUCK7 { regulator-compatible = "BUCK7"; regulator-name = "VCC_SUB_2.0V"; regulator-min-microvolt = <2000000>; @@ -328,7 +328,7 @@ regulator-always-on; };
- buck8_reg: buck8 { + buck8_reg: BUCK8 { regulator-compatible = "BUCK8"; regulator-name = "VMEM_VDDF_3.0V"; regulator-min-microvolt = <2850000>; @@ -337,7 +337,7 @@ regulator-mem-off; };
- buck9_reg: buck9 { + buck9_reg: BUCK9 { regulator-compatible = "BUCK9"; regulator-name = "CAM_ISP_CORE_1.2V"; regulator-min-microvolt = <1000000>;

On 3 August 2015 at 08:19, Simon Glass sjg@chromium.org wrote:
At present lower case is used for the regulator names in the device tree. The kernel uses upper case and U-Boot will require this also since it will move to a case-sensitive name check.
Signed-off-by: Simon Glass sjg@chromium.org
Changes in v2:
- Add new patch to correct LDO and BUCK naming
arch/arm/dts/exynos4412-odroid.dts | 56 +++++++++++++++--------------- arch/arm/dts/exynos4412-trats2.dts | 70 +++++++++++++++++++------------------- 2 files changed, 63 insertions(+), 63 deletions(-)
Applied to u-boot-dm.

We haven't quite got pinctrl ready to apply to mainline. We don't want to GPIO pull-up/down support to the driver model GPIO layer either. So work around this for now.
We can address this when pinctrl is complete.
Signed-off-by: Simon Glass sjg@chromium.org ---
Changes in v2: - Add a new patch to hold off the need for driver model pinctrl
drivers/video/bridge/video-bridge-uclass.c | 28 ++++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-)
diff --git a/drivers/video/bridge/video-bridge-uclass.c b/drivers/video/bridge/video-bridge-uclass.c index e1ea428..6c5990f 100644 --- a/drivers/video/bridge/video-bridge-uclass.c +++ b/drivers/video/bridge/video-bridge-uclass.c @@ -57,22 +57,30 @@ static int video_bridge_pre_probe(struct udevice *dev) debug("%s: Could not decode sleep-gpios (%d)\n", __func__, ret); return ret; } - ret = dm_gpio_set_pull(&uc_priv->sleep, GPIO_PULL_NONE); - if (ret) { - debug("%s: Could not set sleep pull value\n", __func__); - return ret; - } + /* + * Drop this for now as we do not have driver model pinctrl support + * + * ret = dm_gpio_set_pull(&uc_priv->sleep, GPIO_PULL_NONE); + * if (ret) { + * debug("%s: Could not set sleep pull value\n", __func__); + * return ret; + * } + */ ret = gpio_request_by_name(dev, "reset-gpios", 0, &uc_priv->reset, GPIOD_IS_OUT); if (ret) { debug("%s: Could not decode reset-gpios (%d)\n", __func__, ret); return ret; } - ret = dm_gpio_set_pull(&uc_priv->reset, GPIO_PULL_NONE); - if (ret) { - debug("%s: Could not set reset pull value\n", __func__); - return ret; - } + /* + * Drop this for now as we do not have driver model pinctrl support + * + * ret = dm_gpio_set_pull(&uc_priv->reset, GPIO_PULL_NONE); + * if (ret) { + * debug("%s: Could not set reset pull value\n", __func__); + * return ret; + * } + */ ret = gpio_request_by_name(dev, "hotplug-gpios", 0, &uc_priv->hotplug, GPIOD_IS_IN); if (ret && ret != -ENOENT) {

On 3 August 2015 at 08:19, Simon Glass sjg@chromium.org wrote:
We haven't quite got pinctrl ready to apply to mainline. We don't want to GPIO pull-up/down support to the driver model GPIO layer either. So work around this for now.
We can address this when pinctrl is complete.
Signed-off-by: Simon Glass sjg@chromium.org
Changes in v2:
- Add a new patch to hold off the need for driver model pinctrl
drivers/video/bridge/video-bridge-uclass.c | 28 ++++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-)
Applied to u-boot-dm.

Add a new I2C_MUX uclass. Devices in this class can multiplex between several I2C buses, selecting them one at a time for use by the system. The multiplexing mechanism is left to the driver to decide - it may be controlled by GPIOs, for example.
The uclass supports only two methods: select() and deselect().
The current mux state is expected to be stored in the mux itself since it is the only thing that knows how to make things work. The mux can record the current state and then avoid switching unless it is necessary. So select() can be skipped if the mux is already in the correct state. Also deselect() can be made a nop if required.
Signed-off-by: Simon Glass sjg@chromium.org ---
Changes in v2: - Update commit message and header file to better explain select()/deselect()
doc/device-tree-bindings/i2c/i2c-mux.txt | 60 ++++++++++ drivers/i2c/Kconfig | 2 + drivers/i2c/Makefile | 2 + drivers/i2c/muxes/Kconfig | 8 ++ drivers/i2c/muxes/Makefile | 6 + drivers/i2c/muxes/i2c-mux-uclass.c | 198 +++++++++++++++++++++++++++++++ include/dm/uclass-id.h | 1 + include/i2c.h | 39 ++++++ 8 files changed, 316 insertions(+) create mode 100644 doc/device-tree-bindings/i2c/i2c-mux.txt create mode 100644 drivers/i2c/muxes/Kconfig create mode 100644 drivers/i2c/muxes/Makefile create mode 100644 drivers/i2c/muxes/i2c-mux-uclass.c
diff --git a/doc/device-tree-bindings/i2c/i2c-mux.txt b/doc/device-tree-bindings/i2c/i2c-mux.txt new file mode 100644 index 0000000..af84cce --- /dev/null +++ b/doc/device-tree-bindings/i2c/i2c-mux.txt @@ -0,0 +1,60 @@ +Common i2c bus multiplexer/switch properties. + +An i2c bus multiplexer/switch will have several child busses that are +numbered uniquely in a device dependent manner. The nodes for an i2c bus +multiplexer/switch will have one child node for each child +bus. + +Required properties: +- #address-cells = <1>; +- #size-cells = <0>; + +Required properties for child nodes: +- #address-cells = <1>; +- #size-cells = <0>; +- reg : The sub-bus number. + +Optional properties for child nodes: +- Other properties specific to the multiplexer/switch hardware. +- Child nodes conforming to i2c bus binding + + +Example : + + /* + An NXP pca9548 8 channel I2C multiplexer at address 0x70 + with two NXP pca8574 GPIO expanders attached, one each to + ports 3 and 4. + */ + + mux@70 { + compatible = "nxp,pca9548"; + reg = <0x70>; + #address-cells = <1>; + #size-cells = <0>; + + i2c@3 { + #address-cells = <1>; + #size-cells = <0>; + reg = <3>; + + gpio1: gpio@38 { + compatible = "nxp,pca8574"; + reg = <0x38>; + #gpio-cells = <2>; + gpio-controller; + }; + }; + i2c@4 { + #address-cells = <1>; + #size-cells = <0>; + reg = <4>; + + gpio2: gpio@38 { + compatible = "nxp,pca8574"; + reg = <0x38>; + #gpio-cells = <2>; + gpio-controller; + }; + }; + }; diff --git a/drivers/i2c/Kconfig b/drivers/i2c/Kconfig index 86fb36b..caee3d8 100644 --- a/drivers/i2c/Kconfig +++ b/drivers/i2c/Kconfig @@ -73,3 +73,5 @@ config SYS_I2C_UNIPHIER_F help Support for UniPhier FIFO-builtin I2C controller driver. This I2C controller is used on PH1-Pro4 or newer UniPhier SoCs. + +source "drivers/i2c/muxes/Kconfig" diff --git a/drivers/i2c/Makefile b/drivers/i2c/Makefile index d9e912f..dc9e81b 100644 --- a/drivers/i2c/Makefile +++ b/drivers/i2c/Makefile @@ -37,3 +37,5 @@ obj-$(CONFIG_SYS_I2C_TEGRA) += tegra_i2c.o obj-$(CONFIG_SYS_I2C_UNIPHIER) += i2c-uniphier.o obj-$(CONFIG_SYS_I2C_UNIPHIER_F) += i2c-uniphier-f.o obj-$(CONFIG_SYS_I2C_ZYNQ) += zynq_i2c.o + +obj-y += muxes/ diff --git a/drivers/i2c/muxes/Kconfig b/drivers/i2c/muxes/Kconfig new file mode 100644 index 0000000..a05b32d --- /dev/null +++ b/drivers/i2c/muxes/Kconfig @@ -0,0 +1,8 @@ +config I2C_MUX + bool "Suport I2C multiplexers" + depends on DM_I2C + help + This enables I2C buses to be multiplexed, so that you can select + one of several buses using some sort of control mechanism. The + bus select is handled automatically when that bus is accessed, + using a suitable I2C MUX driver. diff --git a/drivers/i2c/muxes/Makefile b/drivers/i2c/muxes/Makefile new file mode 100644 index 0000000..7583e3a --- /dev/null +++ b/drivers/i2c/muxes/Makefile @@ -0,0 +1,6 @@ +# +# Copyright (c) 2015 Google, Inc +# +# SPDX-License-Identifier: GPL-2.0+ +# +obj-$(CONFIG_I2C_MUX) += i2c-mux-uclass.o diff --git a/drivers/i2c/muxes/i2c-mux-uclass.c b/drivers/i2c/muxes/i2c-mux-uclass.c new file mode 100644 index 0000000..3f52bff --- /dev/null +++ b/drivers/i2c/muxes/i2c-mux-uclass.c @@ -0,0 +1,198 @@ +/* + * Copyright (c) 2015 Google, Inc + * Written by Simon Glass sjg@chromium.org + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <dm.h> +#include <errno.h> +#include <i2c.h> +#include <dm/lists.h> +#include <dm/root.h> + +DECLARE_GLOBAL_DATA_PTR; + +/** + * struct i2c_mux: Information the uclass stores about an I2C mux + * + * @selected: Currently selected mux, or -1 for none + * @i2c_bus: I2C bus to use for communcation + */ +struct i2c_mux { + int selected; + struct udevice *i2c_bus; +}; + +/** + * struct i2c_mux_bus: Information about each bus the mux controls + * + * @channel: Channel number used to select this bus + */ +struct i2c_mux_bus { + uint channel; +}; + +/* Find out the mux channel number */ +static int i2c_mux_child_post_bind(struct udevice *dev) +{ + struct i2c_mux_bus *plat = dev_get_parent_platdata(dev); + int channel; + + channel = fdtdec_get_int(gd->fdt_blob, dev->of_offset, "reg", -1); + if (channel < 0) + return -EINVAL; + plat->channel = channel; + + return 0; +} + +/* Find the I2C buses selected by this mux */ +static int i2c_mux_post_bind(struct udevice *mux) +{ + const void *blob = gd->fdt_blob; + 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, mux->of_offset); + offset > 0; + offset = fdt_next_subnode(blob, offset)) { + struct udevice *dev; + const char *name; + + name = fdt_get_name(blob, offset, NULL); + ret = device_bind_driver_to_node(mux, "i2c_mux_bus_drv", name, + offset, &dev); + debug(" - bind ret=%d, %s\n", ret, dev ? dev->name : NULL); + if (ret) + return ret; + } + + return 0; +} + +/* Set up the mux ready for use */ +static int i2c_mux_post_probe(struct udevice *mux) +{ + struct i2c_mux *priv = dev_get_uclass_priv(mux); + int ret; + + debug("%s: %s\n", __func__, mux->name); + priv->selected = -1; + + ret = uclass_get_device_by_phandle(UCLASS_I2C, mux, "i2c-parent", + &priv->i2c_bus); + if (ret) + return ret; + debug("%s: bus=%p/%s\n", __func__, priv->i2c_bus, priv->i2c_bus->name); + + return 0; +} + +int i2c_mux_select(struct udevice *dev) +{ + struct i2c_mux_bus *plat = dev_get_parent_platdata(dev); + struct udevice *mux = dev->parent; + struct i2c_mux_ops *ops = i2c_mux_get_ops(mux); + + if (!ops->select) + return -ENOSYS; + + return ops->select(mux, dev, plat->channel); +} + +int i2c_mux_deselect(struct udevice *dev) +{ + struct i2c_mux_bus *plat = dev_get_parent_platdata(dev); + struct udevice *mux = dev->parent; + struct i2c_mux_ops *ops = i2c_mux_get_ops(mux); + + if (!ops->deselect) + return -ENOSYS; + + return ops->deselect(mux, dev, plat->channel); +} + +static int i2c_mux_bus_set_bus_speed(struct udevice *dev, unsigned int speed) +{ + struct udevice *mux = dev->parent; + struct i2c_mux *priv = dev_get_uclass_priv(mux); + int ret, ret2; + + ret = i2c_mux_select(dev); + if (ret) + return ret; + ret = dm_i2c_set_bus_speed(priv->i2c_bus, speed); + ret2 = i2c_mux_deselect(dev); + + return ret ? ret : ret2; +} + +static int i2c_mux_bus_probe(struct udevice *dev, uint chip_addr, + uint chip_flags) +{ + struct udevice *mux = dev->parent; + struct i2c_mux *priv = dev_get_uclass_priv(mux); + struct dm_i2c_ops *ops = i2c_get_ops(priv->i2c_bus); + int ret, ret2; + + debug("%s: %s, bus %s\n", __func__, dev->name, priv->i2c_bus->name); + if (!ops->probe_chip) + return -ENOSYS; + ret = i2c_mux_select(dev); + if (ret) + return ret; + ret = ops->probe_chip(priv->i2c_bus, chip_addr, chip_flags); + ret2 = i2c_mux_deselect(dev); + + return ret ? ret : ret2; +} + +static int i2c_mux_bus_xfer(struct udevice *dev, struct i2c_msg *msg, + int nmsgs) +{ + struct udevice *mux = dev->parent; + struct i2c_mux *priv = dev_get_uclass_priv(mux); + struct dm_i2c_ops *ops = i2c_get_ops(priv->i2c_bus); + int ret, ret2; + + debug("%s: %s, bus %s\n", __func__, dev->name, priv->i2c_bus->name); + if (!ops->xfer) + return -ENOSYS; + ret = i2c_mux_select(dev); + if (ret) + return ret; + ret = ops->xfer(priv->i2c_bus, msg, nmsgs); + ret2 = i2c_mux_deselect(dev); + + return ret ? ret : ret2; +} + +static const struct dm_i2c_ops i2c_mux_bus_ops = { + .xfer = i2c_mux_bus_xfer, + .probe_chip = i2c_mux_bus_probe, + .set_bus_speed = i2c_mux_bus_set_bus_speed, +}; + +U_BOOT_DRIVER(i2c_mux_bus) = { + .name = "i2c_mux_bus_drv", + .id = UCLASS_I2C, + .per_child_auto_alloc_size = sizeof(struct dm_i2c_chip), + .ops = &i2c_mux_bus_ops, +}; + +UCLASS_DRIVER(i2c_mux) = { + .id = UCLASS_I2C_MUX, + .name = "i2c_mux", + .post_bind = i2c_mux_post_bind, + .post_probe = i2c_mux_post_probe, + .per_device_auto_alloc_size = sizeof(struct i2c_mux), + .per_child_platdata_auto_alloc_size = sizeof(struct i2c_mux_bus), + .child_post_bind = i2c_mux_child_post_bind, +}; diff --git a/include/dm/uclass-id.h b/include/dm/uclass-id.h index 1b80ca0..c744044 100644 --- a/include/dm/uclass-id.h +++ b/include/dm/uclass-id.h @@ -35,6 +35,7 @@ enum uclass_id { UCLASS_I2C, /* I2C bus */ UCLASS_I2C_EEPROM, /* I2C EEPROM device */ UCLASS_I2C_GENERIC, /* Generic I2C device */ + UCLASS_I2C_MUX, /* I2C multiplexer */ UCLASS_LED, /* Light-emitting diode (LED) */ UCLASS_LPC, /* x86 'low pin count' interface */ UCLASS_MASS_STORAGE, /* Mass storage device */ diff --git a/include/i2c.h b/include/i2c.h index d191829..6493931 100644 --- a/include/i2c.h +++ b/include/i2c.h @@ -445,6 +445,45 @@ struct dm_i2c_ops { #define i2c_get_ops(dev) ((struct dm_i2c_ops *)(dev)->driver->ops)
/** + * struct i2c_mux_ops - operations for an I2C mux + * + * The current mux state is expected to be stored in the mux itself since + * it is the only thing that knows how to make things work. The mux can + * record the current state and then avoid switching unless it is necessary. + * So select() can be skipped if the mux is already in the correct state. + * Also deselect() can be made a nop if required. + */ +struct i2c_mux_ops { + /** + * select() - select one of of I2C buses attached to a mux + * + * This will be called when there is no bus currently selected by the + * mux. This method does not need to deselect the old bus since + * deselect() will be already have been called if necessary. + * + * @mux: Mux device + * @bus: I2C bus to select + * @channel: Channel number correponding to the bus to select + * @return 0 if OK, -ve on error + */ + int (*select)(struct udevice *mux, struct udevice *bus, uint channel); + + /** + * deselect() - select one of of I2C buses attached to a mux + * + * This is used to deselect the currently selected I2C bus. + * + * @mux: Mux device + * @bus: I2C bus to deselect + * @channel: Channel number correponding to the bus to deselect + * @return 0 if OK, -ve on error + */ + int (*deselect)(struct udevice *mux, struct udevice *bus, uint channel); +}; + +#define i2c_mux_get_ops(dev) ((struct i2c_mux_ops *)(dev)->driver->ops) + +/** * i2c_get_chip() - get a device to use to access a chip on a bus * * This returns the device for the given chip address. The device can then

On 3 August 2015 at 08:19, Simon Glass sjg@chromium.org wrote:
Add a new I2C_MUX uclass. Devices in this class can multiplex between several I2C buses, selecting them one at a time for use by the system. The multiplexing mechanism is left to the driver to decide - it may be controlled by GPIOs, for example.
The uclass supports only two methods: select() and deselect().
The current mux state is expected to be stored in the mux itself since it is the only thing that knows how to make things work. The mux can record the current state and then avoid switching unless it is necessary. So select() can be skipped if the mux is already in the correct state. Also deselect() can be made a nop if required.
Signed-off-by: Simon Glass sjg@chromium.org
Changes in v2:
- Update commit message and header file to better explain select()/deselect()
doc/device-tree-bindings/i2c/i2c-mux.txt | 60 ++++++++++ drivers/i2c/Kconfig | 2 + drivers/i2c/Makefile | 2 + drivers/i2c/muxes/Kconfig | 8 ++ drivers/i2c/muxes/Makefile | 6 + drivers/i2c/muxes/i2c-mux-uclass.c | 198 +++++++++++++++++++++++++++++++ include/dm/uclass-id.h | 1 + include/i2c.h | 39 ++++++ 8 files changed, 316 insertions(+) create mode 100644 doc/device-tree-bindings/i2c/i2c-mux.txt create mode 100644 drivers/i2c/muxes/Kconfig create mode 100644 drivers/i2c/muxes/Makefile create mode 100644 drivers/i2c/muxes/i2c-mux-uclass.c
Applied to u-boot-dm.

While I2C supports multi-master buses this is difficult to get right. The implementation on the master side in software is quite complex. Clock-stretching and the arbitrary time that an I2C transaction can take make it difficult to share the bus fairly in the face of high traffic. When one or more masters can be reset independently part-way through a transaction it is hard to know the state of the bus.
This driver provides a scheme based on two 'claim' GPIOs, one driven by the AP (Application Processor, meaning the main CPU) and one driven by the EC (Embedded Controller, a small CPU aimed at handling system tasks). With these they can communicate and reliably share the bus. This scheme has minimal overhead and involves very little code. It is used on snow to permit the EC and the AP to share access to the main system PMIC and battery. The scheme can survive reboots by either side without difficulty. This scheme has been tested in the field with millions of devices.
Since U-Boot runs on the AP, the terminology used is 'our' claim GPIO, meaning the AP's, and 'their' claim GPIO, meaning the EC's. This terminology is used by the device tree bindings in Linux also.
Signed-off-by: Simon Glass sjg@chromium.org ---
Changes in v2: - Add a README explaining the algorithm and update the commit message
doc/README.i2c | 60 ++++++++++++ drivers/i2c/muxes/Kconfig | 9 ++ drivers/i2c/muxes/Makefile | 1 + drivers/i2c/muxes/i2c-arb-gpio-challenge.c | 147 +++++++++++++++++++++++++++++ 4 files changed, 217 insertions(+) create mode 100644 doc/README.i2c create mode 100644 drivers/i2c/muxes/i2c-arb-gpio-challenge.c
diff --git a/doc/README.i2c b/doc/README.i2c new file mode 100644 index 0000000..07cd8df --- /dev/null +++ b/doc/README.i2c @@ -0,0 +1,60 @@ +I2C Bus Arbitration +=================== + +While I2C supports multi-master buses this is difficult to get right. +The implementation on the master side in software is quite complex. +Clock-stretching and the arbitrary time that an I2C transaction can take +make it difficult to share the bus fairly in the face of high traffic. +When one or more masters can be reset independently part-way through a +transaction it is hard to know the state of the bus. + +U-Boot provides a scheme based on two 'claim' GPIOs, one driven by the +AP (Application Processor, meaning the main CPU) and one driven by the EC +(Embedded Controller, a small CPU aimed at handling system tasks). With +these they can communicate and reliably share the bus. This scheme has +minimal overhead and involves very little code. The scheme can survive +reboots by either side without difficulty. + +Since U-Boot runs on the AP, the terminology used is 'our' claim GPIO, +meaning the AP's, and 'their' claim GPIO, meaning the EC's. This terminology +is used by the device tree bindings in Linux also. + +The driver is implemented as an I2C mux, as it is in Linux. See +i2c-arb-gpio-challenge for the implementation. + +GPIO lines are shared between the AP and EC to manage the bus. The AP and EC +each have a 'bus claim' line, which is an output that the other can see. + +- AP_CLAIM: output from AP, signalling to the EC that the AP wants the bus +- EC_CLAIM: output from EC, signalling to the AP that the EC wants the bus + +The basic algorithm is to assert your line when you want the bus, then make +sure that the other side doesn't want it also. A detailed explanation is best +done with an example. + +Let's say the AP wants to claim the bus. It: + +1. Asserts AP_CLAIM +2. Waits a little bit for the other side to notice (slew time) +3. Checks EC_CLAIM. If this is not asserted, then the AP has the bus, and we + are done +4. Otherwise, wait for a few milliseconds (retry time) and see if EC_CLAIM is + released +5. If not, back off, release the claim and wait for a few more milliseconds + (retry time again) +6. Go back to 1 if things don't look wedged (wait time has expired) +7. Panic. The other side is hung with the CLAIM line set. + +The same algorithm applies on the EC. + +To release the bus, just de-assert the claim line. + +Typical delays are: +- slew time 10 us +- retry time 3 ms +- wait time - 50ms + +In general the traffic is fairly light, and in particular the EC wants access +to the bus quite rarely (maybe every 10s or 30s to check the battery). This +scheme works very nicely with very low contention. There is only a 10 us +wait for access to the bus assuming that the other side isn't using it. diff --git a/drivers/i2c/muxes/Kconfig b/drivers/i2c/muxes/Kconfig index a05b32d..bd3e078 100644 --- a/drivers/i2c/muxes/Kconfig +++ b/drivers/i2c/muxes/Kconfig @@ -6,3 +6,12 @@ config I2C_MUX one of several buses using some sort of control mechanism. The bus select is handled automatically when that bus is accessed, using a suitable I2C MUX driver. + +config I2C_ARB_GPIO_CHALLENGE + bool "GPIO-based I2C arbitration" + depends on I2C_MUX + help + If you say yes to this option, support will be included for an + I2C multimaster arbitration scheme using GPIOs and a challenge & + response mechanism where masters have to claim the bus by asserting + a GPIO. diff --git a/drivers/i2c/muxes/Makefile b/drivers/i2c/muxes/Makefile index 7583e3a..612cc27 100644 --- a/drivers/i2c/muxes/Makefile +++ b/drivers/i2c/muxes/Makefile @@ -3,4 +3,5 @@ # # SPDX-License-Identifier: GPL-2.0+ # +obj-$(CONFIG_I2C_ARB_GPIO_CHALLENGE) += i2c-arb-gpio-challenge.o obj-$(CONFIG_I2C_MUX) += i2c-mux-uclass.o diff --git a/drivers/i2c/muxes/i2c-arb-gpio-challenge.c b/drivers/i2c/muxes/i2c-arb-gpio-challenge.c new file mode 100644 index 0000000..3f072c7 --- /dev/null +++ b/drivers/i2c/muxes/i2c-arb-gpio-challenge.c @@ -0,0 +1,147 @@ +/* + * Copyright (c) 2015 Google, Inc + * Written by Simon Glass sjg@chromium.org + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <dm.h> +#include <errno.h> +#include <i2c.h> +#include <asm/gpio.h> + +DECLARE_GLOBAL_DATA_PTR; + +struct i2c_arbitrator_priv { + struct gpio_desc ap_claim; + struct gpio_desc ec_claim; + uint slew_delay_us; + uint wait_retry_ms; + uint wait_free_ms; +}; + +int i2c_arbitrator_deselect(struct udevice *mux, struct udevice *bus, + uint channel) +{ + struct i2c_arbitrator_priv *priv = dev_get_priv(mux); + int ret; + + debug("%s: %s\n", __func__, mux->name); + ret = dm_gpio_set_value(&priv->ap_claim, 0); + udelay(priv->slew_delay_us); + + return ret; +} + +int i2c_arbitrator_select(struct udevice *mux, struct udevice *bus, + uint channel) +{ + struct i2c_arbitrator_priv *priv = dev_get_priv(mux); + unsigned start; + int ret; + + debug("%s: %s\n", __func__, mux->name); + /* Start a round of trying to claim the bus */ + start = get_timer(0); + do { + unsigned start_retry; + int waiting = 0; + + /* Indicate that we want to claim the bus */ + ret = dm_gpio_set_value(&priv->ap_claim, 1); + if (ret) + goto err; + udelay(priv->slew_delay_us); + + /* Wait for the EC to release it */ + start_retry = get_timer(0); + while (get_timer(start_retry) < priv->wait_retry_ms) { + ret = dm_gpio_get_value(&priv->ec_claim); + if (ret < 0) { + goto err; + } else if (!ret) { + /* We got it, so return */ + return 0; + } + + if (!waiting) + waiting = 1; + } + + /* It didn't release, so give up, wait, and try again */ + ret = dm_gpio_set_value(&priv->ap_claim, 0); + if (ret) + goto err; + + mdelay(priv->wait_retry_ms); + } while (get_timer(start) < priv->wait_free_ms); + + /* Give up, release our claim */ + printf("I2C: Could not claim bus, timeout %lu\n", get_timer(start)); + ret = -ETIMEDOUT; + ret = 0; +err: + return ret; +} + +static int i2c_arbitrator_probe(struct udevice *dev) +{ + struct i2c_arbitrator_priv *priv = dev_get_priv(dev); + const void *blob = gd->fdt_blob; + int node = dev->of_offset; + int ret; + + debug("%s: %s\n", __func__, dev->name); + priv->slew_delay_us = fdtdec_get_int(blob, node, "slew-delay-us", 0); + priv->wait_retry_ms = fdtdec_get_int(blob, node, "wait-retry-us", 0) / + 1000; + priv->wait_free_ms = fdtdec_get_int(blob, node, "wait-free-us", 0) / + 1000; + ret = gpio_request_by_name(dev, "our-claim-gpio", 0, &priv->ap_claim, + GPIOD_IS_OUT); + if (ret) + goto err; + ret = gpio_request_by_name(dev, "their-claim-gpios", 0, &priv->ec_claim, + GPIOD_IS_IN); + if (ret) + goto err_ec_gpio; + + return 0; + +err_ec_gpio: + dm_gpio_free(dev, &priv->ap_claim); +err: + debug("%s: ret=%d\n", __func__, ret); + return ret; +} + +static int i2c_arbitrator_remove(struct udevice *dev) +{ + struct i2c_arbitrator_priv *priv = dev_get_priv(dev); + + dm_gpio_free(dev, &priv->ap_claim); + dm_gpio_free(dev, &priv->ec_claim); + + return 0; +} + +static const struct i2c_mux_ops i2c_arbitrator_ops = { + .select = i2c_arbitrator_select, + .deselect = i2c_arbitrator_deselect, +}; + +static const struct udevice_id i2c_arbitrator_ids[] = { + { .compatible = "i2c-arb-gpio-challenge" }, + { } +}; + +U_BOOT_DRIVER(i2c_arbitrator) = { + .name = "i2c_arbitrator", + .id = UCLASS_I2C_MUX, + .of_match = i2c_arbitrator_ids, + .probe = i2c_arbitrator_probe, + .remove = i2c_arbitrator_remove, + .ops = &i2c_arbitrator_ops, + .priv_auto_alloc_size = sizeof(struct i2c_arbitrator_priv), +};

On 3 August 2015 at 08:19, Simon Glass sjg@chromium.org wrote:
While I2C supports multi-master buses this is difficult to get right. The implementation on the master side in software is quite complex. Clock-stretching and the arbitrary time that an I2C transaction can take make it difficult to share the bus fairly in the face of high traffic. When one or more masters can be reset independently part-way through a transaction it is hard to know the state of the bus.
This driver provides a scheme based on two 'claim' GPIOs, one driven by the AP (Application Processor, meaning the main CPU) and one driven by the EC (Embedded Controller, a small CPU aimed at handling system tasks). With these they can communicate and reliably share the bus. This scheme has minimal overhead and involves very little code. It is used on snow to permit the EC and the AP to share access to the main system PMIC and battery. The scheme can survive reboots by either side without difficulty. This scheme has been tested in the field with millions of devices.
Since U-Boot runs on the AP, the terminology used is 'our' claim GPIO, meaning the AP's, and 'their' claim GPIO, meaning the EC's. This terminology is used by the device tree bindings in Linux also.
Signed-off-by: Simon Glass sjg@chromium.org
Changes in v2:
- Add a README explaining the algorithm and update the commit message
doc/README.i2c | 60 ++++++++++++ drivers/i2c/muxes/Kconfig | 9 ++ drivers/i2c/muxes/Makefile | 1 + drivers/i2c/muxes/i2c-arb-gpio-challenge.c | 147 +++++++++++++++++++++++++++++ 4 files changed, 217 insertions(+) create mode 100644 doc/README.i2c create mode 100644 drivers/i2c/muxes/i2c-arb-gpio-challenge.c
Applied to u-boot-dm.

The Chrome OS EC supports tunnelling through to an I2C bus on the EC. This currently uses a copy of the I2C command code and a special 'crosec' sub-command.
With driver model we can define an I2C bus which tunnels through to the EC, and use the normal 'i2c' command to access it. This simplifies the code and removes some duplication.
Add an I2C driver which tunnels through to the EC. Adjust the EC code to support binding child devices so that it can be set up. Adjust the existing I2C xfer function to fit driver model better.
For now the old code remains to allow things to still work. It will be removed in a later patch once the new flow is fully enabled.
Signed-off-by: Simon Glass sjg@chromium.org ---
Changes in v2: None
configs/peach-pi_defconfig | 2 + configs/peach-pit_defconfig | 2 + drivers/i2c/Kconfig | 11 +++++ drivers/i2c/Makefile | 1 + drivers/i2c/cros_ec_tunnel.c | 41 +++++++++++++++ drivers/misc/cros_ec.c | 93 +++++++++++++++++++++++++++++++++-- drivers/power/pmic/pmic_tps65090_ec.c | 8 +-- include/cros_ec.h | 14 +++++- 8 files changed, 161 insertions(+), 11 deletions(-) create mode 100644 drivers/i2c/cros_ec_tunnel.c
diff --git a/configs/peach-pi_defconfig b/configs/peach-pi_defconfig index c17fc73..5050f5b 100644 --- a/configs/peach-pi_defconfig +++ b/configs/peach-pi_defconfig @@ -12,3 +12,5 @@ CONFIG_CROS_EC_SPI=y CONFIG_CROS_EC_KEYB=y CONFIG_USB=y CONFIG_DM_USB=y +CONFIG_I2C_MUX=y +CONFIG_I2C_CROS_EC_TUNNEL=y diff --git a/configs/peach-pit_defconfig b/configs/peach-pit_defconfig index 8f21722..d19bff2 100644 --- a/configs/peach-pit_defconfig +++ b/configs/peach-pit_defconfig @@ -12,3 +12,5 @@ CONFIG_CROS_EC_SPI=y CONFIG_CROS_EC_KEYB=y CONFIG_USB=y CONFIG_DM_USB=y +CONFIG_I2C_MUX=y +CONFIG_I2C_CROS_EC_TUNNEL=y diff --git a/drivers/i2c/Kconfig b/drivers/i2c/Kconfig index caee3d8..e861b53 100644 --- a/drivers/i2c/Kconfig +++ b/drivers/i2c/Kconfig @@ -19,6 +19,17 @@ config DM_I2C_COMPAT to convert all code for a board in a single commit. It should not be enabled for any board in an official release.
+config I2C_CROS_EC_TUNNEL + tristate "Chrome OS EC tunnel I2C bus" + depends on CROS_EC + help + This provides an I2C bus that will tunnel i2c commands through to + the other side of the Chrome OS EC to the I2C bus connected there. + This will work whatever the interface used to talk to the EC (SPI, + I2C or LPC). Some Chromebooks use this when the hardware design + does not allow direct access to the main PMIC from the AP. + + config DM_I2C_GPIO bool "Enable Driver Model for software emulated I2C bus driver" depends on DM_I2C && DM_GPIO diff --git a/drivers/i2c/Makefile b/drivers/i2c/Makefile index dc9e81b..7f01fce 100644 --- a/drivers/i2c/Makefile +++ b/drivers/i2c/Makefile @@ -7,6 +7,7 @@ obj-$(CONFIG_DM_I2C) += i2c-uclass.o obj-$(CONFIG_DM_I2C_COMPAT) += i2c-uclass-compat.o obj-$(CONFIG_DM_I2C_GPIO) += i2c-gpio.o +obj-$(CONFIG_I2C_CROS_EC_TUNNEL) += cros_ec_tunnel.o
obj-$(CONFIG_SYS_I2C_ADI) += adi_i2c.o obj-$(CONFIG_I2C_MV) += mv_i2c.o diff --git a/drivers/i2c/cros_ec_tunnel.c b/drivers/i2c/cros_ec_tunnel.c new file mode 100644 index 0000000..7ab1fd8 --- /dev/null +++ b/drivers/i2c/cros_ec_tunnel.c @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2015 Google, Inc + * Written by Simon Glass sjg@chromium.org + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <dm.h> +#include <cros_ec.h> +#include <errno.h> +#include <i2c.h> + +static int cros_ec_i2c_set_bus_speed(struct udevice *dev, unsigned int speed) +{ + return 0; +} + +static int cros_ec_i2c_xfer(struct udevice *dev, struct i2c_msg *msg, + int nmsgs) +{ + return cros_ec_i2c_tunnel(dev->parent, msg, nmsgs); +} + +static const struct dm_i2c_ops cros_ec_i2c_ops = { + .xfer = cros_ec_i2c_xfer, + .set_bus_speed = cros_ec_i2c_set_bus_speed, +}; + +static const struct udevice_id cros_ec_i2c_ids[] = { + { .compatible = "google,cros-ec-i2c-tunnel" }, + { } +}; + +U_BOOT_DRIVER(cros_ec_tunnel) = { + .name = "cros_ec_tunnel", + .id = UCLASS_I2C, + .of_match = cros_ec_i2c_ids, + .per_child_auto_alloc_size = sizeof(struct dm_i2c_chip), + .ops = &cros_ec_i2c_ops, +}; diff --git a/drivers/misc/cros_ec.c b/drivers/misc/cros_ec.c index 4b6ac6a..ae52561 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/root.h> #include <dm/uclass-internal.h>
#ifdef DEBUG_TRACE @@ -1053,8 +1054,8 @@ int cros_ec_decode_ec_flash(const void *blob, int node, return 0; }
-int cros_ec_i2c_xfer(struct cros_ec_dev *dev, uchar chip, uint addr, - int alen, uchar *buffer, int len, int is_read) +int cros_ec_i2c_xfer_old(struct cros_ec_dev *dev, uchar chip, uint addr, + int alen, uchar *buffer, int len, int is_read) { union { struct ec_params_i2c_passthru p; @@ -1134,6 +1135,81 @@ int cros_ec_i2c_xfer(struct cros_ec_dev *dev, uchar chip, uint addr, return 0; }
+int cros_ec_i2c_tunnel(struct udevice *dev, struct i2c_msg *in, int nmsgs) +{ + struct cros_ec_dev *cdev = dev_get_uclass_priv(dev); + union { + struct ec_params_i2c_passthru p; + uint8_t outbuf[EC_PROTO2_MAX_PARAM_SIZE]; + } params; + union { + struct ec_response_i2c_passthru r; + uint8_t inbuf[EC_PROTO2_MAX_PARAM_SIZE]; + } response; + struct ec_params_i2c_passthru *p = ¶ms.p; + struct ec_response_i2c_passthru *r = &response.r; + struct ec_params_i2c_passthru_msg *msg; + uint8_t *pdata, *read_ptr = NULL; + int read_len; + int size; + int rv; + int i; + + p->port = 0; + + p->num_msgs = nmsgs; + size = sizeof(*p) + p->num_msgs * sizeof(*msg); + + /* Create a message to write the register address and optional data */ + pdata = (uint8_t *)p + size; + + read_len = 0; + for (i = 0, msg = p->msg; i < nmsgs; i++, msg++, in++) { + bool is_read = in->flags & I2C_M_RD; + + msg->addr_flags = in->addr; + msg->len = in->len; + if (is_read) { + msg->addr_flags |= EC_I2C_FLAG_READ; + read_len += in->len; + read_ptr = in->buf; + if (sizeof(*r) + read_len > sizeof(response)) { + puts("Read length too big for buffer\n"); + return -1; + } + } else { + if (pdata - (uint8_t *)p + in->len > sizeof(params)) { + puts("Params too large for buffer\n"); + return -1; + } + memcpy(pdata, in->buf, in->len); + pdata += in->len; + } + } + + rv = ec_command(cdev, EC_CMD_I2C_PASSTHRU, 0, p, pdata - (uint8_t *)p, + r, sizeof(*r) + read_len); + if (rv < 0) + return rv; + + /* Parse response */ + if (r->i2c_status & EC_I2C_STATUS_ERROR) { + printf("Transfer failed with status=0x%x\n", r->i2c_status); + return -1; + } + + if (rv < sizeof(*r) + read_len) { + puts("Truncated read response\n"); + return -1; + } + + /* We only support a single read message for each transfer */ + if (read_len) + memcpy(read_ptr, r->data, read_len); + + return 0; +} + #ifdef CONFIG_CMD_CROS_EC
/** @@ -1267,8 +1343,8 @@ static int cros_ec_i2c_md(struct cros_ec_dev *dev, int flag, int argc,
linebytes = (nbytes > DISP_LINE_LEN) ? DISP_LINE_LEN : nbytes;
- if (cros_ec_i2c_xfer(dev, chip, addr, alen, linebuf, linebytes, - 1)) + if (cros_ec_i2c_xfer_old(dev, chip, addr, alen, linebuf, + linebytes, 1)) puts("Error reading the chip.\n"); else { printf("%04x:", addr); @@ -1333,7 +1409,7 @@ static int cros_ec_i2c_mw(struct cros_ec_dev *dev, int flag, int argc, count = 1;
while (count-- > 0) { - if (cros_ec_i2c_xfer(dev, chip, addr++, alen, &byte, 1, 0)) + if (cros_ec_i2c_xfer_old(dev, chip, addr++, alen, &byte, 1, 0)) puts("Error writing the chip.\n"); /* * Wait for the write to complete. The write can take @@ -1633,6 +1709,12 @@ static int do_cros_ec(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) return ret; }
+int cros_ec_post_bind(struct udevice *dev) +{ + /* Scan for available EC devices (e.g. I2C tunnel) */ + return dm_scan_fdt_node(dev, gd->fdt_blob, dev->of_offset, false); +} + U_BOOT_CMD( crosec, 6, 1, do_cros_ec, "CROS-EC utility command", @@ -1661,4 +1743,5 @@ UCLASS_DRIVER(cros_ec) = { .id = UCLASS_CROS_EC, .name = "cros_ec", .per_device_auto_alloc_size = sizeof(struct cros_ec_dev), + .post_bind = cros_ec_post_bind, }; diff --git a/drivers/power/pmic/pmic_tps65090_ec.c b/drivers/power/pmic/pmic_tps65090_ec.c index ac0d44f..f79a878 100644 --- a/drivers/power/pmic/pmic_tps65090_ec.c +++ b/drivers/power/pmic/pmic_tps65090_ec.c @@ -56,8 +56,8 @@ enum { */ static int tps65090_read(u32 reg, u8 *val) { - return cros_ec_i2c_xfer(config.dev, TPS65090_ADDR, reg, 1, - val, 1, true); + return cros_ec_i2c_xfer_old(config.dev, TPS65090_ADDR, reg, 1, + val, 1, true); }
/** @@ -69,8 +69,8 @@ static int tps65090_read(u32 reg, u8 *val) */ static int tps65090_write(u32 reg, u8 val) { - return cros_ec_i2c_xfer(config.dev, TPS65090_ADDR, reg, 1, - &val, 1, false); + return cros_ec_i2c_xfer_old(config.dev, TPS65090_ADDR, reg, 1, + &val, 1, false); }
/** diff --git a/include/cros_ec.h b/include/cros_ec.h index 3b2be2c..41951c3 100644 --- a/include/cros_ec.h +++ b/include/cros_ec.h @@ -390,6 +390,16 @@ int cros_ec_decode_ec_flash(const void *blob, int node, */ void cros_ec_check_keyboard(struct cros_ec_dev *dev);
+struct i2c_msg; +/* + * Tunnel an I2C transfer to the EC + * + * @param dev CROS-EC device + * @param msg List of messages to transfer + * @param nmsgs Number of messages to transfer + */ +int cros_ec_i2c_tunnel(struct udevice *dev, struct i2c_msg *msg, int nmsgs); + /* * Tunnel an I2C transfer to the EC * @@ -401,7 +411,7 @@ void cros_ec_check_keyboard(struct cros_ec_dev *dev); * @param len Length of buffer * @param is_read 1 if this is a read, 0 if this is a write */ -int cros_ec_i2c_xfer(struct cros_ec_dev *dev, uchar chip, uint addr, - int alen, uchar *buffer, int len, int is_read); +int cros_ec_i2c_xfer_old(struct cros_ec_dev *dev, uchar chip, uint addr, + int alen, uchar *buffer, int len, int is_read);
#endif

On 3 August 2015 at 08:19, Simon Glass sjg@chromium.org wrote:
The Chrome OS EC supports tunnelling through to an I2C bus on the EC. This currently uses a copy of the I2C command code and a special 'crosec' sub-command.
With driver model we can define an I2C bus which tunnels through to the EC, and use the normal 'i2c' command to access it. This simplifies the code and removes some duplication.
Add an I2C driver which tunnels through to the EC. Adjust the EC code to support binding child devices so that it can be set up. Adjust the existing I2C xfer function to fit driver model better.
For now the old code remains to allow things to still work. It will be removed in a later patch once the new flow is fully enabled.
Signed-off-by: Simon Glass sjg@chromium.org
Changes in v2: None
configs/peach-pi_defconfig | 2 + configs/peach-pit_defconfig | 2 + drivers/i2c/Kconfig | 11 +++++ drivers/i2c/Makefile | 1 + drivers/i2c/cros_ec_tunnel.c | 41 +++++++++++++++ drivers/misc/cros_ec.c | 93 +++++++++++++++++++++++++++++++++-- drivers/power/pmic/pmic_tps65090_ec.c | 8 +-- include/cros_ec.h | 14 +++++- 8 files changed, 161 insertions(+), 11 deletions(-) create mode 100644 drivers/i2c/cros_ec_tunnel.c
Applied to u-boot-dm.

Add a driver to support the special LDO access used by spring. This is a custom method in the cros_ec protocol - it does not use an I2C pass-through.
There are two implementation choices:
1. Write a special LDO driver which can talk across the EC. Duplicate all the logic from TPS65090 for retrying when the LDO fails to come up.
2. Write a special I2C bus driver which pretends to be a TPS65090 and transfers reads and writes using the LDO message.
Either is distasteful. The latter method is chosen since it results in less code duplication and a fairly simple (30-line) implementation of the core logic.
The crosec 'ldo' subcommand could be removed (since i2c md/mw will work instead) but is retained as a convenience.
Signed-off-by: Simon Glass sjg@chromium.org ---
Changes in v2: None
drivers/i2c/Kconfig | 13 ++++++++ drivers/i2c/Makefile | 1 + drivers/i2c/cros_ec_ldo.c | 77 +++++++++++++++++++++++++++++++++++++++++++++++ drivers/misc/cros_ec.c | 21 +++++++------ include/cros_ec.h | 4 +-- 5 files changed, 104 insertions(+), 12 deletions(-) create mode 100644 drivers/i2c/cros_ec_ldo.c
diff --git a/drivers/i2c/Kconfig b/drivers/i2c/Kconfig index e861b53..9a62ddd 100644 --- a/drivers/i2c/Kconfig +++ b/drivers/i2c/Kconfig @@ -29,6 +29,19 @@ config I2C_CROS_EC_TUNNEL I2C or LPC). Some Chromebooks use this when the hardware design does not allow direct access to the main PMIC from the AP.
+config I2C_CROS_EC_LDO + bool "Provide access to LDOs on the Chrome OS EC" + depends on CROS_EC + ---help--- + On many Chromebooks the main PMIC is inaccessible to the AP. This is + often dealt with by using an I2C pass-through interface provided by + the EC. On some unfortunate models (e.g. Spring) the pass-through + is not available, and an LDO message is available instead. This + option enables a driver which provides very basic access to those + regulators, via the EC. We implement this as an I2C bus which + emulates just the TPS65090 messages we know about. This is done to + avoid duplicating the logic in the TPS65090 regulator driver for + enabling/disabling an LDO.
config DM_I2C_GPIO bool "Enable Driver Model for software emulated I2C bus driver" diff --git a/drivers/i2c/Makefile b/drivers/i2c/Makefile index 7f01fce..9b45248 100644 --- a/drivers/i2c/Makefile +++ b/drivers/i2c/Makefile @@ -8,6 +8,7 @@ obj-$(CONFIG_DM_I2C) += i2c-uclass.o obj-$(CONFIG_DM_I2C_COMPAT) += i2c-uclass-compat.o obj-$(CONFIG_DM_I2C_GPIO) += i2c-gpio.o obj-$(CONFIG_I2C_CROS_EC_TUNNEL) += cros_ec_tunnel.o +obj-$(CONFIG_I2C_CROS_EC_LDO) += cros_ec_ldo.o
obj-$(CONFIG_SYS_I2C_ADI) += adi_i2c.o obj-$(CONFIG_I2C_MV) += mv_i2c.o diff --git a/drivers/i2c/cros_ec_ldo.c b/drivers/i2c/cros_ec_ldo.c new file mode 100644 index 0000000..b817c61 --- /dev/null +++ b/drivers/i2c/cros_ec_ldo.c @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2015 Google, Inc + * Written by Simon Glass sjg@chromium.org + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <dm.h> +#include <cros_ec.h> +#include <errno.h> +#include <i2c.h> +#include <power/tps65090.h> + +static int cros_ec_ldo_set_bus_speed(struct udevice *dev, unsigned int speed) +{ + return 0; +} + +static int cros_ec_ldo_xfer(struct udevice *dev, struct i2c_msg *msg, + int nmsgs) +{ + bool is_read = nmsgs > 1; + int fet_id, ret; + + /* + * Look for reads and writes of the LDO registers. In either case the + * first message is a write with the register number as the first byte. + */ + if (!nmsgs || !msg->len || (msg->flags & I2C_M_RD)) { + debug("%s: Invalid message\n", __func__); + goto err; + } + + fet_id = msg->buf[0] - REG_FET_BASE; + if (fet_id < 1 || fet_id > MAX_FET_NUM) { + debug("%s: Invalid FET %d\n", __func__, fet_id); + goto err; + } + + if (is_read) { + uint8_t state; + + ret = cros_ec_get_ldo(dev->parent, fet_id, &state); + if (!ret) + msg[1].buf[0] = state ? + FET_CTRL_ENFET | FET_CTRL_PGFET : 0; + } else { + bool on = msg->buf[1] & FET_CTRL_ENFET; + + ret = cros_ec_set_ldo(dev->parent, fet_id, on); + } + + return ret; + +err: + /* Indicate that the message is unimplemented */ + return -ENOSYS; +} + +static const struct dm_i2c_ops cros_ec_i2c_ops = { + .xfer = cros_ec_ldo_xfer, + .set_bus_speed = cros_ec_ldo_set_bus_speed, +}; + +static const struct udevice_id cros_ec_i2c_ids[] = { + { .compatible = "google,cros-ec-ldo-tunnel" }, + { } +}; + +U_BOOT_DRIVER(cros_ec_ldo) = { + .name = "cros_ec_ldo_tunnel", + .id = UCLASS_I2C, + .of_match = cros_ec_i2c_ids, + .per_child_auto_alloc_size = sizeof(struct dm_i2c_chip), + .ops = &cros_ec_i2c_ops, +}; diff --git a/drivers/misc/cros_ec.c b/drivers/misc/cros_ec.c index ae52561..6027177 100644 --- a/drivers/misc/cros_ec.c +++ b/drivers/misc/cros_ec.c @@ -931,31 +931,32 @@ int cros_ec_write_vbnvcontext(struct cros_ec_dev *dev, const uint8_t *block) return 0; }
-int cros_ec_set_ldo(struct cros_ec_dev *dev, uint8_t index, uint8_t state) +int cros_ec_set_ldo(struct udevice *dev, uint8_t index, uint8_t state) { + struct cros_ec_dev *cdev = dev_get_uclass_priv(dev); struct ec_params_ldo_set params;
params.index = index; params.state = state;
- if (ec_command_inptr(dev, EC_CMD_LDO_SET, 0, - ¶ms, sizeof(params), - NULL, 0)) + if (ec_command_inptr(cdev, EC_CMD_LDO_SET, 0, ¶ms, sizeof(params), + NULL, 0)) return -1;
return 0; }
-int cros_ec_get_ldo(struct cros_ec_dev *dev, uint8_t index, uint8_t *state) +int cros_ec_get_ldo(struct udevice *dev, uint8_t index, uint8_t *state) { + struct cros_ec_dev *cdev = dev_get_uclass_priv(dev); struct ec_params_ldo_get params; struct ec_response_ldo_get *resp;
params.index = index;
- if (ec_command_inptr(dev, EC_CMD_LDO_GET, 0, - ¶ms, sizeof(params), - (uint8_t **)&resp, sizeof(*resp)) != sizeof(*resp)) + if (ec_command_inptr(cdev, EC_CMD_LDO_GET, 0, ¶ms, sizeof(params), + (uint8_t **)&resp, sizeof(*resp)) != + sizeof(*resp)) return -1;
*state = resp->state; @@ -1681,9 +1682,9 @@ static int do_cros_ec(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) state = simple_strtoul(argv[3], &endp, 10); if (*argv[3] == 0 || *endp != 0) return CMD_RET_USAGE; - ret = cros_ec_set_ldo(dev, index, state); + ret = cros_ec_set_ldo(udev, index, state); } else { - ret = cros_ec_get_ldo(dev, index, &state); + ret = cros_ec_get_ldo(udev, index, &state); if (!ret) { printf("LDO%d: %s\n", index, state == EC_LDO_STATE_ON ? diff --git a/include/cros_ec.h b/include/cros_ec.h index 41951c3..0ad9d81 100644 --- a/include/cros_ec.h +++ b/include/cros_ec.h @@ -350,7 +350,7 @@ int cros_ec_read_build_info(struct cros_ec_dev *dev, char **strp); * @param state new state of the LDO/FET : EC_LDO_STATE_ON|OFF * @return 0 if ok, -1 on error */ -int cros_ec_set_ldo(struct cros_ec_dev *dev, uint8_t index, uint8_t state); +int cros_ec_set_ldo(struct udevice *dev, uint8_t index, uint8_t state);
/** * Read back a LDO / FET current state. @@ -360,7 +360,7 @@ int cros_ec_set_ldo(struct cros_ec_dev *dev, uint8_t index, uint8_t state); * @param state current state of the LDO/FET : EC_LDO_STATE_ON|OFF * @return 0 if ok, -1 on error */ -int cros_ec_get_ldo(struct cros_ec_dev *dev, uint8_t index, uint8_t *state); +int cros_ec_get_ldo(struct udevice *dev, uint8_t index, uint8_t *state);
/** * Get access to the error reported when cros_ec_board_init() was called

On 3 August 2015 at 08:19, Simon Glass sjg@chromium.org wrote:
Add a driver to support the special LDO access used by spring. This is a custom method in the cros_ec protocol - it does not use an I2C pass-through.
There are two implementation choices:
- Write a special LDO driver which can talk across the EC. Duplicate all
the logic from TPS65090 for retrying when the LDO fails to come up.
- Write a special I2C bus driver which pretends to be a TPS65090 and
transfers reads and writes using the LDO message.
Either is distasteful. The latter method is chosen since it results in less code duplication and a fairly simple (30-line) implementation of the core logic.
The crosec 'ldo' subcommand could be removed (since i2c md/mw will work instead) but is retained as a convenience.
Signed-off-by: Simon Glass sjg@chromium.org
Changes in v2: None
drivers/i2c/Kconfig | 13 ++++++++ drivers/i2c/Makefile | 1 + drivers/i2c/cros_ec_ldo.c | 77 +++++++++++++++++++++++++++++++++++++++++++++++ drivers/misc/cros_ec.c | 21 +++++++------ include/cros_ec.h | 4 +-- 5 files changed, 104 insertions(+), 12 deletions(-) create mode 100644 drivers/i2c/cros_ec_ldo.c
Applied to u-boot-dm.

Add support for all BUCK regulators, now that the correct register is accessed for each.
Signed-off-by: Simon Glass sjg@chromium.org ---
Changes in v2: - Add a comment about DVS in the driver
drivers/power/regulator/max77686.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-)
diff --git a/drivers/power/regulator/max77686.c b/drivers/power/regulator/max77686.c index 21173fc..946b87c 100644 --- a/drivers/power/regulator/max77686.c +++ b/drivers/power/regulator/max77686.c @@ -81,13 +81,15 @@ static int max77686_buck_volt2hex(int buck, int uV) /* hex = (uV - 600000) / 12500; */ hex = (uV - MAX77686_BUCK_UV_LMIN) / MAX77686_BUCK_UV_LSTEP; hex_max = MAX77686_BUCK234_VOLT_MAX_HEX; - /** - * Those use voltage scaller - temporary not implemented - * so return just 0 - */ - return -ENOSYS; + break; default: - /* hex = (uV - 750000) / 50000; */ + /* + * hex = (uV - 750000) / 50000. We assume that dynamic voltage + * scaling via GPIOs is not enabled and don't support that. + * If this is enabled then the driver will need to take that + * into account anrd check different registers depending on + * the current setting See the datasheet for details. + */ hex = (uV - MAX77686_BUCK_UV_HMIN) / MAX77686_BUCK_UV_HSTEP; hex_max = MAX77686_BUCK_VOLT_MAX_HEX; break; @@ -379,11 +381,11 @@ static int max77686_buck_val(struct udevice *dev, int op, int *uV) case 2: case 3: case 4: - /* Those use voltage scallers - will support in the future */ mask = MAX77686_BUCK234_VOLT_MASK; - return -ENOSYS; + break; default: mask = MAX77686_BUCK_VOLT_MASK; + break; }
ret = pmic_read(dev->parent, adr, &val, 1);

Hello Simon,
On 08/03/2015 04:19 PM, Simon Glass wrote:
Add support for all BUCK regulators, now that the correct register is accessed for each.
Signed-off-by: Simon Glass sjg@chromium.org
Changes in v2:
Add a comment about DVS in the driver
drivers/power/regulator/max77686.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-)
diff --git a/drivers/power/regulator/max77686.c b/drivers/power/regulator/max77686.c index 21173fc..946b87c 100644 --- a/drivers/power/regulator/max77686.c +++ b/drivers/power/regulator/max77686.c @@ -81,13 +81,15 @@ static int max77686_buck_volt2hex(int buck, int uV) /* hex = (uV - 600000) / 12500; */ hex = (uV - MAX77686_BUCK_UV_LMIN) / MAX77686_BUCK_UV_LSTEP; hex_max = MAX77686_BUCK234_VOLT_MAX_HEX;
/**
* Those use voltage scaller - temporary not implemented
* so return just 0
*/
return -ENOSYS;
default:break;
/* hex = (uV - 750000) / 50000; */
/*
* hex = (uV - 750000) / 50000. We assume that dynamic voltage
* scaling via GPIOs is not enabled and don't support that.
* If this is enabled then the driver will need to take that
* into account anrd check different registers depending on
and check
* the current setting See the datasheet for details.
setting. See
... snip ...
Best regards,

On 3 August 2015 at 08:19, Simon Glass sjg@chromium.org wrote:
Add support for all BUCK regulators, now that the correct register is accessed for each.
Signed-off-by: Simon Glass sjg@chromium.org
Changes in v2:
- Add a comment about DVS in the driver
drivers/power/regulator/max77686.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-)
Applied to u-boot-dm.

While the AP can access the main PMIC on snow, it must coordinate with the EC which also wants access. Drop the old definition, which can in principle generate collision errors. We will use the new arbitration driver instead.
Signed-off-by: Simon Glass sjg@chromium.org ---
Changes in v2: None
arch/arm/dts/exynos5250-snow.dts | 16 ---------------- 1 file changed, 16 deletions(-)
diff --git a/arch/arm/dts/exynos5250-snow.dts b/arch/arm/dts/exynos5250-snow.dts index 334a5af..32c0098 100644 --- a/arch/arm/dts/exynos5250-snow.dts +++ b/arch/arm/dts/exynos5250-snow.dts @@ -95,22 +95,6 @@ }; };
- - i2c4: i2c@12CA0000 { - cros_ec_old: cros-ec@1e { - reg = <0x1e>; - compatible = "google,cros-ec-i2c"; - i2c-max-frequency = <100000>; - u-boot,i2c-offset-len = <0>; - ec-interrupt = <&gpx1 6 GPIO_ACTIVE_LOW>; - }; - - power-regulator@48 { - compatible = "ti,tps65090"; - reg = <0x48>; - }; - }; - i2c-arbitrator { compatible = "i2c-arb-gpio-challenge"; #address-cells = <1>;

On 3 August 2015 at 08:19, Simon Glass sjg@chromium.org wrote:
While the AP can access the main PMIC on snow, it must coordinate with the EC which also wants access. Drop the old definition, which can in principle generate collision errors. We will use the new arbitration driver instead.
Signed-off-by: Simon Glass sjg@chromium.org
Changes in v2: None
arch/arm/dts/exynos5250-snow.dts | 16 ---------------- 1 file changed, 16 deletions(-)
Applied to u-boot-dm.

Some boards use device tree for almost all board-specific configuration. They therefore do not need their own separate board code, but can all use the same version. Add a common version of the board code. It uses the PMIC, regulator and video bridge uclasses. This will support smdk5250, smdk5420, snow, spring, pit and pi.
Signed-off-by: Simon Glass sjg@chromium.org ---
Changes in v2: None
board/samsung/common/Makefile | 1 + board/samsung/common/exynos5-dt.c | 362 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 363 insertions(+) create mode 100644 board/samsung/common/exynos5-dt.c
diff --git a/board/samsung/common/Makefile b/board/samsung/common/Makefile index 5fb01ce..6cbd906 100644 --- a/board/samsung/common/Makefile +++ b/board/samsung/common/Makefile @@ -11,4 +11,5 @@ obj-$(CONFIG_MISC_COMMON) += misc.o
ifndef CONFIG_SPL_BUILD obj-$(CONFIG_BOARD_COMMON) += board.o +obj-$(CONFIG_EXYNOS5_DT) += exynos5-dt.o endif diff --git a/board/samsung/common/exynos5-dt.c b/board/samsung/common/exynos5-dt.c new file mode 100644 index 0000000..7d1b88a --- /dev/null +++ b/board/samsung/common/exynos5-dt.c @@ -0,0 +1,362 @@ +/* + * Copyright (C) 2012 Samsung Electronics + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <dm.h> +#include <dwc3-uboot.h> +#include <fdtdec.h> +#include <asm/io.h> +#include <errno.h> +#include <i2c.h> +#include <mmc.h> +#include <netdev.h> +#include <samsung-usb-phy-uboot.h> +#include <spi.h> +#include <usb.h> +#include <video_bridge.h> +#include <asm/gpio.h> +#include <asm/arch/cpu.h> +#include <asm/arch/dwmmc.h> +#include <asm/arch/mmc.h> +#include <asm/arch/pinmux.h> +#include <asm/arch/power.h> +#include <asm/arch/sromc.h> +#include <power/pmic.h> +#include <power/max77686_pmic.h> +#include <power/regulator.h> +#include <power/s5m8767.h> +#include <tmu.h> + +DECLARE_GLOBAL_DATA_PTR; + +static void board_enable_audio_codec(void) +{ + int node, ret; + struct gpio_desc en_gpio; + + node = fdtdec_next_compatible(gd->fdt_blob, 0, + COMPAT_SAMSUNG_EXYNOS5_SOUND); + if (node <= 0) + return; + + ret = gpio_request_by_name_nodev(gd->fdt_blob, node, + "codec-enable-gpio", 0, &en_gpio, + GPIOD_IS_OUT | GPIOD_IS_OUT_ACTIVE); + if (ret == -FDT_ERR_NOTFOUND) + return; + + /* Turn on the GPIO which connects to the codec's "enable" line. */ + gpio_set_pull(gpio_get_number(&en_gpio), S5P_GPIO_PULL_NONE); + +#ifdef CONFIG_SOUND_MAX98095 + /* Enable MAX98095 Codec */ + gpio_request(EXYNOS5_GPIO_X17, "max98095_enable"); + gpio_direction_output(EXYNOS5_GPIO_X17, 1); + gpio_set_pull(EXYNOS5_GPIO_X17, S5P_GPIO_PULL_NONE); +#endif +} + +int exynos_init(void) +{ + board_enable_audio_codec(); + + return 0; +} + +static int exynos_set_regulator(const char *name, uint uv) +{ + struct udevice *dev; + int ret; + + ret = regulator_get_by_platname(name, &dev); + if (ret) { + debug("%s: Cannot find regulator %s\n", __func__, name); + return ret; + } + ret = regulator_set_value(dev, uv); + if (ret) { + debug("%s: Cannot set regulator %s\n", __func__, name); + return ret; + } + + return 0; +} + +int exynos_power_init(void) +{ + struct udevice *dev; + int ret; + + ret = pmic_get("max77686", &dev); + if (!ret) { + /* TODO(sjg@chromium.org): Move into the clock/pmic API */ + ret = pmic_clrsetbits(dev, MAX77686_REG_PMIC_32KHZ, 0, + MAX77686_32KHCP_EN); + if (ret) + return ret; + ret = pmic_clrsetbits(dev, MAX77686_REG_PMIC_BBAT, 0, + MAX77686_BBCHOSTEN | MAX77686_BBCVS_3_5V); + if (ret) + return ret; + } else { + ret = pmic_get("s5m8767-pmic", &dev); + /* TODO(sjg@chromium.org): Use driver model to access clock */ +#ifdef CONFIG_PMIC_S5M8767 + if (!ret) + s5m8767_enable_32khz_cp(dev); +#endif + } + if (ret == -ENODEV) + return 0; + + ret = regulators_enable_boot_on(false); + if (ret) + return ret; + + ret = exynos_set_regulator("vdd_mif", 1100000); + if (ret) + return ret; + + /* + * This would normally be 1.3V, but since we are running slowly 1V + * is enough. For spring it helps reduce CPU temperature and avoid + * hangs with the case open. + */ + ret = exynos_set_regulator("vdd_arm", 1000000); + if (ret) + return ret; + ret = exynos_set_regulator("vdd_int", 1012500); + if (ret) + return ret; + ret = exynos_set_regulator("vdd_g3d", 1200000); + if (ret) + return ret; + + return 0; +} + +int board_get_revision(void) +{ + return 0; +} + +#ifdef CONFIG_LCD + +static int board_dp_bridge_init(struct udevice *dev) +{ + const int max_tries = 10; + int num_tries; + int ret; + + debug("%s\n", __func__); + ret = video_bridge_attach(dev); + if (ret) { + debug("video bridge init failed: %d\n", ret); + return ret; + } + + /* + * We need to wait for 90ms after bringing up the bridge since there + * is a phantom "high" on the HPD chip during its bootup. The phantom + * high comes within 7ms of de-asserting PD and persists for at least + * 15ms. The real high comes roughly 50ms after PD is de-asserted. The + * phantom high makes it hard for us to know when the NXP chip is up. + */ + mdelay(90); + + for (num_tries = 0; num_tries < max_tries; num_tries++) { + /* Check HPD. If it's high, or we don't have it, all is well */ + ret = video_bridge_check_attached(dev); + if (!ret || ret == -ENOENT) + return 0; + + debug("%s: eDP bridge failed to come up; try %d of %d\n", + __func__, num_tries, max_tries); + } + + /* Immediately go into bridge reset if the hp line is not high */ + return -EIO; +} + +static int board_dp_bridge_setup(const void *blob) +{ + const int max_tries = 2; + int num_tries; + struct udevice *dev; + int ret; + + /* Configure I2C registers for Parade bridge */ + ret = uclass_get_device(UCLASS_VIDEO_BRIDGE, 0, &dev); + if (ret) { + debug("video bridge init failed: %d\n", ret); + return ret; + } + + if (strncmp(dev->driver->name, "parade", 6)) { + /* Mux HPHPD to the special hotplug detect mode */ + exynos_pinmux_config(PERIPH_ID_DPHPD, 0); + } + + for (num_tries = 0; num_tries < max_tries; num_tries++) { + ret = board_dp_bridge_init(dev); + if (!ret) + return 0; + if (num_tries == max_tries - 1) + break; + + /* + * If we're here, the bridge chip failed to initialise. + * Power down the bridge in an attempt to reset. + */ + video_bridge_set_active(dev, false); + + /* + * Arbitrarily wait 300ms here with DP_N low. Don't know for + * sure how long we should wait, but we're being paranoid. + */ + mdelay(300); + } + + return ret; +} + +void exynos_cfg_lcd_gpio(void) +{ + /* For Backlight */ + gpio_request(EXYNOS5_GPIO_B20, "lcd_backlight"); + gpio_cfg_pin(EXYNOS5_GPIO_B20, S5P_GPIO_OUTPUT); + gpio_set_value(EXYNOS5_GPIO_B20, 1); +} + +void exynos_set_dp_phy(unsigned int onoff) +{ + set_dp_phy_ctrl(onoff); +} + +static int board_dp_set_backlight(int percent) +{ + struct udevice *dev; + int ret; + + ret = uclass_get_device(UCLASS_VIDEO_BRIDGE, 0, &dev); + if (!ret) + ret = video_bridge_set_backlight(dev, percent); + + return ret; +} + +void exynos_backlight_on(unsigned int on) +{ + struct udevice *dev; + int ret; + + debug("%s(%u)\n", __func__, on); + if (!on) + return; + + ret = regulator_get_by_platname("vcd_led", &dev); + if (!ret) + ret = regulator_set_enable(dev, true); + if (ret) + debug("Failed to enable backlight: ret=%d\n", ret); + + /* T5 in the LCD timing spec (defined as > 10ms) */ + mdelay(10); + + /* board_dp_backlight_pwm */ + gpio_direction_output(EXYNOS5_GPIO_B20, 1); + + /* T6 in the LCD timing spec (defined as > 10ms) */ + mdelay(10); + + /* try to set the backlight in the bridge registers */ + ret = board_dp_set_backlight(80); + + /* if we have no bridge or it does not support backlight, use a GPIO */ + if (ret == -ENODEV || ret == -ENOSYS) { + gpio_request(EXYNOS5_GPIO_X30, "board_dp_backlight_en"); + gpio_direction_output(EXYNOS5_GPIO_X30, 1); + } +} + +void exynos_lcd_power_on(void) +{ + struct udevice *dev; + int ret; + + debug("%s\n", __func__); + ret = regulator_get_by_platname("lcd_vdd", &dev); + if (!ret) + ret = regulator_set_enable(dev, true); + if (ret) + debug("Failed to enable LCD panel: ret=%d\n", ret); + + ret = board_dp_bridge_setup(gd->fdt_blob); + if (ret && ret != -ENODEV) + printf("LCD bridge failed to enable: %d\n", ret); +} + +#endif + +#ifdef CONFIG_USB_DWC3 +static struct dwc3_device dwc3_device_data = { + .maximum_speed = USB_SPEED_SUPER, + .base = 0x12400000, + .dr_mode = USB_DR_MODE_PERIPHERAL, + .index = 0, +}; + +int usb_gadget_handle_interrupts(void) +{ + dwc3_uboot_handle_interrupt(0); + return 0; +} + +int board_usb_init(int index, enum usb_init_type init) +{ + struct exynos_usb3_phy *phy = (struct exynos_usb3_phy *) + samsung_get_base_usb3_phy(); + + if (!phy) { + error("usb3 phy not supported"); + return -ENODEV; + } + + set_usbdrd_phy_ctrl(POWER_USB_DRD_PHY_CTRL_EN); + exynos5_usb3_phy_init(phy); + + return dwc3_uboot_init(&dwc3_device_data); +} +#endif +#ifdef CONFIG_SET_DFU_ALT_INFO +char *get_dfu_alt_system(char *interface, char *devstr) +{ + return getenv("dfu_alt_system"); +} + +char *get_dfu_alt_boot(char *interface, char *devstr) +{ + struct mmc *mmc; + char *alt_boot; + int dev_num; + + dev_num = simple_strtoul(devstr, NULL, 10); + + mmc = find_mmc_device(dev_num); + if (!mmc) + return NULL; + + if (mmc_init(mmc)) + return NULL; + + if (IS_SD(mmc)) + alt_boot = CONFIG_DFU_ALT_BOOT_SD; + else + alt_boot = CONFIG_DFU_ALT_BOOT_EMMC; + + return alt_boot; +} +#endif

Hello Simon,
On 08/03/2015 04:19 PM, Simon Glass wrote:
Some boards use device tree for almost all board-specific configuration. They therefore do not need their own separate board code, but can all use the same version. Add a common version of the board code. It uses the PMIC, regulator and video bridge uclasses. This will support smdk5250, smdk5420, snow, spring, pit and pi.
Signed-off-by: Simon Glass sjg@chromium.org
Changes in v2: None
board/samsung/common/Makefile | 1 + board/samsung/common/exynos5-dt.c | 362 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 363 insertions(+) create mode 100644 board/samsung/common/exynos5-dt.c
diff --git a/board/samsung/common/Makefile b/board/samsung/common/Makefile index 5fb01ce..6cbd906 100644 --- a/board/samsung/common/Makefile +++ b/board/samsung/common/Makefile @@ -11,4 +11,5 @@ obj-$(CONFIG_MISC_COMMON) += misc.o
ifndef CONFIG_SPL_BUILD obj-$(CONFIG_BOARD_COMMON) += board.o +obj-$(CONFIG_EXYNOS5_DT) += exynos5-dt.o endif diff --git a/board/samsung/common/exynos5-dt.c b/board/samsung/common/exynos5-dt.c new file mode 100644 index 0000000..7d1b88a --- /dev/null +++ b/board/samsung/common/exynos5-dt.c @@ -0,0 +1,362 @@ +/*
- Copyright (C) 2012 Samsung Electronics
- SPDX-License-Identifier: GPL-2.0+
- */
+#include <common.h> +#include <dm.h> +#include <dwc3-uboot.h> +#include <fdtdec.h> +#include <asm/io.h> +#include <errno.h> +#include <i2c.h> +#include <mmc.h> +#include <netdev.h> +#include <samsung-usb-phy-uboot.h> +#include <spi.h> +#include <usb.h> +#include <video_bridge.h> +#include <asm/gpio.h> +#include <asm/arch/cpu.h> +#include <asm/arch/dwmmc.h> +#include <asm/arch/mmc.h> +#include <asm/arch/pinmux.h> +#include <asm/arch/power.h> +#include <asm/arch/sromc.h> +#include <power/pmic.h> +#include <power/max77686_pmic.h> +#include <power/regulator.h> +#include <power/s5m8767.h> +#include <tmu.h>
+DECLARE_GLOBAL_DATA_PTR;
+static void board_enable_audio_codec(void) +{
- int node, ret;
- struct gpio_desc en_gpio;
- node = fdtdec_next_compatible(gd->fdt_blob, 0,
COMPAT_SAMSUNG_EXYNOS5_SOUND);
- if (node <= 0)
return;
- ret = gpio_request_by_name_nodev(gd->fdt_blob, node,
"codec-enable-gpio", 0, &en_gpio,
GPIOD_IS_OUT | GPIOD_IS_OUT_ACTIVE);
- if (ret == -FDT_ERR_NOTFOUND)
return;
- /* Turn on the GPIO which connects to the codec's "enable" line. */
- gpio_set_pull(gpio_get_number(&en_gpio), S5P_GPIO_PULL_NONE);
+#ifdef CONFIG_SOUND_MAX98095
- /* Enable MAX98095 Codec */
- gpio_request(EXYNOS5_GPIO_X17, "max98095_enable");
- gpio_direction_output(EXYNOS5_GPIO_X17, 1);
- gpio_set_pull(EXYNOS5_GPIO_X17, S5P_GPIO_PULL_NONE);
+#endif +}
+int exynos_init(void) +{
- board_enable_audio_codec();
- return 0;
+}
+static int exynos_set_regulator(const char *name, uint uv) +{
- struct udevice *dev;
- int ret;
- ret = regulator_get_by_platname(name, &dev);
- if (ret) {
debug("%s: Cannot find regulator %s\n", __func__, name);
return ret;
- }
- ret = regulator_set_value(dev, uv);
- if (ret) {
debug("%s: Cannot set regulator %s\n", __func__, name);
return ret;
- }
- return 0;
+}
+int exynos_power_init(void) +{
- struct udevice *dev;
- int ret;
- ret = pmic_get("max77686", &dev);
- if (!ret) {
/* TODO(sjg@chromium.org): Move into the clock/pmic API */
ret = pmic_clrsetbits(dev, MAX77686_REG_PMIC_32KHZ, 0,
MAX77686_32KHCP_EN);
if (ret)
return ret;
ret = pmic_clrsetbits(dev, MAX77686_REG_PMIC_BBAT, 0,
MAX77686_BBCHOSTEN | MAX77686_BBCVS_3_5V);
if (ret)
return ret;
- } else {
ret = pmic_get("s5m8767-pmic", &dev);
/* TODO(sjg@chromium.org): Use driver model to access clock */
+#ifdef CONFIG_PMIC_S5M8767
What about: "if (dev)" or "if (!ret && dev)", instead of #ifdef?
if (!ret)
s5m8767_enable_32khz_cp(dev);
+#endif
... snip ...
Best regards

Hi Prazemyslaw,
On 5 August 2015 at 08:16, Przemyslaw Marczak p.marczak@samsung.com wrote:
Hello Simon,
On 08/03/2015 04:19 PM, Simon Glass wrote:
Some boards use device tree for almost all board-specific configuration. They therefore do not need their own separate board code, but can all use the same version. Add a common version of the board code. It uses the PMIC, regulator and video bridge uclasses. This will support smdk5250, smdk5420, snow, spring, pit and pi.
Signed-off-by: Simon Glass sjg@chromium.org
Changes in v2: None
board/samsung/common/Makefile | 1 + board/samsung/common/exynos5-dt.c | 362 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 363 insertions(+) create mode 100644 board/samsung/common/exynos5-dt.c
diff --git a/board/samsung/common/Makefile b/board/samsung/common/Makefile index 5fb01ce..6cbd906 100644 --- a/board/samsung/common/Makefile +++ b/board/samsung/common/Makefile @@ -11,4 +11,5 @@ obj-$(CONFIG_MISC_COMMON) += misc.o
ifndef CONFIG_SPL_BUILD obj-$(CONFIG_BOARD_COMMON) += board.o +obj-$(CONFIG_EXYNOS5_DT) += exynos5-dt.o endif diff --git a/board/samsung/common/exynos5-dt.c b/board/samsung/common/exynos5-dt.c new file mode 100644 index 0000000..7d1b88a --- /dev/null +++ b/board/samsung/common/exynos5-dt.c @@ -0,0 +1,362 @@ +/*
- Copyright (C) 2012 Samsung Electronics
- SPDX-License-Identifier: GPL-2.0+
- */
+#include <common.h> +#include <dm.h> +#include <dwc3-uboot.h> +#include <fdtdec.h> +#include <asm/io.h> +#include <errno.h> +#include <i2c.h> +#include <mmc.h> +#include <netdev.h> +#include <samsung-usb-phy-uboot.h> +#include <spi.h> +#include <usb.h> +#include <video_bridge.h> +#include <asm/gpio.h> +#include <asm/arch/cpu.h> +#include <asm/arch/dwmmc.h> +#include <asm/arch/mmc.h> +#include <asm/arch/pinmux.h> +#include <asm/arch/power.h> +#include <asm/arch/sromc.h> +#include <power/pmic.h> +#include <power/max77686_pmic.h> +#include <power/regulator.h> +#include <power/s5m8767.h> +#include <tmu.h>
+DECLARE_GLOBAL_DATA_PTR;
+static void board_enable_audio_codec(void) +{
int node, ret;
struct gpio_desc en_gpio;
node = fdtdec_next_compatible(gd->fdt_blob, 0,
COMPAT_SAMSUNG_EXYNOS5_SOUND);
if (node <= 0)
return;
ret = gpio_request_by_name_nodev(gd->fdt_blob, node,
"codec-enable-gpio", 0, &en_gpio,
GPIOD_IS_OUT |
GPIOD_IS_OUT_ACTIVE);
if (ret == -FDT_ERR_NOTFOUND)
return;
/* Turn on the GPIO which connects to the codec's "enable" line.
*/
gpio_set_pull(gpio_get_number(&en_gpio), S5P_GPIO_PULL_NONE);
+#ifdef CONFIG_SOUND_MAX98095
/* Enable MAX98095 Codec */
gpio_request(EXYNOS5_GPIO_X17, "max98095_enable");
gpio_direction_output(EXYNOS5_GPIO_X17, 1);
gpio_set_pull(EXYNOS5_GPIO_X17, S5P_GPIO_PULL_NONE);
+#endif +}
+int exynos_init(void) +{
board_enable_audio_codec();
return 0;
+}
+static int exynos_set_regulator(const char *name, uint uv) +{
struct udevice *dev;
int ret;
ret = regulator_get_by_platname(name, &dev);
if (ret) {
debug("%s: Cannot find regulator %s\n", __func__, name);
return ret;
}
ret = regulator_set_value(dev, uv);
if (ret) {
debug("%s: Cannot set regulator %s\n", __func__, name);
return ret;
}
return 0;
+}
+int exynos_power_init(void) +{
struct udevice *dev;
int ret;
ret = pmic_get("max77686", &dev);
if (!ret) {
/* TODO(sjg@chromium.org): Move into the clock/pmic API */
ret = pmic_clrsetbits(dev, MAX77686_REG_PMIC_32KHZ, 0,
MAX77686_32KHCP_EN);
if (ret)
return ret;
ret = pmic_clrsetbits(dev, MAX77686_REG_PMIC_BBAT, 0,
MAX77686_BBCHOSTEN | MAX77686_BBCVS_3_5V);
if (ret)
return ret;
} else {
ret = pmic_get("s5m8767-pmic", &dev);
/* TODO(sjg@chromium.org): Use driver model to access
clock */ +#ifdef CONFIG_PMIC_S5M8767
What about: "if (dev)" or "if (!ret && dev)", instead of #ifdef?
if (!ret)
s5m8767_enable_32khz_cp(dev);
+#endif
Unfortunately s5m8767_enable_32khz_cp() doesn't go through driver model so we can't call it if it is not compiled in. The correct fix would be to add a clock device as a child of the PMIC and set that up with the clock uclass. Later.
Applied to u-boot-dm.
Regards, Simon

Enable PMICs, regulators and the like so that new drivers will be made available.
Signed-off-by: Simon Glass sjg@chromium.org ---
Changes in v2: None
board/samsung/smdk5420/smdk5420.c | 2 +- configs/arndale_defconfig | 2 ++ configs/odroid-xu3_defconfig | 6 ++++++ configs/peach-pi_defconfig | 17 +++++++++++++++++ configs/peach-pit_defconfig | 17 +++++++++++++++++ configs/smdk5250_defconfig | 10 ++++++++++ configs/smdk5420_defconfig | 6 ++++++ configs/snow_defconfig | 23 +++++++++++++++++++++++ include/configs/arndale.h | 4 ++++ include/configs/exynos5-common.h | 10 ++-------- include/configs/exynos5-dt-common.h | 5 ----- include/configs/smdk5250.h | 3 --- include/configs/snow.h | 3 --- 13 files changed, 88 insertions(+), 20 deletions(-)
diff --git a/board/samsung/smdk5420/smdk5420.c b/board/samsung/smdk5420/smdk5420.c index 88f4044..57cc92c 100644 --- a/board/samsung/smdk5420/smdk5420.c +++ b/board/samsung/smdk5420/smdk5420.c @@ -50,9 +50,9 @@ static int has_edp_bridge(void)
void exynos_lcd_power_on(void) { +#ifdef CONFIG_POWER_TPS65090 int ret;
-#ifdef CONFIG_POWER_TPS65090 ret = tps65090_init(); if (ret < 0) { printf("%s: tps65090_init() failed\n", __func__); diff --git a/configs/arndale_defconfig b/configs/arndale_defconfig index aa489cf..ebac9ad 100644 --- a/configs/arndale_defconfig +++ b/configs/arndale_defconfig @@ -13,3 +13,5 @@ CONFIG_SOUND_MAX98095=y CONFIG_SOUND_WM8994=y CONFIG_USB=y CONFIG_DM_USB=y +CONFIG_DM_I2C=y +CONFIG_DM_I2C_COMPAT=y diff --git a/configs/odroid-xu3_defconfig b/configs/odroid-xu3_defconfig index 2b960d5..155ce39 100644 --- a/configs/odroid-xu3_defconfig +++ b/configs/odroid-xu3_defconfig @@ -7,3 +7,9 @@ CONFIG_DEFAULT_DEVICE_TREE="exynos5422-odroidxu3" # CONFIG_CMD_SETEXPR is not set CONFIG_USB=y CONFIG_DM_USB=y +CONFIG_CMD_NET=y +CONFIG_DM_I2C=y +CONFIG_DM_I2C_COMPAT=y +CONFIG_DM_PMIC=y +CONFIG_DM_REGULATOR=y +CONFIG_VIDEO_BRIDGE=y diff --git a/configs/peach-pi_defconfig b/configs/peach-pi_defconfig index 5050f5b..86d5a0b 100644 --- a/configs/peach-pi_defconfig +++ b/configs/peach-pi_defconfig @@ -14,3 +14,20 @@ CONFIG_USB=y CONFIG_DM_USB=y CONFIG_I2C_MUX=y CONFIG_I2C_CROS_EC_TUNNEL=y +CONFIG_SOUND=y +CONFIG_I2S=y +CONFIG_I2S_SAMSUNG=y +CONFIG_SOUND_MAX98095=y +CONFIG_SOUND_WM8994=y +CONFIG_DM_I2C=y +CONFIG_DM_PMIC=y +CONFIG_DM_REGULATOR=y +CONFIG_PMIC_TPS65090=y +CONFIG_REGULATOR_TPS65090=y +CONFIG_DM_I2C_COMPAT=y +CONFIG_I2C_ARB_GPIO_CHALLENGE=y +CONFIG_CMD_PMIC=y +CONFIG_CMD_REGULATOR=y +CONFIG_ERRNO_STR=y +CONFIG_VIDEO_BRIDGE=y +CONFIG_VIDEO_BRIDGE_PARADE_PS862X=y diff --git a/configs/peach-pit_defconfig b/configs/peach-pit_defconfig index d19bff2..8fe423e 100644 --- a/configs/peach-pit_defconfig +++ b/configs/peach-pit_defconfig @@ -14,3 +14,20 @@ CONFIG_USB=y CONFIG_DM_USB=y CONFIG_I2C_MUX=y CONFIG_I2C_CROS_EC_TUNNEL=y +CONFIG_SOUND=y +CONFIG_I2S=y +CONFIG_I2S_SAMSUNG=y +CONFIG_SOUND_MAX98095=y +CONFIG_SOUND_WM8994=y +CONFIG_DM_I2C=y +CONFIG_DM_PMIC=y +CONFIG_DM_REGULATOR=y +CONFIG_PMIC_TPS65090=y +CONFIG_REGULATOR_TPS65090=y +CONFIG_DM_I2C_COMPAT=y +CONFIG_I2C_ARB_GPIO_CHALLENGE=y +CONFIG_CMD_PMIC=y +CONFIG_CMD_REGULATOR=y +CONFIG_ERRNO_STR=y +CONFIG_VIDEO_BRIDGE=y +CONFIG_VIDEO_BRIDGE_PARADE_PS862X=y diff --git a/configs/smdk5250_defconfig b/configs/smdk5250_defconfig index 8412d6f..b061e47 100644 --- a/configs/smdk5250_defconfig +++ b/configs/smdk5250_defconfig @@ -14,3 +14,13 @@ CONFIG_SOUND_MAX98095=y CONFIG_SOUND_WM8994=y CONFIG_USB=y CONFIG_DM_USB=y +CONFIG_DM_I2C=y +CONFIG_DM_I2C_COMPAT=y +CONFIG_DM_PMIC=y +CONFIG_DM_REGULATOR=y +CONFIG_CMD_PMIC=y +CONFIG_CMD_REGULATOR=y +CONFIG_ERRNO_STR=y +CONFIG_DM_PMIC_MAX77686=y +CONFIG_DM_REGULATOR_MAX77686=y +CONFIG_VIDEO_BRIDGE=y diff --git a/configs/smdk5420_defconfig b/configs/smdk5420_defconfig index a96b368..1561f6a 100644 --- a/configs/smdk5420_defconfig +++ b/configs/smdk5420_defconfig @@ -8,3 +8,9 @@ CONFIG_SPL=y CONFIG_SPI_FLASH=y CONFIG_USB=y CONFIG_DM_USB=y +CONFIG_CMD_NET=y +CONFIG_DM_I2C=y +CONFIG_DM_I2C_COMPAT=y +CONFIG_DM_PMIC=y +CONFIG_DM_REGULATOR=y +CONFIG_VIDEO_BRIDGE=y diff --git a/configs/snow_defconfig b/configs/snow_defconfig index 93fbcae..a7d9e7a 100644 --- a/configs/snow_defconfig +++ b/configs/snow_defconfig @@ -18,3 +18,26 @@ CONFIG_SOUND_MAX98095=y CONFIG_SOUND_WM8994=y CONFIG_USB=y CONFIG_DM_USB=y +CONFIG_DM_I2C=y +CONFIG_DM_PMIC=y +CONFIG_DM_REGULATOR=y +CONFIG_PMIC_TPS65090=y +CONFIG_REGULATOR_TPS65090=y +CONFIG_DM_I2C_COMPAT=y +CONFIG_I2C_ARB_GPIO_CHALLENGE=y +CONFIG_I2C_MUX=y +CONFIG_CMD_PMIC=y +CONFIG_CMD_REGULATOR=y +CONFIG_ERRNO_STR=y +CONFIG_DM_PMIC_MAX77686=y +CONFIG_DM_REGULATOR_MAX77686=y +CONFIG_DEBUG_UART=y +CONFIG_DEBUG_UART_S5P=y +CONFIG_DEBUG_UART_CLOCK=100000000 +CONFIG_DEBUG_UART_BASE=0x12c30000 +CONFIG_I2C_CROS_EC_LDO=y +CONFIG_PMIC_S5M8767=y +CONFIG_REGULATOR_S5M8767=y +CONFIG_VIDEO_BRIDGE=y +CONFIG_VIDEO_BRIDGE_PARADE_PS862X=y +CONFIG_VIDEO_BRIDGE_NXP_PTN3460=y diff --git a/include/configs/arndale.h b/include/configs/arndale.h index 3ad4a9b..91e32df 100644 --- a/include/configs/arndale.h +++ b/include/configs/arndale.h @@ -60,4 +60,8 @@ /* The PERIPHBASE in the CBAR register is wrong on the Arndale, so override it */ #define CONFIG_ARM_GIC_BASE_ADDRESS 0x10480000
+/* Power */ +#define CONFIG_POWER +#define CONFIG_POWER_I2C + #endif /* __CONFIG_H */ diff --git a/include/configs/exynos5-common.h b/include/configs/exynos5-common.h index e04dec7..15363d0 100644 --- a/include/configs/exynos5-common.h +++ b/include/configs/exynos5-common.h @@ -67,6 +67,8 @@
#define CONFIG_SPL_LIBCOMMON_SUPPORT #define CONFIG_SPL_GPIO_SUPPORT +#define CONFIG_SPL_SERIAL_SUPPORT +#define CONFIG_SPL_LIBGENERIC_SUPPORT
/* specific .lds file */ #define CONFIG_SPL_LDSCRIPT "board/samsung/common/exynos-uboot-spl.lds" @@ -126,10 +128,6 @@ #define SPI_FLASH_UBOOT_POS (CONFIG_SEC_FW_SIZE + CONFIG_BL1_SIZE)
/* I2C */ - -/* TODO(sjg@chromium.org): Move these two options to Kconfig */ -#define CONFIG_DM_I2C -#define CONFIG_DM_I2C_COMPAT #define CONFIG_CMD_I2C #define CONFIG_SYS_I2C_S3C24X0 #define CONFIG_SYS_I2C_S3C24X0_SPEED 100000 /* 100 Kbps */ @@ -149,10 +147,6 @@ #define CONFIG_OF_SPI #endif
-/* Power */ -#define CONFIG_POWER -#define CONFIG_POWER_I2C - #ifdef CONFIG_ENV_IS_IN_SPI_FLASH #define CONFIG_ENV_SPI_MODE SPI_MODE_0 #define CONFIG_ENV_SECT_SIZE CONFIG_ENV_SIZE diff --git a/include/configs/exynos5-dt-common.h b/include/configs/exynos5-dt-common.h index b1b8e1a..098734b 100644 --- a/include/configs/exynos5-dt-common.h +++ b/include/configs/exynos5-dt-common.h @@ -18,11 +18,6 @@
#include "exynos5-common.h"
-/* PMIC */ -#define CONFIG_POWER -#define CONFIG_POWER_I2C -#define CONFIG_POWER_TPS65090 - /* Enable keyboard */ #define CONFIG_KEYBOARD
diff --git a/include/configs/smdk5250.h b/include/configs/smdk5250.h index e5655fc..bbec672 100644 --- a/include/configs/smdk5250.h +++ b/include/configs/smdk5250.h @@ -17,9 +17,6 @@
#include <configs/exynos5250-common.h>
-/* PMIC */ -#define CONFIG_POWER_MAX77686 - #define CONFIG_BOARD_COMMON
#define CONFIG_USB_XHCI diff --git a/include/configs/snow.h b/include/configs/snow.h index 557f86c..a467792 100644 --- a/include/configs/snow.h +++ b/include/configs/snow.h @@ -18,9 +18,6 @@ #include <configs/exynos5250-common.h> #include <configs/exynos5-dt-common.h>
- -#define CONFIG_POWER_TPS65090_I2C - #define CONFIG_BOARD_COMMON
#define CONFIG_USB_XHCI

On 3 August 2015 at 08:19, Simon Glass sjg@chromium.org wrote:
Enable PMICs, regulators and the like so that new drivers will be made available.
Signed-off-by: Simon Glass sjg@chromium.org
Changes in v2: None
board/samsung/smdk5420/smdk5420.c | 2 +- configs/arndale_defconfig | 2 ++ configs/odroid-xu3_defconfig | 6 ++++++ configs/peach-pi_defconfig | 17 +++++++++++++++++ configs/peach-pit_defconfig | 17 +++++++++++++++++ configs/smdk5250_defconfig | 10 ++++++++++ configs/smdk5420_defconfig | 6 ++++++ configs/snow_defconfig | 23 +++++++++++++++++++++++ include/configs/arndale.h | 4 ++++ include/configs/exynos5-common.h | 10 ++-------- include/configs/exynos5-dt-common.h | 5 ----- include/configs/smdk5250.h | 3 --- include/configs/snow.h | 3 --- 13 files changed, 88 insertions(+), 20 deletions(-)
Applied to u-boot-dm.

Many options are duplicated on the exynos5 boards. Move these to the common files. Also some options are not used so can be removed.
Tidy this up to make the files easier to maintain.
Signed-off-by: Simon Glass sjg@chromium.org Acked-by: Przemyslaw Marczak p.marczak@samsung.com ---
Changes in v2: - Rebase to dm/master
include/configs/arndale.h | 14 ++------------ include/configs/exynos5-common.h | 3 --- include/configs/exynos5-dt-common.h | 16 +++++++++++++++- include/configs/exynos5250-common.h | 16 ++++++---------- include/configs/exynos5420-common.h | 9 +++------ include/configs/odroid_xu3.h | 2 ++ include/configs/peach-pi.h | 12 +----------- include/configs/peach-pit.h | 20 +------------------- include/configs/smdk5250.h | 15 ++++----------- include/configs/smdk5420.h | 10 ++++------ include/configs/snow.h | 12 +----------- 11 files changed, 39 insertions(+), 90 deletions(-)
diff --git a/include/configs/arndale.h b/include/configs/arndale.h index 91e32df..8784c4e 100644 --- a/include/configs/arndale.h +++ b/include/configs/arndale.h @@ -13,6 +13,7 @@ "fdtfile=exynos5250-arndale.dtb\0"
#include "exynos5250-common.h" +#include <configs/exynos5-common.h>
/* SD/MMC configuration */ #define CONFIG_SUPPORT_EMMC_BOOT @@ -20,15 +21,6 @@ /* allow to overwrite serial and ethaddr */ #define CONFIG_ENV_OVERWRITE
-/* USB */ -#define CONFIG_USB_EHCI -#define CONFIG_USB_EHCI_EXYNOS - -#define CONFIG_SYS_USB_EHCI_MAX_ROOT_PORTS 3 -#define CONFIG_USB_HOST_ETHER -#define CONFIG_USB_ETHER_ASIX -#define CONFIG_USB_ETHER_ASIX88179 - /* MMC SPL */ #define CONFIG_EXYNOS_SPL
@@ -36,9 +28,6 @@ #define CONFIG_SYS_PROMPT "ARNDALE # " #define CONFIG_DEFAULT_CONSOLE "console=ttySAC2,115200n8\0"
-#define CONFIG_NR_DRAM_BANKS 8 -#define SDRAM_BANK_SIZE (256UL << 20UL) /* 256 MB */ - #define CONFIG_IDENT_STRING " for ARNDALE"
#define CONFIG_ENV_IS_IN_MMC @@ -49,6 +38,7 @@ #define CONFIG_SYS_INIT_SP_ADDR CONFIG_IRAM_STACK
/* PMIC */ +#define CONFIG_POWER #define CONFIG_PMIC #define CONFIG_POWER_I2C
diff --git a/include/configs/exynos5-common.h b/include/configs/exynos5-common.h index 15363d0..e710f41 100644 --- a/include/configs/exynos5-common.h +++ b/include/configs/exynos5-common.h @@ -143,8 +143,6 @@ #define CONFIG_SPI_FLASH_GIGADEVICE #define CONFIG_SF_DEFAULT_MODE SPI_MODE_0 #define CONFIG_SF_DEFAULT_SPEED 50000000 -#define EXYNOS5_SPI_NUM_CONTROLLERS 5 -#define CONFIG_OF_SPI #endif
#ifdef CONFIG_ENV_IS_IN_SPI_FLASH @@ -194,7 +192,6 @@ #define CONFIG_FIT #define CONFIG_FIT_BEST_MATCH
- #define BOOT_TARGET_DEVICES(func) \ func(MMC, mmc, 1) \ func(MMC, mmc, 0) \ diff --git a/include/configs/exynos5-dt-common.h b/include/configs/exynos5-dt-common.h index 098734b..29ef84b 100644 --- a/include/configs/exynos5-dt-common.h +++ b/include/configs/exynos5-dt-common.h @@ -16,7 +16,21 @@ "stdout=serial,lcd\0" \ "stderr=serial,lcd\0"
-#include "exynos5-common.h" +#define CONFIG_ENV_IS_IN_SPI_FLASH +#define CONFIG_ENV_SPI_BASE 0x12D30000 +#define FLASH_SIZE (4 << 20) +#define CONFIG_ENV_OFFSET (FLASH_SIZE - CONFIG_ENV_SECT_SIZE) +#define CONFIG_SPI_BOOTING + +#define CONFIG_BOARD_COMMON + +/* Display */ +#define CONFIG_LCD +#ifdef CONFIG_LCD +#define CONFIG_EXYNOS_FB +#define CONFIG_EXYNOS_DP +#define LCD_BPP LCD_COLOR16 +#endif
/* Enable keyboard */ #define CONFIG_KEYBOARD diff --git a/include/configs/exynos5250-common.h b/include/configs/exynos5250-common.h index 95e96ec..7d8921f 100644 --- a/include/configs/exynos5250-common.h +++ b/include/configs/exynos5250-common.h @@ -10,7 +10,6 @@ #ifndef __CONFIG_5250_H #define __CONFIG_5250_H
-#include <configs/exynos5-common.h> #define CONFIG_EXYNOS5250
#define CONFIG_SYS_SDRAM_BASE 0x40000000 @@ -28,16 +27,13 @@
#define CONFIG_SYS_INIT_SP_ADDR CONFIG_IRAM_STACK
-/* I2C */ -#define CONFIG_MAX_I2C_NUM 8 +/* USB */ +#define CONFIG_USB_EHCI +#define CONFIG_USB_EHCI_EXYNOS
-/* Display */ -#define CONFIG_LCD -#ifdef CONFIG_LCD -#define CONFIG_EXYNOS_FB -#define CONFIG_EXYNOS_DP -#define LCD_BPP LCD_COLOR16 -#endif +#define CONFIG_USB_HOST_ETHER +#define CONFIG_USB_ETHER_ASIX +#define CONFIG_USB_ETHER_ASIX88179
/* DRAM Memory Banks */ #define CONFIG_NR_DRAM_BANKS 8 diff --git a/include/configs/exynos5420-common.h b/include/configs/exynos5420-common.h index 3b1ac2c..3cdec51 100644 --- a/include/configs/exynos5420-common.h +++ b/include/configs/exynos5420-common.h @@ -13,8 +13,6 @@ /* A variant of Exynos5420 (Exynos5 Family) */ #define CONFIG_EXYNOS5800
-#include <configs/exynos5-common.h> - #define MACH_TYPE_SMDK5420 8002 #define CONFIG_MACH_TYPE MACH_TYPE_SMDK5420
@@ -32,10 +30,6 @@ #define CONFIG_DEVICE_TREE_LIST "exynos5800-peach-pi" \ "exynos5420-peach-pit exynos5420-smdk5420"
-#define CONFIG_MAX_I2C_NUM 11 - -#define CONFIG_BOARD_REV_GPIO_COUNT 2 - #define CONFIG_PHY_IRAM_BASE 0x02020000
/* Address for relocating helper code (Last 4 KB of IRAM) */ @@ -52,4 +46,7 @@ */ #define CONFIG_CORE_COUNT 0x8
+#define CONFIG_USB_XHCI +#define CONFIG_USB_XHCI_EXYNOS + #endif /* __CONFIG_EXYNOS5420_H */ diff --git a/include/configs/odroid_xu3.h b/include/configs/odroid_xu3.h index 8d5c736..0deff46 100644 --- a/include/configs/odroid_xu3.h +++ b/include/configs/odroid_xu3.h @@ -9,7 +9,9 @@ #define __CONFIG_ODROID_XU3_H
#include "exynos5420-common.h" +#include <configs/exynos5-common.h>
+#undef CONFIG_ENV_IS_IN_SPI_FLASH #define CONFIG_SYS_PROMPT "ODROID-XU3 # " #define CONFIG_IDENT_STRING " for ODROID-XU3"
diff --git a/include/configs/peach-pi.h b/include/configs/peach-pi.h index 46699ff..b97faf2 100644 --- a/include/configs/peach-pi.h +++ b/include/configs/peach-pi.h @@ -9,12 +9,6 @@ #ifndef __CONFIG_PEACH_PI_H #define __CONFIG_PEACH_PI_H
-#define CONFIG_ENV_IS_IN_SPI_FLASH -#define CONFIG_ENV_SPI_BASE 0x12D30000 -#define FLASH_SIZE (0x4 << 20) -#define CONFIG_ENV_OFFSET (FLASH_SIZE - CONFIG_BL2_SIZE) -#define CONFIG_SPI_BOOTING - #define MEM_LAYOUT_ENV_SETTINGS \ "bootm_size=0x10000000\0" \ "kernel_addr_r=0x22000000\0" \ @@ -25,8 +19,7 @@
#include <configs/exynos5420-common.h> #include <configs/exynos5-dt-common.h> - -#define CONFIG_BOARD_COMMON +#include <configs/exynos5-common.h>
#define CONFIG_SYS_SDRAM_BASE 0x20000000 #define CONFIG_SYS_TEXT_BASE 0x23E00000 @@ -51,9 +44,6 @@
#define CONFIG_POWER_TPS65090_EC
-#define CONFIG_USB_XHCI -#define CONFIG_USB_XHCI_EXYNOS - /* DRAM Memory Banks */ #define CONFIG_NR_DRAM_BANKS 7 #define SDRAM_BANK_SIZE (512UL << 20UL) /* 512 MB */ diff --git a/include/configs/peach-pit.h b/include/configs/peach-pit.h index c5c9e3a..18be42c 100644 --- a/include/configs/peach-pit.h +++ b/include/configs/peach-pit.h @@ -9,12 +9,6 @@ #ifndef __CONFIG_PEACH_PIT_H #define __CONFIG_PEACH_PIT_H
-#define CONFIG_ENV_IS_IN_SPI_FLASH -#define CONFIG_ENV_SPI_BASE 0x12D30000 -#define FLASH_SIZE (0x4 << 20) -#define CONFIG_ENV_OFFSET (FLASH_SIZE - CONFIG_BL2_SIZE) -#define CONFIG_SPI_BOOTING - #define MEM_LAYOUT_ENV_SETTINGS \ "bootm_size=0x10000000\0" \ "kernel_addr_r=0x22000000\0" \ @@ -25,8 +19,7 @@
#include <configs/exynos5420-common.h> #include <configs/exynos5-dt-common.h> - -#define CONFIG_BOARD_COMMON +#include <configs/exynos5-common.h>
#define CONFIG_SYS_SDRAM_BASE 0x20000000 #define CONFIG_SYS_TEXT_BASE 0x23E00000 @@ -41,19 +34,8 @@
#define CONFIG_VIDEO_PARADE
-/* Display */ -#define CONFIG_LCD -#ifdef CONFIG_LCD -#define CONFIG_EXYNOS_FB -#define CONFIG_EXYNOS_DP -#define LCD_BPP LCD_COLOR16 -#endif - #define CONFIG_POWER_TPS65090_EC
-#define CONFIG_USB_XHCI -#define CONFIG_USB_XHCI_EXYNOS - /* DRAM Memory Banks */ #define CONFIG_NR_DRAM_BANKS 4 #define SDRAM_BANK_SIZE (512UL << 20UL) /* 512 MB */ diff --git a/include/configs/smdk5250.h b/include/configs/smdk5250.h index bbec672..82d41cc 100644 --- a/include/configs/smdk5250.h +++ b/include/configs/smdk5250.h @@ -9,23 +9,16 @@ #ifndef __CONFIG_SMDK_H #define __CONFIG_SMDK_H
-#define CONFIG_ENV_IS_IN_SPI_FLASH -#define CONFIG_ENV_SPI_BASE 0x12D30000 -#define FLASH_SIZE (0x4 << 20) -#define CONFIG_ENV_OFFSET (FLASH_SIZE - CONFIG_BL2_SIZE) -#define CONFIG_SPI_BOOTING - #include <configs/exynos5250-common.h> +#include <configs/exynos5-dt-common.h> +#include <configs/exynos5-common.h>
-#define CONFIG_BOARD_COMMON +#undef CONFIG_KEYBOARD
-#define CONFIG_USB_XHCI -#define CONFIG_USB_XHCI_EXYNOS +#define CONFIG_BOARD_COMMON
#define CONFIG_SYS_PROMPT "SMDK5250 # " #define CONFIG_IDENT_STRING " for SMDK5250" - -/* Miscellaneous configurable options */ #define CONFIG_DEFAULT_CONSOLE "console=ttySAC1,115200n8\0"
#endif /* __CONFIG_SMDK_H */ diff --git a/include/configs/smdk5420.h b/include/configs/smdk5420.h index 607877c..623efa8 100644 --- a/include/configs/smdk5420.h +++ b/include/configs/smdk5420.h @@ -9,13 +9,11 @@ #ifndef __CONFIG_SMDK5420_H #define __CONFIG_SMDK5420_H
-#define CONFIG_ENV_IS_IN_SPI_FLASH -#define CONFIG_ENV_SPI_BASE 0x12D30000 -#define FLASH_SIZE (0x4 << 20) -#define CONFIG_ENV_OFFSET (FLASH_SIZE - CONFIG_BL2_SIZE) -#define CONFIG_SPI_BOOTING - #include <configs/exynos5420-common.h> +#include <configs/exynos5-dt-common.h> +#include <configs/exynos5-common.h> + +#undef CONFIG_KEYBOARD
#define CONFIG_BOARD_COMMON
diff --git a/include/configs/snow.h b/include/configs/snow.h index a467792..bf3377c 100644 --- a/include/configs/snow.h +++ b/include/configs/snow.h @@ -9,22 +9,12 @@ #ifndef __CONFIG_SNOW_H #define __CONFIG_SNOW_H
-#define CONFIG_ENV_IS_IN_SPI_FLASH -#define CONFIG_ENV_SPI_BASE 0x12D30000 -#define FLASH_SIZE (0x4 << 20) -#define CONFIG_ENV_OFFSET (FLASH_SIZE - CONFIG_BL2_SIZE) -#define CONFIG_SPI_BOOTING - #include <configs/exynos5250-common.h> #include <configs/exynos5-dt-common.h> +#include <configs/exynos5-common.h>
#define CONFIG_BOARD_COMMON
-#define CONFIG_USB_XHCI -#define CONFIG_USB_EHCI -#define CONFIG_USB_XHCI_EXYNOS -#define CONFIG_USB_EHCI_EXYNOS - #define CONFIG_SYS_PROMPT "snow # " #define CONFIG_IDENT_STRING " for snow" #define CONFIG_DEFAULT_CONSOLE "console=ttySAC1,115200n8\0"

On 3 August 2015 at 08:19, Simon Glass sjg@chromium.org wrote:
Many options are duplicated on the exynos5 boards. Move these to the common files. Also some options are not used so can be removed.
Tidy this up to make the files easier to maintain.
Signed-off-by: Simon Glass sjg@chromium.org Acked-by: Przemyslaw Marczak p.marczak@samsung.com
Changes in v2:
- Rebase to dm/master
include/configs/arndale.h | 14 ++------------ include/configs/exynos5-common.h | 3 --- include/configs/exynos5-dt-common.h | 16 +++++++++++++++- include/configs/exynos5250-common.h | 16 ++++++---------- include/configs/exynos5420-common.h | 9 +++------ include/configs/odroid_xu3.h | 2 ++ include/configs/peach-pi.h | 12 +----------- include/configs/peach-pit.h | 20 +------------------- include/configs/smdk5250.h | 15 ++++----------- include/configs/smdk5420.h | 10 ++++------ include/configs/snow.h | 12 +----------- 11 files changed, 39 insertions(+), 90 deletions(-)
Applied to u-boot-dm.

Now that exynos5420 boards can use the generic exynos5 code, switch over to it and remove the old code.
Signed-off-by: Simon Glass sjg@chromium.org Acked-by: Przemyslaw Marczak p.marczak@samsung.com ---
Changes in v2: None
board/samsung/smdk5420/Makefile | 4 - board/samsung/smdk5420/smdk5420.c | 143 ------------------------------------ include/configs/exynos5420-common.h | 2 + 3 files changed, 2 insertions(+), 147 deletions(-) delete mode 100644 board/samsung/smdk5420/smdk5420.c
diff --git a/board/samsung/smdk5420/Makefile b/board/samsung/smdk5420/Makefile index c2f8886..96a400a 100644 --- a/board/samsung/smdk5420/Makefile +++ b/board/samsung/smdk5420/Makefile @@ -5,7 +5,3 @@ #
obj-y += smdk5420_spl.o - -ifndef CONFIG_SPL_BUILD -obj-y += smdk5420.o -endif diff --git a/board/samsung/smdk5420/smdk5420.c b/board/samsung/smdk5420/smdk5420.c deleted file mode 100644 index 57cc92c..0000000 --- a/board/samsung/smdk5420/smdk5420.c +++ /dev/null @@ -1,143 +0,0 @@ -/* - * Copyright (C) 2013 Samsung Electronics - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include <common.h> -#include <fdtdec.h> -#include <errno.h> -#include <asm/io.h> -#include <asm/gpio.h> -#include <asm/arch/cpu.h> -#include <asm/arch/board.h> -#include <asm/arch/power.h> -#include <asm/arch/system.h> -#include <asm/arch/pinmux.h> -#include <asm/arch/dp_info.h> -#include <asm/arch/xhci-exynos.h> -#include <power/tps65090_pmic.h> -#include <i2c.h> -#include <lcd.h> -#include <mmc.h> -#include <parade.h> -#include <spi.h> -#include <usb.h> -#include <dwc3-uboot.h> -#include <samsung-usb-phy-uboot.h> - -DECLARE_GLOBAL_DATA_PTR; - -int exynos_init(void) -{ - return 0; -} - -#ifdef CONFIG_LCD -static int has_edp_bridge(void) -{ - int node; - - node = fdtdec_next_compatible(gd->fdt_blob, 0, COMPAT_PARADE_PS8625); - - /* No node for bridge in device tree. */ - if (node <= 0) - return 0; - - /* Default is with bridge ic */ - return 1; -} - -void exynos_lcd_power_on(void) -{ -#ifdef CONFIG_POWER_TPS65090 - int ret; - - ret = tps65090_init(); - if (ret < 0) { - printf("%s: tps65090_init() failed\n", __func__); - return; - } - - tps65090_fet_enable(6); -#endif - - mdelay(5); - - if (has_edp_bridge()) - if (parade_init(gd->fdt_blob)) - printf("%s: ps8625_init() failed\n", __func__); -} - -void exynos_backlight_on(unsigned int onoff) -{ -#ifdef CONFIG_POWER_TPS65090 - tps65090_fet_enable(1); -#endif -} -#endif - -int board_get_revision(void) -{ - return 0; -} - -#ifdef CONFIG_USB_DWC3 -static struct dwc3_device dwc3_device_data = { - .maximum_speed = USB_SPEED_SUPER, - .base = 0x12400000, - .dr_mode = USB_DR_MODE_PERIPHERAL, - .index = 0, -}; - -int usb_gadget_handle_interrupts(void) -{ - dwc3_uboot_handle_interrupt(0); - return 0; -} - -int board_usb_init(int index, enum usb_init_type init) -{ - struct exynos_usb3_phy *phy = (struct exynos_usb3_phy *) - samsung_get_base_usb3_phy(); - - if (!phy) { - error("usb3 phy not supported"); - return -ENODEV; - } - - set_usbdrd_phy_ctrl(POWER_USB_DRD_PHY_CTRL_EN); - exynos5_usb3_phy_init(phy); - - return dwc3_uboot_init(&dwc3_device_data); -} -#endif -#ifdef CONFIG_SET_DFU_ALT_INFO -char *get_dfu_alt_system(char *interface, char *devstr) -{ - return getenv("dfu_alt_system"); -} - -char *get_dfu_alt_boot(char *interface, char *devstr) -{ - struct mmc *mmc; - char *alt_boot; - int dev_num; - - dev_num = simple_strtoul(devstr, NULL, 10); - - mmc = find_mmc_device(dev_num); - if (!mmc) - return NULL; - - if (mmc_init(mmc)) - return NULL; - - if (IS_SD(mmc)) - alt_boot = CONFIG_DFU_ALT_BOOT_SD; - else - alt_boot = CONFIG_DFU_ALT_BOOT_EMMC; - - return alt_boot; -} -#endif diff --git a/include/configs/exynos5420-common.h b/include/configs/exynos5420-common.h index 3cdec51..cd86e06 100644 --- a/include/configs/exynos5420-common.h +++ b/include/configs/exynos5420-common.h @@ -13,6 +13,8 @@ /* A variant of Exynos5420 (Exynos5 Family) */ #define CONFIG_EXYNOS5800
+#define CONFIG_EXYNOS5_DT + #define MACH_TYPE_SMDK5420 8002 #define CONFIG_MACH_TYPE MACH_TYPE_SMDK5420

On 3 August 2015 at 08:19, Simon Glass sjg@chromium.org wrote:
Now that exynos5420 boards can use the generic exynos5 code, switch over to it and remove the old code.
Signed-off-by: Simon Glass sjg@chromium.org Acked-by: Przemyslaw Marczak p.marczak@samsung.com
Changes in v2: None
board/samsung/smdk5420/Makefile | 4 - board/samsung/smdk5420/smdk5420.c | 143 ------------------------------------ include/configs/exynos5420-common.h | 2 + 3 files changed, 2 insertions(+), 147 deletions(-) delete mode 100644 board/samsung/smdk5420/smdk5420.c
Applied to u-boot-dm.

Now that most exynos5250 boards can use the generic exynos5 code, switch over to it and remove the old code.
Signed-off-by: Simon Glass sjg@chromium.org ---
Changes in v2: None
board/samsung/smdk5250/Makefile | 4 - board/samsung/smdk5250/exynos5-dt.c | 306 ------------------------------------ include/configs/exynos5-dt-common.h | 2 + 3 files changed, 2 insertions(+), 310 deletions(-) delete mode 100644 board/samsung/smdk5250/exynos5-dt.c
diff --git a/board/samsung/smdk5250/Makefile b/board/samsung/smdk5250/Makefile index 3d96b07..501cab6 100644 --- a/board/samsung/smdk5250/Makefile +++ b/board/samsung/smdk5250/Makefile @@ -5,7 +5,3 @@ #
obj-y += smdk5250_spl.o - -ifndef CONFIG_SPL_BUILD -obj-y += exynos5-dt.o -endif diff --git a/board/samsung/smdk5250/exynos5-dt.c b/board/samsung/smdk5250/exynos5-dt.c deleted file mode 100644 index 53ff706..0000000 --- a/board/samsung/smdk5250/exynos5-dt.c +++ /dev/null @@ -1,306 +0,0 @@ -/* - * Copyright (C) 2012 Samsung Electronics - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include <common.h> -#include <fdtdec.h> -#include <asm/io.h> -#include <errno.h> -#include <i2c.h> -#include <netdev.h> -#include <spi.h> -#include <asm/gpio.h> -#include <asm/arch/cpu.h> -#include <asm/arch/dwmmc.h> -#include <asm/arch/mmc.h> -#include <asm/arch/pinmux.h> -#include <asm/arch/power.h> -#include <asm/arch/sromc.h> -#include <power/pmic.h> -#include <power/max77686_pmic.h> -#include <power/tps65090_pmic.h> -#include <tmu.h> - -DECLARE_GLOBAL_DATA_PTR; - -#ifdef CONFIG_SOUND_MAX98095 -static void board_enable_audio_codec(void) -{ - /* Enable MAX98095 Codec */ - gpio_request(EXYNOS5_GPIO_X17, "max98095_enable"); - gpio_direction_output(EXYNOS5_GPIO_X17, 1); - gpio_set_pull(EXYNOS5_GPIO_X17, S5P_GPIO_PULL_NONE); -} -#endif - -int exynos_init(void) -{ -#ifdef CONFIG_SOUND_MAX98095 - board_enable_audio_codec(); -#endif - return 0; -} - -#if defined(CONFIG_POWER) -#ifdef CONFIG_POWER_MAX77686 -static int pmic_reg_update(struct pmic *p, int reg, uint regval) -{ - u32 val; - int ret = 0; - - ret = pmic_reg_read(p, reg, &val); - if (ret) { - debug("%s: PMIC %d register read failed\n", __func__, reg); - return -1; - } - val |= regval; - ret = pmic_reg_write(p, reg, val); - if (ret) { - debug("%s: PMIC %d register write failed\n", __func__, reg); - return -1; - } - return 0; -} - -static int max77686_init(void) -{ - struct pmic *p; - - if (pmic_init(I2C_PMIC)) - return -1; - - p = pmic_get("MAX77686_PMIC"); - if (!p) - return -ENODEV; - - if (pmic_probe(p)) - return -1; - - if (pmic_reg_update(p, MAX77686_REG_PMIC_32KHZ, MAX77686_32KHCP_EN)) - return -1; - - if (pmic_reg_update(p, MAX77686_REG_PMIC_BBAT, - MAX77686_BBCHOSTEN | MAX77686_BBCVS_3_5V)) - return -1; - - /* VDD_MIF */ - if (pmic_reg_write(p, MAX77686_REG_PMIC_BUCK1OUT, - MAX77686_BUCK1OUT_1V)) { - debug("%s: PMIC %d register write failed\n", __func__, - MAX77686_REG_PMIC_BUCK1OUT); - return -1; - } - - if (pmic_reg_update(p, MAX77686_REG_PMIC_BUCK1CRTL, - MAX77686_BUCK1CTRL_EN)) - return -1; - - /* VDD_ARM */ - if (pmic_reg_write(p, MAX77686_REG_PMIC_BUCK2DVS1, - MAX77686_BUCK2DVS1_1_3V)) { - debug("%s: PMIC %d register write failed\n", __func__, - MAX77686_REG_PMIC_BUCK2DVS1); - return -1; - } - - if (pmic_reg_update(p, MAX77686_REG_PMIC_BUCK2CTRL1, - MAX77686_BUCK2CTRL_ON)) - return -1; - - /* VDD_INT */ - if (pmic_reg_write(p, MAX77686_REG_PMIC_BUCK3DVS1, - MAX77686_BUCK3DVS1_1_0125V)) { - debug("%s: PMIC %d register write failed\n", __func__, - MAX77686_REG_PMIC_BUCK3DVS1); - return -1; - } - - if (pmic_reg_update(p, MAX77686_REG_PMIC_BUCK3CTRL, - MAX77686_BUCK3CTRL_ON)) - return -1; - - /* VDD_G3D */ - if (pmic_reg_write(p, MAX77686_REG_PMIC_BUCK4DVS1, - MAX77686_BUCK4DVS1_1_2V)) { - debug("%s: PMIC %d register write failed\n", __func__, - MAX77686_REG_PMIC_BUCK4DVS1); - return -1; - } - - if (pmic_reg_update(p, MAX77686_REG_PMIC_BUCK4CTRL1, - MAX77686_BUCK3CTRL_ON)) - return -1; - - /* VDD_LDO2 */ - if (pmic_reg_update(p, MAX77686_REG_PMIC_LDO2CTRL1, - MAX77686_LD02CTRL1_1_5V | EN_LDO)) - return -1; - - /* VDD_LDO3 */ - if (pmic_reg_update(p, MAX77686_REG_PMIC_LDO3CTRL1, - MAX77686_LD03CTRL1_1_8V | EN_LDO)) - return -1; - - /* VDD_LDO5 */ - if (pmic_reg_update(p, MAX77686_REG_PMIC_LDO5CTRL1, - MAX77686_LD05CTRL1_1_8V | EN_LDO)) - return -1; - - /* VDD_LDO10 */ - if (pmic_reg_update(p, MAX77686_REG_PMIC_LDO10CTRL1, - MAX77686_LD10CTRL1_1_8V | EN_LDO)) - return -1; - - return 0; -} -#endif /* CONFIG_POWER_MAX77686 */ - -int exynos_power_init(void) -{ - int ret = 0; - -#ifdef CONFIG_POWER_MAX77686 - ret = max77686_init(); - if (ret) - return ret; -#endif -#ifdef CONFIG_POWER_TPS65090 - /* - * The TPS65090 may not be in the device tree. If so, it is not - * an error. - */ - ret = tps65090_init(); - if (ret == 0 || ret == -ENODEV) - return 0; -#endif - - return ret; -} -#endif /* CONFIG_POWER */ - -#ifdef CONFIG_LCD -static int board_dp_bridge_setup(void) -{ - const int max_tries = 10; - int num_tries, node; - - /* - * TODO(sjg): Use device tree for GPIOs when exynos GPIO - * numbering patch is in mainline. - */ - debug("%s\n", __func__); - node = fdtdec_next_compatible(gd->fdt_blob, 0, COMPAT_NXP_PTN3460); - if (node < 0) { - debug("%s: No node for DP bridge in device tree\n", __func__); - return -ENODEV; - } - - /* Setup the GPIOs */ - - /* PD is ACTIVE_LOW, and initially de-asserted */ - gpio_request(EXYNOS5_GPIO_Y25, "dp_bridge_pd"); - gpio_set_pull(EXYNOS5_GPIO_Y25, S5P_GPIO_PULL_NONE); - gpio_direction_output(EXYNOS5_GPIO_Y25, 1); - - /* Reset is ACTIVE_LOW */ - gpio_request(EXYNOS5_GPIO_X15, "dp_bridge_reset"); - gpio_set_pull(EXYNOS5_GPIO_X15, S5P_GPIO_PULL_NONE); - gpio_direction_output(EXYNOS5_GPIO_X15, 0); - - udelay(10); - gpio_set_value(EXYNOS5_GPIO_X15, 1); - - gpio_request(EXYNOS5_GPIO_X07, "dp_bridge_hpd"); - gpio_direction_input(EXYNOS5_GPIO_X07); - - /* - * We need to wait for 90ms after bringing up the bridge since there - * is a phantom "high" on the HPD chip during its bootup. The phantom - * high comes within 7ms of de-asserting PD and persists for at least - * 15ms. The real high comes roughly 50ms after PD is de-asserted. The - * phantom high makes it hard for us to know when the NXP chip is up. - */ - mdelay(90); - - for (num_tries = 0; num_tries < max_tries; num_tries++) { - /* Check HPD. If it's high, we're all good. */ - if (gpio_get_value(EXYNOS5_GPIO_X07)) - return 0; - - debug("%s: eDP bridge failed to come up; try %d of %d\n", - __func__, num_tries, max_tries); - } - - /* Immediately go into bridge reset if the hp line is not high */ - return -ENODEV; -} - -void exynos_cfg_lcd_gpio(void) -{ - /* For Backlight */ - gpio_request(EXYNOS5_GPIO_B20, "lcd_backlight"); - gpio_cfg_pin(EXYNOS5_GPIO_B20, S5P_GPIO_OUTPUT); - gpio_set_value(EXYNOS5_GPIO_B20, 1); - - /* LCD power on */ - gpio_request(EXYNOS5_GPIO_X15, "lcd_power"); - gpio_cfg_pin(EXYNOS5_GPIO_X15, S5P_GPIO_OUTPUT); - gpio_set_value(EXYNOS5_GPIO_X15, 1); - - /* Set Hotplug detect for DP */ - gpio_cfg_pin(EXYNOS5_GPIO_X07, S5P_GPIO_FUNC(0x3)); -} - -void exynos_set_dp_phy(unsigned int onoff) -{ - set_dp_phy_ctrl(onoff); -} - -void exynos_backlight_on(unsigned int on) -{ - debug("%s(%u)\n", __func__, on); - - if (!on) - return; - -#ifdef CONFIG_POWER_TPS65090 - int ret; - - ret = tps65090_fet_enable(1); /* Enable FET1, backlight */ - if (ret) - return; - - /* T5 in the LCD timing spec (defined as > 10ms) */ - mdelay(10); - - /* board_dp_backlight_pwm */ - gpio_direction_output(EXYNOS5_GPIO_B20, 1); - - /* T6 in the LCD timing spec (defined as > 10ms) */ - mdelay(10); - - /* board_dp_backlight_en */ - gpio_request(EXYNOS5_GPIO_X30, "board_dp_backlight_en"); - gpio_direction_output(EXYNOS5_GPIO_X30, 1); -#endif -} - -void exynos_lcd_power_on(void) -{ - int ret; - - debug("%s\n", __func__); - -#ifdef CONFIG_POWER_TPS65090 - /* board_dp_lcd_vdd */ - tps65090_fet_enable(6); /* Enable FET6, lcd panel */ -#endif - - ret = board_dp_bridge_setup(); - if (ret && ret != -ENODEV) - printf("LCD bridge failed to enable: %d\n", ret); -} - -#endif diff --git a/include/configs/exynos5-dt-common.h b/include/configs/exynos5-dt-common.h index 29ef84b..8b61a52 100644 --- a/include/configs/exynos5-dt-common.h +++ b/include/configs/exynos5-dt-common.h @@ -16,6 +16,8 @@ "stdout=serial,lcd\0" \ "stderr=serial,lcd\0"
+#define CONFIG_EXYNOS5_DT + #define CONFIG_ENV_IS_IN_SPI_FLASH #define CONFIG_ENV_SPI_BASE 0x12D30000 #define FLASH_SIZE (4 << 20)

On 3 August 2015 at 08:19, Simon Glass sjg@chromium.org wrote:
Now that most exynos5250 boards can use the generic exynos5 code, switch over to it and remove the old code.
Signed-off-by: Simon Glass sjg@chromium.org
Changes in v2: None
board/samsung/smdk5250/Makefile | 4 - board/samsung/smdk5250/exynos5-dt.c | 306 ------------------------------------ include/configs/exynos5-dt-common.h | 2 + 3 files changed, 2 insertions(+), 310 deletions(-) delete mode 100644 board/samsung/smdk5250/exynos5-dt.c
Applied to u-boot-dm.

Remove the old drivers (both the normal one and the cros_ec one) now that we have new drivers that use driver model.
Signed-off-by: Simon Glass sjg@chromium.org ---
Changes in v2: None
drivers/power/pmic/Makefile | 2 - drivers/power/pmic/pmic_tps65090.c | 310 ---------------------------------- drivers/power/pmic/pmic_tps65090_ec.c | 218 ------------------------ include/configs/peach-pit.h | 2 - include/fdtdec.h | 1 - include/power/tps65090_pmic.h | 73 -------- lib/fdtdec.c | 1 - 7 files changed, 607 deletions(-) delete mode 100644 drivers/power/pmic/pmic_tps65090.c delete mode 100644 drivers/power/pmic/pmic_tps65090_ec.c delete mode 100644 include/power/tps65090_pmic.h
diff --git a/drivers/power/pmic/Makefile b/drivers/power/pmic/Makefile index 322c2c6..6ef149a 100644 --- a/drivers/power/pmic/Makefile +++ b/drivers/power/pmic/Makefile @@ -18,8 +18,6 @@ obj-$(CONFIG_POWER_MAX8997) += pmic_max8997.o obj-$(CONFIG_POWER_MUIC_MAX8997) += muic_max8997.o obj-$(CONFIG_POWER_MAX77686) += pmic_max77686.o obj-$(CONFIG_POWER_PFUZE100) += pmic_pfuze100.o -obj-$(CONFIG_POWER_TPS65090_I2C) += pmic_tps65090.o -obj-$(CONFIG_POWER_TPS65090_EC) += pmic_tps65090_ec.o obj-$(CONFIG_POWER_TPS65217) += pmic_tps65217.o obj-$(CONFIG_POWER_TPS65218) += pmic_tps62362.o obj-$(CONFIG_POWER_TPS65218) += pmic_tps65218.o diff --git a/drivers/power/pmic/pmic_tps65090.c b/drivers/power/pmic/pmic_tps65090.c deleted file mode 100644 index 337903a..0000000 --- a/drivers/power/pmic/pmic_tps65090.c +++ /dev/null @@ -1,310 +0,0 @@ -/* - * Copyright (c) 2012 The Chromium OS Authors. - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include <common.h> -#include <errno.h> -#include <fdtdec.h> -#include <i2c.h> -#include <power/pmic.h> -#include <power/tps65090_pmic.h> - -DECLARE_GLOBAL_DATA_PTR; - -#define TPS65090_NAME "TPS65090_PMIC" - -/* TPS65090 register addresses */ -enum { - REG_IRQ1 = 0, - REG_CG_CTRL0 = 4, - REG_CG_STATUS1 = 0xa, - REG_FET1_CTRL = 0x0f, - REG_FET2_CTRL, - REG_FET3_CTRL, - REG_FET4_CTRL, - REG_FET5_CTRL, - REG_FET6_CTRL, - REG_FET7_CTRL, - TPS65090_NUM_REGS, -}; - -enum { - IRQ1_VBATG = 1 << 3, - CG_CTRL0_ENC_MASK = 0x01, - - MAX_FET_NUM = 7, - MAX_CTRL_READ_TRIES = 5, - - /* TPS65090 FET_CTRL register values */ - FET_CTRL_TOFET = 1 << 7, /* Timeout, startup, overload */ - FET_CTRL_PGFET = 1 << 4, /* Power good for FET status */ - FET_CTRL_WAIT = 3 << 2, /* Overcurrent timeout max */ - FET_CTRL_ADENFET = 1 << 1, /* Enable output auto discharge */ - FET_CTRL_ENFET = 1 << 0, /* Enable FET */ -}; - -/** - * Checks for a valid FET number - * - * @param fet_id FET number to check - * @return 0 if ok, -EINVAL if FET value is out of range - */ -static int tps65090_check_fet(unsigned int fet_id) -{ - if (fet_id == 0 || fet_id > MAX_FET_NUM) { - debug("parameter fet_id is out of range, %u not in 1 ~ %u\n", - fet_id, MAX_FET_NUM); - return -EINVAL; - } - - return 0; -} - -/** - * Set the power state for a FET - * - * @param pmic pmic structure for the tps65090 - * @param fet_id Fet number to set (1..MAX_FET_NUM) - * @param set 1 to power on FET, 0 to power off - * @return -EIO if we got a comms error, -EAGAIN if the FET failed to - * change state. If all is ok, returns 0. - */ -static int tps65090_fet_set(struct pmic *pmic, int fet_id, bool set) -{ - int retry; - u32 reg, value; - - value = FET_CTRL_ADENFET | FET_CTRL_WAIT; - if (set) - value |= FET_CTRL_ENFET; - - if (pmic_reg_write(pmic, REG_FET1_CTRL + fet_id - 1, value)) - return -EIO; - - /* Try reading until we get a result */ - for (retry = 0; retry < MAX_CTRL_READ_TRIES; retry++) { - if (pmic_reg_read(pmic, REG_FET1_CTRL + fet_id - 1, ®)) - return -EIO; - - /* Check that the fet went into the expected state */ - if (!!(reg & FET_CTRL_PGFET) == set) - return 0; - - /* If we got a timeout, there is no point in waiting longer */ - if (reg & FET_CTRL_TOFET) - break; - - mdelay(1); - } - - debug("FET %d: Power good should have set to %d but reg=%#02x\n", - fet_id, set, reg); - return -EAGAIN; -} - -int tps65090_fet_enable(unsigned int fet_id) -{ - struct pmic *pmic; - ulong start; - int loops; - int ret; - - ret = tps65090_check_fet(fet_id); - if (ret) - return ret; - - pmic = pmic_get(TPS65090_NAME); - if (!pmic) - return -EACCES; - - start = get_timer(0); - for (loops = 0;; loops++) { - ret = tps65090_fet_set(pmic, fet_id, true); - if (!ret) - break; - - if (get_timer(start) > 100) - break; - - /* Turn it off and try again until we time out */ - tps65090_fet_set(pmic, fet_id, false); - } - - if (ret) - debug("%s: FET%d failed to power on: time=%lums, loops=%d\n", - __func__, fet_id, get_timer(start), loops); - else if (loops) - debug("%s: FET%d powered on after %lums, loops=%d\n", - __func__, fet_id, get_timer(start), loops); - - /* - * Unfortunately, there are some conditions where the power - * good bit will be 0, but the fet still comes up. One such - * case occurs with the lcd backlight. We'll just return 0 here - * and assume that the fet will eventually come up. - */ - if (ret == -EAGAIN) - ret = 0; - - return ret; -} - -int tps65090_fet_disable(unsigned int fet_id) -{ - struct pmic *pmic; - int ret; - - ret = tps65090_check_fet(fet_id); - if (ret) - return ret; - - pmic = pmic_get(TPS65090_NAME); - if (!pmic) - return -EACCES; - ret = tps65090_fet_set(pmic, fet_id, false); - - return ret; -} - -int tps65090_fet_is_enabled(unsigned int fet_id) -{ - struct pmic *pmic; - u32 reg; - int ret; - - ret = tps65090_check_fet(fet_id); - if (ret) - return ret; - - pmic = pmic_get(TPS65090_NAME); - if (!pmic) - return -ENODEV; - ret = pmic_reg_read(pmic, REG_FET1_CTRL + fet_id - 1, ®); - if (ret) { - debug("fail to read FET%u_CTRL register over I2C", fet_id); - return -EIO; - } - - return reg & FET_CTRL_ENFET; -} - -int tps65090_get_charging(void) -{ - struct pmic *pmic; - u32 val; - int ret; - - pmic = pmic_get(TPS65090_NAME); - if (!pmic) - return -EACCES; - - ret = pmic_reg_read(pmic, REG_CG_CTRL0, &val); - if (ret) - return ret; - - return !!(val & CG_CTRL0_ENC_MASK); -} - -static int tps65090_charger_state(struct pmic *pmic, int state, - int current) -{ - u32 val; - int ret; - - ret = pmic_reg_read(pmic, REG_CG_CTRL0, &val); - if (!ret) { - if (state == PMIC_CHARGER_ENABLE) - val |= CG_CTRL0_ENC_MASK; - else - val &= ~CG_CTRL0_ENC_MASK; - ret = pmic_reg_write(pmic, REG_CG_CTRL0, val); - } - if (ret) { - debug("%s: Failed to read/write register\n", __func__); - return ret; - } - - return 0; -} - -int tps65090_get_status(void) -{ - struct pmic *pmic; - u32 val; - int ret; - - pmic = pmic_get(TPS65090_NAME); - if (!pmic) - return -EACCES; - - ret = pmic_reg_read(pmic, REG_CG_STATUS1, &val); - if (ret) - return ret; - - return val; -} - -static int tps65090_charger_bat_present(struct pmic *pmic) -{ - u32 val; - int ret; - - ret = pmic_reg_read(pmic, REG_IRQ1, &val); - if (ret) - return ret; - - return !!(val & IRQ1_VBATG); -} - -static struct power_chrg power_chrg_pmic_ops = { - .chrg_bat_present = tps65090_charger_bat_present, - .chrg_state = tps65090_charger_state, -}; - -int tps65090_init(void) -{ - struct pmic *p; - int bus; - int addr; - const void *blob = gd->fdt_blob; - int node, parent; - - node = fdtdec_next_compatible(blob, 0, COMPAT_TI_TPS65090); - if (node < 0) { - debug("PMIC: No node for PMIC Chip in device tree\n"); - debug("node = %d\n", node); - return -ENODEV; - } - - parent = fdt_parent_offset(blob, node); - if (parent < 0) { - debug("%s: Cannot find node parent\n", __func__); - return -EINVAL; - } - - bus = i2c_get_bus_num_fdt(parent); - if (bus < 0) { - debug("%s: Cannot find I2C bus\n", __func__); - return -ENOENT; - } - addr = fdtdec_get_int(blob, node, "reg", TPS65090_I2C_ADDR); - p = pmic_alloc(); - if (!p) { - printf("%s: POWER allocation error!\n", __func__); - return -ENOMEM; - } - - p->name = TPS65090_NAME; - p->bus = bus; - p->interface = PMIC_I2C; - p->number_of_regs = TPS65090_NUM_REGS; - p->hw.i2c.addr = addr; - p->hw.i2c.tx_num = 1; - p->chrg = &power_chrg_pmic_ops; - - puts("TPS65090 PMIC init\n"); - - return 0; -} diff --git a/drivers/power/pmic/pmic_tps65090_ec.c b/drivers/power/pmic/pmic_tps65090_ec.c deleted file mode 100644 index f79a878..0000000 --- a/drivers/power/pmic/pmic_tps65090_ec.c +++ /dev/null @@ -1,218 +0,0 @@ -/* - * Copyright (c) 2013 The Chromium OS Authors. - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include <common.h> -#include <cros_ec.h> -#include <errno.h> -#include <power/tps65090_pmic.h> - -DECLARE_GLOBAL_DATA_PTR; - -#define TPS65090_ADDR 0x48 - -static struct tps65090 { - struct cros_ec_dev *dev; /* The CROS_EC device */ -} config; - -/* TPS65090 register addresses */ -enum { - REG_IRQ1 = 0, - REG_CG_CTRL0 = 4, - REG_CG_STATUS1 = 0xa, - REG_FET1_CTRL = 0x0f, - REG_FET2_CTRL, - REG_FET3_CTRL, - REG_FET4_CTRL, - REG_FET5_CTRL, - REG_FET6_CTRL, - REG_FET7_CTRL, - TPS65090_NUM_REGS, -}; - -enum { - IRQ1_VBATG = 1 << 3, - CG_CTRL0_ENC_MASK = 0x01, - - MAX_FET_NUM = 7, - MAX_CTRL_READ_TRIES = 5, - - /* TPS65090 FET_CTRL register values */ - FET_CTRL_TOFET = 1 << 7, /* Timeout, startup, overload */ - FET_CTRL_PGFET = 1 << 4, /* Power good for FET status */ - FET_CTRL_WAIT = 3 << 2, /* Overcurrent timeout max */ - FET_CTRL_ADENFET = 1 << 1, /* Enable output auto discharge */ - FET_CTRL_ENFET = 1 << 0, /* Enable FET */ -}; - -/** - * tps65090_read - read a byte from tps6090 - * - * @param reg The register address to read from. - * @param val We'll return value value read here. - * @return 0 if ok; error if EC returns failure. - */ -static int tps65090_read(u32 reg, u8 *val) -{ - return cros_ec_i2c_xfer_old(config.dev, TPS65090_ADDR, reg, 1, - val, 1, true); -} - -/** - * tps65090_write - write a byte to tps6090 - * - * @param reg The register address to write to. - * @param val The value to write. - * @return 0 if ok; error if EC returns failure. - */ -static int tps65090_write(u32 reg, u8 val) -{ - return cros_ec_i2c_xfer_old(config.dev, TPS65090_ADDR, reg, 1, - &val, 1, false); -} - -/** - * Checks for a valid FET number - * - * @param fet_id FET number to check - * @return 0 if ok, -EINVAL if FET value is out of range - */ -static int tps65090_check_fet(unsigned int fet_id) -{ - if (fet_id == 0 || fet_id > MAX_FET_NUM) { - debug("parameter fet_id is out of range, %u not in 1 ~ %u\n", - fet_id, MAX_FET_NUM); - return -EINVAL; - } - - return 0; -} - -/** - * Set the power state for a FET - * - * @param fet_id Fet number to set (1..MAX_FET_NUM) - * @param set 1 to power on FET, 0 to power off - * @return -EIO if we got a comms error, -EAGAIN if the FET failed to - * change state. If all is ok, returns 0. - */ -static int tps65090_fet_set(int fet_id, bool set) -{ - int retry; - u8 reg, value; - - value = FET_CTRL_ADENFET | FET_CTRL_WAIT; - if (set) - value |= FET_CTRL_ENFET; - - if (tps65090_write(REG_FET1_CTRL + fet_id - 1, value)) - return -EIO; - - /* Try reading until we get a result */ - for (retry = 0; retry < MAX_CTRL_READ_TRIES; retry++) { - if (tps65090_read(REG_FET1_CTRL + fet_id - 1, ®)) - return -EIO; - - /* Check that the fet went into the expected state */ - if (!!(reg & FET_CTRL_PGFET) == set) - return 0; - - /* If we got a timeout, there is no point in waiting longer */ - if (reg & FET_CTRL_TOFET) - break; - - mdelay(1); - } - - debug("FET %d: Power good should have set to %d but reg=%#02x\n", - fet_id, set, reg); - return -EAGAIN; -} - -int tps65090_fet_enable(unsigned int fet_id) -{ - ulong start; - int loops; - int ret; - - ret = tps65090_check_fet(fet_id); - if (ret) - return ret; - - start = get_timer(0); - for (loops = 0;; loops++) { - ret = tps65090_fet_set(fet_id, true); - if (!ret) - break; - - if (get_timer(start) > 100) - break; - - /* Turn it off and try again until we time out */ - tps65090_fet_set(fet_id, false); - } - - if (ret) { - debug("%s: FET%d failed to power on: time=%lums, loops=%d\n", - __func__, fet_id, get_timer(start), loops); - } else if (loops) { - debug("%s: FET%d powered on after %lums, loops=%d\n", - __func__, fet_id, get_timer(start), loops); - } - /* - * Unfortunately, there are some conditions where the power - * good bit will be 0, but the fet still comes up. One such - * case occurs with the lcd backlight. We'll just return 0 here - * and assume that the fet will eventually come up. - */ - if (ret == -EAGAIN) - ret = 0; - - return ret; -} - -int tps65090_fet_disable(unsigned int fet_id) -{ - int ret; - - ret = tps65090_check_fet(fet_id); - if (ret) - return ret; - - ret = tps65090_fet_set(fet_id, false); - - return ret; -} - -int tps65090_fet_is_enabled(unsigned int fet_id) -{ - u8 reg = 0; - int ret; - - ret = tps65090_check_fet(fet_id); - if (ret) - return ret; - ret = tps65090_read(REG_FET1_CTRL + fet_id - 1, ®); - if (ret) { - debug("fail to read FET%u_CTRL register over I2C", fet_id); - return -EIO; - } - - return reg & FET_CTRL_ENFET; -} - -int tps65090_init(void) -{ - puts("TPS65090 PMIC EC init\n"); - - config.dev = board_get_cros_ec_dev(); - if (!config.dev) { - debug("%s: no cros_ec device: cannot init tps65090\n", - __func__); - return -ENODEV; - } - - return 0; -} diff --git a/include/configs/peach-pit.h b/include/configs/peach-pit.h index 18be42c..beb65b0 100644 --- a/include/configs/peach-pit.h +++ b/include/configs/peach-pit.h @@ -34,8 +34,6 @@
#define CONFIG_VIDEO_PARADE
-#define CONFIG_POWER_TPS65090_EC - /* DRAM Memory Banks */ #define CONFIG_NR_DRAM_BANKS 4 #define SDRAM_BANK_SIZE (512UL << 20UL) /* 512 MB */ diff --git a/include/fdtdec.h b/include/fdtdec.h index 4b3f8d1..12dc5fd 100644 --- a/include/fdtdec.h +++ b/include/fdtdec.h @@ -170,7 +170,6 @@ enum fdt_compat_id { COMPAT_INFINEON_SLB9645_TPM, /* Infineon SLB9645 TPM */ COMPAT_SAMSUNG_EXYNOS5_I2C, /* Exynos5 High Speed I2C Controller */ COMPAT_SANDBOX_LCD_SDL, /* Sandbox LCD emulation with SDL */ - COMPAT_TI_TPS65090, /* Texas Instrument TPS65090 */ COMPAT_NXP_PTN3460, /* NXP PTN3460 DP/LVDS bridge */ COMPAT_SAMSUNG_EXYNOS_SYSMMU, /* Exynos sysmmu */ COMPAT_PARADE_PS8625, /* Parade PS8622 EDP->LVDS bridge */ diff --git a/include/power/tps65090_pmic.h b/include/power/tps65090_pmic.h deleted file mode 100644 index dcf99c9..0000000 --- a/include/power/tps65090_pmic.h +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright (c) 2012 The Chromium OS Authors. - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#ifndef __TPS65090_PMIC_H_ -#define __TPS65090_PMIC_H_ - -/* I2C device address for TPS65090 PMU */ -#define TPS65090_I2C_ADDR 0x48 - -enum { - /* Status register fields */ - TPS65090_ST1_OTC = 1 << 0, - TPS65090_ST1_OCC = 1 << 1, - TPS65090_ST1_STATE_SHIFT = 4, - TPS65090_ST1_STATE_MASK = 0xf << TPS65090_ST1_STATE_SHIFT, -}; - -/** - * Enable FET - * - * @param fet_id FET ID, value between 1 and 7 - * @return 0 on success, non-0 on failure - */ -int tps65090_fet_enable(unsigned int fet_id); - -/** - * Disable FET - * - * @param fet_id FET ID, value between 1 and 7 - * @return 0 on success, non-0 on failure - */ -int tps65090_fet_disable(unsigned int fet_id); - -/** - * Is FET enabled? - * - * @param fet_id FET ID, value between 1 and 7 - * @return 1 enabled, 0 disabled, negative value on failure - */ -int tps65090_fet_is_enabled(unsigned int fet_id); - -/** - * Enable / disable the battery charger - * - * @param enable 0 to disable charging, non-zero to enable - */ -int tps65090_set_charge_enable(int enable); - -/** - * Check whether we have enabled battery charging - * - * @return 1 if enabled, 0 if disabled - */ -int tps65090_get_charging(void); - -/** - * Return the value of the status register - * - * @return status register value, or -1 on error - */ -int tps65090_get_status(void); - -/** - * Initialize the TPS65090 PMU. - * - * @return 0 on success, non-0 on failure - */ -int tps65090_init(void); - -#endif /* __TPS65090_PMIC_H_ */ diff --git a/lib/fdtdec.c b/lib/fdtdec.c index a954051..670612f 100644 --- a/lib/fdtdec.c +++ b/lib/fdtdec.c @@ -62,7 +62,6 @@ static const char * const compat_names[COMPAT_COUNT] = { COMPAT(INFINEON_SLB9645_TPM, "infineon,slb9645tt"), COMPAT(SAMSUNG_EXYNOS5_I2C, "samsung,exynos5-hsi2c"), COMPAT(SANDBOX_LCD_SDL, "sandbox,lcd-sdl"), - COMPAT(TI_TPS65090, "ti,tps65090"), COMPAT(COMPAT_NXP_PTN3460, "nxp,ptn3460"), COMPAT(SAMSUNG_EXYNOS_SYSMMU, "samsung,sysmmu-v3.3"), COMPAT(PARADE_PS8625, "parade,ps8625"),

On 3 August 2015 at 08:19, Simon Glass sjg@chromium.org wrote:
Remove the old drivers (both the normal one and the cros_ec one) now that we have new drivers that use driver model.
Signed-off-by: Simon Glass sjg@chromium.org
Changes in v2: None
drivers/power/pmic/Makefile | 2 - drivers/power/pmic/pmic_tps65090.c | 310 ---------------------------------- drivers/power/pmic/pmic_tps65090_ec.c | 218 ------------------------ include/configs/peach-pit.h | 2 - include/fdtdec.h | 1 - include/power/tps65090_pmic.h | 73 -------- lib/fdtdec.c | 1 - 7 files changed, 607 deletions(-) delete mode 100644 drivers/power/pmic/pmic_tps65090.c delete mode 100644 drivers/power/pmic/pmic_tps65090_ec.c delete mode 100644 include/power/tps65090_pmic.h
Applied to u-boot-dm.

This is not needed with driver mode. Remove it.
Signed-off-by: Simon Glass sjg@chromium.org ---
Changes in v2: None
drivers/misc/cros_ec.c | 268 +------------------------------------------------ include/cros_ec.h | 14 --- 2 files changed, 1 insertion(+), 281 deletions(-)
diff --git a/drivers/misc/cros_ec.c b/drivers/misc/cros_ec.c index 6027177..ba36795 100644 --- a/drivers/misc/cros_ec.c +++ b/drivers/misc/cros_ec.c @@ -1055,87 +1055,6 @@ int cros_ec_decode_ec_flash(const void *blob, int node, return 0; }
-int cros_ec_i2c_xfer_old(struct cros_ec_dev *dev, uchar chip, uint addr, - int alen, uchar *buffer, int len, int is_read) -{ - union { - struct ec_params_i2c_passthru p; - uint8_t outbuf[EC_PROTO2_MAX_PARAM_SIZE]; - } params; - union { - struct ec_response_i2c_passthru r; - uint8_t inbuf[EC_PROTO2_MAX_PARAM_SIZE]; - } response; - struct ec_params_i2c_passthru *p = ¶ms.p; - struct ec_response_i2c_passthru *r = &response.r; - struct ec_params_i2c_passthru_msg *msg = p->msg; - uint8_t *pdata; - int read_len, write_len; - int size; - int rv; - - p->port = 0; - - if (alen != 1) { - printf("Unsupported address length %d\n", alen); - return -1; - } - if (is_read) { - read_len = len; - write_len = alen; - p->num_msgs = 2; - } else { - read_len = 0; - write_len = alen + len; - p->num_msgs = 1; - } - - size = sizeof(*p) + p->num_msgs * sizeof(*msg); - if (size + write_len > sizeof(params)) { - puts("Params too large for buffer\n"); - return -1; - } - if (sizeof(*r) + read_len > sizeof(response)) { - puts("Read length too big for buffer\n"); - return -1; - } - - /* Create a message to write the register address and optional data */ - pdata = (uint8_t *)p + size; - msg->addr_flags = chip; - msg->len = write_len; - pdata[0] = addr; - if (!is_read) - memcpy(pdata + 1, buffer, len); - msg++; - - if (read_len) { - msg->addr_flags = chip | EC_I2C_FLAG_READ; - msg->len = read_len; - } - - rv = ec_command(dev, EC_CMD_I2C_PASSTHRU, 0, p, size + write_len, - r, sizeof(*r) + read_len); - if (rv < 0) - return rv; - - /* Parse response */ - if (r->i2c_status & EC_I2C_STATUS_ERROR) { - printf("Transfer failed with status=0x%x\n", r->i2c_status); - return -1; - } - - if (rv < sizeof(*r) + read_len) { - puts("Truncated read response\n"); - return -1; - } - - if (read_len) - memcpy(buffer, r->data, read_len); - - return 0; -} - int cros_ec_i2c_tunnel(struct udevice *dev, struct i2c_msg *in, int nmsgs) { struct cros_ec_dev *cdev = dev_get_uclass_priv(dev); @@ -1266,187 +1185,6 @@ static int do_read_write(struct cros_ec_dev *dev, int is_write, int argc, return 0; }
-/** - * get_alen() - Small parser helper function to get address length - * - * Returns the address length. - */ -static uint get_alen(char *arg) -{ - int j; - int alen; - - alen = 1; - for (j = 0; j < 8; j++) { - if (arg[j] == '.') { - alen = arg[j+1] - '0'; - break; - } else if (arg[j] == '\0') { - break; - } - } - return alen; -} - -#define DISP_LINE_LEN 16 - -/* - * TODO(sjg@chromium.org): This code copied almost verbatim from cmd_i2c.c - * so we can remove it later. - */ -static int cros_ec_i2c_md(struct cros_ec_dev *dev, int flag, int argc, - char * const argv[]) -{ - u_char chip; - uint addr, alen, length = 0x10; - int j, nbytes, linebytes; - - if (argc < 2) - return CMD_RET_USAGE; - - if (1 || (flag & CMD_FLAG_REPEAT) == 0) { - /* - * New command specified. - */ - - /* - * I2C chip address - */ - chip = simple_strtoul(argv[0], NULL, 16); - - /* - * I2C data address within the chip. This can be 1 or - * 2 bytes long. Some day it might be 3 bytes long :-). - */ - addr = simple_strtoul(argv[1], NULL, 16); - alen = get_alen(argv[1]); - if (alen > 3) - return CMD_RET_USAGE; - - /* - * If another parameter, it is the length to display. - * Length is the number of objects, not number of bytes. - */ - if (argc > 2) - length = simple_strtoul(argv[2], NULL, 16); - } - - /* - * Print the lines. - * - * We buffer all read data, so we can make sure data is read only - * once. - */ - nbytes = length; - do { - unsigned char linebuf[DISP_LINE_LEN]; - unsigned char *cp; - - linebytes = (nbytes > DISP_LINE_LEN) ? DISP_LINE_LEN : nbytes; - - if (cros_ec_i2c_xfer_old(dev, chip, addr, alen, linebuf, - linebytes, 1)) - puts("Error reading the chip.\n"); - else { - printf("%04x:", addr); - cp = linebuf; - for (j = 0; j < linebytes; j++) { - printf(" %02x", *cp++); - addr++; - } - puts(" "); - cp = linebuf; - for (j = 0; j < linebytes; j++) { - if ((*cp < 0x20) || (*cp > 0x7e)) - puts("."); - else - printf("%c", *cp); - cp++; - } - putc('\n'); - } - nbytes -= linebytes; - } while (nbytes > 0); - - return 0; -} - -static int cros_ec_i2c_mw(struct cros_ec_dev *dev, int flag, int argc, - char * const argv[]) -{ - uchar chip; - ulong addr; - uint alen; - uchar byte; - int count; - - if ((argc < 3) || (argc > 4)) - return CMD_RET_USAGE; - - /* - * Chip is always specified. - */ - chip = simple_strtoul(argv[0], NULL, 16); - - /* - * Address is always specified. - */ - addr = simple_strtoul(argv[1], NULL, 16); - alen = get_alen(argv[1]); - if (alen > 3) - return CMD_RET_USAGE; - - /* - * Value to write is always specified. - */ - byte = simple_strtoul(argv[2], NULL, 16); - - /* - * Optional count - */ - if (argc == 4) - count = simple_strtoul(argv[3], NULL, 16); - else - count = 1; - - while (count-- > 0) { - if (cros_ec_i2c_xfer_old(dev, chip, addr++, alen, &byte, 1, 0)) - puts("Error writing the chip.\n"); - /* - * Wait for the write to complete. The write can take - * up to 10mSec (we allow a little more time). - */ -/* - * No write delay with FRAM devices. - */ -#if !defined(CONFIG_SYS_I2C_FRAM) - udelay(11000); -#endif - } - - return 0; -} - -/* Temporary code until we have driver model and can use the i2c command */ -static int cros_ec_i2c_passthrough(struct cros_ec_dev *dev, int flag, - int argc, char * const argv[]) -{ - const char *cmd; - - if (argc < 1) - return CMD_RET_USAGE; - cmd = *argv++; - argc--; - if (0 == strcmp("md", cmd)) - cros_ec_i2c_md(dev, flag, argc, argv); - else if (0 == strcmp("mw", cmd)) - cros_ec_i2c_mw(dev, flag, argc, argv); - else - return CMD_RET_USAGE; - - return 0; -} - static int do_cros_ec(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { struct cros_ec_dev *dev; @@ -1696,8 +1434,6 @@ static int do_cros_ec(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) debug("%s: Could not access LDO%d\n", __func__, index); return ret; } - } else if (0 == strcmp("i2c", cmd)) { - ret = cros_ec_i2c_passthrough(dev, flag, argc - 2, argv + 2); } else { return CMD_RET_USAGE; } @@ -1734,9 +1470,7 @@ U_BOOT_CMD( "crosec vbnvcontext [hexstring] Read [write] VbNvContext from EC\n" "crosec ldo <idx> [<state>] Switch/Read LDO state\n" "crosec test run tests on cros_ec\n" - "crosec version Read CROS-EC version\n" - "crosec i2c md chip address[.0, .1, .2] [# of objects] - read from I2C passthru\n" - "crosec i2c mw chip address[.0, .1, .2] value [count] - write to I2C passthru (fill)" + "crosec version Read CROS-EC version" ); #endif
diff --git a/include/cros_ec.h b/include/cros_ec.h index 0ad9d81..b926934 100644 --- a/include/cros_ec.h +++ b/include/cros_ec.h @@ -400,18 +400,4 @@ struct i2c_msg; */ int cros_ec_i2c_tunnel(struct udevice *dev, struct i2c_msg *msg, int nmsgs);
-/* - * Tunnel an I2C transfer to the EC - * - * @param dev CROS-EC device - * @param chip Chip address (7-bit I2C address) - * @param addr Register address to read/write - * @param alen Length of register address in bytes - * @param buffer Buffer containing data to read/write - * @param len Length of buffer - * @param is_read 1 if this is a read, 0 if this is a write - */ -int cros_ec_i2c_xfer_old(struct cros_ec_dev *dev, uchar chip, uint addr, - int alen, uchar *buffer, int len, int is_read); - #endif

On 3 August 2015 at 08:19, Simon Glass sjg@chromium.org wrote:
This is not needed with driver mode. Remove it.
Signed-off-by: Simon Glass sjg@chromium.org
Changes in v2: None
drivers/misc/cros_ec.c | 268 +------------------------------------------------ include/cros_ec.h | 14 --- 2 files changed, 1 insertion(+), 281 deletions(-)
Applied to u-boot-dm.

We have a new one which uses driver model and device tree configuration. Remove the old one.
Signed-off-by: Simon Glass sjg@chromium.org ---
Changes in v2: None
drivers/video/Makefile | 1 - drivers/video/parade.c | 231 -------------------------------------------- include/configs/peach-pi.h | 2 - include/configs/peach-pit.h | 2 - include/fdtdec.h | 1 - include/parade.h | 18 ---- lib/fdtdec.c | 1 - 7 files changed, 256 deletions(-) delete mode 100644 drivers/video/parade.c delete mode 100644 include/parade.h
diff --git a/drivers/video/Makefile b/drivers/video/Makefile index 599fe83..c2c4dfc 100644 --- a/drivers/video/Makefile +++ b/drivers/video/Makefile @@ -51,7 +51,6 @@ obj-$(CONFIG_VIDEO_VESA) += vesa_fb.o obj-$(CONFIG_FORMIKE) += formike.o obj-$(CONFIG_LG4573) += lg4573.o obj-$(CONFIG_AM335X_LCD) += am335x-fb.o -obj-$(CONFIG_VIDEO_PARADE) += parade.o
obj-${CONFIG_VIDEO_TEGRA124} += tegra124/
diff --git a/drivers/video/parade.c b/drivers/video/parade.c deleted file mode 100644 index ae50971..0000000 --- a/drivers/video/parade.c +++ /dev/null @@ -1,231 +0,0 @@ -/* - * Copyright (c) 2014 The Chromium OS Authors. All rights reserved. - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -/* - * This file is a driver for Parade dP<->LVDS bridges. The original submission - * is for the ps8625 chip. - */ -#include <config.h> -#include <common.h> -#include <i2c.h> -#include <fdtdec.h> -#include <asm/gpio.h> - -/* - * Initialization of the chip is a process of writing certaing values into - * certain registers over i2c bus. The chip in fact responds to a range of - * addresses on the i2c bus, so for each written value three parameters are - * required: i2c address, register address and the actual value. - * - * The base address is derived from the device tree, only address offset is - * stored in the table below. - */ -/** - * struct reg_data() - data for a parade register write - * - * @addr_off offset from the i2c base address for parade - * @reg_addr register address to write - * @value value to be written - */ -struct reg_data { - uint8_t addr_off; - uint8_t reg; - uint8_t value; -} _packed; - -#define END_OF_TABLE 0xff /* Ficticious offset */ - -static const struct reg_data parade_values[] = { - {0x02, 0xa1, 0x01}, /* HPD low */ - /* - * SW setting - * [1:0] SW output 1.2V voltage is lower to 96% - */ - {0x04, 0x14, 0x01}, - /* - * RCO SS setting - * [5:4] = b01 0.5%, b10 1%, b11 1.5% - */ - {0x04, 0xe3, 0x20}, - {0x04, 0xe2, 0x80}, /* [7] RCO SS enable */ - /* - * RPHY Setting - * [3:2] CDR tune wait cycle before - * measure for fine tune b00: 1us, - * 01: 0.5us, 10:2us, 11:4us. - */ - {0x04, 0x8a, 0x0c}, - {0x04, 0x89, 0x08}, /* [3] RFD always on */ - /* - * CTN lock in/out: - * 20000ppm/80000ppm. Lock out 2 - * times. - */ - {0x04, 0x71, 0x2d}, - /* - * 2.7G CDR settings - * NOF=40LSB for HBR CDR setting - */ - {0x04, 0x7d, 0x07}, - {0x04, 0x7b, 0x00}, /* [1:0] Fmin=+4bands */ - {0x04, 0x7a, 0xfd}, /* [7:5] DCO_FTRNG=+-40% */ - /* - * 1.62G CDR settings - * [5:2]NOF=64LSB [1:0]DCO scale is 2/5 - */ - {0x04, 0xc0, 0x12}, - {0x04, 0xc1, 0x92}, /* Gitune=-37% */ - {0x04, 0xc2, 0x1c}, /* Fbstep=100% */ - {0x04, 0x32, 0x80}, /* [7] LOS signal disable */ - /* - * RPIO Setting - * [7:4] LVDS driver bias current : - * 75% (250mV swing) - */ - {0x04, 0x00, 0xb0}, - /* - * [7:6] Right-bar GPIO output strength is 8mA - */ - {0x04, 0x15, 0x40}, - /* EQ Training State Machine Setting */ - {0x04, 0x54, 0x10}, /* RCO calibration start */ - /* [4:0] MAX_LANE_COUNT set to one lane */ - {0x01, 0x02, 0x81}, - /* [4:0] LANE_COUNT_SET set to one lane */ - {0x01, 0x21, 0x81}, - {0x00, 0x52, 0x20}, - {0x00, 0xf1, 0x03}, /* HPD CP toggle enable */ - {0x00, 0x62, 0x41}, - /* Counter number, add 1ms counter delay */ - {0x00, 0xf6, 0x01}, - /* - * [6]PWM function control by - * DPCD0040f[7], default is PWM - * block always works. - */ - {0x00, 0x77, 0x06}, - /* - * 04h Adjust VTotal tolerance to - * fix the 30Hz no display issue - */ - {0x00, 0x4c, 0x04}, - /* DPCD00400='h00, Parade OUI = 'h001cf8 */ - {0x01, 0xc0, 0x00}, - {0x01, 0xc1, 0x1c}, /* DPCD00401='h1c */ - {0x01, 0xc2, 0xf8}, /* DPCD00402='hf8 */ - /* - * DPCD403~408 = ASCII code - * D2SLV5='h4432534c5635 - */ - {0x01, 0xc3, 0x44}, - {0x01, 0xc4, 0x32}, /* DPCD404 */ - {0x01, 0xc5, 0x53}, /* DPCD405 */ - {0x01, 0xc6, 0x4c}, /* DPCD406 */ - {0x01, 0xc7, 0x56}, /* DPCD407 */ - {0x01, 0xc8, 0x35}, /* DPCD408 */ - /* - * DPCD40A, Initial Code major revision - * '01' - */ - {0x01, 0xca, 0x01}, - /* DPCD40B, Initial Code minor revision '05' */ - {0x01, 0xcb, 0x05}, - /* DPCD720, Select internal PWM */ - {0x01, 0xa5, 0xa0}, - /* - * FFh for 100% PWM of brightness, 0h for 0% - * brightness - */ - {0x01, 0xa7, 0xff}, - /* - * Set LVDS output as 6bit-VESA mapping, - * single LVDS channel - */ - {0x01, 0xcc, 0x13}, - /* Enable SSC set by register */ - {0x02, 0xb1, 0x20}, - /* - * Set SSC enabled and +/-1% central - * spreading - */ - {0x04, 0x10, 0x16}, - /* MPU Clock source: LC => RCO */ - {0x04, 0x59, 0x60}, - {0x04, 0x54, 0x14}, /* LC -> RCO */ - {0x02, 0xa1, 0x91}, /* HPD high */ - {END_OF_TABLE} -}; - -/** - * Write values table into the Parade eDP bridge - * - * @return 0 on success, non-0 on failure - */ - -static int parade_write_regs(int base_addr, const struct reg_data *table) -{ - int ret = 0; - - while (!ret && (table->addr_off != END_OF_TABLE)) { - ret = i2c_write(base_addr + table->addr_off, - table->reg, 1, - (uint8_t *)&table->value, - sizeof(table->value)); - table++; - } - return ret; -} - -int parade_init(const void *blob) -{ - struct gpio_desc rst_gpio; - struct gpio_desc slp_gpio; - int bus, old_bus; - int parent; - int node; - int addr; - int ret; - - node = fdtdec_next_compatible(blob, 0, COMPAT_PARADE_PS8625); - if (node < 0) - return 0; - - parent = fdt_parent_offset(blob, node); - if (parent < 0) { - debug("%s: Could not find parent i2c node\n", __func__); - return -1; - } - addr = fdtdec_get_int(blob, node, "reg", -1); - if (addr < 0) { - debug("%s: Could not find i2c address\n", __func__); - return -1; - } - - gpio_request_by_name_nodev(blob, node, "sleep-gpio", 0, &slp_gpio, - GPIOD_IS_OUT | GPIOD_IS_OUT_ACTIVE); - - mdelay(10); - - gpio_request_by_name_nodev(blob, node, "reset-gpio", 0, &rst_gpio, - GPIOD_IS_OUT | GPIOD_IS_OUT_ACTIVE); - - bus = i2c_get_bus_num_fdt(parent); - old_bus = i2c_get_bus_num(); - - debug("%s: Using i2c bus %d\n", __func__, bus); - - /* - * TODO(sjg@chromium.org): Hmmm we seem to need some sort of delay - * here. - */ - mdelay(40); - i2c_set_bus_num(bus); - ret = parade_write_regs(addr, parade_values); - - i2c_set_bus_num(old_bus); - - return ret; -} diff --git a/include/configs/peach-pi.h b/include/configs/peach-pi.h index b97faf2..0f5e9fe 100644 --- a/include/configs/peach-pi.h +++ b/include/configs/peach-pi.h @@ -32,8 +32,6 @@ #define CONFIG_SYS_PROMPT "Peach-Pi # " #define CONFIG_IDENT_STRING " for Peach-Pi"
-#define CONFIG_VIDEO_PARADE - /* Display */ #define CONFIG_LCD #ifdef CONFIG_LCD diff --git a/include/configs/peach-pit.h b/include/configs/peach-pit.h index beb65b0..f259434 100644 --- a/include/configs/peach-pit.h +++ b/include/configs/peach-pit.h @@ -32,8 +32,6 @@ #define CONFIG_SYS_PROMPT "Peach-Pit # " #define CONFIG_IDENT_STRING " for Peach-Pit"
-#define CONFIG_VIDEO_PARADE - /* DRAM Memory Banks */ #define CONFIG_NR_DRAM_BANKS 4 #define SDRAM_BANK_SIZE (512UL << 20UL) /* 512 MB */ diff --git a/include/fdtdec.h b/include/fdtdec.h index 12dc5fd..b994f2c 100644 --- a/include/fdtdec.h +++ b/include/fdtdec.h @@ -172,7 +172,6 @@ enum fdt_compat_id { COMPAT_SANDBOX_LCD_SDL, /* Sandbox LCD emulation with SDL */ COMPAT_NXP_PTN3460, /* NXP PTN3460 DP/LVDS bridge */ COMPAT_SAMSUNG_EXYNOS_SYSMMU, /* Exynos sysmmu */ - COMPAT_PARADE_PS8625, /* Parade PS8622 EDP->LVDS bridge */ COMPAT_INTEL_MICROCODE, /* Intel microcode update */ COMPAT_MEMORY_SPD, /* Memory SPD information */ COMPAT_INTEL_PANTHERPOINT_AHCI, /* Intel Pantherpoint AHCI */ diff --git a/include/parade.h b/include/parade.h deleted file mode 100644 index 887f56d..0000000 --- a/include/parade.h +++ /dev/null @@ -1,18 +0,0 @@ -/* - * (C) Copyright 2012 Samsung Electronics - * Donghwa Lee dh09.lee@samsung.com - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#ifndef __PARADE_H__ -#define __PARADE_H__ - -/* Initialize the Parade dP<->LVDS bridge if present */ -#ifdef CONFIG_VIDEO_PARADE -int parade_init(const void *blob); -#else -static inline int parade_init(const void *blob) { return -1; } -#endif - -#endif /* __PARADE_H__ */ diff --git a/lib/fdtdec.c b/lib/fdtdec.c index 670612f..d70e81b 100644 --- a/lib/fdtdec.c +++ b/lib/fdtdec.c @@ -64,7 +64,6 @@ static const char * const compat_names[COMPAT_COUNT] = { COMPAT(SANDBOX_LCD_SDL, "sandbox,lcd-sdl"), COMPAT(COMPAT_NXP_PTN3460, "nxp,ptn3460"), COMPAT(SAMSUNG_EXYNOS_SYSMMU, "samsung,sysmmu-v3.3"), - COMPAT(PARADE_PS8625, "parade,ps8625"), COMPAT(INTEL_MICROCODE, "intel,microcode"), COMPAT(MEMORY_SPD, "memory-spd"), COMPAT(INTEL_PANTHERPOINT_AHCI, "intel,pantherpoint-ahci"),

On Mon, 3 Aug 2015 08:19:34 -0600 Simon Glass sjg@chromium.org wrote:
We have a new one which uses driver model and device tree configuration. Remove the old one.
Signed-off-by: Simon Glass sjg@chromium.org
Acked-by: Anatolij Gustschin agust@denx.de

On 3 August 2015 at 08:19, Simon Glass sjg@chromium.org wrote:
We have a new one which uses driver model and device tree configuration. Remove the old one.
Signed-off-by: Simon Glass sjg@chromium.org
Changes in v2: None
drivers/video/Makefile | 1 - drivers/video/parade.c | 231 -------------------------------------------- include/configs/peach-pi.h | 2 - include/configs/peach-pit.h | 2 - include/fdtdec.h | 1 - include/parade.h | 18 ---- lib/fdtdec.c | 1 - 7 files changed, 256 deletions(-) delete mode 100644 drivers/video/parade.c delete mode 100644 include/parade.h
Applied to u-boot-dm.

This has moved to driver model so we can drop the fdtdec support.
Signed-off-by: Simon Glass sjg@chromium.org ---
Changes in v2: None
include/fdtdec.h | 1 - lib/fdtdec.c | 1 - 2 files changed, 2 deletions(-)
diff --git a/include/fdtdec.h b/include/fdtdec.h index b994f2c..cd4ec66 100644 --- a/include/fdtdec.h +++ b/include/fdtdec.h @@ -170,7 +170,6 @@ enum fdt_compat_id { COMPAT_INFINEON_SLB9645_TPM, /* Infineon SLB9645 TPM */ COMPAT_SAMSUNG_EXYNOS5_I2C, /* Exynos5 High Speed I2C Controller */ COMPAT_SANDBOX_LCD_SDL, /* Sandbox LCD emulation with SDL */ - COMPAT_NXP_PTN3460, /* NXP PTN3460 DP/LVDS bridge */ COMPAT_SAMSUNG_EXYNOS_SYSMMU, /* Exynos sysmmu */ COMPAT_INTEL_MICROCODE, /* Intel microcode update */ COMPAT_MEMORY_SPD, /* Memory SPD information */ diff --git a/lib/fdtdec.c b/lib/fdtdec.c index d70e81b..aeed232 100644 --- a/lib/fdtdec.c +++ b/lib/fdtdec.c @@ -62,7 +62,6 @@ static const char * const compat_names[COMPAT_COUNT] = { COMPAT(INFINEON_SLB9645_TPM, "infineon,slb9645tt"), COMPAT(SAMSUNG_EXYNOS5_I2C, "samsung,exynos5-hsi2c"), COMPAT(SANDBOX_LCD_SDL, "sandbox,lcd-sdl"), - COMPAT(COMPAT_NXP_PTN3460, "nxp,ptn3460"), COMPAT(SAMSUNG_EXYNOS_SYSMMU, "samsung,sysmmu-v3.3"), COMPAT(INTEL_MICROCODE, "intel,microcode"), COMPAT(MEMORY_SPD, "memory-spd"),

On 3 August 2015 at 08:19, Simon Glass sjg@chromium.org wrote:
This has moved to driver model so we can drop the fdtdec support.
Signed-off-by: Simon Glass sjg@chromium.org
Changes in v2: None
include/fdtdec.h | 1 - lib/fdtdec.c | 1 - 2 files changed, 2 deletions(-)
Applied to u-boot-dm.

We always use device tree on exynos, so remove the unused code.
Signed-off-by: Simon Glass sjg@chromium.org ---
Changes in v2: None
arch/arm/include/asm/arch-exynos/dp_info.h | 2 -- drivers/video/exynos_dp.c | 22 ---------------------- 2 files changed, 24 deletions(-)
diff --git a/arch/arm/include/asm/arch-exynos/dp_info.h b/arch/arm/include/asm/arch-exynos/dp_info.h index 3f6750a..17e8f56 100644 --- a/arch/arm/include/asm/arch-exynos/dp_info.h +++ b/arch/arm/include/asm/arch-exynos/dp_info.h @@ -197,6 +197,4 @@ unsigned int exynos_init_dp(void) } #endif
-void exynos_set_dp_platform_data(struct exynos_dp_platform_data *pd); - #endif /* _DP_INFO_H */ diff --git a/drivers/video/exynos_dp.c b/drivers/video/exynos_dp.c index c3f7a3a..5b6fc14 100644 --- a/drivers/video/exynos_dp.c +++ b/drivers/video/exynos_dp.c @@ -22,8 +22,6 @@
DECLARE_GLOBAL_DATA_PTR;
-static struct exynos_dp_platform_data *dp_pd; - void __exynos_set_dp_phy(unsigned int onoff) { } @@ -851,7 +849,6 @@ static unsigned int exynos_dp_config_video(struct edp_device_info *edp_info) return ret; }
-#ifdef CONFIG_OF_CONTROL int exynos_dp_parse_dt(const void *blob, struct edp_device_info *edp_info) { unsigned int node = fdtdec_next_compatible(blob, 0, @@ -905,7 +902,6 @@ int exynos_dp_parse_dt(const void *blob, struct edp_device_info *edp_info) "samsung,color-depth", 0); return 0; } -#endif
unsigned int exynos_init_dp(void) { @@ -918,16 +914,8 @@ unsigned int exynos_init_dp(void) return -EFAULT; }
-#ifdef CONFIG_OF_CONTROL if (exynos_dp_parse_dt(gd->fdt_blob, edp_info)) debug("unable to parse DP DT node\n"); -#else - edp_info = dp_pd->edp_dev_info; - if (edp_info == NULL) { - debug("failed to get edp_info data.\n"); - return -EFAULT; - } -#endif
exynos_dp_set_base_addr();
@@ -971,13 +959,3 @@ unsigned int exynos_init_dp(void)
return ret; } - -void exynos_set_dp_platform_data(struct exynos_dp_platform_data *pd) -{ - if (pd == NULL) { - debug("pd is NULL\n"); - return; - } - - dp_pd = pd; -}

Hi Simon,
On Mon, 3 Aug 2015 08:19:36 -0600 Simon Glass sjg@chromium.org wrote:
We always use device tree on exynos, so remove the unused code.
Signed-off-by: Simon Glass sjg@chromium.org
Acked-by: Anatolij Gustschin agust@denx.de

On 3 August 2015 at 08:19, Simon Glass sjg@chromium.org wrote:
We always use device tree on exynos, so remove the unused code.
Signed-off-by: Simon Glass sjg@chromium.org
Changes in v2: None
arch/arm/include/asm/arch-exynos/dp_info.h | 2 -- drivers/video/exynos_dp.c | 22 ---------------------- 2 files changed, 24 deletions(-)
Applied to u-boot-dm.

Spring is the first ARM-based HP Chromebook 11. It is similar to snow and it uses the same Samsung Exynos5250 chip. But has some unusual features. Mainline support for it has lagged snow (both in kernel and U-Boot). Now that the exynos5 code is common we can support spring just by adding a device tree and a few lines of configuration.
Signed-off-by: Simon Glass sjg@chromium.org ---
Changes in v2: - Rebase to dm/master
arch/arm/cpu/armv7/exynos/Kconfig | 6 + arch/arm/dts/Makefile | 1 + arch/arm/dts/exynos5250-spring.dts | 588 +++++++++++++++++++++++++++++++++++++ board/samsung/smdk5250/Kconfig | 13 + board/samsung/smdk5250/MAINTAINERS | 6 + configs/spring_defconfig | 42 +++ include/configs/spring.h | 20 ++ 7 files changed, 676 insertions(+) create mode 100644 arch/arm/dts/exynos5250-spring.dts create mode 100644 configs/spring_defconfig create mode 100644 include/configs/spring.h
diff --git a/arch/arm/cpu/armv7/exynos/Kconfig b/arch/arm/cpu/armv7/exynos/Kconfig index 4a7d82f..37b89b0 100644 --- a/arch/arm/cpu/armv7/exynos/Kconfig +++ b/arch/arm/cpu/armv7/exynos/Kconfig @@ -51,6 +51,12 @@ config TARGET_SNOW select OF_CONTROL select SPL_DISABLE_OF_CONTROL
+config TARGET_SPRING + bool "Spring board" + select SUPPORT_SPL + select OF_CONTROL + select SPL_DISABLE_OF_CONTROL + config TARGET_SMDK5420 bool "SMDK5420 board" select SUPPORT_SPL diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile index ba63553..2df957c 100644 --- a/arch/arm/dts/Makefile +++ b/arch/arm/dts/Makefile @@ -9,6 +9,7 @@ dtb-$(CONFIG_EXYNOS4) += exynos4210-origen.dtb \
dtb-$(CONFIG_EXYNOS5) += exynos5250-arndale.dtb \ exynos5250-snow.dtb \ + exynos5250-spring.dtb \ exynos5250-smdk5250.dtb \ exynos5420-smdk5420.dtb \ exynos5420-peach-pit.dtb \ diff --git a/arch/arm/dts/exynos5250-spring.dts b/arch/arm/dts/exynos5250-spring.dts new file mode 100644 index 0000000..76d5323 --- /dev/null +++ b/arch/arm/dts/exynos5250-spring.dts @@ -0,0 +1,588 @@ +/* + * Google Spring board device tree source + * + * Copyright (c) 2013 Google, Inc + * Copyright (c) 2014 SUSE LINUX Products GmbH + * + * SPDX-License-Identifier: GPL-2.0 + */ + +/dts-v1/; +#include <dt-bindings/gpio/gpio.h> +#include <dt-bindings/interrupt-controller/irq.h> +#include <dt-bindings/input/input.h> +#include "exynos5250.dtsi" + +/ { + model = "Google Spring"; + compatible = "google,spring", "samsung,exynos5250", "samsung,exynos5"; + + aliases { + i2c0 = "/i2c@12C60000"; + i2c1 = "/i2c@12C70000"; + i2c2 = "/i2c@12C80000"; + i2c3 = "/i2c@12C90000"; + i2c4 = "/i2c@12CA0000"; + i2c5 = "/i2c@12CB0000"; + i2c6 = "/i2c@12CC0000"; + i2c7 = "/i2c@12CD0000"; + i2c104 = &cros_ec_ldo_tunnel; + spi0 = "/spi@12d20000"; + spi1 = "/spi@12d30000"; + spi2 = "/spi@12d40000"; + spi3 = "/spi@131a0000"; + spi4 = "/spi@131b0000"; + mmc0 = "/mmc@12000000"; + serial0 = "/serial@12C30000"; + console = "/serial@12C30000"; + i2s = "/sound@3830000"; + }; + + memory { + reg = <0x40000000 0x80000000>; + }; + + flash@0 { + spl { /* spl size override */ + size = <0x8000>; + }; + }; + + chosen { + bootargs = "console=tty1"; + stdout-path = "serial3:115200n8"; + }; + + board-rev { + compatible = "google,board-revision"; + google,board-rev-gpios = <&gpy4 0 0>, <&gpy4 1 0>, + <&gpy4 2 0>; + }; + + mmc@12200000 { + samsung,bus-width = <8>; + samsung,timing = <1 3 3>; + samsung,removable = <0>; + }; + + mmc@12210000 { + status = "disabled"; + }; + + mmc@12220000 { + /* MMC2 pins are used as GPIO for eDP bridge */ + status = "disabled"; + }; + + mmc@12230000 { + status = "disabled"; + }; + + ehci@12110000 { + samsung,vbus-gpio = <&gpx1 1 GPIO_ACTIVE_HIGH>; + status = "okay"; + }; + + xhci@12000000 { + samsung,vbus-gpio = <&gpx2 7 GPIO_ACTIVE_HIGH>; + }; + + spi@12d30000 { + spi-max-frequency = <50000000>; + firmware_storage_spi: flash@0 { + compatible = "spi-flash"; + reg = <0>; + }; + }; + + tmu@10060000 { + samsung,min-temp = <25>; + samsung,max-temp = <125>; + samsung,start-warning = <95>; + samsung,start-tripping = <105>; + samsung,hw-tripping = <110>; + samsung,efuse-min-value = <40>; + samsung,efuse-value = <55>; + samsung,efuse-max-value = <100>; + samsung,slope = <274761730>; + samsung,dc-value = <25>; + }; + + fimd@14400000 { + samsung,vl-freq = <60>; + samsung,vl-col = <1366>; + samsung,vl-row = <768>; + samsung,vl-width = <1366>; + samsung,vl-height = <768>; + + samsung,vl-clkp; + samsung,vl-dp; + samsung,vl-hsp; + samsung,vl-vsp; + + samsung,vl-bpix = <4>; + + samsung,vl-hspw = <32>; + samsung,vl-hbpd = <80>; + samsung,vl-hfpd = <48>; + samsung,vl-vspw = <5>; + samsung,vl-vbpd = <14>; + samsung,vl-vfpd = <3>; + samsung,vl-cmd-allow-len = <0xf>; + + samsung,winid = <0>; + samsung,interface-mode = <1>; + samsung,dp-enabled = <1>; + samsung,dual-lcd-enabled = <0>; + }; + + dp@145b0000 { + samsung,lt-status = <0>; + + samsung,master-mode = <0>; + samsung,bist-mode = <0>; + samsung,bist-pattern = <0>; + samsung,h-sync-polarity = <0>; + samsung,v-sync-polarity = <0>; + samsung,interlaced = <0>; + samsung,color-space = <0>; + samsung,dynamic-range = <0>; + samsung,ycbcr-coeff = <0>; + samsung,color-depth = <1>; + }; +}; + +&i2c_0 { + status = "okay"; + samsung,i2c-sda-delay = <100>; + samsung,i2c-max-bus-freq = <378000>; + + s5m8767-pmic@66 { + compatible = "samsung,s5m8767-pmic"; + reg = <0x66>; + interrupt-parent = <&gpx3>; + wakeup-source; + + s5m8767,pmic-buck-dvs-gpios = <&gpd1 0 GPIO_ACTIVE_LOW>, /* DVS1 */ + <&gpd1 1 GPIO_ACTIVE_LOW>, /* DVS2 */ + <&gpd1 2 GPIO_ACTIVE_LOW>; /* DVS3 */ + + s5m8767,pmic-buck-ds-gpios = <&gpx2 3 GPIO_ACTIVE_LOW>, /* SET1 */ + <&gpx2 4 GPIO_ACTIVE_LOW>, /* SET2 */ + <&gpx2 5 GPIO_ACTIVE_LOW>; /* SET3 */ + + /* + * The following arrays of DVS voltages are not used, since we are + * not using GPIOs to control PMIC bucks, but they must be defined + * to please the driver. + */ + s5m8767,pmic-buck2-dvs-voltage = <1350000>, <1300000>, + <1250000>, <1200000>, + <1150000>, <1100000>, + <1000000>, <950000>; + + s5m8767,pmic-buck3-dvs-voltage = <1100000>, <1100000>, + <1100000>, <1100000>, + <1000000>, <1000000>, + <1000000>, <1000000>; + + s5m8767,pmic-buck4-dvs-voltage = <1200000>, <1200000>, + <1200000>, <1200000>, + <1200000>, <1200000>, + <1200000>, <1200000>; + + clocks { + compatible = "samsung,s5m8767-clk"; + #clock-cells = <1>; + clock-output-names = "en32khz_ap", + "en32khz_cp", + "en32khz_bt"; + }; + + regulators { + ldo4_reg: LDO4 { + regulator-name = "P1.0V_LDO_OUT4"; + regulator-min-microvolt = <1000000>; + regulator-max-microvolt = <1000000>; + regulator-always-on; + op_mode = <0>; + }; + + ldo5_reg: LDO5 { + regulator-name = "P1.8V_LDO_OUT5"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-always-on; + op_mode = <0>; + }; + + ldo6_reg: LDO6 { + regulator-name = "vdd_mydp"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + regulator-always-on; + op_mode = <3>; + }; + + ldo7_reg: LDO7 { + regulator-name = "P1.1V_LDO_OUT7"; + regulator-min-microvolt = <1100000>; + regulator-max-microvolt = <1100000>; + regulator-always-on; + op_mode = <3>; + }; + + ldo8_reg: LDO8 { + regulator-name = "P1.0V_LDO_OUT8"; + regulator-min-microvolt = <1000000>; + regulator-max-microvolt = <1000000>; + regulator-always-on; + op_mode = <3>; + }; + + ldo10_reg: LDO10 { + regulator-name = "P1.8V_LDO_OUT10"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-always-on; + op_mode = <3>; + }; + + ldo11_reg: LDO11 { + regulator-name = "P1.8V_LDO_OUT11"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-always-on; + op_mode = <0>; + }; + + ldo12_reg: LDO12 { + regulator-name = "P3.0V_LDO_OUT12"; + regulator-min-microvolt = <3000000>; + regulator-max-microvolt = <3000000>; + regulator-always-on; + op_mode = <3>; + }; + + ldo13_reg: LDO13 { + regulator-name = "P1.8V_LDO_OUT13"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-always-on; + op_mode = <0>; + }; + + ldo14_reg: LDO14 { + regulator-name = "P1.8V_LDO_OUT14"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-always-on; + op_mode = <3>; + }; + + ldo15_reg: LDO15 { + regulator-name = "P1.0V_LDO_OUT15"; + regulator-min-microvolt = <1000000>; + regulator-max-microvolt = <1000000>; + regulator-always-on; + op_mode = <3>; + }; + + ldo16_reg: LDO16 { + regulator-name = "P1.8V_LDO_OUT16"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-always-on; + op_mode = <3>; + }; + + ldo17_reg: LDO17 { + regulator-name = "P1.2V_LDO_OUT17"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + regulator-always-on; + op_mode = <0>; + }; + + ldo25_reg: LDO25 { + regulator-name = "vdd_bridge"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + regulator-always-on; + op_mode = <1>; + }; + + buck1_reg: BUCK1 { + regulator-name = "vdd_mif"; + regulator-min-microvolt = <950000>; + regulator-max-microvolt = <1300000>; + regulator-always-on; + regulator-boot-on; + op_mode = <3>; + }; + + buck2_reg: BUCK2 { + regulator-name = "vdd_arm"; + regulator-min-microvolt = <850000>; + regulator-max-microvolt = <1350000>; + regulator-always-on; + regulator-boot-on; + op_mode = <3>; + }; + + buck3_reg: BUCK3 { + regulator-name = "vdd_int"; + regulator-min-microvolt = <900000>; + regulator-max-microvolt = <1200000>; + regulator-always-on; + regulator-boot-on; + op_mode = <3>; + }; + + buck4_reg: BUCK4 { + regulator-name = "vdd_g3d"; + regulator-min-microvolt = <850000>; + regulator-max-microvolt = <1300000>; + regulator-boot-on; + op_mode = <3>; + }; + + buck5_reg: BUCK5 { + regulator-name = "P1.8V_BUCK_OUT5"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-always-on; + regulator-boot-on; + op_mode = <1>; + }; + + buck6_reg: BUCK6 { + regulator-name = "P1.2V_BUCK_OUT6"; + regulator-min-microvolt = <2050000>; + regulator-max-microvolt = <2050000>; + regulator-always-on; + regulator-boot-on; + op_mode = <0>; + }; + + buck9_reg: BUCK9 { + regulator-name = "vdd_ummc"; + regulator-min-microvolt = <950000>; + regulator-max-microvolt = <3000000>; + regulator-always-on; + regulator-boot-on; + op_mode = <3>; + }; + }; + }; +}; + +&i2c_1 { + status = "okay"; + samsung,i2c-sda-delay = <100>; + samsung,i2c-max-bus-freq = <378000>; +}; + +&i2c_2 { + status = "okay"; + samsung,i2c-sda-delay = <100>; + samsung,i2c-max-bus-freq = <66000>; +}; + +&i2c_3 { + status = "okay"; + samsung,i2c-sda-delay = <100>; + samsung,i2c-max-bus-freq = <66000>; +}; + +&i2c_4 { + status = "okay"; + samsung,i2c-sda-delay = <100>; + samsung,i2c-max-bus-freq = <66000>; + clock-frequency = <66000>; + + cros_ec: embedded-controller { + compatible = "google,cros-ec-i2c"; + reg = <0x1e>; + interrupts = <6 IRQ_TYPE_NONE>; + interrupt-parent = <&gpx1>; + wakeup-source; + u-boot,i2c-offset-len = <0>; + ec-interrupt = <&gpx1 6 GPIO_ACTIVE_LOW>; + cros_ec_ldo_tunnel: cros-ec-ldo-tunnel { + compatible = "google,cros-ec-ldo-tunnel"; + #address-cells = <1>; + #size-cells = <0>; + power-regulator { + compatible = "ti,tps65090"; + reg = <0x48>; + + regulators { + dcdc1 { + ti,enable-ext-control; + }; + dcdc2 { + ti,enable-ext-control; + }; + dcdc3 { + ti,enable-ext-control; + }; + fet1: fet1 { + regulator-name = "vcd_led"; + ti,overcurrent-wait = <3>; + }; + tps65090_fet2: fet2 { + regulator-name = "video_mid"; + regulator-always-on; + ti,overcurrent-wait = <3>; + }; + fet3 { + regulator-name = "wwan_r"; + regulator-always-on; + ti,overcurrent-wait = <3>; + }; + fet4 { + regulator-name = "sdcard"; + ti,overcurrent-wait = <3>; + }; + fet5 { + regulator-name = "camout"; + regulator-always-on; + ti,overcurrent-wait = <3>; + }; + fet6: fet6 { + regulator-name = "lcd_vdd"; + ti,overcurrent-wait = <3>; + }; + tps65090_fet7: fet7 { + regulator-name = "video_mid_1a"; + regulator-always-on; + ti,overcurrent-wait = <3>; + }; + ldo1 { + }; + ldo2 { + }; + }; + }; + }; + }; +}; + +&i2c_5 { + status = "okay"; + samsung,i2c-sda-delay = <100>; + samsung,i2c-max-bus-freq = <66000>; +}; + +&i2c_7 { + status = "okay"; + samsung,i2c-sda-delay = <100>; + samsung,i2c-max-bus-freq = <66000>; + + ps8622-bridge@8 { + compatible = "parade,ps8622"; + reg = <0x8>; + sleep-gpios = <&gpc3 6 GPIO_ACTIVE_LOW>; + reset-gpios = <&gpc3 1 GPIO_ACTIVE_LOW>; + hotplug-gpios = <&gpc3 0 GPIO_ACTIVE_HIGH>; + power-supply = <&ldo6_reg>; + parade,regs = /bits/ 8 < + 0x02 0xa1 0x01 /* HPD low */ + /* + * SW setting: [1:0] SW output 1.2V voltage is + * lower to 96% + */ + 0x04 0x14 0x01 + /* RCO SS setting: [5:4] = b01 0.5%, b10 1%, b11 1.5% */ + 0x04 0xe3 0x20 + 0x04 0xe2 0x80 /* [7] RCO SS enable */ + /* + * RPHY Setting: [3:2] CDR tune wait cycle before + * measure for fine tune b00: 1us, + * 01: 0.5us, 10:2us, 11:4us + */ + 0x04 0x8a 0x0c + 0x04 0x89 0x08 /* [3] RFD always on */ + /* + * CTN lock in/out: 20000ppm/80000ppm. Lock out 2 times + */ + 0x04 0x71 0x2d + /* 2.7G CDR settings */ + 0x04 0x7d 0x07 /* NOF=40LSB for HBR CDR setting */ + 0x04 0x7b 0x00 /* [1:0] Fmin=+4bands */ + 0x04 0x7a 0xfd /* [7:5] DCO_FTRNG=+-40% */ + /* + * 1.62G CDR settings: + * [5:2]NOF=64LSB [1:0]DCO scale is 2/5 + */ + 0x04 0xc0 0x12 + 0x04 0xc1 0x92 /* Gitune=-37% */ + 0x04 0xc2 0x1c /* Fbstep=100% */ + 0x04 0x32 0x80 /* [7] LOS signal disable */ + /* RPIO Setting */ + /* [7:4] LVDS driver bias current 75% (250mV swing) */ + 0x04 0x00 0xb0 + /* [7:6] Right-bar GPIO output strength is 8mA */ + 0x04 0x15 0x40 + /* EQ Training State Machine Setting */ + 0x04 0x54 0x10 /* RCO calibration start */ + /* [4:0] MAX_LANE_COUNT set to one lane */ + 0x01 0x02 0x81 + /* [4:0] LANE_COUNT_SET set to one lane */ + 0x01 0x21 0x81 + 0x00 0x52 0x20 + 0x00 0xf1 0x03 /* HPD CP toggle enable */ + 0x00 0x62 0x41 + /* Counter number add 1ms counter delay */ + 0x00 0xf6 0x01 + /* + * [6]PWM function control by DPCD0040f[7], default + * is PWM block always works + */ + 0x00 0x77 0x06 + 0x00 0x4c 0x04 + /* + * 04h Adjust VTotal tolerance to fix the 30Hz no- + * display issue + * DPCD00400='h00 Parade OUI = 'h001cf8 + */ + 0x01 0xc0 0x00 + 0x01 0xc1 0x1c /* DPCD00401='h1c */ + 0x01 0xc2 0xf8 /* DPCD00402='hf8 */ + /* DPCD403~408 = ASCII code D2SLV5='h4432534c5635 */ + 0x01 0xc3 0x44 + 0x01 0xc4 0x32 /* DPCD404 */ + 0x01 0xc5 0x53 /* DPCD405 */ + 0x01 0xc6 0x4c /* DPCD406 */ + 0x01 0xc7 0x56 /* DPCD407 */ + 0x01 0xc8 0x35 /* DPCD408 */ + /* DPCD40A Initial Code major revision '01' */ + 0x01 0xca 0x01 + /* DPCD40B Initial Code minor revision '05' */ + 0x01 0xcb 0x05 + 0x01 0xa5 0xa0 /* DPCD720, Select internal PWM */ + /* + * 0xff for 100% PWM of brightness, 0h for 0% brightness + */ + 0x01 0xa7 0x00 + /* + * Set LVDS output as 6bit-VESA mapping, single LVDS + * channel + */ + 0x01 0xcc 0x13 + 0x02 0xb1 0x20 /* Enable SSC set by register */ + /* Set SSC enabled and +/-1% central spreading */ + 0x04 0x10 0x16 + 0x04 0x59 0x60 /* MPU Clock source: LC => RCO */ + 0x04 0x54 0x14 /* LC -> RCO */ + 0x02 0xa1 0x91>; /* HPD high */ + }; + + soundcodec@20 { + reg = <0x20>; + compatible = "maxim,max98088-codec"; + }; +}; + +#include "cros-ec-keyboard.dtsi" diff --git a/board/samsung/smdk5250/Kconfig b/board/samsung/smdk5250/Kconfig index 698ee91..11ffaee 100644 --- a/board/samsung/smdk5250/Kconfig +++ b/board/samsung/smdk5250/Kconfig @@ -23,3 +23,16 @@ config SYS_CONFIG_NAME default "snow"
endif + +if TARGET_SPRING + +config SYS_BOARD + default "smdk5250" + +config SYS_VENDOR + default "samsung" + +config SYS_CONFIG_NAME + default "spring" + +endif diff --git a/board/samsung/smdk5250/MAINTAINERS b/board/samsung/smdk5250/MAINTAINERS index 070593e..cde966f 100644 --- a/board/samsung/smdk5250/MAINTAINERS +++ b/board/samsung/smdk5250/MAINTAINERS @@ -10,3 +10,9 @@ M: Akshay Saraswat akshay.s@samsung.com S: Maintained F: include/configs/snow.h F: configs/snow_defconfig + +SPRING BOARD +M: Simon Glass sjg@chromium.org +S: Maintained +F: include/configs/spring.h +F: configs/spring_defconfig diff --git a/configs/spring_defconfig b/configs/spring_defconfig new file mode 100644 index 0000000..a3abb35 --- /dev/null +++ b/configs/spring_defconfig @@ -0,0 +1,42 @@ +CONFIG_ARM=y +CONFIG_ARCH_EXYNOS=y +CONFIG_TARGET_SPRING=y +CONFIG_DEFAULT_DEVICE_TREE="exynos5250-spring" +CONFIG_SPL=y +# CONFIG_CMD_IMLS is not set +# CONFIG_CMD_SETEXPR is not set +CONFIG_CMD_SOUND=y +CONFIG_SPI_FLASH=y +CONFIG_CMD_CROS_EC=y +CONFIG_CROS_EC=y +CONFIG_CROS_EC_I2C=y +CONFIG_CROS_EC_KEYB=y +CONFIG_SOUND=y +CONFIG_I2S=y +CONFIG_I2S_SAMSUNG=y +CONFIG_SOUND_MAX98095=y +CONFIG_SOUND_WM8994=y +CONFIG_USB=y +CONFIG_DM_USB=y +CONFIG_DM_I2C=y +CONFIG_DM_PMIC=y +CONFIG_DM_REGULATOR=y +CONFIG_PMIC_TPS65090=y +CONFIG_REGULATOR_TPS65090=y +CONFIG_DM_I2C_COMPAT=y +CONFIG_I2C_ARB_GPIO_CHALLENGE=y +CONFIG_I2C_MUX=y +CONFIG_CMD_PMIC=y +CONFIG_CMD_REGULATOR=y +CONFIG_ERRNO_STR=y +CONFIG_DM_PMIC_MAX77686=y +CONFIG_DM_REGULATOR_MAX77686=y +CONFIG_DEBUG_UART=y +CONFIG_DEBUG_UART_S5P=y +CONFIG_DEBUG_UART_CLOCK=100000000 +CONFIG_DEBUG_UART_BASE=0x12c30000 +CONFIG_I2C_CROS_EC_LDO=y +CONFIG_PMIC_S5M8767=y +CONFIG_REGULATOR_S5M8767=y +CONFIG_VIDEO_BRIDGE=y +CONFIG_VIDEO_BRIDGE_PARADE_PS862X=y diff --git a/include/configs/spring.h b/include/configs/spring.h new file mode 100644 index 0000000..a692dfd --- /dev/null +++ b/include/configs/spring.h @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2015 Google, Inc + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef __CONFIG_SPRING_H +#define __CONFIG_SPRING_H + +#include <configs/exynos5250-common.h> +#include <configs/exynos5-dt-common.h> +#include <configs/exynos5-common.h> + +#define CONFIG_BOARD_COMMON + +#define CONFIG_SYS_PROMPT "spring # " +#define CONFIG_IDENT_STRING " for spring" +#define CONFIG_DEFAULT_CONSOLE "console=ttySAC1,115200n8\0" + +#endif /* __CONFIG_SPRING_H */

On 3 August 2015 at 08:19, Simon Glass sjg@chromium.org wrote:
Spring is the first ARM-based HP Chromebook 11. It is similar to snow and it uses the same Samsung Exynos5250 chip. But has some unusual features. Mainline support for it has lagged snow (both in kernel and U-Boot). Now that the exynos5 code is common we can support spring just by adding a device tree and a few lines of configuration.
Signed-off-by: Simon Glass sjg@chromium.org
Changes in v2:
- Rebase to dm/master
arch/arm/cpu/armv7/exynos/Kconfig | 6 + arch/arm/dts/Makefile | 1 + arch/arm/dts/exynos5250-spring.dts | 588 +++++++++++++++++++++++++++++++++++++ board/samsung/smdk5250/Kconfig | 13 + board/samsung/smdk5250/MAINTAINERS | 6 + configs/spring_defconfig | 42 +++ include/configs/spring.h | 20 ++ 7 files changed, 676 insertions(+) create mode 100644 arch/arm/dts/exynos5250-spring.dts create mode 100644 configs/spring_defconfig create mode 100644 include/configs/spring.h
Applied to u-boot-dm.

Hello Simon,
On 08/03/2015 04:19 PM, Simon Glass wrote:
This series adds a number of fixes and improvements to driver model as well as two new uclasses (video bridges and I2c muxes).
The series is aimed at adding support for spring (HP 11 Chromebook). Since it is very similar to other ARM Chromebooks, some effory is made to use common code rather than duplicating functionality. In fact spring uses the same code as several other boards, just with a different device tree and a few configuration changes.
Audio works correctly on pit, pi, spring and snow with this series. A bug in the I2C driver broken this recently.
The exynos implementation still has a few rough areas - e.g. some hard-coded GPIOs and the old-style SPL. Also it does not yet support CPU frequency scaling and power management.
Spring has some oddities and they are hard to handle with U-Boot's old way of doing drivers. With driver model these can be implemented cleanly and this sort of problem was the original motivation for my interest in driver model.
This series is available at u-boot-dm in branch spring-working. It is based on the previous set of driver model changes in branch clk-working.
Changes in v2:
- Add a README explaining the algorithm and update the commit message
- Add a comment about DVS in the driver
- Add a new patch to hold off the need for driver model pinctrl
- Add new patch to correct LDO and BUCK naming
- Rebase to dm/master
- Update commit message and header file to better explain select()/deselect()
Simon Glass (19): exynos: dts: Correct LDO and BUCK naming video: Work around lack of pinctrl dm: i2c: Add support for multiplexed I2C buses i2c: Add a mux for GPIO-based I2C bus arbitration dm: cros_ec: Convert the I2C tunnel code to use driver model cros_ec: Support the LDO access method used by spring dm: pmic: max77686: Support all BUCK regulators exynos: dts: Drop the old TPS65090 I2C node exynos: Add common board code for exynos5 boards that use device tree exynos: Enable new features for exynos5 boards exynos: config: Move common options to the common headers and tidy up exynos: Drop old exynos5420-specific board code exynos: Drop old exynos5250-specific board code power: Remove old TPS65090 drivers cros_ec: Remove the old tunnel code video: Remove the old parade driver dts: Drop unused compatible ID for the NXP video bridge exynos: video: Remove non-device-tree code exynos: Add support for spring
arch/arm/cpu/armv7/exynos/Kconfig | 6 + arch/arm/dts/Makefile | 1 + arch/arm/dts/exynos4412-odroid.dts | 56 +-- arch/arm/dts/exynos4412-trats2.dts | 70 ++-- arch/arm/dts/exynos5250-snow.dts | 16 - arch/arm/dts/exynos5250-spring.dts | 588 +++++++++++++++++++++++++++++ arch/arm/include/asm/arch-exynos/dp_info.h | 2 - board/samsung/common/Makefile | 1 + board/samsung/common/exynos5-dt.c | 362 ++++++++++++++++++ board/samsung/smdk5250/Kconfig | 13 + board/samsung/smdk5250/MAINTAINERS | 6 + board/samsung/smdk5250/Makefile | 4 - board/samsung/smdk5250/exynos5-dt.c | 306 --------------- board/samsung/smdk5420/Makefile | 4 - board/samsung/smdk5420/smdk5420.c | 143 ------- configs/arndale_defconfig | 2 + configs/odroid-xu3_defconfig | 6 + configs/peach-pi_defconfig | 19 + configs/peach-pit_defconfig | 19 + configs/smdk5250_defconfig | 10 + configs/smdk5420_defconfig | 6 + configs/snow_defconfig | 23 ++ configs/spring_defconfig | 42 +++ doc/README.i2c | 60 +++ doc/device-tree-bindings/i2c/i2c-mux.txt | 60 +++ drivers/i2c/Kconfig | 26 ++ drivers/i2c/Makefile | 4 + drivers/i2c/cros_ec_ldo.c | 77 ++++ drivers/i2c/cros_ec_tunnel.c | 41 ++ drivers/i2c/muxes/Kconfig | 17 + drivers/i2c/muxes/Makefile | 7 + drivers/i2c/muxes/i2c-arb-gpio-challenge.c | 147 ++++++++ drivers/i2c/muxes/i2c-mux-uclass.c | 198 ++++++++++ drivers/misc/cros_ec.c | 288 +++----------- drivers/power/pmic/Makefile | 2 - drivers/power/pmic/pmic_tps65090.c | 310 --------------- drivers/power/pmic/pmic_tps65090_ec.c | 218 ----------- drivers/power/regulator/max77686.c | 18 +- drivers/video/Makefile | 1 - drivers/video/bridge/video-bridge-uclass.c | 28 +- drivers/video/exynos_dp.c | 22 -- drivers/video/parade.c | 231 ------------ include/configs/arndale.h | 18 +- include/configs/exynos5-common.h | 13 +- include/configs/exynos5-dt-common.h | 21 +- include/configs/exynos5250-common.h | 16 +- include/configs/exynos5420-common.h | 9 +- include/configs/odroid_xu3.h | 2 + include/configs/peach-pi.h | 14 +- include/configs/peach-pit.h | 24 +- include/configs/smdk5250.h | 16 +- include/configs/smdk5420.h | 10 +- include/configs/snow.h | 15 +- include/configs/spring.h | 20 + include/cros_ec.h | 16 +- include/dm/uclass-id.h | 1 + include/fdtdec.h | 3 - include/i2c.h | 39 ++ include/parade.h | 18 - include/power/tps65090_pmic.h | 73 ---- lib/fdtdec.c | 3 - 61 files changed, 1997 insertions(+), 1794 deletions(-) create mode 100644 arch/arm/dts/exynos5250-spring.dts create mode 100644 board/samsung/common/exynos5-dt.c delete mode 100644 board/samsung/smdk5250/exynos5-dt.c delete mode 100644 board/samsung/smdk5420/smdk5420.c create mode 100644 configs/spring_defconfig create mode 100644 doc/README.i2c create mode 100644 doc/device-tree-bindings/i2c/i2c-mux.txt create mode 100644 drivers/i2c/cros_ec_ldo.c create mode 100644 drivers/i2c/cros_ec_tunnel.c create mode 100644 drivers/i2c/muxes/Kconfig create mode 100644 drivers/i2c/muxes/Makefile create mode 100644 drivers/i2c/muxes/i2c-arb-gpio-challenge.c create mode 100644 drivers/i2c/muxes/i2c-mux-uclass.c delete mode 100644 drivers/power/pmic/pmic_tps65090.c delete mode 100644 drivers/power/pmic/pmic_tps65090_ec.c delete mode 100644 drivers/video/parade.c create mode 100644 include/configs/spring.h delete mode 100644 include/parade.h delete mode 100644 include/power/tps65090_pmic.h
That's great job! I've got only two cosmetics comments.
Tested-on: Odroid U3(E4412) and Odroid XU3(E5422).
Acked-by: Przemyslaw Marczak p.marczak@smsung.com
Best regards,
participants (3)
-
Anatolij Gustschin
-
Przemyslaw Marczak
-
Simon Glass