clk: renesas: Updates for v5.17
- Add serial (SCI1), watchdog (WDT), timer (OSTM), SPI (RSPI), and thermal (TSU) clocks and resets on RZ/G2L, - Rework SDHI clock handling in the R-Car Gen3 and RZ/G2 clock drivers, and in the Renesas SDHI driver, - Make the Cortex-A55 (I) clock on RZ/G2L programmable, - Document support for the new R-Car S4-8 (R8A779F0) SoC, - Miscellaneous fixes and improvements. -----BEGIN PGP SIGNATURE----- iHUEABYIAB0WIQQ9qaHoIs/1I4cXmEiKwlD9ZEnxcAUCYan39AAKCRCKwlD9ZEnx cA2SAQD5SrXssNvqpiA0yFT+JZXDPouF1L2OfMkvBUX0bEgA3AEAh846DQtx5XKQ 8DlNi366Iqj5mWvrfI5vkFe2hlZqbQ4= =qDzV -----END PGP SIGNATURE----- Merge tag 'renesas-clk-for-v5.17-tag1' of git://git.kernel.org/pub/scm/linux/kernel/git/geert/renesas-drivers into clk-renesas Pull Renesas clk driver updates from Geert Uytterhoeven: - Add serial (SCI1), watchdog (WDT), timer (OSTM), SPI (RSPI), and thermal (TSU) clocks and resets on RZ/G2L - Rework SDHI clock handling in the R-Car Gen3 and RZ/G2 clock drivers, and in the Renesas SDHI driver - Make the Cortex-A55 (I) clock on RZ/G2L programmable, - Document support for the new R-Car S4-8 (R8A779F0) SoC - Miscellaneous fixes and improvements * tag 'renesas-clk-for-v5.17-tag1' of git://git.kernel.org/pub/scm/linux/kernel/git/geert/renesas-drivers: (24 commits) clk: renesas: r9a07g044: Add TSU clock and reset entry mmc: renesas_sdhi: Simplify an expression mmc: renesas_sdhi: Use devm_clk_get_optional() to obtain CD clock dt-bindings: clock: renesas,cpg-mssr: Document r8a779f0 clk: renesas: cpg-mssr: propagate return value of_genpd_add_provider_simple() clk: renesas: cpg-mssr: Check return value of pm_genpd_init() clk: renesas: rzg2l: propagate return value of_genpd_add_provider_simple() clk: renesas: rzg2l: Check return value of pm_genpd_init() clk: renesas: r9a07g044: Add RSPI clock and reset entries clk: renesas: r9a07g044: Change core clock "I" from DEF_FIXED->DEF_DIV clk: renesas: rzg2l: Add CPG_PL1_DDIV macro mmc: renesas_sdhi: Parse DT for SDnH mmc: renesas_sdhi: Use dev_err_probe when getting clock fails clk: renesas: rcar-gen3: Remove outdated SD_SKIP_FIRST clk: renesas: rcar-gen3: Switch to new SD clock handling mmc: renesas_sdhi: Flag non-standard SDnH handling for V3M clk: renesas: r8a779a0: Add SDnH clock to V3U clk: renesas: rcar-gen3: Add SDnH clock clk: renesas: rcar-gen3: Add dummy SDnH clock clk: renesas: r9a07g044: Add OSTM clock and reset entries ...
This commit is contained in:
commit
1dfeb03e86
@ -48,6 +48,7 @@ properties:
|
||||
- renesas,r8a77990-cpg-mssr # R-Car E3
|
||||
- renesas,r8a77995-cpg-mssr # R-Car D3
|
||||
- renesas,r8a779a0-cpg-mssr # R-Car V3U
|
||||
- renesas,r8a779f0-cpg-mssr # R-Car S4-8
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
@ -100,10 +100,14 @@ static const struct cpg_core_clk r8a774a1_core_clks[] __initconst = {
|
||||
DEF_FIXED("s3d2", R8A774A1_CLK_S3D2, CLK_S3, 2, 1),
|
||||
DEF_FIXED("s3d4", R8A774A1_CLK_S3D4, CLK_S3, 4, 1),
|
||||
|
||||
DEF_GEN3_SD("sd0", R8A774A1_CLK_SD0, CLK_SDSRC, 0x074),
|
||||
DEF_GEN3_SD("sd1", R8A774A1_CLK_SD1, CLK_SDSRC, 0x078),
|
||||
DEF_GEN3_SD("sd2", R8A774A1_CLK_SD2, CLK_SDSRC, 0x268),
|
||||
DEF_GEN3_SD("sd3", R8A774A1_CLK_SD3, CLK_SDSRC, 0x26c),
|
||||
DEF_GEN3_SDH("sd0h", R8A774A1_CLK_SD0H, CLK_SDSRC, 0x074),
|
||||
DEF_GEN3_SDH("sd1h", R8A774A1_CLK_SD1H, CLK_SDSRC, 0x078),
|
||||
DEF_GEN3_SDH("sd2h", R8A774A1_CLK_SD2H, CLK_SDSRC, 0x268),
|
||||
DEF_GEN3_SDH("sd3h", R8A774A1_CLK_SD3H, CLK_SDSRC, 0x26c),
|
||||
DEF_GEN3_SD("sd0", R8A774A1_CLK_SD0, R8A774A1_CLK_SD0H, 0x074),
|
||||
DEF_GEN3_SD("sd1", R8A774A1_CLK_SD1, R8A774A1_CLK_SD1H, 0x078),
|
||||
DEF_GEN3_SD("sd2", R8A774A1_CLK_SD2, R8A774A1_CLK_SD2H, 0x268),
|
||||
DEF_GEN3_SD("sd3", R8A774A1_CLK_SD3, R8A774A1_CLK_SD3H, 0x26c),
|
||||
|
||||
DEF_FIXED("cl", R8A774A1_CLK_CL, CLK_PLL1_DIV2, 48, 1),
|
||||
DEF_FIXED("cp", R8A774A1_CLK_CP, CLK_EXTAL, 2, 1),
|
||||
|
@ -97,10 +97,14 @@ static const struct cpg_core_clk r8a774b1_core_clks[] __initconst = {
|
||||
DEF_FIXED("s3d2", R8A774B1_CLK_S3D2, CLK_S3, 2, 1),
|
||||
DEF_FIXED("s3d4", R8A774B1_CLK_S3D4, CLK_S3, 4, 1),
|
||||
|
||||
DEF_GEN3_SD("sd0", R8A774B1_CLK_SD0, CLK_SDSRC, 0x074),
|
||||
DEF_GEN3_SD("sd1", R8A774B1_CLK_SD1, CLK_SDSRC, 0x078),
|
||||
DEF_GEN3_SD("sd2", R8A774B1_CLK_SD2, CLK_SDSRC, 0x268),
|
||||
DEF_GEN3_SD("sd3", R8A774B1_CLK_SD3, CLK_SDSRC, 0x26c),
|
||||
DEF_GEN3_SDH("sd0h", R8A774B1_CLK_SD0H, CLK_SDSRC, 0x074),
|
||||
DEF_GEN3_SDH("sd1h", R8A774B1_CLK_SD1H, CLK_SDSRC, 0x078),
|
||||
DEF_GEN3_SDH("sd2h", R8A774B1_CLK_SD2H, CLK_SDSRC, 0x268),
|
||||
DEF_GEN3_SDH("sd3h", R8A774B1_CLK_SD3H, CLK_SDSRC, 0x26c),
|
||||
DEF_GEN3_SD("sd0", R8A774B1_CLK_SD0, R8A774B1_CLK_SD0H, 0x074),
|
||||
DEF_GEN3_SD("sd1", R8A774B1_CLK_SD1, R8A774B1_CLK_SD1H, 0x078),
|
||||
DEF_GEN3_SD("sd2", R8A774B1_CLK_SD2, R8A774B1_CLK_SD2H, 0x268),
|
||||
DEF_GEN3_SD("sd3", R8A774B1_CLK_SD3, R8A774B1_CLK_SD3H, 0x26c),
|
||||
|
||||
DEF_FIXED("cl", R8A774B1_CLK_CL, CLK_PLL1_DIV2, 48, 1),
|
||||
DEF_FIXED("cp", R8A774B1_CLK_CP, CLK_EXTAL, 2, 1),
|
||||
|
@ -108,9 +108,12 @@ static const struct cpg_core_clk r8a774c0_core_clks[] __initconst = {
|
||||
DEF_FIXED("s3d2", R8A774C0_CLK_S3D2, CLK_S3, 2, 1),
|
||||
DEF_FIXED("s3d4", R8A774C0_CLK_S3D4, CLK_S3, 4, 1),
|
||||
|
||||
DEF_GEN3_SD("sd0", R8A774C0_CLK_SD0, CLK_SDSRC, 0x0074),
|
||||
DEF_GEN3_SD("sd1", R8A774C0_CLK_SD1, CLK_SDSRC, 0x0078),
|
||||
DEF_GEN3_SD("sd3", R8A774C0_CLK_SD3, CLK_SDSRC, 0x026c),
|
||||
DEF_GEN3_SDH("sd0h", R8A774C0_CLK_SD0H, CLK_SDSRC, 0x0074),
|
||||
DEF_GEN3_SDH("sd1h", R8A774C0_CLK_SD1H, CLK_SDSRC, 0x0078),
|
||||
DEF_GEN3_SDH("sd3h", R8A774C0_CLK_SD3H, CLK_SDSRC, 0x026c),
|
||||
DEF_GEN3_SD("sd0", R8A774C0_CLK_SD0, R8A774C0_CLK_SD0H, 0x0074),
|
||||
DEF_GEN3_SD("sd1", R8A774C0_CLK_SD1, R8A774C0_CLK_SD1H, 0x0078),
|
||||
DEF_GEN3_SD("sd3", R8A774C0_CLK_SD3, R8A774C0_CLK_SD3H, 0x026c),
|
||||
|
||||
DEF_FIXED("cl", R8A774C0_CLK_CL, CLK_PLL1, 48, 1),
|
||||
DEF_FIXED("cp", R8A774C0_CLK_CP, CLK_EXTAL, 2, 1),
|
||||
|
@ -100,10 +100,14 @@ static const struct cpg_core_clk r8a774e1_core_clks[] __initconst = {
|
||||
DEF_FIXED("s3d2", R8A774E1_CLK_S3D2, CLK_S3, 2, 1),
|
||||
DEF_FIXED("s3d4", R8A774E1_CLK_S3D4, CLK_S3, 4, 1),
|
||||
|
||||
DEF_GEN3_SD("sd0", R8A774E1_CLK_SD0, CLK_SDSRC, 0x074),
|
||||
DEF_GEN3_SD("sd1", R8A774E1_CLK_SD1, CLK_SDSRC, 0x078),
|
||||
DEF_GEN3_SD("sd2", R8A774E1_CLK_SD2, CLK_SDSRC, 0x268),
|
||||
DEF_GEN3_SD("sd3", R8A774E1_CLK_SD3, CLK_SDSRC, 0x26c),
|
||||
DEF_GEN3_SDH("sd0h", R8A774E1_CLK_SD0H, CLK_SDSRC, 0x074),
|
||||
DEF_GEN3_SDH("sd1h", R8A774E1_CLK_SD1H, CLK_SDSRC, 0x078),
|
||||
DEF_GEN3_SDH("sd2h", R8A774E1_CLK_SD2H, CLK_SDSRC, 0x268),
|
||||
DEF_GEN3_SDH("sd3h", R8A774E1_CLK_SD3H, CLK_SDSRC, 0x26c),
|
||||
DEF_GEN3_SD("sd0", R8A774E1_CLK_SD0, R8A774E1_CLK_SD0H, 0x074),
|
||||
DEF_GEN3_SD("sd1", R8A774E1_CLK_SD1, R8A774E1_CLK_SD1H, 0x078),
|
||||
DEF_GEN3_SD("sd2", R8A774E1_CLK_SD2, R8A774E1_CLK_SD2H, 0x268),
|
||||
DEF_GEN3_SD("sd3", R8A774E1_CLK_SD3, R8A774E1_CLK_SD3H, 0x26c),
|
||||
|
||||
DEF_FIXED("cl", R8A774E1_CLK_CL, CLK_PLL1_DIV2, 48, 1),
|
||||
DEF_FIXED("cr", R8A774E1_CLK_CR, CLK_PLL1_DIV4, 2, 1),
|
||||
|
@ -104,10 +104,14 @@ static struct cpg_core_clk r8a7795_core_clks[] __initdata = {
|
||||
DEF_FIXED("s3d2", R8A7795_CLK_S3D2, CLK_S3, 2, 1),
|
||||
DEF_FIXED("s3d4", R8A7795_CLK_S3D4, CLK_S3, 4, 1),
|
||||
|
||||
DEF_GEN3_SD("sd0", R8A7795_CLK_SD0, CLK_SDSRC, 0x074),
|
||||
DEF_GEN3_SD("sd1", R8A7795_CLK_SD1, CLK_SDSRC, 0x078),
|
||||
DEF_GEN3_SD("sd2", R8A7795_CLK_SD2, CLK_SDSRC, 0x268),
|
||||
DEF_GEN3_SD("sd3", R8A7795_CLK_SD3, CLK_SDSRC, 0x26c),
|
||||
DEF_GEN3_SDH("sd0h", R8A7795_CLK_SD0H, CLK_SDSRC, 0x074),
|
||||
DEF_GEN3_SDH("sd1h", R8A7795_CLK_SD1H, CLK_SDSRC, 0x078),
|
||||
DEF_GEN3_SDH("sd2h", R8A7795_CLK_SD2H, CLK_SDSRC, 0x268),
|
||||
DEF_GEN3_SDH("sd3h", R8A7795_CLK_SD3H, CLK_SDSRC, 0x26c),
|
||||
DEF_GEN3_SD("sd0", R8A7795_CLK_SD0, R8A7795_CLK_SD0H, 0x074),
|
||||
DEF_GEN3_SD("sd1", R8A7795_CLK_SD1, R8A7795_CLK_SD1H, 0x078),
|
||||
DEF_GEN3_SD("sd2", R8A7795_CLK_SD2, R8A7795_CLK_SD2H, 0x268),
|
||||
DEF_GEN3_SD("sd3", R8A7795_CLK_SD3, R8A7795_CLK_SD3H, 0x26c),
|
||||
|
||||
DEF_FIXED("cl", R8A7795_CLK_CL, CLK_PLL1_DIV2, 48, 1),
|
||||
DEF_FIXED("cr", R8A7795_CLK_CR, CLK_PLL1_DIV4, 2, 1),
|
||||
|
@ -106,10 +106,14 @@ static const struct cpg_core_clk r8a7796_core_clks[] __initconst = {
|
||||
DEF_FIXED("s3d2", R8A7796_CLK_S3D2, CLK_S3, 2, 1),
|
||||
DEF_FIXED("s3d4", R8A7796_CLK_S3D4, CLK_S3, 4, 1),
|
||||
|
||||
DEF_GEN3_SD("sd0", R8A7796_CLK_SD0, CLK_SDSRC, 0x074),
|
||||
DEF_GEN3_SD("sd1", R8A7796_CLK_SD1, CLK_SDSRC, 0x078),
|
||||
DEF_GEN3_SD("sd2", R8A7796_CLK_SD2, CLK_SDSRC, 0x268),
|
||||
DEF_GEN3_SD("sd3", R8A7796_CLK_SD3, CLK_SDSRC, 0x26c),
|
||||
DEF_GEN3_SDH("sd0h", R8A7796_CLK_SD0H, CLK_SDSRC, 0x074),
|
||||
DEF_GEN3_SDH("sd1h", R8A7796_CLK_SD1H, CLK_SDSRC, 0x078),
|
||||
DEF_GEN3_SDH("sd2h", R8A7796_CLK_SD2H, CLK_SDSRC, 0x268),
|
||||
DEF_GEN3_SDH("sd3h", R8A7796_CLK_SD3H, CLK_SDSRC, 0x26c),
|
||||
DEF_GEN3_SD("sd0", R8A7796_CLK_SD0, R8A7796_CLK_SD0H, 0x074),
|
||||
DEF_GEN3_SD("sd1", R8A7796_CLK_SD1, R8A7796_CLK_SD1H, 0x078),
|
||||
DEF_GEN3_SD("sd2", R8A7796_CLK_SD2, R8A7796_CLK_SD2H, 0x268),
|
||||
DEF_GEN3_SD("sd3", R8A7796_CLK_SD3, R8A7796_CLK_SD3H, 0x26c),
|
||||
|
||||
DEF_FIXED("cl", R8A7796_CLK_CL, CLK_PLL1_DIV2, 48, 1),
|
||||
DEF_FIXED("cr", R8A7796_CLK_CR, CLK_PLL1_DIV4, 2, 1),
|
||||
|
@ -101,10 +101,14 @@ static const struct cpg_core_clk r8a77965_core_clks[] __initconst = {
|
||||
DEF_FIXED("s3d2", R8A77965_CLK_S3D2, CLK_S3, 2, 1),
|
||||
DEF_FIXED("s3d4", R8A77965_CLK_S3D4, CLK_S3, 4, 1),
|
||||
|
||||
DEF_GEN3_SD("sd0", R8A77965_CLK_SD0, CLK_SDSRC, 0x074),
|
||||
DEF_GEN3_SD("sd1", R8A77965_CLK_SD1, CLK_SDSRC, 0x078),
|
||||
DEF_GEN3_SD("sd2", R8A77965_CLK_SD2, CLK_SDSRC, 0x268),
|
||||
DEF_GEN3_SD("sd3", R8A77965_CLK_SD3, CLK_SDSRC, 0x26c),
|
||||
DEF_GEN3_SDH("sd0h", R8A77965_CLK_SD0H, CLK_SDSRC, 0x074),
|
||||
DEF_GEN3_SDH("sd1h", R8A77965_CLK_SD1H, CLK_SDSRC, 0x078),
|
||||
DEF_GEN3_SDH("sd2h", R8A77965_CLK_SD2H, CLK_SDSRC, 0x268),
|
||||
DEF_GEN3_SDH("sd3h", R8A77965_CLK_SD3H, CLK_SDSRC, 0x26c),
|
||||
DEF_GEN3_SD("sd0", R8A77965_CLK_SD0, R8A77965_CLK_SD0H, 0x074),
|
||||
DEF_GEN3_SD("sd1", R8A77965_CLK_SD1, R8A77965_CLK_SD1H, 0x078),
|
||||
DEF_GEN3_SD("sd2", R8A77965_CLK_SD2, R8A77965_CLK_SD2H, 0x268),
|
||||
DEF_GEN3_SD("sd3", R8A77965_CLK_SD3, R8A77965_CLK_SD3H, 0x26c),
|
||||
|
||||
DEF_FIXED("cl", R8A77965_CLK_CL, CLK_PLL1_DIV2, 48, 1),
|
||||
DEF_FIXED("cr", R8A77965_CLK_CR, CLK_PLL1_DIV4, 2, 1),
|
||||
|
@ -96,7 +96,8 @@ static const struct cpg_core_clk r8a77980_core_clks[] __initconst = {
|
||||
DEF_FIXED("s3d2", R8A77980_CLK_S3D2, CLK_S3, 2, 1),
|
||||
DEF_FIXED("s3d4", R8A77980_CLK_S3D4, CLK_S3, 4, 1),
|
||||
|
||||
DEF_GEN3_SD("sd0", R8A77980_CLK_SD0, CLK_SDSRC, 0x0074),
|
||||
DEF_GEN3_SDH("sd0h", R8A77980_CLK_SD0H, CLK_SDSRC, 0x0074),
|
||||
DEF_GEN3_SD("sd0", R8A77980_CLK_SD0, R8A77980_CLK_SD0H, 0x0074),
|
||||
|
||||
DEF_FIXED("cl", R8A77980_CLK_CL, CLK_PLL1_DIV2, 48, 1),
|
||||
DEF_FIXED("cp", R8A77980_CLK_CP, CLK_EXTAL, 2, 1),
|
||||
|
@ -100,9 +100,12 @@ static const struct cpg_core_clk r8a77990_core_clks[] __initconst = {
|
||||
DEF_FIXED("s3d2", R8A77990_CLK_S3D2, CLK_S3, 2, 1),
|
||||
DEF_FIXED("s3d4", R8A77990_CLK_S3D4, CLK_S3, 4, 1),
|
||||
|
||||
DEF_GEN3_SD("sd0", R8A77990_CLK_SD0, CLK_SDSRC, 0x0074),
|
||||
DEF_GEN3_SD("sd1", R8A77990_CLK_SD1, CLK_SDSRC, 0x0078),
|
||||
DEF_GEN3_SD("sd3", R8A77990_CLK_SD3, CLK_SDSRC, 0x026c),
|
||||
DEF_GEN3_SDH("sd0h", R8A77990_CLK_SD0H, CLK_SDSRC, 0x0074),
|
||||
DEF_GEN3_SDH("sd1h", R8A77990_CLK_SD1H, CLK_SDSRC, 0x0078),
|
||||
DEF_GEN3_SDH("sd3h", R8A77990_CLK_SD3H, CLK_SDSRC, 0x026c),
|
||||
DEF_GEN3_SD("sd0", R8A77990_CLK_SD0, R8A77990_CLK_SD0H, 0x0074),
|
||||
DEF_GEN3_SD("sd1", R8A77990_CLK_SD1, R8A77990_CLK_SD1H, 0x0078),
|
||||
DEF_GEN3_SD("sd3", R8A77990_CLK_SD3, R8A77990_CLK_SD3H, 0x026c),
|
||||
|
||||
DEF_FIXED("cl", R8A77990_CLK_CL, CLK_PLL1, 48, 1),
|
||||
DEF_FIXED("cr", R8A77990_CLK_CR, CLK_PLL1D2, 2, 1),
|
||||
|
@ -103,7 +103,8 @@ static const struct cpg_core_clk r8a77995_core_clks[] __initconst = {
|
||||
DEF_GEN3_PE("s3d2c", R8A77995_CLK_S3D2C, CLK_S3, 2, CLK_PE, 2),
|
||||
DEF_GEN3_PE("s3d4c", R8A77995_CLK_S3D4C, CLK_S3, 4, CLK_PE, 4),
|
||||
|
||||
DEF_GEN3_SD("sd0", R8A77995_CLK_SD0, CLK_SDSRC, 0x268),
|
||||
DEF_GEN3_SDH("sd0h", R8A77995_CLK_SD0H, CLK_SDSRC, 0x268),
|
||||
DEF_GEN3_SD("sd0", R8A77995_CLK_SD0, R8A77995_CLK_SD0H, 0x268),
|
||||
|
||||
DEF_DIV6P1("canfd", R8A77995_CLK_CANFD, CLK_PLL0D3, 0x244),
|
||||
DEF_DIV6P1("mso", R8A77995_CLK_MSO, CLK_PLL1D2, 0x014),
|
||||
|
@ -34,6 +34,7 @@ enum rcar_r8a779a0_clk_types {
|
||||
CLK_TYPE_R8A779A0_PLL2X_3X, /* PLL[23][01] */
|
||||
CLK_TYPE_R8A779A0_PLL5,
|
||||
CLK_TYPE_R8A779A0_Z,
|
||||
CLK_TYPE_R8A779A0_SDH,
|
||||
CLK_TYPE_R8A779A0_SD,
|
||||
CLK_TYPE_R8A779A0_MDSEL, /* Select parent/divider using mode pin */
|
||||
CLK_TYPE_R8A779A0_OSC, /* OSC EXTAL predivider and fixed divider */
|
||||
@ -92,6 +93,9 @@ enum clk_ids {
|
||||
DEF_BASE(_name, _id, CLK_TYPE_R8A779A0_Z, _parent, .div = _div, \
|
||||
.offset = _offset)
|
||||
|
||||
#define DEF_SDH(_name, _id, _parent, _offset) \
|
||||
DEF_BASE(_name, _id, CLK_TYPE_R8A779A0_SDH, _parent, .offset = _offset)
|
||||
|
||||
#define DEF_SD(_name, _id, _parent, _offset) \
|
||||
DEF_BASE(_name, _id, CLK_TYPE_R8A779A0_SD, _parent, .offset = _offset)
|
||||
|
||||
@ -159,7 +163,8 @@ static const struct cpg_core_clk r8a779a0_core_clks[] __initconst = {
|
||||
DEF_FIXED("cp", R8A779A0_CLK_CP, CLK_EXTAL, 2, 1),
|
||||
DEF_FIXED("cl16mck", R8A779A0_CLK_CL16MCK, CLK_PLL1_DIV2, 64, 1),
|
||||
|
||||
DEF_SD("sd0", R8A779A0_CLK_SD0, CLK_SDSRC, 0x870),
|
||||
DEF_SDH("sdh0", R8A779A0_CLK_SD0H, CLK_SDSRC, 0x870),
|
||||
DEF_SD("sd0", R8A779A0_CLK_SD0, R8A779A0_CLK_SD0H, 0x870),
|
||||
|
||||
DEF_DIV6P1("mso", R8A779A0_CLK_MSO, CLK_PLL5_DIV4, 0x87c),
|
||||
DEF_DIV6P1("canfd", R8A779A0_CLK_CANFD, CLK_PLL5_DIV4, 0x878),
|
||||
@ -469,11 +474,13 @@ static struct clk * __init rcar_r8a779a0_cpg_clk_register(struct device *dev,
|
||||
return cpg_z_clk_register(core->name, __clk_get_name(parent),
|
||||
base, core->div, core->offset);
|
||||
|
||||
case CLK_TYPE_R8A779A0_SDH:
|
||||
return cpg_sdh_clk_register(core->name, base + core->offset,
|
||||
__clk_get_name(parent), notifiers);
|
||||
|
||||
case CLK_TYPE_R8A779A0_SD:
|
||||
return cpg_sd_clk_register(core->name, base, core->offset,
|
||||
__clk_get_name(parent), notifiers,
|
||||
false);
|
||||
break;
|
||||
return cpg_sd_clk_register(core->name, base + core->offset,
|
||||
__clk_get_name(parent));
|
||||
|
||||
case CLK_TYPE_R8A779A0_MDSEL:
|
||||
/*
|
||||
|
@ -26,8 +26,8 @@ enum clk_ids {
|
||||
CLK_PLL1,
|
||||
CLK_PLL2,
|
||||
CLK_PLL2_DIV2,
|
||||
CLK_PLL2_DIV16,
|
||||
CLK_PLL2_DIV20,
|
||||
CLK_PLL2_DIV2_8,
|
||||
CLK_PLL2_DIV2_10,
|
||||
CLK_PLL3,
|
||||
CLK_PLL3_400,
|
||||
CLK_PLL3_533,
|
||||
@ -56,6 +56,14 @@ enum clk_ids {
|
||||
};
|
||||
|
||||
/* Divider tables */
|
||||
static const struct clk_div_table dtable_1_8[] = {
|
||||
{0, 1},
|
||||
{1, 2},
|
||||
{2, 4},
|
||||
{3, 8},
|
||||
{0, 0},
|
||||
};
|
||||
|
||||
static const struct clk_div_table dtable_1_32[] = {
|
||||
{0, 1},
|
||||
{1, 2},
|
||||
@ -94,8 +102,8 @@ static const struct cpg_core_clk r9a07g044_core_clks[] __initconst = {
|
||||
DEF_FIXED(".clk_400", CLK_PLL2_SDHI_400, CLK_PLL2_800, 1, 2),
|
||||
DEF_FIXED(".clk_266", CLK_PLL2_SDHI_266, CLK_PLL2_SDHI_533, 1, 2),
|
||||
|
||||
DEF_FIXED(".pll2_div16", CLK_PLL2_DIV16, CLK_PLL2, 1, 16),
|
||||
DEF_FIXED(".pll2_div20", CLK_PLL2_DIV20, CLK_PLL2, 1, 20),
|
||||
DEF_FIXED(".pll2_div2_8", CLK_PLL2_DIV2_8, CLK_PLL2_DIV2, 1, 8),
|
||||
DEF_FIXED(".pll2_div2_10", CLK_PLL2_DIV2_10, CLK_PLL2_DIV2, 1, 10),
|
||||
|
||||
DEF_FIXED(".pll3_div2", CLK_PLL3_DIV2, CLK_PLL3, 1, 2),
|
||||
DEF_FIXED(".pll3_div2_4", CLK_PLL3_DIV2_4, CLK_PLL3_DIV2, 1, 4),
|
||||
@ -110,11 +118,12 @@ static const struct cpg_core_clk r9a07g044_core_clks[] __initconst = {
|
||||
DEF_FIXED(".pll6_250", CLK_PLL6_250, CLK_PLL6, 1, 2),
|
||||
|
||||
/* Core output clk */
|
||||
DEF_FIXED("I", R9A07G044_CLK_I, CLK_PLL1, 1, 1),
|
||||
DEF_DIV("P0", R9A07G044_CLK_P0, CLK_PLL2_DIV16, DIVPL2A,
|
||||
DEF_DIV("I", R9A07G044_CLK_I, CLK_PLL1, DIVPL1A, dtable_1_8,
|
||||
CLK_DIVIDER_HIWORD_MASK),
|
||||
DEF_DIV("P0", R9A07G044_CLK_P0, CLK_PLL2_DIV2_8, DIVPL2A,
|
||||
dtable_1_32, CLK_DIVIDER_HIWORD_MASK),
|
||||
DEF_FIXED("P0_DIV2", R9A07G044_CLK_P0_DIV2, R9A07G044_CLK_P0, 1, 2),
|
||||
DEF_FIXED("TSU", R9A07G044_CLK_TSU, CLK_PLL2_DIV20, 1, 1),
|
||||
DEF_FIXED("TSU", R9A07G044_CLK_TSU, CLK_PLL2_DIV2_10, 1, 1),
|
||||
DEF_DIV("P1", R9A07G044_CLK_P1, CLK_PLL3_DIV2_4,
|
||||
DIVPL3B, dtable_1_32, CLK_DIVIDER_HIWORD_MASK),
|
||||
DEF_FIXED("P1_DIV2", CLK_P1_DIV2, R9A07G044_CLK_P1, 1, 2),
|
||||
@ -145,6 +154,24 @@ static struct rzg2l_mod_clk r9a07g044_mod_clks[] = {
|
||||
0x52c, 0),
|
||||
DEF_MOD("dmac_pclk", R9A07G044_DMAC_PCLK, CLK_P1_DIV2,
|
||||
0x52c, 1),
|
||||
DEF_MOD("ostm0_pclk", R9A07G044_OSTM0_PCLK, R9A07G044_CLK_P0,
|
||||
0x534, 0),
|
||||
DEF_MOD("ostm1_clk", R9A07G044_OSTM1_PCLK, R9A07G044_CLK_P0,
|
||||
0x534, 1),
|
||||
DEF_MOD("ostm2_pclk", R9A07G044_OSTM2_PCLK, R9A07G044_CLK_P0,
|
||||
0x534, 2),
|
||||
DEF_MOD("wdt0_pclk", R9A07G044_WDT0_PCLK, R9A07G044_CLK_P0,
|
||||
0x548, 0),
|
||||
DEF_MOD("wdt0_clk", R9A07G044_WDT0_CLK, R9A07G044_OSCCLK,
|
||||
0x548, 1),
|
||||
DEF_MOD("wdt1_pclk", R9A07G044_WDT1_PCLK, R9A07G044_CLK_P0,
|
||||
0x548, 2),
|
||||
DEF_MOD("wdt1_clk", R9A07G044_WDT1_CLK, R9A07G044_OSCCLK,
|
||||
0x548, 3),
|
||||
DEF_MOD("wdt2_pclk", R9A07G044_WDT2_PCLK, R9A07G044_CLK_P0,
|
||||
0x548, 4),
|
||||
DEF_MOD("wdt2_clk", R9A07G044_WDT2_CLK, R9A07G044_OSCCLK,
|
||||
0x548, 5),
|
||||
DEF_MOD("spi_clk2", R9A07G044_SPI_CLK2, R9A07G044_CLK_SPI1,
|
||||
0x550, 0),
|
||||
DEF_MOD("spi_clk", R9A07G044_SPI_CLK, R9A07G044_CLK_SPI0,
|
||||
@ -217,6 +244,14 @@ static struct rzg2l_mod_clk r9a07g044_mod_clks[] = {
|
||||
0x584, 4),
|
||||
DEF_MOD("sci0", R9A07G044_SCI0_CLKP, R9A07G044_CLK_P0,
|
||||
0x588, 0),
|
||||
DEF_MOD("sci1", R9A07G044_SCI1_CLKP, R9A07G044_CLK_P0,
|
||||
0x588, 1),
|
||||
DEF_MOD("rspi0", R9A07G044_RSPI0_CLKB, R9A07G044_CLK_P0,
|
||||
0x590, 0),
|
||||
DEF_MOD("rspi1", R9A07G044_RSPI1_CLKB, R9A07G044_CLK_P0,
|
||||
0x590, 1),
|
||||
DEF_MOD("rspi2", R9A07G044_RSPI2_CLKB, R9A07G044_CLK_P0,
|
||||
0x590, 2),
|
||||
DEF_MOD("canfd", R9A07G044_CANFD_PCLK, R9A07G044_CLK_P0,
|
||||
0x594, 0),
|
||||
DEF_MOD("gpio", R9A07G044_GPIO_HCLK, R9A07G044_OSCCLK,
|
||||
@ -225,6 +260,8 @@ static struct rzg2l_mod_clk r9a07g044_mod_clks[] = {
|
||||
0x5a8, 0),
|
||||
DEF_MOD("adc_pclk", R9A07G044_ADC_PCLK, R9A07G044_CLK_P0,
|
||||
0x5a8, 1),
|
||||
DEF_MOD("tsu_pclk", R9A07G044_TSU_PCLK, R9A07G044_CLK_TSU,
|
||||
0x5ac, 0),
|
||||
};
|
||||
|
||||
static struct rzg2l_reset r9a07g044_resets[] = {
|
||||
@ -233,6 +270,12 @@ static struct rzg2l_reset r9a07g044_resets[] = {
|
||||
DEF_RST(R9A07G044_IA55_RESETN, 0x818, 0),
|
||||
DEF_RST(R9A07G044_DMAC_ARESETN, 0x82c, 0),
|
||||
DEF_RST(R9A07G044_DMAC_RST_ASYNC, 0x82c, 1),
|
||||
DEF_RST(R9A07G044_OSTM0_PRESETZ, 0x834, 0),
|
||||
DEF_RST(R9A07G044_OSTM1_PRESETZ, 0x834, 1),
|
||||
DEF_RST(R9A07G044_OSTM2_PRESETZ, 0x834, 2),
|
||||
DEF_RST(R9A07G044_WDT0_PRESETN, 0x848, 0),
|
||||
DEF_RST(R9A07G044_WDT1_PRESETN, 0x848, 1),
|
||||
DEF_RST(R9A07G044_WDT2_PRESETN, 0x848, 2),
|
||||
DEF_RST(R9A07G044_SPI_RST, 0x850, 0),
|
||||
DEF_RST(R9A07G044_SDHI0_IXRST, 0x854, 0),
|
||||
DEF_RST(R9A07G044_SDHI1_IXRST, 0x854, 1),
|
||||
@ -256,6 +299,10 @@ static struct rzg2l_reset r9a07g044_resets[] = {
|
||||
DEF_RST(R9A07G044_SCIF3_RST_SYSTEM_N, 0x884, 3),
|
||||
DEF_RST(R9A07G044_SCIF4_RST_SYSTEM_N, 0x884, 4),
|
||||
DEF_RST(R9A07G044_SCI0_RST, 0x888, 0),
|
||||
DEF_RST(R9A07G044_SCI1_RST, 0x888, 1),
|
||||
DEF_RST(R9A07G044_RSPI0_RST, 0x890, 0),
|
||||
DEF_RST(R9A07G044_RSPI1_RST, 0x890, 1),
|
||||
DEF_RST(R9A07G044_RSPI2_RST, 0x890, 2),
|
||||
DEF_RST(R9A07G044_CANFD_RSTP_N, 0x894, 0),
|
||||
DEF_RST(R9A07G044_CANFD_RSTC_N, 0x894, 1),
|
||||
DEF_RST(R9A07G044_GPIO_RSTN, 0x898, 0),
|
||||
@ -263,6 +310,7 @@ static struct rzg2l_reset r9a07g044_resets[] = {
|
||||
DEF_RST(R9A07G044_GPIO_SPARE_RESETN, 0x898, 2),
|
||||
DEF_RST(R9A07G044_ADC_PRESETN, 0x8a8, 0),
|
||||
DEF_RST(R9A07G044_ADC_ADRST_N, 0x8a8, 1),
|
||||
DEF_RST(R9A07G044_TSU_PRESETN, 0x8ac, 0),
|
||||
};
|
||||
|
||||
static const unsigned int r9a07g044_crit_mod_clks[] __initconst = {
|
||||
|
@ -65,206 +65,49 @@ void cpg_simple_notifier_register(struct raw_notifier_head *notifiers,
|
||||
/*
|
||||
* SDn Clock
|
||||
*/
|
||||
#define CPG_SD_STP_HCK BIT(9)
|
||||
#define CPG_SD_STP_CK BIT(8)
|
||||
|
||||
#define CPG_SD_STP_MASK (CPG_SD_STP_HCK | CPG_SD_STP_CK)
|
||||
#define CPG_SD_FC_MASK (0x7 << 2 | 0x3 << 0)
|
||||
#define SDnSRCFC_SHIFT 2
|
||||
#define STPnHCK BIT(9 - SDnSRCFC_SHIFT)
|
||||
|
||||
#define CPG_SD_DIV_TABLE_DATA(stp_hck, sd_srcfc, sd_fc, sd_div) \
|
||||
{ \
|
||||
.val = ((stp_hck) ? CPG_SD_STP_HCK : 0) | \
|
||||
((sd_srcfc) << 2) | \
|
||||
((sd_fc) << 0), \
|
||||
.div = (sd_div), \
|
||||
}
|
||||
|
||||
struct sd_div_table {
|
||||
u32 val;
|
||||
unsigned int div;
|
||||
static const struct clk_div_table cpg_sdh_div_table[] = {
|
||||
{ 0, 1 }, { 1, 2 }, { STPnHCK | 2, 4 }, { STPnHCK | 3, 8 },
|
||||
{ STPnHCK | 4, 16 }, { 0, 0 },
|
||||
};
|
||||
|
||||
struct sd_clock {
|
||||
struct clk_hw hw;
|
||||
const struct sd_div_table *div_table;
|
||||
struct cpg_simple_notifier csn;
|
||||
unsigned int div_num;
|
||||
unsigned int cur_div_idx;
|
||||
};
|
||||
|
||||
/* SDn divider
|
||||
* sd_srcfc sd_fc div
|
||||
* stp_hck (div) (div) = sd_srcfc x sd_fc
|
||||
*---------------------------------------------------------
|
||||
* 0 0 (1) 1 (4) 4 : SDR104 / HS200 / HS400 (8 TAP)
|
||||
* 0 1 (2) 1 (4) 8 : SDR50
|
||||
* 1 2 (4) 1 (4) 16 : HS / SDR25
|
||||
* 1 3 (8) 1 (4) 32 : NS / SDR12
|
||||
* 1 4 (16) 1 (4) 64
|
||||
* 0 0 (1) 0 (2) 2
|
||||
* 0 1 (2) 0 (2) 4 : SDR104 / HS200 / HS400 (4 TAP)
|
||||
* 1 2 (4) 0 (2) 8
|
||||
* 1 3 (8) 0 (2) 16
|
||||
* 1 4 (16) 0 (2) 32
|
||||
*
|
||||
* NOTE: There is a quirk option to ignore the first row of the dividers
|
||||
* table when searching for suitable settings. This is because HS400 on
|
||||
* early ES versions of H3 and M3-W requires a specific setting to work.
|
||||
*/
|
||||
static const struct sd_div_table cpg_sd_div_table[] = {
|
||||
/* CPG_SD_DIV_TABLE_DATA(stp_hck, sd_srcfc, sd_fc, sd_div) */
|
||||
CPG_SD_DIV_TABLE_DATA(0, 0, 1, 4),
|
||||
CPG_SD_DIV_TABLE_DATA(0, 1, 1, 8),
|
||||
CPG_SD_DIV_TABLE_DATA(1, 2, 1, 16),
|
||||
CPG_SD_DIV_TABLE_DATA(1, 3, 1, 32),
|
||||
CPG_SD_DIV_TABLE_DATA(1, 4, 1, 64),
|
||||
CPG_SD_DIV_TABLE_DATA(0, 0, 0, 2),
|
||||
CPG_SD_DIV_TABLE_DATA(0, 1, 0, 4),
|
||||
CPG_SD_DIV_TABLE_DATA(1, 2, 0, 8),
|
||||
CPG_SD_DIV_TABLE_DATA(1, 3, 0, 16),
|
||||
CPG_SD_DIV_TABLE_DATA(1, 4, 0, 32),
|
||||
};
|
||||
|
||||
#define to_sd_clock(_hw) container_of(_hw, struct sd_clock, hw)
|
||||
|
||||
static int cpg_sd_clock_enable(struct clk_hw *hw)
|
||||
struct clk * __init cpg_sdh_clk_register(const char *name,
|
||||
void __iomem *sdnckcr, const char *parent_name,
|
||||
struct raw_notifier_head *notifiers)
|
||||
{
|
||||
struct sd_clock *clock = to_sd_clock(hw);
|
||||
struct cpg_simple_notifier *csn;
|
||||
struct clk *clk;
|
||||
|
||||
cpg_reg_modify(clock->csn.reg, CPG_SD_STP_MASK,
|
||||
clock->div_table[clock->cur_div_idx].val &
|
||||
CPG_SD_STP_MASK);
|
||||
csn = kzalloc(sizeof(*csn), GFP_KERNEL);
|
||||
if (!csn)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
return 0;
|
||||
}
|
||||
csn->reg = sdnckcr;
|
||||
|
||||
static void cpg_sd_clock_disable(struct clk_hw *hw)
|
||||
{
|
||||
struct sd_clock *clock = to_sd_clock(hw);
|
||||
|
||||
cpg_reg_modify(clock->csn.reg, 0, CPG_SD_STP_MASK);
|
||||
}
|
||||
|
||||
static int cpg_sd_clock_is_enabled(struct clk_hw *hw)
|
||||
{
|
||||
struct sd_clock *clock = to_sd_clock(hw);
|
||||
|
||||
return !(readl(clock->csn.reg) & CPG_SD_STP_MASK);
|
||||
}
|
||||
|
||||
static unsigned long cpg_sd_clock_recalc_rate(struct clk_hw *hw,
|
||||
unsigned long parent_rate)
|
||||
{
|
||||
struct sd_clock *clock = to_sd_clock(hw);
|
||||
|
||||
return DIV_ROUND_CLOSEST(parent_rate,
|
||||
clock->div_table[clock->cur_div_idx].div);
|
||||
}
|
||||
|
||||
static int cpg_sd_clock_determine_rate(struct clk_hw *hw,
|
||||
struct clk_rate_request *req)
|
||||
{
|
||||
unsigned long best_rate = ULONG_MAX, diff_min = ULONG_MAX;
|
||||
struct sd_clock *clock = to_sd_clock(hw);
|
||||
unsigned long calc_rate, diff;
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < clock->div_num; i++) {
|
||||
calc_rate = DIV_ROUND_CLOSEST(req->best_parent_rate,
|
||||
clock->div_table[i].div);
|
||||
if (calc_rate < req->min_rate || calc_rate > req->max_rate)
|
||||
continue;
|
||||
|
||||
diff = calc_rate > req->rate ? calc_rate - req->rate
|
||||
: req->rate - calc_rate;
|
||||
if (diff < diff_min) {
|
||||
best_rate = calc_rate;
|
||||
diff_min = diff;
|
||||
}
|
||||
clk = clk_register_divider_table(NULL, name, parent_name, 0, sdnckcr,
|
||||
SDnSRCFC_SHIFT, 8, 0, cpg_sdh_div_table,
|
||||
&cpg_lock);
|
||||
if (IS_ERR(clk)) {
|
||||
kfree(csn);
|
||||
return clk;
|
||||
}
|
||||
|
||||
if (best_rate == ULONG_MAX)
|
||||
return -EINVAL;
|
||||
|
||||
req->rate = best_rate;
|
||||
return 0;
|
||||
cpg_simple_notifier_register(notifiers, csn);
|
||||
return clk;
|
||||
}
|
||||
|
||||
static int cpg_sd_clock_set_rate(struct clk_hw *hw, unsigned long rate,
|
||||
unsigned long parent_rate)
|
||||
{
|
||||
struct sd_clock *clock = to_sd_clock(hw);
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < clock->div_num; i++)
|
||||
if (rate == DIV_ROUND_CLOSEST(parent_rate,
|
||||
clock->div_table[i].div))
|
||||
break;
|
||||
|
||||
if (i >= clock->div_num)
|
||||
return -EINVAL;
|
||||
|
||||
clock->cur_div_idx = i;
|
||||
|
||||
cpg_reg_modify(clock->csn.reg, CPG_SD_STP_MASK | CPG_SD_FC_MASK,
|
||||
clock->div_table[i].val &
|
||||
(CPG_SD_STP_MASK | CPG_SD_FC_MASK));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct clk_ops cpg_sd_clock_ops = {
|
||||
.enable = cpg_sd_clock_enable,
|
||||
.disable = cpg_sd_clock_disable,
|
||||
.is_enabled = cpg_sd_clock_is_enabled,
|
||||
.recalc_rate = cpg_sd_clock_recalc_rate,
|
||||
.determine_rate = cpg_sd_clock_determine_rate,
|
||||
.set_rate = cpg_sd_clock_set_rate,
|
||||
static const struct clk_div_table cpg_sd_div_table[] = {
|
||||
{ 0, 2 }, { 1, 4 }, { 0, 0 },
|
||||
};
|
||||
|
||||
struct clk * __init cpg_sd_clk_register(const char *name,
|
||||
void __iomem *base, unsigned int offset, const char *parent_name,
|
||||
struct raw_notifier_head *notifiers, bool skip_first)
|
||||
void __iomem *sdnckcr, const char *parent_name)
|
||||
{
|
||||
struct clk_init_data init = {};
|
||||
struct sd_clock *clock;
|
||||
struct clk *clk;
|
||||
u32 val;
|
||||
|
||||
clock = kzalloc(sizeof(*clock), GFP_KERNEL);
|
||||
if (!clock)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
init.name = name;
|
||||
init.ops = &cpg_sd_clock_ops;
|
||||
init.flags = CLK_SET_RATE_PARENT;
|
||||
init.parent_names = &parent_name;
|
||||
init.num_parents = 1;
|
||||
|
||||
clock->csn.reg = base + offset;
|
||||
clock->hw.init = &init;
|
||||
clock->div_table = cpg_sd_div_table;
|
||||
clock->div_num = ARRAY_SIZE(cpg_sd_div_table);
|
||||
|
||||
if (skip_first) {
|
||||
clock->div_table++;
|
||||
clock->div_num--;
|
||||
}
|
||||
|
||||
val = readl(clock->csn.reg) & ~CPG_SD_FC_MASK;
|
||||
val |= CPG_SD_STP_MASK | (clock->div_table[0].val & CPG_SD_FC_MASK);
|
||||
writel(val, clock->csn.reg);
|
||||
|
||||
clk = clk_register(NULL, &clock->hw);
|
||||
if (IS_ERR(clk))
|
||||
goto free_clock;
|
||||
|
||||
cpg_simple_notifier_register(notifiers, &clock->csn);
|
||||
return clk;
|
||||
|
||||
free_clock:
|
||||
kfree(clock);
|
||||
return clk;
|
||||
return clk_register_divider_table(NULL, name, parent_name, 0, sdnckcr,
|
||||
0, 2, 0, cpg_sd_div_table, &cpg_lock);
|
||||
}
|
||||
|
||||
struct rpc_clock {
|
||||
|
@ -26,9 +26,12 @@ void cpg_simple_notifier_register(struct raw_notifier_head *notifiers,
|
||||
|
||||
void cpg_reg_modify(void __iomem *reg, u32 clear, u32 set);
|
||||
|
||||
struct clk * __init cpg_sdh_clk_register(const char *name,
|
||||
void __iomem *sdnckcr, const char *parent_name,
|
||||
struct raw_notifier_head *notifiers);
|
||||
|
||||
struct clk * __init cpg_sd_clk_register(const char *name,
|
||||
void __iomem *base, unsigned int offset, const char *parent_name,
|
||||
struct raw_notifier_head *notifiers, bool skip_first);
|
||||
void __iomem *sdnckcr, const char *parent_name);
|
||||
|
||||
struct clk * __init cpg_rpc_clk_register(const char *name,
|
||||
void __iomem *rpcckcr, const char *parent_name,
|
||||
|
@ -312,29 +312,20 @@ static u32 cpg_quirks __initdata;
|
||||
|
||||
#define PLL_ERRATA BIT(0) /* Missing PLL0/2/4 post-divider */
|
||||
#define RCKCR_CKSEL BIT(1) /* Manual RCLK parent selection */
|
||||
#define SD_SKIP_FIRST BIT(2) /* Skip first clock in SD table */
|
||||
|
||||
|
||||
static const struct soc_device_attribute cpg_quirks_match[] __initconst = {
|
||||
{
|
||||
.soc_id = "r8a7795", .revision = "ES1.0",
|
||||
.data = (void *)(PLL_ERRATA | RCKCR_CKSEL | SD_SKIP_FIRST),
|
||||
.data = (void *)(PLL_ERRATA | RCKCR_CKSEL),
|
||||
},
|
||||
{
|
||||
.soc_id = "r8a7795", .revision = "ES1.*",
|
||||
.data = (void *)(RCKCR_CKSEL | SD_SKIP_FIRST),
|
||||
},
|
||||
{
|
||||
.soc_id = "r8a7795", .revision = "ES2.0",
|
||||
.data = (void *)SD_SKIP_FIRST,
|
||||
.data = (void *)(RCKCR_CKSEL),
|
||||
},
|
||||
{
|
||||
.soc_id = "r8a7796", .revision = "ES1.0",
|
||||
.data = (void *)(RCKCR_CKSEL | SD_SKIP_FIRST),
|
||||
},
|
||||
{
|
||||
.soc_id = "r8a7796", .revision = "ES1.1",
|
||||
.data = (void *)SD_SKIP_FIRST,
|
||||
.data = (void *)(RCKCR_CKSEL),
|
||||
},
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
@ -401,10 +392,13 @@ struct clk * __init rcar_gen3_cpg_clk_register(struct device *dev,
|
||||
mult *= 2;
|
||||
break;
|
||||
|
||||
case CLK_TYPE_GEN3_SDH:
|
||||
return cpg_sdh_clk_register(core->name, base + core->offset,
|
||||
__clk_get_name(parent), notifiers);
|
||||
|
||||
case CLK_TYPE_GEN3_SD:
|
||||
return cpg_sd_clk_register(core->name, base, core->offset,
|
||||
__clk_get_name(parent), notifiers,
|
||||
cpg_quirks & SD_SKIP_FIRST);
|
||||
return cpg_sd_clk_register(core->name, base + core->offset,
|
||||
__clk_get_name(parent));
|
||||
|
||||
case CLK_TYPE_GEN3_R:
|
||||
if (cpg_quirks & RCKCR_CKSEL) {
|
||||
|
@ -17,6 +17,7 @@ enum rcar_gen3_clk_types {
|
||||
CLK_TYPE_GEN3_PLL2,
|
||||
CLK_TYPE_GEN3_PLL3,
|
||||
CLK_TYPE_GEN3_PLL4,
|
||||
CLK_TYPE_GEN3_SDH,
|
||||
CLK_TYPE_GEN3_SD,
|
||||
CLK_TYPE_GEN3_R,
|
||||
CLK_TYPE_GEN3_MDSEL, /* Select parent/divider using mode pin */
|
||||
@ -32,6 +33,9 @@ enum rcar_gen3_clk_types {
|
||||
CLK_TYPE_GEN3_SOC_BASE,
|
||||
};
|
||||
|
||||
#define DEF_GEN3_SDH(_name, _id, _parent, _offset) \
|
||||
DEF_BASE(_name, _id, CLK_TYPE_GEN3_SDH, _parent, .offset = _offset)
|
||||
|
||||
#define DEF_GEN3_SD(_name, _id, _parent, _offset) \
|
||||
DEF_BASE(_name, _id, CLK_TYPE_GEN3_SD, _parent, .offset = _offset)
|
||||
|
||||
|
@ -552,6 +552,11 @@ void cpg_mssr_detach_dev(struct generic_pm_domain *unused, struct device *dev)
|
||||
pm_clk_destroy(dev);
|
||||
}
|
||||
|
||||
static void cpg_mssr_genpd_remove(void *data)
|
||||
{
|
||||
pm_genpd_remove(data);
|
||||
}
|
||||
|
||||
static int __init cpg_mssr_add_clk_domain(struct device *dev,
|
||||
const unsigned int *core_pm_clks,
|
||||
unsigned int num_core_pm_clks)
|
||||
@ -560,6 +565,7 @@ static int __init cpg_mssr_add_clk_domain(struct device *dev,
|
||||
struct generic_pm_domain *genpd;
|
||||
struct cpg_mssr_clk_domain *pd;
|
||||
size_t pm_size = num_core_pm_clks * sizeof(core_pm_clks[0]);
|
||||
int ret;
|
||||
|
||||
pd = devm_kzalloc(dev, sizeof(*pd) + pm_size, GFP_KERNEL);
|
||||
if (!pd)
|
||||
@ -574,11 +580,17 @@ static int __init cpg_mssr_add_clk_domain(struct device *dev,
|
||||
GENPD_FLAG_ACTIVE_WAKEUP;
|
||||
genpd->attach_dev = cpg_mssr_attach_dev;
|
||||
genpd->detach_dev = cpg_mssr_detach_dev;
|
||||
pm_genpd_init(genpd, &pm_domain_always_on_gov, false);
|
||||
ret = pm_genpd_init(genpd, &pm_domain_always_on_gov, false);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = devm_add_action_or_reset(dev, cpg_mssr_genpd_remove, genpd);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
cpg_mssr_clk_domain = pd;
|
||||
|
||||
of_genpd_add_provider_simple(np, genpd);
|
||||
return 0;
|
||||
return of_genpd_add_provider_simple(np, genpd);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_RESET_CONTROLLER
|
||||
|
@ -74,6 +74,7 @@ struct sd_hw_data {
|
||||
* @clks: Array containing all Core and Module Clocks
|
||||
* @num_core_clks: Number of Core Clocks in clks[]
|
||||
* @num_mod_clks: Number of Module Clocks in clks[]
|
||||
* @num_resets: Number of Module Resets in info->resets[]
|
||||
* @last_dt_core_clk: ID of the last Core Clock exported to DT
|
||||
* @notifiers: Notifier chain to save/restore clock state for system resume
|
||||
* @info: Pointer to platform data
|
||||
@ -850,10 +851,16 @@ static void rzg2l_cpg_detach_dev(struct generic_pm_domain *unused, struct device
|
||||
pm_clk_destroy(dev);
|
||||
}
|
||||
|
||||
static void rzg2l_cpg_genpd_remove(void *data)
|
||||
{
|
||||
pm_genpd_remove(data);
|
||||
}
|
||||
|
||||
static int __init rzg2l_cpg_add_clk_domain(struct device *dev)
|
||||
{
|
||||
struct device_node *np = dev->of_node;
|
||||
struct generic_pm_domain *genpd;
|
||||
int ret;
|
||||
|
||||
genpd = devm_kzalloc(dev, sizeof(*genpd), GFP_KERNEL);
|
||||
if (!genpd)
|
||||
@ -864,10 +871,15 @@ static int __init rzg2l_cpg_add_clk_domain(struct device *dev)
|
||||
GENPD_FLAG_ACTIVE_WAKEUP;
|
||||
genpd->attach_dev = rzg2l_cpg_attach_dev;
|
||||
genpd->detach_dev = rzg2l_cpg_detach_dev;
|
||||
pm_genpd_init(genpd, &pm_domain_always_on_gov, false);
|
||||
ret = pm_genpd_init(genpd, &pm_domain_always_on_gov, false);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
of_genpd_add_provider_simple(np, genpd);
|
||||
return 0;
|
||||
ret = devm_add_action_or_reset(dev, rzg2l_cpg_genpd_remove, genpd);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return of_genpd_add_provider_simple(np, genpd);
|
||||
}
|
||||
|
||||
static int __init rzg2l_cpg_probe(struct platform_device *pdev)
|
||||
|
@ -9,6 +9,7 @@
|
||||
#ifndef __RENESAS_RZG2L_CPG_H__
|
||||
#define __RENESAS_RZG2L_CPG_H__
|
||||
|
||||
#define CPG_PL1_DDIV (0x200)
|
||||
#define CPG_PL2_DDIV (0x204)
|
||||
#define CPG_PL3A_DDIV (0x208)
|
||||
#define CPG_PL2SDHI_DSEL (0x218)
|
||||
@ -29,6 +30,7 @@
|
||||
|
||||
#define DDIV_PACK(offset, bitpos, size) \
|
||||
(((offset) << 20) | ((bitpos) << 12) | ((size) << 8))
|
||||
#define DIVPL1A DDIV_PACK(CPG_PL1_DDIV, 0, 2)
|
||||
#define DIVPL2A DDIV_PACK(CPG_PL2_DDIV, 0, 3)
|
||||
#define DIVPL3A DDIV_PACK(CPG_PL3A_DDIV, 0, 3)
|
||||
#define DIVPL3B DDIV_PACK(CPG_PL3A_DDIV, 4, 3)
|
||||
@ -168,6 +170,9 @@ struct rzg2l_reset {
|
||||
* @num_mod_clks: Number of entries in mod_clks[]
|
||||
* @num_hw_mod_clks: Number of Module Clocks supported by the hardware
|
||||
*
|
||||
* @resets: Array of Module Reset definitions
|
||||
* @num_resets: Number of entries in resets[]
|
||||
*
|
||||
* @crit_mod_clks: Array with Module Clock IDs of critical clocks that
|
||||
* should not be disabled without a knowledgeable driver
|
||||
* @num_crit_mod_clks: Number of entries in crit_mod_clks[]
|
||||
|
@ -18,6 +18,8 @@ struct renesas_sdhi_scc {
|
||||
u32 tap_hs400_4tap; /* sampling clock position for HS400 (4 TAP) */
|
||||
};
|
||||
|
||||
#define SDHI_FLAG_NEED_CLKH_FALLBACK BIT(0)
|
||||
|
||||
struct renesas_sdhi_of_data {
|
||||
unsigned long tmio_flags;
|
||||
u32 tmio_ocr_mask;
|
||||
@ -31,6 +33,7 @@ struct renesas_sdhi_of_data {
|
||||
int taps_num;
|
||||
unsigned int max_blk_count;
|
||||
unsigned short max_segs;
|
||||
unsigned long sdhi_flags;
|
||||
};
|
||||
|
||||
#define SDHI_CALIB_TABLE_MAX 32
|
||||
@ -57,6 +60,7 @@ struct tmio_mmc_dma {
|
||||
|
||||
struct renesas_sdhi {
|
||||
struct clk *clk;
|
||||
struct clk *clkh;
|
||||
struct clk *clk_cd;
|
||||
struct tmio_mmc_data mmc_data;
|
||||
struct tmio_mmc_dma dma_priv;
|
||||
|
@ -127,10 +127,12 @@ static int renesas_sdhi_clk_enable(struct tmio_mmc_host *host)
|
||||
}
|
||||
|
||||
static unsigned int renesas_sdhi_clk_update(struct tmio_mmc_host *host,
|
||||
unsigned int new_clock)
|
||||
unsigned int wanted_clock)
|
||||
{
|
||||
struct renesas_sdhi *priv = host_to_priv(host);
|
||||
struct clk *ref_clk = priv->clk;
|
||||
unsigned int freq, diff, best_freq = 0, diff_min = ~0;
|
||||
unsigned int new_clock, clkh_shift = 0;
|
||||
int i;
|
||||
|
||||
/*
|
||||
@ -141,6 +143,16 @@ static unsigned int renesas_sdhi_clk_update(struct tmio_mmc_host *host,
|
||||
if (!(host->pdata->flags & TMIO_MMC_MIN_RCAR2) || mmc_doing_tune(host->mmc))
|
||||
return clk_get_rate(priv->clk);
|
||||
|
||||
if (priv->clkh) {
|
||||
bool use_4tap = priv->quirks && priv->quirks->hs400_4taps;
|
||||
bool need_slow_clkh = (host->mmc->ios.timing == MMC_TIMING_UHS_SDR104) ||
|
||||
(host->mmc->ios.timing == MMC_TIMING_MMC_HS400);
|
||||
clkh_shift = use_4tap && need_slow_clkh ? 1 : 2;
|
||||
ref_clk = priv->clkh;
|
||||
}
|
||||
|
||||
new_clock = wanted_clock << clkh_shift;
|
||||
|
||||
/*
|
||||
* We want the bus clock to be as close as possible to, but no
|
||||
* greater than, new_clock. As we can divide by 1 << i for
|
||||
@ -148,11 +160,10 @@ static unsigned int renesas_sdhi_clk_update(struct tmio_mmc_host *host,
|
||||
* possible, but no greater than, new_clock << i.
|
||||
*/
|
||||
for (i = min(9, ilog2(UINT_MAX / new_clock)); i >= 0; i--) {
|
||||
freq = clk_round_rate(priv->clk, new_clock << i);
|
||||
freq = clk_round_rate(ref_clk, new_clock << i);
|
||||
if (freq > (new_clock << i)) {
|
||||
/* Too fast; look for a slightly slower option */
|
||||
freq = clk_round_rate(priv->clk,
|
||||
(new_clock << i) / 4 * 3);
|
||||
freq = clk_round_rate(ref_clk, (new_clock << i) / 4 * 3);
|
||||
if (freq > (new_clock << i))
|
||||
continue;
|
||||
}
|
||||
@ -164,7 +175,10 @@ static unsigned int renesas_sdhi_clk_update(struct tmio_mmc_host *host,
|
||||
}
|
||||
}
|
||||
|
||||
clk_set_rate(priv->clk, best_freq);
|
||||
clk_set_rate(ref_clk, best_freq);
|
||||
|
||||
if (priv->clkh)
|
||||
clk_set_rate(priv->clk, best_freq >> clkh_shift);
|
||||
|
||||
return clk_get_rate(priv->clk);
|
||||
}
|
||||
@ -904,11 +918,12 @@ int renesas_sdhi_probe(struct platform_device *pdev,
|
||||
dma_priv = &priv->dma_priv;
|
||||
|
||||
priv->clk = devm_clk_get(&pdev->dev, NULL);
|
||||
if (IS_ERR(priv->clk)) {
|
||||
ret = PTR_ERR(priv->clk);
|
||||
dev_err(&pdev->dev, "cannot get clock: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
if (IS_ERR(priv->clk))
|
||||
return dev_err_probe(&pdev->dev, PTR_ERR(priv->clk), "cannot get clock");
|
||||
|
||||
priv->clkh = devm_clk_get_optional(&pdev->dev, "clkh");
|
||||
if (IS_ERR(priv->clkh))
|
||||
return dev_err_probe(&pdev->dev, PTR_ERR(priv->clkh), "cannot get clkh");
|
||||
|
||||
/*
|
||||
* Some controllers provide a 2nd clock just to run the internal card
|
||||
@ -921,9 +936,9 @@ int renesas_sdhi_probe(struct platform_device *pdev,
|
||||
* to the card detect circuit. That leaves us with if separate clocks
|
||||
* are presented, we must treat them both as virtually 1 clock.
|
||||
*/
|
||||
priv->clk_cd = devm_clk_get(&pdev->dev, "cd");
|
||||
priv->clk_cd = devm_clk_get_optional(&pdev->dev, "cd");
|
||||
if (IS_ERR(priv->clk_cd))
|
||||
priv->clk_cd = NULL;
|
||||
return dev_err_probe(&pdev->dev, PTR_ERR(priv->clk_cd), "cannot get cd clock");
|
||||
|
||||
priv->pinctrl = devm_pinctrl_get(&pdev->dev);
|
||||
if (!IS_ERR(priv->pinctrl)) {
|
||||
@ -947,6 +962,10 @@ int renesas_sdhi_probe(struct platform_device *pdev,
|
||||
mmc_data->max_segs = of_data->max_segs;
|
||||
dma_priv->dma_buswidth = of_data->dma_buswidth;
|
||||
host->bus_shift = of_data->bus_shift;
|
||||
/* Fallback for old DTs */
|
||||
if (!priv->clkh && of_data->sdhi_flags & SDHI_FLAG_NEED_CLKH_FALLBACK)
|
||||
priv->clkh = clk_get_parent(clk_get_parent(priv->clk));
|
||||
|
||||
}
|
||||
|
||||
host->write16_hook = renesas_sdhi_write16_hook;
|
||||
@ -1044,7 +1063,7 @@ int renesas_sdhi_probe(struct platform_device *pdev,
|
||||
host->mmc->caps2 & (MMC_CAP2_HS200_1_8V_SDR |
|
||||
MMC_CAP2_HS400_1_8V))) {
|
||||
const struct renesas_sdhi_scc *taps = of_data->taps;
|
||||
bool use_4tap = priv->quirks && priv->quirks->hs400_4taps;
|
||||
bool use_4tap = quirks && quirks->hs400_4taps;
|
||||
bool hit = false;
|
||||
|
||||
for (i = 0; i < of_data->taps_num; i++) {
|
||||
|
@ -125,6 +125,22 @@ static const struct renesas_sdhi_of_data of_data_rcar_gen3 = {
|
||||
/* DMAC can handle 32bit blk count but only 1 segment */
|
||||
.max_blk_count = UINT_MAX / TMIO_MAX_BLK_SIZE,
|
||||
.max_segs = 1,
|
||||
.sdhi_flags = SDHI_FLAG_NEED_CLKH_FALLBACK,
|
||||
};
|
||||
|
||||
static const struct renesas_sdhi_of_data of_data_rcar_gen3_no_fallback = {
|
||||
.tmio_flags = TMIO_MMC_HAS_IDLE_WAIT | TMIO_MMC_CLK_ACTUAL |
|
||||
TMIO_MMC_HAVE_CBSY | TMIO_MMC_MIN_RCAR2,
|
||||
.capabilities = MMC_CAP_SD_HIGHSPEED | MMC_CAP_SDIO_IRQ |
|
||||
MMC_CAP_CMD23 | MMC_CAP_WAIT_WHILE_BUSY,
|
||||
.capabilities2 = MMC_CAP2_NO_WRITE_PROTECT | MMC_CAP2_MERGE_CAPABLE,
|
||||
.bus_shift = 2,
|
||||
.scc_offset = 0x1000,
|
||||
.taps = rcar_gen3_scc_taps,
|
||||
.taps_num = ARRAY_SIZE(rcar_gen3_scc_taps),
|
||||
/* DMAC can handle 32bit blk count but only 1 segment */
|
||||
.max_blk_count = UINT_MAX / TMIO_MAX_BLK_SIZE,
|
||||
.max_segs = 1,
|
||||
};
|
||||
|
||||
static const u8 r8a7796_es13_calib_table[2][SDHI_CALIB_TABLE_MAX] = {
|
||||
@ -214,6 +230,10 @@ static const struct renesas_sdhi_of_data_with_quirks of_r8a77965_compatible = {
|
||||
.quirks = &sdhi_quirks_r8a77965,
|
||||
};
|
||||
|
||||
static const struct renesas_sdhi_of_data_with_quirks of_r8a77970_compatible = {
|
||||
.of_data = &of_data_rcar_gen3_no_fallback,
|
||||
};
|
||||
|
||||
static const struct renesas_sdhi_of_data_with_quirks of_r8a77980_compatible = {
|
||||
.of_data = &of_data_rcar_gen3,
|
||||
.quirks = &sdhi_quirks_nohs400,
|
||||
@ -235,6 +255,7 @@ static const struct of_device_id renesas_sdhi_internal_dmac_of_match[] = {
|
||||
{ .compatible = "renesas,sdhi-r8a7796", .data = &of_rcar_gen3_compatible, },
|
||||
{ .compatible = "renesas,sdhi-r8a77961", .data = &of_r8a77961_compatible, },
|
||||
{ .compatible = "renesas,sdhi-r8a77965", .data = &of_r8a77965_compatible, },
|
||||
{ .compatible = "renesas,sdhi-r8a77970", .data = &of_r8a77970_compatible, },
|
||||
{ .compatible = "renesas,sdhi-r8a77980", .data = &of_r8a77980_compatible, },
|
||||
{ .compatible = "renesas,sdhi-r8a77990", .data = &of_r8a77990_compatible, },
|
||||
{ .compatible = "renesas,rcar-gen3-sdhi", .data = &of_rcar_gen3_compatible, },
|
||||
|
Loading…
x
Reference in New Issue
Block a user