From: Heiko Schocher <hs@denx.de>
To: u-boot@lists.denx.de
Subject: [U-Boot] [PATCH V2 3/3] i2c: tegra: add standardized clk/reset API support
Date: Mon, 8 Aug 2016 06:15:10 +0200 [thread overview]
Message-ID: <57A8074E.5030100@denx.de> (raw)
In-Reply-To: <20160805221035.12157-3-swarren@wwwdotorg.org>
Hello Stephen,
Am 06.08.2016 um 00:10 schrieb Stephen Warren:
> From: Bryan Wu <pengw@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 <pengw@nvidia.com>
> (swarren, simplified some ifdefs, removed indent level inside an ifdef)
> (swarren, added comment about the ifdefs)
> Signed-off-by: Stephen Warren <swarren@nvidia.com>
> ---
> v2: Add TODO comment describing the messy ifdefs.
> ---
> drivers/i2c/tegra_i2c.c | 89 ++++++++++++++++++++++++++++++++++++++++++++++---
> 1 file changed, 85 insertions(+), 4 deletions(-)
Reviewed-by: Heiko Schocher <hs@denx.de>
bye,
Heiko
>
> diff --git a/drivers/i2c/tegra_i2c.c b/drivers/i2c/tegra_i2c.c
> index 2fa07f9c57c4..31ba263b7295 100644
> --- a/drivers/i2c/tegra_i2c.c
> +++ b/drivers/i2c/tegra_i2c.c
> @@ -12,13 +12,27 @@
> #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>
>
> +/*
> + * FIXME: TODO: This driver contains a number of ifdef CONFIG_TEGRA186 that
> + * should not be present. These are needed because newer Tegra SoCs support
> + * only the standard clock/reset APIs, whereas older Tegra SoCs support only
> + * a custom Tegra-specific API. ASAP the older Tegra SoCs' code should be
> + * fixed to implement the standard APIs, and all drivers converted to solely
> + * use the new standard APIs, with no ifdefs.
> + */
> +
> DECLARE_GLOBAL_DATA_PTR;
>
> enum i2c_type {
> @@ -30,7 +44,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
> int speed;
> int pinmux_config;
> struct i2c_control *control;
> @@ -62,12 +81,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 +126,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 +146,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 +169,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 +392,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 +408,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 +434,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 +446,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,
> +#else
> + -1,
> +#endif
> + i2c_bus->speed);
>
> return 0;
> }
>
--
DENX Software Engineering GmbH, Managing Director: Wolfgang Denk
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
next prev parent reply other threads:[~2016-08-08 4:15 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-08-05 22:10 [U-Boot] [PATCH V2 1/3] mmc: tegra: port to standard clock/reset APIs Stephen Warren
2016-08-05 22:10 ` [U-Boot] [PATCH V2 2/3] pci: tegra: port to standard clock/reset/pwr domain APIs Stephen Warren
2016-08-06 1:40 ` Simon Glass
2016-08-05 22:10 ` [U-Boot] [PATCH V2 3/3] i2c: tegra: add standardized clk/reset API support Stephen Warren
2016-08-06 1:40 ` Simon Glass
2016-08-08 4:15 ` Heiko Schocher [this message]
2016-08-06 1:40 ` [U-Boot] [PATCH V2 1/3] mmc: tegra: port to standard clock/reset APIs Simon Glass
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=57A8074E.5030100@denx.de \
--to=hs@denx.de \
--cc=u-boot@lists.denx.de \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.