2022-11-14 23:27:00

by Dinh Nguyen

[permalink] [raw]
Subject: [PATCHv9 1/6] dt-bindings: mmc: synopsys-dw-mshc: document "altr,sysmgr-syscon"

Document the optional "altr,sysmgr-syscon" binding that is used to
access the System Manager register that controls the SDMMC clock
phase.

Signed-off-by: Dinh Nguyen <[email protected]>
---
v9: remove required for "altr,sysmgr-syscon"
v8: remove "" around synopsys-dw-mshc-common.yaml#
v7: and "not" for the required "altr,sysmgr-syscon" binding
v6: make "altr,sysmgr-syscon" optional
v5: document reg shift
v4: add else statement
v3: document that the "altr,sysmgr-syscon" binding is only applicable to
"altr,socfpga-dw-mshc"
v2: document "altr,sysmgr-syscon" in the MMC section
---
.../bindings/mmc/synopsys-dw-mshc.yaml | 32 +++++++++++++++++--
1 file changed, 29 insertions(+), 3 deletions(-)

diff --git a/Documentation/devicetree/bindings/mmc/synopsys-dw-mshc.yaml b/Documentation/devicetree/bindings/mmc/synopsys-dw-mshc.yaml
index ae6d6fca79e2..e1f5f26f3f1c 100644
--- a/Documentation/devicetree/bindings/mmc/synopsys-dw-mshc.yaml
+++ b/Documentation/devicetree/bindings/mmc/synopsys-dw-mshc.yaml
@@ -6,9 +6,6 @@ $schema: http://devicetree.org/meta-schemas/core.yaml#

title: Synopsys Designware Mobile Storage Host Controller Binding

-allOf:
- - $ref: "synopsys-dw-mshc-common.yaml#"
-
maintainers:
- Ulf Hansson <[email protected]>

@@ -38,6 +35,35 @@ properties:
- const: biu
- const: ciu

+ altr,sysmgr-syscon:
+ $ref: /schemas/types.yaml#/definitions/phandle-array
+ items:
+ - items:
+ - description: phandle to the sysmgr node
+ - description: register offset that controls the SDMMC clock phase
+ - description: register shift for the smplsel(drive in) setting
+ description:
+ This property is optional. Contains the phandle to System Manager block
+ that contains the SDMMC clock-phase control register. The first value is
+ the pointer to the sysmgr, the 2nd value is the register offset for the
+ SDMMC clock phase register, and the 3rd value is the bit shift for the
+ smplsel(drive in) setting.
+
+allOf:
+ - $ref: synopsys-dw-mshc-common.yaml#
+
+ - if:
+ properties:
+ compatible:
+ contains:
+ const: altr,socfpga-dw-mshc
+ then:
+ properties:
+ altr,sysmgr-syscon: true
+ else:
+ properties:
+ altr,sysmgr-syscon: false
+
required:
- compatible
- reg
--
2.25.1



2022-11-14 23:33:29

by Dinh Nguyen

[permalink] [raw]
Subject: [PATCHv9 5/6] clk: socfpga: remove the setting of clk-phase for sdmmc_clk

Now that the SDMMC driver supports setting the clk-phase, we can remove
the need to do it in the clock driver.

Acked-by: Stephen Boyd <[email protected]>
Signed-off-by: Dinh Nguyen <[email protected]>
---
v9: no changes
v8: no changes
v7: add acked-by
v6: remove unused clk_phase in clk-gate.c
v5: new
---
drivers/clk/socfpga/clk-gate-a10.c | 68 ------------------------------
drivers/clk/socfpga/clk-gate.c | 61 ---------------------------
drivers/clk/socfpga/clk.h | 1 -
3 files changed, 130 deletions(-)

diff --git a/drivers/clk/socfpga/clk-gate-a10.c b/drivers/clk/socfpga/clk-gate-a10.c
index 738c53391e39..7cdf2f07c79b 100644
--- a/drivers/clk/socfpga/clk-gate-a10.c
+++ b/drivers/clk/socfpga/clk-gate-a10.c
@@ -35,59 +35,7 @@ static unsigned long socfpga_gate_clk_recalc_rate(struct clk_hw *hwclk,
return parent_rate / div;
}

