From patchwork Mon Sep 12 22:04:27 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Glass X-Patchwork-Id: 114425 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from theia.denx.de (theia.denx.de [85.214.87.163]) by ozlabs.org (Postfix) with ESMTP id 38F2AB70C3 for ; Tue, 13 Sep 2011 08:06:05 +1000 (EST) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 40EE028270; Tue, 13 Sep 2011 00:05:49 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at theia.denx.de Received: from theia.denx.de ([127.0.0.1]) by localhost (theia.denx.de [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 2HvqxCogTJ-q; Tue, 13 Sep 2011 00:05:49 +0200 (CEST) Received: from theia.denx.de (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id EFC4C282A8; Tue, 13 Sep 2011 00:05:28 +0200 (CEST) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 20A1928281 for ; Tue, 13 Sep 2011 00:05:19 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at theia.denx.de Received: from theia.denx.de ([127.0.0.1]) by localhost (theia.denx.de [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id ziB+hUqBofGI for ; Tue, 13 Sep 2011 00:05:17 +0200 (CEST) X-policyd-weight: NOT_IN_SBL_XBL_SPAMHAUS=-1.5 NOT_IN_SPAMCOP=-1.5 NOT_IN_BL_NJABL=-1.5 (only DNSBL check requested) Received: from smtp-out.google.com (smtp-out.google.com [216.239.44.51]) by theia.denx.de (Postfix) with ESMTPS id 85A4C2825A for ; Tue, 13 Sep 2011 00:05:12 +0200 (CEST) Received: from wpaz37.hot.corp.google.com (wpaz37.hot.corp.google.com [172.24.198.101]) by smtp-out.google.com with ESMTP id p8CM4tVD018048; Mon, 12 Sep 2011 15:04:55 -0700 Received: from sglass.mtv.corp.google.com (sglass.mtv.corp.google.com [172.22.72.144]) by wpaz37.hot.corp.google.com with ESMTP id p8CM4rsf029460; Mon, 12 Sep 2011 15:04:54 -0700 Received: by sglass.mtv.corp.google.com (Postfix, from userid 121222) id 7EA9D140B9B; Mon, 12 Sep 2011 15:04:52 -0700 (PDT) From: Simon Glass To: U-Boot Mailing List Date: Mon, 12 Sep 2011 15:04:27 -0700 Message-Id: <1315865067-1443-7-git-send-email-sjg@chromium.org> X-Mailer: git-send-email 1.7.3.1 In-Reply-To: <1315865067-1443-1-git-send-email-sjg@chromium.org> References: <1315865067-1443-1-git-send-email-sjg@chromium.org> X-System-Of-Record: true Cc: Grant Likely , Tom Warren Subject: [U-Boot] [RFC PATCH v2 6/6] fdt: example modification of i2c driver for fdt control X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.9 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: u-boot-bounces@lists.denx.de Errors-To: u-boot-bounces@lists.denx.de This is only an example for comment. It is not a real driver as yet. It just shows how the config is read from the fdt. You can see that the main difference (as you might expect) is whether configuration comes from the fdt or the CONFIG options. Some drivers will need changing to split their config out in such a clear way, or to add a structure to hold the config rather than using CONFIG_... options throughout their code. This also provides an example fdt fragment to show what the device is actually reading. Signed-off-by: Simon Glass --- Changes in v2: - Add example of i2c driver changes required to support fdt control - Add example fdt fragments for Tegra2 I2C, just for illustration board/nvidia/seaboard/tegra2-seaboard.dts | 20 ++++++ board/nvidia/seaboard/tegra250.dtsi | 42 +++++++++++++ drivers/i2c/tegra2_i2c.c | 91 +++++++++++++++++++++++++++++ 3 files changed, 153 insertions(+), 0 deletions(-) create mode 100644 board/nvidia/seaboard/tegra2-seaboard.dts create mode 100644 board/nvidia/seaboard/tegra250.dtsi diff --git a/board/nvidia/seaboard/tegra2-seaboard.dts b/board/nvidia/seaboard/tegra2-seaboard.dts new file mode 100644 index 0000000..2c17139 --- /dev/null +++ b/board/nvidia/seaboard/tegra2-seaboard.dts @@ -0,0 +1,20 @@ +/dts-v1/; + +/memreserve/ 0x1c000000 0x04000000; +/include/ "tegra250.dtsi" + +/ { + model = "NVIDIA Seaboard"; + compatible = "nvidia,seaboard", "nvidia,tegra250"; + + /* Enable the ports we want to use, and update the speed if needed */ + i2c@0x7000c000 { + status = "ok"; + }; + + i2c@0x7000c400 { + speed = <400000>; + status = "ok"; + }; + +}; diff --git a/board/nvidia/seaboard/tegra250.dtsi b/board/nvidia/seaboard/tegra250.dtsi new file mode 100644 index 0000000..d6dc19b --- /dev/null +++ b/board/nvidia/seaboard/tegra250.dtsi @@ -0,0 +1,42 @@ +/* This is not a real fdt! It is just for illustration in this RFC */ + +/ { + model = "NVIDIA Tegra 250"; + compatible = "nvidia,tegra250"; + + i2c@0x7000c000 { + compatible = "nvidia,tegra250-i2c"; + reg = <0x7000c000 0x006c>; + pinmux = <1>; + speed = <100000>; + periph-id = <12>; // PERIPH_ID_I2C1 + status = "disabled"; + }; + + i2c@0x7000c400 { + compatible = "nvidia,tegra250-i2c"; + reg = <0x7000c400 0x006c>; + pinmux = <2>; + speed = <100000>; + periph-id = <54>; // PERIPH_ID_I2C2 + status = "disabled"; + }; + + i2c@0x7000c500 { + compatible = "nvidia,tegra250-i2c"; + reg = <0x7000c500 0x006c>; + pinmux = <1>; + speed = <100000>; + periph-id = <67>; // PERIPH_ID_I2C3 + status = "disabled"; + }; + + i2c@0x7000d000 { + compatible = "nvidia,tegra250-i2c"; + reg = <0x7000d000 0x007c>; + pinmux = <1>; + speed = <100000>; + periph-id = <47>; // PERIPH_ID_DVC_I2C + status = "disabled"; + }; +}; diff --git a/drivers/i2c/tegra2_i2c.c b/drivers/i2c/tegra2_i2c.c index d98519c..9485b56 100644 --- a/drivers/i2c/tegra2_i2c.c +++ b/drivers/i2c/tegra2_i2c.c @@ -388,6 +388,97 @@ static int tegra2_i2c_read_data(u32 addr, u8 *data, u32 len) return error; } +#ifndef CONFIG_OF_CONTROL +/* This is the original code, whic uses CONFIG_..., TEGRA2_...,etc. */ +static const enum periph_id i2c_periph_ids[CONFIG_SYS_MAX_I2C_BUS] = { + PERIPH_ID_DVC_I2C, + PERIPH_ID_I2C1, + PERIPH_ID_I2C2, + PERIPH_ID_I2C3 +}; + +static const u32 *i2c_bus_base[CONFIG_SYS_MAX_I2C_BUS] = { + (u32 *)TEGRA2_DVC_BASE, + (u32 *)TEGRA2_I2C1_BASE, + (u32 *)TEGRA2_I2C2_BASE, + (u32 *)TEGRA2_I2C3_BASE +}; + +/* pinmux_configs based on the pinmux configuration */ +static const int pinmux_configs[CONFIG_SYS_MAX_I2C_BUS] = { + CONFIG_I2CP_PIN_MUX, /* for I2CP (DVC I2C) */ + CONFIG_I2C1_PIN_MUX, /* for I2C1 */ + CONFIG_I2C2_PIN_MUX, /* for I2C2 */ + CONFIG_I2C3_PIN_MUX /* for I2C3 */ +}; + +static int i2c_get_config(int *index, struct i2c_bus *i2c_bus) +{ + int i = *index; + + if (i >= CONFIG_SYS_MAX_I2C_BUS) + return -1; + + i2c_bus->periph_id = i2c_periph_ids[i]; + i2c_bus->pinmux_config = pinmux_configs[i]; + i2c_bus->regs = (struct i2c_ctlr *)i2c_bus_base[i]; + i2c_bus->speed = I2CSPEED_KHZ * 1000; + + *index = i + 1; + + return 0; +} +#else +/* This is the fdt code */ +static int i2c_get_config(int *index, struct i2c_bus *i2c_bus) +{ + const void *blob = gd->blob; + struct fdt_i2c config; + int node = fdt_decode_next_alias(blob, + "i2c", + COMPAT_NVIDIA_TEGRA250_I2C, + index); + if (node < 0) + return -1; + + if (fdt_decode_i2c(blob, node, &config)) + return -1; + + i2c_bus->periph_id = config.periph_id; + i2c_bus->pinmux_config = config.pinmux; + i2c_bus->regs = config.reg; + i2c_bus->speed = config.speed; + i2c_bus->enabled = config.enable; + + return 0; +} +#endif + +int i2c_init_board(void) +{ + struct i2c_bus *i2c_bus; + int index = 0; + int i; + + /* build the i2c_controllers[] for each controller */ + for (i = 0; i < CONFIG_SYS_MAX_I2C_BUS; ++i) { + i2c_bus = &i2c_controllers[i]; + i2c_bus->id = i; + + i2c_get_config(&index, i2c_bus); + + if (i2c_bus->periph_id == PERIPH_ID_DVC_I2C) + i2c_bus->control = + &((struct dvc_ctlr *)i2c_bus->regs)->control; + else + i2c_bus->control = &i2c_bus->regs->control; + + i2c_init_controller(i2c_bus); + } + + return 0; +} + void i2c_init(int speed, int slaveaddr) { debug("i2c_init(speed=%u, slaveaddr=0x%x)\n", speed, slaveaddr);