mtd: rawnand: denali_dt: add more clocks based on IP datasheet

Currently, denali_dt.c requires a single anonymous clock, but
the Denali User's Guide requires three clocks for this IP:

 - clk: controller core clock

 - clk_x: bus interface clock

 - ecc_clk: clock at which ECC circuitry is run

This commit supports these named clocks to represent the real hardware.

For the backward compatibility, the driver still accepts a single clock
just as before.  The clk_x_rate is taken from the clock driver again if
the named clock "clk_x" is available.  This will happen only for future
DT, hence the existing DT files are not affected.

Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
Reviewed-by: Richard Weinberger <richard@nod.at>
Tested-by: Richard Weinberger <richard@nod.at>
Reviewed-by: Boris Brezillon <boris.brezillon@bootlin.com>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
This commit is contained in:
Masahiro Yamada 2018-06-23 01:06:37 +09:00 committed by Miquel Raynal
parent d91e8a3eec
commit 6f1fe97bec

View File

@ -27,7 +27,9 @@
struct denali_dt {
struct denali_nand_info denali;
struct clk *clk;
struct clk *clk; /* core clock */
struct clk *clk_x; /* bus interface clock */
struct clk *clk_ecc; /* ECC circuit clock */
};
struct denali_dt_data {
@ -115,28 +117,61 @@ static int denali_dt_probe(struct platform_device *pdev)
if (IS_ERR(denali->host))
return PTR_ERR(denali->host);
dt->clk = devm_clk_get(dev, NULL);
/*
* A single anonymous clock is supported for the backward compatibility.
* New platforms should support all the named clocks.
*/
dt->clk = devm_clk_get(dev, "nand");
if (IS_ERR(dt->clk))
dt->clk = devm_clk_get(dev, NULL);
if (IS_ERR(dt->clk)) {
dev_err(dev, "no clk available\n");
return PTR_ERR(dt->clk);
}
dt->clk_x = devm_clk_get(dev, "nand_x");
if (IS_ERR(dt->clk_x))
dt->clk_x = NULL;
dt->clk_ecc = devm_clk_get(dev, "ecc");
if (IS_ERR(dt->clk_ecc))
dt->clk_ecc = NULL;
ret = clk_prepare_enable(dt->clk);
if (ret)
return ret;
/*
* Hardcode the clock rate for the backward compatibility.
* This works for both SOCFPGA and UniPhier.
*/
denali->clk_x_rate = 200000000;
ret = clk_prepare_enable(dt->clk_x);
if (ret)
goto out_disable_clk;
ret = clk_prepare_enable(dt->clk_ecc);
if (ret)
goto out_disable_clk_x;
if (dt->clk_x) {
denali->clk_x_rate = clk_get_rate(dt->clk_x);
} else {
/*
* Hardcode the clock rates for the backward compatibility.
* This works for both SOCFPGA and UniPhier.
*/
dev_notice(dev,
"necessary clock is missing. default clock rates are used.\n");
denali->clk_x_rate = 200000000;
}
ret = denali_init(denali);
if (ret)
goto out_disable_clk;
goto out_disable_clk_ecc;
platform_set_drvdata(pdev, dt);
return 0;
out_disable_clk_ecc:
clk_disable_unprepare(dt->clk_ecc);
out_disable_clk_x:
clk_disable_unprepare(dt->clk_x);
out_disable_clk:
clk_disable_unprepare(dt->clk);
@ -148,6 +183,8 @@ static int denali_dt_remove(struct platform_device *pdev)
struct denali_dt *dt = platform_get_drvdata(pdev);
denali_remove(&dt->denali);
clk_disable_unprepare(dt->clk_ecc);
clk_disable_unprepare(dt->clk_x);
clk_disable_unprepare(dt->clk);
return 0;