summaryrefslogtreecommitdiff
path: root/drivers/i2c
diff options
context:
space:
mode:
authorTom Rini <trini@konsulko.com>2022-04-05 15:33:32 +0300
committerTom Rini <trini@konsulko.com>2022-04-05 15:33:32 +0300
commit4de720e98d552dfda9278516bf788c4a73b3e56f (patch)
tree063af389b20d9b742486a1a834978676d1f42e87 /drivers/i2c
parent01f1ab67f38882dc7665a0a6eca4bbeba6d84f81 (diff)
parent69a0ea007826bf27584943591e61ee087683fdca (diff)
downloadu-boot-4de720e98d552dfda9278516bf788c4a73b3e56f.tar.xz
Merge branch 'master' of https://source.denx.de/u-boot/custodians/u-boot-sunxi
A big part is the DM pinctrl driver, which allows us to get rid of quite some custom pinmux code and make the whole port much more robust. Many thanks to Samuel for that nice contribution! There are some more or less cosmetic warnings about missing clocks right now, I will send the trivial fixes for that later. Another big chunk is the mkimage upgrade, which adds RISC-V and TOC0 (secure images) support. Both features are unused at the moment, but I have an always-secure board that will use that once the DT lands in the kernel. On top of those big things we have some smaller fixes, improving the I2C DM support, fixing some H6/H616 early clock setup and improving the eMMC boot partition support. The gitlab CI completed successfully, including the build test for all 161 sunxi boards. I also boot tested on a A64, A20, H3, H6, and F1C100 board. USB, SD card, eMMC, and Ethernet all work there (where applicable).
Diffstat (limited to 'drivers/i2c')
-rw-r--r--drivers/i2c/sun6i_p2wi.c27
-rw-r--r--drivers/i2c/sun8i_rsb.c61
2 files changed, 53 insertions, 35 deletions
diff --git a/drivers/i2c/sun6i_p2wi.c b/drivers/i2c/sun6i_p2wi.c
index c9e1b3fcd5..d221323295 100644
--- a/drivers/i2c/sun6i_p2wi.c
+++ b/drivers/i2c/sun6i_p2wi.c
@@ -14,10 +14,12 @@
*/
#include <axp_pmic.h>
+#include <clk.h>
#include <common.h>
#include <dm.h>
#include <errno.h>
#include <i2c.h>
+#include <reset.h>
#include <time.h>
#include <asm/io.h>
#include <asm/arch/cpu.h>
@@ -102,12 +104,6 @@ static int sun6i_p2wi_change_to_p2wi_mode(struct sunxi_p2wi_reg *base,
static void sun6i_p2wi_init(struct sunxi_p2wi_reg *base)
{
- /* Enable p2wi and PIO clk, and de-assert their resets */
- prcm_apb0_enable(PRCM_APB0_GATE_PIO | PRCM_APB0_GATE_P2WI);
-
- sunxi_gpio_set_cfgpin(SUNXI_GPL(0), SUN6I_GPL0_R_P2WI_SCK);
- sunxi_gpio_set_cfgpin(SUNXI_GPL(1), SUN6I_GPL1_R_P2WI_SDA);
-
/* Reset p2wi controller and set clock to CLKIN(12)/8 = 1.5 MHz */
writel(P2WI_CTRL_RESET, &base->ctrl);
sdelay(0x100);
@@ -142,6 +138,12 @@ void p2wi_init(void)
{
struct sunxi_p2wi_reg *base = (struct sunxi_p2wi_reg *)SUN6I_P2WI_BASE;
+ /* Enable p2wi and PIO clk, and de-assert their resets */
+ prcm_apb0_enable(PRCM_APB0_GATE_PIO | PRCM_APB0_GATE_P2WI);
+
+ sunxi_gpio_set_cfgpin(SUNXI_GPL(0), SUN6I_GPL0_R_P2WI_SCK);
+ sunxi_gpio_set_cfgpin(SUNXI_GPL(1), SUN6I_GPL1_R_P2WI_SDA);
+
sun6i_p2wi_init(base);
}
#endif
@@ -180,9 +182,19 @@ static int sun6i_p2wi_probe_chip(struct udevice *bus, uint chip_addr,
static int sun6i_p2wi_probe(struct udevice *bus)
{
struct sun6i_p2wi_priv *priv = dev_get_priv(bus);
+ struct reset_ctl *reset;
+ struct clk *clk;
priv->base = dev_read_addr_ptr(bus);
+ reset = devm_reset_control_get(bus, NULL);
+ if (!IS_ERR(reset))
+ reset_deassert(reset);
+
+ clk = devm_clk_get(bus, NULL);
+ if (!IS_ERR(clk))
+ clk_enable(clk);
+
sun6i_p2wi_init(priv->base);
return 0;
@@ -191,11 +203,12 @@ static int sun6i_p2wi_probe(struct udevice *bus)
static int sun6i_p2wi_child_pre_probe(struct udevice *child)
{
struct dm_i2c_chip *chip = dev_get_parent_plat(child);
+ struct udevice *bus = child->parent;
/* Ensure each transfer is for a single register. */
chip->flags |= DM_I2C_CHIP_RD_ADDRESS | DM_I2C_CHIP_WR_ADDRESS;
- return 0;
+ return sun6i_p2wi_probe_chip(bus, chip->chip_addr, 0);
}
static const struct dm_i2c_ops sun6i_p2wi_ops = {
diff --git a/drivers/i2c/sun8i_rsb.c b/drivers/i2c/sun8i_rsb.c
index 716b245a00..47fa05b6d1 100644
--- a/drivers/i2c/sun8i_rsb.c
+++ b/drivers/i2c/sun8i_rsb.c
@@ -9,10 +9,12 @@
*/
#include <axp_pmic.h>
+#include <clk.h>
#include <common.h>
#include <dm.h>
#include <errno.h>
#include <i2c.h>
+#include <reset.h>
#include <time.h>
#include <asm/arch/cpu.h>
#include <asm/arch/gpio.h>
@@ -95,27 +97,6 @@ static int sun8i_rsb_set_device_address(struct sunxi_rsb_reg *base,
return sun8i_rsb_do_trans(base);
}
-static void sun8i_rsb_cfg_io(void)
-{
-#ifdef CONFIG_MACH_SUN8I
- sunxi_gpio_set_cfgpin(SUNXI_GPL(0), SUN8I_GPL_R_RSB);
- sunxi_gpio_set_cfgpin(SUNXI_GPL(1), SUN8I_GPL_R_RSB);
- sunxi_gpio_set_pull(SUNXI_GPL(0), 1);
- sunxi_gpio_set_pull(SUNXI_GPL(1), 1);
- sunxi_gpio_set_drv(SUNXI_GPL(0), 2);
- sunxi_gpio_set_drv(SUNXI_GPL(1), 2);
-#elif defined CONFIG_MACH_SUN9I
- sunxi_gpio_set_cfgpin(SUNXI_GPN(0), SUN9I_GPN_R_RSB);
- sunxi_gpio_set_cfgpin(SUNXI_GPN(1), SUN9I_GPN_R_RSB);
- sunxi_gpio_set_pull(SUNXI_GPN(0), 1);
- sunxi_gpio_set_pull(SUNXI_GPN(1), 1);
- sunxi_gpio_set_drv(SUNXI_GPN(0), 2);
- sunxi_gpio_set_drv(SUNXI_GPN(1), 2);
-#else
-#error unsupported MACH_SUNXI
-#endif
-}
-
static void sun8i_rsb_set_clk(struct sunxi_rsb_reg *base)
{
u32 div = 0;
@@ -147,12 +128,6 @@ static int sun8i_rsb_set_device_mode(struct sunxi_rsb_reg *base)
static int sun8i_rsb_init(struct sunxi_rsb_reg *base)
{
- /* Enable RSB and PIO clk, and de-assert their resets */
- prcm_apb0_enable(PRCM_APB0_GATE_PIO | PRCM_APB0_GATE_RSB);
-
- /* Setup external pins */
- sun8i_rsb_cfg_io();
-
writel(RSB_CTRL_SOFT_RST, &base->ctrl);
sun8i_rsb_set_clk(base);
@@ -185,6 +160,25 @@ int rsb_init(void)
{
struct sunxi_rsb_reg *base = (struct sunxi_rsb_reg *)SUNXI_RSB_BASE;
+ /* Enable RSB and PIO clk, and de-assert their resets */
+ prcm_apb0_enable(PRCM_APB0_GATE_PIO | PRCM_APB0_GATE_RSB);
+
+ if (IS_ENABLED(CONFIG_MACH_SUN9I)) {
+ sunxi_gpio_set_cfgpin(SUNXI_GPN(0), SUN9I_GPN_R_RSB);
+ sunxi_gpio_set_cfgpin(SUNXI_GPN(1), SUN9I_GPN_R_RSB);
+ sunxi_gpio_set_pull(SUNXI_GPN(0), 1);
+ sunxi_gpio_set_pull(SUNXI_GPN(1), 1);
+ sunxi_gpio_set_drv(SUNXI_GPN(0), 2);
+ sunxi_gpio_set_drv(SUNXI_GPN(1), 2);
+ } else {
+ sunxi_gpio_set_cfgpin(SUNXI_GPL(0), SUN8I_GPL_R_RSB);
+ sunxi_gpio_set_cfgpin(SUNXI_GPL(1), SUN8I_GPL_R_RSB);
+ sunxi_gpio_set_pull(SUNXI_GPL(0), 1);
+ sunxi_gpio_set_pull(SUNXI_GPL(1), 1);
+ sunxi_gpio_set_drv(SUNXI_GPL(0), 2);
+ sunxi_gpio_set_drv(SUNXI_GPL(1), 2);
+ }
+
return sun8i_rsb_init(base);
}
#endif
@@ -243,20 +237,31 @@ static int sun8i_rsb_probe_chip(struct udevice *bus, uint chip_addr,
static int sun8i_rsb_probe(struct udevice *bus)
{
struct sun8i_rsb_priv *priv = dev_get_priv(bus);
+ struct reset_ctl *reset;
+ struct clk *clk;
priv->base = dev_read_addr_ptr(bus);
+ reset = devm_reset_control_get(bus, NULL);
+ if (!IS_ERR(reset))
+ reset_deassert(reset);
+
+ clk = devm_clk_get(bus, NULL);
+ if (!IS_ERR(clk))
+ clk_enable(clk);
+
return sun8i_rsb_init(priv->base);
}
static int sun8i_rsb_child_pre_probe(struct udevice *child)
{
struct dm_i2c_chip *chip = dev_get_parent_plat(child);
+ struct udevice *bus = child->parent;
/* Ensure each transfer is for a single register. */
chip->flags |= DM_I2C_CHIP_RD_ADDRESS | DM_I2C_CHIP_WR_ADDRESS;
- return 0;
+ return sun8i_rsb_probe_chip(bus, chip->chip_addr, 0);
}
static const struct dm_i2c_ops sun8i_rsb_ops = {