diff options
author | Andrew Jeffery <andrew@aj.id.au> | 2021-01-14 13:44:28 +1030 |
---|---|---|
committer | Ulf Hansson <ulf.hansson@linaro.org> | 2021-02-01 11:54:47 +0100 |
commit | 3561afa02605b398d1b98e1ce913ea6411cdc5dd (patch) | |
tree | 2cfabc460c4814f3be7c368db5792b2574212ce2 /drivers/mmc/core/host.c | |
parent | 7c7905df68c5ca5b3b20f41ef3f0d245ae6f32c3 (diff) |
mmc: core: Add helper for parsing clock phase properties
Drivers for MMC hosts that accept phase corrections can take advantage
of the helper by embedding an instance of struct mmc_clk_phase_map in
their private data and invoking mmc_of_parse_clk_phase() to extract
phase parameters. It is the responsibility of the host driver to
translate and apply the extracted values to hardware as required.
Signed-off-by: Andrew Jeffery <andrew@aj.id.au>
Link: https://lore.kernel.org/r/20210114031433.2388532-2-andrew@aj.id.au
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
Diffstat (limited to 'drivers/mmc/core/host.c')
-rw-r--r-- | drivers/mmc/core/host.c | 44 |
1 files changed, 44 insertions, 0 deletions
diff --git a/drivers/mmc/core/host.c b/drivers/mmc/core/host.c index 96b2ca1f1b06..74e853bb6948 100644 --- a/drivers/mmc/core/host.c +++ b/drivers/mmc/core/host.c @@ -163,6 +163,50 @@ static void mmc_retune_timer(struct timer_list *t) mmc_retune_needed(host); } +static void mmc_of_parse_timing_phase(struct device *dev, const char *prop, + struct mmc_clk_phase *phase) +{ + int degrees[2] = {0}; + int rc; + + rc = device_property_read_u32_array(dev, prop, degrees, 2); + phase->valid = !rc; + if (phase->valid) { + phase->in_deg = degrees[0]; + phase->out_deg = degrees[1]; + } +} + +void +mmc_of_parse_clk_phase(struct mmc_host *host, struct mmc_clk_phase_map *map) +{ + struct device *dev = host->parent; + + mmc_of_parse_timing_phase(dev, "clk-phase-legacy", + &map->phase[MMC_TIMING_LEGACY]); + mmc_of_parse_timing_phase(dev, "clk-phase-mmc-hs", + &map->phase[MMC_TIMING_MMC_HS]); + mmc_of_parse_timing_phase(dev, "clk-phase-sd-hs", + &map->phase[MMC_TIMING_SD_HS]); + mmc_of_parse_timing_phase(dev, "clk-phase-uhs-sdr12", + &map->phase[MMC_TIMING_UHS_SDR12]); + mmc_of_parse_timing_phase(dev, "clk-phase-uhs-sdr25", + &map->phase[MMC_TIMING_UHS_SDR25]); + mmc_of_parse_timing_phase(dev, "clk-phase-uhs-sdr50", + &map->phase[MMC_TIMING_UHS_SDR50]); + mmc_of_parse_timing_phase(dev, "clk-phase-uhs-sdr104", + &map->phase[MMC_TIMING_UHS_SDR104]); + mmc_of_parse_timing_phase(dev, "clk-phase-uhs-ddr50", + &map->phase[MMC_TIMING_UHS_DDR50]); + mmc_of_parse_timing_phase(dev, "clk-phase-mmc-ddr52", + &map->phase[MMC_TIMING_MMC_DDR52]); + mmc_of_parse_timing_phase(dev, "clk-phase-mmc-hs200", + &map->phase[MMC_TIMING_MMC_HS200]); + mmc_of_parse_timing_phase(dev, "clk-phase-mmc-hs400", + &map->phase[MMC_TIMING_MMC_HS400]); +} +EXPORT_SYMBOL(mmc_of_parse_clk_phase); + /** * mmc_of_parse() - parse host's device-tree node * @host: host whose node should be parsed. |