-static int socfpga_clk_prepare(struct clk_hw *hwclk)
-{
- struct socfpga_gate_clk *socfpgaclk = to_socfpga_gate_clk(hwclk);
- int i;
- u32 hs_timing;
- u32 clk_phase[2];
-
- if (socfpgaclk->clk_phase[0] || socfpgaclk->clk_phase[1]) {
- for (i = 0; i < ARRAY_SIZE(clk_phase); i++) {
- switch (socfpgaclk->clk_phase[i]) {
- case 0:
- clk_phase[i] = 0;
- break;
- case 45:
- clk_phase[i] = 1;
- break;
- case 90:
- clk_phase[i] = 2;
- break;
- case 135:
- clk_phase[i] = 3;
- break;
- case 180:
- clk_phase[i] = 4;
- break;
- case 225:
- clk_phase[i] = 5;
- break;
- case 270:
- clk_phase[i] = 6;
- break;
- case 315:
- clk_phase[i] = 7;
- break;
- default:
- clk_phase[i] = 0;
- break;
- }
- }
-
- hs_timing = SYSMGR_SDMMC_CTRL_SET_AS10(clk_phase[0], clk_phase[1]);
- if (!IS_ERR(socfpgaclk->sys_mgr_base_addr))
- regmap_write(socfpgaclk->sys_mgr_base_addr,
- SYSMGR_SDMMCGRP_CTRL_OFFSET, hs_timing);
- else
- pr_err("%s: cannot set clk_phase because sys_mgr_base_addr is not available!\n",
- __func__);
- }
- return 0;
-}
-
static struct clk_ops gateclk_ops = {
- .prepare = socfpga_clk_prepare,
.recalc_rate = socfpga_gate_clk_recalc_rate,
};

