* [RFC PATCH V2 01/12] Documentation: Introduce config settings framework
2024-07-01 15:12 [RFC PATCH V2 00/12] Introduce Tegra register config settings Krishna Yarlagadda
@ 2024-07-01 15:12 ` Krishna Yarlagadda
2024-07-01 15:12 ` [RFC PATCH V2 02/12] dt-bindings: misc: Tegra configuration settings Krishna Yarlagadda
` (10 subsequent siblings)
11 siblings, 0 replies; 20+ messages in thread
From: Krishna Yarlagadda @ 2024-07-01 15:12 UTC (permalink / raw)
To: linux-tegra, devicetree, linux-doc, linux-i2c, linux-mmc,
linux-kernel
Cc: thierry.reding, jonathanh, robh, krzk+dt, conor+dt, corbet,
andi.shyti, wsa+renesas, ulf.hansson, adrian.hunter, digetx,
ldewangan, kyarlagadda, mkumard
Add documentation for config settings framework utilized by Tegra SOCs.
This framework is used to configure various device registers (I2C, SPI,
etc) with the optimal/recommended settings for a given operating mode.
For each operating mode there may be various register fields that need
to be configured and so these settings are broken down by register field.
This framework uses device-tree for specifying various register settings
for each operating mode for a given device.
Signed-off-by: Krishna Yarlagadda <kyarlagadda@nvidia.com>
---
Documentation/misc-devices/tegra-cfg.rst | 133 +++++++++++++++++++++++
MAINTAINERS | 7 ++
2 files changed, 140 insertions(+)
create mode 100644 Documentation/misc-devices/tegra-cfg.rst
diff --git a/Documentation/misc-devices/tegra-cfg.rst b/Documentation/misc-devices/tegra-cfg.rst
new file mode 100644
index 000000000000..407e3b3449dc
--- /dev/null
+++ b/Documentation/misc-devices/tegra-cfg.rst
@@ -0,0 +1,133 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+===================================
+NVIDIA Tegra Configuration Settings
+===================================
+
+Introduction
+------------
+NVIDIA Tegra SoCs have various I/O controllers and these controllers require
+specific register configurations.
+
+They could be due to changes in:
+ - Functional mode (eg. speed)
+ - Interface properties (eg. signal timings)
+ - Manufacturing characteristics (eg. process/package)
+ - Thermal characteristics
+ - Board characteristics
+
+Some of the configurations can be provided by device specific standard DT
+properties like speed of interface in I2C, rising/falling timing etc. However,
+there are more device specific configurations required to tune the interface
+based on execution mode or other runtime parameters. All such configurations are
+defined as 'config' settings of the device. This configures a device to operate
+with the optimal settings for a particular mode to improve performance,
+stability or reduce power.
+
+These configurations are either static or dynamic:
+ - Static configuration which is set once during device boot and controller
+ reset
+ - Dynamic configuration is applied based on a particular condition like bus
+ speed, controller mode, peripheral connected to controller, SoC and platform
+ characterization
+
+Static configurations are provided as common config setting and dynamic
+configurations are provided as mode/condition specific.
+
+Background
+----------
+Slew rates, tap delay and other calibration parameters for an interface
+controller, are measured through characterization. These values are dynamic
+and requires different values for same property / field.
+
+Use case
+--------
+Tegra device drivers that use these config settings include:
+ - I2C uses config settings to configure setup & hold times, clock divider
+ values.
+ - SDMMC tuning iterations per speed and CQE values can be set with this method.
+
+Device tree
+-----------
+Config settings of a controller are added under a configsettings and
+referenced via phandle in the controller's device tree node.
+Further subnodes are created under config for each conditional setting.
+::
+
+ configsettings {
+ config-ctrlxyz {
+ ctrl-common-cfg {
+ reg-field-a = <val-a1>;
+ reg-field-b = <val-b1>;
+ reg-field-c = <val-c1>;
+ };
+ ctrl-condition1-cfg {
+ reg-field-a = <val-a2>;
+ reg-field-b = <val-b2>;
+ reg-field-c = <val-c2>;
+ };
+ ctrl-condition2-cfg {
+ reg-field-a = <val-a3>;
+ reg-field-b = <val-b3>;
+ reg-field-c = <val-c3>;
+ };
+ };
+ };
+
+:
+ - "config-<ctrlxyz>": subnode in device node to hold configuration settings.
+ - "<ctrl>-common-cfg": static configuration that needs to be applied during
+ controller reset. Register fields under this node are applied during
+ initialization irrespective of any condition.
+ - "<ctrl>-condition1-cfg": conditional configuration to be applied when
+ controller is set in specific functional mode. Conditional configs may
+ override existing settings in 'common' or contain settings unique to the
+ config.
+ - Properties defined under config must correspond to a register field of
+ device controller.
+ - Properties are device specific and added to device node.
+
+Example
+-------
+Ex::
+
+ configsettings {
+ configi2c1: config-i2c3160000 {
+ i2c-common-cfg {
+ nvidia,i2c-hs-sclk-high-period = <0x03>;
+ nvidia,i2c-hs-sclk-low-period = <0x08>;
+ };
+ i2c-fast-cfg {
+ nvidia,i2c-clk-divisor-fs-mode = <0x3c>;
+ nvidia,i2c-sclk-high-period = <0x02>;
+ nvidia,i2c-sclk-low-period = <0x02>;
+ nvidia,i2c-bus-free-time = <0x02>;
+ nvidia,i2c-stop-setup-time = <0x02>;
+ nvidia,i2c-start-hold-time = <0x02>;
+ nvidia,i2c-start-setup-time = <0x02>;
+ };
+ i2c-fastplus-cfg {
+ nvidia,i2c-clk-divisor-fs-mode = <0x16>;
+ nvidia,i2c-sclk-high-period = <0x02>;
+ nvidia,i2c-sclk-low-period = <0x02>;
+ nvidia,i2c-bus-free-time = <0x02>;
+ nvidia,i2c-stop-setup-time = <0x02>;
+ nvidia,i2c-start-hold-time = <0x02>;
+ nvidia,i2c-start-setup-time = <0x02>;
+ };
+ i2c-standard-cfg {
+ nvidia,i2c-clk-divisor-fs-mode = <0x4f>;
+ nvidia,i2c-sclk-high-period = <0x07>;
+ nvidia,i2c-sclk-low-period = <0x08>;
+ nvidia,i2c-bus-free-time = <0x08>;
+ nvidia,i2c-stop-setup-time = <0x08>;
+ nvidia,i2c-start-hold-time = <0x08>;
+ nvidia,i2c-start-setup-time = <0x08>;
+ };
+ };
+ };
+
+ i2c@3160000 {
+ config-settings = <&configi2c1>
+ };
+
diff --git a/MAINTAINERS b/MAINTAINERS
index e58374b99e5e..8a60c98ac755 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -22255,6 +22255,13 @@ S: Maintained
F: Documentation/devicetree/bindings/mtd/nvidia-tegra20-nand.txt
F: drivers/mtd/nand/raw/tegra_nand.c
+TEGRA CONFIG SETTINGS DRIVER
+M: Thierry Reding <thierry.reding@gmail.com>
+R: Laxman Dewangan <ldewangan@nvidia.com>
+R: Krishna Yarlagadda <kyarlagadda@nvidia.com>
+S: Supported
+F: Documentation/misc-devices/tegra-cfg.rst
+
TEGRA PWM DRIVER
M: Thierry Reding <thierry.reding@gmail.com>
S: Supported
--
2.43.2
^ permalink raw reply related [flat|nested] 20+ messages in thread* [RFC PATCH V2 02/12] dt-bindings: misc: Tegra configuration settings
2024-07-01 15:12 [RFC PATCH V2 00/12] Introduce Tegra register config settings Krishna Yarlagadda
2024-07-01 15:12 ` [RFC PATCH V2 01/12] Documentation: Introduce config settings framework Krishna Yarlagadda
@ 2024-07-01 15:12 ` Krishna Yarlagadda
2024-07-01 16:58 ` Rob Herring (Arm)
2024-07-01 15:12 ` [RFC PATCH V2 03/12] soc: tegra: Add config setting framework Krishna Yarlagadda
` (9 subsequent siblings)
11 siblings, 1 reply; 20+ messages in thread
From: Krishna Yarlagadda @ 2024-07-01 15:12 UTC (permalink / raw)
To: linux-tegra, devicetree, linux-doc, linux-i2c, linux-mmc,
linux-kernel
Cc: thierry.reding, jonathanh, robh, krzk+dt, conor+dt, corbet,
andi.shyti, wsa+renesas, ulf.hansson, adrian.hunter, digetx,
ldewangan, kyarlagadda, mkumard
Config framework parses device tree and provides a list of register
settings with mask per mode to be applied by the controller.
Add binding document for config settings framework. Config settings
are defined as a property per field and have different modes per device.
Signed-off-by: Krishna Yarlagadda <kyarlagadda@nvidia.com>
---
.../misc/nvidia,tegra-config-settings.yaml | 62 +++++++++++++++++++
MAINTAINERS | 1 +
2 files changed, 63 insertions(+)
create mode 100644 Documentation/devicetree/bindings/misc/nvidia,tegra-config-settings.yaml
diff --git a/Documentation/devicetree/bindings/misc/nvidia,tegra-config-settings.yaml b/Documentation/devicetree/bindings/misc/nvidia,tegra-config-settings.yaml
new file mode 100644
index 000000000000..4e5d52504c01
--- /dev/null
+++ b/Documentation/devicetree/bindings/misc/nvidia,tegra-config-settings.yaml
@@ -0,0 +1,62 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/misc/nvidia,tegra-config-settings.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Config properties for a device
+
+description:
+ Config setting is the configuration based on chip/board/system
+ characterization on interface/controller settings. This is needed for
+ - making the controller internal configuration to better perform
+ - making the interface to work proper by setting drive strength, slew
+ rates etc
+ - making the low power leakage.
+ There are two types of recommended configuration settings
+ - Controller register specific for internal operation of controller.
+ - Pad control/Pinmux/pincontrol registers for interfacing.
+ These configurations can further be categorized as static and dynamic.
+ - Static config does not change until a controller is reset.
+ - Dynamic config changes based on mode or condition, controller is
+ operating in.
+
+maintainers:
+ - Thierry Reding <thierry.reding@gmail.com>
+
+properties:
+ $nodename:
+ const: configsettings
+
+patternProperties:
+ "config-[a-z0-9_]+$":
+ description:
+ Config node representing properties of a device. Properties of
+ each device are listed under a unique subnode and referenced from
+ device node.
+ type: object
+ additionalProperties: false
+
+ patternProperties:
+ "^[a-z0-9_]+-cfg$":
+ description:
+ Config profiles applied conditionally.
+ type: object
+ patternProperties:
+ "nvidia,[a-z0-9_]+$":
+ description:
+ Register field configuration.
+ $ref: /schemas/types.yaml#/definitions/uint32
+
+additionalProperties: true
+
+examples:
+ - |
+ configsettings {
+ configi2c1: config-i2c3160000 {
+ i2c-common-cfg {
+ nvidia,i2c-hs-sclk-high-period = <0x03>;
+ nvidia,i2c-hs-sclk-low-period = <0x08>;
+ };
+ };
+ };
diff --git a/MAINTAINERS b/MAINTAINERS
index 8a60c98ac755..ac8410ed421f 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -22260,6 +22260,7 @@ M: Thierry Reding <thierry.reding@gmail.com>
R: Laxman Dewangan <ldewangan@nvidia.com>
R: Krishna Yarlagadda <kyarlagadda@nvidia.com>
S: Supported
+F: Documentation/devicetree/bindings/misc/nvidia,tegra-config-settings.yaml
F: Documentation/misc-devices/tegra-cfg.rst
TEGRA PWM DRIVER
--
2.43.2
^ permalink raw reply related [flat|nested] 20+ messages in thread* Re: [RFC PATCH V2 02/12] dt-bindings: misc: Tegra configuration settings
2024-07-01 15:12 ` [RFC PATCH V2 02/12] dt-bindings: misc: Tegra configuration settings Krishna Yarlagadda
@ 2024-07-01 16:58 ` Rob Herring (Arm)
0 siblings, 0 replies; 20+ messages in thread
From: Rob Herring (Arm) @ 2024-07-01 16:58 UTC (permalink / raw)
To: Krishna Yarlagadda
Cc: linux-kernel, linux-i2c, thierry.reding, corbet, wsa+renesas,
linux-mmc, mkumard, conor+dt, digetx, jonathanh, ulf.hansson,
adrian.hunter, krzk+dt, ldewangan, andi.shyti, devicetree,
linux-tegra, linux-doc
On Mon, 01 Jul 2024 20:42:20 +0530, Krishna Yarlagadda wrote:
> Config framework parses device tree and provides a list of register
> settings with mask per mode to be applied by the controller.
>
> Add binding document for config settings framework. Config settings
> are defined as a property per field and have different modes per device.
>
> Signed-off-by: Krishna Yarlagadda <kyarlagadda@nvidia.com>
> ---
> .../misc/nvidia,tegra-config-settings.yaml | 62 +++++++++++++++++++
> MAINTAINERS | 1 +
> 2 files changed, 63 insertions(+)
> create mode 100644 Documentation/devicetree/bindings/misc/nvidia,tegra-config-settings.yaml
>
My bot found errors running 'make dt_binding_check' on your patch:
yamllint warnings/errors:
./Documentation/devicetree/bindings/misc/nvidia,tegra-config-settings.yaml:46:1: [error] syntax error: found character '\t' that cannot start any token (syntax)
dtschema/dtc warnings/errors:
make[2]: *** Deleting file 'Documentation/devicetree/bindings/misc/nvidia,tegra-config-settings.example.dts'
Documentation/devicetree/bindings/misc/nvidia,tegra-config-settings.yaml:46:1: found character that cannot start any token
make[2]: *** [Documentation/devicetree/bindings/Makefile:26: Documentation/devicetree/bindings/misc/nvidia,tegra-config-settings.example.dts] Error 1
make[2]: *** Waiting for unfinished jobs....
./Documentation/devicetree/bindings/misc/nvidia,tegra-config-settings.yaml:46:1: found character that cannot start any token
/builds/robherring/dt-review-ci/linux/Documentation/devicetree/bindings/misc/nvidia,tegra-config-settings.yaml: ignoring, error parsing file
make[1]: *** [/builds/robherring/dt-review-ci/linux/Makefile:1430: dt_binding_check] Error 2
make: *** [Makefile:240: __sub-make] Error 2
doc reference errors (make refcheckdocs):
See https://patchwork.ozlabs.org/project/devicetree-bindings/patch/20240701151231.29425-3-kyarlagadda@nvidia.com
The base for the series is generally the latest rc1. A different dependency
should be noted in *this* patch.
If you already ran 'make dt_binding_check' and didn't see the above
error(s), then make sure 'yamllint' is installed and dt-schema is up to
date:
pip3 install dtschema --upgrade
Please check and re-submit after running the above command yourself. Note
that DT_SCHEMA_FILES can be set to your schema file to speed up checking
your schema. However, it must be unset to test all examples with your schema.
^ permalink raw reply [flat|nested] 20+ messages in thread
* [RFC PATCH V2 03/12] soc: tegra: Add config setting framework
2024-07-01 15:12 [RFC PATCH V2 00/12] Introduce Tegra register config settings Krishna Yarlagadda
2024-07-01 15:12 ` [RFC PATCH V2 01/12] Documentation: Introduce config settings framework Krishna Yarlagadda
2024-07-01 15:12 ` [RFC PATCH V2 02/12] dt-bindings: misc: Tegra configuration settings Krishna Yarlagadda
@ 2024-07-01 15:12 ` Krishna Yarlagadda
2024-07-01 15:12 ` [RFC PATCH V2 04/12] dt-bindings: misc: tegra-i2c: config settings Krishna Yarlagadda
` (8 subsequent siblings)
11 siblings, 0 replies; 20+ messages in thread
From: Krishna Yarlagadda @ 2024-07-01 15:12 UTC (permalink / raw)
To: linux-tegra, devicetree, linux-doc, linux-i2c, linux-mmc,
linux-kernel
Cc: thierry.reding, jonathanh, robh, krzk+dt, conor+dt, corbet,
andi.shyti, wsa+renesas, ulf.hansson, adrian.hunter, digetx,
ldewangan, kyarlagadda, mkumard
Config settings are defined as a property per field and have different
modes per device. Each mode contains multiple properties and a device
can have multiple modes.
Config framework parses device tree and provides a list of register
settings with mask per mode to be applied by the controller.
Add APIs to parse list of register config settings and to get config
from the list by name to be applied.
Signed-off-by: Laxman Dewangan <ldewangan@nvidia.com>
Signed-off-by: Krishna Yarlagadda <kyarlagadda@nvidia.com>
---
MAINTAINERS | 1 +
drivers/soc/tegra/Makefile | 1 +
drivers/soc/tegra/tegra-cfg.c | 147 ++++++++++++++++++++++++++++++++++
include/soc/tegra/tegra-cfg.h | 87 ++++++++++++++++++++
4 files changed, 236 insertions(+)
create mode 100644 drivers/soc/tegra/tegra-cfg.c
create mode 100644 include/soc/tegra/tegra-cfg.h
diff --git a/MAINTAINERS b/MAINTAINERS
index ac8410ed421f..23e79a878f2a 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -22262,6 +22262,7 @@ R: Krishna Yarlagadda <kyarlagadda@nvidia.com>
S: Supported
F: Documentation/devicetree/bindings/misc/nvidia,tegra-config-settings.yaml
F: Documentation/misc-devices/tegra-cfg.rst
+F: drivers/soc/tegra/tegra-cfg.c
TEGRA PWM DRIVER
M: Thierry Reding <thierry.reding@gmail.com>
diff --git a/drivers/soc/tegra/Makefile b/drivers/soc/tegra/Makefile
index 01059619e764..8d0c8dc62c8c 100644
--- a/drivers/soc/tegra/Makefile
+++ b/drivers/soc/tegra/Makefile
@@ -8,3 +8,4 @@ obj-$(CONFIG_SOC_TEGRA_PMC) += pmc.o
obj-$(CONFIG_SOC_TEGRA20_VOLTAGE_COUPLER) += regulators-tegra20.o
obj-$(CONFIG_SOC_TEGRA30_VOLTAGE_COUPLER) += regulators-tegra30.o
obj-$(CONFIG_ARCH_TEGRA_186_SOC) += ari-tegra186.o
+obj-y += tegra-cfg.o
diff --git a/drivers/soc/tegra/tegra-cfg.c b/drivers/soc/tegra/tegra-cfg.c
new file mode 100644
index 000000000000..50a15651aaa1
--- /dev/null
+++ b/drivers/soc/tegra/tegra-cfg.c
@@ -0,0 +1,147 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2024 NVIDIA CORPORATION. All rights reserved.
+ */
+
+#include <linux/device.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/slab.h>
+
+#include <soc/tegra/tegra-cfg.h>
+
+static int tegra_cfg_update_reg_info(struct device_node *cfg_node,
+ const struct tegra_cfg_field_desc *field,
+ struct tegra_cfg_reg *regs,
+ struct tegra_cfg *cfg)
+{
+ int ret;
+ unsigned int k, value = 0;
+
+ ret = of_property_read_u32(cfg_node, field->name, &value);
+ if (ret)
+ return ret;
+
+ /*
+ * Find matching register for this field in register info. Field info
+ * has details of register offset.
+ */
+ for (k = 0; k < cfg->num_regs; ++k) {
+ if (regs[k].offset == field->offset)
+ break;
+ }
+
+ /* If register not found, add new at end of list */
+ if (k == cfg->num_regs) {
+ cfg->num_regs++;
+ regs[k].offset = field->offset;
+ }
+
+ /* add field value to register */
+ value = value << __ffs(field->mask);
+ regs[k].value |= value & field->mask;
+ regs[k].mask |= field->mask;
+
+ return 0;
+}
+
+/*
+ * Initialize config list. Parse config node for properties (register fields).
+ * Get list of configs and value of fields populated in tegra_cfg_desc.
+ * Consolidate field data in reg offset, mask & value format in tegra_cfg.
+ * Repeat for each config and store in tegra_cfg_list.
+ */
+static struct tegra_cfg_list *tegra_cfg_init(struct device *dev,
+ const struct device_node *np,
+ const struct tegra_cfg_desc *cfg_desc)
+{
+ struct device_node *np_cfg = NULL, *child;
+ struct tegra_cfg_reg *regs;
+ struct tegra_cfg_list *list;
+ struct tegra_cfg *cfg;
+ const struct tegra_cfg_field_desc *fields;
+ unsigned int count, i;
+ int ret;
+
+ if (np)
+ np_cfg = of_parse_phandle(np, "config-settings", 0);
+ if (!np_cfg)
+ return ERR_PTR(-ENODEV);
+
+ count = of_get_child_count(np_cfg);
+ if (count <= 0) {
+ dev_dbg(dev, "Node %s: No config settings\n",
+ np->name);
+ return ERR_PTR(-ENODEV);
+ }
+
+ list = devm_kzalloc(dev, sizeof(*list), GFP_KERNEL);
+ if (!list)
+ return ERR_PTR(-ENOMEM);
+ list->num_cfg = 0;
+ list->cfg = NULL;
+
+ /* allocate mem for all configurations */
+ list->cfg = devm_kcalloc(dev, count, sizeof(*list->cfg),
+ GFP_KERNEL);
+ if (!list->cfg)
+ return ERR_PTR(-ENOMEM);
+
+ fields = cfg_desc->fields;
+ count = 0;
+ /*
+ * Iterate through all configurations.
+ */
+ for_each_available_child_of_node(np_cfg, child) {
+ cfg = &list->cfg[count];
+
+ regs = devm_kcalloc(dev, cfg_desc->num_regs,
+ sizeof(*regs), GFP_KERNEL);
+ if (!regs)
+ return ERR_PTR(-ENOMEM);
+
+ cfg->name = child->name;
+ cfg->regs = regs;
+ cfg->num_regs = 0;
+
+ /* Look for all fields in 'child' config */
+ for (i = 0; i < cfg_desc->num_fields; i++) {
+ ret = tegra_cfg_update_reg_info(child, &fields[i],
+ regs, cfg);
+ if (ret < 0)
+ continue;
+ }
+ count++;
+ }
+
+ list->num_cfg = count;
+
+ return list;
+}
+
+struct tegra_cfg *
+tegra_cfg_get_by_name(struct device *dev,
+ const struct tegra_cfg_list *list,
+ const char *name)
+{
+ unsigned int i;
+
+ for (i = 0; i < list->num_cfg; ++i) {
+ if (!strcmp(list->cfg[i].name, name))
+ return &list->cfg[i];
+ }
+
+ return NULL;
+}
+EXPORT_SYMBOL(tegra_cfg_get_by_name);
+
+struct tegra_cfg_list *tegra_cfg_get(struct device *dev,
+ const struct device_node *np,
+ const struct tegra_cfg_desc *cfg_desc)
+{
+ return tegra_cfg_init(dev, np, cfg_desc);
+}
+EXPORT_SYMBOL(tegra_cfg_get);
diff --git a/include/soc/tegra/tegra-cfg.h b/include/soc/tegra/tegra-cfg.h
new file mode 100644
index 000000000000..ece6f63a83c1
--- /dev/null
+++ b/include/soc/tegra/tegra-cfg.h
@@ -0,0 +1,87 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2024, NVIDIA CORPORATION. All rights reserved.
+ */
+
+#ifndef __SOC_TEGRA_CFG_H__
+#define __SOC_TEGRA_CFG_H__
+
+#include <linux/types.h>
+
+/**
+ * Config settings are a list of DT properties holding each field's recommended
+ * value. Field info is held in tegra_cfg_field and tegra_cfg_desc.
+ * Data of all fields in a single register are parsed and stored in
+ * tegra_cfg_reg. Struct tegra_cfg_list contains list of configurations
+ * and each config tegra_cfg contains register list.
+ * Client drivers provide field and register data through tegra_cfg_desc.
+ */
+
+/**
+ * Register field and DT property mapping.
+ * @name: device property name of the field.
+ * @offset: offset of register from base.
+ * @mask: mask of field within register.
+ */
+struct tegra_cfg_field_desc {
+ const char *name;
+ u32 offset;
+ u32 mask;
+};
+
+#define TEGRA_CFG_FIELD(fname, roffset, fmask) \
+{ \
+ .name = fname, \
+ .offset = roffset, \
+ .mask = fmask, \
+}
+
+/**
+ * Configuration setting from controller where it passes the total number of
+ * registers having config, and their register field names.
+ */
+struct tegra_cfg_desc {
+ unsigned int num_regs;
+ unsigned int num_fields;
+ const struct tegra_cfg_field_desc *fields;
+};
+
+/**
+ * Configuration register info generated by combining all field config settings
+ * in device tree of a register.
+ * @offset: offset of register from base.
+ * @mask: generated mask from aggregate of all field settings read from dt.
+ * @value: generated value by combining all field properties read from dt.
+ */
+struct tegra_cfg_reg {
+ u32 offset;
+ u32 mask;
+ u32 value;
+};
+
+/**
+ * Per config info of all registers.
+ */
+struct tegra_cfg {
+ const char *name;
+ unsigned int num_regs;
+ struct tegra_cfg_reg *regs;
+};
+
+/**
+ * Config settings list.
+ */
+struct tegra_cfg_list {
+ unsigned int num_cfg;
+ struct tegra_cfg *cfg;
+};
+
+struct tegra_cfg *
+tegra_cfg_get_by_name(struct device *dev,
+ const struct tegra_cfg_list *list,
+ const char *cfg_name);
+
+struct tegra_cfg_list *tegra_cfg_get(struct device *dev,
+ const struct device_node *np,
+ const struct tegra_cfg_desc *cfg_dev);
+#endif /* __SOC_TEGRA_CFG_H__ */
--
2.43.2
^ permalink raw reply related [flat|nested] 20+ messages in thread* [RFC PATCH V2 04/12] dt-bindings: misc: tegra-i2c: config settings
2024-07-01 15:12 [RFC PATCH V2 00/12] Introduce Tegra register config settings Krishna Yarlagadda
` (2 preceding siblings ...)
2024-07-01 15:12 ` [RFC PATCH V2 03/12] soc: tegra: Add config setting framework Krishna Yarlagadda
@ 2024-07-01 15:12 ` Krishna Yarlagadda
2024-07-01 16:58 ` Rob Herring (Arm)
2024-07-01 17:42 ` Rob Herring
2024-07-01 15:12 ` [RFC PATCH V2 05/12] dt-bindings: i2c: tegra-i2c: reference to config Krishna Yarlagadda
` (7 subsequent siblings)
11 siblings, 2 replies; 20+ messages in thread
From: Krishna Yarlagadda @ 2024-07-01 15:12 UTC (permalink / raw)
To: linux-tegra, devicetree, linux-doc, linux-i2c, linux-mmc,
linux-kernel
Cc: thierry.reding, jonathanh, robh, krzk+dt, conor+dt, corbet,
andi.shyti, wsa+renesas, ulf.hansson, adrian.hunter, digetx,
ldewangan, kyarlagadda, mkumard
I2C interface timing registers are configured using config setting
framework. List available field properties for Tegra I2C controllers.
Signed-off-by: Krishna Yarlagadda <kyarlagadda@nvidia.com>
---
.../misc/nvidia,tegra-config-settings.yaml | 83 +++++++++++++++++--
1 file changed, 74 insertions(+), 9 deletions(-)
diff --git a/Documentation/devicetree/bindings/misc/nvidia,tegra-config-settings.yaml b/Documentation/devicetree/bindings/misc/nvidia,tegra-config-settings.yaml
index 4e5d52504c01..5f4da633e69b 100644
--- a/Documentation/devicetree/bindings/misc/nvidia,tegra-config-settings.yaml
+++ b/Documentation/devicetree/bindings/misc/nvidia,tegra-config-settings.yaml
@@ -38,17 +38,74 @@ patternProperties:
additionalProperties: false
patternProperties:
- "^[a-z0-9_]+-cfg$":
- description:
- Config profiles applied conditionally.
+ "^i2c-[a-z0-9_]+-cfg$":
+ description: Config settings for I2C devices.
type: object
- patternProperties:
- "nvidia,[a-z0-9_]+$":
- description:
- Register field configuration.
- $ref: /schemas/types.yaml#/definitions/uint32
+ additionalProperties: false
-additionalProperties: true
+ properties:
+ nvidia,i2c-clk-divisor-hs-mode:
+ description: I2C clock divisor for HS mode.
+ $ref: /schemas/types.yaml#/definitions/uint32
+ minimum: 0
+ maximum: 0xffff
+ nvidia,i2c-clk-divisor-fs-mode:
+ description: I2C clock divisor for FS mode.
+ $ref: /schemas/types.yaml#/definitions/uint32
+ minimum: 0
+ maximum: 0xffff
+ nvidia,i2c-hs-sclk-high-period:
+ description: I2C high speed sclk high period.
+ $ref: /schemas/types.yaml#/definitions/uint32
+ minimum: 0
+ maximum: 0xffff
+ nvidia,i2c-hs-sclk-low-period:
+ description: I2C high speed sclk low period.
+ $ref: /schemas/types.yaml#/definitions/uint32
+ minimum: 0
+ maximum: 0xffff
+ nvidia,i2c-hs-stop-setup-time:
+ description: I2C high speed stop setup time.
+ $ref: /schemas/types.yaml#/definitions/uint32
+ minimum: 0
+ maximum: 0xffff
+ nvidia,i2c-hs-start-hold-time:
+ description: I2C high speed start hold time.
+ $ref: /schemas/types.yaml#/definitions/uint32
+ minimum: 0
+ maximum: 0xffff
+ nvidia,i2c-hs-start-setup-time:
+ description: I2C high speed start setup time.
+ $ref: /schemas/types.yaml#/definitions/uint32
+ minimum: 0
+ maximum: 0xffff
+ nvidia,i2c-sclk-high-period:
+ description: I2C sclk high period.
+ $ref: /schemas/types.yaml#/definitions/uint32
+ minimum: 0
+ maximum: 0xffff
+ nvidia,i2c-sclk-low-period:
+ description: I2C sclk low period.
+ $ref: /schemas/types.yaml#/definitions/uint32
+ minimum: 0
+ maximum: 0xffff
+ nvidia,i2c-bus-free-time:
+ description: I2C bus free time.
+ $ref: /schemas/types.yaml#/definitions/uint32
+ minimum: 0
+ maximum: 0xffff
+ nvidia,i2c-stop-setup-time:
+ description: I2C stop setup time.
+ $ref: /schemas/types.yaml#/definitions/uint32
+ minimum: 0
+ maximum: 0xffff
+ nvidia,i2c-start-hold-time:
+ description: I2C start hold time.
+ $ref: /schemas/types.yaml#/definitions/uint32
+ minimum: 0
+ maximum: 0xffff
+
+additionalProperties: false
examples:
- |
@@ -58,5 +115,13 @@ examples:
nvidia,i2c-hs-sclk-high-period = <0x03>;
nvidia,i2c-hs-sclk-low-period = <0x08>;
};
+ i2c-fast-cfg {
+ nvidia,i2c-clk-divisor-fs-mode = <0x3c>;
+ nvidia,i2c-sclk-high-period = <0x02>;
+ };
+ i2c-fastplus-cfg {
+ nvidia,i2c-clk-divisor-fs-mode = <0x4f>;
+ nvidia,i2c-sclk-high-period = <0x07>;
+ };
};
};
--
2.43.2
^ permalink raw reply related [flat|nested] 20+ messages in thread* Re: [RFC PATCH V2 04/12] dt-bindings: misc: tegra-i2c: config settings
2024-07-01 15:12 ` [RFC PATCH V2 04/12] dt-bindings: misc: tegra-i2c: config settings Krishna Yarlagadda
@ 2024-07-01 16:58 ` Rob Herring (Arm)
2024-07-01 17:42 ` Rob Herring
1 sibling, 0 replies; 20+ messages in thread
From: Rob Herring (Arm) @ 2024-07-01 16:58 UTC (permalink / raw)
To: Krishna Yarlagadda
Cc: thierry.reding, andi.shyti, krzk+dt, ulf.hansson, linux-mmc,
devicetree, digetx, corbet, linux-i2c, jonathanh, conor+dt,
ldewangan, mkumard, linux-doc, linux-kernel, wsa+renesas,
adrian.hunter, linux-tegra
On Mon, 01 Jul 2024 20:42:22 +0530, Krishna Yarlagadda wrote:
> I2C interface timing registers are configured using config setting
> framework. List available field properties for Tegra I2C controllers.
>
> Signed-off-by: Krishna Yarlagadda <kyarlagadda@nvidia.com>
> ---
> .../misc/nvidia,tegra-config-settings.yaml | 83 +++++++++++++++++--
> 1 file changed, 74 insertions(+), 9 deletions(-)
>
My bot found errors running 'make dt_binding_check' on your patch:
yamllint warnings/errors:
dtschema/dtc warnings/errors:
Documentation/devicetree/bindings/net/wireless/qcom,ath11k.example.dtb: /example-0/remoteproc@cd00000: failed to match any schema with compatible: ['qcom,ipq8074-wcss-pil']
Documentation/devicetree/bindings/clock/sprd,sc9863a-clk.example.dtb: /example-1/syscon@20e00000: failed to match any schema with compatible: ['sprd,sc9863a-glbregs', 'syscon', 'simple-mfd']
Documentation/devicetree/bindings/clock/milbeaut-clock.example.dtb: /example-2/serial@1e700010: failed to match any schema with compatible: ['socionext,milbeaut-usio-uart']
Documentation/devicetree/bindings/arm/hisilicon/controller/hi3798cv200-perictrl.example.dtb: /example-0/peripheral-controller@8a20000/phy@850: failed to match any schema with compatible: ['hisilicon,hi3798cv200-combphy']
/builds/robherring/dt-review-ci/linux/Documentation/devicetree/bindings/arm/stm32/st,mlahb.example.dtb: ahb@38000000: Unevaluated properties are not allowed ('reg' was unexpected)
from schema $id: http://devicetree.org/schemas/arm/stm32/st,mlahb.yaml#
Documentation/devicetree/bindings/sound/st,stm32-sai.example.dtb: /example-0/sai@4400b000/audio-controller@4400b004: failed to match any schema with compatible: ['st,stm32-sai-sub-a']
Documentation/devicetree/bindings/thermal/brcm,avs-ro-thermal.example.dtb: /example-0/avs-monitor@7d5d2000: failed to match any schema with compatible: ['brcm,bcm2711-avs-monitor', 'syscon', 'simple-mfd']
doc reference errors (make refcheckdocs):
See https://patchwork.ozlabs.org/project/devicetree-bindings/patch/20240701151231.29425-5-kyarlagadda@nvidia.com
The base for the series is generally the latest rc1. A different dependency
should be noted in *this* patch.
If you already ran 'make dt_binding_check' and didn't see the above
error(s), then make sure 'yamllint' is installed and dt-schema is up to
date:
pip3 install dtschema --upgrade
Please check and re-submit after running the above command yourself. Note
that DT_SCHEMA_FILES can be set to your schema file to speed up checking
your schema. However, it must be unset to test all examples with your schema.
^ permalink raw reply [flat|nested] 20+ messages in thread* Re: [RFC PATCH V2 04/12] dt-bindings: misc: tegra-i2c: config settings
2024-07-01 15:12 ` [RFC PATCH V2 04/12] dt-bindings: misc: tegra-i2c: config settings Krishna Yarlagadda
2024-07-01 16:58 ` Rob Herring (Arm)
@ 2024-07-01 17:42 ` Rob Herring
2024-07-02 10:29 ` Thierry Reding
1 sibling, 1 reply; 20+ messages in thread
From: Rob Herring @ 2024-07-01 17:42 UTC (permalink / raw)
To: Krishna Yarlagadda
Cc: linux-tegra, devicetree, linux-doc, linux-i2c, linux-mmc,
linux-kernel, thierry.reding, jonathanh, krzk+dt, conor+dt,
corbet, andi.shyti, wsa+renesas, ulf.hansson, adrian.hunter,
digetx, ldewangan, mkumard
On Mon, Jul 01, 2024 at 08:42:22PM +0530, Krishna Yarlagadda wrote:
> I2C interface timing registers are configured using config setting
> framework. List available field properties for Tegra I2C controllers.
How is I2C bus timing parameters specific to NVIDIA? Just because you
have more controls? No. That's no reason to invent a whole new way to
specify parameters. Extend what's already there and make it work for
anyone.
Rob
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [RFC PATCH V2 04/12] dt-bindings: misc: tegra-i2c: config settings
2024-07-01 17:42 ` Rob Herring
@ 2024-07-02 10:29 ` Thierry Reding
2024-07-03 20:21 ` Rob Herring
0 siblings, 1 reply; 20+ messages in thread
From: Thierry Reding @ 2024-07-02 10:29 UTC (permalink / raw)
To: Rob Herring
Cc: Krishna Yarlagadda, linux-tegra, devicetree, linux-doc, linux-i2c,
linux-mmc, linux-kernel, jonathanh, krzk+dt, conor+dt, corbet,
andi.shyti, wsa+renesas, ulf.hansson, adrian.hunter, digetx,
ldewangan, mkumard
[-- Attachment #1: Type: text/plain, Size: 992 bytes --]
On Mon, Jul 01, 2024 at 11:42:27AM GMT, Rob Herring wrote:
> On Mon, Jul 01, 2024 at 08:42:22PM +0530, Krishna Yarlagadda wrote:
> > I2C interface timing registers are configured using config setting
> > framework. List available field properties for Tegra I2C controllers.
>
> How is I2C bus timing parameters specific to NVIDIA? Just because you
> have more controls? No. That's no reason to invent a whole new way to
> specify parameters. Extend what's already there and make it work for
> anyone.
This may be applicable to a subset of this, and yes, maybe we can find
generalizations for some of these parameters.
However, we're also looking for feedback specifically on these config
nodes that go beyond individual timing parameters. For example in the
case of I2C, how should parameters for different operating modes be
described?
Would you agree with something along the lines provided in this series?
Do you have any better suggestions?
Thanks,
Thierry
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [RFC PATCH V2 04/12] dt-bindings: misc: tegra-i2c: config settings
2024-07-02 10:29 ` Thierry Reding
@ 2024-07-03 20:21 ` Rob Herring
2024-07-05 10:51 ` Thierry Reding
0 siblings, 1 reply; 20+ messages in thread
From: Rob Herring @ 2024-07-03 20:21 UTC (permalink / raw)
To: Thierry Reding
Cc: Krishna Yarlagadda, linux-tegra, devicetree, linux-doc, linux-i2c,
linux-mmc, linux-kernel, jonathanh, krzk+dt, conor+dt, corbet,
andi.shyti, wsa+renesas, ulf.hansson, adrian.hunter, digetx,
ldewangan, mkumard
On Tue, Jul 2, 2024 at 4:29 AM Thierry Reding <thierry.reding@gmail.com> wrote:
>
> On Mon, Jul 01, 2024 at 11:42:27AM GMT, Rob Herring wrote:
> > On Mon, Jul 01, 2024 at 08:42:22PM +0530, Krishna Yarlagadda wrote:
> > > I2C interface timing registers are configured using config setting
> > > framework. List available field properties for Tegra I2C controllers.
> >
> > How is I2C bus timing parameters specific to NVIDIA? Just because you
> > have more controls? No. That's no reason to invent a whole new way to
> > specify parameters. Extend what's already there and make it work for
> > anyone.
>
> This may be applicable to a subset of this, and yes, maybe we can find
> generalizations for some of these parameters.
>
> However, we're also looking for feedback specifically on these config
> nodes that go beyond individual timing parameters. For example in the
> case of I2C, how should parameters for different operating modes be
> described?
Like what? It all looks like timing to me.
> Would you agree with something along the lines provided in this series?
When there are multiple users/vendors of it, maybe.
In general, it goes against the DT design of properties for foo go in
foo's node. This looks more like how ACPI does things where it's add
another table for this new thing we need.
Rob
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [RFC PATCH V2 04/12] dt-bindings: misc: tegra-i2c: config settings
2024-07-03 20:21 ` Rob Herring
@ 2024-07-05 10:51 ` Thierry Reding
0 siblings, 0 replies; 20+ messages in thread
From: Thierry Reding @ 2024-07-05 10:51 UTC (permalink / raw)
To: Rob Herring
Cc: Krishna Yarlagadda, linux-tegra, devicetree, linux-doc, linux-i2c,
linux-mmc, linux-kernel, jonathanh, krzk+dt, conor+dt, corbet,
andi.shyti, wsa+renesas, ulf.hansson, adrian.hunter, digetx,
ldewangan, mkumard
[-- Attachment #1: Type: text/plain, Size: 2912 bytes --]
On Wed, Jul 03, 2024 at 02:21:04PM GMT, Rob Herring wrote:
> On Tue, Jul 2, 2024 at 4:29 AM Thierry Reding <thierry.reding@gmail.com> wrote:
> >
> > On Mon, Jul 01, 2024 at 11:42:27AM GMT, Rob Herring wrote:
> > > On Mon, Jul 01, 2024 at 08:42:22PM +0530, Krishna Yarlagadda wrote:
> > > > I2C interface timing registers are configured using config setting
> > > > framework. List available field properties for Tegra I2C controllers.
> > >
> > > How is I2C bus timing parameters specific to NVIDIA? Just because you
> > > have more controls? No. That's no reason to invent a whole new way to
> > > specify parameters. Extend what's already there and make it work for
> > > anyone.
> >
> > This may be applicable to a subset of this, and yes, maybe we can find
> > generalizations for some of these parameters.
> >
> > However, we're also looking for feedback specifically on these config
> > nodes that go beyond individual timing parameters. For example in the
> > case of I2C, how should parameters for different operating modes be
> > described?
>
> Like what? It all looks like timing to me.
The problem here isn't the individual properties but rather how to group
them. More generally the problem is that we have a set of settings that
need to be applied in different variants. Yes, they are all timings, but
the values differ based on what mode a given controller operates at.
Take for example I2C where we have things like start-hold time or stop-
setup time, which we could describe in a more generic way (i.e. leave
out the vendor prefix). However, depending on the mode that the I2C
controller runs at (could be standard mode, fast mode or fastplus mode)
these values need to be adjusted.
So it's the same set of properties but with different values for each
different operating mode. As far as I can tell there's no good construct
to describe this in DT currently.
> > Would you agree with something along the lines provided in this series?
>
> When there are multiple users/vendors of it, maybe.
>
> In general, it goes against the DT design of properties for foo go in
> foo's node. This looks more like how ACPI does things where it's add
> another table for this new thing we need.
Well, that's what Krishna had proposed in the first version of the
series, which you guys rejected. The problem with that is that we cannot
easily group these settings using nodes because subnodes of I2C
controllers are considered to be clients by default. This applies to SPI
and other busses as well.
This approach avoids these issues and can be more easily optimized since
settings could be shared between multiple instances of the controllers.
I have a slight preference of putting this into the controllers' device
tree nodes, but I can't think of a good way of avoiding the above child
node problem other than what we had in v1.
Thierry
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
^ permalink raw reply [flat|nested] 20+ messages in thread
* [RFC PATCH V2 05/12] dt-bindings: i2c: tegra-i2c: reference to config
2024-07-01 15:12 [RFC PATCH V2 00/12] Introduce Tegra register config settings Krishna Yarlagadda
` (3 preceding siblings ...)
2024-07-01 15:12 ` [RFC PATCH V2 04/12] dt-bindings: misc: tegra-i2c: config settings Krishna Yarlagadda
@ 2024-07-01 15:12 ` Krishna Yarlagadda
2024-07-01 16:58 ` Rob Herring (Arm)
2024-07-01 15:12 ` [RFC PATCH V2 06/12] i2c: tegra: split clock initialization code Krishna Yarlagadda
` (6 subsequent siblings)
11 siblings, 1 reply; 20+ messages in thread
From: Krishna Yarlagadda @ 2024-07-01 15:12 UTC (permalink / raw)
To: linux-tegra, devicetree, linux-doc, linux-i2c, linux-mmc,
linux-kernel
Cc: thierry.reding, jonathanh, robh, krzk+dt, conor+dt, corbet,
andi.shyti, wsa+renesas, ulf.hansson, adrian.hunter, digetx,
ldewangan, kyarlagadda, mkumard
I2C interface timing registers are configured using config setting
framework. Add reference to I2C config settings.
Signed-off-by: Krishna Yarlagadda <kyarlagadda@nvidia.com>
---
.../devicetree/bindings/i2c/nvidia,tegra20-i2c.yaml | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/Documentation/devicetree/bindings/i2c/nvidia,tegra20-i2c.yaml b/Documentation/devicetree/bindings/i2c/nvidia,tegra20-i2c.yaml
index 424a4fc218b6..2f6f12149876 100644
--- a/Documentation/devicetree/bindings/i2c/nvidia,tegra20-i2c.yaml
+++ b/Documentation/devicetree/bindings/i2c/nvidia,tegra20-i2c.yaml
@@ -119,6 +119,11 @@ properties:
- const: rx
- const: tx
+ config-settings:
+ items:
+ - description: phandle to the i2c configuration settings
+ - $ref: /schemas/types.yaml#/definitions/phandle
+
allOf:
- $ref: /schemas/i2c/i2c-controller.yaml
- if:
--
2.43.2
^ permalink raw reply related [flat|nested] 20+ messages in thread* Re: [RFC PATCH V2 05/12] dt-bindings: i2c: tegra-i2c: reference to config
2024-07-01 15:12 ` [RFC PATCH V2 05/12] dt-bindings: i2c: tegra-i2c: reference to config Krishna Yarlagadda
@ 2024-07-01 16:58 ` Rob Herring (Arm)
0 siblings, 0 replies; 20+ messages in thread
From: Rob Herring (Arm) @ 2024-07-01 16:58 UTC (permalink / raw)
To: Krishna Yarlagadda
Cc: ldewangan, digetx, adrian.hunter, mkumard, thierry.reding,
jonathanh, conor+dt, andi.shyti, ulf.hansson, wsa+renesas,
krzk+dt, linux-tegra, corbet, devicetree, linux-doc, linux-kernel,
linux-mmc, linux-i2c
On Mon, 01 Jul 2024 20:42:23 +0530, Krishna Yarlagadda wrote:
> I2C interface timing registers are configured using config setting
> framework. Add reference to I2C config settings.
>
> Signed-off-by: Krishna Yarlagadda <kyarlagadda@nvidia.com>
> ---
> .../devicetree/bindings/i2c/nvidia,tegra20-i2c.yaml | 5 +++++
> 1 file changed, 5 insertions(+)
>
My bot found errors running 'make dt_binding_check' on your patch:
yamllint warnings/errors:
dtschema/dtc warnings/errors:
/builds/robherring/dt-review-ci/linux/Documentation/devicetree/bindings/i2c/nvidia,tegra20-i2c.yaml: config-settings: missing type definition
doc reference errors (make refcheckdocs):
See https://patchwork.ozlabs.org/project/devicetree-bindings/patch/20240701151231.29425-6-kyarlagadda@nvidia.com
The base for the series is generally the latest rc1. A different dependency
should be noted in *this* patch.
If you already ran 'make dt_binding_check' and didn't see the above
error(s), then make sure 'yamllint' is installed and dt-schema is up to
date:
pip3 install dtschema --upgrade
Please check and re-submit after running the above command yourself. Note
that DT_SCHEMA_FILES can be set to your schema file to speed up checking
your schema. However, it must be unset to test all examples with your schema.
^ permalink raw reply [flat|nested] 20+ messages in thread
* [RFC PATCH V2 06/12] i2c: tegra: split clock initialization code
2024-07-01 15:12 [RFC PATCH V2 00/12] Introduce Tegra register config settings Krishna Yarlagadda
` (4 preceding siblings ...)
2024-07-01 15:12 ` [RFC PATCH V2 05/12] dt-bindings: i2c: tegra-i2c: reference to config Krishna Yarlagadda
@ 2024-07-01 15:12 ` Krishna Yarlagadda
2024-07-01 15:12 ` [RFC PATCH V2 07/12] i2c: tegra: config settings for interface timings Krishna Yarlagadda
` (5 subsequent siblings)
11 siblings, 0 replies; 20+ messages in thread
From: Krishna Yarlagadda @ 2024-07-01 15:12 UTC (permalink / raw)
To: linux-tegra, devicetree, linux-doc, linux-i2c, linux-mmc,
linux-kernel
Cc: thierry.reding, jonathanh, robh, krzk+dt, conor+dt, corbet,
andi.shyti, wsa+renesas, ulf.hansson, adrian.hunter, digetx,
ldewangan, kyarlagadda, mkumard
Add new methods for setting clock parameters and setting
clock divisor.
Signed-off-by: Krishna Yarlagadda <kyarlagadda@nvidia.com>
---
drivers/i2c/busses/i2c-tegra.c | 127 ++++++++++++++++++++-------------
1 file changed, 77 insertions(+), 50 deletions(-)
diff --git a/drivers/i2c/busses/i2c-tegra.c b/drivers/i2c/busses/i2c-tegra.c
index 85b31edc558d..b3dc2603db35 100644
--- a/drivers/i2c/busses/i2c-tegra.c
+++ b/drivers/i2c/busses/i2c-tegra.c
@@ -604,12 +604,83 @@ static int tegra_i2c_wait_for_config_load(struct tegra_i2c_dev *i2c_dev)
return 0;
}
+static void tegra_i2c_set_clk_params(struct tegra_i2c_dev *i2c_dev)
+{
+ u32 val, clk_divisor, tsu_thd, tlow, thigh, non_hs_mode;
+
+ switch (i2c_dev->timings.bus_freq_hz) {
+ case I2C_MAX_STANDARD_MODE_FREQ + 1 ... I2C_MAX_FAST_MODE_PLUS_FREQ:
+ default:
+ tlow = i2c_dev->hw->tlow_fast_fastplus_mode;
+ thigh = i2c_dev->hw->thigh_fast_fastplus_mode;
+ tsu_thd = i2c_dev->hw->setup_hold_time_fast_fast_plus_mode;
+
+ if (i2c_dev->timings.bus_freq_hz > I2C_MAX_FAST_MODE_FREQ)
+ non_hs_mode = i2c_dev->hw->clk_divisor_fast_plus_mode;
+ else
+ non_hs_mode = i2c_dev->hw->clk_divisor_fast_mode;
+ break;
+
+ case 0 ... I2C_MAX_STANDARD_MODE_FREQ:
+ tlow = i2c_dev->hw->tlow_std_mode;
+ thigh = i2c_dev->hw->thigh_std_mode;
+ tsu_thd = i2c_dev->hw->setup_hold_time_std_mode;
+ non_hs_mode = i2c_dev->hw->clk_divisor_std_mode;
+ break;
+ }
+
+ /* make sure clock divisor programmed correctly */
+ clk_divisor = FIELD_PREP(I2C_CLK_DIVISOR_HSMODE,
+ i2c_dev->hw->clk_divisor_hs_mode) |
+ FIELD_PREP(I2C_CLK_DIVISOR_STD_FAST_MODE, non_hs_mode);
+ i2c_writel(i2c_dev, clk_divisor, I2C_CLK_DIVISOR);
+
+ if (i2c_dev->hw->has_interface_timing_reg) {
+ val = FIELD_PREP(I2C_INTERFACE_TIMING_THIGH, thigh) |
+ FIELD_PREP(I2C_INTERFACE_TIMING_TLOW, tlow);
+ i2c_writel(i2c_dev, val, I2C_INTERFACE_TIMING_0);
+ }
+
+ /*
+ * Configure setup and hold times only when tsu_thd is non-zero.
+ * Otherwise, preserve the chip default values.
+ */
+ if (i2c_dev->hw->has_interface_timing_reg && tsu_thd)
+ i2c_writel(i2c_dev, tsu_thd, I2C_INTERFACE_TIMING_1);
+}
+
+static int tegra_i2c_set_div_clk(struct tegra_i2c_dev *i2c_dev)
+{
+ u32 clk_multiplier, tlow, thigh, non_hs_mode;
+ u32 timing, clk_divisor;
+ int err;
+
+ timing = i2c_readl(i2c_dev, I2C_INTERFACE_TIMING_0);
+
+ tlow = FIELD_GET(I2C_INTERFACE_TIMING_TLOW, timing);
+ thigh = FIELD_GET(I2C_INTERFACE_TIMING_THIGH, timing);
+
+ clk_divisor = i2c_readl(i2c_dev, I2C_CLK_DIVISOR);
+
+ non_hs_mode = FIELD_GET(I2C_CLK_DIVISOR_STD_FAST_MODE, clk_divisor);
+
+ clk_multiplier = (thigh + tlow + 2) * (non_hs_mode + 1);
+
+ err = clk_set_rate(i2c_dev->div_clk,
+ i2c_dev->timings.bus_freq_hz * clk_multiplier);
+ if (err) {
+ dev_err(i2c_dev->dev, "failed to set div_clk rate: %d\n", err);
+ return err;
+ }
+
+ return 0;
+}
+
static int tegra_i2c_init(struct tegra_i2c_dev *i2c_dev)
{
- u32 val, clk_divisor, clk_multiplier, tsu_thd, tlow, thigh, non_hs_mode;
+ u32 val;
+ int err;
acpi_handle handle = ACPI_HANDLE(i2c_dev->dev);
- struct i2c_timings *t = &i2c_dev->timings;
- int err;
/*
* The reset shouldn't ever fail in practice. The failure will be a
@@ -641,54 +712,10 @@ static int tegra_i2c_init(struct tegra_i2c_dev *i2c_dev)
if (IS_VI(i2c_dev))
tegra_i2c_vi_init(i2c_dev);
- switch (t->bus_freq_hz) {
- case I2C_MAX_STANDARD_MODE_FREQ + 1 ... I2C_MAX_FAST_MODE_PLUS_FREQ:
- default:
- tlow = i2c_dev->hw->tlow_fast_fastplus_mode;
- thigh = i2c_dev->hw->thigh_fast_fastplus_mode;
- tsu_thd = i2c_dev->hw->setup_hold_time_fast_fast_plus_mode;
-
- if (t->bus_freq_hz > I2C_MAX_FAST_MODE_FREQ)
- non_hs_mode = i2c_dev->hw->clk_divisor_fast_plus_mode;
- else
- non_hs_mode = i2c_dev->hw->clk_divisor_fast_mode;
- break;
-
- case 0 ... I2C_MAX_STANDARD_MODE_FREQ:
- tlow = i2c_dev->hw->tlow_std_mode;
- thigh = i2c_dev->hw->thigh_std_mode;
- tsu_thd = i2c_dev->hw->setup_hold_time_std_mode;
- non_hs_mode = i2c_dev->hw->clk_divisor_std_mode;
- break;
- }
-
- /* make sure clock divisor programmed correctly */
- clk_divisor = FIELD_PREP(I2C_CLK_DIVISOR_HSMODE,
- i2c_dev->hw->clk_divisor_hs_mode) |
- FIELD_PREP(I2C_CLK_DIVISOR_STD_FAST_MODE, non_hs_mode);
- i2c_writel(i2c_dev, clk_divisor, I2C_CLK_DIVISOR);
-
- if (i2c_dev->hw->has_interface_timing_reg) {
- val = FIELD_PREP(I2C_INTERFACE_TIMING_THIGH, thigh) |
- FIELD_PREP(I2C_INTERFACE_TIMING_TLOW, tlow);
- i2c_writel(i2c_dev, val, I2C_INTERFACE_TIMING_0);
- }
-
- /*
- * Configure setup and hold times only when tsu_thd is non-zero.
- * Otherwise, preserve the chip default values.
- */
- if (i2c_dev->hw->has_interface_timing_reg && tsu_thd)
- i2c_writel(i2c_dev, tsu_thd, I2C_INTERFACE_TIMING_1);
-
- clk_multiplier = (tlow + thigh + 2) * (non_hs_mode + 1);
-
- err = clk_set_rate(i2c_dev->div_clk,
- t->bus_freq_hz * clk_multiplier);
- if (err) {
- dev_err(i2c_dev->dev, "failed to set div-clk rate: %d\n", err);
+ tegra_i2c_set_clk_params(i2c_dev);
+ err = tegra_i2c_set_div_clk(i2c_dev);
+ if (err)
return err;
- }
if (!IS_DVC(i2c_dev) && !IS_VI(i2c_dev)) {
u32 sl_cfg = i2c_readl(i2c_dev, I2C_SL_CNFG);
--
2.43.2
^ permalink raw reply related [flat|nested] 20+ messages in thread* [RFC PATCH V2 07/12] i2c: tegra: config settings for interface timings
2024-07-01 15:12 [RFC PATCH V2 00/12] Introduce Tegra register config settings Krishna Yarlagadda
` (5 preceding siblings ...)
2024-07-01 15:12 ` [RFC PATCH V2 06/12] i2c: tegra: split clock initialization code Krishna Yarlagadda
@ 2024-07-01 15:12 ` Krishna Yarlagadda
2024-07-01 15:12 ` [RFC PATCH V2 08/12] arm64: tegra: I2C " Krishna Yarlagadda
` (4 subsequent siblings)
11 siblings, 0 replies; 20+ messages in thread
From: Krishna Yarlagadda @ 2024-07-01 15:12 UTC (permalink / raw)
To: linux-tegra, devicetree, linux-doc, linux-i2c, linux-mmc,
linux-kernel
Cc: thierry.reding, jonathanh, robh, krzk+dt, conor+dt, corbet,
andi.shyti, wsa+renesas, ulf.hansson, adrian.hunter, digetx,
ldewangan, kyarlagadda, mkumard, Akhil R
Use config settings framework to initialize Tegra I2C interface
timing registers and clock divisor based on I2C speed modes.
Each speed mode uses predefined configuration for interface timing
and clock registers.
Signed-off-by: Akhil R <akhilrajeev@nvidia.com>
Signed-off-by: Laxman Dewangan <ldewangan@nvidia.com>
Signed-off-by: Krishna Yarlagadda <kyarlagadda@nvidia.com>
---
drivers/i2c/busses/i2c-tegra.c | 134 +++++++++++++++++++++++++++++++--
1 file changed, 129 insertions(+), 5 deletions(-)
diff --git a/drivers/i2c/busses/i2c-tegra.c b/drivers/i2c/busses/i2c-tegra.c
index b3dc2603db35..b81925576060 100644
--- a/drivers/i2c/busses/i2c-tegra.c
+++ b/drivers/i2c/busses/i2c-tegra.c
@@ -28,6 +28,8 @@
#include <linux/pm_runtime.h>
#include <linux/reset.h>
+#include <soc/tegra/tegra-cfg.h>
+
#define BYTES_PER_FIFO_WORD 4
#define I2C_CNFG 0x000
@@ -108,8 +110,9 @@
#define I2C_MST_CORE_CLKEN_OVR BIT(0)
#define I2C_INTERFACE_TIMING_0 0x094
-#define I2C_INTERFACE_TIMING_THIGH GENMASK(13, 8)
-#define I2C_INTERFACE_TIMING_TLOW GENMASK(5, 0)
+#define I2C_INTERFACE_TIMING_THIGH GENMASK(15, 8)
+#define I2C_INTERFACE_TIMING_TLOW GENMASK(7, 0)
+
#define I2C_INTERFACE_TIMING_1 0x098
#define I2C_INTERFACE_TIMING_TBUF GENMASK(29, 24)
#define I2C_INTERFACE_TIMING_TSU_STO GENMASK(21, 16)
@@ -117,8 +120,9 @@
#define I2C_INTERFACE_TIMING_TSU_STA GENMASK(5, 0)
#define I2C_HS_INTERFACE_TIMING_0 0x09c
-#define I2C_HS_INTERFACE_TIMING_THIGH GENMASK(13, 8)
-#define I2C_HS_INTERFACE_TIMING_TLOW GENMASK(5, 0)
+#define I2C_HS_INTERFACE_TIMING_THIGH GENMASK(15, 8)
+#define I2C_HS_INTERFACE_TIMING_TLOW GENMASK(7, 0)
+
#define I2C_HS_INTERFACE_TIMING_1 0x0a0
#define I2C_HS_INTERFACE_TIMING_TSU_STO GENMASK(21, 16)
#define I2C_HS_INTERFACE_TIMING_THD_STA GENMASK(13, 8)
@@ -226,6 +230,49 @@ struct tegra_i2c_hw_feature {
bool has_interface_timing_reg;
};
+/**
+ * I2C register config fields.
+ */
+static const struct tegra_cfg_field_desc i2c_cfg_fields[] = {
+ TEGRA_CFG_FIELD("nvidia,i2c-clk-divisor-fs-mode",
+ I2C_CLK_DIVISOR, I2C_CLK_DIVISOR_STD_FAST_MODE),
+ TEGRA_CFG_FIELD("nvidia,i2c-clk-divisor-hs-mode",
+ I2C_CLK_DIVISOR, I2C_CLK_DIVISOR_HSMODE),
+ TEGRA_CFG_FIELD("nvidia,i2c-hs-sclk-high-period",
+ I2C_HS_INTERFACE_TIMING_0,
+ I2C_HS_INTERFACE_TIMING_THIGH),
+ TEGRA_CFG_FIELD("nvidia,i2c-hs-sclk-low-period",
+ I2C_HS_INTERFACE_TIMING_0,
+ I2C_HS_INTERFACE_TIMING_TLOW),
+ TEGRA_CFG_FIELD("nvidia,i2c-hs-stop-setup-time",
+ I2C_HS_INTERFACE_TIMING_1,
+ I2C_HS_INTERFACE_TIMING_TSU_STO),
+ TEGRA_CFG_FIELD("nvidia,i2c-hs-start-hold-time",
+ I2C_HS_INTERFACE_TIMING_1,
+ I2C_HS_INTERFACE_TIMING_THD_STA),
+ TEGRA_CFG_FIELD("nvidia,i2c-hs-start-setup-time",
+ I2C_HS_INTERFACE_TIMING_1,
+ I2C_HS_INTERFACE_TIMING_TSU_STA),
+ TEGRA_CFG_FIELD("nvidia,i2c-sclk-high-period",
+ I2C_INTERFACE_TIMING_0, I2C_INTERFACE_TIMING_THIGH),
+ TEGRA_CFG_FIELD("nvidia,i2c-sclk-low-period",
+ I2C_INTERFACE_TIMING_0, I2C_INTERFACE_TIMING_TLOW),
+ TEGRA_CFG_FIELD("nvidia,i2c-bus-free-time",
+ I2C_INTERFACE_TIMING_1, I2C_INTERFACE_TIMING_TBUF),
+ TEGRA_CFG_FIELD("nvidia,i2c-stop-setup-time",
+ I2C_INTERFACE_TIMING_1, I2C_INTERFACE_TIMING_TSU_STO),
+ TEGRA_CFG_FIELD("nvidia,i2c-start-hold-time",
+ I2C_INTERFACE_TIMING_1, I2C_INTERFACE_TIMING_THD_STA),
+ TEGRA_CFG_FIELD("nvidia,i2c-start-setup-time",
+ I2C_INTERFACE_TIMING_1, I2C_INTERFACE_TIMING_TSU_STA),
+};
+
+static struct tegra_cfg_desc i2c_cfg_desc = {
+ .num_regs = 0,
+ .num_fields = ARRAY_SIZE(i2c_cfg_fields),
+ .fields = i2c_cfg_fields,
+};
+
/**
* struct tegra_i2c_dev - per device I2C context
* @dev: device reference for power management
@@ -288,6 +335,8 @@ struct tegra_i2c_dev {
dma_addr_t dma_phys;
void *dma_buf;
+ struct tegra_cfg_list *list;
+
bool multimaster_mode;
bool atomic_mode;
bool dma_mode;
@@ -340,6 +389,16 @@ static u32 i2c_readl(struct tegra_i2c_dev *i2c_dev, unsigned int reg)
return readl_relaxed(i2c_dev->base + tegra_i2c_reg_addr(i2c_dev, reg));
}
+static void i2c_update(struct tegra_i2c_dev *i2c_dev, u32 mask,
+ u32 val, unsigned int reg)
+{
+ u32 rval;
+
+ rval = i2c_readl(i2c_dev, reg);
+ rval = (rval & ~mask) | val;
+ i2c_writel(i2c_dev, rval, reg);
+}
+
static void i2c_writesl(struct tegra_i2c_dev *i2c_dev, void *data,
unsigned int reg, unsigned int len)
{
@@ -604,6 +663,48 @@ static int tegra_i2c_wait_for_config_load(struct tegra_i2c_dev *i2c_dev)
return 0;
}
+static void tegra_i2c_write_cfg_settings(struct tegra_i2c_dev *i2c_dev,
+ const char *name)
+{
+ struct tegra_cfg_reg *regs;
+ struct tegra_cfg *cfg;
+ unsigned int i;
+
+ cfg = tegra_cfg_get_by_name(i2c_dev->dev, i2c_dev->list, name);
+ if (!cfg)
+ return;
+
+ regs = cfg->regs;
+ for (i = 0; i < cfg->num_regs; i++) {
+ i2c_update(i2c_dev, regs[i].mask, regs[i].value,
+ regs[i].offset);
+ }
+}
+
+static void tegra_i2c_config_cfg_settings(struct tegra_i2c_dev *i2c_dev)
+{
+ const char *name;
+
+ switch (i2c_dev->timings.bus_freq_hz) {
+ case I2C_MAX_FAST_MODE_PLUS_FREQ + 1 ... I2C_MAX_HIGH_SPEED_MODE_FREQ:
+ name = "i2c-high-cfg";
+ break;
+ case I2C_MAX_FAST_MODE_FREQ + 1 ... I2C_MAX_FAST_MODE_PLUS_FREQ:
+ name = "i2c-fastplus-cfg";
+ break;
+ case I2C_MAX_STANDARD_MODE_FREQ + 1 ... I2C_MAX_FAST_MODE_FREQ:
+ name = "i2c-fast-cfg";
+ break;
+ case 0 ... I2C_MAX_STANDARD_MODE_FREQ:
+ default:
+ name = "i2c-standard-cfg";
+ break;
+ }
+
+ tegra_i2c_write_cfg_settings(i2c_dev, "i2c-common-cfg");
+ tegra_i2c_write_cfg_settings(i2c_dev, name);
+}
+
static void tegra_i2c_set_clk_params(struct tegra_i2c_dev *i2c_dev)
{
u32 val, clk_divisor, tsu_thd, tlow, thigh, non_hs_mode;
@@ -712,7 +813,11 @@ static int tegra_i2c_init(struct tegra_i2c_dev *i2c_dev)
if (IS_VI(i2c_dev))
tegra_i2c_vi_init(i2c_dev);
- tegra_i2c_set_clk_params(i2c_dev);
+ if (i2c_dev->list)
+ tegra_i2c_config_cfg_settings(i2c_dev);
+ else
+ tegra_i2c_set_clk_params(i2c_dev);
+
err = tegra_i2c_set_div_clk(i2c_dev);
if (err)
return err;
@@ -1772,6 +1877,8 @@ static int tegra_i2c_probe(struct platform_device *pdev)
struct tegra_i2c_dev *i2c_dev;
struct resource *res;
int err;
+ const struct tegra_cfg_field_desc *fields;
+ unsigned int count = 0, i, j;
i2c_dev = devm_kzalloc(&pdev->dev, sizeof(*i2c_dev), GFP_KERNEL);
if (!i2c_dev)
@@ -1808,6 +1915,23 @@ static int tegra_i2c_probe(struct platform_device *pdev)
if (err)
return err;
+ fields = i2c_cfg_fields;
+
+ for (i = 0; i < i2c_cfg_desc.num_fields; i++) {
+ for (j = 0; j < i; j++)
+ if (fields[i].offset == fields[j].offset)
+ break;
+ if (i == j)
+ count++;
+ }
+ i2c_cfg_desc.num_regs = count;
+
+ i2c_dev->list = tegra_cfg_get(i2c_dev->dev, NULL, &i2c_cfg_desc);
+ if (IS_ERR_OR_NULL(i2c_dev->list)) {
+ dev_dbg(&pdev->dev, "Config setting not available\n");
+ i2c_dev->list = NULL;
+ }
+
tegra_i2c_parse_dt(i2c_dev);
err = tegra_i2c_init_reset(i2c_dev);
--
2.43.2
^ permalink raw reply related [flat|nested] 20+ messages in thread* [RFC PATCH V2 08/12] arm64: tegra: I2C interface timings
2024-07-01 15:12 [RFC PATCH V2 00/12] Introduce Tegra register config settings Krishna Yarlagadda
` (6 preceding siblings ...)
2024-07-01 15:12 ` [RFC PATCH V2 07/12] i2c: tegra: config settings for interface timings Krishna Yarlagadda
@ 2024-07-01 15:12 ` Krishna Yarlagadda
2024-07-01 15:12 ` [RFC PATCH V2 09/12] dt-bindings: misc: tegra-sdhci: config settings Krishna Yarlagadda
` (3 subsequent siblings)
11 siblings, 0 replies; 20+ messages in thread
From: Krishna Yarlagadda @ 2024-07-01 15:12 UTC (permalink / raw)
To: linux-tegra, devicetree, linux-doc, linux-i2c, linux-mmc,
linux-kernel
Cc: thierry.reding, jonathanh, robh, krzk+dt, conor+dt, corbet,
andi.shyti, wsa+renesas, ulf.hansson, adrian.hunter, digetx,
ldewangan, kyarlagadda, mkumard
Set I2C interface timing registers through config settings for
Tegra234 chip and P3701 board.
Signed-off-by: Krishna Yarlagadda <kyarlagadda@nvidia.com>
---
MAINTAINERS | 1 +
arch/arm64/boot/dts/nvidia/tegra234-cfg.dtsi | 465 ++++++++++++++++++
.../dts/nvidia/tegra234-p3701-0000-cfg.dtsi | 107 ++++
.../boot/dts/nvidia/tegra234-p3701-0000.dtsi | 1 +
4 files changed, 574 insertions(+)
create mode 100644 arch/arm64/boot/dts/nvidia/tegra234-cfg.dtsi
create mode 100644 arch/arm64/boot/dts/nvidia/tegra234-p3701-0000-cfg.dtsi
diff --git a/MAINTAINERS b/MAINTAINERS
index 23e79a878f2a..99495e159e70 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -22260,6 +22260,7 @@ M: Thierry Reding <thierry.reding@gmail.com>
R: Laxman Dewangan <ldewangan@nvidia.com>
R: Krishna Yarlagadda <kyarlagadda@nvidia.com>
S: Supported
+F: arch/arm64/boot/dts/nvidia/tegra234*cfg.dtsi
F: Documentation/devicetree/bindings/misc/nvidia,tegra-config-settings.yaml
F: Documentation/misc-devices/tegra-cfg.rst
F: drivers/soc/tegra/tegra-cfg.c
diff --git a/arch/arm64/boot/dts/nvidia/tegra234-cfg.dtsi b/arch/arm64/boot/dts/nvidia/tegra234-cfg.dtsi
new file mode 100644
index 000000000000..7e5b9c10c617
--- /dev/null
+++ b/arch/arm64/boot/dts/nvidia/tegra234-cfg.dtsi
@@ -0,0 +1,465 @@
+// SPDX-License-Identifier: GPL-2.0-only
+
+/ {
+ configsettings {
+ configi2c1: config-i2c3160000 {
+
+ i2c-common-cfg {
+ nvidia,i2c-hs-sclk-high-period = <0x03>;
+ nvidia,i2c-hs-sclk-low-period = <0x08>;
+ };
+
+ i2c-fast-cfg {
+ nvidia,i2c-clk-divisor-fs-mode = <0x3c>;
+ nvidia,i2c-sclk-high-period = <0x02>;
+ nvidia,i2c-sclk-low-period = <0x02>;
+ nvidia,i2c-bus-free-time = <0x02>;
+ nvidia,i2c-stop-setup-time = <0x02>;
+ nvidia,i2c-start-hold-time = <0x02>;
+ nvidia,i2c-start-setup-time = <0x02>;
+ };
+
+ i2c-fastplus-cfg {
+ nvidia,i2c-clk-divisor-fs-mode = <0x16>;
+ nvidia,i2c-sclk-high-period = <0x02>;
+ nvidia,i2c-sclk-low-period = <0x02>;
+ nvidia,i2c-bus-free-time = <0x02>;
+ nvidia,i2c-stop-setup-time = <0x02>;
+ nvidia,i2c-start-hold-time = <0x02>;
+ nvidia,i2c-start-setup-time = <0x02>;
+ };
+
+ i2c-high-cfg {
+ nvidia,i2c-clk-divisor-fs-mode = <0x16>;
+ nvidia,i2c-clk-divisor-hs-mode = <0x02>;
+ nvidia,i2c-sclk-high-period = <0x02>;
+ nvidia,i2c-sclk-low-period = <0x02>;
+ nvidia,i2c-bus-free-time = <0x02>;
+ nvidia,i2c-stop-setup-time = <0x02>;
+ nvidia,i2c-start-hold-time = <0x02>;
+ nvidia,i2c-start-setup-time = <0x02>;
+ nvidia,i2c-hs-stop-setup-time = <0x09>;
+ nvidia,i2c-hs-start-hold-time = <0x09>;
+ nvidia,i2c-hs-start-setup-time = <0x09>;
+ };
+
+ i2c-standard-cfg {
+ nvidia,i2c-clk-divisor-fs-mode = <0x4f>;
+ nvidia,i2c-sclk-high-period = <0x07>;
+ nvidia,i2c-sclk-low-period = <0x08>;
+ nvidia,i2c-bus-free-time = <0x08>;
+ nvidia,i2c-stop-setup-time = <0x08>;
+ nvidia,i2c-start-hold-time = <0x08>;
+ nvidia,i2c-start-setup-time = <0x08>;
+ };
+
+ };
+
+ configi2c2: config-i2c3180000 {
+
+ i2c-common-cfg {
+ nvidia,i2c-hs-sclk-high-period = <0x03>;
+ nvidia,i2c-hs-sclk-low-period = <0x08>;
+ };
+
+ i2c-fast-cfg {
+ nvidia,i2c-clk-divisor-fs-mode = <0x3c>;
+ nvidia,i2c-sclk-high-period = <0x02>;
+ nvidia,i2c-sclk-low-period = <0x02>;
+ nvidia,i2c-bus-free-time = <0x02>;
+ nvidia,i2c-stop-setup-time = <0x02>;
+ nvidia,i2c-start-hold-time = <0x02>;
+ nvidia,i2c-start-setup-time = <0x02>;
+ };
+
+ i2c-fastplus-cfg {
+ nvidia,i2c-clk-divisor-fs-mode = <0x16>;
+ nvidia,i2c-sclk-high-period = <0x02>;
+ nvidia,i2c-sclk-low-period = <0x02>;
+ nvidia,i2c-bus-free-time = <0x02>;
+ nvidia,i2c-stop-setup-time = <0x02>;
+ nvidia,i2c-start-hold-time = <0x02>;
+ nvidia,i2c-start-setup-time = <0x02>;
+ };
+
+ i2c-high-cfg {
+ nvidia,i2c-clk-divisor-fs-mode = <0x16>;
+ nvidia,i2c-clk-divisor-hs-mode = <0x02>;
+ nvidia,i2c-sclk-high-period = <0x02>;
+ nvidia,i2c-sclk-low-period = <0x02>;
+ nvidia,i2c-bus-free-time = <0x02>;
+ nvidia,i2c-stop-setup-time = <0x02>;
+ nvidia,i2c-start-hold-time = <0x02>;
+ nvidia,i2c-start-setup-time = <0x02>;
+ nvidia,i2c-hs-stop-setup-time = <0x09>;
+ nvidia,i2c-hs-start-hold-time = <0x09>;
+ nvidia,i2c-hs-start-setup-time = <0x09>;
+ };
+
+ i2c-standard-cfg {
+ nvidia,i2c-clk-divisor-fs-mode = <0x4f>;
+ nvidia,i2c-sclk-high-period = <0x07>;
+ nvidia,i2c-sclk-low-period = <0x08>;
+ nvidia,i2c-bus-free-time = <0x08>;
+ nvidia,i2c-stop-setup-time = <0x08>;
+ nvidia,i2c-start-hold-time = <0x08>;
+ nvidia,i2c-start-setup-time = <0x08>;
+ };
+
+ };
+
+ configi2c3: config-i2c3190000 {
+
+ i2c-common-cfg {
+ nvidia,i2c-hs-sclk-high-period = <0x03>;
+ nvidia,i2c-hs-sclk-low-period = <0x08>;
+ };
+
+ i2c-fast-cfg {
+ nvidia,i2c-clk-divisor-fs-mode = <0x3c>;
+ nvidia,i2c-sclk-high-period = <0x02>;
+ nvidia,i2c-sclk-low-period = <0x02>;
+ nvidia,i2c-bus-free-time = <0x02>;
+ nvidia,i2c-stop-setup-time = <0x02>;
+ nvidia,i2c-start-hold-time = <0x02>;
+ nvidia,i2c-start-setup-time = <0x02>;
+ };
+
+ i2c-fastplus-cfg {
+ nvidia,i2c-clk-divisor-fs-mode = <0x16>;
+ nvidia,i2c-sclk-high-period = <0x02>;
+ nvidia,i2c-sclk-low-period = <0x02>;
+ nvidia,i2c-bus-free-time = <0x02>;
+ nvidia,i2c-stop-setup-time = <0x02>;
+ nvidia,i2c-start-hold-time = <0x02>;
+ nvidia,i2c-start-setup-time = <0x02>;
+ };
+
+ i2c-high-cfg {
+ nvidia,i2c-clk-divisor-fs-mode = <0x16>;
+ nvidia,i2c-clk-divisor-hs-mode = <0x02>;
+ nvidia,i2c-sclk-high-period = <0x02>;
+ nvidia,i2c-sclk-low-period = <0x02>;
+ nvidia,i2c-bus-free-time = <0x02>;
+ nvidia,i2c-stop-setup-time = <0x02>;
+ nvidia,i2c-start-hold-time = <0x02>;
+ nvidia,i2c-start-setup-time = <0x02>;
+ nvidia,i2c-hs-stop-setup-time = <0x09>;
+ nvidia,i2c-hs-start-hold-time = <0x09>;
+ nvidia,i2c-hs-start-setup-time = <0x09>;
+ };
+
+ i2c-standard-cfg {
+ nvidia,i2c-clk-divisor-fs-mode = <0x4f>;
+ nvidia,i2c-sclk-high-period = <0x07>;
+ nvidia,i2c-sclk-low-period = <0x08>;
+ nvidia,i2c-bus-free-time = <0x08>;
+ nvidia,i2c-stop-setup-time = <0x08>;
+ nvidia,i2c-start-hold-time = <0x08>;
+ nvidia,i2c-start-setup-time = <0x08>;
+ };
+
+ };
+
+ configi2c4: config-i2c31b0000 {
+
+ i2c-common-cfg {
+ nvidia,i2c-hs-sclk-high-period = <0x03>;
+ nvidia,i2c-hs-sclk-low-period = <0x08>;
+ };
+
+ i2c-fast-cfg {
+ nvidia,i2c-clk-divisor-fs-mode = <0x3c>;
+ nvidia,i2c-sclk-high-period = <0x02>;
+ nvidia,i2c-sclk-low-period = <0x02>;
+ nvidia,i2c-bus-free-time = <0x02>;
+ nvidia,i2c-stop-setup-time = <0x02>;
+ nvidia,i2c-start-hold-time = <0x02>;
+ nvidia,i2c-start-setup-time = <0x02>;
+ };
+
+ i2c-fastplus-cfg {
+ nvidia,i2c-clk-divisor-fs-mode = <0x16>;
+ nvidia,i2c-sclk-high-period = <0x02>;
+ nvidia,i2c-sclk-low-period = <0x02>;
+ nvidia,i2c-bus-free-time = <0x02>;
+ nvidia,i2c-stop-setup-time = <0x02>;
+ nvidia,i2c-start-hold-time = <0x02>;
+ nvidia,i2c-start-setup-time = <0x02>;
+ };
+
+ i2c-high-cfg {
+ nvidia,i2c-clk-divisor-fs-mode = <0x16>;
+ nvidia,i2c-clk-divisor-hs-mode = <0x02>;
+ nvidia,i2c-sclk-high-period = <0x02>;
+ nvidia,i2c-sclk-low-period = <0x02>;
+ nvidia,i2c-bus-free-time = <0x02>;
+ nvidia,i2c-stop-setup-time = <0x02>;
+ nvidia,i2c-start-hold-time = <0x02>;
+ nvidia,i2c-start-setup-time = <0x02>;
+ nvidia,i2c-hs-stop-setup-time = <0x09>;
+ nvidia,i2c-hs-start-hold-time = <0x09>;
+ nvidia,i2c-hs-start-setup-time = <0x09>;
+ };
+
+ i2c-standard-cfg {
+ nvidia,i2c-clk-divisor-fs-mode = <0x4f>;
+ nvidia,i2c-sclk-high-period = <0x07>;
+ nvidia,i2c-sclk-low-period = <0x08>;
+ nvidia,i2c-bus-free-time = <0x08>;
+ nvidia,i2c-stop-setup-time = <0x08>;
+ nvidia,i2c-start-hold-time = <0x08>;
+ nvidia,i2c-start-setup-time = <0x08>;
+ };
+
+ };
+
+ configi2c5: config-i2c31c0000 {
+
+ i2c-common-cfg {
+ nvidia,i2c-hs-sclk-high-period = <0x03>;
+ nvidia,i2c-hs-sclk-low-period = <0x08>;
+ };
+
+ i2c-fast-cfg {
+ nvidia,i2c-clk-divisor-fs-mode = <0x3c>;
+ nvidia,i2c-sclk-high-period = <0x02>;
+ nvidia,i2c-sclk-low-period = <0x02>;
+ nvidia,i2c-bus-free-time = <0x02>;
+ nvidia,i2c-stop-setup-time = <0x02>;
+ nvidia,i2c-start-hold-time = <0x02>;
+ nvidia,i2c-start-setup-time = <0x02>;
+ };
+
+ i2c-fastplus-cfg {
+ nvidia,i2c-clk-divisor-fs-mode = <0x16>;
+ nvidia,i2c-sclk-high-period = <0x02>;
+ nvidia,i2c-sclk-low-period = <0x02>;
+ nvidia,i2c-bus-free-time = <0x02>;
+ nvidia,i2c-stop-setup-time = <0x02>;
+ nvidia,i2c-start-hold-time = <0x02>;
+ nvidia,i2c-start-setup-time = <0x02>;
+ };
+
+ i2c-high-cfg {
+ nvidia,i2c-clk-divisor-fs-mode = <0x16>;
+ nvidia,i2c-clk-divisor-hs-mode = <0x02>;
+ nvidia,i2c-sclk-high-period = <0x02>;
+ nvidia,i2c-sclk-low-period = <0x02>;
+ nvidia,i2c-bus-free-time = <0x02>;
+ nvidia,i2c-stop-setup-time = <0x02>;
+ nvidia,i2c-start-hold-time = <0x02>;
+ nvidia,i2c-start-setup-time = <0x02>;
+ nvidia,i2c-hs-stop-setup-time = <0x09>;
+ nvidia,i2c-hs-start-hold-time = <0x09>;
+ nvidia,i2c-hs-start-setup-time = <0x09>;
+ };
+
+ i2c-standard-cfg {
+ nvidia,i2c-clk-divisor-fs-mode = <0x4f>;
+ nvidia,i2c-sclk-high-period = <0x07>;
+ nvidia,i2c-sclk-low-period = <0x08>;
+ nvidia,i2c-bus-free-time = <0x08>;
+ nvidia,i2c-stop-setup-time = <0x08>;
+ nvidia,i2c-start-hold-time = <0x08>;
+ nvidia,i2c-start-setup-time = <0x08>;
+ };
+
+ };
+
+ configi2c6: config-i2c31e0000 {
+
+ i2c-common-cfg {
+ nvidia,i2c-hs-sclk-high-period = <0x03>;
+ nvidia,i2c-hs-sclk-low-period = <0x08>;
+ };
+
+ i2c-fast-cfg {
+ nvidia,i2c-clk-divisor-fs-mode = <0x3c>;
+ nvidia,i2c-sclk-high-period = <0x02>;
+ nvidia,i2c-sclk-low-period = <0x02>;
+ nvidia,i2c-bus-free-time = <0x02>;
+ nvidia,i2c-stop-setup-time = <0x02>;
+ nvidia,i2c-start-hold-time = <0x02>;
+ nvidia,i2c-start-setup-time = <0x02>;
+ };
+
+ i2c-fastplus-cfg {
+ nvidia,i2c-clk-divisor-fs-mode = <0x16>;
+ nvidia,i2c-sclk-high-period = <0x02>;
+ nvidia,i2c-sclk-low-period = <0x02>;
+ nvidia,i2c-bus-free-time = <0x02>;
+ nvidia,i2c-stop-setup-time = <0x02>;
+ nvidia,i2c-start-hold-time = <0x02>;
+ nvidia,i2c-start-setup-time = <0x02>;
+ };
+
+ i2c-high-cfg {
+ nvidia,i2c-clk-divisor-fs-mode = <0x16>;
+ nvidia,i2c-clk-divisor-hs-mode = <0x02>;
+ nvidia,i2c-sclk-high-period = <0x02>;
+ nvidia,i2c-sclk-low-period = <0x02>;
+ nvidia,i2c-bus-free-time = <0x02>;
+ nvidia,i2c-stop-setup-time = <0x02>;
+ nvidia,i2c-start-hold-time = <0x02>;
+ nvidia,i2c-start-setup-time = <0x02>;
+ nvidia,i2c-hs-stop-setup-time = <0x09>;
+ nvidia,i2c-hs-start-hold-time = <0x09>;
+ nvidia,i2c-hs-start-setup-time = <0x09>;
+ };
+
+ i2c-standard-cfg {
+ nvidia,i2c-clk-divisor-fs-mode = <0x4f>;
+ nvidia,i2c-sclk-high-period = <0x07>;
+ nvidia,i2c-sclk-low-period = <0x08>;
+ nvidia,i2c-bus-free-time = <0x08>;
+ nvidia,i2c-stop-setup-time = <0x08>;
+ nvidia,i2c-start-hold-time = <0x08>;
+ nvidia,i2c-start-setup-time = <0x08>;
+ };
+
+ };
+
+ configi2c7: config-i2cc240000 {
+
+ i2c-common-cfg {
+ nvidia,i2c-hs-sclk-high-period = <0x03>;
+ nvidia,i2c-hs-sclk-low-period = <0x08>;
+ };
+
+ i2c-fast-cfg {
+ nvidia,i2c-clk-divisor-fs-mode = <0x3c>;
+ nvidia,i2c-sclk-high-period = <0x02>;
+ nvidia,i2c-sclk-low-period = <0x02>;
+ nvidia,i2c-bus-free-time = <0x02>;
+ nvidia,i2c-stop-setup-time = <0x02>;
+ nvidia,i2c-start-hold-time = <0x02>;
+ nvidia,i2c-start-setup-time = <0x02>;
+ };
+
+ i2c-fastplus-cfg {
+ nvidia,i2c-clk-divisor-fs-mode = <0x16>;
+ nvidia,i2c-sclk-high-period = <0x02>;
+ nvidia,i2c-sclk-low-period = <0x02>;
+ nvidia,i2c-bus-free-time = <0x02>;
+ nvidia,i2c-stop-setup-time = <0x02>;
+ nvidia,i2c-start-hold-time = <0x02>;
+ nvidia,i2c-start-setup-time = <0x02>;
+ };
+
+ i2c-high-cfg {
+ nvidia,i2c-clk-divisor-fs-mode = <0x16>;
+ nvidia,i2c-clk-divisor-hs-mode = <0x02>;
+ nvidia,i2c-sclk-high-period = <0x02>;
+ nvidia,i2c-sclk-low-period = <0x02>;
+ nvidia,i2c-bus-free-time = <0x02>;
+ nvidia,i2c-stop-setup-time = <0x02>;
+ nvidia,i2c-start-hold-time = <0x02>;
+ nvidia,i2c-start-setup-time = <0x02>;
+ nvidia,i2c-hs-stop-setup-time = <0x09>;
+ nvidia,i2c-hs-start-hold-time = <0x09>;
+ nvidia,i2c-hs-start-setup-time = <0x09>;
+ };
+
+ i2c-standard-cfg {
+ nvidia,i2c-clk-divisor-fs-mode = <0x4f>;
+ nvidia,i2c-sclk-high-period = <0x07>;
+ nvidia,i2c-sclk-low-period = <0x08>;
+ nvidia,i2c-bus-free-time = <0x08>;
+ nvidia,i2c-stop-setup-time = <0x08>;
+ nvidia,i2c-start-hold-time = <0x08>;
+ nvidia,i2c-start-setup-time = <0x08>;
+ };
+
+ };
+
+ configi2c8: config-i2cc250000 {
+
+ i2c-common-cfg {
+ nvidia,i2c-hs-sclk-high-period = <0x03>;
+ nvidia,i2c-hs-sclk-low-period = <0x08>;
+ };
+
+ i2c-fast-cfg {
+ nvidia,i2c-clk-divisor-fs-mode = <0x3c>;
+ nvidia,i2c-sclk-high-period = <0x02>;
+ nvidia,i2c-sclk-low-period = <0x02>;
+ nvidia,i2c-bus-free-time = <0x02>;
+ nvidia,i2c-stop-setup-time = <0x02>;
+ nvidia,i2c-start-hold-time = <0x02>;
+ nvidia,i2c-start-setup-time = <0x02>;
+ };
+
+ i2c-fastplus-cfg {
+ nvidia,i2c-clk-divisor-fs-mode = <0x16>;
+ nvidia,i2c-sclk-high-period = <0x02>;
+ nvidia,i2c-sclk-low-period = <0x02>;
+ nvidia,i2c-bus-free-time = <0x02>;
+ nvidia,i2c-stop-setup-time = <0x02>;
+ nvidia,i2c-start-hold-time = <0x02>;
+ nvidia,i2c-start-setup-time = <0x02>;
+ };
+
+ i2c-high-cfg {
+ nvidia,i2c-clk-divisor-fs-mode = <0x16>;
+ nvidia,i2c-clk-divisor-hs-mode = <0x02>;
+ nvidia,i2c-sclk-high-period = <0x02>;
+ nvidia,i2c-sclk-low-period = <0x02>;
+ nvidia,i2c-bus-free-time = <0x02>;
+ nvidia,i2c-stop-setup-time = <0x02>;
+ nvidia,i2c-start-hold-time = <0x02>;
+ nvidia,i2c-start-setup-time = <0x02>;
+ nvidia,i2c-hs-stop-setup-time = <0x09>;
+ nvidia,i2c-hs-start-hold-time = <0x09>;
+ nvidia,i2c-hs-start-setup-time = <0x09>;
+ };
+
+ i2c-standard-cfg {
+ nvidia,i2c-clk-divisor-fs-mode = <0x4f>;
+ nvidia,i2c-sclk-high-period = <0x07>;
+ nvidia,i2c-sclk-low-period = <0x08>;
+ nvidia,i2c-bus-free-time = <0x08>;
+ nvidia,i2c-stop-setup-time = <0x08>;
+ nvidia,i2c-start-hold-time = <0x08>;
+ nvidia,i2c-start-setup-time = <0x08>;
+ };
+
+ };
+
+ };
+
+ bus@0 {
+ i2c@3160000 {
+ config-settings = <&configi2c1>;
+ };
+
+ i2c@3180000 {
+ config-settings = <&configi2c2>;
+ };
+
+ i2c@3190000 {
+ config-settings = <&configi2c3>;
+ };
+
+ i2c@31b0000 {
+ config-settings = <&configi2c4>;
+ };
+
+ i2c@31c0000 {
+ config-settings = <&configi2c5>;
+ };
+
+ i2c@31e0000 {
+ config-settings = <&configi2c6>;
+ };
+
+ i2c@c240000 {
+ config-settings = <&configi2c7>;
+ };
+
+ i2c@c250000 {
+ config-settings = <&configi2c8>;
+ };
+
+ };
+};
diff --git a/arch/arm64/boot/dts/nvidia/tegra234-p3701-0000-cfg.dtsi b/arch/arm64/boot/dts/nvidia/tegra234-p3701-0000-cfg.dtsi
new file mode 100644
index 000000000000..72ce8ee5a57f
--- /dev/null
+++ b/arch/arm64/boot/dts/nvidia/tegra234-p3701-0000-cfg.dtsi
@@ -0,0 +1,107 @@
+// SPDX-License-Identifier: GPL-2.0-only
+
+#include "tegra234-cfg.dtsi"
+
+/ {
+ config-i2c3160000 {
+ i2c-fast-cfg {
+ nvidia,i2c-clk-divisor-fs-mode = <0x3c>;
+ nvidia,i2c-sclk-high-period = <0x02>;
+ nvidia,i2c-sclk-low-period = <0x02>;
+ nvidia,i2c-bus-free-time = <0x02>;
+ nvidia,i2c-stop-setup-time = <0x02>;
+ nvidia,i2c-start-hold-time = <0x02>;
+ nvidia,i2c-start-setup-time = <0x02>;
+ };
+ i2c-fastplus-cfg {
+ nvidia,i2c-clk-divisor-fs-mode = <0x16>;
+ nvidia,i2c-sclk-high-period = <0x02>;
+ nvidia,i2c-sclk-low-period = <0x02>;
+ nvidia,i2c-bus-free-time = <0x02>;
+ nvidia,i2c-stop-setup-time = <0x02>;
+ nvidia,i2c-start-hold-time = <0x02>;
+ nvidia,i2c-start-setup-time = <0x02>;
+ };
+ };
+
+ config-i2c3180000 {
+ i2c-fastplus-cfg {
+ nvidia,i2c-clk-divisor-fs-mode = <0x16>;
+ nvidia,i2c-sclk-high-period = <0x02>;
+ nvidia,i2c-sclk-low-period = <0x02>;
+ nvidia,i2c-bus-free-time = <0x02>;
+ nvidia,i2c-stop-setup-time = <0x02>;
+ nvidia,i2c-start-hold-time = <0x02>;
+ nvidia,i2c-start-setup-time = <0x02>;
+ };
+ i2c-standard-cfg {
+ nvidia,i2c-clk-divisor-fs-mode = <0x4f>;
+ nvidia,i2c-sclk-high-period = <0x07>;
+ nvidia,i2c-sclk-low-period = <0x08>;
+ nvidia,i2c-bus-free-time = <0x08>;
+ nvidia,i2c-stop-setup-time = <0x08>;
+ nvidia,i2c-start-hold-time = <0x08>;
+ nvidia,i2c-start-setup-time = <0x08>;
+ };
+ };
+
+ config-i2c3190000 {
+ i2c-fast-cfg {
+ nvidia,i2c-clk-divisor-fs-mode = <0x3c>;
+ nvidia,i2c-sclk-high-period = <0x02>;
+ nvidia,i2c-sclk-low-period = <0x02>;
+ nvidia,i2c-bus-free-time = <0x02>;
+ nvidia,i2c-stop-setup-time = <0x02>;
+ nvidia,i2c-start-hold-time = <0x02>;
+ nvidia,i2c-start-setup-time = <0x02>;
+ };
+ };
+
+ config-i2c31c0000 {
+ i2c-fast-cfg {
+ nvidia,i2c-clk-divisor-fs-mode = <0x3c>;
+ nvidia,i2c-sclk-high-period = <0x02>;
+ nvidia,i2c-sclk-low-period = <0x02>;
+ nvidia,i2c-bus-free-time = <0x02>;
+ nvidia,i2c-stop-setup-time = <0x02>;
+ nvidia,i2c-start-hold-time = <0x02>;
+ nvidia,i2c-start-setup-time = <0x02>;
+ };
+ };
+
+ config-i2c31e0000 {
+ i2c-fast-cfg {
+ nvidia,i2c-clk-divisor-fs-mode = <0x3c>;
+ nvidia,i2c-sclk-high-period = <0x02>;
+ nvidia,i2c-sclk-low-period = <0x02>;
+ nvidia,i2c-bus-free-time = <0x02>;
+ nvidia,i2c-stop-setup-time = <0x02>;
+ nvidia,i2c-start-hold-time = <0x02>;
+ nvidia,i2c-start-setup-time = <0x02>;
+ };
+ };
+
+ config-i2cc240000 {
+ i2c-fastplus-cfg {
+ nvidia,i2c-clk-divisor-fs-mode = <0x16>;
+ nvidia,i2c-sclk-high-period = <0x02>;
+ nvidia,i2c-sclk-low-period = <0x02>;
+ nvidia,i2c-bus-free-time = <0x02>;
+ nvidia,i2c-stop-setup-time = <0x02>;
+ nvidia,i2c-start-hold-time = <0x02>;
+ nvidia,i2c-start-setup-time = <0x02>;
+ };
+ };
+
+ config-i2cc250000 {
+ i2c-fastplus-cfg {
+ nvidia,i2c-clk-divisor-fs-mode = <0x16>;
+ nvidia,i2c-sclk-high-period = <0x02>;
+ nvidia,i2c-sclk-low-period = <0x02>;
+ nvidia,i2c-bus-free-time = <0x02>;
+ nvidia,i2c-stop-setup-time = <0x02>;
+ nvidia,i2c-start-hold-time = <0x02>;
+ nvidia,i2c-start-setup-time = <0x02>;
+ };
+ };
+};
diff --git a/arch/arm64/boot/dts/nvidia/tegra234-p3701-0000.dtsi b/arch/arm64/boot/dts/nvidia/tegra234-p3701-0000.dtsi
index cb792041fc62..71506c51a5ea 100644
--- a/arch/arm64/boot/dts/nvidia/tegra234-p3701-0000.dtsi
+++ b/arch/arm64/boot/dts/nvidia/tegra234-p3701-0000.dtsi
@@ -2,6 +2,7 @@
#include "tegra234.dtsi"
#include "tegra234-p3701.dtsi"
+#include "tegra234-p3701-0000-cfg.dtsi"
/ {
model = "NVIDIA Jetson AGX Orin";
--
2.43.2
^ permalink raw reply related [flat|nested] 20+ messages in thread* [RFC PATCH V2 09/12] dt-bindings: misc: tegra-sdhci: config settings
2024-07-01 15:12 [RFC PATCH V2 00/12] Introduce Tegra register config settings Krishna Yarlagadda
` (7 preceding siblings ...)
2024-07-01 15:12 ` [RFC PATCH V2 08/12] arm64: tegra: I2C " Krishna Yarlagadda
@ 2024-07-01 15:12 ` Krishna Yarlagadda
2024-07-01 15:12 ` [RFC PATCH V2 10/12] dt-bindings: mmc: tegra-sdhci: reference to config Krishna Yarlagadda
` (2 subsequent siblings)
11 siblings, 0 replies; 20+ messages in thread
From: Krishna Yarlagadda @ 2024-07-01 15:12 UTC (permalink / raw)
To: linux-tegra, devicetree, linux-doc, linux-i2c, linux-mmc,
linux-kernel
Cc: thierry.reding, jonathanh, robh, krzk+dt, conor+dt, corbet,
andi.shyti, wsa+renesas, ulf.hansson, adrian.hunter, digetx,
ldewangan, kyarlagadda, mkumard
SDHCI vendor tuning registers are configured using config setting
framework. List available field config for Tegra SDHCI controllers.
Signed-off-by: Krishna Yarlagadda <kyarlagadda@nvidia.com>
---
.../misc/nvidia,tegra-config-settings.yaml | 31 +++++++++++++++++++
1 file changed, 31 insertions(+)
diff --git a/Documentation/devicetree/bindings/misc/nvidia,tegra-config-settings.yaml b/Documentation/devicetree/bindings/misc/nvidia,tegra-config-settings.yaml
index 5f4da633e69b..f4440cb6286d 100644
--- a/Documentation/devicetree/bindings/misc/nvidia,tegra-config-settings.yaml
+++ b/Documentation/devicetree/bindings/misc/nvidia,tegra-config-settings.yaml
@@ -38,6 +38,32 @@ patternProperties:
additionalProperties: false
patternProperties:
+ "^sdhci-[a-z0-9_-]+-cfg$":
+ description: Config settings for SDHCI devices.
+ SDHCI has configuration based on device speed modes.
+ - common is set on all speeds and can be overridden by speed mode.
+ - List of speed modes and their config name
+ "default", /* MMC_TIMING_LEGACY */
+ "sd-mmc-highspeed", /* MMC_TIMING_MMC_HS */
+ "sd-mmc-highspeed", /* MMC_TIMING_SD_HS */
+ "uhs-sdr12", /* MMC_TIMING_UHS_SDR12 */
+ "uhs-sdr25", /* MMC_TIMING_UHS_SDR25 */
+ "uhs-sdr50", /* MMC_TIMING_UHS_SDR50 */
+ "uhs-sdr104", /* MMC_TIMING_UHS_SDR104 */
+ "uhs-ddr52", /* MMC_TIMING_UHS_DDR50 */
+ "uhs-ddr52", /* MMC_TIMING_MMC_DDR52 */
+ "mmc-hs200", /* MMC_TIMING_MMC_HS200 */
+ "mmc-hs400", /* MMC_TIMING_MMC_HS400 */
+ type: object
+ additionalProperties: false
+
+ properties:
+ nvidia,mmc-num-tuning-iter:
+ description: Specify DQS trim value for HS400 timing.
+ $ref: /schemas/types.yaml#/definitions/uint32
+ minimum: 0
+ maximum: 0xffff
+
"^i2c-[a-z0-9_]+-cfg$":
description: Config settings for I2C devices.
type: object
@@ -124,4 +150,9 @@ examples:
nvidia,i2c-sclk-high-period = <0x07>;
};
};
+ configmmc1: config-mmc3400000 {
+ sdhci-mmc-hs200-cfg {
+ nvidia,mmc-num-tuning-iter = <0x02>;
+ };
+ };
};
--
2.43.2
^ permalink raw reply related [flat|nested] 20+ messages in thread* [RFC PATCH V2 10/12] dt-bindings: mmc: tegra-sdhci: reference to config
2024-07-01 15:12 [RFC PATCH V2 00/12] Introduce Tegra register config settings Krishna Yarlagadda
` (8 preceding siblings ...)
2024-07-01 15:12 ` [RFC PATCH V2 09/12] dt-bindings: misc: tegra-sdhci: config settings Krishna Yarlagadda
@ 2024-07-01 15:12 ` Krishna Yarlagadda
2024-07-01 15:12 ` [RFC PATCH V2 11/12] mmc: host: tegra: config settings for timing Krishna Yarlagadda
2024-07-01 15:12 ` [RFC PATCH V2 12/12] arm64: tegra: SDHCI timing settings Krishna Yarlagadda
11 siblings, 0 replies; 20+ messages in thread
From: Krishna Yarlagadda @ 2024-07-01 15:12 UTC (permalink / raw)
To: linux-tegra, devicetree, linux-doc, linux-i2c, linux-mmc,
linux-kernel
Cc: thierry.reding, jonathanh, robh, krzk+dt, conor+dt, corbet,
andi.shyti, wsa+renesas, ulf.hansson, adrian.hunter, digetx,
ldewangan, kyarlagadda, mkumard
SDHCI vendor tuning registers are configured using config setting
framework. Add reference to SDHCI controllers config settings.
Signed-off-by: Krishna Yarlagadda <kyarlagadda@nvidia.com>
---
.../devicetree/bindings/mmc/nvidia,tegra20-sdhci.yaml | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/Documentation/devicetree/bindings/mmc/nvidia,tegra20-sdhci.yaml b/Documentation/devicetree/bindings/mmc/nvidia,tegra20-sdhci.yaml
index 72987f0326a1..39bda6ce1e50 100644
--- a/Documentation/devicetree/bindings/mmc/nvidia,tegra20-sdhci.yaml
+++ b/Documentation/devicetree/bindings/mmc/nvidia,tegra20-sdhci.yaml
@@ -88,6 +88,10 @@ properties:
items:
- description: phandle to the core power domain
+ config-settings:
+ description: phandle to the sdhci configuration settings
+ $ref: /schemas/types.yaml#/definitions/phandle
+
nvidia,default-tap:
description: Specify the default inbound sampling clock trimmer value for
non-tunable modes.
--
2.43.2
^ permalink raw reply related [flat|nested] 20+ messages in thread* [RFC PATCH V2 11/12] mmc: host: tegra: config settings for timing
2024-07-01 15:12 [RFC PATCH V2 00/12] Introduce Tegra register config settings Krishna Yarlagadda
` (9 preceding siblings ...)
2024-07-01 15:12 ` [RFC PATCH V2 10/12] dt-bindings: mmc: tegra-sdhci: reference to config Krishna Yarlagadda
@ 2024-07-01 15:12 ` Krishna Yarlagadda
2024-07-01 15:12 ` [RFC PATCH V2 12/12] arm64: tegra: SDHCI timing settings Krishna Yarlagadda
11 siblings, 0 replies; 20+ messages in thread
From: Krishna Yarlagadda @ 2024-07-01 15:12 UTC (permalink / raw)
To: linux-tegra, devicetree, linux-doc, linux-i2c, linux-mmc,
linux-kernel
Cc: thierry.reding, jonathanh, robh, krzk+dt, conor+dt, corbet,
andi.shyti, wsa+renesas, ulf.hansson, adrian.hunter, digetx,
ldewangan, kyarlagadda, mkumard, Prathamesh Shete
Use config settings framework to initialize Tegra SDHCI
timing registers
Signed-off-by: Krishna Yarlagadda <kyarlagadda@nvidia.com>
Signed-off-by: Prathamesh Shete <pshete@nvidia.com>
---
drivers/mmc/host/sdhci-tegra.c | 84 ++++++++++++++++++++++++++++++++++
1 file changed, 84 insertions(+)
diff --git a/drivers/mmc/host/sdhci-tegra.c b/drivers/mmc/host/sdhci-tegra.c
index 1ad0a6b3a2eb..abd664359ddc 100644
--- a/drivers/mmc/host/sdhci-tegra.c
+++ b/drivers/mmc/host/sdhci-tegra.c
@@ -28,6 +28,7 @@
#include <linux/reset.h>
#include <soc/tegra/common.h>
+#include <soc/tegra/tegra-cfg.h>
#include "sdhci-cqhci.h"
#include "sdhci-pltfm.h"
@@ -64,6 +65,7 @@
#define SDHCI_TEGRA_DLLCAL_STA_ACTIVE BIT(31)
#define SDHCI_VNDR_TUN_CTRL0_0 0x1c0
+#define SDHCI_VNDR_TUN_CTRL0_CMD_CRC_ERR_EN BIT(28)
#define SDHCI_VNDR_TUN_CTRL0_TUN_HW_TAP 0x20000
#define SDHCI_VNDR_TUN_CTRL0_START_TAP_VAL_MASK 0x03fc0000
#define SDHCI_VNDR_TUN_CTRL0_START_TAP_VAL_SHIFT 18
@@ -74,6 +76,7 @@
#define TRIES_128 2
#define TRIES_256 4
#define SDHCI_VNDR_TUN_CTRL0_TUN_WORD_SEL_MASK 0x7
+#define SDHCI_VNDR_TUN_CTRL0_DIV_N_MASK GENMASK(5, 3)
#define SDHCI_TEGRA_VNDR_TUN_CTRL1_0 0x1c4
#define SDHCI_TEGRA_VNDR_TUN_STATUS0 0x1C8
@@ -134,6 +137,20 @@
SDHCI_TRNS_BLK_CNT_EN | \
SDHCI_TRNS_DMA)
+static const char * const cfg_device_states[] = {
+ "sdhci-default-cfg", /* MMC_TIMING_LEGACY */
+ "sdhci-sd-mmc-highspeed-cfg", /* MMC_TIMING_MMC_HS */
+ "sdhci-sd-mmc-highspeed-cfg", /* MMC_TIMING_SD_HS */
+ "sdhci-uhs-sdr12-cfg", /* MMC_TIMING_UHS_SDR12 */
+ "sdhci-uhs-sdr25-cfg", /* MMC_TIMING_UHS_SDR25 */
+ "sdhci-uhs-sdr50-cfg", /* MMC_TIMING_UHS_SDR50 */
+ "sdhci-uhs-sdr104-cfg", /* MMC_TIMING_UHS_SDR104 */
+ "sdhci-uhs-ddr52-cfg", /* MMC_TIMING_UHS_DDR50 */
+ "sdhci-uhs-ddr52-cfg", /* MMC_TIMING_MMC_DDR52 */
+ "sdhci-mmc-hs200-cfg", /* MMC_TIMING_MMC_HS200 */
+ "sdhci-mmc-hs400-cfg", /* MMC_TIMING_MMC_HS400 */
+};
+
struct sdhci_tegra_soc_data {
const struct sdhci_pltfm_data *pdata;
u64 dma_mask;
@@ -158,6 +175,18 @@ struct sdhci_tegra_autocal_offsets {
u32 pull_down_hs400;
};
+static const struct tegra_cfg_field_desc sdhci_cfg_fields[] = {
+ TEGRA_CFG_FIELD("nvidia,num-tuning-iter",
+ SDHCI_VNDR_TUN_CTRL0_0,
+ SDHCI_VNDR_TUN_CTRL0_TUN_ITER_MASK),
+};
+
+static struct tegra_cfg_desc sdhci_cfg_desc = {
+ .num_regs = 0,
+ .num_fields = ARRAY_SIZE(sdhci_cfg_fields),
+ .fields = sdhci_cfg_fields,
+};
+
struct sdhci_tegra {
const struct sdhci_tegra_soc_data *soc_data;
struct gpio_desc *power_gpio;
@@ -183,6 +212,7 @@ struct sdhci_tegra {
unsigned long curr_clk_rate;
u8 tuned_tap_delay;
u32 stream_id;
+ struct tegra_cfg_list *list;
};
static u16 tegra_sdhci_readw(struct sdhci_host *host, int reg)
@@ -362,6 +392,30 @@ static void tegra_sdhci_set_tap(struct sdhci_host *host, unsigned int tap)
}
}
+static void tegra_sdhci_write_cfg_settings(struct sdhci_host *host,
+ const char *name)
+{
+ struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
+ struct sdhci_tegra *tegra_host = sdhci_pltfm_priv(pltfm_host);
+ struct tegra_cfg_reg *regs;
+ struct tegra_cfg *cfg;
+ unsigned int i;
+ u32 val;
+
+ cfg = tegra_cfg_get_by_name(mmc_dev(host->mmc),
+ tegra_host->list, name);
+ if (!cfg)
+ return;
+
+ regs = cfg->regs;
+ for (i = 0; i < cfg->num_regs; ++i) {
+ val = sdhci_readl(host, regs[i].offset);
+ val &= ~regs[i].mask;
+ val |= regs[i].value;
+ sdhci_writel(host, val, regs[i].offset);
+ }
+}
+
static void tegra_sdhci_reset(struct sdhci_host *host, u8 mask)
{
struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
@@ -374,6 +428,8 @@ static void tegra_sdhci_reset(struct sdhci_host *host, u8 mask)
if (!(mask & SDHCI_RESET_ALL))
return;
+ tegra_sdhci_write_cfg_settings(host, "shdci-common-cfg");
+
tegra_sdhci_set_tap(host, tegra_host->default_tap);
misc_ctrl = sdhci_readl(host, SDHCI_TEGRA_VENDOR_MISC_CTRL);
@@ -1011,6 +1067,7 @@ static void tegra_sdhci_set_uhs_signaling(struct sdhci_host *host,
bool set_default_tap = false;
bool set_dqs_trim = false;
bool do_hs400_dll_cal = false;
+ bool set_config = false;
u8 iter = TRIES_256;
u32 val;
@@ -1027,6 +1084,7 @@ static void tegra_sdhci_set_uhs_signaling(struct sdhci_host *host,
set_dqs_trim = true;
do_hs400_dll_cal = true;
iter = TRIES_128;
+ set_config = true;
break;
case MMC_TIMING_MMC_DDR52:
case MMC_TIMING_UHS_DDR50:
@@ -1059,6 +1117,9 @@ static void tegra_sdhci_set_uhs_signaling(struct sdhci_host *host,
else
tegra_sdhci_set_tap(host, tegra_host->default_tap);
+ if (set_config)
+ tegra_sdhci_write_cfg_settings(host,
+ cfg_device_states[timing]);
if (set_dqs_trim)
tegra_sdhci_set_dqs_trim(host, tegra_host->dqs_trim);
@@ -1129,6 +1190,29 @@ static int sdhci_tegra_start_signal_voltage_switch(struct mmc_host *mmc,
static int tegra_sdhci_init_pinctrl_info(struct device *dev,
struct sdhci_tegra *tegra_host)
{
+ unsigned int i, j, count;
+ const struct tegra_cfg_field_desc *fields;
+
+ count = 0;
+ fields = sdhci_cfg_fields;
+
+ for (i = 0; i < sdhci_cfg_desc.num_fields; i++) {
+ for (j = 0; j < i; j++)
+ if (fields[i].offset == fields[j].offset)
+ break;
+
+ if (i == j)
+ count++;
+ }
+
+ sdhci_cfg_desc.num_regs = count;
+ tegra_host->list = tegra_cfg_get(dev, NULL, &sdhci_cfg_desc);
+ if (IS_ERR(tegra_host->list)) {
+ dev_dbg(dev, "Config setting not available, err: %ld\n",
+ PTR_ERR(tegra_host->list));
+ tegra_host->list = NULL;
+ }
+
tegra_host->pinctrl_sdmmc = devm_pinctrl_get(dev);
if (IS_ERR(tegra_host->pinctrl_sdmmc)) {
dev_dbg(dev, "No pinctrl info, err: %ld\n",
--
2.43.2
^ permalink raw reply related [flat|nested] 20+ messages in thread* [RFC PATCH V2 12/12] arm64: tegra: SDHCI timing settings
2024-07-01 15:12 [RFC PATCH V2 00/12] Introduce Tegra register config settings Krishna Yarlagadda
` (10 preceding siblings ...)
2024-07-01 15:12 ` [RFC PATCH V2 11/12] mmc: host: tegra: config settings for timing Krishna Yarlagadda
@ 2024-07-01 15:12 ` Krishna Yarlagadda
11 siblings, 0 replies; 20+ messages in thread
From: Krishna Yarlagadda @ 2024-07-01 15:12 UTC (permalink / raw)
To: linux-tegra, devicetree, linux-doc, linux-i2c, linux-mmc,
linux-kernel
Cc: thierry.reding, jonathanh, robh, krzk+dt, conor+dt, corbet,
andi.shyti, wsa+renesas, ulf.hansson, adrian.hunter, digetx,
ldewangan, kyarlagadda, mkumard
Set SDHCI timing registers through config settings for
Tegra234 chip and P3701 board.
Signed-off-by: Krishna Yarlagadda <kyarlagadda@nvidia.com>
---
arch/arm64/boot/dts/nvidia/tegra234-cfg.dtsi | 36 ++++++++++++++++++++
1 file changed, 36 insertions(+)
diff --git a/arch/arm64/boot/dts/nvidia/tegra234-cfg.dtsi b/arch/arm64/boot/dts/nvidia/tegra234-cfg.dtsi
index 7e5b9c10c617..30c125636123 100644
--- a/arch/arm64/boot/dts/nvidia/tegra234-cfg.dtsi
+++ b/arch/arm64/boot/dts/nvidia/tegra234-cfg.dtsi
@@ -426,6 +426,34 @@ i2c-standard-cfg {
};
+ configmmc1: config-mmc3400000 {
+
+ sdhci-mmc-hs200-cfg {
+ nvidia,num-tuning-iter = <0x2>;
+ };
+
+ sdhci-uhs-sdr104-cfg {
+ nvidia,num-tuning-iter = <0x2>;
+ };
+
+ sdhci-uhs-sdr50-cfg {
+ nvidia,num-tuning-iter = <0x4>;
+ };
+
+ };
+
+ configmmc2: config-mmc3460000 {
+
+ sdhci-mmc-hs200-cfg {
+ nvidia,num-tuning-iter = <0x2>;
+ };
+
+ sdhci-mmc-hs400-cfg {
+ nvidia,num-tuning-iter = <0x2>;
+ };
+
+ };
+
};
bus@0 {
@@ -461,5 +489,13 @@ i2c@c250000 {
config-settings = <&configi2c8>;
};
+ mmc@3400000 {
+ config-settings = <&configmmc1>;
+ };
+
+ mmc@3460000 {
+ config-settings = <&configmmc2>;
+ };
+
};
};
--
2.43.2
^ permalink raw reply related [flat|nested] 20+ messages in thread