* [PATCH 02/14] arm64: dts: msm8992: Place clock nodes in clocks{}
From: Konrad Dybcio @ 2020-05-31 17:27 UTC (permalink / raw)
Cc: Konrad Dybcio, Andy Gross, Bjorn Andersson, Rob Herring,
linux-arm-msm, devicetree, linux-kernel
In-Reply-To: <20200531172804.256335-1-konradybcio@gmail.com>
This commits brings no changes
functionality-wise, but aligns the DTS
with the style used in newer ones.
Signed-off-by: Konrad Dybcio <konradybcio@gmail.com>
---
arch/arm64/boot/dts/qcom/msm8992.dtsi | 20 +++++++++++---------
1 file changed, 11 insertions(+), 9 deletions(-)
diff --git a/arch/arm64/boot/dts/qcom/msm8992.dtsi b/arch/arm64/boot/dts/qcom/msm8992.dtsi
index 900c9445e0ba..e255b577af37 100644
--- a/arch/arm64/boot/dts/qcom/msm8992.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8992.dtsi
@@ -116,16 +116,18 @@ timer {
<GIC_PPI 1 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>;
};
- xo_board: xo_board {
- compatible = "fixed-clock";
- #clock-cells = <0>;
- clock-frequency = <19200000>;
- };
+ clocks {
+ xo_board: xo_board {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <19200000>;
+ };
- sleep_clk: sleep_clk {
- compatible = "fixed-clock";
- #clock-cells = <0>;
- clock-frequency = <32768>;
+ sleep_clk: sleep_clk {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <32768>;
+ };
};
vreg_vph_pwr: vreg-vph-pwr {
--
2.26.2
^ permalink raw reply related
* [PATCH 03/14] arm64: dts: msm8992: Add a SCM node
From: Konrad Dybcio @ 2020-05-31 17:27 UTC (permalink / raw)
Cc: Konrad Dybcio, Andy Gross, Bjorn Andersson, Rob Herring,
linux-arm-msm, devicetree, linux-kernel
In-Reply-To: <20200531172804.256335-1-konradybcio@gmail.com>
Signed-off-by: Konrad Dybcio <konradybcio@gmail.com>
---
arch/arm64/boot/dts/qcom/msm8992.dtsi | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/arch/arm64/boot/dts/qcom/msm8992.dtsi b/arch/arm64/boot/dts/qcom/msm8992.dtsi
index e255b577af37..535be60521d8 100644
--- a/arch/arm64/boot/dts/qcom/msm8992.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8992.dtsi
@@ -154,6 +154,12 @@ smem {
hwlocks = <&sfpb_mutex 3>;
};
+ firmware {
+ scm {
+ compatible = "qcom,scm-msm8992";
+ };
+ };
+
soc {
#address-cells = <1>;
#size-cells = <1>;
--
2.26.2
^ permalink raw reply related
* [PATCH 0/4] Add msm8992 GCC driver
From: Konrad Dybcio @ 2020-05-31 17:46 UTC (permalink / raw)
Cc: Konrad Dybcio, Andy Gross, Bjorn Andersson, Michael Turquette,
Stephen Boyd, Rob Herring, Philipp Zabel, linux-arm-msm,
linux-clk, devicetree, linux-kernel
This SoC is very similar to msm8994, but features
less clocks (as in no UFS or PCIE1-related ones,
for example). This implementation also adds support
for GDSCs and resets, which are lacking in the current
8994 driver and I can't test them over there, as I don't
have a device featuring that SoC. Qualcomm also
separates 8992 and 8994 drivers on downstream kernels,
so I find this appropriate.
Konrad Dybcio (4):
drivers: clk: qcom: Add msm8992 GCC driver
Add compatible strings and the include files for the msm8992 GCC.
arm64: dts: Adjust msm8992 DTS to use the correct GCC driver
driver: clk: Add msm8992 GCC Kconfig and Makefile entries
.../devicetree/bindings/clock/qcom,gcc.yaml | 2 +
arch/arm64/boot/dts/qcom/msm8992.dtsi | 15 +-
drivers/clk/qcom/Kconfig | 8 +
drivers/clk/qcom/Makefile | 1 +
drivers/clk/qcom/gcc-msm8992.c | 2429 +++++++++++++++++
include/dt-bindings/clock/qcom,gcc-msm8992.h | 144 +
include/dt-bindings/reset/qcom,gcc-msm8992.h | 8 +
7 files changed, 2600 insertions(+), 7 deletions(-)
create mode 100644 drivers/clk/qcom/gcc-msm8992.c
create mode 100644 include/dt-bindings/clock/qcom,gcc-msm8992.h
create mode 100644 include/dt-bindings/reset/qcom,gcc-msm8992.h
--
2.26.2
^ permalink raw reply
* [PATCH 1/4] drivers: clk: qcom: Add msm8992 GCC driver
From: Konrad Dybcio @ 2020-05-31 17:46 UTC (permalink / raw)
Cc: Konrad Dybcio, Andy Gross, Bjorn Andersson, Michael Turquette,
Stephen Boyd, Rob Herring, Philipp Zabel, linux-arm-msm,
linux-clk, devicetree, linux-kernel
In-Reply-To: <20200531174612.260113-1-konradybcio@gmail.com>
This commit adds support for the msm8992 Global
Clock Controller with GDSC and resets support.
It is in fact very similar to msm8994, but features
less clocks (no PCIE1 or UFS) and adds support for the
missing ones (such as USB-related clocks).
Signed-off-by: Konrad Dybcio <konradybcio@gmail.com>
---
drivers/clk/qcom/gcc-msm8992.c | 2429 ++++++++++++++++++++++++++++++++
1 file changed, 2429 insertions(+)
create mode 100644 drivers/clk/qcom/gcc-msm8992.c
diff --git a/drivers/clk/qcom/gcc-msm8992.c b/drivers/clk/qcom/gcc-msm8992.c
new file mode 100644
index 000000000000..3e8c0243be78
--- /dev/null
+++ b/drivers/clk/qcom/gcc-msm8992.c
@@ -0,0 +1,2429 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/* Copyright (c) 2013-2016, The Linux Foundation. All rights reserved.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/err.h>
+#include <linux/ctype.h>
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/module.h>
+#include <linux/regmap.h>
+
+#include <dt-bindings/clock/qcom,gcc-msm8992.h>
+#include <dt-bindings/reset/qcom,gcc-msm8992.h>
+
+#include "common.h"
+#include "clk-regmap.h"
+#include "clk-alpha-pll.h"
+#include "clk-rcg.h"
+#include "clk-branch.h"
+#include "reset.h"
+#include "gdsc.h"
+
+enum {
+ P_XO,
+ P_GPLL0,
+ P_GPLL4,
+};
+
+static const struct parent_map gcc_xo_gpll0_map[] = {
+ { P_XO, 0 },
+ { P_GPLL0, 1 },
+};
+
+static const char * const gcc_xo_gpll0[] = {
+ "xo",
+ "gpll0",
+};
+
+static const struct parent_map gcc_xo_gpll0_gpll4_map[] = {
+ { P_XO, 0 },
+ { P_GPLL0, 1 },
+ { P_GPLL4, 5 },
+};
+
+static const char * const gcc_xo_gpll0_gpll4[] = {
+ "xo",
+ "gpll0",
+ "gpll4",
+};
+
+static struct clk_fixed_factor xo = {
+ .mult = 1,
+ .div = 1,
+ .hw.init = &(struct clk_init_data)
+ {
+ .name = "xo",
+ .parent_names = (const char *[]) { "xo_board" },
+ .num_parents = 1,
+ .ops = &clk_fixed_factor_ops,
+ },
+};
+
+static struct clk_alpha_pll gpll0_early = {
+ .offset = 0x00000,
+ .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
+ .clkr = {
+ .enable_reg = 0x1480,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data)
+ {
+ .name = "gpll0_early",
+ .parent_names = (const char *[]) { "xo" },
+ .num_parents = 1,
+ .ops = &clk_alpha_pll_ops,
+ },
+ },
+};
+
+static struct clk_alpha_pll_postdiv gpll0 = {
+ .offset = 0x00000,
+ .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
+ .clkr.hw.init = &(struct clk_init_data)
+ {
+ .name = "gpll0",
+ .parent_names = (const char *[]) { "gpll0_early" },
+ .num_parents = 1,
+ .ops = &clk_alpha_pll_postdiv_ops,
+ },
+};
+
+static struct clk_alpha_pll gpll4_early = {
+ .offset = 0x1dc0,
+ .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
+ .clkr = {
+ .enable_reg = 0x1480,
+ .enable_mask = BIT(4),
+ .hw.init = &(struct clk_init_data)
+ {
+ .name = "gpll4_early",
+ .parent_names = (const char *[]) { "xo" },
+ .num_parents = 1,
+ .ops = &clk_alpha_pll_ops,
+ },
+ },
+};
+
+static struct clk_alpha_pll_postdiv gpll4 = {
+ .offset = 0x1dc0,
+ .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
+ .clkr.hw.init = &(struct clk_init_data)
+ {
+ .name = "gpll4",
+ .parent_names = (const char *[]) { "gpll4_early" },
+ .num_parents = 1,
+ .ops = &clk_alpha_pll_postdiv_ops,
+ },
+};
+
+static struct freq_tbl ftbl_usb30_master_clk_src[] = {
+ F(19200000, P_XO, 1, 0, 0),
+ F(125000000, P_GPLL0, 1, 5, 24),
+ { }
+};
+
+static struct clk_rcg2 usb30_master_clk_src = {
+ .cmd_rcgr = 0x03d4,
+ .mnd_width = 8,
+ .hid_width = 5,
+ .parent_map = gcc_xo_gpll0_map,
+ .freq_tbl = ftbl_usb30_master_clk_src,
+ .clkr.hw.init = &(struct clk_init_data)
+ {
+ .name = "usb30_master_clk_src",
+ .parent_names = gcc_xo_gpll0,
+ .num_parents = 2,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static struct freq_tbl ftbl_blsp_i2c_apps_clk_src[] = {
+ F(19200000, P_XO, 1, 0, 0),
+ F(50000000, P_GPLL0, 12, 0, 0),
+ { }
+};
+
+static struct clk_rcg2 blsp1_qup1_i2c_apps_clk_src = {
+ .cmd_rcgr = 0x0660,
+ .hid_width = 5,
+ .parent_map = gcc_xo_gpll0_map,
+ .freq_tbl = ftbl_blsp_i2c_apps_clk_src,
+ .clkr.hw.init = &(struct clk_init_data)
+ {
+ .name = "blsp1_qup1_i2c_apps_clk_src",
+ .parent_names = gcc_xo_gpll0,
+ .num_parents = 2,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static struct freq_tbl ftbl_blspqup_spi_apps_clk_src[] = {
+ F(960000, P_XO, 10, 1, 2),
+ F(4800000, P_XO, 4, 0, 0),
+ F(9600000, P_XO, 2, 0, 0),
+ F(15000000, P_GPLL0, 10, 1, 4),
+ F(19200000, P_XO, 1, 0, 0),
+ F(25000000, P_GPLL0, 12, 1, 2),
+ F(50000000, P_GPLL0, 12, 0, 0),
+ { }
+};
+
+static struct clk_rcg2 blsp1_qup1_spi_apps_clk_src = {
+ .cmd_rcgr = 0x064c,
+ .mnd_width = 8,
+ .hid_width = 5,
+ .parent_map = gcc_xo_gpll0_map,
+ .freq_tbl = ftbl_blspqup_spi_apps_clk_src,
+ .clkr.hw.init = &(struct clk_init_data)
+ {
+ .name = "blsp1_qup1_spi_apps_clk_src",
+ .parent_names = gcc_xo_gpll0,
+ .num_parents = 2,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static struct clk_rcg2 blsp1_qup2_i2c_apps_clk_src = {
+ .cmd_rcgr = 0x06e0,
+ .hid_width = 5,
+ .parent_map = gcc_xo_gpll0_map,
+ .freq_tbl = ftbl_blsp_i2c_apps_clk_src,
+ .clkr.hw.init = &(struct clk_init_data)
+ {
+ .name = "blsp1_qup2_i2c_apps_clk_src",
+ .parent_names = gcc_xo_gpll0,
+ .num_parents = 2,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static struct clk_rcg2 blsp1_qup2_spi_apps_clk_src = {
+ .cmd_rcgr = 0x06cc,
+ .mnd_width = 8,
+ .hid_width = 5,
+ .parent_map = gcc_xo_gpll0_map,
+ .freq_tbl = ftbl_blspqup_spi_apps_clk_src,
+ .clkr.hw.init = &(struct clk_init_data)
+ {
+ .name = "blsp1_qup2_spi_apps_clk_src",
+ .parent_names = gcc_xo_gpll0,
+ .num_parents = 2,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static struct clk_rcg2 blsp1_qup3_i2c_apps_clk_src = {
+ .cmd_rcgr = 0x0760,
+ .hid_width = 5,
+ .parent_map = gcc_xo_gpll0_map,
+ .freq_tbl = ftbl_blsp_i2c_apps_clk_src,
+ .clkr.hw.init = &(struct clk_init_data)
+ {
+ .name = "blsp1_qup3_i2c_apps_clk_src",
+ .parent_names = gcc_xo_gpll0,
+ .num_parents = 2,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static struct clk_rcg2 blsp1_qup3_spi_apps_clk_src = {
+ .cmd_rcgr = 0x074c,
+ .mnd_width = 8,
+ .hid_width = 5,
+ .parent_map = gcc_xo_gpll0_map,
+ .freq_tbl = ftbl_blspqup_spi_apps_clk_src,
+ .clkr.hw.init = &(struct clk_init_data)
+ {
+ .name = "blsp1_qup3_spi_apps_clk_src",
+ .parent_names = gcc_xo_gpll0,
+ .num_parents = 2,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static struct clk_rcg2 blsp1_qup4_i2c_apps_clk_src = {
+ .cmd_rcgr = 0x07e0,
+ .hid_width = 5,
+ .parent_map = gcc_xo_gpll0_map,
+ .freq_tbl = ftbl_blsp_i2c_apps_clk_src,
+ .clkr.hw.init = &(struct clk_init_data)
+ {
+ .name = "blsp1_qup4_i2c_apps_clk_src",
+ .parent_names = gcc_xo_gpll0,
+ .num_parents = 2,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static struct clk_rcg2 blsp1_qup4_spi_apps_clk_src = {
+ .cmd_rcgr = 0x07cc,
+ .mnd_width = 8,
+ .hid_width = 5,
+ .parent_map = gcc_xo_gpll0_map,
+ .freq_tbl = ftbl_blspqup_spi_apps_clk_src,
+ .clkr.hw.init = &(struct clk_init_data)
+ {
+ .name = "blsp1_qup4_spi_apps_clk_src",
+ .parent_names = gcc_xo_gpll0,
+ .num_parents = 2,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static struct clk_rcg2 blsp1_qup5_i2c_apps_clk_src = {
+ .cmd_rcgr = 0x0860,
+ .hid_width = 5,
+ .parent_map = gcc_xo_gpll0_map,
+ .freq_tbl = ftbl_blsp_i2c_apps_clk_src,
+ .clkr.hw.init = &(struct clk_init_data)
+ {
+ .name = "blsp1_qup5_i2c_apps_clk_src",
+ .parent_names = gcc_xo_gpll0,
+ .num_parents = 2,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static struct clk_rcg2 blsp1_qup5_spi_apps_clk_src = {
+ .cmd_rcgr = 0x084c,
+ .mnd_width = 8,
+ .hid_width = 5,
+ .parent_map = gcc_xo_gpll0_map,
+ .freq_tbl = ftbl_blspqup_spi_apps_clk_src,
+ .clkr.hw.init = &(struct clk_init_data)
+ {
+ .name = "blsp1_qup5_spi_apps_clk_src",
+ .parent_names = gcc_xo_gpll0,
+ .num_parents = 2,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static struct clk_rcg2 blsp1_qup6_i2c_apps_clk_src = {
+ .cmd_rcgr = 0x08e0,
+ .hid_width = 5,
+ .parent_map = gcc_xo_gpll0_map,
+ .freq_tbl = ftbl_blsp_i2c_apps_clk_src,
+ .clkr.hw.init = &(struct clk_init_data)
+ {
+ .name = "blsp1_qup6_i2c_apps_clk_src",
+ .parent_names = gcc_xo_gpll0,
+ .num_parents = 2,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static struct clk_rcg2 blsp1_qup6_spi_apps_clk_src = {
+ .cmd_rcgr = 0x08cc,
+ .mnd_width = 8,
+ .hid_width = 5,
+ .parent_map = gcc_xo_gpll0_map,
+ .freq_tbl = ftbl_blspqup_spi_apps_clk_src,
+ .clkr.hw.init = &(struct clk_init_data)
+ {
+ .name = "blsp1_qup6_spi_apps_clk_src",
+ .parent_names = gcc_xo_gpll0,
+ .num_parents = 2,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static struct freq_tbl ftbl_blsp_uart_apps_clk_src[] = {
+ F(3686400, P_GPLL0, 1, 96, 15625),
+ F(7372800, P_GPLL0, 1, 192, 15625),
+ F(14745600, P_GPLL0, 1, 384, 15625),
+ F(16000000, P_GPLL0, 5, 2, 15),
+ F(19200000, P_XO, 1, 0, 0),
+ F(24000000, P_GPLL0, 5, 1, 5),
+ F(32000000, P_GPLL0, 1, 4, 75),
+ F(40000000, P_GPLL0, 15, 0, 0),
+ F(46400000, P_GPLL0, 1, 29, 375),
+ F(48000000, P_GPLL0, 12.5, 0, 0),
+ F(51200000, P_GPLL0, 1, 32, 375),
+ F(56000000, P_GPLL0, 1, 7, 75),
+ F(58982400, P_GPLL0, 1, 1536, 15625),
+ F(60000000, P_GPLL0, 10, 0, 0),
+ F(63160000, P_GPLL0, 9.5, 0, 0),
+ { }
+};
+
+static struct clk_rcg2 blsp1_uart1_apps_clk_src = {
+ .cmd_rcgr = 0x068c,
+ .mnd_width = 16,
+ .hid_width = 5,
+ .parent_map = gcc_xo_gpll0_map,
+ .freq_tbl = ftbl_blsp_uart_apps_clk_src,
+ .clkr.hw.init = &(struct clk_init_data)
+ {
+ .name = "blsp1_uart1_apps_clk_src",
+ .parent_names = gcc_xo_gpll0,
+ .num_parents = 2,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static struct clk_rcg2 blsp1_uart2_apps_clk_src = {
+ .cmd_rcgr = 0x070c,
+ .mnd_width = 16,
+ .hid_width = 5,
+ .parent_map = gcc_xo_gpll0_map,
+ .freq_tbl = ftbl_blsp_uart_apps_clk_src,
+ .clkr.hw.init = &(struct clk_init_data)
+ {
+ .name = "blsp1_uart2_apps_clk_src",
+ .parent_names = gcc_xo_gpll0,
+ .num_parents = 2,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static struct clk_rcg2 blsp1_uart3_apps_clk_src = {
+ .cmd_rcgr = 0x078c,
+ .mnd_width = 16,
+ .hid_width = 5,
+ .parent_map = gcc_xo_gpll0_map,
+ .freq_tbl = ftbl_blsp_uart_apps_clk_src,
+ .clkr.hw.init = &(struct clk_init_data)
+ {
+ .name = "blsp1_uart3_apps_clk_src",
+ .parent_names = gcc_xo_gpll0,
+ .num_parents = 2,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static struct clk_rcg2 blsp1_uart4_apps_clk_src = {
+ .cmd_rcgr = 0x080c,
+ .mnd_width = 16,
+ .hid_width = 5,
+ .parent_map = gcc_xo_gpll0_map,
+ .freq_tbl = ftbl_blsp_uart_apps_clk_src,
+ .clkr.hw.init = &(struct clk_init_data)
+ {
+ .name = "blsp1_uart4_apps_clk_src",
+ .parent_names = gcc_xo_gpll0,
+ .num_parents = 2,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static struct clk_rcg2 blsp1_uart5_apps_clk_src = {
+ .cmd_rcgr = 0x088c,
+ .mnd_width = 16,
+ .hid_width = 5,
+ .parent_map = gcc_xo_gpll0_map,
+ .freq_tbl = ftbl_blsp_uart_apps_clk_src,
+ .clkr.hw.init = &(struct clk_init_data)
+ {
+ .name = "blsp1_uart5_apps_clk_src",
+ .parent_names = gcc_xo_gpll0,
+ .num_parents = 2,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static struct clk_rcg2 blsp1_uart6_apps_clk_src = {
+ .cmd_rcgr = 0x090c,
+ .mnd_width = 16,
+ .hid_width = 5,
+ .parent_map = gcc_xo_gpll0_map,
+ .freq_tbl = ftbl_blsp_uart_apps_clk_src,
+ .clkr.hw.init = &(struct clk_init_data)
+ {
+ .name = "blsp1_uart6_apps_clk_src",
+ .parent_names = gcc_xo_gpll0,
+ .num_parents = 2,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static struct clk_rcg2 blsp2_qup1_i2c_apps_clk_src = {
+ .cmd_rcgr = 0x09a0,
+ .hid_width = 5,
+ .parent_map = gcc_xo_gpll0_map,
+ .freq_tbl = ftbl_blsp_i2c_apps_clk_src,
+ .clkr.hw.init = &(struct clk_init_data)
+ {
+ .name = "blsp2_qup1_i2c_apps_clk_src",
+ .parent_names = gcc_xo_gpll0,
+ .num_parents = 2,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static struct clk_rcg2 blsp2_qup1_spi_apps_clk_src = {
+ .cmd_rcgr = 0x098c,
+ .mnd_width = 8,
+ .hid_width = 5,
+ .parent_map = gcc_xo_gpll0_map,
+ .freq_tbl = ftbl_blspqup_spi_apps_clk_src,
+ .clkr.hw.init = &(struct clk_init_data)
+ {
+ .name = "blsp2_qup1_spi_apps_clk_src",
+ .parent_names = gcc_xo_gpll0,
+ .num_parents = 2,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static struct clk_rcg2 blsp2_qup2_i2c_apps_clk_src = {
+ .cmd_rcgr = 0x0a20,
+ .hid_width = 5,
+ .parent_map = gcc_xo_gpll0_map,
+ .freq_tbl = ftbl_blsp_i2c_apps_clk_src,
+ .clkr.hw.init = &(struct clk_init_data)
+ {
+ .name = "blsp2_qup2_i2c_apps_clk_src",
+ .parent_names = gcc_xo_gpll0,
+ .num_parents = 2,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static struct clk_rcg2 blsp2_qup2_spi_apps_clk_src = {
+ .cmd_rcgr = 0x0a0c,
+ .mnd_width = 8,
+ .hid_width = 5,
+ .parent_map = gcc_xo_gpll0_map,
+ .freq_tbl = ftbl_blspqup_spi_apps_clk_src,
+ .clkr.hw.init = &(struct clk_init_data)
+ {
+ .name = "blsp2_qup2_spi_apps_clk_src",
+ .parent_names = gcc_xo_gpll0,
+ .num_parents = 2,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static struct clk_rcg2 blsp2_qup3_i2c_apps_clk_src = {
+ .cmd_rcgr = 0x0aa0,
+ .hid_width = 5,
+ .parent_map = gcc_xo_gpll0_map,
+ .freq_tbl = ftbl_blsp_i2c_apps_clk_src,
+ .clkr.hw.init = &(struct clk_init_data)
+ {
+ .name = "blsp2_qup3_i2c_apps_clk_src",
+ .parent_names = gcc_xo_gpll0,
+ .num_parents = 2,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static struct clk_rcg2 blsp2_qup3_spi_apps_clk_src = {
+ .cmd_rcgr = 0x0a8c,
+ .mnd_width = 8,
+ .hid_width = 5,
+ .parent_map = gcc_xo_gpll0_map,
+ .freq_tbl = ftbl_blspqup_spi_apps_clk_src,
+ .clkr.hw.init = &(struct clk_init_data)
+ {
+ .name = "blsp2_qup3_spi_apps_clk_src",
+ .parent_names = gcc_xo_gpll0,
+ .num_parents = 2,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static struct clk_rcg2 blsp2_qup4_i2c_apps_clk_src = {
+ .cmd_rcgr = 0x0b20,
+ .hid_width = 5,
+ .parent_map = gcc_xo_gpll0_map,
+ .freq_tbl = ftbl_blsp_i2c_apps_clk_src,
+ .clkr.hw.init = &(struct clk_init_data)
+ {
+ .name = "blsp2_qup4_i2c_apps_clk_src",
+ .parent_names = gcc_xo_gpll0,
+ .num_parents = 2,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static struct clk_rcg2 blsp2_qup4_spi_apps_clk_src = {
+ .cmd_rcgr = 0x0b0c,
+ .mnd_width = 8,
+ .hid_width = 5,
+ .parent_map = gcc_xo_gpll0_map,
+ .freq_tbl = ftbl_blspqup_spi_apps_clk_src,
+ .clkr.hw.init = &(struct clk_init_data)
+ {
+ .name = "blsp2_qup4_spi_apps_clk_src",
+ .parent_names = gcc_xo_gpll0,
+ .num_parents = 2,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static struct clk_rcg2 blsp2_qup5_i2c_apps_clk_src = {
+ .cmd_rcgr = 0x0ba0,
+ .hid_width = 5,
+ .parent_map = gcc_xo_gpll0_map,
+ .freq_tbl = ftbl_blsp_i2c_apps_clk_src,
+ .clkr.hw.init = &(struct clk_init_data)
+ {
+ .name = "blsp2_qup5_i2c_apps_clk_src",
+ .parent_names = gcc_xo_gpll0,
+ .num_parents = 2,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static struct clk_rcg2 blsp2_qup5_spi_apps_clk_src = {
+ .cmd_rcgr = 0x0b8c,
+ .mnd_width = 8,
+ .hid_width = 5,
+ .parent_map = gcc_xo_gpll0_map,
+ .freq_tbl = ftbl_blspqup_spi_apps_clk_src,
+ .clkr.hw.init = &(struct clk_init_data)
+ {
+ .name = "blsp2_qup5_spi_apps_clk_src",
+ .parent_names = gcc_xo_gpll0,
+ .num_parents = 2,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static struct clk_rcg2 blsp2_qup6_i2c_apps_clk_src = {
+ .cmd_rcgr = 0x0c20,
+ .hid_width = 5,
+ .parent_map = gcc_xo_gpll0_map,
+ .freq_tbl = ftbl_blsp_i2c_apps_clk_src,
+ .clkr.hw.init = &(struct clk_init_data)
+ {
+ .name = "blsp2_qup6_i2c_apps_clk_src",
+ .parent_names = gcc_xo_gpll0,
+ .num_parents = 2,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static struct clk_rcg2 blsp2_qup6_spi_apps_clk_src = {
+ .cmd_rcgr = 0x0c0c,
+ .mnd_width = 8,
+ .hid_width = 5,
+ .parent_map = gcc_xo_gpll0_map,
+ .freq_tbl = ftbl_blspqup_spi_apps_clk_src,
+ .clkr.hw.init = &(struct clk_init_data)
+ {
+ .name = "blsp2_qup6_spi_apps_clk_src",
+ .parent_names = gcc_xo_gpll0,
+ .num_parents = 2,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static struct clk_rcg2 blsp2_uart1_apps_clk_src = {
+ .cmd_rcgr = 0x09cc,
+ .mnd_width = 16,
+ .hid_width = 5,
+ .parent_map = gcc_xo_gpll0_map,
+ .freq_tbl = ftbl_blsp_uart_apps_clk_src,
+ .clkr.hw.init = &(struct clk_init_data)
+ {
+ .name = "blsp2_uart1_apps_clk_src",
+ .parent_names = gcc_xo_gpll0,
+ .num_parents = 2,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static struct clk_rcg2 blsp2_uart2_apps_clk_src = {
+ .cmd_rcgr = 0x0a4c,
+ .mnd_width = 16,
+ .hid_width = 5,
+ .parent_map = gcc_xo_gpll0_map,
+ .freq_tbl = ftbl_blsp_uart_apps_clk_src,
+ .clkr.hw.init = &(struct clk_init_data)
+ {
+ .name = "blsp2_uart2_apps_clk_src",
+ .parent_names = gcc_xo_gpll0,
+ .num_parents = 2,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static struct clk_rcg2 blsp2_uart3_apps_clk_src = {
+ .cmd_rcgr = 0x0acc,
+ .mnd_width = 16,
+ .hid_width = 5,
+ .parent_map = gcc_xo_gpll0_map,
+ .freq_tbl = ftbl_blsp_uart_apps_clk_src,
+ .clkr.hw.init = &(struct clk_init_data)
+ {
+ .name = "blsp2_uart3_apps_clk_src",
+ .parent_names = gcc_xo_gpll0,
+ .num_parents = 2,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static struct clk_rcg2 blsp2_uart4_apps_clk_src = {
+ .cmd_rcgr = 0x0b4c,
+ .mnd_width = 16,
+ .hid_width = 5,
+ .parent_map = gcc_xo_gpll0_map,
+ .freq_tbl = ftbl_blsp_uart_apps_clk_src,
+ .clkr.hw.init = &(struct clk_init_data)
+ {
+ .name = "blsp2_uart4_apps_clk_src",
+ .parent_names = gcc_xo_gpll0,
+ .num_parents = 2,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static struct clk_rcg2 blsp2_uart5_apps_clk_src = {
+ .cmd_rcgr = 0x0bcc,
+ .mnd_width = 16,
+ .hid_width = 5,
+ .parent_map = gcc_xo_gpll0_map,
+ .freq_tbl = ftbl_blsp_uart_apps_clk_src,
+ .clkr.hw.init = &(struct clk_init_data)
+ {
+ .name = "blsp2_uart5_apps_clk_src",
+ .parent_names = gcc_xo_gpll0,
+ .num_parents = 2,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static struct clk_rcg2 blsp2_uart6_apps_clk_src = {
+ .cmd_rcgr = 0x0c4c,
+ .mnd_width = 16,
+ .hid_width = 5,
+ .parent_map = gcc_xo_gpll0_map,
+ .freq_tbl = ftbl_blsp_uart_apps_clk_src,
+ .clkr.hw.init = &(struct clk_init_data)
+ {
+ .name = "blsp2_uart6_apps_clk_src",
+ .parent_names = gcc_xo_gpll0,
+ .num_parents = 2,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static struct freq_tbl ftbl_gp1_clk_src[] = {
+ F(19200000, P_XO, 1, 0, 0),
+ F(100000000, P_GPLL0, 6, 0, 0),
+ F(200000000, P_GPLL0, 3, 0, 0),
+ { }
+};
+
+static struct clk_rcg2 gp1_clk_src = {
+ .cmd_rcgr = 0x1904,
+ .mnd_width = 8,
+ .hid_width = 5,
+ .parent_map = gcc_xo_gpll0_map,
+ .freq_tbl = ftbl_gp1_clk_src,
+ .clkr.hw.init = &(struct clk_init_data)
+ {
+ .name = "gp1_clk_src",
+ .parent_names = gcc_xo_gpll0,
+ .num_parents = 2,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static struct freq_tbl ftbl_gp2_clk_src[] = {
+ F(19200000, P_XO, 1, 0, 0),
+ F(100000000, P_GPLL0, 6, 0, 0),
+ F(200000000, P_GPLL0, 3, 0, 0),
+ { }
+};
+
+static struct clk_rcg2 gp2_clk_src = {
+ .cmd_rcgr = 0x1944,
+ .mnd_width = 8,
+ .hid_width = 5,
+ .parent_map = gcc_xo_gpll0_map,
+ .freq_tbl = ftbl_gp2_clk_src,
+ .clkr.hw.init = &(struct clk_init_data)
+ {
+ .name = "gp2_clk_src",
+ .parent_names = gcc_xo_gpll0,
+ .num_parents = 2,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static struct freq_tbl ftbl_gp3_clk_src[] = {
+ F(19200000, P_XO, 1, 0, 0),
+ F(100000000, P_GPLL0, 6, 0, 0),
+ F(200000000, P_GPLL0, 3, 0, 0),
+ { }
+};
+
+static struct clk_rcg2 gp3_clk_src = {
+ .cmd_rcgr = 0x1984,
+ .mnd_width = 8,
+ .hid_width = 5,
+ .parent_map = gcc_xo_gpll0_map,
+ .freq_tbl = ftbl_gp3_clk_src,
+ .clkr.hw.init = &(struct clk_init_data)
+ {
+ .name = "gp3_clk_src",
+ .parent_names = gcc_xo_gpll0,
+ .num_parents = 2,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static struct freq_tbl ftbl_pcie_0_aux_clk_src[] = {
+ F(1011000, P_XO, 1, 1, 19),
+ { }
+};
+
+static struct clk_rcg2 pcie_0_aux_clk_src = {
+ .cmd_rcgr = 0x1b00,
+ .mnd_width = 8,
+ .hid_width = 5,
+ .freq_tbl = ftbl_pcie_0_aux_clk_src,
+ .clkr.hw.init = &(struct clk_init_data)
+ {
+ .name = "pcie_0_aux_clk_src",
+ .parent_names = (const char *[]) { "xo" },
+ .num_parents = 1,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static struct freq_tbl ftbl_pcie_pipe_clk_src[] = {
+ F(125000000, P_XO, 1, 0, 0),
+ { }
+};
+
+static struct clk_rcg2 pcie_0_pipe_clk_src = {
+ .cmd_rcgr = 0x1adc,
+ .hid_width = 5,
+ .freq_tbl = ftbl_pcie_pipe_clk_src,
+ .clkr.hw.init = &(struct clk_init_data)
+ {
+ .name = "pcie_0_pipe_clk_src",
+ .parent_names = (const char *[]) { "xo" },
+ .num_parents = 1,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static struct freq_tbl ftbl_pdm2_clk_src[] = {
+ F(60000000, P_GPLL0, 10, 0, 0),
+ { }
+};
+
+static struct clk_rcg2 pdm2_clk_src = {
+ .cmd_rcgr = 0x0cd0,
+ .hid_width = 5,
+ .parent_map = gcc_xo_gpll0_map,
+ .freq_tbl = ftbl_pdm2_clk_src,
+ .clkr.hw.init = &(struct clk_init_data)
+ {
+ .name = "pdm2_clk_src",
+ .parent_names = gcc_xo_gpll0,
+ .num_parents = 2,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static struct freq_tbl ftbl_sdcc1_apps_clk_src[] = {
+ F(144000, P_XO, 16, 3, 25),
+ F(400000, P_XO, 12, 1, 4),
+ F(20000000, P_GPLL0, 15, 1, 2),
+ F(25000000, P_GPLL0, 12, 1, 2),
+ F(50000000, P_GPLL0, 12, 0, 0),
+ F(100000000, P_GPLL0, 6, 0, 0),
+ F(192000000, P_GPLL4, 2, 0, 0),
+ F(384000000, P_GPLL4, 1, 0, 0),
+ { }
+};
+
+static struct clk_rcg2 sdcc1_apps_clk_src = {
+ .cmd_rcgr = 0x04d0,
+ .mnd_width = 8,
+ .hid_width = 5,
+ .parent_map = gcc_xo_gpll0_gpll4_map,
+ .freq_tbl = ftbl_sdcc1_apps_clk_src,
+ .clkr.hw.init = &(struct clk_init_data)
+ {
+ .name = "sdcc1_apps_clk_src",
+ .parent_names = gcc_xo_gpll0_gpll4,
+ .num_parents = 3,
+ .ops = &clk_rcg2_floor_ops,
+ },
+};
+
+static struct freq_tbl ftbl_sdcc2_4_apps_clk_src[] = {
+ F(144000, P_XO, 16, 3, 25),
+ F(400000, P_XO, 12, 1, 4),
+ F(20000000, P_GPLL0, 15, 1, 2),
+ F(25000000, P_GPLL0, 12, 1, 2),
+ F(50000000, P_GPLL0, 12, 0, 0),
+ F(100000000, P_GPLL0, 6, 0, 0),
+ F(200000000, P_GPLL0, 3, 0, 0),
+ { }
+};
+
+static struct clk_rcg2 sdcc2_apps_clk_src = {
+ .cmd_rcgr = 0x0510,
+ .mnd_width = 8,
+ .hid_width = 5,
+ .parent_map = gcc_xo_gpll0_map,
+ .freq_tbl = ftbl_sdcc2_4_apps_clk_src,
+ .clkr.hw.init = &(struct clk_init_data)
+ {
+ .name = "sdcc2_apps_clk_src",
+ .parent_names = gcc_xo_gpll0,
+ .num_parents = 2,
+ .ops = &clk_rcg2_floor_ops,
+ },
+};
+
+static struct clk_rcg2 sdcc3_apps_clk_src = {
+ .cmd_rcgr = 0x0550,
+ .mnd_width = 8,
+ .hid_width = 5,
+ .parent_map = gcc_xo_gpll0_map,
+ .freq_tbl = ftbl_sdcc2_4_apps_clk_src,
+ .clkr.hw.init = &(struct clk_init_data)
+ {
+ .name = "sdcc3_apps_clk_src",
+ .parent_names = gcc_xo_gpll0,
+ .num_parents = 2,
+ .ops = &clk_rcg2_floor_ops,
+ },
+};
+
+static struct clk_rcg2 sdcc4_apps_clk_src = {
+ .cmd_rcgr = 0x0590,
+ .mnd_width = 8,
+ .hid_width = 5,
+ .parent_map = gcc_xo_gpll0_map,
+ .freq_tbl = ftbl_sdcc2_4_apps_clk_src,
+ .clkr.hw.init = &(struct clk_init_data)
+ {
+ .name = "sdcc4_apps_clk_src",
+ .parent_names = gcc_xo_gpll0,
+ .num_parents = 2,
+ .ops = &clk_rcg2_floor_ops,
+ },
+};
+
+static struct freq_tbl ftbl_tsif_ref_clk_src[] = {
+ F(105500, P_XO, 1, 1, 182),
+ { }
+};
+
+static struct clk_rcg2 tsif_ref_clk_src = {
+ .cmd_rcgr = 0x0d90,
+ .mnd_width = 8,
+ .hid_width = 5,
+ .freq_tbl = ftbl_tsif_ref_clk_src,
+ .clkr.hw.init = &(struct clk_init_data)
+ {
+ .name = "tsif_ref_clk_src",
+ .parent_names = (const char *[]) { "xo" },
+ .num_parents = 1,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static struct freq_tbl ftbl_usb30_mock_utmi_clk_src[] = {
+ F(19200000, P_XO, 1, 0, 0),
+ F(60000000, P_GPLL0, 10, 0, 0),
+ { }
+};
+
+static struct clk_rcg2 usb30_mock_utmi_clk_src = {
+ .cmd_rcgr = 0x03e8,
+ .hid_width = 5,
+ .parent_map = gcc_xo_gpll0_map,
+ .freq_tbl = ftbl_usb30_mock_utmi_clk_src,
+ .clkr.hw.init = &(struct clk_init_data)
+ {
+ .name = "usb30_mock_utmi_clk_src",
+ .parent_names = gcc_xo_gpll0,
+ .num_parents = 2,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static struct freq_tbl ftbl_usb3_phy_aux_clk_src[] = {
+ F(1200000, P_XO, 16, 0, 0),
+ { }
+};
+
+static struct clk_rcg2 usb3_phy_aux_clk_src = {
+ .cmd_rcgr = 0x1414,
+ .hid_width = 5,
+ .freq_tbl = ftbl_usb3_phy_aux_clk_src,
+ .clkr.hw.init = &(struct clk_init_data)
+ {
+ .name = "usb3_phy_aux_clk_src",
+ .parent_names = (const char *[]) { "xo" },
+ .num_parents = 1,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static struct freq_tbl ftbl_usb_hs_system_clk_src[] = {
+ F(75000000, P_GPLL0, 8, 0, 0),
+ { }
+};
+
+static struct clk_rcg2 usb_hs_system_clk_src = {
+ .cmd_rcgr = 0x0490,
+ .hid_width = 5,
+ .parent_map = gcc_xo_gpll0_map,
+ .freq_tbl = ftbl_usb_hs_system_clk_src,
+ .clkr.hw.init = &(struct clk_init_data)
+ {
+ .name = "usb_hs_system_clk_src",
+ .parent_names = gcc_xo_gpll0,
+ .num_parents = 2,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static struct clk_branch gcc_blsp1_ahb_clk = {
+ .halt_reg = 0x05c4,
+ .halt_check = BRANCH_HALT_VOTED,
+ .clkr = {
+ .enable_reg = 0x1484,
+ .enable_mask = BIT(17),
+ .hw.init = &(struct clk_init_data)
+ {
+ .name = "gcc_blsp1_ahb_clk",
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_blsp1_qup1_i2c_apps_clk = {
+ .halt_reg = 0x0648,
+ .clkr = {
+ .enable_reg = 0x0648,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data)
+ {
+ .name = "gcc_blsp1_qup1_i2c_apps_clk",
+ .parent_names = (const char *[]) {
+ "blsp1_qup1_i2c_apps_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_blsp1_qup1_spi_apps_clk = {
+ .halt_reg = 0x0644,
+ .clkr = {
+ .enable_reg = 0x0644,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data)
+ {
+ .name = "gcc_blsp1_qup1_spi_apps_clk",
+ .parent_names = (const char *[]) {
+ "blsp1_qup1_spi_apps_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_blsp1_qup2_i2c_apps_clk = {
+ .halt_reg = 0x06c8,
+ .clkr = {
+ .enable_reg = 0x06c8,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data)
+ {
+ .name = "gcc_blsp1_qup2_i2c_apps_clk",
+ .parent_names = (const char *[]) {
+ "blsp1_qup2_i2c_apps_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_blsp1_qup2_spi_apps_clk = {
+ .halt_reg = 0x06c4,
+ .clkr = {
+ .enable_reg = 0x06c4,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data)
+ {
+ .name = "gcc_blsp1_qup2_spi_apps_clk",
+ .parent_names = (const char *[]) {
+ "blsp1_qup2_spi_apps_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_blsp1_qup3_i2c_apps_clk = {
+ .halt_reg = 0x0748,
+ .clkr = {
+ .enable_reg = 0x0748,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data)
+ {
+ .name = "gcc_blsp1_qup3_i2c_apps_clk",
+ .parent_names = (const char *[]) {
+ "blsp1_qup3_i2c_apps_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_blsp1_qup3_spi_apps_clk = {
+ .halt_reg = 0x0744,
+ .clkr = {
+ .enable_reg = 0x0744,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data)
+ {
+ .name = "gcc_blsp1_qup3_spi_apps_clk",
+ .parent_names = (const char *[]) {
+ "blsp1_qup3_spi_apps_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_blsp1_qup4_i2c_apps_clk = {
+ .halt_reg = 0x07c8,
+ .clkr = {
+ .enable_reg = 0x07c8,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data)
+ {
+ .name = "gcc_blsp1_qup4_i2c_apps_clk",
+ .parent_names = (const char *[]) {
+ "blsp1_qup4_i2c_apps_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_blsp1_qup4_spi_apps_clk = {
+ .halt_reg = 0x07c4,
+ .clkr = {
+ .enable_reg = 0x07c4,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data)
+ {
+ .name = "gcc_blsp1_qup4_spi_apps_clk",
+ .parent_names = (const char *[]) {
+ "blsp1_qup4_spi_apps_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_blsp1_qup5_i2c_apps_clk = {
+ .halt_reg = 0x0848,
+ .clkr = {
+ .enable_reg = 0x0848,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data)
+ {
+ .name = "gcc_blsp1_qup5_i2c_apps_clk",
+ .parent_names = (const char *[]) {
+ "blsp1_qup5_i2c_apps_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_blsp1_qup5_spi_apps_clk = {
+ .halt_reg = 0x0844,
+ .clkr = {
+ .enable_reg = 0x0844,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data)
+ {
+ .name = "gcc_blsp1_qup5_spi_apps_clk",
+ .parent_names = (const char *[]) {
+ "blsp1_qup5_spi_apps_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_blsp1_qup6_i2c_apps_clk = {
+ .halt_reg = 0x08c8,
+ .clkr = {
+ .enable_reg = 0x08c8,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data)
+ {
+ .name = "gcc_blsp1_qup6_i2c_apps_clk",
+ .parent_names = (const char *[]) {
+ "blsp1_qup6_i2c_apps_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_blsp1_qup6_spi_apps_clk = {
+ .halt_reg = 0x08c4,
+ .clkr = {
+ .enable_reg = 0x08c4,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data)
+ {
+ .name = "gcc_blsp1_qup6_spi_apps_clk",
+ .parent_names = (const char *[]) {
+ "blsp1_qup6_spi_apps_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_blsp1_uart1_apps_clk = {
+ .halt_reg = 0x0684,
+ .clkr = {
+ .enable_reg = 0x0684,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data)
+ {
+ .name = "gcc_blsp1_uart1_apps_clk",
+ .parent_names = (const char *[]) {
+ "blsp1_uart1_apps_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_blsp1_uart2_apps_clk = {
+ .halt_reg = 0x0704,
+ .clkr = {
+ .enable_reg = 0x0704,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data)
+ {
+ .name = "gcc_blsp1_uart2_apps_clk",
+ .parent_names = (const char *[]) {
+ "blsp1_uart2_apps_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_blsp1_uart3_apps_clk = {
+ .halt_reg = 0x0784,
+ .clkr = {
+ .enable_reg = 0x0784,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data)
+ {
+ .name = "gcc_blsp1_uart3_apps_clk",
+ .parent_names = (const char *[]) {
+ "blsp1_uart3_apps_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_blsp1_uart4_apps_clk = {
+ .halt_reg = 0x0804,
+ .clkr = {
+ .enable_reg = 0x0804,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data)
+ {
+ .name = "gcc_blsp1_uart4_apps_clk",
+ .parent_names = (const char *[]) {
+ "blsp1_uart4_apps_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_blsp1_uart5_apps_clk = {
+ .halt_reg = 0x0884,
+ .clkr = {
+ .enable_reg = 0x0884,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data)
+ {
+ .name = "gcc_blsp1_uart5_apps_clk",
+ .parent_names = (const char *[]) {
+ "blsp1_uart5_apps_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_blsp1_uart6_apps_clk = {
+ .halt_reg = 0x0904,
+ .clkr = {
+ .enable_reg = 0x0904,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data)
+ {
+ .name = "gcc_blsp1_uart6_apps_clk",
+ .parent_names = (const char *[]) {
+ "blsp1_uart6_apps_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_blsp2_ahb_clk = {
+ .halt_reg = 0x0944,
+ .halt_check = BRANCH_HALT_VOTED,
+ .clkr = {
+ .enable_reg = 0x1484,
+ .enable_mask = BIT(15),
+ .hw.init = &(struct clk_init_data)
+ {
+ .name = "gcc_blsp2_ahb_clk",
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_blsp2_qup1_i2c_apps_clk = {
+ .halt_reg = 0x0988,
+ .clkr = {
+ .enable_reg = 0x0988,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data)
+ {
+ .name = "gcc_blsp2_qup1_i2c_apps_clk",
+ .parent_names = (const char *[]) {
+ "blsp2_qup1_i2c_apps_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_blsp2_qup1_spi_apps_clk = {
+ .halt_reg = 0x0984,
+ .clkr = {
+ .enable_reg = 0x0984,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data)
+ {
+ .name = "gcc_blsp2_qup1_spi_apps_clk",
+ .parent_names = (const char *[]) {
+ "blsp2_qup1_spi_apps_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_blsp2_qup2_i2c_apps_clk = {
+ .halt_reg = 0x0a08,
+ .clkr = {
+ .enable_reg = 0x0a08,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data)
+ {
+ .name = "gcc_blsp2_qup2_i2c_apps_clk",
+ .parent_names = (const char *[]) {
+ "blsp2_qup2_i2c_apps_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_blsp2_qup2_spi_apps_clk = {
+ .halt_reg = 0x0a04,
+ .clkr = {
+ .enable_reg = 0x0a04,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data)
+ {
+ .name = "gcc_blsp2_qup2_spi_apps_clk",
+ .parent_names = (const char *[]) {
+ "blsp2_qup2_spi_apps_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_blsp2_qup3_i2c_apps_clk = {
+ .halt_reg = 0x0a88,
+ .clkr = {
+ .enable_reg = 0x0a88,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data)
+ {
+ .name = "gcc_blsp2_qup3_i2c_apps_clk",
+ .parent_names = (const char *[]) {
+ "blsp2_qup3_i2c_apps_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_blsp2_qup3_spi_apps_clk = {
+ .halt_reg = 0x0a84,
+ .clkr = {
+ .enable_reg = 0x0a84,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data)
+ {
+ .name = "gcc_blsp2_qup3_spi_apps_clk",
+ .parent_names = (const char *[]) {
+ "blsp2_qup3_spi_apps_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_blsp2_qup4_i2c_apps_clk = {
+ .halt_reg = 0x0b08,
+ .clkr = {
+ .enable_reg = 0x0b08,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data)
+ {
+ .name = "gcc_blsp2_qup4_i2c_apps_clk",
+ .parent_names = (const char *[]) {
+ "blsp2_qup4_i2c_apps_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_blsp2_qup4_spi_apps_clk = {
+ .halt_reg = 0x0b04,
+ .clkr = {
+ .enable_reg = 0x0b04,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data)
+ {
+ .name = "gcc_blsp2_qup4_spi_apps_clk",
+ .parent_names = (const char *[]) {
+ "blsp2_qup4_spi_apps_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_blsp2_qup5_i2c_apps_clk = {
+ .halt_reg = 0x0b88,
+ .clkr = {
+ .enable_reg = 0x0b88,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data)
+ {
+ .name = "gcc_blsp2_qup5_i2c_apps_clk",
+ .parent_names = (const char *[]) {
+ "blsp2_qup5_i2c_apps_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_blsp2_qup5_spi_apps_clk = {
+ .halt_reg = 0x0b84,
+ .clkr = {
+ .enable_reg = 0x0b84,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data)
+ {
+ .name = "gcc_blsp2_qup5_spi_apps_clk",
+ .parent_names = (const char *[]) {
+ "blsp2_qup5_spi_apps_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_blsp2_qup6_i2c_apps_clk = {
+ .halt_reg = 0x0c08,
+ .clkr = {
+ .enable_reg = 0x0c08,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data)
+ {
+ .name = "gcc_blsp2_qup6_i2c_apps_clk",
+ .parent_names = (const char *[]) {
+ "blsp2_qup6_i2c_apps_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_blsp2_qup6_spi_apps_clk = {
+ .halt_reg = 0x0c04,
+ .clkr = {
+ .enable_reg = 0x0c04,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data)
+ {
+ .name = "gcc_blsp2_qup6_spi_apps_clk",
+ .parent_names = (const char *[]) {
+ "blsp2_qup6_spi_apps_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_blsp2_uart1_apps_clk = {
+ .halt_reg = 0x09c4,
+ .clkr = {
+ .enable_reg = 0x09c4,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data)
+ {
+ .name = "gcc_blsp2_uart1_apps_clk",
+ .parent_names = (const char *[]) {
+ "blsp2_uart1_apps_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_blsp2_uart2_apps_clk = {
+ .halt_reg = 0x0a44,
+ .clkr = {
+ .enable_reg = 0x0a44,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data)
+ {
+ .name = "gcc_blsp2_uart2_apps_clk",
+ .parent_names = (const char *[]) {
+ "blsp2_uart2_apps_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_blsp2_uart3_apps_clk = {
+ .halt_reg = 0x0ac4,
+ .clkr = {
+ .enable_reg = 0x0ac4,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data)
+ {
+ .name = "gcc_blsp2_uart3_apps_clk",
+ .parent_names = (const char *[]) {
+ "blsp2_uart3_apps_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_blsp2_uart4_apps_clk = {
+ .halt_reg = 0x0b44,
+ .clkr = {
+ .enable_reg = 0x0b44,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data)
+ {
+ .name = "gcc_blsp2_uart4_apps_clk",
+ .parent_names = (const char *[]) {
+ "blsp2_uart4_apps_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_blsp2_uart5_apps_clk = {
+ .halt_reg = 0x0bc4,
+ .clkr = {
+ .enable_reg = 0x0bc4,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data)
+ {
+ .name = "gcc_blsp2_uart5_apps_clk",
+ .parent_names = (const char *[]) {
+ "blsp2_uart5_apps_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_blsp2_uart6_apps_clk = {
+ .halt_reg = 0x0c44,
+ .clkr = {
+ .enable_reg = 0x0c44,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data)
+ {
+ .name = "gcc_blsp2_uart6_apps_clk",
+ .parent_names = (const char *[]) {
+ "blsp2_uart6_apps_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_boot_rom_ahb_clk = {
+ .halt_reg = 0x0e04,
+ .halt_check = BRANCH_HALT_VOTED,
+ .clkr = {
+ .enable_reg = 0x1484,
+ .enable_mask = BIT(10),
+ .hw.init = &(struct clk_init_data)
+ {
+ .name = "gcc_boot_rom_ahb_clk",
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_gp1_clk = {
+ .halt_reg = 0x1900,
+ .clkr = {
+ .enable_reg = 0x1900,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data)
+ {
+ .name = "gcc_gp1_clk",
+ .parent_names = (const char *[]) {
+ "gp1_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_gp2_clk = {
+ .halt_reg = 0x1940,
+ .clkr = {
+ .enable_reg = 0x1940,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data)
+ {
+ .name = "gcc_gp2_clk",
+ .parent_names = (const char *[]) {
+ "gp2_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_gp3_clk = {
+ .halt_reg = 0x1980,
+ .clkr = {
+ .enable_reg = 0x1980,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data)
+ {
+ .name = "gcc_gp3_clk",
+ .parent_names = (const char *[]) {
+ "gp3_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_mss_cfg_ahb_clk = {
+ .halt_reg = 0x0280,
+ .clkr = {
+ .enable_reg = 0x0280,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data)
+ {
+ .name = "gcc_mss_cfg_ahb_clk",
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_mss_q6_bimc_axi_clk = {
+ .halt_reg = 0x0284,
+ .clkr = {
+ .enable_reg = 0x0284,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data)
+ {
+ .name = "gcc_mss_q6_bimc_axi_clk",
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_pcie_0_aux_clk = {
+ .halt_reg = 0x1ad4,
+ .clkr = {
+ .enable_reg = 0x1ad4,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data)
+ {
+ .name = "gcc_pcie_0_aux_clk",
+ .parent_names = (const char *[]) {
+ "pcie_0_aux_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_pcie_0_cfg_ahb_clk = {
+ .halt_reg = 0x1ad0,
+ .clkr = {
+ .enable_reg = 0x1ad0,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data)
+ {
+ .name = "gcc_pcie_0_cfg_ahb_clk",
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_pcie_0_mstr_axi_clk = {
+ .halt_reg = 0x1acc,
+ .clkr = {
+ .enable_reg = 0x1acc,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data)
+ {
+ .name = "gcc_pcie_0_mstr_axi_clk",
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_pcie_0_pipe_clk = {
+ .halt_reg = 0x1ad8,
+ .halt_check = BRANCH_HALT_DELAY,
+ .clkr = {
+ .enable_reg = 0x1ad8,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data)
+ {
+ .name = "gcc_pcie_0_pipe_clk",
+ .parent_names = (const char *[]) {
+ "pcie_0_pipe_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_pcie_0_slv_axi_clk = {
+ .halt_reg = 0x1ac8,
+ .halt_check = BRANCH_HALT_DELAY,
+ .clkr = {
+ .enable_reg = 0x1ac8,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data)
+ {
+ .name = "gcc_pcie_0_slv_axi_clk",
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_pdm2_clk = {
+ .halt_reg = 0x0ccc,
+ .clkr = {
+ .enable_reg = 0x0ccc,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data)
+ {
+ .name = "gcc_pdm2_clk",
+ .parent_names = (const char *[]) {
+ "pdm2_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_pdm_ahb_clk = {
+ .halt_reg = 0x0cc4,
+ .clkr = {
+ .enable_reg = 0x0cc4,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data)
+ {
+ .name = "gcc_pdm_ahb_clk",
+ .ops = &clk_branch2_ops,
+ }
+ }
+};
+
+static struct clk_branch gcc_prng_ahb_clk = {
+ .halt_reg = 0x0d04,
+ .clkr = {
+ .enable_reg = 0x0d04,
+ .enable_mask = BIT(13),
+ .hw.init = &(struct clk_init_data)
+ {
+ .name = "gcc_prng_ahb_clk",
+ .ops = &clk_branch2_ops,
+ }
+ }
+};
+
+static struct clk_branch gcc_sdcc1_ahb_clk = {
+ .halt_reg = 0x04c8,
+ .clkr = {
+ .enable_reg = 0x04c8,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data)
+ {
+ .name = "gcc_sdcc1_ahb_clk",
+ .parent_names = (const char *[]){
+ "periph_noc_clk_src",
+ },
+ .num_parents = 1,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_sdcc1_apps_clk = {
+ .halt_reg = 0x04c4,
+ .clkr = {
+ .enable_reg = 0x04c4,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data)
+ {
+ .name = "gcc_sdcc1_apps_clk",
+ .parent_names = (const char *[]) {
+ "sdcc1_apps_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_sdcc2_ahb_clk = {
+ .halt_reg = 0x0508,
+ .clkr = {
+ .enable_reg = 0x0508,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data)
+ {
+ .name = "gcc_sdcc2_ahb_clk",
+ .parent_names = (const char *[]){
+ "periph_noc_clk_src",
+ },
+ .num_parents = 1,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_sdcc2_apps_clk = {
+ .halt_reg = 0x0504,
+ .clkr = {
+ .enable_reg = 0x0504,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data)
+ {
+ .name = "gcc_sdcc2_apps_clk",
+ .parent_names = (const char *[]) {
+ "sdcc2_apps_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_sdcc3_ahb_clk = {
+ .halt_reg = 0x0548,
+ .clkr = {
+ .enable_reg = 0x0548,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data)
+ {
+ .name = "gcc_sdcc3_ahb_clk",
+ .parent_names = (const char *[]){
+ "periph_noc_clk_src",
+ },
+ .num_parents = 1,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_sdcc3_apps_clk = {
+ .halt_reg = 0x0544,
+ .clkr = {
+ .enable_reg = 0x0544,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data)
+ {
+ .name = "gcc_sdcc3_apps_clk",
+ .parent_names = (const char *[]) {
+ "sdcc3_apps_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_sdcc4_ahb_clk = {
+ .halt_reg = 0x0588,
+ .clkr = {
+ .enable_reg = 0x0588,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data)
+ {
+ .name = "gcc_sdcc4_ahb_clk",
+ .parent_names = (const char *[]){
+ "periph_noc_clk_src",
+ },
+ .num_parents = 1,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_sdcc4_apps_clk = {
+ .halt_reg = 0x0584,
+ .clkr = {
+ .enable_reg = 0x0584,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data)
+ {
+ .name = "gcc_sdcc4_apps_clk",
+ .parent_names = (const char *[]) {
+ "sdcc4_apps_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_sys_noc_usb3_axi_clk = {
+ .halt_reg = 0x03fc,
+ .clkr = {
+ .enable_reg = 0x03fc,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data)
+ {
+ .name = "gcc_sys_noc_usb3_axi_clk",
+ .parent_names = (const char *[]) {
+ "usb30_master_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_tsif_ahb_clk = {
+ .halt_reg = 0x0d84,
+ .clkr = {
+ .enable_reg = 0x0d84,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data)
+ {
+ .name = "gcc_tsif_ahb_clk",
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_tsif_ref_clk = {
+ .halt_reg = 0x0d88,
+ .clkr = {
+ .enable_reg = 0x0d88,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data)
+ {
+ .name = "gcc_tsif_ref_clk",
+ .parent_names = (const char *[]) {
+ "tsif_ref_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_usb2_hs_phy_sleep_clk = {
+ .halt_reg = 0x04ac,
+ .clkr = {
+ .enable_reg = 0x04ac,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data)
+ {
+ .name = "gcc_usb2_hs_phy_sleep_clk",
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_usb30_master_clk = {
+ .halt_reg = 0x03c8,
+ .clkr = {
+ .enable_reg = 0x03c8,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data)
+ {
+ .name = "gcc_usb30_master_clk",
+ .parent_names = (const char *[]) {
+ "usb30_master_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_usb30_mock_utmi_clk = {
+ .halt_reg = 0x03d0,
+ .clkr = {
+ .enable_reg = 0x03d0,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data)
+ {
+ .name = "gcc_usb30_mock_utmi_clk",
+ .parent_names = (const char *[]) {
+ "usb30_mock_utmi_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_usb30_sleep_clk = {
+ .halt_reg = 0x03cc,
+ .clkr = {
+ .enable_reg = 0x03cc,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data)
+ {
+ .name = "gcc_usb30_sleep_clk",
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_usb3_phy_aux_clk = {
+ .halt_reg = 0x1408,
+ .clkr = {
+ .enable_reg = 0x1408,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data)
+ {
+ .name = "gcc_usb3_phy_aux_clk",
+ .parent_names = (const char *[]) {
+ "usb3_phy_aux_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_usb3_phy_pipe_clk = {
+ .halt_reg = 0x140c,
+ .clkr = {
+ .enable_reg = 0x140c,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data)
+ {
+ .name = "gcc_usb3_phy_pipe_clk",
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_usb_hs_ahb_clk = {
+ .halt_reg = 0x0488,
+ .clkr = {
+ .enable_reg = 0x0488,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data)
+ {
+ .name = "gcc_usb_hs_ahb_clk",
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_usb_hs_system_clk = {
+ .halt_reg = 0x0484,
+ .clkr = {
+ .enable_reg = 0x0484,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data)
+ {
+ .name = "gcc_usb_hs_system_clk",
+ .parent_names = (const char *[]) {
+ "usb_hs_system_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_usb_phy_cfg_ahb2phy_clk = {
+ .halt_reg = 0x1a84,
+ .clkr = {
+ .enable_reg = 0x1a84,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data)
+ {
+ .name = "gcc_usb_phy_cfg_ahb2phy_clk",
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct gdsc pcie_gdsc = {
+ .gdscr = 0x1e18,
+ .pd = {
+ .name = "pcie",
+ },
+ .pwrsts = PWRSTS_OFF_ON,
+};
+
+static struct gdsc pcie_0_gdsc = {
+ .gdscr = 0x1ac4,
+ .pd = {
+ .name = "pcie_0",
+ },
+ .pwrsts = PWRSTS_OFF_ON,
+};
+
+static struct gdsc usb30_gdsc = {
+ .gdscr = 0x3c4,
+ .pd = {
+ .name = "usb30",
+ },
+ .pwrsts = PWRSTS_OFF_ON,
+};
+
+static struct clk_regmap *gcc_msm8992_clocks[] = {
+ [GPLL0_EARLY] = &gpll0_early.clkr,
+ [GPLL0] = &gpll0.clkr,
+ [GPLL4_EARLY] = &gpll4_early.clkr,
+ [GPLL4] = &gpll4.clkr,
+ [USB30_MASTER_CLK_SRC] = &usb30_master_clk_src.clkr,
+ [BLSP1_QUP1_I2C_APPS_CLK_SRC] = &blsp1_qup1_i2c_apps_clk_src.clkr,
+ [BLSP1_QUP1_SPI_APPS_CLK_SRC] = &blsp1_qup1_spi_apps_clk_src.clkr,
+ [BLSP1_QUP2_I2C_APPS_CLK_SRC] = &blsp1_qup2_i2c_apps_clk_src.clkr,
+ [BLSP1_QUP2_SPI_APPS_CLK_SRC] = &blsp1_qup2_spi_apps_clk_src.clkr,
+ [BLSP1_QUP3_I2C_APPS_CLK_SRC] = &blsp1_qup3_i2c_apps_clk_src.clkr,
+ [BLSP1_QUP3_SPI_APPS_CLK_SRC] = &blsp1_qup3_spi_apps_clk_src.clkr,
+ [BLSP1_QUP4_I2C_APPS_CLK_SRC] = &blsp1_qup4_i2c_apps_clk_src.clkr,
+ [BLSP1_QUP4_SPI_APPS_CLK_SRC] = &blsp1_qup4_spi_apps_clk_src.clkr,
+ [BLSP1_QUP5_I2C_APPS_CLK_SRC] = &blsp1_qup5_i2c_apps_clk_src.clkr,
+ [BLSP1_QUP5_SPI_APPS_CLK_SRC] = &blsp1_qup5_spi_apps_clk_src.clkr,
+ [BLSP1_QUP6_I2C_APPS_CLK_SRC] = &blsp1_qup6_i2c_apps_clk_src.clkr,
+ [BLSP1_QUP6_SPI_APPS_CLK_SRC] = &blsp1_qup6_spi_apps_clk_src.clkr,
+ [BLSP1_UART1_APPS_CLK_SRC] = &blsp1_uart1_apps_clk_src.clkr,
+ [BLSP1_UART2_APPS_CLK_SRC] = &blsp1_uart2_apps_clk_src.clkr,
+ [BLSP1_UART3_APPS_CLK_SRC] = &blsp1_uart3_apps_clk_src.clkr,
+ [BLSP1_UART4_APPS_CLK_SRC] = &blsp1_uart4_apps_clk_src.clkr,
+ [BLSP1_UART5_APPS_CLK_SRC] = &blsp1_uart5_apps_clk_src.clkr,
+ [BLSP1_UART6_APPS_CLK_SRC] = &blsp1_uart6_apps_clk_src.clkr,
+ [BLSP2_QUP1_I2C_APPS_CLK_SRC] = &blsp2_qup1_i2c_apps_clk_src.clkr,
+ [BLSP2_QUP1_SPI_APPS_CLK_SRC] = &blsp2_qup1_spi_apps_clk_src.clkr,
+ [BLSP2_QUP2_I2C_APPS_CLK_SRC] = &blsp2_qup2_i2c_apps_clk_src.clkr,
+ [BLSP2_QUP2_SPI_APPS_CLK_SRC] = &blsp2_qup2_spi_apps_clk_src.clkr,
+ [BLSP2_QUP3_I2C_APPS_CLK_SRC] = &blsp2_qup3_i2c_apps_clk_src.clkr,
+ [BLSP2_QUP3_SPI_APPS_CLK_SRC] = &blsp2_qup3_spi_apps_clk_src.clkr,
+ [BLSP2_QUP4_I2C_APPS_CLK_SRC] = &blsp2_qup4_i2c_apps_clk_src.clkr,
+ [BLSP2_QUP4_SPI_APPS_CLK_SRC] = &blsp2_qup4_spi_apps_clk_src.clkr,
+ [BLSP2_QUP5_I2C_APPS_CLK_SRC] = &blsp2_qup5_i2c_apps_clk_src.clkr,
+ [BLSP2_QUP5_SPI_APPS_CLK_SRC] = &blsp2_qup5_spi_apps_clk_src.clkr,
+ [BLSP2_QUP6_I2C_APPS_CLK_SRC] = &blsp2_qup6_i2c_apps_clk_src.clkr,
+ [BLSP2_QUP6_SPI_APPS_CLK_SRC] = &blsp2_qup6_spi_apps_clk_src.clkr,
+ [BLSP2_UART1_APPS_CLK_SRC] = &blsp2_uart1_apps_clk_src.clkr,
+ [BLSP2_UART2_APPS_CLK_SRC] = &blsp2_uart2_apps_clk_src.clkr,
+ [BLSP2_UART3_APPS_CLK_SRC] = &blsp2_uart3_apps_clk_src.clkr,
+ [BLSP2_UART4_APPS_CLK_SRC] = &blsp2_uart4_apps_clk_src.clkr,
+ [BLSP2_UART5_APPS_CLK_SRC] = &blsp2_uart5_apps_clk_src.clkr,
+ [BLSP2_UART6_APPS_CLK_SRC] = &blsp2_uart6_apps_clk_src.clkr,
+ [GP1_CLK_SRC] = &gp1_clk_src.clkr,
+ [GP2_CLK_SRC] = &gp2_clk_src.clkr,
+ [GP3_CLK_SRC] = &gp3_clk_src.clkr,
+ [PCIE_0_AUX_CLK_SRC] = &pcie_0_aux_clk_src.clkr,
+ [PCIE_0_PIPE_CLK_SRC] = &pcie_0_pipe_clk_src.clkr,
+ [PDM2_CLK_SRC] = &pdm2_clk_src.clkr,
+ [SDCC1_APPS_CLK_SRC] = &sdcc1_apps_clk_src.clkr,
+ [SDCC2_APPS_CLK_SRC] = &sdcc2_apps_clk_src.clkr,
+ [SDCC3_APPS_CLK_SRC] = &sdcc3_apps_clk_src.clkr,
+ [SDCC4_APPS_CLK_SRC] = &sdcc4_apps_clk_src.clkr,
+ [TSIF_REF_CLK_SRC] = &tsif_ref_clk_src.clkr,
+ [USB30_MOCK_UTMI_CLK_SRC] = &usb30_mock_utmi_clk_src.clkr,
+ [USB3_PHY_AUX_CLK_SRC] = &usb3_phy_aux_clk_src.clkr,
+ [USB_HS_SYSTEM_CLK_SRC] = &usb_hs_system_clk_src.clkr,
+ [GCC_BLSP1_AHB_CLK] = &gcc_blsp1_ahb_clk.clkr,
+ [GCC_BLSP1_QUP1_I2C_APPS_CLK] = &gcc_blsp1_qup1_i2c_apps_clk.clkr,
+ [GCC_BLSP1_QUP1_SPI_APPS_CLK] = &gcc_blsp1_qup1_spi_apps_clk.clkr,
+ [GCC_BLSP1_QUP2_I2C_APPS_CLK] = &gcc_blsp1_qup2_i2c_apps_clk.clkr,
+ [GCC_BLSP1_QUP2_SPI_APPS_CLK] = &gcc_blsp1_qup2_spi_apps_clk.clkr,
+ [GCC_BLSP1_QUP3_I2C_APPS_CLK] = &gcc_blsp1_qup3_i2c_apps_clk.clkr,
+ [GCC_BLSP1_QUP3_SPI_APPS_CLK] = &gcc_blsp1_qup3_spi_apps_clk.clkr,
+ [GCC_BLSP1_QUP4_I2C_APPS_CLK] = &gcc_blsp1_qup4_i2c_apps_clk.clkr,
+ [GCC_BLSP1_QUP4_SPI_APPS_CLK] = &gcc_blsp1_qup4_spi_apps_clk.clkr,
+ [GCC_BLSP1_QUP5_I2C_APPS_CLK] = &gcc_blsp1_qup5_i2c_apps_clk.clkr,
+ [GCC_BLSP1_QUP5_SPI_APPS_CLK] = &gcc_blsp1_qup5_spi_apps_clk.clkr,
+ [GCC_BLSP1_QUP6_I2C_APPS_CLK] = &gcc_blsp1_qup6_i2c_apps_clk.clkr,
+ [GCC_BLSP1_QUP6_SPI_APPS_CLK] = &gcc_blsp1_qup6_spi_apps_clk.clkr,
+ [GCC_BLSP1_UART1_APPS_CLK] = &gcc_blsp1_uart1_apps_clk.clkr,
+ [GCC_BLSP1_UART2_APPS_CLK] = &gcc_blsp1_uart2_apps_clk.clkr,
+ [GCC_BLSP1_UART3_APPS_CLK] = &gcc_blsp1_uart3_apps_clk.clkr,
+ [GCC_BLSP1_UART4_APPS_CLK] = &gcc_blsp1_uart4_apps_clk.clkr,
+ [GCC_BLSP1_UART5_APPS_CLK] = &gcc_blsp1_uart5_apps_clk.clkr,
+ [GCC_BLSP1_UART6_APPS_CLK] = &gcc_blsp1_uart6_apps_clk.clkr,
+ [GCC_BLSP2_AHB_CLK] = &gcc_blsp2_ahb_clk.clkr,
+ [GCC_BLSP2_QUP1_I2C_APPS_CLK] = &gcc_blsp2_qup1_i2c_apps_clk.clkr,
+ [GCC_BLSP2_QUP1_SPI_APPS_CLK] = &gcc_blsp2_qup1_spi_apps_clk.clkr,
+ [GCC_BLSP2_QUP2_I2C_APPS_CLK] = &gcc_blsp2_qup2_i2c_apps_clk.clkr,
+ [GCC_BLSP2_QUP2_SPI_APPS_CLK] = &gcc_blsp2_qup2_spi_apps_clk.clkr,
+ [GCC_BLSP2_QUP3_I2C_APPS_CLK] = &gcc_blsp2_qup3_i2c_apps_clk.clkr,
+ [GCC_BLSP2_QUP3_SPI_APPS_CLK] = &gcc_blsp2_qup3_spi_apps_clk.clkr,
+ [GCC_BLSP2_QUP4_I2C_APPS_CLK] = &gcc_blsp2_qup4_i2c_apps_clk.clkr,
+ [GCC_BLSP2_QUP4_SPI_APPS_CLK] = &gcc_blsp2_qup4_spi_apps_clk.clkr,
+ [GCC_BLSP2_QUP5_I2C_APPS_CLK] = &gcc_blsp2_qup5_i2c_apps_clk.clkr,
+ [GCC_BLSP2_QUP5_SPI_APPS_CLK] = &gcc_blsp2_qup5_spi_apps_clk.clkr,
+ [GCC_BLSP2_QUP6_I2C_APPS_CLK] = &gcc_blsp2_qup6_i2c_apps_clk.clkr,
+ [GCC_BLSP2_QUP6_SPI_APPS_CLK] = &gcc_blsp2_qup6_spi_apps_clk.clkr,
+ [GCC_BLSP2_UART1_APPS_CLK] = &gcc_blsp2_uart1_apps_clk.clkr,
+ [GCC_BLSP2_UART2_APPS_CLK] = &gcc_blsp2_uart2_apps_clk.clkr,
+ [GCC_BLSP2_UART3_APPS_CLK] = &gcc_blsp2_uart3_apps_clk.clkr,
+ [GCC_BLSP2_UART4_APPS_CLK] = &gcc_blsp2_uart4_apps_clk.clkr,
+ [GCC_BLSP2_UART5_APPS_CLK] = &gcc_blsp2_uart5_apps_clk.clkr,
+ [GCC_BLSP2_UART6_APPS_CLK] = &gcc_blsp2_uart6_apps_clk.clkr,
+ [GCC_BOOT_ROM_AHB_CLK] = &gcc_boot_rom_ahb_clk.clkr,
+ [GCC_GP1_CLK] = &gcc_gp1_clk.clkr,
+ [GCC_GP2_CLK] = &gcc_gp2_clk.clkr,
+ [GCC_GP3_CLK] = &gcc_gp3_clk.clkr,
+ [GCC_MSS_CFG_AHB_CLK] = &gcc_mss_cfg_ahb_clk.clkr,
+ [GCC_MSS_Q6_BIMC_AXI_CLK] = &gcc_mss_q6_bimc_axi_clk.clkr,
+ [GCC_PCIE_0_AUX_CLK] = &gcc_pcie_0_aux_clk.clkr,
+ [GCC_PCIE_0_CFG_AHB_CLK] = &gcc_pcie_0_cfg_ahb_clk.clkr,
+ [GCC_PCIE_0_MSTR_AXI_CLK] = &gcc_pcie_0_mstr_axi_clk.clkr,
+ [GCC_PCIE_0_PIPE_CLK] = &gcc_pcie_0_pipe_clk.clkr,
+ [GCC_PCIE_0_SLV_AXI_CLK] = &gcc_pcie_0_slv_axi_clk.clkr,
+ [GCC_PDM2_CLK] = &gcc_pdm2_clk.clkr,
+ [GCC_PDM_AHB_CLK] = &gcc_pdm_ahb_clk.clkr,
+ [GCC_PRNG_AHB_CLK] = &gcc_prng_ahb_clk.clkr,
+ [GCC_SDCC1_AHB_CLK] = &gcc_sdcc1_ahb_clk.clkr,
+ [GCC_SDCC1_APPS_CLK] = &gcc_sdcc1_apps_clk.clkr,
+ [GCC_SDCC2_AHB_CLK] = &gcc_sdcc2_ahb_clk.clkr,
+ [GCC_SDCC2_APPS_CLK] = &gcc_sdcc2_apps_clk.clkr,
+ [GCC_SDCC3_AHB_CLK] = &gcc_sdcc3_ahb_clk.clkr,
+ [GCC_SDCC3_APPS_CLK] = &gcc_sdcc3_apps_clk.clkr,
+ [GCC_SDCC4_AHB_CLK] = &gcc_sdcc4_ahb_clk.clkr,
+ [GCC_SDCC4_APPS_CLK] = &gcc_sdcc4_apps_clk.clkr,
+ [GCC_SYS_NOC_USB3_AXI_CLK] = &gcc_sys_noc_usb3_axi_clk.clkr,
+ [GCC_TSIF_AHB_CLK] = &gcc_tsif_ahb_clk.clkr,
+ [GCC_TSIF_REF_CLK] = &gcc_tsif_ref_clk.clkr,
+ [GCC_USB2_HS_PHY_SLEEP_CLK] = &gcc_usb2_hs_phy_sleep_clk.clkr,
+ [GCC_USB30_MASTER_CLK] = &gcc_usb30_master_clk.clkr,
+ [GCC_USB30_MOCK_UTMI_CLK] = &gcc_usb30_mock_utmi_clk.clkr,
+ [GCC_USB30_SLEEP_CLK] = &gcc_usb30_sleep_clk.clkr,
+ [GCC_USB3_PHY_AUX_CLK] = &gcc_usb3_phy_aux_clk.clkr,
+ [GCC_USB3_PHY_PIPE_CLK] = &gcc_usb3_phy_pipe_clk.clkr,
+ [GCC_USB_HS_AHB_CLK] = &gcc_usb_hs_ahb_clk.clkr,
+ [GCC_USB_HS_SYSTEM_CLK] = &gcc_usb_hs_system_clk.clkr,
+ [GCC_USB_PHY_CFG_AHB2PHY_CLK] = &gcc_usb_phy_cfg_ahb2phy_clk.clkr,
+};
+
+static struct gdsc *gcc_msm8992_gdscs[] = {
+ [PCIE_GDSC] = &pcie_gdsc,
+ [PCIE_0_GDSC] = &pcie_0_gdsc,
+ [USB30_GDSC] = &usb30_gdsc,
+};
+
+static const struct qcom_reset_map gcc_msm8992_resets[] = {
+ [PCIE_PHY_0_RESET] = { 0x1B18 },
+ [QUSB2_PHY_RESET] = { 0x04B8 },
+ [USB3_PHY_RESET] = { 0x1400 },
+};
+
+static const struct regmap_config gcc_msm8992_regmap_config = {
+ .reg_bits = 32,
+ .reg_stride = 4,
+ .val_bits = 32,
+ .max_register = 0x2000,
+ .fast_io = true,
+};
+
+static const struct qcom_cc_desc gcc_msm8992_desc = {
+ .config = &gcc_msm8992_regmap_config,
+ .clks = gcc_msm8992_clocks,
+ .num_clks = ARRAY_SIZE(gcc_msm8992_clocks),
+ .resets = gcc_msm8992_resets,
+ .num_resets = ARRAY_SIZE(gcc_msm8992_resets),
+ .gdscs = gcc_msm8992_gdscs,
+ .num_gdscs = ARRAY_SIZE(gcc_msm8992_gdscs),
+};
+
+static const struct of_device_id gcc_msm8992_match_table[] = {
+ { .compatible = "qcom,gcc-msm8992" },
+ {}
+};
+MODULE_DEVICE_TABLE(of, gcc_msm8992_match_table);
+
+static int gcc_msm8992_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct clk *clk;
+
+ clk = devm_clk_register(dev, &xo.hw);
+ if (IS_ERR(clk))
+ return PTR_ERR(clk);
+
+ return qcom_cc_probe(pdev, &gcc_msm8992_desc);
+}
+
+static struct platform_driver gcc_msm8992_driver = {
+ .probe = gcc_msm8992_probe,
+ .driver = {
+ .name = "gcc-msm8992",
+ .of_match_table = gcc_msm8992_match_table,
+ },
+};
+
+static int __init gcc_msm8992_init(void)
+{
+ return platform_driver_register(&gcc_msm8992_driver);
+}
+core_initcall(gcc_msm8992_init);
+
+static void __exit gcc_msm8992_exit(void)
+{
+ platform_driver_unregister(&gcc_msm8992_driver);
+}
+module_exit(gcc_msm8992_exit);
+
+MODULE_DESCRIPTION("Qualcomm GCC MSM8992 Driver");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:gcc-msm8992");
--
2.26.2
^ permalink raw reply related
* [PATCH 4/4] driver: clk: Add msm8992 GCC Kconfig and Makefile entries
From: Konrad Dybcio @ 2020-05-31 17:46 UTC (permalink / raw)
Cc: Konrad Dybcio, Andy Gross, Bjorn Andersson, Michael Turquette,
Stephen Boyd, Rob Herring, Philipp Zabel, linux-arm-msm,
linux-clk, devicetree, linux-kernel
In-Reply-To: <20200531174612.260113-1-konradybcio@gmail.com>
Signed-off-by: Konrad Dybcio <konradybcio@gmail.com>
---
drivers/clk/qcom/Kconfig | 8 ++++++++
drivers/clk/qcom/Makefile | 1 +
2 files changed, 9 insertions(+)
diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig
index 11ec6f466467..d102b4015289 100644
--- a/drivers/clk/qcom/Kconfig
+++ b/drivers/clk/qcom/Kconfig
@@ -197,6 +197,14 @@ config MSM_MMCC_8974
Say Y if you want to support multimedia devices such as display,
graphics, video encode/decode, camera, etc.
+config MSM_GCC_8992
+ tristate "MSM8992 Global Clock Controller"
+ select QCOM_GDSC
+ help
+ Support for the global clock controller on msm8992 devices.
+ Say Y if you want to use peripheral devices such as UART, SPI,
+ i2c, USB, SD/eMMC, PCIe, etc.
+
config MSM_GCC_8994
tristate "MSM8994 Global Clock Controller"
help
diff --git a/drivers/clk/qcom/Makefile b/drivers/clk/qcom/Makefile
index 691efbf7e81f..4d931562c42f 100644
--- a/drivers/clk/qcom/Makefile
+++ b/drivers/clk/qcom/Makefile
@@ -30,6 +30,7 @@ obj-$(CONFIG_MSM_GCC_8660) += gcc-msm8660.o
obj-$(CONFIG_MSM_GCC_8916) += gcc-msm8916.o
obj-$(CONFIG_MSM_GCC_8960) += gcc-msm8960.o
obj-$(CONFIG_MSM_GCC_8974) += gcc-msm8974.o
+obj-$(CONFIG_MSM_GCC_8992) += gcc-msm8992.o
obj-$(CONFIG_MSM_GCC_8994) += gcc-msm8994.o
obj-$(CONFIG_MSM_GCC_8996) += gcc-msm8996.o
obj-$(CONFIG_MSM_LCC_8960) += lcc-msm8960.o
--
2.26.2
^ permalink raw reply related
* [PATCH 3/4] arm64: dts: Adjust msm8992 DTS to use the correct GCC driver
From: Konrad Dybcio @ 2020-05-31 17:46 UTC (permalink / raw)
Cc: Konrad Dybcio, Andy Gross, Bjorn Andersson, Michael Turquette,
Stephen Boyd, Rob Herring, Philipp Zabel, linux-arm-msm,
linux-clk, devicetree, linux-kernel
In-Reply-To: <20200531174612.260113-1-konradybcio@gmail.com>
This commit adds the necessary includes and corrects the
compatible string for the msm8992 GCC driver. It also
renames "clock_gcc" to "gcc" to follow the style used in
other device trees.
Signed-off-by: Konrad Dybcio <konradybcio@gmail.com>
---
arch/arm64/boot/dts/qcom/msm8992.dtsi | 15 ++++++++-------
1 file changed, 8 insertions(+), 7 deletions(-)
diff --git a/arch/arm64/boot/dts/qcom/msm8992.dtsi b/arch/arm64/boot/dts/qcom/msm8992.dtsi
index 81fed16fcee6..7f618f6183d8 100644
--- a/arch/arm64/boot/dts/qcom/msm8992.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8992.dtsi
@@ -3,7 +3,8 @@
*/
#include <dt-bindings/interrupt-controller/arm-gic.h>
-#include <dt-bindings/clock/qcom,gcc-msm8994.h>
+#include <dt-bindings/clock/qcom,gcc-msm8992.h>
+#include <dt-bindings/reset/qcom,gcc-msm8992.h>
/ {
model = "Qualcomm Technologies, Inc. MSM 8992";
@@ -275,8 +276,8 @@ blsp1_uart2: serial@f991e000 {
interrupts = <GIC_SPI 108 IRQ_TYPE_LEVEL_LOW>;
status = "disabled";
clock-names = "core", "iface";
- clocks = <&clock_gcc GCC_BLSP1_UART2_APPS_CLK>,
- <&clock_gcc GCC_BLSP1_AHB_CLK>;
+ clocks = <&gcc GCC_BLSP1_UART2_APPS_CLK>,
+ <&gcc GCC_BLSP1_AHB_CLK>;
};
blsp2_uart2: serial@f995e000 {
@@ -289,8 +290,8 @@ blsp2_uart2: serial@f995e000 {
<&gcc GCC_BLSP2_AHB_CLK>;
};
- clock_gcc: clock-controller@fc400000 {
- compatible = "qcom,gcc-msm8994";
+ gcc: clock-controller@fc400000 {
+ compatible = "qcom,gcc-msm8992";
#clock-cells = <1>;
#reset-cells = <1>;
#power-domain-cells = <1>;
@@ -306,8 +307,8 @@ sdhci1: mmc@f9824900 {
<GIC_SPI 138 IRQ_TYPE_LEVEL_HIGH>;
interrupt-names = "hc_irq", "pwr_irq";
- clocks = <&clock_gcc GCC_SDCC1_APPS_CLK>,
- <&clock_gcc GCC_SDCC1_AHB_CLK>;
+ clocks = <&gcc GCC_SDCC1_APPS_CLK>,
+ <&gcc GCC_SDCC1_AHB_CLK>;
clock-names = "core", "iface";
pinctrl-names = "default", "sleep";
--
2.26.2
^ permalink raw reply related
* [PATCH 2/4] Add compatible strings and the include files for the msm8992 GCC.
From: Konrad Dybcio @ 2020-05-31 17:46 UTC (permalink / raw)
Cc: Konrad Dybcio, Andy Gross, Bjorn Andersson, Michael Turquette,
Stephen Boyd, Rob Herring, Philipp Zabel, linux-arm-msm,
linux-clk, devicetree, linux-kernel
In-Reply-To: <20200531174612.260113-1-konradybcio@gmail.com>
This commit adds the include files and documents compatible
strings for the msm8992 GCC driver
Signed-off-by: Konrad Dybcio <konradybcio@gmail.com>
---
.../devicetree/bindings/clock/qcom,gcc.yaml | 2 +
include/dt-bindings/clock/qcom,gcc-msm8992.h | 144 ++++++++++++++++++
include/dt-bindings/reset/qcom,gcc-msm8992.h | 8 +
3 files changed, 154 insertions(+)
create mode 100644 include/dt-bindings/clock/qcom,gcc-msm8992.h
create mode 100644 include/dt-bindings/reset/qcom,gcc-msm8992.h
diff --git a/Documentation/devicetree/bindings/clock/qcom,gcc.yaml b/Documentation/devicetree/bindings/clock/qcom,gcc.yaml
index e533bb0cfd2b..66e51f2c0c27 100644
--- a/Documentation/devicetree/bindings/clock/qcom,gcc.yaml
+++ b/Documentation/devicetree/bindings/clock/qcom,gcc.yaml
@@ -26,6 +26,7 @@ description: |
- dt-bindings/reset/qcom,gcc-msm8660.h
- dt-bindings/clock/qcom,gcc-msm8974.h
- dt-bindings/reset/qcom,gcc-msm8974.h
+ - dt-bindings/reset/qcom,gcc-msm8992.h
- dt-bindings/clock/qcom,gcc-msm8994.h
- dt-bindings/clock/qcom,gcc-mdm9615.h
- dt-bindings/reset/qcom,gcc-mdm9615.h
@@ -45,6 +46,7 @@ properties:
- qcom,gcc-msm8974
- qcom,gcc-msm8974pro
- qcom,gcc-msm8974pro-ac
+ - qcom,gcc-msm8992
- qcom,gcc-msm8994
- qcom,gcc-mdm9615
- qcom,gcc-sdm630
diff --git a/include/dt-bindings/clock/qcom,gcc-msm8992.h b/include/dt-bindings/clock/qcom,gcc-msm8992.h
new file mode 100644
index 000000000000..8591a881005d
--- /dev/null
+++ b/include/dt-bindings/clock/qcom,gcc-msm8992.h
@@ -0,0 +1,144 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2016, The Linux Foundation. All rights reserved.
+ */
+
+
+#ifndef _DT_BINDINGS_CLK_MSM_GCC_8992_H
+#define _DT_BINDINGS_CLK_MSM_GCC_8992_H
+
+#define GPLL0_EARLY 0
+#define GPLL0 1
+#define GPLL4_EARLY 2
+#define GPLL4 3
+#define USB30_MASTER_CLK_SRC 4
+#define BLSP1_QUP1_I2C_APPS_CLK_SRC 5
+#define BLSP1_QUP1_SPI_APPS_CLK_SRC 6
+#define BLSP1_QUP2_I2C_APPS_CLK_SRC 7
+#define BLSP1_QUP2_SPI_APPS_CLK_SRC 8
+#define BLSP1_QUP3_I2C_APPS_CLK_SRC 9
+#define BLSP1_QUP3_SPI_APPS_CLK_SRC 10
+#define BLSP1_QUP4_I2C_APPS_CLK_SRC 11
+#define BLSP1_QUP4_SPI_APPS_CLK_SRC 12
+#define BLSP1_QUP5_I2C_APPS_CLK_SRC 13
+#define BLSP1_QUP5_SPI_APPS_CLK_SRC 14
+#define BLSP1_QUP6_I2C_APPS_CLK_SRC 15
+#define BLSP1_QUP6_SPI_APPS_CLK_SRC 16
+#define BLSP1_UART1_APPS_CLK_SRC 17
+#define BLSP1_UART2_APPS_CLK_SRC 18
+#define BLSP1_UART3_APPS_CLK_SRC 19
+#define BLSP1_UART4_APPS_CLK_SRC 20
+#define BLSP1_UART5_APPS_CLK_SRC 21
+#define BLSP1_UART6_APPS_CLK_SRC 22
+#define BLSP2_QUP1_I2C_APPS_CLK_SRC 23
+#define BLSP2_QUP1_SPI_APPS_CLK_SRC 24
+#define BLSP2_QUP2_I2C_APPS_CLK_SRC 25
+#define BLSP2_QUP2_SPI_APPS_CLK_SRC 26
+#define BLSP2_QUP3_I2C_APPS_CLK_SRC 27
+#define BLSP2_QUP3_SPI_APPS_CLK_SRC 28
+#define BLSP2_QUP4_I2C_APPS_CLK_SRC 29
+#define BLSP2_QUP4_SPI_APPS_CLK_SRC 30
+#define BLSP2_QUP5_I2C_APPS_CLK_SRC 31
+#define BLSP2_QUP5_SPI_APPS_CLK_SRC 32
+#define BLSP2_QUP6_I2C_APPS_CLK_SRC 33
+#define BLSP2_QUP6_SPI_APPS_CLK_SRC 34
+#define BLSP2_UART1_APPS_CLK_SRC 35
+#define BLSP2_UART2_APPS_CLK_SRC 36
+#define BLSP2_UART3_APPS_CLK_SRC 37
+#define BLSP2_UART4_APPS_CLK_SRC 38
+#define BLSP2_UART5_APPS_CLK_SRC 39
+#define BLSP2_UART6_APPS_CLK_SRC 40
+#define GP1_CLK_SRC 41
+#define GP2_CLK_SRC 42
+#define GP3_CLK_SRC 43
+#define PCIE_0_AUX_CLK_SRC 44
+#define PCIE_0_PIPE_CLK_SRC 45
+#define PDM2_CLK_SRC 46
+#define SDCC1_APPS_CLK_SRC 47
+#define SDCC2_APPS_CLK_SRC 48
+#define SDCC3_APPS_CLK_SRC 49
+#define SDCC4_APPS_CLK_SRC 50
+#define TSIF_REF_CLK_SRC 51
+#define USB30_MOCK_UTMI_CLK_SRC 52
+#define USB3_PHY_AUX_CLK_SRC 53
+#define USB_HS_SYSTEM_CLK_SRC 54
+#define GCC_BLSP1_AHB_CLK 55
+#define GCC_BLSP1_QUP1_I2C_APPS_CLK 56
+#define GCC_BLSP1_QUP1_SPI_APPS_CLK 57
+#define GCC_BLSP1_QUP2_I2C_APPS_CLK 58
+#define GCC_BLSP1_QUP2_SPI_APPS_CLK 59
+#define GCC_BLSP1_QUP3_I2C_APPS_CLK 60
+#define GCC_BLSP1_QUP3_SPI_APPS_CLK 61
+#define GCC_BLSP1_QUP4_I2C_APPS_CLK 62
+#define GCC_BLSP1_QUP4_SPI_APPS_CLK 63
+#define GCC_BLSP1_QUP5_I2C_APPS_CLK 64
+#define GCC_BLSP1_QUP5_SPI_APPS_CLK 65
+#define GCC_BLSP1_QUP6_I2C_APPS_CLK 66
+#define GCC_BLSP1_QUP6_SPI_APPS_CLK 67
+#define GCC_BLSP1_UART1_APPS_CLK 69
+#define GCC_BLSP1_UART2_APPS_CLK 70
+#define GCC_BLSP1_UART3_APPS_CLK 71
+#define GCC_BLSP1_UART4_APPS_CLK 72
+#define GCC_BLSP1_UART5_APPS_CLK 73
+#define GCC_BLSP1_UART6_APPS_CLK 74
+#define GCC_BLSP2_AHB_CLK 75
+#define GCC_BLSP2_QUP1_I2C_APPS_CLK 76
+#define GCC_BLSP2_QUP1_SPI_APPS_CLK 77
+#define GCC_BLSP2_QUP2_I2C_APPS_CLK 78
+#define GCC_BLSP2_QUP2_SPI_APPS_CLK 79
+#define GCC_BLSP2_QUP3_I2C_APPS_CLK 80
+#define GCC_BLSP2_QUP3_SPI_APPS_CLK 81
+#define GCC_BLSP2_QUP4_I2C_APPS_CLK 82
+#define GCC_BLSP2_QUP4_SPI_APPS_CLK 83
+#define GCC_BLSP2_QUP5_I2C_APPS_CLK 84
+#define GCC_BLSP2_QUP5_SPI_APPS_CLK 85
+#define GCC_BLSP2_QUP6_I2C_APPS_CLK 86
+#define GCC_BLSP2_QUP6_SPI_APPS_CLK 87
+#define GCC_BLSP2_UART1_APPS_CLK 88
+#define GCC_BLSP2_UART2_APPS_CLK 89
+#define GCC_BLSP2_UART3_APPS_CLK 90
+#define GCC_BLSP2_UART4_APPS_CLK 91
+#define GCC_BLSP2_UART5_APPS_CLK 92
+#define GCC_BLSP2_UART6_APPS_CLK 93
+#define GCC_BOOT_ROM_AHB_CLK 94
+#define GCC_GP1_CLK 95
+#define GCC_GP2_CLK 96
+#define GCC_GP3_CLK 97
+#define GCC_MSS_CFG_AHB_CLK 98
+#define GCC_MSS_Q6_BIMC_AXI_CLK 99
+#define GCC_PCIE_0_AUX_CLK 100
+#define GCC_PCIE_0_CFG_AHB_CLK 101
+#define GCC_PCIE_0_MSTR_AXI_CLK 102
+#define GCC_PCIE_0_PIPE_CLK 103
+#define GCC_PCIE_0_SLV_AXI_CLK 104
+#define GCC_PDM2_CLK 105
+#define GCC_PDM_AHB_CLK 106
+#define GCC_PRNG_AHB_CLK 107
+#define GCC_SDCC1_AHB_CLK 108
+#define GCC_SDCC1_APPS_CLK 109
+#define GCC_SDCC2_AHB_CLK 110
+#define GCC_SDCC2_APPS_CLK 111
+#define GCC_SDCC3_AHB_CLK 112
+#define GCC_SDCC3_APPS_CLK 113
+#define GCC_SDCC4_AHB_CLK 114
+#define GCC_SDCC4_APPS_CLK 115
+#define GCC_SYS_NOC_USB3_AXI_CLK 116
+#define GCC_TSIF_AHB_CLK 117
+#define GCC_TSIF_REF_CLK 118
+#define GCC_USB2_HS_PHY_SLEEP_CLK 119
+#define GCC_USB30_MASTER_CLK 120
+#define GCC_USB30_MOCK_UTMI_CLK 121
+#define GCC_USB30_SLEEP_CLK 122
+#define GCC_USB3_PHY_AUX_CLK 123
+#define GCC_USB3_PHY_PIPE_CLK 124
+#define GCC_USB_HS_AHB_CLK 125
+#define GCC_USB_HS_SYSTEM_CLK 126
+#define GCC_USB_PHY_CFG_AHB2PHY_CLK 127
+
+
+/* Indexes for GDSCs */
+#define PCIE_GDSC 0
+#define PCIE_0_GDSC 1
+#define USB30_GDSC 2
+
+#endif
diff --git a/include/dt-bindings/reset/qcom,gcc-msm8992.h b/include/dt-bindings/reset/qcom,gcc-msm8992.h
new file mode 100644
index 000000000000..558dfeffdeef
--- /dev/null
+++ b/include/dt-bindings/reset/qcom,gcc-msm8992.h
@@ -0,0 +1,8 @@
+#ifndef _DT_BINDINGS_RESET_MSM_GCC_8992_H
+#define _DT_BINDINGS_RESET_MSM_GCC_8992_H
+
+#define PCIE_PHY_0_RESET 0
+#define QUSB2_PHY_RESET 1
+#define USB3_PHY_RESET 2
+
+#endif
--
2.26.2
^ permalink raw reply related
* Re: [PATCH 4/4] driver: clk: Add msm8992 GCC Kconfig and Makefile entries
From: Randy Dunlap @ 2020-05-31 17:50 UTC (permalink / raw)
To: Konrad Dybcio
Cc: Andy Gross, Bjorn Andersson, Michael Turquette, Stephen Boyd,
Rob Herring, Philipp Zabel, linux-arm-msm, linux-clk, devicetree,
linux-kernel
In-Reply-To: <20200531174612.260113-5-konradybcio@gmail.com>
On 5/31/20 10:46 AM, Konrad Dybcio wrote:
> Signed-off-by: Konrad Dybcio <konradybcio@gmail.com>
> ---
> drivers/clk/qcom/Kconfig | 8 ++++++++
> drivers/clk/qcom/Makefile | 1 +
> 2 files changed, 9 insertions(+)
>
> diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig
> index 11ec6f466467..d102b4015289 100644
> --- a/drivers/clk/qcom/Kconfig
> +++ b/drivers/clk/qcom/Kconfig
> @@ -197,6 +197,14 @@ config MSM_MMCC_8974
> Say Y if you want to support multimedia devices such as display,
> graphics, video encode/decode, camera, etc.
>
> +config MSM_GCC_8992
> + tristate "MSM8992 Global Clock Controller"
> + select QCOM_GDSC
> + help
> + Support for the global clock controller on msm8992 devices.
> + Say Y if you want to use peripheral devices such as UART, SPI,
> + i2c, USB, SD/eMMC, PCIe, etc.
I2C
please.
> +
> config MSM_GCC_8994
> tristate "MSM8994 Global Clock Controller"
> help
--
~Randy
^ permalink raw reply
* Re: [PATCH v25 03/16] dt: bindings: lp50xx: Introduce the lp50xx family of RGB drivers
From: Pavel Machek @ 2020-05-31 19:06 UTC (permalink / raw)
To: Dan Murphy; +Cc: jacek.anaszewski, robh, devicetree, linux-leds, linux-kernel
In-Reply-To: <d22658c2-07e2-74e6-dc2b-4b64fd9789dd@ti.com>
[-- Attachment #1: Type: text/plain, Size: 665 bytes --]
Hi!
> > > + There can only be one instance of the ti,led-bank
> > > + property for each device node. This is a required node is the LED
> > > + modules are to be backed.
> > I don't understand the second sentence. Pretty sure it is not valid
> > english.
>
>
> If I make these changes is this still viable for 5.8 or would you then go
> into 5.9?
It really depends if we get -rc8 or not, and if you'll need to do any
changes to C code or not...
Best regards,
Pavel
--
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 195 bytes --]
^ permalink raw reply
* Re: [PATCH v2] check: Add 10bit/slave i2c reg flags support
From: Serge Semin @ 2020-05-31 19:07 UTC (permalink / raw)
To: Wolfram Sang
Cc: Serge Semin, devicetree-compiler, Alexey Malahov,
Thomas Bogendoerfer, Jarkko Nikula, Andy Shevchenko, Frank Rowand,
Rob Herring, devicetree, linux-i2c, linux-kernel
In-Reply-To: <20200530093152.GA1038@ninjato>
On Sat, May 30, 2020 at 11:31:52AM +0200, Wolfram Sang wrote:
>
> > + addr = reg & 0x3FFFFFFFU;
> > + snprintf(unit_addr, sizeof(unit_addr), "%x", addr);
>
> Hmm, this hardcoded value will not work if we ever need to add another
> bit. I hope this will never happen, though.
>
> > + if ((reg & (1U << 31)) && addr > 0x3ff)
>
> Same here with bit 31.
I'd be glad to use a macro or some helper here, but alas there is no
ready-to-use i2c-related one in the dtc code. See, there are hard-coded
literals in the PCI nodes checkers (check_pci_device_reg(),
check_pci_device_bus_num()) and the hard-coded literals've been in the
i2c-nodes checkers even before this patch.
> I haven't checked DTC but can't we import the
> header with the defines into the project? Or is this then a circular
> dependency?
>
I guess importing header would be much better than the hard-coded values
currently used. What do the code maintainers say about that? Any idea how it
is supposed to be implemented?
-Sergey
^ permalink raw reply
* Re: [PATCH v2 1/4] iio: chemical: scd30: add core driver
From: Tomasz Duszynski @ 2020-05-31 19:21 UTC (permalink / raw)
To: Jonathan Cameron
Cc: Tomasz Duszynski, linux-iio, linux-kernel, devicetree, robh+dt,
andy.shevchenko, pmeerw
In-Reply-To: <20200531105840.27e17f3d@archlinux>
On Sun, May 31, 2020 at 10:58:40AM +0100, Jonathan Cameron wrote:
> On Sat, 30 May 2020 23:36:27 +0200
> Tomasz Duszynski <tomasz.duszynski@octakon.com> wrote:
>
> > Add Sensirion SCD30 carbon dioxide core driver.
> >
> > Signed-off-by: Tomasz Duszynski <tomasz.duszynski@octakon.com>
>
> Hi Tomasz
>
> A few things inline. Includes the alignment issue on
> x86_32 that I fell into whilst trying to fix timestamp
> alignment issues. Suggested resolution inline for that.
>
> Thanks,
>
> Jonathan
>
> > ---
> > Documentation/ABI/testing/sysfs-bus-iio-scd30 | 20 +
> > MAINTAINERS | 6 +
> > drivers/iio/chemical/Kconfig | 11 +
> > drivers/iio/chemical/Makefile | 1 +
> > drivers/iio/chemical/scd30.h | 75 ++
> > drivers/iio/chemical/scd30_core.c | 764 ++++++++++++++++++
> > 6 files changed, 877 insertions(+)
> > create mode 100644 Documentation/ABI/testing/sysfs-bus-iio-scd30
> > create mode 100644 drivers/iio/chemical/scd30.h
> > create mode 100644 drivers/iio/chemical/scd30_core.c
> >
> > diff --git a/Documentation/ABI/testing/sysfs-bus-iio-scd30 b/Documentation/ABI/testing/sysfs-bus-iio-scd30
> > new file mode 100644
> > index 000000000000..a05b1d28e94a
> > --- /dev/null
> > +++ b/Documentation/ABI/testing/sysfs-bus-iio-scd30
> > @@ -0,0 +1,20 @@
> > +What: /sys/bus/iio/devices/iio:deviceX/calibration
> > +Date: June 2020
> > +KernelVersion: 5.8
> > +Contact: linux-iio@vger.kernel.org
> > +Description:
> > + Contaminants build-up in the measurement chamber or optical
> > + elements deterioration leads to sensor drift.
> > +
> > + One can compensate for sensor drift by using either automatic
> > + self calibration (asc) or forced recalibration (frc). If used
> > + at once one will overwrite the other.
> > +
> > + Writing 1 or 0 to this attribute will respectively activate or
> > + deactivate asc.
> > +
> > + Picking value from the range [400 1 2000] and writing it to the
> > + sensor will set frc.
> Seems to me like this would be more intuitive as two separate parameters
> perhaps:
> calibration_auto_enable
> calibration_forced_value
> ?
>
Fine.
> > +
> > + Upon reading current asc status and frc value are returned
> > + respectively.
> > diff --git a/MAINTAINERS b/MAINTAINERS
> > index 60ed2963efaa..41a509cca6f1 100644
> > --- a/MAINTAINERS
> > +++ b/MAINTAINERS
> > @@ -15137,6 +15137,12 @@ S: Maintained
> > F: drivers/misc/phantom.c
> > F: include/uapi/linux/phantom.h
> >
> > +SENSIRION SCD30 CARBON DIOXIDE SENSOR DRIVER
> > +M: Tomasz Duszynski <tomasz.duszynski@octakon.com>
> > +S: Maintained
> > +F: drivers/iio/chemical/scd30.h
> > +F: drivers/iio/chemical/scd30_core.c
> > +
> > SENSIRION SPS30 AIR POLLUTION SENSOR DRIVER
> > M: Tomasz Duszynski <tduszyns@gmail.com>
> > S: Maintained
> > diff --git a/drivers/iio/chemical/Kconfig b/drivers/iio/chemical/Kconfig
> > index 7f21afd73b1c..99e852b67e55 100644
> > --- a/drivers/iio/chemical/Kconfig
> > +++ b/drivers/iio/chemical/Kconfig
> > @@ -85,6 +85,17 @@ config PMS7003
> > To compile this driver as a module, choose M here: the module will
> > be called pms7003.
> >
> > +config SCD30_CORE
> > + tristate "SCD30 carbon dioxide sensor driver"
> > + select IIO_BUFFER
> > + select IIO_TRIGGERED_BUFFER
> > + help
> > + Say Y here to build support for the Sensirion SCD30 sensor with carbon
> > + dioxide, relative humidity and temperature sensing capabilities.
> > +
> > + To compile this driver as a module, choose M here: the module will
> > + be called scd30_core.
> > +
> > config SENSIRION_SGP30
> > tristate "Sensirion SGPxx gas sensors"
> > depends on I2C
> > diff --git a/drivers/iio/chemical/Makefile b/drivers/iio/chemical/Makefile
> > index aba4167db745..c9804b041ecd 100644
> > --- a/drivers/iio/chemical/Makefile
> > +++ b/drivers/iio/chemical/Makefile
> > @@ -12,6 +12,7 @@ obj-$(CONFIG_BME680_SPI) += bme680_spi.o
> > obj-$(CONFIG_CCS811) += ccs811.o
> > obj-$(CONFIG_IAQCORE) += ams-iaq-core.o
> > obj-$(CONFIG_PMS7003) += pms7003.o
> > +obj-$(CONFIG_SCD30_CORE) += scd30_core.o
> > obj-$(CONFIG_SENSIRION_SGP30) += sgp30.o
> > obj-$(CONFIG_SPS30) += sps30.o
> > obj-$(CONFIG_VZ89X) += vz89x.o
> > diff --git a/drivers/iio/chemical/scd30.h b/drivers/iio/chemical/scd30.h
> > new file mode 100644
> > index 000000000000..9b25f7423142
> > --- /dev/null
> > +++ b/drivers/iio/chemical/scd30.h
> > @@ -0,0 +1,75 @@
> > +/* SPDX-License-Identifier: GPL-2.0 */
> > +#ifndef _SCD30_H
> > +#define _SCD30_H
> > +
> > +#include <linux/completion.h>
> > +#include <linux/device.h>
> > +#include <linux/mutex.h>
> > +#include <linux/pm.h>
> > +#include <linux/regulator/consumer.h>
> > +#include <linux/types.h>
> > +
> > +struct scd30_state;
> > +
> > +enum scd30_cmd {
> > + /* start continuous measurement with pressure compensation */
> > + CMD_START_MEAS,
> > + /* stop continuous measurement */
> > + CMD_STOP_MEAS,
> > + /* set/get measurement interval */
> > + CMD_MEAS_INTERVAL,
> > + /* check whether new measurement is ready */
> > + CMD_MEAS_READY,
> > + /* get measurement */
> > + CMD_READ_MEAS,
> > + /* turn on/off automatic self calibration */
> > + CMD_ASC,
> > + /* set/get forced recalibration value */
> > + CMD_FRC,
> > + /* set/get temperature offset */
> > + CMD_TEMP_OFFSET,
> > + /* get firmware version */
> > + CMD_FW_VERSION,
> > + /* reset sensor */
> > + CMD_RESET,
> > + /*
> > + * Command for altitude compensation was omitted intentionally because
> > + * the same can be achieved by means of CMD_START_MEAS which takes
> > + * pressure above the sea level as an argument.
> > + */
> > +};
> > +
> > +#define SCD30_MEAS_COUNT 3
> > +
> > +typedef int (*scd30_command_t)(struct scd30_state *state, enum scd30_cmd cmd,
> > + u16 arg, void *response, int size);
> > +
> > +struct scd30_state {
> > + /* serialize access to the device */
> > + struct mutex lock;
> > + struct device *dev;
> > + struct regulator *vdd;
> > + struct completion meas_ready;
> > + void *priv;
> > + int irq;
> > + /*
> > + * no way to retrieve current ambient pressure compensation value from
> > + * the sensor so keep one around
> > + */
> > + u16 pressure_comp;
> > + u16 meas_interval;
> > + int meas[SCD30_MEAS_COUNT];
> > +
> > + scd30_command_t command;
> > +};
> > +
> > +int scd30_suspend(struct device *dev);
> > +int scd30_resume(struct device *dev);
> > +
> > +static __maybe_unused SIMPLE_DEV_PM_OPS(scd30_pm_ops, scd30_suspend,
> > + scd30_resume);
> > +
> > +int scd30_probe(struct device *dev, int irq, const char *name, void *priv,
> > + scd30_command_t command);
> > +
> > +#endif
> > diff --git a/drivers/iio/chemical/scd30_core.c b/drivers/iio/chemical/scd30_core.c
> > new file mode 100644
> > index 000000000000..3b7d0a7ea7ae
> > --- /dev/null
> > +++ b/drivers/iio/chemical/scd30_core.c
> > @@ -0,0 +1,764 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +/*
> > + * Sensirion SCD30 carbon dioxide sensor core driver
> > + *
> > + * Copyright (c) 2020 Tomasz Duszynski <tomasz.duszynski@octakon.com>
> > + */
> > +#include <linux/bits.h>
> > +#include <linux/completion.h>
> > +#include <linux/delay.h>
> > +#include <linux/device.h>
> > +#include <linux/errno.h>
> > +#include <linux/export.h>
> > +#include <linux/iio/buffer.h>
> > +#include <linux/iio/iio.h>
> > +#include <linux/iio/sysfs.h>
> > +#include <linux/iio/trigger.h>
> > +#include <linux/iio/trigger_consumer.h>
> > +#include <linux/iio/triggered_buffer.h>
> > +#include <linux/iio/types.h>
> > +#include <linux/interrupt.h>
> > +#include <linux/irqreturn.h>
> > +#include <linux/jiffies.h>
> > +#include <linux/kernel.h>
> > +#include <linux/module.h>
> > +#include <linux/mutex.h>
> > +#include <linux/regulator/consumer.h>
> > +#include <linux/string.h>
> > +#include <linux/sysfs.h>
> > +#include <linux/types.h>
> > +#include <asm/byteorder.h>
> > +
> > +#include "scd30.h"
> > +
> > +#define SCD30_PRESSURE_COMP_MIN_MBAR 700
> > +#define SCD30_PRESSURE_COMP_MAX_MBAR 1400
> > +#define SCD30_PRESSURE_COMP_DEFAULT 1013
> > +#define SCD30_MEAS_INTERVAL_MIN_S 2
> > +#define SCD30_MEAS_INTERVAL_MAX_S 1800
> > +#define SCD30_MEAS_INTERVAL_DEFAULT SCD30_MEAS_INTERVAL_MIN_S
> > +#define SCD30_FRC_MIN_PPM 400
> > +#define SCD30_FRC_MAX_PPM 2000
> > +#define SCD30_TEMP_OFFSET_MAX 655360
> > +#define SCD30_EXTRA_TIMEOUT_PER_S 250
> > +
> > +enum {
> > + SCD30_CONC,
> > + SCD30_TEMP,
> > + SCD30_HR,
> > +};
> > +
> > +static int scd30_command_write(struct scd30_state *state, enum scd30_cmd cmd,
> > + u16 arg)
> > +{
> > + return state->command(state, cmd, arg, NULL, 0);
> > +}
> > +
> > +static int scd30_command_read(struct scd30_state *state, enum scd30_cmd cmd,
> > + u16 *val)
> > +{
> > + int ret;
> > +
> > + ret = state->command(state, cmd, 0, val, sizeof(*val));
> > + *val = be16_to_cpup((__be16 *)val);
>
> Please use a local variable for the __be16 as it makes thing more readable
> and easier to check for endian problems.
>
Okay.
> > +
> > + return ret;
> > +}
> > +
> > +static int scd30_reset(struct scd30_state *state)
> > +{
> > + int ret;
> > + u16 val;
> > +
> > + ret = scd30_command_write(state, CMD_RESET, 0);
> > + if (ret)
> > + return ret;
> > +
> > + /* sensor boots up within 2 secs */
> > + msleep(2000);
> > + /*
> > + * Power-on-reset causes sensor to produce some glitch on i2c bus and
> > + * some controllers end up in error state. Try to recover by placing
> > + * any data on the bus.
> > + */
> > + scd30_command_read(state, CMD_MEAS_READY, &val);
> > +
> > + return 0;
> > +}
> > +
> > +/* simplified float to fixed point conversion with a scaling factor of 0.01 */
> > +static int scd30_float_to_fp(int float32)
> > +{
> > + int fraction, shift,
> > + mantissa = float32 & GENMASK(22, 0),
> > + sign = float32 & BIT(31) ? -1 : 1,
> > + exp = (float32 & ~BIT(31)) >> 23;
> > +
> > + /* special case 0 */
> > + if (!exp && !mantissa)
> > + return 0;
> > +
> > + exp -= 127;
> > + if (exp < 0) {
> > + exp = -exp;
> > + /* return values ranging from 1 to 99 */
> > + return sign * ((((BIT(23) + mantissa) * 100) >> 23) >> exp);
> > + }
> > +
> > + /* return values starting at 100 */
> > + shift = 23 - exp;
> > + float32 = BIT(exp) + (mantissa >> shift);
> > + fraction = mantissa & GENMASK(shift - 1, 0);
> > +
> > + return sign * (float32 * 100 + ((fraction * 100) >> shift));
> > +}
> > +
> > +static int scd30_read_meas(struct scd30_state *state)
> > +{
> > + int i, ret;
> > +
> > + ret = state->command(state, CMD_READ_MEAS, 0, state->meas,
> > + sizeof(state->meas));
> > + if (ret)
> > + return ret;
> > +
> > + be32_to_cpu_array(state->meas, state->meas, ARRAY_SIZE(state->meas));
> > +
> > + for (i = 0; i < ARRAY_SIZE(state->meas); i++)
> > + state->meas[i] = scd30_float_to_fp(state->meas[i]);
> > +
> > + return 0;
> > +}
> > +
> > +static int scd30_wait_meas_irq(struct scd30_state *state)
> > +{
> > + int ret, timeout;
> > +
> > + timeout = state->meas_interval * (1000 + SCD30_EXTRA_TIMEOUT_PER_S);
> > + timeout = msecs_to_jiffies(timeout);
> > + reinit_completion(&state->meas_ready);
> > + enable_irq(state->irq);
> > + ret = wait_for_completion_interruptible_timeout(&state->meas_ready,
> > + timeout);
> > + if (ret > 0)
> > + ret = 0;
> > + else if (!ret)
> > + ret = -ETIMEDOUT;
> > +
> > + disable_irq(state->irq);
> > +
> > + return ret;
> > +}
> > +
> > +static int scd30_wait_meas_poll(struct scd30_state *state)
> > +{
> > + int timeout = state->meas_interval * SCD30_EXTRA_TIMEOUT_PER_S;
> > + int tries = 5;
> > +
> > + do {
> > + int ret;
> > + u16 val;
> > +
> > + ret = scd30_command_read(state, CMD_MEAS_READY, &val);
> > + if (ret)
> > + return -EIO;
> > +
> > + /* new measurement available */
> > + if (val)
> > + break;
> > +
> > + msleep_interruptible(timeout);
> > + } while (--tries);
> > +
> > + return tries ? 0 : -ETIMEDOUT;
> > +}
> > +
> > +static int scd30_read_poll(struct scd30_state *state)
> > +{
> > + int ret;
> > +
> > + ret = scd30_wait_meas_poll(state);
> > + if (ret)
> > + return ret;
> > +
> > + return scd30_read_meas(state);
> > +}
> > +
> > +static int scd30_read(struct scd30_state *state)
> > +{
> > + if (state->irq > 0)
> > + return scd30_wait_meas_irq(state);
> > +
> > + return scd30_read_poll(state);
> > +}
> > +
> > +static int scd30_read_raw(struct iio_dev *indio_dev,
> > + struct iio_chan_spec const *chan,
> > + int *val, int *val2, long mask)
> > +{
> > + struct scd30_state *state = iio_priv(indio_dev);
> > + int ret, meas[SCD30_MEAS_COUNT];
> > +
> > + switch (mask) {
> > + case IIO_CHAN_INFO_RAW:
> > + case IIO_CHAN_INFO_PROCESSED:
> > + ret = iio_device_claim_direct_mode(indio_dev);
> > + if (ret)
> > + return ret;
> > +
> > + mutex_lock(&state->lock);
> > + ret = scd30_read(state);
> > + memcpy(meas, state->meas, SCD30_MEAS_COUNT * sizeof(*meas));
>
> The local copy seems a bit excessive. This isn't likely to be a particularly
> fast path so perhaps skip the copy but hold the locks until we are
> done with the buffer?
>
Okay.
> > + mutex_unlock(&state->lock);
> > + iio_device_release_direct_mode(indio_dev);
> > + if (ret)
> > + return ret;
> > +
> > + switch (chan->type) {
> > + case IIO_CONCENTRATION:
> > + *val = meas[chan->address] / 1000000;
> > + *val2 = meas[chan->address] % 1000000;
> > +
> > + return IIO_VAL_INT_PLUS_MICRO;
> > + case IIO_TEMP:
> > + case IIO_HUMIDITYRELATIVE:
> > + *val = meas[chan->address] * 10;
> > +
> > + return IIO_VAL_INT;
> > + default:
> > + return -EINVAL;
> > + }
> > + case IIO_CHAN_INFO_SCALE:
> > + switch (chan->type) {
> > + case IIO_CONCENTRATION:
> > + *val = 0;
> > + *val2 = 1;
> > +
> > + return IIO_VAL_INT_PLUS_MICRO;
> > + case IIO_TEMP:
> > + case IIO_HUMIDITYRELATIVE:
> > + *val = 10;
> > +
> > + return IIO_VAL_INT;
> > + default:
> > + return -EINVAL;
> > + }
> > + case IIO_CHAN_INFO_SAMP_FREQ:
> > + *val = 0;
> > + *val2 = 0;
> > +
> > + mutex_lock(&state->lock);
> > + ret = scd30_command_read(state, CMD_MEAS_INTERVAL, (u16 *)val2);
>
> See below. I'll assume you'll fix all of these.
>
> > + mutex_unlock(&state->lock);
> > + if (ret)
> > + return ret;
> > +
> > + *val2 = 1000000000 / *val2;
> > +
> > + return IIO_VAL_INT_PLUS_NANO;
> > + case IIO_CHAN_INFO_CALIBSCALE:
> > + mutex_lock(&state->lock);
> > + *val = state->pressure_comp / 10;
> > + *val2 = (state->pressure_comp % 10) * 100000;
> > + mutex_unlock(&state->lock);
> > +
> > + return IIO_VAL_INT_PLUS_MICRO;
> > + case IIO_CHAN_INFO_CALIBBIAS:
> > + *val = 0;
> > + mutex_lock(&state->lock);
> > + ret = scd30_command_read(state, CMD_TEMP_OFFSET, (u16 *)val);
>
> Reading a u16 directly into a int is not a good idea. What you get will
> depend on the endianness of the machine.
>
Right, that would obviously break on BE. Sometimes trying to keep number
of local variables low simply stops paying off :).
> Use an intermediate variable of the right size.
>
> > + mutex_unlock(&state->lock);
> > +
> > + return IIO_VAL_INT;
> > + }
> > +
> > + return -EINVAL;
> > +}
> > +
> > +static int scd30_write_raw(struct iio_dev *indio_dev,
> > + struct iio_chan_spec const *chan,
> > + int val, int val2, long mask)
> > +{
> > + struct scd30_state *state = iio_priv(indio_dev);
> > + int ret = -EINVAL;
> > +
> > + mutex_lock(&state->lock);
> > + switch (mask) {
> > + case IIO_CHAN_INFO_SAMP_FREQ:
> > + if (val)
> > + break;
> > +
> > + val = 1000000000 / val2;
> > + if (val < SCD30_MEAS_INTERVAL_MIN_S ||
> > + val > SCD30_MEAS_INTERVAL_MAX_S)
> > + break;
> > +
> > + ret = scd30_command_write(state, CMD_MEAS_INTERVAL, val);
> > + if (ret)
> > + break;
> > +
> > + state->meas_interval = val;
> > + break;
> > + case IIO_CHAN_INFO_CALIBSCALE:
> > + val = (val * 1000000 + val2) / 100000;
> > + if (val < SCD30_PRESSURE_COMP_MIN_MBAR ||
> > + val > SCD30_PRESSURE_COMP_MAX_MBAR)
> > + break;
> > +
> > + ret = scd30_command_write(state, CMD_START_MEAS, val);
> > + if (ret)
> > + break;
> > +
> > + state->pressure_comp = val;
> > + break;
> > + case IIO_CHAN_INFO_CALIBBIAS:
> > + if (val < 0 || val > SCD30_TEMP_OFFSET_MAX)
> > + break;
> > + /*
> > + * Manufacturer does not explicitly specify min/max sensible
> > + * values hence check is omitted for simplicity.
> > + */
> > + ret = scd30_command_write(state, CMD_TEMP_OFFSET / 10, val);
> > + }
> > + mutex_unlock(&state->lock);
> > +
> > + return ret;
> > +}
> > +
> > +static int scd30_write_raw_get_fmt(struct iio_dev *indio_dev,
> > + struct iio_chan_spec const *chan, long mask)
> > +{
> > + switch (mask) {
> > + case IIO_CHAN_INFO_RAW:
> > + case IIO_CHAN_INFO_CALIBBIAS:
> > + return IIO_VAL_INT;
> > + case IIO_CHAN_INFO_CALIBSCALE:
> > + return IIO_VAL_INT_PLUS_MICRO;
> > + case IIO_CHAN_INFO_SAMP_FREQ:
> > + return IIO_VAL_INT_PLUS_NANO;
> > + }
> > +
> > + return -EINVAL;
> > +}
> > +
> > +static const int scd30_pressure_calibscale_available[] = {
> > + SCD30_PRESSURE_COMP_MIN_MBAR / 10, 0,
> > + 0, 100000,
> > + SCD30_PRESSURE_COMP_MAX_MBAR / 10, 0,
> > +};
> > +
> > +static const int scd30_temp_calibbias_available[] = {
> > + 0, 10, SCD30_TEMP_OFFSET_MAX,
> > +};
> > +
> > +static int scd30_read_avail(struct iio_dev *indio_dev,
> > + struct iio_chan_spec const *chan, const int **vals,
> > + int *type, int *length, long mask)
> > +{
> > + switch (mask) {
> > + case IIO_CHAN_INFO_CALIBSCALE:
> > + *vals = scd30_pressure_calibscale_available;
> > + *type = IIO_VAL_INT_PLUS_MICRO;
> > +
> > + return IIO_AVAIL_RANGE;
> > + case IIO_CHAN_INFO_CALIBBIAS:
> > + *vals = scd30_temp_calibbias_available;
> > + *type = IIO_VAL_INT;
> > +
> > + return IIO_AVAIL_RANGE;
> > + }
> > +
> > + return -EINVAL;
> > +}
> > +
> > +static ssize_t sampling_frequency_available_show(struct device *dev,
> > + struct device_attribute *attr,
> > + char *buf)
> > +{
> > + int i = SCD30_MEAS_INTERVAL_MIN_S;
> > + ssize_t len = 0;
> > +
> > + do {
> > + len += scnprintf(buf + len, PAGE_SIZE - len, "0.%09u ",
> > + 1000000000 / i);
> > + /*
> > + * Not all values fit PAGE_SIZE buffer hence print every 6th
> > + * (each frequency differs by 6s in time domain from the
> > + * adjecent). Unlisted but valid ones are still accepted.
>
> adjacent
>
> Hmm. Maybe we need to think about some description for inverse of linear
> cases as they are likely to be fairly common.
> This will work in meantime.
>
> > + */
> > + i += 6;
> > + } while (i <= SCD30_MEAS_INTERVAL_MAX_S);
> > +
> > + buf[len - 1] = '\n';
> > +
> > + return len;
> > +}
> > +
> > +static ssize_t calibration_show(struct device *dev,
> > + struct device_attribute *attr, char *buf)
> > +{
> > + struct iio_dev *indio_dev = dev_to_iio_dev(dev);
> > + struct scd30_state *state = iio_priv(indio_dev);
> > + u16 asc, frc;
> > + int ret;
> > +
> > + mutex_lock(&state->lock);
> > + ret = scd30_command_read(state, CMD_ASC, &asc);
> > + if (ret)
> > + goto out;
> > +
> > + ret = scd30_command_read(state, CMD_FRC, &frc);
> > +out:
> > + mutex_unlock(&state->lock);
> > +
> > + return ret ?: sprintf(buf, "%d %d\n", asc, frc);
> > +}
> > +
> > +static ssize_t calibration_store(struct device *dev,
> > + struct device_attribute *attr, const char *buf,
> > + size_t len)
> > +{
> > + struct iio_dev *indio_dev = dev_to_iio_dev(dev);
> > + struct scd30_state *state = iio_priv(indio_dev);
> > + int ret;
> > + u16 val;
>
> As commented above, this interface doesn't win on the
> obvious front so needs a rethink!
>
> > +
> > + ret = kstrtou16(buf, 0, &val);
> > + if (ret)
> > + return ret;
> > +
> > + mutex_lock(&state->lock);
> > + if (val == 0 || val == 1)
> > + ret = scd30_command_write(state, CMD_ASC, val);
> > + else if (val >= SCD30_FRC_MIN_PPM && val <= SCD30_FRC_MAX_PPM)
> > + ret = scd30_command_write(state, CMD_FRC, val);
> > + else
> > + ret = -EINVAL;
> > + mutex_unlock(&state->lock);
> > +
> > + return ret ?: len;
> > +}
> > +
> > +static IIO_DEVICE_ATTR_RO(sampling_frequency_available, 0);
> > +static IIO_DEVICE_ATTR_RW(calibration, 0);
> > +
> > +static struct attribute *scd30_attrs[] = {
> > + &iio_dev_attr_sampling_frequency_available.dev_attr.attr,
> > + &iio_dev_attr_calibration.dev_attr.attr,
> > + NULL
> > +};
> > +
> > +static const struct attribute_group scd30_attr_group = {
> > + .attrs = scd30_attrs,
> > +};
> > +
> > +static const struct iio_info scd30_info = {
> > + .attrs = &scd30_attr_group,
> > + .read_raw = scd30_read_raw,
> > + .write_raw = scd30_write_raw,
> > + .write_raw_get_fmt = scd30_write_raw_get_fmt,
> > + .read_avail = scd30_read_avail,
> > +};
> > +
> > +#define SCD30_CHAN_SCAN_TYPE(_sign, _realbits) .scan_type = { \
> > + .sign = _sign, \
> > + .realbits = _realbits, \
> > + .storagebits = 32, \
> > + .endianness = IIO_CPU, \
> > +}
> > +
> > +static const struct iio_chan_spec scd30_channels[] = {
> > + {
> > + .type = IIO_PRESSURE,
> > + .info_mask_separate = BIT(IIO_CHAN_INFO_CALIBSCALE),
> > + .info_mask_separate_available = BIT(IIO_CHAN_INFO_CALIBSCALE),
> > + .scan_index = -1,
> > + },
> > + {
> > + .type = IIO_CONCENTRATION,
> > + .channel2 = IIO_MOD_CO2,
> > + .address = SCD30_CONC,
> > + .scan_index = SCD30_CONC,
> > + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
> > + BIT(IIO_CHAN_INFO_SCALE),
> > + .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ),
> > + .modified = 1,
> > +
> > + SCD30_CHAN_SCAN_TYPE('u', 16),
> > + },
> > + {
> > + .type = IIO_TEMP,
> > + .address = SCD30_TEMP,
> > + .scan_index = SCD30_TEMP,
> > + .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED) |
> > + BIT(IIO_CHAN_INFO_CALIBBIAS) |
> > + BIT(IIO_CHAN_INFO_SCALE),
>
> Combination of processed and scale is unusual. Normally scale provides
> a conversion factor or a _RAW reading.
Right that's pointless. Scales were for raw measurements inside buffer.
Somehow I failed to realize that only co2 concentration is raw.
>
> I 'think' these units are otherwise fine (milli degrees centigrade)
>
>
> > + .info_mask_separate_available = BIT(IIO_CHAN_INFO_CALIBBIAS),
> > + .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ),
> > +
> > + SCD30_CHAN_SCAN_TYPE('s', 14),
> > + },
> > + {
> > + .type = IIO_HUMIDITYRELATIVE,
> > + .address = SCD30_HR,
> > + .scan_index = SCD30_HR,
> > + .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED) |
> > + BIT(IIO_CHAN_INFO_SCALE),
>
> As above. Not normal to see scale and processed.
>
> > + .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ),
> > +
> > + SCD30_CHAN_SCAN_TYPE('u', 14),
> > + },
> > + IIO_CHAN_SOFT_TIMESTAMP(3),
> > +};
> > +
> > +int __maybe_unused scd30_suspend(struct device *dev)
> > +{
> > + struct iio_dev *indio_dev = dev_get_drvdata(dev);
> > + struct scd30_state *state = iio_priv(indio_dev);
> > + int ret;
> > +
> > + ret = scd30_command_write(state, CMD_STOP_MEAS, 0);
> > + if (ret)
> > + return ret;
> > +
> > + return regulator_disable(state->vdd);
> > +}
> > +EXPORT_SYMBOL(scd30_suspend);
> > +
> > +int __maybe_unused scd30_resume(struct device *dev)
> > +{
> > + struct iio_dev *indio_dev = dev_get_drvdata(dev);
> > + struct scd30_state *state = iio_priv(indio_dev);
> > + int ret;
> > +
> > + ret = regulator_enable(state->vdd);
> > + if (ret)
> > + return ret;
> > +
> > + return scd30_command_write(state, CMD_START_MEAS, state->pressure_comp);
> > +}
> > +EXPORT_SYMBOL(scd30_resume);
> > +
> > +static void scd30_stop_meas(void *data)
> > +{
> > + struct scd30_state *state = data;
> > +
> > + scd30_command_write(state, CMD_STOP_MEAS, 0);
> > +}
> > +
> > +static void scd30_disable_regulator(void *data)
> > +{
> > + struct scd30_state *state = data;
> > +
> > + regulator_disable(state->vdd);
> > +}
> > +
> > +static irqreturn_t scd30_irq_handler(int irq, void *priv)
> > +{
> > + struct iio_dev *indio_dev = priv;
> > +
> > + if (iio_buffer_enabled(indio_dev)) {
>
> There is a potential quirk here. It's possible that
> this device is using a different trigger, but another device
> is registered to use this one. If that happens this check
> will be a bit counter intuitive.
>
> As such you might want to provide the validate callback so
> that this device is the only device allowed to use it's
> own trigger.
>
Right. This needs to be fixed.
> > + iio_trigger_poll(indio_dev->trig);
> > +
> > + return IRQ_HANDLED;
> > + }
> > +
> > + return IRQ_WAKE_THREAD;
> > +}
> > +
> > +static irqreturn_t scd30_irq_thread_handler(int irq, void *priv)
> > +{
> > + struct iio_dev *indio_dev = priv;
> > + struct scd30_state *state = iio_priv(indio_dev);
> > + int ret;
> > +
> > + ret = scd30_read_meas(state);
> > + if (ret)
> > + goto out;
> > +
> > + complete_all(&state->meas_ready);
> > +out:
> > + return IRQ_HANDLED;
> > +}
> > +
> > +static irqreturn_t scd30_trigger_handler(int irq, void *p)
> > +{
> > + struct iio_poll_func *pf = p;
> > + struct iio_dev *indio_dev = pf->indio_dev;
> > + struct scd30_state *state = iio_priv(indio_dev);
> > + struct {
> > + int data[SCD30_MEAS_COUNT];
> > + u64 ts;
>
> Turns out I was wrong when suggesting this approach for drivers. On x86_32
> this will result in there not being any padding between the
> data and the timestamp (and in IIO rule of naturally aligned there
> needs to be 4 bytes there). Result is that this structure is
> too short. (thanks btw to Andy who pointed out this issue!)
>
> So, to force that my current preference is.
>
> struct {
> int data[SCD30_MEAS_COUNT];
> s64 ts __aligned(8);
> } scan;
>
Ah, so x86_32 aligns s64 to 4 bytes.
> However, given we do have a hole in the structure there is
> a kernel data leak. So either you need to zero it here,
> or move it into the iio_priv() structure. Doing that
> will ensure it is zeroed at allocation.
>
> > + } scan;
> > + int ret;
> > +
> > + mutex_lock(&state->lock);
> > + if (!iio_trigger_using_own(indio_dev))
> > + ret = scd30_read_poll(state);
> > + else
> > + ret = scd30_read_meas(state);
> > + memcpy(scan.data, state->meas, sizeof(state->meas));
> > + mutex_unlock(&state->lock);
> > + if (ret)
> > + goto out;
> > +
> > + iio_push_to_buffers_with_timestamp(indio_dev, &scan,
> > + iio_get_time_ns(indio_dev));
> > +out:
> > + iio_trigger_notify_done(indio_dev->trig);
> > + return IRQ_HANDLED;
> > +}
> > +
> > +static int scd30_set_trigger_state(struct iio_trigger *trig, bool state)
> > +{
> > + struct iio_dev *indio_dev = iio_trigger_get_drvdata(trig);
> > + struct scd30_state *st = iio_priv(indio_dev);
> > +
> > + if (state)
> > + enable_irq(st->irq);
> > + else
> > + disable_irq(st->irq);
> > +
> > + return 0;
> > +}
> > +
> > +static const struct iio_trigger_ops scd30_trigger_ops = {
> > + .set_trigger_state = scd30_set_trigger_state,
> > +};
> > +
> > +static int scd30_setup_trigger(struct iio_dev *indio_dev)
> > +{
> > + struct scd30_state *state = iio_priv(indio_dev);
> > + struct device *dev = indio_dev->dev.parent;
> > + struct iio_trigger *trig;
> > + int ret;
> > +
> > + trig = devm_iio_trigger_alloc(dev, "%s-dev%d", indio_dev->name,
> > + indio_dev->id);
> > + if (!trig) {
> > + dev_err(dev, "failed to allocate trigger\n");
> > + return -ENOMEM;
> > + }
> > +
> > + trig->dev.parent = dev;
> > + trig->ops = &scd30_trigger_ops;
> > + iio_trigger_set_drvdata(trig, indio_dev);
> > +
> > + ret = devm_iio_trigger_register(dev, trig);
> > + if (ret)
> > + return ret;
> > +
> > + indio_dev->trig = iio_trigger_get(trig);
> > +
> > + ret = devm_request_threaded_irq(dev, state->irq, scd30_irq_handler,
> > + scd30_irq_thread_handler,
> > + IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
> > + indio_dev->name, indio_dev);
> > + if (ret)
> > + dev_err(dev, "failed to request irq\n");
> > +
> > + disable_irq(state->irq);
>
> Given there is a gap between the request above and this disable, this
> disable needs a comment explaining why it is here.
>
> I'm assuming it's an optimization?
>
Interrupt is enabled just before taking measurement to grab the fresh
data and disabled afterwards. Not disabling it here would produce fat warning
about unbalanced irqs.
And that is because sensor takes measurements continuously. On demand
mode, even though possible, doesn't work reliably. Sensor (at least the one
sitting on my desk) needs way too much time to wakeup and grab measurement which
makes the whole point of adjustable sampling frequency pointless :).
> > +
> > + return ret;
> > +}
> > +
> > +int scd30_probe(struct device *dev, int irq, const char *name, void *priv,
> > + scd30_command_t command)
> > +{
> > + static const unsigned long scd30_scan_masks[] = { 0x07, 0x00 };
> > + struct scd30_state *state;
> > + struct iio_dev *indio_dev;
> > + int ret;
> > + u16 val;
> > +
> > + indio_dev = devm_iio_device_alloc(dev, sizeof(*state));
> > + if (!indio_dev)
> > + return -ENOMEM;
> > +
> > + state = iio_priv(indio_dev);
> > + state->dev = dev;
>
> Doesn't seem to be used.
>
> > + state->priv = priv;
>
> What's this for? At least at first glance I can't find it being used
> anywhere.
>
> > + state->irq = irq;
> > + state->pressure_comp = SCD30_PRESSURE_COMP_DEFAULT;
> > + state->meas_interval = SCD30_MEAS_INTERVAL_DEFAULT;
> > + state->command = command;
> > + mutex_init(&state->lock);
> > + init_completion(&state->meas_ready);
> > +
> > + dev_set_drvdata(dev, indio_dev);
> > +
> > + indio_dev->dev.parent = dev;
>
> Side note that there is a series moving this into the core under revision at
> the moment. Hopefully I'll remember to fix this up when applying your patch
> if that one has gone in ahead of it.
>
> > + indio_dev->info = &scd30_info;
> > + indio_dev->name = name;
> > + indio_dev->channels = scd30_channels;
> > + indio_dev->num_channels = ARRAY_SIZE(scd30_channels);
> > + indio_dev->modes = INDIO_DIRECT_MODE;
> > + indio_dev->available_scan_masks = scd30_scan_masks;
> > +
> > + state->vdd = devm_regulator_get(dev, "vdd");
> > + if (IS_ERR(state->vdd)) {
> > + if (PTR_ERR(state->vdd) == -EPROBE_DEFER)
> > + return -EPROBE_DEFER;
> > +
> > + dev_err(dev, "failed to get regulator\n");
> > + return PTR_ERR(state->vdd);
> > + }
> > +
> > + ret = regulator_enable(state->vdd);
> > + if (ret)
> > + return ret;
> > +
> > + ret = devm_add_action_or_reset(dev, scd30_disable_regulator, state);
> > + if (ret)
> > + return ret;
> > +
>
> A comment here on why it makes sense to register this here. What
> started mesurement? It seems that happens well below here so
> we should really call this after that start all.
>
Sensor after being powered up starts in mode it was left in.
Chances are it was continuous mode and we want to shut it down.
> > + ret = devm_add_action_or_reset(dev, scd30_stop_meas, state);
> > + if (ret)
> > + return ret;
> > +
> > + ret = scd30_reset(state);
> > + if (ret) {
> > + dev_err(dev, "failed to reset device: %d\n", ret);
> > + return ret;
> > + }
> > +
> > + if (state->irq > 0) {
> > + ret = scd30_setup_trigger(indio_dev);
> > + if (ret) {
> > + dev_err(dev, "failed to setup trigger: %d\n", ret);
> > + return ret;
> > + }
> > + }
> > +
> > + ret = devm_iio_triggered_buffer_setup(dev, indio_dev, NULL,
> > + scd30_trigger_handler, NULL);
> > + if (ret)
> > + return ret;
> > +
> > + ret = scd30_command_read(state, CMD_FW_VERSION, &val);
> > + if (ret) {
> > + dev_err(dev, "failed to read firmware version: %d\n", ret);
> > + return ret;
> > + }
> > + dev_info(dev, "firmware version: %d.%d\n", val >> 8, (char)val);
> > +
> > + ret = scd30_command_write(state, CMD_MEAS_INTERVAL,
> > + state->meas_interval);
> > + if (ret) {
> > + dev_err(dev, "failed to set measurement interval: %d\n", ret);
> > + return ret;
> > + }
> > +
> > + ret = scd30_command_write(state, CMD_START_MEAS, state->pressure_comp);
> > + if (ret) {
> > + dev_err(dev, "failed to start measurement: %d\n", ret);
> > + return ret;
> > + }
> > +
> > + return devm_iio_device_register(dev, indio_dev);
> > +}
> > +EXPORT_SYMBOL(scd30_probe);
> > +
> > +MODULE_AUTHOR("Tomasz Duszynski <tomasz.duszynski@octakon.com>");
> > +MODULE_DESCRIPTION("Sensirion SCD30 carbon dioxide sensor core driver");
> > +MODULE_LICENSE("GPL v2");
> > --
> > 2.26.2
> >
>
^ permalink raw reply
* Re: [PATCH 4/4] driver: clk: Add msm8992 GCC Kconfig and Makefile entries
From: Stephen Boyd @ 2020-05-31 19:48 UTC (permalink / raw)
To: Konrad Dybcio, Randy Dunlap
Cc: Andy Gross, Bjorn Andersson, Michael Turquette, Rob Herring,
Philipp Zabel, linux-arm-msm, linux-clk, devicetree, linux-kernel
In-Reply-To: <d5813ebc-dcb2-afc2-7a7e-71e73113f8fc@infradead.org>
Quoting Randy Dunlap (2020-05-31 10:50:26)
> On 5/31/20 10:46 AM, Konrad Dybcio wrote:
> > Signed-off-by: Konrad Dybcio <konradybcio@gmail.com>
> > ---
> > drivers/clk/qcom/Kconfig | 8 ++++++++
> > drivers/clk/qcom/Makefile | 1 +
> > 2 files changed, 9 insertions(+)
> >
> > diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig
> > index 11ec6f466467..d102b4015289 100644
> > --- a/drivers/clk/qcom/Kconfig
> > +++ b/drivers/clk/qcom/Kconfig
> > @@ -197,6 +197,14 @@ config MSM_MMCC_8974
> > Say Y if you want to support multimedia devices such as display,
> > graphics, video encode/decode, camera, etc.
> >
> > +config MSM_GCC_8992
> > + tristate "MSM8992 Global Clock Controller"
> > + select QCOM_GDSC
> > + help
> > + Support for the global clock controller on msm8992 devices.
> > + Say Y if you want to use peripheral devices such as UART, SPI,
> > + i2c, USB, SD/eMMC, PCIe, etc.
>
> I2C
> please.
Also please put someone in the "To:" field of these emails.
^ permalink raw reply
* Re: [PATCH v5 03/14] PCI: cadence: Convert all r/w accessors to perform only 32-bit accesses
From: Kishon Vijay Abraham I @ 2020-06-01 1:16 UTC (permalink / raw)
To: Rob Herring
Cc: Tom Joseph, Lorenzo Pieralisi, Bjorn Helgaas, PCI,
linux-kernel@vger.kernel.org, Arnd Bergmann, Greg Kroah-Hartman,
devicetree, linux-omap,
moderated list:ARM/FREESCALE IMX / MXC ARM ARCHITECTURE
In-Reply-To: <457db3ae-e68a-d2fc-ba5f-5393ad464413@ti.com>
Hi Rob,
On 5/28/2020 3:36 AM, Kishon Vijay Abraham I wrote:
> Hi Rob,
>
> On 5/27/2020 10:07 PM, Rob Herring wrote:
>> On Wed, May 27, 2020 at 4:49 AM Kishon Vijay Abraham I <kishon@ti.com> wrote:
>>>
>>> Hi Rob,
>>>
>>> On 5/26/2020 8:42 PM, Rob Herring wrote:
>>>> On Sun, May 24, 2020 at 9:30 PM Kishon Vijay Abraham I <kishon@ti.com> wrote:
>>>>>
>>>>> Hi Rob,
>>>>>
>>>>> On 5/22/2020 9:24 PM, Rob Herring wrote:
>>>>>> On Thu, May 21, 2020 at 9:37 PM Kishon Vijay Abraham I <kishon@ti.com> wrote:
>>>>>>>
>>>>>>> Certain platforms like TI's J721E using Cadence PCIe IP can perform only
>>>>>>> 32-bit accesses for reading or writing to Cadence registers. Convert all
>>>>>>> read and write accesses to 32-bit in Cadence PCIe driver in preparation
>>>>>>> for adding PCIe support in TI's J721E SoC.
>>>>>>
>>>>>> Looking more closely I don't think cdns_pcie_ep_assert_intx is okay
>>>>>> with this and never can be given the PCI_COMMAND and PCI_STATUS
>>>>>> registers are in the same word (IIRC, that's the main reason 32-bit
>>>>>> config space accesses are broken). So this isn't going to work at
>>>>>
>>>>> right, PCI_STATUS has write '1' to clear bits and there's a chance that it
>>>>> could be reset while raising legacy interrupt. While this cannot be avoided for
>>>>> TI's J721E, other platforms doesn't have to have this limitation.
>>>>>> least for EP accesses. And maybe you need a custom .raise_irq() hook
>>>>>> to minimize any problems (such as making the RMW atomic at least from
>>>>>> the endpoint's perspective).
>>>>>
>>>>> This is to make sure EP doesn't update in-consistent state when RC is updating
>>>>> the PCI_STATUS register? Since this involves two different systems, how do we
>>>>> make this atomic?
>>>>
>>>> You can't make it atomic WRT both systems, but is there locking around
>>>> each RMW? Specifically, are preemption and interrupts disabled to
>>>> ensure time between a read and write are minimized? You wouldn't want
>>>> interrupts disabled during the delay too though (i.e. around
>>>> .raise_irq()).
>>>
>>> Okay, I'll add spin spin_lock_irqsave() in cdns_pcie_write_sz(). As you also
>>> pointed below that delay for legacy interrupt is wrong and it has to be fixed
>>> (with a later series).
>>
>> But you don't need a lock everywhere. You need locks in the callers
>> (and only sometimes).
>
> Okay, the locks should be added only for registers where HOST can also write to
> the same register? Maybe only raise_irq then..
>
>>
>>> How do you want to handle cdns_pcie_ep_fn_writew() now? Because now we are
>>> changing the default implementation to perform only 32-bit access (used for
>>> legacy interrupt, msi-x interrupt and while writing standard headers) and it's
>>> not okay only for legacy interrupts for platforms other than TI.
>>
>> Now I'm wondering how set_msi is not racy in the current code with the
>> host setting/clearing PCI_MSI_FLAGS_ENABLE? Maybe that bit is RO from
>> the EP side?
>
> set_msi/set_msix is a one time configuration that is invoked before the host
> establishes the link with the endpoint. I don't think we have to consider this
> as racy.
Can we try to close on this discussion please?
Thanks
Kishon
>
> Thanks
> Kishon
>
>>
>> Ultimately I think you're going to have to provide your own endpoint
>> functions or you need accessors for specific registers like
>> PCI_MSI_FLAGS. Then for example, you just rely on the 2 bytes before
>> PCI_MSI_FLAGS being reserved and do a 32-bit access without a RMW.
>> Trying to abstract this at the register read/write level is going to
>> be fragile
>>
>> Rob
>>
^ permalink raw reply
* RE: [PATCH v10 10/10] arm64: dts: Add node for ufs exynos7
From: Alim Akhtar @ 2020-06-01 1:30 UTC (permalink / raw)
To: 'Krzysztof Kozlowski'
Cc: robh, devicetree, linux-scsi, avri.altman, martin.petersen,
kwmad.kim, stanley.chu, cang, linux-samsung-soc, linux-arm-kernel,
linux-kernel
In-Reply-To: <20200529080546.GB23221@kozik-lap>
> -----Original Message-----
> From: Krzysztof Kozlowski <krzk@kernel.org>
> Sent: 29 May 2020 13:36
> To: Alim Akhtar <alim.akhtar@samsung.com>
> Cc: robh@kernel.org; devicetree@vger.kernel.org; linux-scsi@vger.kernel.org;
> avri.altman@wdc.com; martin.petersen@oracle.com;
> kwmad.kim@samsung.com; stanley.chu@mediatek.com;
> cang@codeaurora.org; linux-samsung-soc@vger.kernel.org; linux-arm-
> kernel@lists.infradead.org; linux-kernel@vger.kernel.org
> Subject: Re: [PATCH v10 10/10] arm64: dts: Add node for ufs exynos7
>
> On Thu, May 28, 2020 at 06:46:58AM +0530, Alim Akhtar wrote:
> > Adding dt node foe UFS and UFS-PHY for exynos7 SoC.
> >
> > Signed-off-by: Alim Akhtar <alim.akhtar@samsung.com>
> > Tested-by: Paweł Chmiel <pawel.mikolaj.chmiel@gmail.com>
> > ---
> > .../boot/dts/exynos/exynos7-espresso.dts | 4 ++
> > arch/arm64/boot/dts/exynos/exynos7.dtsi | 43 ++++++++++++++++++-
>
> Thanks, applied to next/dt-late. It might miss this merge window and in such
> case I will keep it for v5.9 cycle.
Thanks Krzysztof.
>
> Best regards,
> Krzysztof
^ permalink raw reply
* RE: [PATCH v10 00/10] exynos-ufs: Add support for UFS HCI
From: Alim Akhtar @ 2020-06-01 1:40 UTC (permalink / raw)
To: martin.petersen, 'Kishon Vijay Abraham I'
Cc: devicetree, linux-scsi, krzk, avri.altman, kwmad.kim, stanley.chu,
cang, linux-samsung-soc, linux-arm-kernel, linux-kernel, robh
In-Reply-To: <20200528011658.71590-1-alim.akhtar@samsung.com>
> -----Original Message-----
> From: Alim Akhtar <alim.akhtar@samsung.com>
> Sent: 28 May 2020 06:47
> To: robh@kernel.org
> Cc: devicetree@vger.kernel.org; linux-scsi@vger.kernel.org; krzk@kernel.org;
> avri.altman@wdc.com; martin.petersen@oracle.com;
> kwmad.kim@samsung.com; stanley.chu@mediatek.com;
> cang@codeaurora.org; linux-samsung-soc@vger.kernel.org; linux-arm-
> kernel@lists.infradead.org; linux-kernel@vger.kernel.org; Alim Akhtar
> <alim.akhtar@samsung.com>
> Subject: [PATCH v10 00/10] exynos-ufs: Add support for UFS HCI
>
> This patch-set introduces UFS (Universal Flash Storage) host controller support
> for Samsung family SoC. Mostly, it consists of UFS PHY and host specific driver.
>
.
.
.
> Alim Akhtar (9):
> scsi: ufs: add quirk to fix mishandling utrlclr/utmrlclr
> scsi: ufs: add quirk to disallow reset of interrupt aggregation
> scsi: ufs: add quirk to enable host controller without hce
> scsi: ufs: introduce UFSHCD_QUIRK_PRDT_BYTE_GRAN quirk
> dt-bindings: phy: Document Samsung UFS PHY bindings
> phy: samsung-ufs: add UFS PHY driver for samsung SoC
> dt-bindings: ufs: Add bindings for Samsung ufs host
> scsi: ufs-exynos: add UFS host support for Exynos SoCs
> arm64: dts: Add node for ufs exynos7
>
> Kiwoong Kim (1):
> scsi: ufs: add quirk to fix abnormal ocs fatal error
>
> .../bindings/phy/samsung,ufs-phy.yaml | 75 +
> .../bindings/ufs/samsung,exynos-ufs.yaml | 89 ++
> .../boot/dts/exynos/exynos7-espresso.dts | 4 +
> arch/arm64/boot/dts/exynos/exynos7.dtsi | 43 +-
> drivers/phy/samsung/Kconfig | 9 +
> drivers/phy/samsung/Makefile | 1 +
> drivers/phy/samsung/phy-exynos7-ufs.h | 86 ++
> drivers/phy/samsung/phy-samsung-ufs.c | 380 +++++
> drivers/phy/samsung/phy-samsung-ufs.h | 143 ++
> drivers/scsi/ufs/Kconfig | 12 +
> drivers/scsi/ufs/Makefile | 1 +
> drivers/scsi/ufs/ufs-exynos.c | 1292 +++++++++++++++++
> drivers/scsi/ufs/ufs-exynos.h | 287 ++++
> drivers/scsi/ufs/ufshcd.c | 126 +-
> drivers/scsi/ufs/ufshcd.h | 29 +
> drivers/scsi/ufs/unipro.h | 33 +
> 16 files changed, 2596 insertions(+), 14 deletions(-)
> create mode 100644 Documentation/devicetree/bindings/phy/samsung,ufs-
> phy.yaml
> create mode 100644 Documentation/devicetree/bindings/ufs/samsung,exynos-
> ufs.yaml
> create mode 100644 drivers/phy/samsung/phy-exynos7-ufs.h
> create mode 100644 drivers/phy/samsung/phy-samsung-ufs.c
> create mode 100644 drivers/phy/samsung/phy-samsung-ufs.h
> create mode 100644 drivers/scsi/ufs/ufs-exynos.c
> create mode 100644 drivers/scsi/ufs/ufs-exynos.h
>
Hi Martin and Kishon,
Can you please take the patches into your respective trees?
Thanks,
>
> base-commit: 0e698dfa282211e414076f9dc7e83c1c288314fd
> --
> 2.17.1
^ permalink raw reply
* [PATCH 0/3] arm64: dts: imx8qxp: dtb aliases fix/update
From: peng.fan @ 2020-06-01 2:06 UTC (permalink / raw)
To: shawnguo, fabio.estevam, kernel, aisheng.dong
Cc: linux-arm-kernel, linux-kernel, linux-imx, leonard.crestez,
daniel.baluta, l.stach, devicetree, Peng Fan
From: Peng Fan <peng.fan@nxp.com>
Minor patchset to fix and update alias for i.MX8QXP
Peng Fan (3):
arm64: dts: imx8qxp: add alias for lsio MU
arm64: dts: imx8qxp: add i2c aliases
arm64: dts: imx8qxp: Add ethernet alias
arch/arm64/boot/dts/freescale/imx8qxp.dtsi | 10 ++++++++++
1 file changed, 10 insertions(+)
--
2.16.4
^ permalink raw reply
* [PATCH 1/3] arm64: dts: imx8qxp: add alias for lsio MU
From: peng.fan @ 2020-06-01 2:06 UTC (permalink / raw)
To: shawnguo, fabio.estevam, kernel, aisheng.dong
Cc: linux-arm-kernel, linux-kernel, linux-imx, leonard.crestez,
daniel.baluta, l.stach, devicetree, Peng Fan
In-Reply-To: <1590977180-9957-1-git-send-email-peng.fan@nxp.com>
From: Peng Fan <peng.fan@nxp.com>
Add lsio mu alias for all lsio MUs that could communicate with SCU,
imx_scu_enable_general_irq_channel will parse the alias to get
the mu resource id, if using other MU, not MU1, the `mu_resource_id`
is not what we expect, so add alias to fix this issue.
Signed-off-by: Peng Fan <peng.fan@nxp.com>
---
arch/arm64/boot/dts/freescale/imx8qxp.dtsi | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/arch/arm64/boot/dts/freescale/imx8qxp.dtsi b/arch/arm64/boot/dts/freescale/imx8qxp.dtsi
index d1c3c98e4b39..33363c127478 100644
--- a/arch/arm64/boot/dts/freescale/imx8qxp.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8qxp.dtsi
@@ -30,7 +30,11 @@
mmc0 = &usdhc1;
mmc1 = &usdhc2;
mmc2 = &usdhc3;
+ mu0 = &lsio_mu0;
mu1 = &lsio_mu1;
+ mu2 = &lsio_mu2;
+ mu3 = &lsio_mu3;
+ mu4 = &lsio_mu4;
serial0 = &adma_lpuart0;
serial1 = &adma_lpuart1;
serial2 = &adma_lpuart2;
--
2.16.4
^ permalink raw reply related
* [PATCH 2/3] arm64: dts: imx8qxp: add i2c aliases
From: peng.fan @ 2020-06-01 2:06 UTC (permalink / raw)
To: shawnguo, fabio.estevam, kernel, aisheng.dong
Cc: linux-arm-kernel, linux-kernel, linux-imx, leonard.crestez,
daniel.baluta, l.stach, devicetree, Peng Fan
In-Reply-To: <1590977180-9957-1-git-send-email-peng.fan@nxp.com>
From: Peng Fan <peng.fan@nxp.com>
The devices could be enumerated properly with aliases.
Signed-off-by: Peng Fan <peng.fan@nxp.com>
---
arch/arm64/boot/dts/freescale/imx8qxp.dtsi | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/arch/arm64/boot/dts/freescale/imx8qxp.dtsi b/arch/arm64/boot/dts/freescale/imx8qxp.dtsi
index 33363c127478..8ce997110cd6 100644
--- a/arch/arm64/boot/dts/freescale/imx8qxp.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8qxp.dtsi
@@ -19,6 +19,10 @@
#size-cells = <2>;
aliases {
+ i2c0 = &adma_i2c0;
+ i2c1 = &adma_i2c1;
+ i2c2 = &adma_i2c2;
+ i2c3 = &adma_i2c3;
gpio0 = &lsio_gpio0;
gpio1 = &lsio_gpio1;
gpio2 = &lsio_gpio2;
--
2.16.4
^ permalink raw reply related
* [PATCH 3/3] arm64: dts: imx8qxp: Add ethernet alias
From: peng.fan @ 2020-06-01 2:06 UTC (permalink / raw)
To: shawnguo, fabio.estevam, kernel, aisheng.dong
Cc: linux-arm-kernel, linux-kernel, linux-imx, leonard.crestez,
daniel.baluta, l.stach, devicetree, Peng Fan
In-Reply-To: <1590977180-9957-1-git-send-email-peng.fan@nxp.com>
From: Peng Fan <peng.fan@nxp.com>
Add ethernet alias, so bootloader code can use this to find the
primary ethernet device, and set the MAC address.
Signed-off-by: Peng Fan <peng.fan@nxp.com>
---
arch/arm64/boot/dts/freescale/imx8qxp.dtsi | 2 ++
1 file changed, 2 insertions(+)
diff --git a/arch/arm64/boot/dts/freescale/imx8qxp.dtsi b/arch/arm64/boot/dts/freescale/imx8qxp.dtsi
index 8ce997110cd6..ff6368af7d39 100644
--- a/arch/arm64/boot/dts/freescale/imx8qxp.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8qxp.dtsi
@@ -23,6 +23,8 @@
i2c1 = &adma_i2c1;
i2c2 = &adma_i2c2;
i2c3 = &adma_i2c3;
+ ethernet0 = &fec1;
+ ethernet1 = &fec2;
gpio0 = &lsio_gpio0;
gpio1 = &lsio_gpio1;
gpio2 = &lsio_gpio2;
--
2.16.4
^ permalink raw reply related
* Re: [PATCH v9 1/8] tpm: tpm_tis: Make implementation of read16, read32 and write32 optional
From: Jarkko Sakkinen @ 2020-06-01 2:23 UTC (permalink / raw)
To: amirmizi6
Cc: Eyal.Cohen, oshrialkoby85, alexander.steffen, robh+dt, peterhuewe,
christophe-h.richard, jgg, arnd, gregkh, devicetree, linux-kernel,
linux-integrity, oshri.alkoby, tmaimon77, gcwilson, kgoldman,
Dan.Morav, oren.tanami, shmulik.hager, amir.mizinski
In-Reply-To: <20200526141658.157801-2-amirmizi6@gmail.com>
Plese, write the short summary as
tpm: Make read{16, 32}() and write32() in tpm_tis_phy_ops optional
On Tue, May 26, 2020 at 05:16:51PM +0300, amirmizi6@gmail.com wrote:
> From: Amir Mizinski <amirmizi6@gmail.com>
>
> Only tpm_tis can use memory-mapped I/O, which is truly mapped into
> the kernel's memory space. Therefore, using ioread16/ioread32/iowrite32
> turns into a straightforward pointer dereference.
> Every other driver requires more complicated operations to read more than
> one byte at a time and will just fall back to read_bytes/write_bytes.
> Therefore, move this common code out of tpm_tis_spi and into tpm_tis_core
> so that it is used automatically when low-level drivers do not implement
> the specialized methods.
>
> Co-developed-by: Alexander Steffen <Alexander.Steffen@infineon.com>
> Signed-off-by: Alexander Steffen <Alexander.Steffen@infineon.com>
> Signed-off-by: Amir Mizinski <amirmizi6@gmail.com>
> ---
> drivers/char/tpm/tpm_tis_core.h | 38 +++++++++++++++++++++++++++++++---
> drivers/char/tpm/tpm_tis_spi.h | 4 ----
> drivers/char/tpm/tpm_tis_spi_cr50.c | 3 ---
> drivers/char/tpm/tpm_tis_spi_main.c | 41 -------------------------------------
> 4 files changed, 35 insertions(+), 51 deletions(-)
>
> diff --git a/drivers/char/tpm/tpm_tis_core.h b/drivers/char/tpm/tpm_tis_core.h
> index 7337819..d06c65b 100644
> --- a/drivers/char/tpm/tpm_tis_core.h
> +++ b/drivers/char/tpm/tpm_tis_core.h
> @@ -122,13 +122,35 @@ static inline int tpm_tis_read8(struct tpm_tis_data *data, u32 addr, u8 *result)
> static inline int tpm_tis_read16(struct tpm_tis_data *data, u32 addr,
> u16 *result)
> {
> - return data->phy_ops->read16(data, addr, result);
> + __le16 result_le;
> + int rc;
> +
> + if (data->phy_ops->read16)
> + return data->phy_ops->read16(data, addr, result);
> +
> + rc = data->phy_ops->read_bytes(data, addr, sizeof(u16),
> + (u8 *)&result_le);
> + if (!rc)
> + *result = le16_to_cpu(result_le);
> +
> + return rc;
> }
>
> static inline int tpm_tis_read32(struct tpm_tis_data *data, u32 addr,
> u32 *result)
> {
> - return data->phy_ops->read32(data, addr, result);
> + __le32 result_le;
> + int rc;
> +
> + if (data->phy_ops->read32)
> + return data->phy_ops->read32(data, addr, result);
> +
> + rc = data->phy_ops->read_bytes(data, addr, sizeof(u32),
> + (u8 *)&result_le);
> + if (!rc)
> + *result = le32_to_cpu(result_le);
> +
> + return rc;
> }
>
> static inline int tpm_tis_write_bytes(struct tpm_tis_data *data, u32 addr,
> @@ -145,7 +167,17 @@ static inline int tpm_tis_write8(struct tpm_tis_data *data, u32 addr, u8 value)
> static inline int tpm_tis_write32(struct tpm_tis_data *data, u32 addr,
> u32 value)
> {
> - return data->phy_ops->write32(data, addr, value);
> + __le32 value_le;
> + int rc;
> +
> + if (data->phy_ops->write32)
> + return data->phy_ops->write32(data, addr, value);
> +
> + value_le = cpu_to_le32(value);
> + rc = data->phy_ops->write_bytes(data, addr, sizeof(u32),
> + (u8 *)&value_le);
> +
> + return rc;
> }
>
> static inline bool is_bsw(void)
> diff --git a/drivers/char/tpm/tpm_tis_spi.h b/drivers/char/tpm/tpm_tis_spi.h
> index bba7397..d0f66f6 100644
> --- a/drivers/char/tpm/tpm_tis_spi.h
> +++ b/drivers/char/tpm/tpm_tis_spi.h
> @@ -31,10 +31,6 @@ extern int tpm_tis_spi_init(struct spi_device *spi, struct tpm_tis_spi_phy *phy,
> extern int tpm_tis_spi_transfer(struct tpm_tis_data *data, u32 addr, u16 len,
> u8 *in, const u8 *out);
>
> -extern int tpm_tis_spi_read16(struct tpm_tis_data *data, u32 addr, u16 *result);
> -extern int tpm_tis_spi_read32(struct tpm_tis_data *data, u32 addr, u32 *result);
> -extern int tpm_tis_spi_write32(struct tpm_tis_data *data, u32 addr, u32 value);
> -
> #ifdef CONFIG_TCG_TIS_SPI_CR50
> extern int cr50_spi_probe(struct spi_device *spi);
> #else
> diff --git a/drivers/char/tpm/tpm_tis_spi_cr50.c b/drivers/char/tpm/tpm_tis_spi_cr50.c
> index 37d72e8..f339d20 100644
> --- a/drivers/char/tpm/tpm_tis_spi_cr50.c
> +++ b/drivers/char/tpm/tpm_tis_spi_cr50.c
> @@ -215,9 +215,6 @@ static int tpm_tis_spi_cr50_write_bytes(struct tpm_tis_data *data, u32 addr,
> static const struct tpm_tis_phy_ops tpm_spi_cr50_phy_ops = {
> .read_bytes = tpm_tis_spi_cr50_read_bytes,
> .write_bytes = tpm_tis_spi_cr50_write_bytes,
> - .read16 = tpm_tis_spi_read16,
> - .read32 = tpm_tis_spi_read32,
> - .write32 = tpm_tis_spi_write32,
> };
>
> static void cr50_print_fw_version(struct tpm_tis_data *data)
> diff --git a/drivers/char/tpm/tpm_tis_spi_main.c b/drivers/char/tpm/tpm_tis_spi_main.c
> index d1754fd..95fef9d 100644
> --- a/drivers/char/tpm/tpm_tis_spi_main.c
> +++ b/drivers/char/tpm/tpm_tis_spi_main.c
> @@ -152,44 +152,6 @@ static int tpm_tis_spi_write_bytes(struct tpm_tis_data *data, u32 addr,
> return tpm_tis_spi_transfer(data, addr, len, NULL, value);
> }
>
> -int tpm_tis_spi_read16(struct tpm_tis_data *data, u32 addr, u16 *result)
> -{
> - __le16 result_le;
> - int rc;
> -
> - rc = data->phy_ops->read_bytes(data, addr, sizeof(u16),
> - (u8 *)&result_le);
> - if (!rc)
> - *result = le16_to_cpu(result_le);
> -
> - return rc;
> -}
> -
> -int tpm_tis_spi_read32(struct tpm_tis_data *data, u32 addr, u32 *result)
> -{
> - __le32 result_le;
> - int rc;
> -
> - rc = data->phy_ops->read_bytes(data, addr, sizeof(u32),
> - (u8 *)&result_le);
> - if (!rc)
> - *result = le32_to_cpu(result_le);
> -
> - return rc;
> -}
> -
> -int tpm_tis_spi_write32(struct tpm_tis_data *data, u32 addr, u32 value)
> -{
> - __le32 value_le;
> - int rc;
> -
> - value_le = cpu_to_le32(value);
> - rc = data->phy_ops->write_bytes(data, addr, sizeof(u32),
> - (u8 *)&value_le);
> -
> - return rc;
> -}
> -
> int tpm_tis_spi_init(struct spi_device *spi, struct tpm_tis_spi_phy *phy,
> int irq, const struct tpm_tis_phy_ops *phy_ops)
> {
> @@ -205,9 +167,6 @@ int tpm_tis_spi_init(struct spi_device *spi, struct tpm_tis_spi_phy *phy,
> static const struct tpm_tis_phy_ops tpm_spi_phy_ops = {
> .read_bytes = tpm_tis_spi_read_bytes,
> .write_bytes = tpm_tis_spi_write_bytes,
> - .read16 = tpm_tis_spi_read16,
> - .read32 = tpm_tis_spi_read32,
> - .write32 = tpm_tis_spi_write32,
> };
>
> static int tpm_tis_spi_probe(struct spi_device *dev)
> --
> 2.7.4
Other than that looks good.
/Jarkko
>
^ permalink raw reply
* Re: [PATCH v9 2/8] tpm: tpm_tis: Fix expected bit handling and send all bytes in one shot without last byte in exception
From: Jarkko Sakkinen @ 2020-06-01 2:30 UTC (permalink / raw)
To: amirmizi6
Cc: Eyal.Cohen, oshrialkoby85, alexander.steffen, robh+dt, peterhuewe,
christophe-h.richard, jgg, arnd, gregkh, devicetree, linux-kernel,
linux-integrity, oshri.alkoby, tmaimon77, gcwilson, kgoldman,
Dan.Morav, oren.tanami, shmulik.hager, amir.mizinski,
Benoit Houyere
In-Reply-To: <20200526141658.157801-3-amirmizi6@gmail.com>
On Tue, May 26, 2020 at 05:16:52PM +0300, amirmizi6@gmail.com wrote:
> From: Amir Mizinski <amirmizi6@gmail.com>
>
> Incorrect implementation of send message was detected. We polled only
> TPM_STS.stsValid bit and then we single-checked the TPM_STS.expect bit
> value.
> TPM_STS.expected bit should be checked at the same time as
> TPM_STS.stsValid bit, and this should be repeated until timeout_A.
I don't understand what the first paragraph is trying to say. It does
not conclude to anything. Please write instead soemthing that explains
what is going on.
> To detect a TPM_STS.expected bit reset, the "wait_for_tpm_stat" function is
> modified to "wait_for_tpm_stat_result". This function regularly reads the
> status register and check the bits defined by "mask" to reach the value
> defined in "mask_result".
Please remove this and explain instead how are you are changing the
existing function.
> This correct implementation is required for using the new CRC calculation
> on I2C TPM command bytes or I2C TPM answer bytes. TPM_STS.expected bit is
> reset after all bytes are acquired and the CRC result is inserted in the
> dedicated register. It introduces a normal latency for TPM_STS.expected
> bit reset.
>
> Respectively, to send a message, as defined in
> TCG_DesignPrinciples_TPM2p0Driver_vp24_pubrev.pdf, all bytes should be
> sent in one shot instead of sending the last byte separately.
>
> Suggested-by: Benoit Houyere <benoit.houyere@st.com>
> Signed-off-by: Amir Mizinski <amirmizi6@gmail.com>
> ---
> drivers/char/tpm/tpm_tis_core.c | 74 +++++++++++++++++------------------------
> 1 file changed, 30 insertions(+), 44 deletions(-)
>
> diff --git a/drivers/char/tpm/tpm_tis_core.c b/drivers/char/tpm/tpm_tis_core.c
> index 27c6ca0..c725b68 100644
> --- a/drivers/char/tpm/tpm_tis_core.c
> +++ b/drivers/char/tpm/tpm_tis_core.c
> @@ -44,9 +44,10 @@ static bool wait_for_tpm_stat_cond(struct tpm_chip *chip, u8 mask,
> return false;
> }
>
> -static int wait_for_tpm_stat(struct tpm_chip *chip, u8 mask,
> - unsigned long timeout, wait_queue_head_t *queue,
> - bool check_cancel)
> +static int wait_for_tpm_stat_result(struct tpm_chip *chip, u8 mask,
> + u8 mask_result, unsigned long timeout,
> + wait_queue_head_t *queue,
> + bool check_cancel)
Please do not change the function name.
/Jarkko
^ permalink raw reply
* Re: [V9, 1/2] media: dt-bindings: media: i2c: Document OV02A10 bindings
From: Dongchun Zhu @ 2020-06-01 2:33 UTC (permalink / raw)
To: Tomasz Figa
Cc: Sakari Ailus, Rob Herring, Linus Walleij, Bartosz Golaszewski,
Mauro Carvalho Chehab, Andy Shevchenko, Mark Rutland,
Nicolas Boichat, Matthias Brugger, Cao Bing Bu, srv_heupstream,
moderated list:ARM/Mediatek SoC support,
moderated list:ARM/FREESCALE IMX / MXC ARM ARCHITECTURE, Sj Huang,
Linux Media Mailing List, linux-devicetree, Louis Kuo,
Shengnan Wang (王圣男), dongchun.zhu
In-Reply-To: <CAAFQd5AuHDpQN8xZsWgnAt6m2reAYJbs9nBp0+mBo7_FS81LbQ@mail.gmail.com>
Hi Tomasz,
On Fri, 2020-05-29 at 15:43 +0200, Tomasz Figa wrote:
> On Thu, May 28, 2020 at 10:06 AM Dongchun Zhu <dongchun.zhu@mediatek.com> wrote:
> >
> > Hi Sakari,
> >
> > On Thu, 2020-05-28 at 10:23 +0300, Sakari Ailus wrote:
> > > Hi Dongchun,
> > >
> > > On Thu, May 28, 2020 at 11:34:42AM +0800, Dongchun Zhu wrote:
> > > > Hi Sakari, Rob,
> > > >
> > > > On Thu, 2020-05-28 at 00:16 +0300, Sakari Ailus wrote:
> > > > > Hi Rob, Dongchun,
> > > > >
> > > > > On Wed, May 27, 2020 at 09:27:22AM -0600, Rob Herring wrote:
> > > > > > > > > + properties:
> > > > > > > > > + endpoint:
> > > > > > > > > + type: object
> > > > > > > > > + additionalProperties: false
> > > > > > > > > +
> > > > > > > > > + properties:
> > > > > > >
> > > > > > > Actually I wonder whether we need to declare 'clock-lanes' here?
> > > > > >
> > > > > > Yes, if you are using it.
> > > > >
> > > > > Dongchun, can you confirm the chip has a single data and a single clock
> > > > > lane and that it does not support lane reordering?
> > > > >
> > > >
> > > > From the datasheet, 'MIPI inside the OV02A10 provides one single
> > > > uni-directional clock lane and one bi-directional data lane solution for
> > > > communication links between components inside a mobile device.
> > > > The data lane has full support for HS(uni-directional) and
> > > > LP(bi-directional) data transfer mode.'
> > > >
> > > > The sensor doesn't support lane reordering, so 'clock-lanes' property
> > > > would not be added in next release.
> > > >
> > > > > So if there's nothing to convey to the driver, also the data-lanes should
> > > > > be removed IMO.
> > > > >
> > > >
> > > > However, 'data-lanes' property may still be required.
> > > > It is known that either data-lanes or clock-lanes is an array of
> > > > physical data lane indexes. Position of an entry determines the logical
> > > > lane number, while the value of an entry indicates physical lane, e.g.,
> > > > for 1-lane MIPI CSI-2 bus we could have "data-lanes = <1>;", assuming
> > > > the clock lane is on hardware lane 0.
> > > >
> > > > As mentioned earlier, the OV02A10 sensor supports only 1C1D and does not
> > > > support lane reordering, so here we shall use 'data-lanes = <1>' as
> > > > there is only a clock lane for OV02A10.
> > > >
> > > > Reminder:
> > > > If 'data-lanes' property is not present, the driver would assume
> > > > four-lane operation. This means for one-lane or two-lane operation, this
> > > > property must be present and set to the right physical lane indexes.
> > > > If the hardware does not support lane reordering, monotonically
> > > > incremented values shall be used from 0 or 1 onwards, depending on
> > > > whether or not there is also a clock lane.
> > >
> > > How can the driver use four lanes, considering the device only supports a
> > > single lane??
> > >
> >
> > I understood your meaning.
> > If we omit the property 'data-lanes', the sensor should work still.
> > But then what's the meaning of the existence of 'data-lanes'?
> > If this property 'data-lanes' is always optional, then why dt-bindings
> > provide the interface?
> >
> > In the meantime, if omitting 'data-lanes' for one sensor(transmitter)
> > that has only one physical data lane, MIPI receiver(e.g., MIPI CSI-2)
> > shall enable four-lane configuration, which may increase consumption of
> > both power and resource in the process of IIC communication.
>
> Wouldn't the receiver still have the data-lanes property under its
> endpoint node, telling it how many lanes and in which order should be
> used?
>
The MIPI receiver(RX) shall use
v4l2_async_notifier_add_fwnode_remote_subdev() API to parse the property
"data-lanes" under sensor output port.
> Best regards,
> Tomasz
^ permalink raw reply
* Re: [PATCH v6] support gce on mt6779 platform
From: Dennis-YC Hsieh @ 2020-06-01 2:41 UTC (permalink / raw)
To: Jassi Brar
Cc: Rob Herring, Mark Rutland, Matthias Brugger, Philipp Zabel,
David Airlie, Daniel Vetter, Linux Kernel Mailing List,
linux-mediatek, Devicetree List, wsd_upstream, dri-devel,
Bibby Hsieh, CK Hu, Houlong Wei, linux-arm-kernel, HS Liao
In-Reply-To: <CABb+yY16FzgafSYRo8DuVMttqUR5JVzXDsaP2rX+UnrNOD6k2A@mail.gmail.com>
Hi Jassi,
Thanks for your comment
On Sat, 2020-05-30 at 15:34 -0500, Jassi Brar wrote:
> On Thu, May 28, 2020 at 12:05 PM Dennis YC Hsieh
> <dennis-yc.hsieh@mediatek.com> wrote:
> >
> > This patch support gce on mt6779 platform.
> >
> > Change since v5:
> > - spearate address shift code in client helper and mailbox controller
> > - separate write_s/write_s_mask and write_s_value/write_s_mask_value so that
> > client can decide use mask or not
> > - fix typo in header
> >
> > Change since v4:
> > - do not clear disp event again in drm driver
> > - symbolize value 1 to jump relative
> >
> > [... snip ...]
> >
> >
> >
> > Dennis YC Hsieh (16):
> > dt-binding: gce: add gce header file for mt6779
> > mailbox: cmdq: variablize address shift in platform
> > mailbox: cmdq: support mt6779 gce platform definition
> > mailbox: mediatek: cmdq: clear task in channel before shutdown
> > soc: mediatek: cmdq: return send msg error code
> > soc: mediatek: cmdq: add address shift in jump
> > soc: mediatek: cmdq: add assign function
> > soc: mediatek: cmdq: add write_s function
> > soc: mediatek: cmdq: add write_s_mask function
> > soc: mediatek: cmdq: add read_s function
> > soc: mediatek: cmdq: add write_s value function
> > soc: mediatek: cmdq: add write_s_mask value function
> > soc: mediatek: cmdq: export finalize function
> > soc: mediatek: cmdq: add jump function
> > soc: mediatek: cmdq: add clear option in cmdq_pkt_wfe api
> > soc: mediatek: cmdq: add set event function
> >
> > .../devicetree/bindings/mailbox/mtk-gce.txt | 8 +-
> > drivers/gpu/drm/mediatek/mtk_drm_crtc.c | 3 +-
> > drivers/mailbox/mtk-cmdq-mailbox.c | 101 ++++++--
> > drivers/soc/mediatek/mtk-cmdq-helper.c | 163 ++++++++++++-
> > include/dt-bindings/gce/mt6779-gce.h | 222 ++++++++++++++++++
> > include/linux/mailbox/mtk-cmdq-mailbox.h | 10 +-
> > include/linux/soc/mediatek/mtk-cmdq.h | 125 +++++++++-
> >
> Please break the patchset into two. The lower mailbox related changes
> with soc changes on top.
Ok, I'll separate patches into two patchset, thanks.
Regards,
Dennis
>
> thanks
^ permalink raw reply
* [PATCH V2] dt-bindings: thermal: Convert qoriq to json-schema
From: Anson Huang @ 2020-06-01 3:35 UTC (permalink / raw)
To: rui.zhang, daniel.lezcano, amit.kucheria, robh+dt, hongtao.jia,
linux-pm, devicetree, linux-kernel
Cc: Linux-imx
Convert the qoriq thermal binding to DT schema format using json-schema
Signed-off-by: Anson Huang <Anson.Huang@nxp.com>
---
Changes since V1:
- add 'maxItems' for 'fsl,tmu-range' property;
- add 'minItems'/'maxItems' and items descriptions for 'fsl,tmu-calibration' property;
- remove description for common property '#thermal-sensor-cells';
- refine 'fsl,tmu-calibration' format in example.
---
.../devicetree/bindings/thermal/qoriq-thermal.txt | 71 -------------
.../devicetree/bindings/thermal/qoriq-thermal.yaml | 112 +++++++++++++++++++++
2 files changed, 112 insertions(+), 71 deletions(-)
delete mode 100644 Documentation/devicetree/bindings/thermal/qoriq-thermal.txt
create mode 100644 Documentation/devicetree/bindings/thermal/qoriq-thermal.yaml
diff --git a/Documentation/devicetree/bindings/thermal/qoriq-thermal.txt b/Documentation/devicetree/bindings/thermal/qoriq-thermal.txt
deleted file mode 100644
index 28f2cba..0000000
--- a/Documentation/devicetree/bindings/thermal/qoriq-thermal.txt
+++ /dev/null
@@ -1,71 +0,0 @@
-* Thermal Monitoring Unit (TMU) on Freescale QorIQ SoCs
-
-Required properties:
-- compatible : Must include "fsl,qoriq-tmu" or "fsl,imx8mq-tmu". The
- version of the device is determined by the TMU IP Block Revision
- Register (IPBRR0) at offset 0x0BF8.
- Table of correspondences between IPBRR0 values and example chips:
- Value Device
- ---------- -----
- 0x01900102 T1040
-- reg : Address range of TMU registers.
-- interrupts : Contains the interrupt for TMU.
-- fsl,tmu-range : The values to be programmed into TTRnCR, as specified by
- the SoC reference manual. The first cell is TTR0CR, the second is
- TTR1CR, etc.
-- fsl,tmu-calibration : A list of cell pairs containing temperature
- calibration data, as specified by the SoC reference manual.
- The first cell of each pair is the value to be written to TTCFGR,
- and the second is the value to be written to TSCFGR.
-- #thermal-sensor-cells : Must be 1. The sensor specifier is the monitoring
- site ID, and represents the "n" in TRITSRn and TRATSRn.
-
-Optional property:
-- little-endian : If present, the TMU registers are little endian. If absent,
- the default is big endian.
-- clocks : the clock for clocking the TMU silicon.
-
-Example:
-
-tmu@f0000 {
- compatible = "fsl,qoriq-tmu";
- reg = <0xf0000 0x1000>;
- interrupts = <18 2 0 0>;
- fsl,tmu-range = <0x000a0000 0x00090026 0x0008004a 0x0001006a>;
- fsl,tmu-calibration = <0x00000000 0x00000025
- 0x00000001 0x00000028
- 0x00000002 0x0000002d
- 0x00000003 0x00000031
- 0x00000004 0x00000036
- 0x00000005 0x0000003a
- 0x00000006 0x00000040
- 0x00000007 0x00000044
- 0x00000008 0x0000004a
- 0x00000009 0x0000004f
- 0x0000000a 0x00000054
-
- 0x00010000 0x0000000d
- 0x00010001 0x00000013
- 0x00010002 0x00000019
- 0x00010003 0x0000001f
- 0x00010004 0x00000025
- 0x00010005 0x0000002d
- 0x00010006 0x00000033
- 0x00010007 0x00000043
- 0x00010008 0x0000004b
- 0x00010009 0x00000053
-
- 0x00020000 0x00000010
- 0x00020001 0x00000017
- 0x00020002 0x0000001f
- 0x00020003 0x00000029
- 0x00020004 0x00000031
- 0x00020005 0x0000003c
- 0x00020006 0x00000042
- 0x00020007 0x0000004d
- 0x00020008 0x00000056
-
- 0x00030000 0x00000012
- 0x00030001 0x0000001d>;
- #thermal-sensor-cells = <1>;
-};
diff --git a/Documentation/devicetree/bindings/thermal/qoriq-thermal.yaml b/Documentation/devicetree/bindings/thermal/qoriq-thermal.yaml
new file mode 100644
index 0000000..c5df999
--- /dev/null
+++ b/Documentation/devicetree/bindings/thermal/qoriq-thermal.yaml
@@ -0,0 +1,112 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/thermal/qoriq-thermal.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Thermal Monitoring Unit (TMU) on Freescale QorIQ SoCs
+
+maintainers:
+ - Hongtao Jia <hongtao.jia@freescale.com>
+
+properties:
+ compatible:
+ description: |
+ The version of the device is determined by the TMU IP Block Revision
+ Register (IPBRR0) at offset 0x0BF8.
+ Table of correspondences between IPBRR0 values and example chips:
+ Value Device
+ ---------- -----
+ 0x01900102 T1040
+ enum:
+ - fsl,qoriq-tmu
+ - fsl,imx8mq-tmu
+
+ reg:
+ maxItems: 1
+
+ interrupts:
+ maxItems: 1
+
+ fsl,tmu-range:
+ $ref: '/schemas/types.yaml#/definitions/uint32-array'
+ description: |
+ The values to be programmed into TTRnCR, as specified by the SoC
+ reference manual. The first cell is TTR0CR, the second is TTR1CR, etc.
+ maxItems: 4
+
+ fsl,tmu-calibration:
+ $ref: '/schemas/types.yaml#/definitions/uint32-matrix'
+ description: |
+ A list of cell pairs containing temperature calibration data, as
+ specified by the SoC reference manual. The first cell of each pair
+ is the value to be written to TTCFGR, and the second is the value
+ to be written to TSCFGR.
+ items:
+ items:
+ - description: value for TTCFGR
+ - description: value for TSCFGR
+ minItems: 1
+ maxItems: 64
+
+ little-endian:
+ description: |
+ boolean, if present, the TMU registers are little endian. If absent,
+ the default is big endian.
+ type: boolean
+
+ clocks:
+ maxItems: 1
+
+ "#thermal-sensor-cells":
+ const: 1
+
+required:
+ - compatible
+ - reg
+ - interrupts
+ - fsl,tmu-range
+ - fsl,tmu-calibration
+ - '#thermal-sensor-cells'
+
+examples:
+ - |
+ tmu@f0000 {
+ compatible = "fsl,qoriq-tmu";
+ reg = <0xf0000 0x1000>;
+ interrupts = <18 2 0 0>;
+ fsl,tmu-range = <0x000a0000 0x00090026 0x0008004a 0x0001006a>;
+ fsl,tmu-calibration = <0x00000000 0x00000025>,
+ <0x00000001 0x00000028>,
+ <0x00000002 0x0000002d>,
+ <0x00000003 0x00000031>,
+ <0x00000004 0x00000036>,
+ <0x00000005 0x0000003a>,
+ <0x00000006 0x00000040>,
+ <0x00000007 0x00000044>,
+ <0x00000008 0x0000004a>,
+ <0x00000009 0x0000004f>,
+ <0x0000000a 0x00000054>,
+ <0x00010000 0x0000000d>,
+ <0x00010001 0x00000013>,
+ <0x00010002 0x00000019>,
+ <0x00010003 0x0000001f>,
+ <0x00010004 0x00000025>,
+ <0x00010005 0x0000002d>,
+ <0x00010006 0x00000033>,
+ <0x00010007 0x00000043>,
+ <0x00010008 0x0000004b>,
+ <0x00010009 0x00000053>,
+ <0x00020000 0x00000010>,
+ <0x00020001 0x00000017>,
+ <0x00020002 0x0000001f>,
+ <0x00020003 0x00000029>,
+ <0x00020004 0x00000031>,
+ <0x00020005 0x0000003c>,
+ <0x00020006 0x00000042>,
+ <0x00020007 0x0000004d>,
+ <0x00020008 0x00000056>,
+ <0x00030000 0x00000012>,
+ <0x00030001 0x0000001d>;
+ #thermal-sensor-cells = <1>;
+ };
--
2.7.4
^ permalink raw reply related
* [PATCH V2 0/3] imx8m: add mu support
From: peng.fan @ 2020-06-01 3:43 UTC (permalink / raw)
To: shawnguo, fabio.estevam, kernel, aisheng.dong, robh+dt, sboyd,
linux, jaswinder.singh
Cc: linux-arm-kernel, linux-kernel, linux-imx, leonard.crestez,
daniel.baluta, l.stach, devicetree, linux-clk, Peng Fan
From: Peng Fan <peng.fan@nxp.com>
V2:
Add dt-bindings
Merge dts changes into one patch, since all is to add mu node
Add mu dt bindings
Add mu node
Add i.MX8MP mu root clk
Peng Fan (3):
dt-bindings: mailbox: imx-mu: support i.MX8M
arm64: dts: imx8m: add mu node
clk: imx8mp: add mu root clk
Documentation/devicetree/bindings/mailbox/fsl,mu.txt | 3 ++-
arch/arm64/boot/dts/freescale/imx8mm.dtsi | 9 +++++++++
arch/arm64/boot/dts/freescale/imx8mn.dtsi | 9 +++++++++
arch/arm64/boot/dts/freescale/imx8mp.dtsi | 9 +++++++++
arch/arm64/boot/dts/freescale/imx8mq.dtsi | 9 +++++++++
drivers/clk/imx/clk-imx8mp.c | 1 +
6 files changed, 39 insertions(+), 1 deletion(-)
--
2.16.4
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox