Hi Stephen, On 27 July 2016 at 15:48, Stephen Warren <swar...@wwwdotorg.org> wrote: > From: Bryan Wu <pe...@nvidia.com> > > clk/reset API was tested on T186 platform and previous chip like > T210/T124 will still use the old APIs. > > Signed-off-by: Bryan Wu <pe...@nvidia.com> > (swarren, simplified some ifdefs, removed indent level inside an ifdef) > Signed-off-by: Stephen Warren <swar...@nvidia.com> > Cc: Heiko Schocher <h...@denx.de> > --- > drivers/i2c/tegra_i2c.c | 80 > ++++++++++++++++++++++++++++++++++++++++++++++--- > 1 file changed, 76 insertions(+), 4 deletions(-) > > diff --git a/drivers/i2c/tegra_i2c.c b/drivers/i2c/tegra_i2c.c > index 2fa07f9c57c4..b8cb24ec87d5 100644 > --- a/drivers/i2c/tegra_i2c.c > +++ b/drivers/i2c/tegra_i2c.c > @@ -12,11 +12,16 @@ > #include <fdtdec.h> > #include <i2c.h> > #include <asm/io.h> > +#ifdef CONFIG_TEGRA186 > +#include <clk.h> > +#include <reset.h> > +#else > #include <asm/arch/clock.h> > #include <asm/arch/funcmux.h> > -#include <asm/arch/gpio.h> > #include <asm/arch/pinmux.h> > #include <asm/arch-tegra/clk_rst.h> > +#endif > +#include <asm/arch/gpio.h> > #include <asm/arch-tegra/tegra_i2c.h> > > DECLARE_GLOBAL_DATA_PTR; > @@ -30,7 +35,12 @@ enum i2c_type { > /* Information about i2c controller */ > struct i2c_bus { > int id; > +#ifdef CONFIG_TEGRA186 > + struct reset_ctl reset_ctl; > + struct clk clk; > +#else > enum periph_id periph_id; > +#endif
This doesn't seem right - the drivers should be SoC-independent at compile-time. > int speed; > int pinmux_config; > struct i2c_control *control; > @@ -62,12 +72,41 @@ static void set_packet_mode(struct i2c_bus *i2c_bus) > static void i2c_reset_controller(struct i2c_bus *i2c_bus) > { > /* Reset I2C controller. */ > +#ifdef CONFIG_TEGRA186 > + reset_assert(&i2c_bus->reset_ctl); > + udelay(1); > + reset_deassert(&i2c_bus->reset_ctl); > + udelay(1); > +#else > reset_periph(i2c_bus->periph_id, 1); > +#endif > > /* re-program config register to packet mode */ > set_packet_mode(i2c_bus); > } > > +#ifdef CONFIG_TEGRA186 > +static int i2c_init_clock(struct i2c_bus *i2c_bus, unsigned rate) > +{ > + int ret; > + > + ret = reset_assert(&i2c_bus->reset_ctl); > + if (ret) > + return ret; > + ret = clk_enable(&i2c_bus->clk); > + if (ret) > + return ret; > + ret = clk_set_rate(&i2c_bus->clk, rate); > + if (IS_ERR_VALUE(ret)) > + return ret; > + ret = reset_deassert(&i2c_bus->reset_ctl); > + if (ret) > + return ret; > + > + return 0; > +} > +#endif > + > static void i2c_init_controller(struct i2c_bus *i2c_bus) > { > if (!i2c_bus->speed) > @@ -78,8 +117,12 @@ static void i2c_init_controller(struct i2c_bus *i2c_bus) > * here, in section 23.3.1, but in fact we seem to need a factor of > * 16 to get the right frequency. > */ > +#ifdef CONFIG_TEGRA186 > + i2c_init_clock(i2c_bus, i2c_bus->speed * 2 * 8); > +#else > clock_start_periph_pll(i2c_bus->periph_id, CLOCK_ID_PERIPH, > i2c_bus->speed * 2 * 8); > +#endif > > if (i2c_bus->type == TYPE_114) { > /* > @@ -94,12 +137,17 @@ static void i2c_init_controller(struct i2c_bus *i2c_bus) > * is running, we hang, and we need it for the new calc. > */ > int clk_div_stdfst_mode = readl(&i2c_bus->regs->clk_div) >> > 16; > + unsigned rate = CLK_MULT_STD_FAST_MODE * > + (clk_div_stdfst_mode + 1) * i2c_bus->speed * > 2; > debug("%s: CLK_DIV_STD_FAST_MODE setting = %d\n", __func__, > clk_div_stdfst_mode); > > +#ifdef CONFIG_TEGRA186 > + i2c_init_clock(i2c_bus, rate); > +#else > clock_start_periph_pll(i2c_bus->periph_id, CLOCK_ID_PERIPH, > - CLK_MULT_STD_FAST_MODE * (clk_div_stdfst_mode + 1) * > - i2c_bus->speed * 2); > + rate); > +#endif > } > > /* Reset I2C controller. */ > @@ -112,7 +160,9 @@ static void i2c_init_controller(struct i2c_bus *i2c_bus) > setbits_le32(&dvc->ctrl3, DVC_CTRL_REG3_I2C_HW_SW_PROG_MASK); > } > > +#ifndef CONFIG_TEGRA186 > funcmux_select(i2c_bus->periph_id, i2c_bus->pinmux_config); > +#endif > } > > static void send_packet_headers( > @@ -333,8 +383,12 @@ static int tegra_i2c_set_bus_speed(struct udevice *dev, > unsigned int speed) > static int tegra_i2c_probe(struct udevice *dev) > { > struct i2c_bus *i2c_bus = dev_get_priv(dev); > +#ifdef CONFIG_TEGRA186 > + int ret; > +#else > const void *blob = gd->fdt_blob; > int node = dev->of_offset; > +#endif > bool is_dvc; > > i2c_bus->id = dev->seq; > @@ -345,6 +399,18 @@ static int tegra_i2c_probe(struct udevice *dev) > * We don't have a binding for pinmux yet. Leave it out for now. So > * far no one needs anything other than the default. > */ > +#ifdef CONFIG_TEGRA186 > + ret = reset_get_by_name(dev, "i2c", &i2c_bus->reset_ctl); > + if (ret) { > + error("reset_get_by_name() failed: %d\n", ret); > + return ret; > + } > + ret = clk_get_by_name(dev, "i2c", &i2c_bus->clk); > + if (ret) { > + error("clk_get_by_name() failed: %d\n", ret); > + return ret; > + } > +#else > i2c_bus->pinmux_config = FUNCMUX_DEFAULT; > i2c_bus->periph_id = clock_decode_periph_id(blob, node); > > @@ -359,6 +425,7 @@ static int tegra_i2c_probe(struct udevice *dev) > */ > if (i2c_bus->periph_id == -1) > return -EINVAL; > +#endif > > is_dvc = dev_get_driver_data(dev) == TYPE_DVC; > if (is_dvc) { > @@ -370,7 +437,12 @@ static int tegra_i2c_probe(struct udevice *dev) > i2c_init_controller(i2c_bus); > debug("%s: controller bus %d at %p, periph_id %d, speed %d: ", > is_dvc ? "dvc" : "i2c", dev->seq, i2c_bus->regs, > - i2c_bus->periph_id, i2c_bus->speed); > +#ifndef CONFIG_TEGRA186 > + i2c_bus->periph_id, Probably the concept of periph_id can go away now? Perhaps this driver needs a clean-up? > +#else > + -1, > +#endif > + i2c_bus->speed); > > return 0; > } > -- > 2.9.2 > Regards, Simon _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot