dt-bindings: allow child nodes inside the Tegra BPMP
Subsystems (4)
PATCH 1/7 dt-bindings: allow child nodes inside the Tegra BPMP
From: Stephen Warren <[email protected]>
The BPMP implements some services which must be represented by separate nodes. For example, it can provide access to certain I2C controllers, and the I2C bindings represent each I2C controller as a device tree node. Update the binding to describe how the BPMP supports this.
---
This series naturally depends on all the other Tegra186 patches I've sent.
.../firmware/nvidia,tegra186-bpmp.txt | 23 ++++++++++++++++++++++ 1 file changed, 23 insertions(+)
doc/device-tree-bindings/firmware/nvidia,tegra186-bpmp.txt +23 -0
@@ -38,6 +38,24 @@ implemented by this node: - .../reset/reset.txt - <dt-bindings/reset/tegra186-reset.h> +The BPMP implements some services which must be represented by separate nodes. +For example, it can provide access to certain I2C controllers, and the I2C +bindings represent each I2C controller as a device tree node. Such nodes should +be nested directly inside the main BPMP node. + +Software can determine whether a child node of the BPMP node represents a device +by checking for a compatible property. Any node with a compatible property +represents a device that can be instantiated. Nodes without a compatible +property may be used to provide configuration information regarding the BPMP +itself, although no such configuration nodes are currently defined by this +binding. + +The BPMP firmware defines no single global name-/numbering-space for such +services. Put another way, the numbering scheme for I2C buses is distinct from +the numbering scheme for any other service the BPMP may provide (e.g. a future +hypothetical SPI bus service). As such, child device nodes will have no reg +property, and the BPMP node will have no #address-cells or #size-cells property. + The shared memory bindings for BPMP -----------------------------------
@@ -78,4 +96,9 @@ bpmp { #clock-cells = <1>; #power-domain-cells = <1>; #reset-cells = <1>; + + i2c { + compatible = "..."; + ... + }; };
Signature · 1 line
2.9.2
PATCH 2/7 misc: Tegra BPMP: support child node devices
From: Stephen Warren <[email protected]>
The BPMP bindings allow devices to be represented as child nodes of the BPMP node. This requires the driver to trigger scanning of its node for those child nodes.
--- drivers/misc/tegra186_bpmp.c | 4 ++++ 1 file changed, 4 insertions(+)
drivers/misc/tegra186_bpmp.c +4 -0
@@ -129,6 +129,10 @@ static int tegra186_bpmp_bind(struct udevice *dev)if (ret)return ret; + ret =dm_scan_fdt_node (dev, gd->fdt_blob, dev->of_offset, false); +if (ret) +return ret; +return 0 ; }
Signature · 1 line
2.9.2
PATCH 2/7 misc: Tegra BPMP: support child node devices
Hi Stephen,
Quoted 16 lines · Stephen Warren
From: Stephen Warren <[email protected]>
The BPMP bindings allow devices to be represented as child nodes of the BPMP node. This requires the driver to trigger scanning of its node for those child nodes.
Signed-off-by Stephen Warren <[email protected]>--- drivers/misc/tegra186_bpmp.c | 4 ++++ 1 file changed, 4 insertions(+)drivers/misc/tegra186_bpmp.c +0
-0
drivers/misc/tegra186_bpmp.c static int tegra186_bpmp_bind(struct udevice *dev) · line 135
Quoted 7 lines
drivers/misc/tegra186_bpmp.c +4
-0@@ -129,6 +129,10 @@ static int tegra186_bpmp_bind(struct udevice *dev)if (ret)return ret; + ret =dm_scan_fdt_node (dev, gd->fdt_blob, dev->of_offset, false); +if (ret) +return ret; +
Can you use dm_scan_fdt_dev() here? Hot off the press.
Quoted 6 lines
drivers/misc/tegra186_bpmp.c +0
-1return 0 ; } --2.9.2
Regards,
Simon
PATCH 2/7 misc: Tegra BPMP: support child node devices
Quoted 14 lines · Simon Glass
Quoted 13 lines · Stephen Warren
From: Stephen Warren <[email protected]>
The BPMP bindings allow devices to be represented as child nodes of the BPMP node. This requires the driver to trigger scanning of its node for
drivers/misc/tegra186_bpmp.c +0
-0@@ -129,6 +129,10 @@ static int tegra186_bpmp_bind(struct udevice *dev)if (ret)return ret;
Quoted 6 lines
drivers/misc/tegra186_bpmp.c static int tegra186_bpmp_bind(struct udevice *dev) · line 135
Quoted 4 lines
drivers/misc/tegra186_bpmp.c +4
-0+ ret =dm_scan_fdt_node (dev, gd->fdt_blob, dev->of_offset, false); +if (ret) +return ret; +Can you use
dm_scan_fdt_dev()here? Hot off the press.
It looks like it, yes.
PATCH 3/7 dt-bindings: add Tegra186 BPMP I2C binding
In reply to Stephen WarrenFrom: Stephen Warren <[email protected]>
In Tegra186, the BPMP (Boot and Power Management Processor) owns certain HW devices, such as the I2C controller for the power management I2C bus. Software running on other CPUs must perform IPC to the BPMP in order to execute transactions on that I2C bus. This binding describes an I2C bus that is accessed in such a fashion.
--- .../i2c/nvidia,tegra186-bpmp-i2c.txt | 42 ++++++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 doc/device-tree-bindings/i2c/nvidia,tegra186-bpmp-i2c.txt
doc/device-tree-bindings/i2c/nvidia,tegra186-bpmp-i2c.txt new file +42 -0
@@ -0,0 +1,42 @@ +NVIDIA Tegra186 BPMP I2C controller + +In Tegra186, the BPMP (Boot and Power Management Processor) owns certain HW +devices, such as the I2C controller for the power management I2C bus. Software +running on other CPUs must perform IPC to the BPMP in order to execute +transactions on that I2C bus. This binding describes an I2C bus that is +accessed in such a fashion. + +The BPMP I2C node must be located directly inside the main BPMP node. See +../firmware/nvidia,tegra186-bpmp.txt for details of the BPMP binding. + +This node represents an I2C controller. See ../i2c/i2c.txt for details of the +core I2C binding. + +Required properties: +- compatible: + Array of strings. + One of: + - "nvidia,tegra186-bpmp-i2c". +- #address-cells: Address cells for I2C device address. + Single-cell integer. + Must be <1>. +- #size-cells: + Single-cell integer. + Must be <0>. +- nvidia,bpmp-bus-id: + Single-cell integer. + Indicates the I2C bus number this DT node represent, as defined by the + BPMP firmware. + +Example: + +bpmp { + ... + + i2c { + compatible = "nvidia,tegra186-bpmp-i2c"; + #address-cells = <1>; + #size-cells = <0>; + nvidia,bpmp-bus-id = <5>; + }; +};
Signature · 1 line
2.9.2
PATCH 3/7 dt-bindings: add Tegra186 BPMP I2C binding
Quoted 8 lines · Stephen Warren
From: Stephen Warren <[email protected]>
In Tegra186, the BPMP (Boot and Power Management Processor) owns certain HW devices, such as the I2C controller for the power management I2C bus. Software running on other CPUs must perform IPC to the BPMP in order to execute transactions on that I2C bus. This binding describes an I2C bus that is accessed in such a fashion.
Quoted 5 lines
Signed-off-by Stephen Warren <[email protected]>--- .../i2c/nvidia,tegra186-bpmp-i2c.txt | 42 ++++++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 doc/device-tree-bindings/i2c/nvidia,tegra186-bpmp-i2c.txt
PATCH 3/7 dt-bindings: add Tegra186 BPMP I2C binding
In reply to Stephen WarrenHello Stephen,
Am 29.07.2016 um 21:15 schrieb Stephen Warren:
Quoted 8 lines
From: Stephen Warren <[email protected]>
In Tegra186, the BPMP (Boot and Power Management Processor) owns certain HW devices, such as the I2C controller for the power management I2C bus. Software running on other CPUs must perform IPC to the BPMP in order to execute transactions on that I2C bus. This binding describes an I2C bus that is accessed in such a fashion.
Quoted 5 lines
Signed-off-by Stephen Warren <[email protected]>--- .../i2c/nvidia,tegra186-bpmp-i2c.txt | 42 ++++++++++++++++++++++ 1 file changed, 42 insertions(+)create mode 100644
doc/device-tree-bindings/i2c/nvidia,tegra186-bpmp-i2c.txt
bye,
Heiko
Quoted 50 lines
doc/device-tree-bindings/i2c/nvidia,tegra186-bpmp-i2c.txt new file +42
-0@@ -0,0 +1,42 @@ +NVIDIA Tegra186 BPMP I2C controller + +In Tegra186, the BPMP (Boot and Power Management Processor) owns certain HW +devices, such as the I2C controller for the power management I2C bus. Software +running on other CPUs must perform IPC to the BPMP in order to execute +transactions on that I2C bus. This binding describes an I2C bus that is +accessed in such a fashion. + +The BPMP I2C node must be located directly inside the main BPMP node. See +../firmware/nvidia,tegra186-bpmp.txt for details of the BPMP binding. + +This node represents an I2C controller. See ../i2c/i2c.txt for details of the +core I2C binding. + +Required properties: +- compatible: + Array of strings. + One of: + - "nvidia,tegra186-bpmp-i2c". +- #address-cells: Address cells for I2C device address. + Single-cell integer. + Must be <1>. +- #size-cells: + Single-cell integer. + Must be <0>. +- nvidia,bpmp-bus-id: + Single-cell integer. + Indicates the I2C bus number this DT node represent, as defined by the + BPMP firmware. + +Example: + +bpmp { + ... + + i2c { + compatible = "nvidia,tegra186-bpmp-i2c"; + #address-cells = <1>; + #size-cells = <0>; + nvidia,bpmp-bus-id = <5>; + }; +};
Signature · 2 lines
DENX Software Engineering GmbH, Managing Director: Wolfgang Denk HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
PATCH 4/7 i2c: add Tegra186 BPMP driver
In reply to Stephen WarrenFrom: Stephen Warren <[email protected]>
On Tegra186, some I2C controllers are directly controlled by the main CPU, whereas others are controlled by the BPMP, and can only be accessed by the main CPU via IPC requests to the BPMP. This driver covers the latter case.
--- drivers/i2c/Kconfig | 10 ++++ drivers/i2c/Makefile | 1 + drivers/i2c/tegra186_bpmp_i2c.c | 129 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 140 insertions(+) create mode 100644 drivers/i2c/tegra186_bpmp_i2c.c
drivers/i2c/Kconfig +10 -0
@@ -154,6 +154,16 @@ config SYS_I2C_UNIPHIER_F Support for UniPhier FIFO-builtin I2C controller driver. This I2C controller is used on PH1-Pro4 or newer UniPhier SoCs. +config TEGRA186_BPMP_I2C + bool "Enable Tegra186 BPMP-based I2C driver" + depends on TEGRA186_BPMP + help + Support for Tegra I2C controllers managed by the BPMP (Boot and + Power Management Processor). On Tegra186, some I2C controllers are + directly controlled by the main CPU, whereas others are controlled + by the BPMP, and can only be accessed by the main CPU via IPC + requests to the BPMP. This driver covers the latter case. + source "drivers/i2c/muxes/Kconfig" endmenu
drivers/i2c/Makefile +1 -0
@@ -41,5 +41,6 @@ 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-$(CONFIG_TEGRA186_BPMP_I2C) += tegra186_bpmp_i2c.o obj-$(CONFIG_I2C_MUX) += muxes/
drivers/i2c/tegra186_bpmp_i2c.c new file +129 -0
129 lines not on this page · raw message
Signature · 1 line
2.9.2
PATCH 4/7 i2c: add Tegra186 BPMP driver
Quoted 6 lines · Stephen Warren
From: Stephen Warren <[email protected]>
On Tegra186, some I2C controllers are directly controlled by the main CPU, whereas others are controlled by the BPMP, and can only be accessed by the main CPU via IPC requests to the BPMP. This driver covers the latter case.
Quoted 7 lines
Signed-off-by Stephen Warren <[email protected]>--- drivers/i2c/Kconfig | 10 ++++ drivers/i2c/Makefile | 1 + drivers/i2c/tegra186_bpmp_i2c.c | 129 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 140 insertions(+) create mode 100644 drivers/i2c/tegra186_bpmp_i2c.c
As before, hopefully the bpmp thing can move to calling via DM.
PATCH 4/7 i2c: add Tegra186 BPMP driver
In reply to Stephen WarrenHello Stephen,
Am 29.07.2016 um 21:15 schrieb Stephen Warren:
Quoted 6 lines
From: Stephen Warren <[email protected]>
On Tegra186, some I2C controllers are directly controlled by the main CPU, whereas others are controlled by the BPMP, and can only be accessed by the main CPU via IPC requests to the BPMP. This driver covers the latter case.
Quoted 7 lines
Signed-off-by Stephen Warren <[email protected]>--- drivers/i2c/Kconfig | 10 ++++ drivers/i2c/Makefile | 1 + drivers/i2c/tegra186_bpmp_i2c.c | 129 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 140 insertions(+)create mode 100644
drivers/i2c/tegra186_bpmp_i2c.c
bye,
Heiko
Quoted 169 lines
drivers/i2c/Kconfig +10
-0@@ -154,6 +154,16 @@ config SYS_I2C_UNIPHIER_F Support for UniPhier FIFO-builtin I2C controller driver. This I2C controller is used on PH1-Pro4 or newer UniPhier SoCs. +config TEGRA186_BPMP_I2C + bool "Enable Tegra186 BPMP-based I2C driver" + depends on TEGRA186_BPMP + help + Support for Tegra I2C controllers managed by the BPMP (Boot and + Power Management Processor). On Tegra186, some I2C controllers are + directly controlled by the main CPU, whereas others are controlled + by the BPMP, and can only be accessed by the main CPU via IPC + requests to the BPMP. This driver covers the latter case. + source "drivers/i2c/muxes/Kconfig" endmenudrivers/i2c/Makefile +1
-0@@ -41,5 +41,6 @@ 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-$(CONFIG_TEGRA186_BPMP_I2C) += tegra186_bpmp_i2c.o obj-$(CONFIG_I2C_MUX) += muxes/drivers/i2c/tegra186_bpmp_i2c.c new file +129
-0@@ -0,0 +1,129 @@ +/* +* Copyright (c) 2016, NVIDIA CORPORATION. +* +* SPDX-License-Identifier: GPL-2.0 +*/ + +#include <common.h> +#include <dm.h> +#include <i2c.h> +#include <asm/arch-tegra/bpmp_abi.h> +#include <asm/arch-tegra/tegra186_bpmp.h> + +DECLARE_GLOBAL_DATA_PTR ; + +struct tegra186_bpmp_i2c { +uint32_t bpmp_bus_id; +}; + +static inline void serialize_u16 (uint8_t **p,uint16_t val) +{ + (*p)[0 ] = val &0xff ; + (*p)[1 ] = val >>8 ; + (*p) +=2 ; +} + +/* These just happen to have the same values as I2C_M_* and SERIALI2C_* */ +#define SUPPORTED_FLAGS \ + (I2C_M_TEN | \ + I2C_M_RD | \ + I2C_M_STOP | \ + I2C_M_NOSTART | \ + I2C_M_REV_DIR_ADDR | \ + I2C_M_IGNORE_NAK | \ + I2C_M_NO_RD_ACK | \ + I2C_M_RECV_LEN) + +static int tegra186_bpmp_i2c_xfer (struct udevice *dev,struct i2c_msg *msg, +int nmsgs) +{ +struct tegra186_bpmp_i2c *priv =dev_get_priv (dev); +struct mrq_i2c_request req; +struct mrq_i2c_response resp; +uint8_t *p; +int left, i, ret; + + req.cmd =CMD_I2C_XFER ; + req.xfer.bus_id = priv->bpmp_bus_id; + p = &req.xfer.data_buf[0 ]; + left =ARRAY_SIZE (req.xfer.data_buf); +for (i =0 ; i < nmsgs; i++) { +int len =6 ; +if (!(msg[i].flags &I2C_M_RD )) + len += msg[i].len; +if ((len >=BIT (16 )) || (len > left)) +return -ENOSPC ; + +if (msg[i].flags & ~SUPPORTED_FLAGS ) +return -EINVAL ; + +serialize_u16 (&p, msg[i].addr); +serialize_u16 (&p, msg[i].flags); +serialize_u16 (&p, msg[i].len); +if (!(msg[i].flags &I2C_M_RD )) { +memcpy (p, msg[i].buf, msg[i].len); + p += msg[i].len; + } + } + req.xfer.data_size = p - &req.xfer.data_buf[0 ]; + + ret =tegra186_bpmp_call (dev->parent,MRQ_I2C , + &req,sizeof (req), &resp,sizeof (resp)); +if (ret) +return ret; + + p = &resp.xfer.data_buf[0 ]; + left = resp.xfer.data_size; +if (left >ARRAY_SIZE (resp.xfer.data_buf)) +return -EINVAL ; +for (i =0 ; i < nmsgs; i++) { +if (msg[i].flags &I2C_M_RD ) { +memcpy (msg[i].buf, p, msg[i].len); + p += msg[i].len; + } + } + +return 0 ; +} + +static int tegra186_bpmp_i2c_probe (struct udevice *dev) +{ +struct tegra186_bpmp_i2c *priv =dev_get_priv (dev); +int ret; +struct fdtdec_phandle_args args; + + ret =fdtdec_parse_phandle_with_args (gd->fdt_blob, dev->of_offset, +"nvidia,bpmp" ,NULL ,0 ,0 , &args); +if (ret <0 ) { +debug ("%s: fdtdec_parse_phandle_with_args() failed: %d\n" , + __func__, ret); +return ret; + } + + priv->bpmp_bus_id =fdtdec_get_uint (gd->fdt_blob, dev->of_offset, +"nvidia,bpmp-bus-id" ,U32_MAX ); +if (priv->bpmp_bus_id ==U32_MAX ) { +debug ("%s: could not parse nvidia,bpmp-bus-id\n" , __func__); +return -ENODEV ; + } + +return 0 ; +} + +static const struct dm_i2c_ops tegra186_bpmp_i2c_ops = { + .xfer = tegra186_bpmp_i2c_xfer, +}; + +static const struct udevice_id tegra186_bpmp_i2c_ids[] = { + { .compatible ="nvidia,tegra186-bpmp-i2c" }, + { } +}; + +U_BOOT_DRIVER (i2c_gpio) = { + .name ="tegra186_bpmp_i2c" , + .id =UCLASS_I2C , + .of_match = tegra186_bpmp_i2c_ids, + .probe = tegra186_bpmp_i2c_probe, + .priv_auto_alloc_size =sizeof (struct tegra186_bpmp_i2c ), + .ops = &tegra186_bpmp_i2c_ops, +};
Signature · 2 lines
DENX Software Engineering GmbH, Managing Director: Wolfgang Denk HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
PATCH 5/7 ARM: tegra: add BPMP to Tegra186 device tree
In reply to Stephen WarrenFrom: Stephen Warren <[email protected]>
This allows the BPMP I2C device to be instantiated, which makes it available to other drivers and the user.
--- arch/arm/dts/tegra186.dtsi | 9 +++++++++ 1 file changed, 9 insertions(+)
arch/arm/dts/tegra186.dtsi +9 -0
@@ -308,5 +308,14 @@ #clock-cells = <1>; #power-domain-cells = <1>; #reset-cells = <1>; + + bpmp_i2c: i2c { + compatible = "nvidia,tegra186-bpmp-i2c"; + nvidia,bpmp = <&bpmp>; + nvidia,bpmp-bus-id = <5>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; }; };
Signature · 1 line
2.9.2
PATCH 5/7 ARM: tegra: add BPMP to Tegra186 device tree
Quoted 9 lines · Stephen Warren
From: Stephen Warren <[email protected]>
This allows the BPMP I2C device to be instantiated, which makes it available to other drivers and the user.
Signed-off-by Stephen Warren <[email protected]>--- arch/arm/dts/tegra186.dtsi | 9 +++++++++ 1 file changed, 9 insertions(+)
PATCH 6/7 ARM: tegra: enable SD card on p2771-0000
In reply to Stephen WarrenFrom: Stephen Warren <[email protected]>
Now that clock and reset drivers exist for Tegra186, we can enable the SD card controller. Now that a BPMP I2C driver exists for Tegra186, we can communicate with the PMIC to enable power to the SD card. Hook up the DT content and board code required to make the SD card work.
--- arch/arm/dts/tegra186-p2771-0000-a02.dts | 5 +++++ arch/arm/dts/tegra186-p2771-0000-b00.dts | 5 +++++ arch/arm/dts/tegra186-p2771-0000.dtsi | 14 ++++++++++++++ board/nvidia/p2771-0000/p2771-0000.c | 26 ++++++++++++++++++++++++++ configs/p2771-0000-a02_defconfig | 1 + configs/p2771-0000-b00_defconfig | 1 + 6 files changed, 52 insertions(+)
arch/arm/dts/tegra186-p2771-0000-a02.dts +5 -0
@@ -5,4 +5,9 @@ / { model = "NVIDIA P2771-0000 A02"; compatible = "nvidia,p2771-0000-a02", "nvidia,p2771-0000", "nvidia,tegra186"; + + sdhci at 3400000 { + cd-gpios = <&gpio_main TEGRA_MAIN_GPIO(P, 6) GPIO_ACTIVE_LOW>; + power-gpios = <&gpio_main TEGRA_MAIN_GPIO(P, 5) GPIO_ACTIVE_HIGH>; + }; };
arch/arm/dts/tegra186-p2771-0000-b00.dts +5 -0
@@ -5,4 +5,9 @@ / { model = "NVIDIA P2771-0000 B00"; compatible = "nvidia,p2771-0000-b00", "nvidia,p2771-0000", "nvidia,tegra186"; + + sdhci at 3400000 { + cd-gpios = <&gpio_main TEGRA_MAIN_GPIO(P, 5) GPIO_ACTIVE_LOW>; + power-gpios = <&gpio_main TEGRA_MAIN_GPIO(P, 6) GPIO_ACTIVE_HIGH>; + }; };
arch/arm/dts/tegra186-p2771-0000.dtsi +14 -0
@@ -10,6 +10,8 @@ aliases { sdhci0 = "/sdhci at 3460000"; + sdhci1 = "/sdhci at 3400000"; + i2c0 = "/bpmp/i2c"; i2c1 = "/i2c at 3160000"; i2c2 = "/i2c at c240000"; i2c3 = "/i2c at 3180000";
@@ -39,6 +41,12 @@ status = "okay"; }; + sdhci at 3400000 { + status = "okay"; + wp-gpios = <&gpio_main TEGRA_MAIN_GPIO(P, 4) GPIO_ACTIVE_HIGH>; + bus-width = <4>; + }; + sdhci at 3460000 { status = "okay"; bus-width = <8>;
@@ -55,4 +63,10 @@ i2c at 31e0000 { status = "okay"; }; + + bpmp { + i2c { + status = "okay"; + }; + }; };
board/nvidia/p2771-0000/p2771-0000.c +26 -0
@@ -5,3 +5,29 @@*/ #include <common.h> +#include <i2c.h> +#include "../p2571/max77620_init.h" + +int tegra_board_init (void ) +{ +struct udevice *dev; +uchar val; +int ret; + +/* Turn on MAX77620 LDO3 to 3.3V for SD card power */ +debug ("%s: Set LDO3 for VDDIO_SDMMC_AP power to 3.3V\n" , __func__); + ret =i2c_get_chip_for_busnum (0 ,MAX77620_I2C_ADDR_7BIT ,1 , &dev); +if (ret) { +printf ("%s: Cannot find MAX77620 I2C chip\n" , __func__); +return ret; + } +/* 0xF2 for 3.3v, enabled: bit7:6 = 11 = enable, bit5:0 = voltage */ + val =0xF2 ; + ret =dm_i2c_write (dev,MAX77620_CNFG1_L3_REG , &val,1 ); +if (ret) { +printf ("i2c_write 0 0x3c 0x27 failed: %d\n" , ret); +return ret; + } + +return 0 ; +}
configs/p2771-0000-a02_defconfig +1 -0
@@ -26,6 +26,7 @@ CONFIG_CMD_EXT4=y CONFIG_CMD_EXT4_WRITE=y CONFIG_CMD_FAT=y CONFIG_CMD_FS_GENERIC=y +CONFIG_TEGRA186_BPMP_I2C=y CONFIG_SYS_NS16550=y CONFIG_USB=y CONFIG_DM_USB=y
configs/p2771-0000-b00_defconfig +1 -0
@@ -26,6 +26,7 @@ CONFIG_CMD_EXT4=y CONFIG_CMD_EXT4_WRITE=y CONFIG_CMD_FAT=y CONFIG_CMD_FS_GENERIC=y +CONFIG_TEGRA186_BPMP_I2C=y CONFIG_SYS_NS16550=y CONFIG_USB=y CONFIG_DM_USB=y
Signature · 1 line
2.9.2
PATCH 6/7 ARM: tegra: enable SD card on p2771-0000
Hi Stephen,
Quoted 103 lines · Stephen Warren
From: Stephen Warren <[email protected]>
Now that clock and reset drivers exist for Tegra186, we can enable the SD card controller. Now that a BPMP I2C driver exists for Tegra186, we can communicate with the PMIC to enable power to the SD card. Hook up the DT content and board code required to make the SD card work.
Signed-off-by Stephen Warren <[email protected]>--- arch/arm/dts/tegra186-p2771-0000-a02.dts | 5 +++++ arch/arm/dts/tegra186-p2771-0000-b00.dts | 5 +++++ arch/arm/dts/tegra186-p2771-0000.dtsi | 14 ++++++++++++++ board/nvidia/p2771-0000/p2771-0000.c | 26 ++++++++++++++++++++++++++ configs/p2771-0000-a02_defconfig | 1 + configs/p2771-0000-b00_defconfig | 1 + 6 files changed, 52 insertions(+)arch/arm/dts/tegra186-p2771-0000-a02.dts +5
-0@@ -5,4 +5,9 @@ / { model = "NVIDIA P2771-0000 A02"; compatible = "nvidia,p2771-0000-a02", "nvidia,p2771-0000", "nvidia,tegra186"; + + sdhci at 3400000 { + cd-gpios = <&gpio_main TEGRA_MAIN_GPIO(P, 6) GPIO_ACTIVE_LOW>; + power-gpios = <&gpio_main TEGRA_MAIN_GPIO(P, 5) GPIO_ACTIVE_HIGH>; + }; };arch/arm/dts/tegra186-p2771-0000-b00.dts +5
-0@@ -5,4 +5,9 @@ / { model = "NVIDIA P2771-0000 B00"; compatible = "nvidia,p2771-0000-b00", "nvidia,p2771-0000", "nvidia,tegra186"; + + sdhci at 3400000 { + cd-gpios = <&gpio_main TEGRA_MAIN_GPIO(P, 5) GPIO_ACTIVE_LOW>; + power-gpios = <&gpio_main TEGRA_MAIN_GPIO(P, 6) GPIO_ACTIVE_HIGH>; + }; };arch/arm/dts/tegra186-p2771-0000.dtsi +14
-0@@ -10,6 +10,8 @@ aliases { sdhci0 = "/sdhci at 3460000"; + sdhci1 = "/sdhci at 3400000"; + i2c0 = "/bpmp/i2c"; i2c1 = "/i2c at 3160000"; i2c2 = "/i2c at c240000"; i2c3 = "/i2c at 3180000";@@ -39,6 +41,12 @@ status = "okay"; }; + sdhci at 3400000 { + status = "okay"; + wp-gpios = <&gpio_main TEGRA_MAIN_GPIO(P, 4) GPIO_ACTIVE_HIGH>; + bus-width = <4>; + }; + sdhci at 3460000 { status = "okay"; bus-width = <8>;@@ -55,4 +63,10 @@ i2c at 31e0000 { status = "okay"; }; + + bpmp { + i2c { + status = "okay"; + }; + }; };board/nvidia/p2771-0000/p2771-0000.c +13
-0@@ -5,3 +5,29 @@*/ #include <common.h> +#include <i2c.h> +#include "../p2571/max77620_init.h" + +int tegra_board_init (void ) +{ +struct udevice *dev; +uchar val; +int ret; + +/* Turn on MAX77620 LDO3 to 3.3V for SD card power */ +debug ("%s: Set LDO3 for VDDIO_SDMMC_AP power to 3.3V\n" , __func__); + ret =i2c_get_chip_for_busnum (0 ,MAX77620_I2C_ADDR_7BIT ,1 , &dev); +if (ret) {
board/nvidia/p2771-0000/p2771-0000.c line 30
Quoted 10 lines
board/nvidia/p2771-0000/p2771-0000.c +10
-0+printf ("%s: Cannot find MAX77620 I2C chip\n" , __func__); +return ret; + } +/* 0xF2 for 3.3v, enabled: bit7:6 = 11 = enable, bit5:0 = voltage */ + val =0xF2 ; + ret =dm_i2c_write (dev,MAX77620_CNFG1_L3_REG , &val,1 ); +if (ret) { +printf ("i2c_write 0 0x3c 0x27 failed: %d\n" , ret); +return ret; + }
Can you add a simple pmic driver for this? It's really easy and avoids the horrible busnum stuff. The i2c_get_chip_for_busnum() should ideally not be used.
Quoted 28 lines
board/nvidia/p2771-0000/p2771-0000.c +3
-0+ +return 0 ; +}configs/p2771-0000-a02_defconfig +1
-0@@ -26,6 +26,7 @@ CONFIG_CMD_EXT4=y CONFIG_CMD_EXT4_WRITE=y CONFIG_CMD_FAT=y CONFIG_CMD_FS_GENERIC=y +CONFIG_TEGRA186_BPMP_I2C=y CONFIG_SYS_NS16550=y CONFIG_USB=y CONFIG_DM_USB=yconfigs/p2771-0000-b00_defconfig +1
-1@@ -26,6 +26,7 @@ CONFIG_CMD_EXT4=y CONFIG_CMD_EXT4_WRITE=y CONFIG_CMD_FAT=y CONFIG_CMD_FS_GENERIC=y +CONFIG_TEGRA186_BPMP_I2C=y CONFIG_SYS_NS16550=y CONFIG_USB=y CONFIG_DM_USB=y --
Quoted 2 lines
2.9.2
Regards,
Simon
PATCH 6/7 ARM: tegra: enable SD card on p2771-0000
Quoted 28 lines · Simon Glass
Hi Stephen,
Quoted 25 lines · Stephen Warren
From: Stephen Warren <[email protected]>
Now that clock and reset drivers exist for Tegra186, we can enable the SD card controller. Now that a BPMP I2C driver exists for Tegra186, we can communicate with the PMIC to enable power to the SD card. Hook up the DT content and board code required to make the SD card work.
board/nvidia/p2771-0000/p2771-0000.c +16
-0+int tegra_board_init (void ) +{ +struct udevice *dev; +uchar val; +int ret; + +/* Turn on MAX77620 LDO3 to 3.3V for SD card power */ +debug ("%s: Set LDO3 for VDDIO_SDMMC_AP power to 3.3V\n" , __func__); + ret =i2c_get_chip_for_busnum (0 ,MAX77620_I2C_ADDR_7BIT ,1 , &dev); +if (ret) { +printf ("%s: Cannot find MAX77620 I2C chip\n" , __func__); +return ret; + } +/* 0xF2 for 3.3v, enabled: bit7:6 = 11 = enable, bit5:0 = voltage */ + val =0xF2 ; + ret =dm_i2c_write (dev,MAX77620_CNFG1_L3_REG , &val,1 );
Quoted 8 lines
board/nvidia/p2771-0000/p2771-0000.c line 30
Quoted 4 lines
board/nvidia/p2771-0000/p2771-0000.c +4
-0+if (ret) { +printf ("i2c_write 0 0x3c 0x27 failed: %d\n" , ret); +return ret; + }Can you add a simple pmic driver for this? It's really easy and avoids the horrible busnum stuff. The
i2c_get_chip_for_busnum()should ideally not be used.
Perhaps we can defer that until later?
FWIW, this current approach is used by all/most Tegra boards and works great for now. If converting this kind of code to use the PMIC infra-structure, I'd rather take a pass and do all Tegra boards at once, but equally I'd rather not hold up the Tegra186 patches behind yet another common API conversion; there are already 3 new common APIs introduced for Tegra in the Tegra186 support...
PATCH 6/7 ARM: tegra: enable SD card on p2771-0000
Hi Stephen,
Quoted 48 lines · Stephen Warren
Quoted 37 lines · Simon Glass
Hi Stephen,
Quoted 33 lines · Stephen Warren
From: Stephen Warren <[email protected]>
Now that clock and reset drivers exist for Tegra186, we can enable the SD card controller. Now that a BPMP I2C driver exists for Tegra186, we can communicate with the PMIC to enable power to the SD card. Hook up the DT content and board code required to make the SD card work.
board/nvidia/p2771-0000/p2771-0000.c +8
-0+int tegra_board_init (void ) +{ +struct udevice *dev; +uchar val; +int ret; + +/* Turn on MAX77620 LDO3 to 3.3V for SD card power */ + debug("%s: Set LDO3 for VDDIO_SDMMC_AP power to 3.3V\n",
__func__);
+ ret = i2c_get_chip_for_busnum(0,MAX77620_I2C_ADDR_7BIT, 1,
&dev);board/nvidia/p2771-0000/p2771-0000.c +5
-0+if (ret) { +printf ("%s: Cannot find MAX77620 I2C chip\n" , __func__); +return ret; + } +/* 0xF2 for 3.3v, enabled: bit7:6 = 11 = enable, bit5:0 = voltage */
board/nvidia/p2771-0000/p2771-0000.c +3
-0+ val =0xF2 ; + ret =dm_i2c_write (dev,MAX77620_CNFG1_L3_REG , &val,1 ); +if (ret) {Quoted 8 lines
board/nvidia/p2771-0000/p2771-0000.c line 30
Quoted 3 lines
board/nvidia/p2771-0000/p2771-0000.c +3
-0+printf ("i2c_write 0 0x3c 0x27 failed: %d\n" , ret); +return ret; + }Can you add a simple pmic driver for this? It's really easy and avoids the horrible busnum stuff. The
i2c_get_chip_for_busnum()should ideally not be used.
Quoted 8 lines
Perhaps we can defer that until later?
FWIW, this current approach is used by all/most Tegra boards and works great for now. If converting this kind of code to use the PMIC infra-structure, I'd rather take a pass and do all Tegra boards at once, but equally I'd rather not hold up the Tegra186 patches behind yet another common API conversion; there are already 3 new common APIs introduced for Tegra in the Tegra186 support...
OK, will I remember this coming up previously, so I look forward to it getting sorted out. It really isn't that much work to write a PMIC driver.
Regards,
Simon
PATCH 7/7 ARM: tegra: enable PCIe controller on p2771-0000
In reply to Stephen WarrenFrom: Stephen Warren <[email protected]>
p2771-0000 has a couple of PCIe ports; one physically x4 desktop PCI connector (which may run at x2 electrically, depending on the board version and configuration) and a x1 connection to the M.2 slot (which may not be active, depending on the board version and configuration). This change enables those.
--- arch/arm/dts/tegra186-p2771-0000-a02.dts | 19 +++++++++++++++++++ arch/arm/dts/tegra186-p2771-0000-b00.dts | 19 +++++++++++++++++++ board/nvidia/p2771-0000/p2771-0000.c | 22 ++++++++++++++++++++++ configs/p2771-0000-a02_defconfig | 5 +++++ configs/p2771-0000-b00_defconfig | 5 +++++ include/configs/p2771-0000.h | 5 +++++ 6 files changed, 75 insertions(+)
arch/arm/dts/tegra186-p2771-0000-a02.dts +19 -0
@@ -10,4 +10,23 @@ cd-gpios = <&gpio_main TEGRA_MAIN_GPIO(P, 6) GPIO_ACTIVE_LOW>; power-gpios = <&gpio_main TEGRA_MAIN_GPIO(P, 5) GPIO_ACTIVE_HIGH>; }; + + pcie-controller at 10003000 { + status = "okay"; + + pci at 1,0 { + status = "okay"; + nvidia,num-lanes = <2>; + }; + + pci at 2,0 { + status = "disabled"; + nvidia,num-lanes = <1>; + }; + + pci at 3,0 { + status = "okay"; + nvidia,num-lanes = <1>; + }; + }; };
arch/arm/dts/tegra186-p2771-0000-b00.dts +19 -0
@@ -10,4 +10,23 @@ cd-gpios = <&gpio_main TEGRA_MAIN_GPIO(P, 5) GPIO_ACTIVE_LOW>; power-gpios = <&gpio_main TEGRA_MAIN_GPIO(P, 6) GPIO_ACTIVE_HIGH>; }; + + pcie-controller at 10003000 { + status = "okay"; + + pci at 1,0 { + status = "okay"; + nvidia,num-lanes = <4>; + }; + + pci at 2,0 { + status = "disabled"; + nvidia,num-lanes = <0>; + }; + + pci at 3,0 { + status = "disabled"; + nvidia,num-lanes = <1>; + }; + }; };
board/nvidia/p2771-0000/p2771-0000.c +22 -0
@@ -31,3 +31,25 @@ int tegra_board_init(void)return 0 ; } + +int tegra_pcie_board_init (void ) +{ +struct udevice *dev; +uchar val; +int ret; + +/* Turn on MAX77620 LDO7 to 1.05V for PEX power */ +debug ("%s: Set LDO7 for PEX power to 1.05V\n" , __func__); + ret =i2c_get_chip_for_busnum (0 ,MAX77620_I2C_ADDR_7BIT ,1 , &dev); +if (ret) { +printf ("%s: Cannot find MAX77620 I2C chip\n" , __func__); +return -1 ; + } +/* 0xC5 for 1.05v, enabled: bit7:6 = 11 = enable, bit5:0 = voltage */ + val =0xC5 ; + ret =dm_i2c_write (dev,MAX77620_CNFG1_L7_REG , &val,1 ); +if (ret) +printf ("i2c_write 0 0x3c 0x31 failed: %d\n" , ret); + +return 0 ; +}
configs/p2771-0000-a02_defconfig +5 -0
@@ -26,7 +26,12 @@ CONFIG_CMD_EXT4=y CONFIG_CMD_EXT4_WRITE=y CONFIG_CMD_FAT=y CONFIG_CMD_FS_GENERIC=y +CONFIG_RTL8169=y +CONFIG_E1000=y +CONFIG_PCI_TEGRA=y CONFIG_TEGRA186_BPMP_I2C=y CONFIG_SYS_NS16550=y CONFIG_USB=y CONFIG_DM_USB=y +CONFIG_POWER_DOMAIN=y +CONFIG_TEGRA186_POWER_DOMAIN=y
configs/p2771-0000-b00_defconfig +5 -0
@@ -26,7 +26,12 @@ CONFIG_CMD_EXT4=y CONFIG_CMD_EXT4_WRITE=y CONFIG_CMD_FAT=y CONFIG_CMD_FS_GENERIC=y +CONFIG_RTL8169=y +CONFIG_E1000=y +CONFIG_PCI_TEGRA=y CONFIG_TEGRA186_BPMP_I2C=y CONFIG_SYS_NS16550=y CONFIG_USB=y CONFIG_DM_USB=y +CONFIG_POWER_DOMAIN=y +CONFIG_TEGRA186_POWER_DOMAIN=y
include/configs/p2771-0000.h +5 -0
@@ -28,6 +28,11 @@#define CONFIG_SYS_MMC_ENV_PART 2#define CONFIG_ENV_OFFSET (-CONFIG_ENV_SIZE) +/* PCI host support */ +#define CONFIG_PCI +#define CONFIG_PCI_PNP +#define CONFIG_CMD_PCI +#include "tegra-common-post.h" /* Crystal is 38.4MHz. clk_m runs at half that rate */
Signature · 1 line
2.9.2
PATCH 7/7 ARM: tegra: enable PCIe controller on p2771-0000
Hi Stephen,
Quoted 91 lines · Stephen Warren
From: Stephen Warren <[email protected]>
p2771-0000 has a couple of PCIe ports; one physically x4 desktop PCI connector (which may run at x2 electrically, depending on the board version and configuration) and a x1 connection to the M.2 slot (which may not be active, depending on the board version and configuration). This change enables those.
Signed-off-by Stephen Warren <[email protected]>--- arch/arm/dts/tegra186-p2771-0000-a02.dts | 19 +++++++++++++++++++ arch/arm/dts/tegra186-p2771-0000-b00.dts | 19 +++++++++++++++++++ board/nvidia/p2771-0000/p2771-0000.c | 22 ++++++++++++++++++++++ configs/p2771-0000-a02_defconfig | 5 +++++ configs/p2771-0000-b00_defconfig | 5 +++++ include/configs/p2771-0000.h | 5 +++++ 6 files changed, 75 insertions(+)arch/arm/dts/tegra186-p2771-0000-a02.dts +19
-0@@ -10,4 +10,23 @@ cd-gpios = <&gpio_main TEGRA_MAIN_GPIO(P, 6) GPIO_ACTIVE_LOW>; power-gpios = <&gpio_main TEGRA_MAIN_GPIO(P, 5) GPIO_ACTIVE_HIGH>; }; + + pcie-controller at 10003000 { + status = "okay"; + + pci at 1,0 { + status = "okay"; + nvidia,num-lanes = <2>; + }; + + pci at 2,0 { + status = "disabled"; + nvidia,num-lanes = <1>; + }; + + pci at 3,0 { + status = "okay"; + nvidia,num-lanes = <1>; + }; + }; };arch/arm/dts/tegra186-p2771-0000-b00.dts +19
-0@@ -10,4 +10,23 @@ cd-gpios = <&gpio_main TEGRA_MAIN_GPIO(P, 5) GPIO_ACTIVE_LOW>; power-gpios = <&gpio_main TEGRA_MAIN_GPIO(P, 6) GPIO_ACTIVE_HIGH>; }; + + pcie-controller at 10003000 { + status = "okay"; + + pci at 1,0 { + status = "okay"; + nvidia,num-lanes = <4>; + }; + + pci at 2,0 { + status = "disabled"; + nvidia,num-lanes = <0>; + }; + + pci at 3,0 { + status = "disabled"; + nvidia,num-lanes = <1>; + }; + }; };board/nvidia/p2771-0000/p2771-0000.c +9
-0@@ -31,3 +31,25 @@ int tegra_board_init(void)return 0 ; } + +int tegra_pcie_board_init (void ) +{ +struct udevice *dev; +uchar val; +int ret; + +/* Turn on MAX77620 LDO7 to 1.05V for PEX power */ +debug ("%s: Set LDO7 for PEX power to 1.05V\n" , __func__);
board/nvidia/p2771-0000/p2771-0000.c int tegra_board_init(void) · line 52
Quoted 10 lines
board/nvidia/p2771-0000/p2771-0000.c +10
-0+ ret =i2c_get_chip_for_busnum (0 ,MAX77620_I2C_ADDR_7BIT ,1 , &dev); +if (ret) { +printf ("%s: Cannot find MAX77620 I2C chip\n" , __func__); +return -1 ; + } +/* 0xC5 for 1.05v, enabled: bit7:6 = 11 = enable, bit5:0 = voltage */ + val =0xC5 ; + ret =dm_i2c_write (dev,MAX77620_CNFG1_L7_REG , &val,1 ); +if (ret) +printf ("i2c_write 0 0x3c 0x31 failed: %d\n" , ret);
This looks like it should be a pmic regulator driver.
Quoted 54 lines
board/nvidia/p2771-0000/p2771-0000.c +3
-0+ +return 0 ; +}configs/p2771-0000-a02_defconfig +5
-0@@ -26,7 +26,12 @@ CONFIG_CMD_EXT4=y CONFIG_CMD_EXT4_WRITE=y CONFIG_CMD_FAT=y CONFIG_CMD_FS_GENERIC=y +CONFIG_RTL8169=y +CONFIG_E1000=y +CONFIG_PCI_TEGRA=y CONFIG_TEGRA186_BPMP_I2C=y CONFIG_SYS_NS16550=y CONFIG_USB=y CONFIG_DM_USB=y +CONFIG_POWER_DOMAIN=y +CONFIG_TEGRA186_POWER_DOMAIN=yconfigs/p2771-0000-b00_defconfig +5
-0@@ -26,7 +26,12 @@ CONFIG_CMD_EXT4=y CONFIG_CMD_EXT4_WRITE=y CONFIG_CMD_FAT=y CONFIG_CMD_FS_GENERIC=y +CONFIG_RTL8169=y +CONFIG_E1000=y +CONFIG_PCI_TEGRA=y CONFIG_TEGRA186_BPMP_I2C=y CONFIG_SYS_NS16550=y CONFIG_USB=y CONFIG_DM_USB=y +CONFIG_POWER_DOMAIN=y +CONFIG_TEGRA186_POWER_DOMAIN=yinclude/configs/p2771-0000.h +5
-1@@ -28,6 +28,11 @@#define CONFIG_SYS_MMC_ENV_PART 2#define CONFIG_ENV_OFFSET (-CONFIG_ENV_SIZE) +/* PCI host support */ +#define CONFIG_PCI +#define CONFIG_PCI_PNP +#define CONFIG_CMD_PCI +#include "tegra-common-post.h" /* Crystal is 38.4MHz. clk_m runs at half that rate */ --
Quoted 2 lines
2.9.2
Regards,
Simon