@@ -96,7 +44,6 @@ static void __init __socfpga_gate_init(struct device_node *node,
{
u32 clk_gate[2];
u32 div_reg[3];
- u32 clk_phase[2];
u32 fixed_div;
struct clk_hw *hw_clk;
struct socfpga_gate_clk *socfpga_clk;
@@ -136,21 +83,6 @@ static void __init __socfpga_gate_init(struct device_node *node,
socfpga_clk->div_reg = NULL;
}

- rc = of_property_read_u32_array(node, "clk-phase", clk_phase, 2);
- if (!rc) {
- socfpga_clk->clk_phase[0] = clk_phase[0];
- socfpga_clk->clk_phase[1] = clk_phase[1];
-
- socfpga_clk->sys_mgr_base_addr =
- syscon_regmap_lookup_by_compatible("altr,sys-mgr");
- if (IS_ERR(socfpga_clk->sys_mgr_base_addr)) {
- pr_err("%s: failed to find altr,sys-mgr regmap!\n",
- __func__);
- kfree(socfpga_clk);
- return;
- }
- }
-
of_property_read_string(node, "clock-output-names", &clk_name);

init.name = clk_name;
diff --git a/drivers/clk/socfpga/clk-gate.c b/drivers/clk/socfpga/clk-gate.c
index 53d6e3ec4309..3e347b9e9eff 100644
--- a/drivers/clk/socfpga/clk-gate.c
+++ b/drivers/clk/socfpga/clk-gate.c
@@ -108,61 +108,7 @@ static unsigned long socfpga_clk_recalc_rate(struct clk_hw *hwclk,
return parent_rate / div;
}

-static int socfpga_clk_prepare(struct clk_hw *hwclk)
-{
- struct socfpga_gate_clk *socfpgaclk = to_socfpga_gate_clk(hwclk);
- struct regmap *sys_mgr_base_addr;
- int i;
- u32 hs_timing;
- u32 clk_phase[2];
-
- if (socfpgaclk->clk_phase[0] || socfpgaclk->clk_phase[1]) {
- sys_mgr_base_addr = syscon_regmap_lookup_by_compatible("altr,sys-mgr");
- if (IS_ERR(sys_mgr_base_addr)) {
- pr_err("%s: failed to find altr,sys-mgr regmap!\n", __func__);
- return -EINVAL;
- }
-
- for (i = 0; i < 2; i++) {
- switch (socfpgaclk->clk_phase[i]) {
- case 0:
- clk_phase[i] = 0;
- break;
- case 45:
- clk_phase[i] = 1;
- break;
- case 90:
- clk_phase[i] = 2;
- break;
- case 135:
- clk_phase[i] = 3;
- break;
- case 180:
- clk_phase[i] = 4;
- break;
- case 225:
- clk_phase[i] = 5;
- break;
- case 270:
- clk_phase[i] = 6;
- break;
- case 315:
- clk_phase[i] = 7;
- break;
- default:
- clk_phase[i] = 0;
- break;
- }
- }
- hs_timing = SYSMGR_SDMMC_CTRL_SET(clk_phase[0], clk_phase[1]);
- regmap_write(sys_mgr_base_addr, SYSMGR_SDMMCGRP_CTRL_OFFSET,
- hs_timing);
- }
- return 0;
-}
-
static struct clk_ops gateclk_ops = {
- .prepare = socfpga_clk_prepare,
.recalc_rate = socfpga_clk_recalc_rate,
.get_parent = socfpga_clk_get_parent,
.set_parent = socfpga_clk_set_parent,
@@ -172,7 +118,6 @@ void __init socfpga_gate_init(struct device_node *node)
{
u32 clk_gate[2];
u32 div_reg[3];
- u32 clk_phase[2];
u32 fixed_div;
struct clk_hw *hw_clk;
struct socfpga_gate_clk *socfpga_clk;
@@ -218,12 +163,6 @@ void __init socfpga_gate_init(struct device_node *node)
socfpga_clk->div_reg = NULL;
}

- rc = of_property_read_u32_array(node, "clk-phase", clk_phase, 2);
- if (!rc) {
- socfpga_clk->clk_phase[0] = clk_phase[0];
- socfpga_clk->clk_phase[1] = clk_phase[1];
- }
-
of_property_read_string(node, "clock-output-names", &clk_name);

init.name = clk_name;
diff --git a/drivers/clk/socfpga/clk.h b/drivers/clk/socfpga/clk.h
index d80115fbdd6a..9a2fb2dde5b8 100644
--- a/drivers/clk/socfpga/clk.h
+++ b/drivers/clk/socfpga/clk.h
@@ -50,7 +50,6 @@ struct socfpga_gate_clk {
u32 width; /* only valid if div_reg != 0 */
u32 shift; /* only valid if div_reg != 0 */
u32 bypass_shift; /* only valid if bypass_reg != 0 */
- u32 clk_phase[2];
};

struct socfpga_periph_clk {
--
2.25.1


2022-11-15 00:03:36

by Dinh Nguyen

[permalink] [raw]
Subject: [PATCHv9 4/6] mmc: dw_mmc-pltfm: socfpga: add method to configure clk-phase

The clock-phase settings for the SDMMC controller in the SoCFPGA
platforms reside in a register in the System Manager. Add a method
to access that register through the syscon interface.

Signed-off-by: Dinh Nguyen <[email protected]>
---
v9: no changes
v8: no changes
v7: use dev_warn if clk-phase-sd-hs is specified, but "altr,sysmgr-syscon"
is not found
v6: not getting the clk-phase-sd-hs is not a hard failure
v5: change error handling from of_property_read_variable_u32_array()
support arm32 by reading the reg_shift
v4: no change
v3: add space before &socfpga_drv_data
v2: simplify clk-phase calculations
---
drivers/mmc/host/dw_mmc-pltfm.c | 41 ++++++++++++++++++++++++++++++++-
1 file changed, 40 insertions(+), 1 deletion(-)

diff --git a/drivers/mmc/host/dw_mmc-pltfm.c b/drivers/mmc/host/dw_mmc-pltfm.c
index 9901208be797..13e55cff8237 100644
--- a/drivers/mmc/host/dw_mmc-pltfm.c
+++ b/drivers/mmc/host/dw_mmc-pltfm.c
@@ -17,10 +17,16 @@
#include <linux/mmc/host.h>
#include <linux/mmc/mmc.h>
#include <linux/of.h>
+#include <linux/mfd/altera-sysmgr.h>
+#include <linux/regmap.h>

#include "dw_mmc.h"
#include "dw_mmc-pltfm.h"

+#define SOCFPGA_DW_MMC_CLK_PHASE_STEP 45
+#define SYSMGR_SDMMC_CTRL_SET(smplsel, drvsel, reg_shift) \
+ ((((smplsel) & 0x7) << reg_shift) | (((drvsel) & 0x7) << 0))
+
int dw_mci_pltfm_register(struct platform_device *pdev,
const struct dw_mci_drv_data *drv_data)
{
@@ -62,9 +68,42 @@ const struct dev_pm_ops dw_mci_pltfm_pmops = {
};
EXPORT_SYMBOL_GPL(dw_mci_pltfm_pmops);

+static int dw_mci_socfpga_priv_init(struct dw_mci *host)
+{
+ struct device_node *np = host->dev->of_node;
+ struct regmap *sys_mgr_base_addr;
+ u32 clk_phase[2] = {0}, reg_offset, reg_shift;
+ int i, rc, hs_timing;
+
+ rc = of_property_read_variable_u32_array(np, "clk-phase-sd-hs", &clk_phase[0], 2, 0);
+ if (rc < 0)
+ return 0;
+
+ sys_mgr_base_addr = altr_sysmgr_regmap_lookup_by_phandle(np, "altr,sysmgr-syscon");
+ if (IS_ERR(sys_mgr_base_addr)) {
+ dev_warn(host->dev, "clk-phase-sd-hs was specified, but failed to find altr,sys-mgr regmap!\n");
+ return 0;
+ }
+
+ of_property_read_u32_index(np, "altr,sysmgr-syscon", 1, &reg_offset);
+ of_property_read_u32_index(np, "altr,sysmgr-syscon", 2, &reg_shift);
+
+ for (i = 0; i < ARRAY_SIZE(clk_phase); i++)
+ clk_phase[i] /= SOCFPGA_DW_MMC_CLK_PHASE_STEP;
+
+ hs_timing = SYSMGR_SDMMC_CTRL_SET(clk_phase[0], clk_phase[1], reg_shift);
+ regmap_write(sys_mgr_base_addr, reg_offset, hs_timing);
+
+ return 0;
+}
+
+static const struct dw_mci_drv_data socfpga_drv_data = {
+ .init = dw_mci_socfpga_priv_init,
+};
+
static const struct of_device_id dw_mci_pltfm_match[] = {
{ .compatible = "snps,dw-mshc", },
- { .compatible = "altr,socfpga-dw-mshc", },
+ { .compatible = "altr,socfpga-dw-mshc", .data = &socfpga_drv_data, },
{ .compatible = "img,pistachio-dw-mshc", },
{},
};
--
2.25.1


2022-11-15 00:07:53

by Dinh Nguyen

[permalink] [raw]
Subject: [PATCHv9 3/6] arm: dts: socfpga: Add clk-phase-sd-hs property to the sdmmc node

The sdmmc controller's CIU(Card Interface Unit) clock's phase can be
adjusted through the register in the system manager. Add the binding
"altr,sysmgr-syscon" to the SDMMC node for the driver to access the
system manager. Add the "clk-phase-sd-hs" property in the SDMMC node to
designate the smpsel and drvsel properties for the CIU clock.

Signed-off-by: Dinh Nguyen <[email protected]>
---
v9: no changes
v8: no changes
v7: no changes
v6: no changes
v5: new
---
arch/arm/boot/dts/socfpga.dtsi | 1 +
arch/arm/boot/dts/socfpga_arria10.dtsi | 1 +
arch/arm/boot/dts/socfpga_arria10_mercury_aa1.dtsi | 1 +
arch/arm/boot/dts/socfpga_arria10_socdk_sdmmc.dts | 1 +
arch/arm/boot/dts/socfpga_arria5.dtsi | 1 +
arch/arm/boot/dts/socfpga_cyclone5.dtsi | 1 +
arch/arm/boot/dts/socfpga_cyclone5_mcv.dtsi | 1 +
7 files changed, 7 insertions(+)

diff --git a/arch/arm/boot/dts/socfpga.dtsi b/arch/arm/boot/dts/socfpga.dtsi
index 2459f3cd7dd9..604fc6e0c4ad 100644
--- a/arch/arm/boot/dts/socfpga.dtsi
+++ b/arch/arm/boot/dts/socfpga.dtsi
@@ -765,6 +765,7 @@ mmc: dwmmc0@ff704000 {
clocks = <&l4_mp_clk>, <&sdmmc_clk_divided>;
clock-names = "biu", "ciu";
resets = <&rst SDMMC_RESET>;
+ altr,sysmgr-syscon = <&sysmgr 0x108 3>;
status = "disabled";
};

diff --git a/arch/arm/boot/dts/socfpga_arria10.dtsi b/arch/arm/boot/dts/socfpga_arria10.dtsi
index 4370e3cbbb4b..b6ebe207e2bc 100644
--- a/arch/arm/boot/dts/socfpga_arria10.dtsi
+++ b/arch/arm/boot/dts/socfpga_arria10.dtsi
@@ -666,6 +666,7 @@ mmc: dwmmc0@ff808000 {
clocks = <&l4_mp_clk>, <&sdmmc_clk>;
clock-names = "biu", "ciu";
resets = <&rst SDMMC_RESET>;
+ altr,sysmgr-syscon = <&sysmgr 0x28 4>;
status = "disabled";
};

diff --git a/arch/arm/boot/dts/socfpga_arria10_mercury_aa1.dtsi b/arch/arm/boot/dts/socfpga_arria10_mercury_aa1.dtsi
index ad7cd14de6b6..41f865c8c098 100644
--- a/arch/arm/boot/dts/socfpga_arria10_mercury_aa1.dtsi
+++ b/arch/arm/boot/dts/socfpga_arria10_mercury_aa1.dtsi
@@ -73,6 +73,7 @@ &mmc {
cap-sd-highspeed;
broken-cd;
bus-width = <4>;
+ clk-phase-sd-hs = <0>, <135>;
};

&osc1 {
diff --git a/arch/arm/boot/dts/socfpga_arria10_socdk_sdmmc.dts b/arch/arm/boot/dts/socfpga_arria10_socdk_sdmmc.dts
index 64dc0799f3d7..d3969367f4b5 100644
--- a/arch/arm/boot/dts/socfpga_arria10_socdk_sdmmc.dts
+++ b/arch/arm/boot/dts/socfpga_arria10_socdk_sdmmc.dts
@@ -12,6 +12,7 @@ &mmc {
cap-mmc-highspeed;
broken-cd;
bus-width = <4>;
+ clk-phase-sd-hs = <0>, <135>;
};

&eccmgr {
diff --git a/arch/arm/boot/dts/socfpga_arria5.dtsi b/arch/arm/boot/dts/socfpga_arria5.dtsi
index 22dbf07afcff..b531639ce7dc 100644
--- a/arch/arm/boot/dts/socfpga_arria5.dtsi
+++ b/arch/arm/boot/dts/socfpga_arria5.dtsi
@@ -23,6 +23,7 @@ mmc0: dwmmc0@ff704000 {
bus-width = <4>;
cap-mmc-highspeed;
cap-sd-highspeed;
+ clk-phase-sd-hs = <0>, <135>;
};

sysmgr@ffd08000 {
diff --git a/arch/arm/boot/dts/socfpga_cyclone5.dtsi b/arch/arm/boot/dts/socfpga_cyclone5.dtsi
index 319a71e41ea4..a9d1ba66f1ff 100644
--- a/arch/arm/boot/dts/socfpga_cyclone5.dtsi
+++ b/arch/arm/boot/dts/socfpga_cyclone5.dtsi
@@ -23,6 +23,7 @@ mmc0: dwmmc0@ff704000 {
bus-width = <4>;
cap-mmc-highspeed;
cap-sd-highspeed;
+ clk-phase-sd-hs = <0>, <135>;
};

sysmgr@ffd08000 {
diff --git a/arch/arm/boot/dts/socfpga_cyclone5_mcv.dtsi b/arch/arm/boot/dts/socfpga_cyclone5_mcv.dtsi
index bd92806ffc12..3b9daddf91cd 100644
--- a/arch/arm/boot/dts/socfpga_cyclone5_mcv.dtsi
+++ b/arch/arm/boot/dts/socfpga_cyclone5_mcv.dtsi
@@ -18,5 +18,6 @@ memory@0 {

&mmc0 { /* On-SoM eMMC */
bus-width = <8>;
+ clk-phase-sd-hs = <0>, <135>;
status = "okay";
};
--
2.25.1


2022-11-16 21:49:33

by Rob Herring

[permalink] [raw]
Subject: Re: [PATCHv9 1/6] dt-bindings: mmc: synopsys-dw-mshc: document "altr,sysmgr-syscon"


On Mon, 14 Nov 2022 17:02:12 -0600, Dinh Nguyen wrote:
> Document the optional "altr,sysmgr-syscon" binding that is used to
> access the System Manager register that controls the SDMMC clock
> phase.
>
> Signed-off-by: Dinh Nguyen <[email protected]>
> ---
> v9: remove required for "altr,sysmgr-syscon"
> v8: remove "" around synopsys-dw-mshc-common.yaml#
> v7: and "not" for the required "altr,sysmgr-syscon" binding
> v6: make "altr,sysmgr-syscon" optional
> v5: document reg shift
> v4: add else statement
> v3: document that the "altr,sysmgr-syscon" binding is only applicable to
> "altr,socfpga-dw-mshc"
> v2: document "altr,sysmgr-syscon" in the MMC section
> ---
> .../bindings/mmc/synopsys-dw-mshc.yaml | 32 +++++++++++++++++--
> 1 file changed, 29 insertions(+), 3 deletions(-)
>

Reviewed-by: Rob Herring <[email protected]>

2022-11-18 09:49:39

by Ulf Hansson

[permalink] [raw]
Subject: Re: [PATCHv9 1/6] dt-bindings: mmc: synopsys-dw-mshc: document "altr,sysmgr-syscon"

On Tue, 15 Nov 2022 at 00:02, Dinh Nguyen <[email protected]> wrote:
>
> Document the optional "altr,sysmgr-syscon" binding that is used to
> access the System Manager register that controls the SDMMC clock
> phase.
>
> Signed-off-by: Dinh Nguyen <[email protected]>

Applied for next, thanks!

Kind regards
Uffe




> ---
> v9: remove required for "altr,sysmgr-syscon"
> v8: remove "" around synopsys-dw-mshc-common.yaml#
> v7: and "not" for the required "altr,sysmgr-syscon" binding
> v6: make "altr,sysmgr-syscon" optional
> v5: document reg shift
> v4: add else statement
> v3: document that the "altr,sysmgr-syscon" binding is only applicable to
> "altr,socfpga-dw-mshc"
> v2: document "altr,sysmgr-syscon" in the MMC section
> ---
> .../bindings/mmc/synopsys-dw-mshc.yaml | 32 +++++++++++++++++--
> 1 file changed, 29 insertions(+), 3 deletions(-)
>
> diff --git a/Documentation/devicetree/bindings/mmc/synopsys-dw-mshc.yaml b/Documentation/devicetree/bindings/mmc/synopsys-dw-mshc.yaml
> index ae6d6fca79e2..e1f5f26f3f1c 100644
> --- a/Documentation/devicetree/bindings/mmc/synopsys-dw-mshc.yaml
> +++ b/Documentation/devicetree/bindings/mmc/synopsys-dw-mshc.yaml
> @@ -6,9 +6,6 @@ $schema: http://devicetree.org/meta-schemas/core.yaml#
>
> title: Synopsys Designware Mobile Storage Host Controller Binding
>
> -allOf:
> - - $ref: "synopsys-dw-mshc-common.yaml#"
> -
> maintainers:
> - Ulf Hansson <[email protected]>
>
> @@ -38,6 +35,35 @@ properties:
> - const: biu
> - const: ciu
>
> + altr,sysmgr-syscon:
> + $ref: /schemas/types.yaml#/definitions/phandle-array
> + items:
> + - items:
> + - description: phandle to the sysmgr node
> + - description: register offset that controls the SDMMC clock phase
> + - description: register shift for the smplsel(drive in) setting
> + description:
> + This property is optional. Contains the phandle to System Manager block
> + that contains the SDMMC clock-phase control register. The first value is
> + the pointer to the sysmgr, the 2nd value is the register offset for the
> + SDMMC clock phase register, and the 3rd value is the bit shift for the
> + smplsel(drive in) setting.
> +
> +allOf:
> + - $ref: synopsys-dw-mshc-common.yaml#
> +
> + - if:
> + properties:
> + compatible:
> + contains:
> + const: altr,socfpga-dw-mshc
> + then:
> + properties:
> + altr,sysmgr-syscon: true
> + else:
> + properties:
> + altr,sysmgr-syscon: false
> +
> required:
> - compatible
> - reg
> --
> 2.25.1
>

2022-11-18 09:50:34

by Ulf Hansson

[permalink] [raw]
Subject: Re: [PATCHv9 5/6] clk: socfpga: remove the setting of clk-phase for sdmmc_clk

On Tue, 15 Nov 2022 at 00:02, Dinh Nguyen <[email protected]> wrote:
>
> Now that the SDMMC driver supports setting the clk-phase, we can remove
> the need to do it in the clock driver.
>
> Acked-by: Stephen Boyd <[email protected]>
> Signed-off-by: Dinh Nguyen <[email protected]>

Applied for next, thanks!

Kind regards
Uffe


> ---
> v9: no changes
> v8: no changes
> v7: add acked-by
> v6: remove unused clk_phase in clk-gate.c
> v5: new
> ---
> drivers/clk/socfpga/clk-gate-a10.c | 68 ------------------------------
> drivers/clk/socfpga/clk-gate.c | 61 ---------------------------
> drivers/clk/socfpga/clk.h | 1 -
> 3 files changed, 130 deletions(-)
>
> diff --git a/drivers/clk/socfpga/clk-gate-a10.c b/drivers/clk/socfpga/clk-gate-a10.c
> index 738c53391e39..7cdf2f07c79b 100644
> --- a/drivers/clk/socfpga/clk-gate-a10.c
> +++ b/drivers/clk/socfpga/clk-gate-a10.c
> @@ -35,59 +35,7 @@ static unsigned long socfpga_gate_clk_recalc_rate(struct clk_hw *hwclk,
> return parent_rate / div;
> }
>
> -static int socfpga_clk_prepare(struct clk_hw *hwclk)
> -{
> - struct socfpga_gate_clk *socfpgaclk = to_socfpga_gate_clk(hwclk);
> - int i;
> - u32 hs_timing;
> - u32 clk_phase[2];
> -
> - if (socfpgaclk->clk_phase[0] || socfpgaclk->clk_phase[1]) {
> - for (i = 0; i < ARRAY_SIZE(clk_phase); i++) {
> - switch (socfpgaclk->clk_phase[i]) {
> - case 0:
> - clk_phase[i] = 0;
> - break;
> - case 45:
> - clk_phase[i] = 1;
> - break;
> - case 90:
> - clk_phase[i] = 2;
> - break;
> - case 135:
> - clk_phase[i] = 3;
> - break;
> - case 180:
> - clk_phase[i] = 4;
> - break;
> - case 225:
> - clk_phase[i] = 5;
> - break;
> - case 270:
> - clk_phase[i] = 6;
> - break;
> - case 315:
> - clk_phase[i] = 7;
> - break;
> - default:
> - clk_phase[i] = 0;
> - break;
> - }
> - }
> -
> - hs_timing = SYSMGR_SDMMC_CTRL_SET_AS10(clk_phase[0], clk_phase[1]);
> - if (!IS_ERR(socfpgaclk->sys_mgr_base_addr))
> - regmap_write(socfpgaclk->sys_mgr_base_addr,
> - SYSMGR_SDMMCGRP_CTRL_OFFSET, hs_timing);
> - else
> - pr_err("%s: cannot set clk_phase because sys_mgr_base_addr is not available!\n",
> - __func__);
> - }
> - return 0;
> -}
> -
> static struct clk_ops gateclk_ops = {
> - .prepare = socfpga_clk_prepare,
> .recalc_rate = socfpga_gate_clk_recalc_rate,
> };
>
> @@ -96,7 +44,6 @@ static void __init __socfpga_gate_init(struct device_node *node,
> {
> u32 clk_gate[2];
> u32 div_reg[3];
> - u32 clk_phase[2];
> u32 fixed_div;
> struct clk_hw *hw_clk;
> struct socfpga_gate_clk *socfpga_clk;
> @@ -136,21 +83,6 @@ static void __init __socfpga_gate_init(struct device_node *node,
> socfpga_clk->div_reg = NULL;
> }
>
> - rc = of_property_read_u32_array(node, "clk-phase", clk_phase, 2);
> - if (!rc) {
> - socfpga_clk->clk_phase[0] = clk_phase[0];
> - socfpga_clk->clk_phase[1] = clk_phase[1];
> -
> - socfpga_clk->sys_mgr_base_addr =
> - syscon_regmap_lookup_by_compatible("altr,sys-mgr");
> - if (IS_ERR(socfpga_clk->sys_mgr_base_addr)) {
> - pr_err("%s: failed to find altr,sys-mgr regmap!\n",
> - __func__);
> - kfree(socfpga_clk);
> - return;
> - }
> - }
> -
> of_property_read_string(node, "clock-output-names", &clk_name);
>
> init.name = clk_name;
> diff --git a/drivers/clk/socfpga/clk-gate.c b/drivers/clk/socfpga/clk-gate.c
> index 53d6e3ec4309..3e347b9e9eff 100644
> --- a/drivers/clk/socfpga/clk-gate.c
> +++ b/drivers/clk/socfpga/clk-gate.c
> @@ -108,61 +108,7 @@ static unsigned long socfpga_clk_recalc_rate(struct clk_hw *hwclk,
> return parent_rate / div;
> }
>
> -static int socfpga_clk_prepare(struct clk_hw *hwclk)
> -{
> - struct socfpga_gate_clk *socfpgaclk = to_socfpga_gate_clk(hwclk);
> - struct regmap *sys_mgr_base_addr;
> - int i;
> - u32 hs_timing;
> - u32 clk_phase[2];
> -
> - if (socfpgaclk->clk_phase[0] || socfpgaclk->clk_phase[1]) {
> - sys_mgr_base_addr = syscon_regmap_lookup_by_compatible("altr,sys-mgr");
> - if (IS_ERR(sys_mgr_base_addr)) {
> - pr_err("%s: failed to find altr,sys-mgr regmap!\n", __func__);
> - return -EINVAL;
> - }
> -
> - for (i = 0; i < 2; i++) {
> - switch (socfpgaclk->clk_phase[i]) {
> - case 0:
> - clk_phase[i] = 0;
> - break;
> - case 45:
> - clk_phase[i] = 1;
> - break;
> - case 90:
> - clk_phase[i] = 2;
> - break;
> - case 135:
> - clk_phase[i] = 3;
> - break;
> - case 180:
> - clk_phase[i] = 4;
> - break;
> - case 225:
> - clk_phase[i] = 5;
> - break;
> - case 270:
> - clk_phase[i] = 6;
> - break;
> - case 315:
> - clk_phase[i] = 7;
> - break;
> - default:
> - clk_phase[i] = 0;
> - break;
> - }
> - }
> - hs_timing = SYSMGR_SDMMC_CTRL_SET(clk_phase[0], clk_phase[1]);
> - regmap_write(sys_mgr_base_addr, SYSMGR_SDMMCGRP_CTRL_OFFSET,
> - hs_timing);
> - }
> - return 0;
> -}
> -
> static struct clk_ops gateclk_ops = {
> - .prepare = socfpga_clk_prepare,
> .recalc_rate = socfpga_clk_recalc_rate,
> .get_parent = socfpga_clk_get_parent,
> .set_parent = socfpga_clk_set_parent,
> @@ -172,7 +118,6 @@ void __init socfpga_gate_init(struct device_node *node)
> {
> u32 clk_gate[2];
> u32 div_reg[3];
> - u32 clk_phase[2];
> u32 fixed_div;
> struct clk_hw *hw_clk;
> struct socfpga_gate_clk *socfpga_clk;
> @@ -218,12 +163,6 @@ void __init socfpga_gate_init(struct device_node *node)
> socfpga_clk->div_reg = NULL;
> }
>
> - rc = of_property_read_u32_array(node, "clk-phase", clk_phase, 2);
> - if (!rc) {
> - socfpga_clk->clk_phase[0] = clk_phase[0];
> - socfpga_clk->clk_phase[1] = clk_phase[1];
> - }
> -
> of_property_read_string(node, "clock-output-names", &clk_name);
>
> init.name = clk_name;
> diff --git a/drivers/clk/socfpga/clk.h b/drivers/clk/socfpga/clk.h
> index d80115fbdd6a..9a2fb2dde5b8 100644
> --- a/drivers/clk/socfpga/clk.h
> +++ b/drivers/clk/socfpga/clk.h
> @@ -50,7 +50,6 @@ struct socfpga_gate_clk {
> u32 width; /* only valid if div_reg != 0 */
> u32 shift; /* only valid if div_reg != 0 */
> u32 bypass_shift; /* only valid if bypass_reg != 0 */
> - u32 clk_phase[2];
> };
>
> struct socfpga_periph_clk {
> --
> 2.25.1
>

2022-11-18 10:10:35

by Ulf Hansson

[permalink] [raw]
Subject: Re: [PATCHv9 4/6] mmc: dw_mmc-pltfm: socfpga: add method to configure clk-phase

On Tue, 15 Nov 2022 at 00:02, Dinh Nguyen <[email protected]> wrote:
>
> The clock-phase settings for the SDMMC controller in the SoCFPGA
> platforms reside in a register in the System Manager. Add a method
> to access that register through the syscon interface.
>
> Signed-off-by: Dinh Nguyen <[email protected]>

Applied for next, thanks!

Kind regards
Uffe


> ---
> v9: no changes
> v8: no changes
> v7: use dev_warn if clk-phase-sd-hs is specified, but "altr,sysmgr-syscon"
> is not found
> v6: not getting the clk-phase-sd-hs is not a hard failure
> v5: change error handling from of_property_read_variable_u32_array()
> support arm32 by reading the reg_shift
> v4: no change
> v3: add space before &socfpga_drv_data
> v2: simplify clk-phase calculations
> ---
> drivers/mmc/host/dw_mmc-pltfm.c | 41 ++++++++++++++++++++++++++++++++-
> 1 file changed, 40 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/mmc/host/dw_mmc-pltfm.c b/drivers/mmc/host/dw_mmc-pltfm.c
> index 9901208be797..13e55cff8237 100644
> --- a/drivers/mmc/host/dw_mmc-pltfm.c
> +++ b/drivers/mmc/host/dw_mmc-pltfm.c
> @@ -17,10 +17,16 @@
> #include <linux/mmc/host.h>
> #include <linux/mmc/mmc.h>
> #include <linux/of.h>
> +#include <linux/mfd/altera-sysmgr.h>
> +#include <linux/regmap.h>
>
> #include "dw_mmc.h"
> #include "dw_mmc-pltfm.h"
>
> +#define SOCFPGA_DW_MMC_CLK_PHASE_STEP 45
> +#define SYSMGR_SDMMC_CTRL_SET(smplsel, drvsel, reg_shift) \
> + ((((smplsel) & 0x7) << reg_shift) | (((drvsel) & 0x7) << 0))
> +
> int dw_mci_pltfm_register(struct platform_device *pdev,
> const struct dw_mci_drv_data *drv_data)
> {
> @@ -62,9 +68,42 @@ const struct dev_pm_ops dw_mci_pltfm_pmops = {
> };
> EXPORT_SYMBOL_GPL(dw_mci_pltfm_pmops);
>
> +static int dw_mci_socfpga_priv_init(struct dw_mci *host)
> +{
> + struct device_node *np = host->dev->of_node;
> + struct regmap *sys_mgr_base_addr;
> + u32 clk_phase[2] = {0}, reg_offset, reg_shift;
> + int i, rc, hs_timing;
> +
> + rc = of_property_read_variable_u32_array(np, "clk-phase-sd-hs", &clk_phase[0], 2, 0);
> + if (rc < 0)
> + return 0;
> +
> + sys_mgr_base_addr = altr_sysmgr_regmap_lookup_by_phandle(np, "altr,sysmgr-syscon");
> + if (IS_ERR(sys_mgr_base_addr)) {
> + dev_warn(host->dev, "clk-phase-sd-hs was specified, but failed to find altr,sys-mgr regmap!\n");
> + return 0;
> + }
> +
> + of_property_read_u32_index(np, "altr,sysmgr-syscon", 1, &reg_offset);
> + of_property_read_u32_index(np, "altr,sysmgr-syscon", 2, &reg_shift);
> +
> + for (i = 0; i < ARRAY_SIZE(clk_phase); i++)
> + clk_phase[i] /= SOCFPGA_DW_MMC_CLK_PHASE_STEP;
> +
> + hs_timing = SYSMGR_SDMMC_CTRL_SET(clk_phase[0], clk_phase[1], reg_shift);
> + regmap_write(sys_mgr_base_addr, reg_offset, hs_timing);
> +
> + return 0;
> +}
> +
> +static const struct dw_mci_drv_data socfpga_drv_data = {
> + .init = dw_mci_socfpga_priv_init,
> +};
> +
> static const struct of_device_id dw_mci_pltfm_match[] = {
> { .compatible = "snps,dw-mshc", },
> - { .compatible = "altr,socfpga-dw-mshc", },
> + { .compatible = "altr,socfpga-dw-mshc", .data = &socfpga_drv_data, },
> { .compatible = "img,pistachio-dw-mshc", },
> {},
> };
> --
> 2.25.1
>