On Thu 17 Feb 2022 at 14:33, Liang Yang <liang.yang@xxxxxxxxxxx> wrote: > EMMC and NAND have the same clock control register named 'SD_EMMC_CLOCK' which is > defined in EMMC port internally. bit0~5 of 'SD_EMMC_CLOCK' is the divider and > bit6~7 is the mux for fix pll and xtal.A common MMC and NAND sub-clock has been > implemented and can be used by the eMMC and NAND controller (which are mutually > exclusive anyway). Let's use this new clock. > > Signed-off-by: Liang Yang <liang.yang@xxxxxxxxxxx> > --- > drivers/mtd/nand/raw/meson_nand.c | 107 +++++++++++++++++------------- > 1 file changed, 61 insertions(+), 46 deletions(-) > > diff --git a/drivers/mtd/nand/raw/meson_nand.c b/drivers/mtd/nand/raw/meson_nand.c > index ac3be92872d0..c5b892d38ea0 100644 > --- a/drivers/mtd/nand/raw/meson_nand.c > +++ b/drivers/mtd/nand/raw/meson_nand.c > @@ -10,6 +10,7 @@ > #include <linux/dma-mapping.h> > #include <linux/interrupt.h> > #include <linux/clk.h> > +#include <linux/clk-provider.h> > #include <linux/mtd/rawnand.h> > #include <linux/mtd/mtd.h> > #include <linux/mfd/syscon.h> > @@ -19,6 +20,7 @@ > #include <linux/iopoll.h> > #include <linux/of.h> > #include <linux/of_device.h> > +#include <linux/of_address.h> > #include <linux/sched/task_stack.h> > > #define NFC_REG_CMD 0x00 > @@ -104,6 +106,9 @@ > > #define PER_INFO_BYTE 8 > > +#define CLK_DIV_SHIFT 0 > +#define CLK_DIV_WIDTH 6 > + > struct meson_nfc_nand_chip { > struct list_head node; > struct nand_chip nand; > @@ -151,15 +156,15 @@ struct meson_nfc { > struct nand_controller controller; > struct clk *core_clk; > struct clk *device_clk; > - struct clk *phase_tx; > - struct clk *phase_rx; > + struct clk *nand_clk; > + struct clk_divider nand_divider; > > unsigned long clk_rate; > u32 bus_timing; > > struct device *dev; > void __iomem *reg_base; > - struct regmap *reg_clk; > + void __iomem *sd_emmc_clock; > struct completion completion; > struct list_head chips; > const struct meson_nfc_data *data; > @@ -988,6 +993,8 @@ static const struct mtd_ooblayout_ops meson_ooblayout_ops = { > static int meson_nfc_clk_init(struct meson_nfc *nfc) > { > int ret; > + struct clk_init_data init = {0}; > + struct clk_parent_data nfc_divider_parent_data[1]; > > /* request core clock */ > nfc->core_clk = devm_clk_get(nfc->dev, "core"); > @@ -1002,21 +1009,26 @@ static int meson_nfc_clk_init(struct meson_nfc *nfc) > return PTR_ERR(nfc->device_clk); > } > > - nfc->phase_tx = devm_clk_get(nfc->dev, "tx"); > - if (IS_ERR(nfc->phase_tx)) { > - dev_err(nfc->dev, "failed to get TX clk\n"); > - return PTR_ERR(nfc->phase_tx); > - } > - > - nfc->phase_rx = devm_clk_get(nfc->dev, "rx"); > - if (IS_ERR(nfc->phase_rx)) { > - dev_err(nfc->dev, "failed to get RX clk\n"); > - return PTR_ERR(nfc->phase_rx); > - } > + init.name = devm_kstrdup(nfc->dev, "nfc#div", GFP_KERNEL); > + init.ops = &clk_divider_ops; > + nfc_divider_parent_data[0].fw_name = __clk_get_name(nfc->device_clk); This is broken. __clk_get_name() gives the actual global name of the clock "fw_name" is the DT name which allows to find the index on the clock