diff --git a/Documentation/devicetree/bindings/mmc/amlogic,meson-gx-mmc.yaml b/Documentation/devicetree/bindings/mmc/amlogic,meson-gx-mmc.yaml index 57646575a13f8..3d45d0960e593 100644 --- a/Documentation/devicetree/bindings/mmc/amlogic,meson-gx-mmc.yaml +++ b/Documentation/devicetree/bindings/mmc/amlogic,meson-gx-mmc.yaml @@ -54,6 +54,16 @@ properties: power-domains: maxItems: 1 + amlogic,mmc-phases: + type: integer + description: | + 3-element array of clock phases for core, tx, rx clock with values: + 0: CLK_PHASE_0 - 0 phase + 1: CLK_PHASE_90 - 90 phase + 2: CLK_PHASE_180 - 180 phase + 3: CLK_PHASE_270 - 270 phase + By default driver use value. + required: - compatible - reg @@ -76,4 +86,5 @@ examples: clock-names = "core", "clkin0", "clkin1"; pinctrl-0 = <&emm_pins>; resets = <&reset_mmc>; + amlogic,mmc-phases = ; }; diff --git a/arch/arm64/boot/dts/amlogic/meson-axg.dtsi b/arch/arm64/boot/dts/amlogic/meson-axg.dtsi index 04fb130ac7c6a..02dc0ca215f2f 100644 --- a/arch/arm64/boot/dts/amlogic/meson-axg.dtsi +++ b/arch/arm64/boot/dts/amlogic/meson-axg.dtsi @@ -13,6 +13,7 @@ #include #include #include +#include / { compatible = "amlogic,meson-axg"; @@ -1959,6 +1960,7 @@ <&clkc CLKID_SD_EMMC_B_CLK0>, <&clkc CLKID_FCLK_DIV2>; clock-names = "core", "clkin0", "clkin1"; + amlogic,mmc-phase = ; resets = <&reset RESET_SD_EMMC_B>; }; @@ -1972,6 +1974,7 @@ <&clkc CLKID_FCLK_DIV2>; clock-names = "core", "clkin0", "clkin1"; resets = <&reset RESET_SD_EMMC_C>; + amlogic,mmc-phase = ; }; nfc: nand-controller@7800 { diff --git a/arch/arm64/boot/dts/amlogic/meson-g12a-radxa-zero.dts b/arch/arm64/boot/dts/amlogic/meson-g12a-radxa-zero.dts index 0289b2b1e8d1d..6de29b07446fa 100644 --- a/arch/arm64/boot/dts/amlogic/meson-g12a-radxa-zero.dts +++ b/arch/arm64/boot/dts/amlogic/meson-g12a-radxa-zero.dts @@ -10,6 +10,7 @@ #include #include #include +#include / { compatible = "radxa,zero", "amlogic,g12a"; @@ -477,6 +478,8 @@ mmc-pwrseq = <&emmc_pwrseq>; vmmc-supply = <&vcc_3v3>; vqmmc-supply = <&vcc_1v8>; + + amlogic,mmc-phase = ; }; &tdmif_b { diff --git a/drivers/mmc/host/meson-gx-mmc.c b/drivers/mmc/host/meson-gx-mmc.c index 694bb443d5f3f..202412d3c41c6 100644 --- a/drivers/mmc/host/meson-gx-mmc.c +++ b/drivers/mmc/host/meson-gx-mmc.c @@ -27,6 +27,7 @@ #include #include #include +#include #define DRIVER_NAME "meson-gx-mmc" @@ -36,8 +37,6 @@ #define CLK_CORE_PHASE_MASK GENMASK(9, 8) #define CLK_TX_PHASE_MASK GENMASK(11, 10) #define CLK_RX_PHASE_MASK GENMASK(13, 12) -#define CLK_PHASE_0 0 -#define CLK_PHASE_180 2 #define CLK_V2_TX_DELAY_MASK GENMASK(19, 16) #define CLK_V2_RX_DELAY_MASK GENMASK(23, 20) #define CLK_V2_ALWAYS_ON BIT(24) @@ -426,13 +425,21 @@ static int meson_mmc_clk_init(struct meson_host *host) const char *mux_parent_names[MUX_CLK_NUM_PARENTS]; const char *clk_parent[1]; u32 clk_reg; - + u32 phase[3]; // + + if (!(host->dev && host->dev->of_node) || (device_property_read_u32_array(host->dev, + "amlogic,mmc-phase", phase, 3) < 0)) { + dev_dbg(host->dev, "get amlogic,mmc-phase failed, use default phase settings\n"); + phase[0] = CLK_PHASE_180; + phase[1] = CLK_PHASE_0; + phase[2] = CLK_PHASE_0; + } /* init SD_EMMC_CLOCK to sane defaults w/min clock rate */ clk_reg = CLK_ALWAYS_ON(host); clk_reg |= CLK_DIV_MASK; - clk_reg |= FIELD_PREP(CLK_CORE_PHASE_MASK, CLK_PHASE_180); - clk_reg |= FIELD_PREP(CLK_TX_PHASE_MASK, CLK_PHASE_0); - clk_reg |= FIELD_PREP(CLK_RX_PHASE_MASK, CLK_PHASE_0); + clk_reg |= FIELD_PREP(CLK_CORE_PHASE_MASK, phase[0]); + clk_reg |= FIELD_PREP(CLK_TX_PHASE_MASK, phase[1]); + clk_reg |= FIELD_PREP(CLK_RX_PHASE_MASK, phase[2]); if (host->mmc->caps & MMC_CAP_SDIO_IRQ) clk_reg |= CLK_IRQ_SDIO_SLEEP(host); writel(clk_reg, host->regs + SD_EMMC_CLOCK); diff --git a/include/dt-bindings/mmc/meson-gx-mmc.h b/include/dt-bindings/mmc/meson-gx-mmc.h new file mode 100644 index 0000000000000..cfc4a9d75b2b1 --- /dev/null +++ b/include/dt-bindings/mmc/meson-gx-mmc.h @@ -0,0 +1,35 @@ +/* SPDX-License-Identifier: (GPL-2.0+ or MIT) */ +/* + * Copyright (c) 2022 Vyacheslav Bocharov + * Author: Vyacheslav Bocharov + */ + +#ifndef _DT_BINDINGS_MESON_GX_MMC_H +#define _DT_BINDINGS_MESON_GX_MMC_H + +/* + * Cfg_rx_phase: RX clock phase + * bits: 9:8 R/W + * default: 0 + * Recommended value: 0 + * + * Cfg_tx_phase: TX clock phase + * bits: 9:8 R/W + * default: 0 + * Recommended value: 2 + * + * Cfg_co_phase: Core clock phase + * bits: 9:8 R/W + * default: 0 + * Recommended value: 2 + * + * values: 0: 0 phase, 1: 90 phase, 2: 180 phase, 3: 270 phase. + */ + +#define CLK_PHASE_0 0 +#define CLK_PHASE_90 1 +#define CLK_PHASE_180 2 +#define CLK_PHASE_270 3 + + +#endif