mirror of
https://github.com/linux-msm/laptops-kernel.git
synced 2026-08-13 14:19:53 -07:00
Merge branch 'renesas-clk' of https://git.kernel.org/pub/scm/linux/kernel/git/geert/renesas-drivers.git
This commit is contained in:
@@ -26,16 +26,22 @@ properties:
|
||||
maxItems: 1
|
||||
|
||||
clocks:
|
||||
minItems: 3
|
||||
items:
|
||||
- description: AUDIO_EXTAL clock input
|
||||
- description: RTXIN clock input
|
||||
- description: QEXTAL clock input
|
||||
- description: AUDIO_CLKB clock input
|
||||
- description: AUDIO_CLKC clock input
|
||||
|
||||
clock-names:
|
||||
minItems: 3
|
||||
items:
|
||||
- const: audio_extal
|
||||
- const: rtxin
|
||||
- const: qextal
|
||||
- const: audio_clkb
|
||||
- const: audio_clkc
|
||||
|
||||
'#clock-cells':
|
||||
description: |
|
||||
|
||||
@@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
title: Renesas Versaclock7 Programmable Clock
|
||||
|
||||
maintainers:
|
||||
- Alex Helms <alexander.helms.jy@renesas.com>
|
||||
- Biju Das <biju.das.jz@bp.renesas.com>
|
||||
|
||||
description: |
|
||||
Renesas Versaclock7 is a family of configurable clock generator and
|
||||
|
||||
+4
-2
@@ -23103,10 +23103,12 @@ L: linux-renesas-soc@vger.kernel.org
|
||||
S: Maintained
|
||||
F: drivers/phy/renesas/phy-rcar-gen3-usb*.c
|
||||
|
||||
RENESAS VERSACLOCK 7 CLOCK DRIVER
|
||||
M: Alex Helms <alexander.helms.jy@renesas.com>
|
||||
RENESAS VERSACLOCK 3 and VERSACLOCK 7 CLOCK DRIVER
|
||||
M: Biju Das <biju.das.jz@bp.renesas.com>
|
||||
S: Maintained
|
||||
F: Documentation/devicetree/bindings/clock/renesas,5p35023.yaml
|
||||
F: Documentation/devicetree/bindings/clock/renesas,versaclock7.yaml
|
||||
F: drivers/clk/clk-versaclock3.c
|
||||
F: drivers/clk/clk-versaclock7.c
|
||||
|
||||
RENESAS X9250 DIGITAL POTENTIOMETERS DRIVER
|
||||
|
||||
@@ -218,10 +218,12 @@ config CLK_R9A09G057
|
||||
config CLK_R9A09G077
|
||||
bool "RZ/T2H clock support" if COMPILE_TEST
|
||||
select CLK_RENESAS_CPG_MSSR
|
||||
select CLK_RZV2H_CPG_LIB
|
||||
|
||||
config CLK_R9A09G087
|
||||
bool "RZ/N2H clock support" if COMPILE_TEST
|
||||
select CLK_RENESAS_CPG_MSSR
|
||||
select CLK_RZV2H_CPG_LIB
|
||||
|
||||
config CLK_SH73A0
|
||||
bool "SH-Mobile AG5 clock support" if COMPILE_TEST
|
||||
@@ -260,8 +262,12 @@ config CLK_RZG2L
|
||||
|
||||
config CLK_RZV2H
|
||||
bool "RZ/{G3E,V2H(P)} family clock support" if COMPILE_TEST
|
||||
select CLK_RZV2H_CPG_LIB
|
||||
select RESET_CONTROLLER
|
||||
|
||||
config CLK_RZV2H_CPG_LIB
|
||||
bool "RZV2H CPG library functions" if COMPILE_TEST
|
||||
|
||||
config CLK_RENESAS_VBATTB
|
||||
tristate "Renesas VBATTB clock controller"
|
||||
depends on ARCH_RZG2L || COMPILE_TEST
|
||||
|
||||
@@ -52,6 +52,7 @@ obj-$(CONFIG_CLK_RCAR_GEN3_CPG) += rcar-gen3-cpg.o
|
||||
obj-$(CONFIG_CLK_RCAR_GEN4_CPG) += rcar-gen4-cpg.o
|
||||
obj-$(CONFIG_CLK_RCAR_USB2_CLOCK_SEL) += rcar-usb2-clock-sel.o
|
||||
obj-$(CONFIG_CLK_RZG2L) += rzg2l-cpg.o
|
||||
obj-$(CONFIG_CLK_RZV2H_CPG_LIB) += rzv2h-cpg-lib.o
|
||||
obj-$(CONFIG_CLK_RZV2H) += rzv2h-cpg.o
|
||||
|
||||
# Generic
|
||||
|
||||
@@ -77,6 +77,7 @@ enum clk_ids {
|
||||
CLK_SEL_PLL4,
|
||||
CLK_P1_DIV2,
|
||||
CLK_P3_DIV2,
|
||||
CLK_P4_DIV2,
|
||||
CLK_SD0_DIV4,
|
||||
CLK_SD1_DIV4,
|
||||
CLK_SD2_DIV4,
|
||||
@@ -172,6 +173,8 @@ static const struct cpg_core_clk r9a08g045_core_clks[] __initconst = {
|
||||
DEF_G3S_DIV("P3", R9A08G045_CLK_P3, CLK_PLL3_DIV2_4, DIVPL3C, G3S_DIVPL3C_STS,
|
||||
dtable_1_32, 0, 0, 0, NULL),
|
||||
DEF_FIXED("P3_DIV2", CLK_P3_DIV2, R9A08G045_CLK_P3, 1, 2),
|
||||
DEF_FIXED("P4", R9A08G045_CLK_P4, CLK_PLL2_DIV2, 1, 5),
|
||||
DEF_FIXED("P4_DIV2", CLK_P4_DIV2, R9A08G045_CLK_P4, 1, 2),
|
||||
DEF_FIXED("P5", R9A08G045_CLK_P5, CLK_PLL2_DIV2, 1, 4),
|
||||
DEF_FIXED("ZT", R9A08G045_CLK_ZT, CLK_PLL3_DIV2_8, 1, 1),
|
||||
DEF_FIXED("S0", R9A08G045_CLK_S0, CLK_SEL_PLL4, 1, 2),
|
||||
@@ -274,6 +277,10 @@ static const struct rzg2l_mod_clk r9a08g045_mod_clks[] = {
|
||||
MSTOP(BUS_MCPU2, BIT(5))),
|
||||
DEF_MOD("scif5_clk_pck", R9A08G045_SCIF5_CLK_PCK, R9A08G045_CLK_P0, 0x584, 5,
|
||||
MSTOP(BUS_MCPU3, BIT(4))),
|
||||
DEF_MOD("canfd_pclk", R9A08G045_CANFD_PCLK, CLK_P4_DIV2, 0x594, 0,
|
||||
MSTOP(BUS_MCPU2, BIT(9))),
|
||||
DEF_MOD("canfd_clk_ram", R9A08G045_CANFD_CLK_RAM, R9A08G045_CLK_P4, 0x594, 1,
|
||||
MSTOP(BUS_MCPU2, BIT(9))),
|
||||
DEF_MOD("gpio_hclk", R9A08G045_GPIO_HCLK, R9A08G045_OSCCLK, 0x598, 0,
|
||||
MSTOP(BUS_PERI_CPU, BIT(6))),
|
||||
DEF_MOD("adc_adclk", R9A08G045_ADC_ADCLK, R9A08G045_CLK_TSU, 0x5a8, 0,
|
||||
@@ -324,6 +331,8 @@ static const struct rzg2l_reset r9a08g045_resets[] = {
|
||||
DEF_RST(R9A08G045_SCIF3_RST_SYSTEM_N, 0x884, 3),
|
||||
DEF_RST(R9A08G045_SCIF4_RST_SYSTEM_N, 0x884, 4),
|
||||
DEF_RST(R9A08G045_SCIF5_RST_SYSTEM_N, 0x884, 5),
|
||||
DEF_RST(R9A08G045_CANFD_RSTP_N, 0x894, 0),
|
||||
DEF_RST(R9A08G045_CANFD_RSTC_N, 0x894, 1),
|
||||
DEF_RST(R9A08G045_GPIO_RSTN, 0x898, 0),
|
||||
DEF_RST(R9A08G045_GPIO_PORT_RESETN, 0x898, 1),
|
||||
DEF_RST(R9A08G045_GPIO_SPARE_RESETN, 0x898, 2),
|
||||
|
||||
@@ -17,10 +17,15 @@
|
||||
/* RZ/G3L Specific registers. */
|
||||
#define G3L_CPG_PL2_DDIV (0x204)
|
||||
#define G3L_CPG_PL3_DDIV (0x208)
|
||||
#define G3L_CPG_SDHI_DDIV (0x218)
|
||||
#define G3L_CPG_GE3D_DDIV (0x224)
|
||||
#define G3L_CPG_CA55CORE_DDIV (0x234)
|
||||
#define G3L_CPG_RSCI_DDIV (0x238)
|
||||
#define G3L_CPG_RSPI_DDIV (0x23c)
|
||||
#define G3L_CPG_SDHI_DSEL (0x244)
|
||||
#define G3L_CLKDIVSTATUS (0x280)
|
||||
#define G3L_CLKSELSTATUS (0x284)
|
||||
#define G3L_CPG_GE3D_SSEL (0x40c)
|
||||
#define G3L_CPG_ETH_SSEL (0x410)
|
||||
#define G3L_CPG_RSCI_SSEL (0x414)
|
||||
#define G3L_CPG_RSPI_SSEL (0x418)
|
||||
@@ -30,6 +35,10 @@
|
||||
#define G3L_DIVPL2A DDIV_PACK(G3L_CPG_PL2_DDIV, 0, 2)
|
||||
#define G3L_DIVPL2B DDIV_PACK(G3L_CPG_PL2_DDIV, 4, 2)
|
||||
#define G3L_DIVPL3A DDIV_PACK(G3L_CPG_PL3_DDIV, 0, 2)
|
||||
#define G3L_DIV_SDHI0 DDIV_PACK(G3L_CPG_SDHI_DDIV, 0, 2)
|
||||
#define G3L_DIV_SDHI1 DDIV_PACK(G3L_CPG_SDHI_DDIV, 4, 2)
|
||||
#define G3L_DIV_SDHI2 DDIV_PACK(G3L_CPG_SDHI_DDIV, 8, 2)
|
||||
#define G3L_DIV_GE3D DDIV_PACK(G3L_CPG_GE3D_DDIV, 0, 3)
|
||||
#define G3L_DIV_CA55_CORE0 DDIV_PACK(G3L_CPG_CA55CORE_DDIV, 0, 3)
|
||||
#define G3L_DIV_CA55_CORE1 DDIV_PACK(G3L_CPG_CA55CORE_DDIV, 4, 3)
|
||||
#define G3L_DIV_CA55_CORE2 DDIV_PACK(G3L_CPG_CA55CORE_DDIV, 8, 3)
|
||||
@@ -61,8 +70,19 @@
|
||||
#define G3L_DIV_RSPI0_STS DDIV_PACK(G3L_CLKDIVSTATUS, 20, 1)
|
||||
#define G3L_DIV_RSPI1_STS DDIV_PACK(G3L_CLKDIVSTATUS, 21, 1)
|
||||
#define G3L_DIV_RSPI2_STS DDIV_PACK(G3L_CLKDIVSTATUS, 22, 1)
|
||||
#define G3L_DIV_SDHI0_STS DDIV_PACK(G3L_CLKDIVSTATUS, 24, 1)
|
||||
#define G3L_DIV_SDHI1_STS DDIV_PACK(G3L_CLKDIVSTATUS, 25, 1)
|
||||
#define G3L_DIV_SDHI2_STS DDIV_PACK(G3L_CLKDIVSTATUS, 26, 1)
|
||||
|
||||
#define G3L_SEL_SDHI0_STS SEL_PLL_PACK(G3L_CLKSELSTATUS, 16, 1)
|
||||
#define G3L_SEL_SDHI1_STS SEL_PLL_PACK(G3L_CLKSELSTATUS, 17, 1)
|
||||
#define G3L_SEL_SDHI2_STS SEL_PLL_PACK(G3L_CLKSELSTATUS, 18, 1)
|
||||
#define G3L_DIV_GE3D_STS DDIV_PACK(G3L_CLKDIVSTATUS, 27, 1)
|
||||
|
||||
/* RZ/G3L Specific clocks select. */
|
||||
#define G3L_SEL_SDHI0 SEL_PLL_PACK(G3L_CPG_SDHI_DSEL, 0, 2)
|
||||
#define G3L_SEL_SDHI1 SEL_PLL_PACK(G3L_CPG_SDHI_DSEL, 4, 2)
|
||||
#define G3L_SEL_SDHI2 SEL_PLL_PACK(G3L_CPG_SDHI_DSEL, 8, 2)
|
||||
#define G3L_SEL_ETH0_TX SEL_PLL_PACK(G3L_CPG_ETH_SSEL, 0, 1)
|
||||
#define G3L_SEL_ETH0_RX SEL_PLL_PACK(G3L_CPG_ETH_SSEL, 1, 1)
|
||||
#define G3L_SEL_ETH0_RM SEL_PLL_PACK(G3L_CPG_ETH_SSEL, 2, 1)
|
||||
@@ -73,6 +93,7 @@
|
||||
#define G3L_SEL_ETH1_RM SEL_PLL_PACK(G3L_CPG_ETH_SSEL, 10, 1)
|
||||
#define G3L_SEL_ETH1_CLK_TX_I SEL_PLL_PACK(G3L_CPG_ETH_SSEL, 11, 1)
|
||||
#define G3L_SEL_ETH1_CLK_RX_I SEL_PLL_PACK(G3L_CPG_ETH_SSEL, 12, 1)
|
||||
#define G3L_SEL_GE3D SEL_PLL_PACK(G3L_CPG_GE3D_SSEL, 0, 2)
|
||||
#define G3L_SEL_RSCI0 SEL_PLL_PACK(G3L_CPG_RSCI_SSEL, 0, 2)
|
||||
#define G3L_SEL_RSCI1 SEL_PLL_PACK(G3L_CPG_RSCI_SSEL, 2, 2)
|
||||
#define G3L_SEL_RSCI2 SEL_PLL_PACK(G3L_CPG_RSCI_SSEL, 4, 2)
|
||||
@@ -94,6 +115,7 @@ enum clk_ids {
|
||||
|
||||
/* Internal Core Clocks */
|
||||
CLK_PLL1,
|
||||
CLK_PLL1_DIV2,
|
||||
CLK_PLL2,
|
||||
CLK_PLL2_DIV2,
|
||||
CLK_PLL2_DIV2_4,
|
||||
@@ -102,6 +124,8 @@ enum clk_ids {
|
||||
CLK_PLL2_DIV7,
|
||||
CLK_PLL3,
|
||||
CLK_PLL3_DIV2,
|
||||
CLK_PLL3_DIV2_2,
|
||||
CLK_PLL3_DIV3,
|
||||
CLK_PLL6,
|
||||
CLK_PLL6_DIV10,
|
||||
CLK_SEL_ETH0_TX,
|
||||
@@ -110,6 +134,7 @@ enum clk_ids {
|
||||
CLK_SEL_ETH1_TX,
|
||||
CLK_SEL_ETH1_RX,
|
||||
CLK_SEL_ETH1_RM,
|
||||
CLK_SEL_GE3D,
|
||||
CLK_SEL_RSCI0,
|
||||
CLK_SEL_RSCI1,
|
||||
CLK_SEL_RSCI2,
|
||||
@@ -117,16 +142,29 @@ enum clk_ids {
|
||||
CLK_SEL_RSPI0,
|
||||
CLK_SEL_RSPI1,
|
||||
CLK_SEL_RSPI2,
|
||||
CLK_SEL_SDHI0,
|
||||
CLK_SEL_SDHI1,
|
||||
CLK_SEL_SDHI2,
|
||||
CLK_ETH0_TR,
|
||||
CLK_ETH0_RM,
|
||||
CLK_ETH1_TR,
|
||||
CLK_ETH1_RM,
|
||||
CLK_SD0_DIV2,
|
||||
CLK_SD1_DIV2,
|
||||
CLK_SD2_DIV2,
|
||||
|
||||
/* Module Clocks */
|
||||
MOD_CLK_BASE,
|
||||
};
|
||||
|
||||
/* Divider tables */
|
||||
static const struct clk_div_table dtable_1_4[] = {
|
||||
{ 0, 1 },
|
||||
{ 1, 2 },
|
||||
{ 2, 4 },
|
||||
{ 0, 0 },
|
||||
};
|
||||
|
||||
static const struct clk_div_table dtable_1_8[] = {
|
||||
{ 0, 1 },
|
||||
{ 1, 2 },
|
||||
@@ -189,12 +227,17 @@ static const char * const sel_eth0_rm[] = { ".pll6_div10", "eth0_rxc_rx_clk" };
|
||||
static const char * const sel_eth1_tx[] = { ".div_eth1_tr", "eth1_txc_tx_clk" };
|
||||
static const char * const sel_eth1_rx[] = { ".div_eth1_tr", "eth1_rxc_rx_clk" };
|
||||
static const char * const sel_eth1_rm[] = { ".pll6_div10", "eth1_rxc_rx_clk" };
|
||||
static const char * const sel_ge3d[] = { ".pll1_div2", ".pll3_div3", ".pll6", ".pll3_div2_2" };
|
||||
static const char * const sel_rsci_rspi[] = { ".pll2_div5", ".pll2_div6", ".pll2_div7", ".pll2_div2_4" };
|
||||
static const char * const sel_sdhi[] = { ".pll2_div2", ".pll1_div2", ".pll6", ".pll2_div6" };
|
||||
static const char * const sel_eth0_clk_tx_i[] = { ".sel_eth0_tx", ".div_eth0_rm" };
|
||||
static const char * const sel_eth0_clk_rx_i[] = { ".sel_eth0_rx", ".div_eth0_rm" };
|
||||
static const char * const sel_eth1_clk_tx_i[] = { ".sel_eth1_tx", ".div_eth1_rm" };
|
||||
static const char * const sel_eth1_clk_rx_i[] = { ".sel_eth1_rx", ".div_eth1_rm" };
|
||||
|
||||
/* Mux clock indices tables. */
|
||||
static const u32 mtable_sd[] = { 0, 1, 2, 3 };
|
||||
|
||||
static const struct cpg_core_clk r9a08g046_core_clks[] __initconst = {
|
||||
/* External Clock Inputs */
|
||||
DEF_INPUT("extal", CLK_EXTAL),
|
||||
@@ -210,13 +253,23 @@ static const struct cpg_core_clk r9a08g046_core_clks[] __initconst = {
|
||||
DEF_FIXED(".pll3", CLK_PLL3, CLK_EXTAL, 200, 3),
|
||||
DEF_G3L_PLL(".pll6", CLK_PLL6, CLK_EXTAL, CPG_PLL_CONF(0x50, 0),
|
||||
500000000UL),
|
||||
DEF_FIXED(".pll1_div2", CLK_PLL1_DIV2, CLK_PLL1, 1, 2),
|
||||
DEF_FIXED(".pll2_div2", CLK_PLL2_DIV2, CLK_PLL2, 1, 2),
|
||||
DEF_FIXED(".pll2_div2_4", CLK_PLL2_DIV2_4, CLK_PLL2_DIV2, 1, 4),
|
||||
DEF_FIXED(".pll2_div5", CLK_PLL2_DIV5, CLK_PLL2, 1, 5),
|
||||
DEF_FIXED(".pll2_div6", CLK_PLL2_DIV6, CLK_PLL2, 1, 6),
|
||||
DEF_FIXED(".pll2_div7", CLK_PLL2_DIV7, CLK_PLL2, 1, 7),
|
||||
DEF_FIXED(".pll3_div2", CLK_PLL3_DIV2, CLK_PLL3, 1, 2),
|
||||
DEF_FIXED(".pll3_div2_2", CLK_PLL3_DIV2_2, CLK_PLL3_DIV2, 1, 2),
|
||||
DEF_FIXED(".pll3_div3", CLK_PLL3_DIV3, CLK_PLL3, 1, 3),
|
||||
DEF_FIXED(".pll6_div10", CLK_PLL6_DIV10, CLK_PLL6, 1, 10),
|
||||
DEF_SD_MUX(".sel_sdhi0", CLK_SEL_SDHI0, G3L_SEL_SDHI0, G3L_SEL_SDHI0_STS, sel_sdhi,
|
||||
mtable_sd, 0, NULL),
|
||||
DEF_SD_MUX(".sel_sdhi1", CLK_SEL_SDHI1, G3L_SEL_SDHI1, G3L_SEL_SDHI1_STS, sel_sdhi,
|
||||
mtable_sd, 0, NULL),
|
||||
DEF_SD_MUX(".sel_sdhi2", CLK_SEL_SDHI2, G3L_SEL_SDHI2, G3L_SEL_SDHI2_STS, sel_sdhi,
|
||||
mtable_sd, 0, NULL),
|
||||
DEF_MUX(".sel_ge3d", CLK_SEL_GE3D, G3L_SEL_GE3D, sel_ge3d),
|
||||
DEF_MUX(".sel_rsci0", CLK_SEL_RSCI0, G3L_SEL_RSCI0, sel_rsci_rspi),
|
||||
DEF_MUX(".sel_rsci1", CLK_SEL_RSCI1, G3L_SEL_RSCI1, sel_rsci_rspi),
|
||||
DEF_MUX(".sel_rsci2", CLK_SEL_RSCI2, G3L_SEL_RSCI2, sel_rsci_rspi),
|
||||
@@ -264,6 +317,18 @@ static const struct cpg_core_clk r9a08g046_core_clks[] __initconst = {
|
||||
dtable_1_8, 0, 200000000UL, 0, NULL),
|
||||
DEF_G3S_DIV("P19", R9A08G046_CLK_P19, CLK_SEL_RSPI2, G3L_DIV_RSPI2, G3L_DIV_RSPI2_STS,
|
||||
dtable_1_8, 0, 200000000UL, 0, NULL),
|
||||
DEF_G3S_DIV("SD0", R9A08G046_CLK_SD0, CLK_SEL_SDHI0, G3L_DIV_SDHI0, G3L_DIV_SDHI0_STS,
|
||||
dtable_1_4, 800000000UL, 600000000UL, CLK_SET_RATE_PARENT,
|
||||
rzg3s_cpg_div_clk_notifier),
|
||||
DEF_G3S_DIV("SD1", R9A08G046_CLK_SD1, CLK_SEL_SDHI1, G3L_DIV_SDHI1, G3L_DIV_SDHI1_STS,
|
||||
dtable_1_4, 800000000UL, 600000000UL, CLK_SET_RATE_PARENT,
|
||||
rzg3s_cpg_div_clk_notifier),
|
||||
DEF_G3S_DIV("SD2", R9A08G046_CLK_SD2, CLK_SEL_SDHI2, G3L_DIV_SDHI2, G3L_DIV_SDHI2_STS,
|
||||
dtable_1_4, 800000000UL, 600000000UL, CLK_SET_RATE_PARENT,
|
||||
rzg3s_cpg_div_clk_notifier),
|
||||
DEF_FIXED(".sd0_div2", CLK_SD0_DIV2, R9A08G046_CLK_SD0, 1, 2),
|
||||
DEF_FIXED(".sd1_div2", CLK_SD1_DIV2, R9A08G046_CLK_SD1, 1, 2),
|
||||
DEF_FIXED(".sd2_div2", CLK_SD2_DIV2, R9A08G046_CLK_SD2, 1, 2),
|
||||
DEF_FIXED("HP", R9A08G046_CLK_HP, CLK_PLL6_DIV10, 1, 1),
|
||||
DEF_MUX_FLAGS("ETHTX01", R9A08G046_CLK_ETHTX01, G3L_SEL_ETH0_CLK_TX_I, sel_eth0_clk_tx_i,
|
||||
CLK_SET_RATE_PARENT),
|
||||
@@ -279,6 +344,8 @@ static const struct cpg_core_clk r9a08g046_core_clks[] __initconst = {
|
||||
DEF_FIXED("ETHRM1", R9A08G046_CLK_ETHRM1, CLK_SEL_ETH1_RM, 1, 1),
|
||||
DEF_FIXED("ETHTX12", R9A08G046_CLK_ETHTX12, CLK_SEL_ETH1_TX, 1, 1),
|
||||
DEF_FIXED("ETHRX12", R9A08G046_CLK_ETHRX12, CLK_SEL_ETH1_RX, 1, 1),
|
||||
DEF_G3S_DIV("G", R9A08G046_CLK_G, CLK_SEL_GE3D, G3L_DIV_GE3D, G3L_DIV_GE3D_STS,
|
||||
dtable_1_32, 0, 0, 0, NULL),
|
||||
DEF_FIXED("OSCCLK", R9A08G046_OSCCLK, CLK_EXTAL, 1, 1),
|
||||
};
|
||||
|
||||
@@ -297,6 +364,42 @@ static const struct rzg2l_mod_clk r9a08g046_mod_clks[] = {
|
||||
MSTOP(BUS_REG0, BIT(0))),
|
||||
DEF_MOD("wdt0_clk", R9A08G046_WDT0_CLK, R9A08G046_OSCCLK, 0x548, 1,
|
||||
MSTOP(BUS_REG0, BIT(0))),
|
||||
DEF_MOD("sdhi0_imclk", R9A08G046_SDHI0_IMCLK, CLK_SD0_DIV2, 0x554, 0,
|
||||
MSTOP(BUS_PERI_COM, BIT(0))),
|
||||
DEF_MOD("sdhi0_imclk2", R9A08G046_SDHI0_IMCLK2, CLK_SD0_DIV2, 0x554, 1,
|
||||
MSTOP(BUS_PERI_COM, BIT(0))),
|
||||
DEF_MOD("sdhi0_clk_hs", R9A08G046_SDHI0_CLK_HS, R9A08G046_CLK_SD0, 0x554, 2,
|
||||
MSTOP(BUS_PERI_COM, BIT(0))),
|
||||
DEF_MOD("sdhi0_iaclks", R9A08G046_SDHI0_IACLKS, R9A08G046_CLK_P1, 0x554, 3,
|
||||
MSTOP(BUS_PERI_COM, BIT(0))),
|
||||
DEF_MOD("sdhi0_iaclkm", R9A08G046_SDHI0_IACLKM, R9A08G046_CLK_P1, 0x554, 12,
|
||||
MSTOP(BUS_PERI_COM, BIT(0))),
|
||||
DEF_MOD("sdhi1_imclk", R9A08G046_SDHI1_IMCLK, CLK_SD1_DIV2, 0x554, 4,
|
||||
MSTOP(BUS_PERI_COM, BIT(1))),
|
||||
DEF_MOD("sdhi1_imclk2", R9A08G046_SDHI1_IMCLK2, CLK_SD1_DIV2, 0x554, 5,
|
||||
MSTOP(BUS_PERI_COM, BIT(1))),
|
||||
DEF_MOD("sdhi1_clk_hs", R9A08G046_SDHI1_CLK_HS, R9A08G046_CLK_SD1, 0x554, 6,
|
||||
MSTOP(BUS_PERI_COM, BIT(1))),
|
||||
DEF_MOD("sdhi1_iaclks", R9A08G046_SDHI1_IACLKS, R9A08G046_CLK_P1, 0x554, 7,
|
||||
MSTOP(BUS_PERI_COM, BIT(1))),
|
||||
DEF_MOD("sdhi1_iaclkm", R9A08G046_SDHI1_IACLKM, R9A08G046_CLK_P1, 0x554, 13,
|
||||
MSTOP(BUS_PERI_COM, BIT(1))),
|
||||
DEF_MOD("sdhi2_imclk", R9A08G046_SDHI2_IMCLK, CLK_SD2_DIV2, 0x554, 8,
|
||||
MSTOP(BUS_PERI_COM, BIT(11))),
|
||||
DEF_MOD("sdhi2_imclk2", R9A08G046_SDHI2_IMCLK2, CLK_SD2_DIV2, 0x554, 9,
|
||||
MSTOP(BUS_PERI_COM, BIT(11))),
|
||||
DEF_MOD("sdhi2_clk_hs", R9A08G046_SDHI2_CLK_HS, R9A08G046_CLK_SD2, 0x554, 10,
|
||||
MSTOP(BUS_PERI_COM, BIT(11))),
|
||||
DEF_MOD("sdhi2_iaclks", R9A08G046_SDHI2_IACLKS, R9A08G046_CLK_P1, 0x554, 11,
|
||||
MSTOP(BUS_PERI_COM, BIT(11))),
|
||||
DEF_MOD("sdhi2_iaclkm", R9A08G046_SDHI2_IACLKM, R9A08G046_CLK_P1, 0x554, 14,
|
||||
MSTOP(BUS_PERI_COM, BIT(11))),
|
||||
DEF_MOD("ge3d_clk", R9A08G046_GE3D_CLK, R9A08G046_CLK_G, 0x558, 0,
|
||||
MSTOP(BUS_PERI_VIDEO, BIT(12))),
|
||||
DEF_MOD("ge3d_axi_clk", R9A08G046_GE3D_AXI_CLK, R9A08G046_CLK_P1, 0x558, 1,
|
||||
MSTOP(BUS_PERI_VIDEO, BIT(12))),
|
||||
DEF_MOD("ge3d_ace_clk", R9A08G046_GE3D_ACE_CLK, R9A08G046_CLK_P1, 0x558, 2,
|
||||
MSTOP(BUS_PERI_VIDEO, BIT(12))),
|
||||
DEF_MOD("ssi0_pclk2", R9A08G046_SSI0_PCLK2, R9A08G046_CLK_P0, 0x570, 0,
|
||||
MSTOP(BUS_MCPU1, BIT(10))),
|
||||
DEF_MOD("ssi0_pclk_sfr", R9A08G046_SSI0_PCLK_SFR, R9A08G046_CLK_P0, 0x570, 1,
|
||||
@@ -313,6 +416,16 @@ static const struct rzg2l_mod_clk r9a08g046_mod_clks[] = {
|
||||
MSTOP(BUS_MCPU1, BIT(13))),
|
||||
DEF_MOD("ssi3_pclk_sfr", R9A08G046_SSI3_PCLK_SFR, R9A08G046_CLK_P0, 0x570, 7,
|
||||
MSTOP(BUS_MCPU1, BIT(13))),
|
||||
DEF_MOD("usb_u2h0_hclk", R9A08G046_USB_U2H0_HCLK, R9A08G046_CLK_P1, 0x578, 0,
|
||||
MSTOP(BUS_PERI_COM, BIT(5))),
|
||||
DEF_MOD("usb_u2h1_hclk", R9A08G046_USB_U2H1_HCLK, R9A08G046_CLK_P1, 0x578, 1,
|
||||
MSTOP(BUS_PERI_COM, BIT(7))),
|
||||
DEF_MOD("usb_u2p0_exr_cpuclk", R9A08G046_USB_U2P0_EXR_CPUCLK, R9A08G046_CLK_P1, 0x578, 2,
|
||||
MSTOP(BUS_PERI_COM, BIT(6))),
|
||||
DEF_MOD("usb_pclk", R9A08G046_USB_PCLK, R9A08G046_CLK_P1, 0x578, 3,
|
||||
MSTOP(BUS_PERI_COM, BIT(4))),
|
||||
DEF_MOD("usb_u2p1_exr_cpuclk", R9A08G046_USB_U2P1_EXR_CPUCLK, R9A08G046_CLK_P1, 0x578, 4,
|
||||
MSTOP(BUS_PERI_COM, BIT(13))),
|
||||
DEF_MOD("eth0_clk_axi", R9A08G046_ETH0_CLK_AXI, R9A08G046_CLK_P1, 0x57c, 0,
|
||||
MSTOP(BUS_PERI_COM, BIT(2))),
|
||||
DEF_MOD("eth1_clk_axi", R9A08G046_ETH1_CLK_AXI, R9A08G046_CLK_P1, 0x57c, 1,
|
||||
@@ -412,10 +525,27 @@ static const struct rzg2l_reset r9a08g046_resets[] = {
|
||||
DEF_RST(R9A08G046_DMAC_ARESETN, 0x82c, 0),
|
||||
DEF_RST(R9A08G046_DMAC_RST_ASYNC, 0x82c, 1),
|
||||
DEF_RST(R9A08G046_WDT0_PRESETN, 0x848, 0),
|
||||
DEF_RST(R9A08G046_SDHI0_IXRST, 0x854, 0),
|
||||
DEF_RST(R9A08G046_SDHI1_IXRST, 0x854, 1),
|
||||
DEF_RST(R9A08G046_SDHI2_IXRST, 0x854, 2),
|
||||
DEF_RST(R9A08G046_SDHI0_IXRSTAXIM, 0x854, 3),
|
||||
DEF_RST(R9A08G046_SDHI0_IXRSTAXIS, 0x854, 4),
|
||||
DEF_RST(R9A08G046_SDHI1_IXRSTAXIM, 0x854, 5),
|
||||
DEF_RST(R9A08G046_SDHI1_IXRSTAXIS, 0x854, 6),
|
||||
DEF_RST(R9A08G046_SDHI2_IXRSTAXIM, 0x854, 7),
|
||||
DEF_RST(R9A08G046_SDHI2_IXRSTAXIS, 0x854, 8),
|
||||
DEF_RST(R9A08G046_GE3D_RESETN, 0x858, 0),
|
||||
DEF_RST(R9A08G046_GE3D_AXI_RESETN, 0x858, 1),
|
||||
DEF_RST(R9A08G046_GE3D_ACE_RESETN, 0x858, 2),
|
||||
DEF_RST(R9A08G046_SSI0_RST_M2_REG, 0x870, 0),
|
||||
DEF_RST(R9A08G046_SSI1_RST_M2_REG, 0x870, 1),
|
||||
DEF_RST(R9A08G046_SSI2_RST_M2_REG, 0x870, 2),
|
||||
DEF_RST(R9A08G046_SSI3_RST_M2_REG, 0x870, 3),
|
||||
DEF_RST(R9A08G046_USB_U2H0_HRESETN, 0x878, 0),
|
||||
DEF_RST(R9A08G046_USB_U2H1_HRESETN, 0x878, 1),
|
||||
DEF_RST(R9A08G046_USB_U2P0_EXL_SYSRST, 0x878, 2),
|
||||
DEF_RST(R9A08G046_USB_PRESETN, 0x878, 3),
|
||||
DEF_RST(R9A08G046_USB_U2P1_EXL_SYSRST, 0x878, 4),
|
||||
DEF_RST(R9A08G046_ETH0_ARESET_N, 0x87c, 0),
|
||||
DEF_RST(R9A08G046_ETH1_ARESET_N, 0x87c, 1),
|
||||
DEF_RST(R9A08G046_I2C0_MRST, 0x880, 0),
|
||||
|
||||
@@ -23,6 +23,8 @@ enum clk_ids {
|
||||
CLK_AUDIO_EXTAL,
|
||||
CLK_RTXIN,
|
||||
CLK_QEXTAL,
|
||||
CLK_AUDIO_CLKB,
|
||||
CLK_AUDIO_CLKC,
|
||||
|
||||
/* PLL Clocks */
|
||||
CLK_PLLCM33,
|
||||
@@ -44,6 +46,7 @@ enum clk_ids {
|
||||
CLK_SMUX2_XSPI_CLK1,
|
||||
CLK_PLLCM33_XSPI,
|
||||
CLK_PLLCLN_DIV2,
|
||||
CLK_PLLCLN_DIV4,
|
||||
CLK_PLLCLN_DIV8,
|
||||
CLK_PLLCLN_DIV16,
|
||||
CLK_PLLCLN_DIV20,
|
||||
@@ -159,6 +162,8 @@ static const struct cpg_core_clk r9a09g047_core_clks[] __initconst = {
|
||||
DEF_INPUT("audio_extal", CLK_AUDIO_EXTAL),
|
||||
DEF_INPUT("rtxin", CLK_RTXIN),
|
||||
DEF_INPUT("qextal", CLK_QEXTAL),
|
||||
DEF_INPUT("audio_clkb", CLK_AUDIO_CLKB),
|
||||
DEF_INPUT("audio_clkc", CLK_AUDIO_CLKC),
|
||||
|
||||
/* PLL Clocks */
|
||||
DEF_FIXED(".pllcm33", CLK_PLLCM33, CLK_QEXTAL, 200, 3),
|
||||
@@ -183,6 +188,7 @@ static const struct cpg_core_clk r9a09g047_core_clks[] __initconst = {
|
||||
DEF_CSDIV(".pllcm33_xspi", CLK_PLLCM33_XSPI, CLK_SMUX2_XSPI_CLK1, CSDIV0_DIVCTL3,
|
||||
dtable_2_16),
|
||||
DEF_FIXED(".pllcln_div2", CLK_PLLCLN_DIV2, CLK_PLLCLN, 1, 2),
|
||||
DEF_FIXED(".pllcln_div4", CLK_PLLCLN_DIV4, CLK_PLLCLN, 1, 4),
|
||||
DEF_FIXED(".pllcln_div8", CLK_PLLCLN_DIV8, CLK_PLLCLN, 1, 8),
|
||||
DEF_FIXED(".pllcln_div16", CLK_PLLCLN_DIV16, CLK_PLLCLN, 1, 16),
|
||||
DEF_FIXED(".pllcln_div20", CLK_PLLCLN_DIV20, CLK_PLLCLN, 1, 20),
|
||||
@@ -194,6 +200,7 @@ static const struct cpg_core_clk r9a09g047_core_clks[] __initconst = {
|
||||
DEF_FIXED(".plldty_acpu_div2", CLK_PLLDTY_ACPU_DIV2, CLK_PLLDTY_ACPU, 1, 2),
|
||||
DEF_FIXED(".plldty_acpu_div4", CLK_PLLDTY_ACPU_DIV4, CLK_PLLDTY_ACPU, 1, 4),
|
||||
DEF_FIXED(".plldty_div8", CLK_PLLDTY_DIV8, CLK_PLLDTY, 1, 8),
|
||||
DEF_FIXED(".plldty_div16", CLK_PLLDTY_DIV16, CLK_PLLDTY, 1, 16),
|
||||
|
||||
DEF_FIXED(".plleth_250_fix", CLK_PLLETH_DIV_250_FIX, CLK_PLLETH, 1, 4),
|
||||
DEF_FIXED(".plleth_125_fix", CLK_PLLETH_DIV_125_FIX, CLK_PLLETH_DIV_250_FIX, 1, 2),
|
||||
@@ -205,7 +212,6 @@ static const struct cpg_core_clk r9a09g047_core_clks[] __initconst = {
|
||||
DEF_SMUX(".smux2_gbe0_rxclk", CLK_SMUX2_GBE0_RXCLK, SSEL0_SELCTL3, smux2_gbe0_rxclk),
|
||||
DEF_SMUX(".smux2_gbe1_txclk", CLK_SMUX2_GBE1_TXCLK, SSEL1_SELCTL0, smux2_gbe1_txclk),
|
||||
DEF_SMUX(".smux2_gbe1_rxclk", CLK_SMUX2_GBE1_RXCLK, SSEL1_SELCTL1, smux2_gbe1_rxclk),
|
||||
DEF_FIXED(".plldty_div16", CLK_PLLDTY_DIV16, CLK_PLLDTY, 1, 16),
|
||||
DEF_DDIV(".plldty_rcpu", CLK_PLLDTY_RCPU, CLK_PLLDTY, CDDIV3_DIVCTL2, dtable_2_64),
|
||||
DEF_FIXED(".plldty_rcpu_div4", CLK_PLLDTY_RCPU_DIV4, CLK_PLLDTY_RCPU, 1, 4),
|
||||
|
||||
@@ -530,10 +536,110 @@ static const struct rzv2h_mod_clk r9a09g047_mod_clks[] __initconst = {
|
||||
BUS_MSTOP(3, BIT(4))),
|
||||
DEF_MOD("ge3d_ace_clk", CLK_PLLDTY_ACPU_DIV2, 15, 2, 7, 18,
|
||||
BUS_MSTOP(3, BIT(4))),
|
||||
DEF_MOD("ssif_0_clk", CLK_PLLCLN_DIV8, 15, 5, 7, 21,
|
||||
BUS_MSTOP(2, BIT(3) | BIT(4))),
|
||||
DEF_MOD("scu_0_clk", CLK_PLLCLN_DIV8, 15, 6, 7, 22,
|
||||
BUS_MSTOP(2, BIT(0) | BIT(1))),
|
||||
DEF_MOD("scu_0_clkx2", CLK_PLLCLN_DIV4, 15, 7, 7, 23,
|
||||
BUS_MSTOP(2, BIT(0) | BIT(1))),
|
||||
DEF_MOD("dmacpp_0_clk", CLK_PLLCLN_DIV8, 15, 8, 7, 24,
|
||||
BUS_MSTOP(2, BIT(5))),
|
||||
DEF_MOD("adg_0_clks1", CLK_PLLCLN_DIV8, 15, 9, 7, 25,
|
||||
BUS_MSTOP(2, BIT(2))),
|
||||
DEF_MOD("adg_0_clk_195m", CLK_PLLCLN_DIV8, 15, 10, 7, 26,
|
||||
BUS_MSTOP(2, BIT(2))),
|
||||
DEF_MOD("adg_0_audio_clka", CLK_AUDIO_EXTAL, 15, 11, 7, 27,
|
||||
BUS_MSTOP(2, BIT(2))),
|
||||
DEF_MOD("adg_0_audio_clkb", CLK_AUDIO_CLKB, 15, 12, 7, 28,
|
||||
BUS_MSTOP(2, BIT(2))),
|
||||
DEF_MOD("adg_0_audio_clkc", CLK_AUDIO_CLKC, 15, 13, 7, 29,
|
||||
BUS_MSTOP(2, BIT(2))),
|
||||
DEF_MOD("tsu_1_pclk", CLK_QEXTAL, 16, 10, 8, 10,
|
||||
BUS_MSTOP(2, BIT(15))),
|
||||
DEF_MOD("adg_ssi0_clk", CLK_PLLCLN_DIV8, 22, 0, -1, -1,
|
||||
BUS_MSTOP(2, BIT(2))),
|
||||
DEF_MOD("adg_ssi1_clk", CLK_PLLCLN_DIV8, 22, 1, -1, -1,
|
||||
BUS_MSTOP(2, BIT(2))),
|
||||
DEF_MOD("adg_ssi2_clk", CLK_PLLCLN_DIV8, 22, 2, -1, -1,
|
||||
BUS_MSTOP(2, BIT(2))),
|
||||
DEF_MOD("adg_ssi3_clk", CLK_PLLCLN_DIV8, 22, 3, -1, -1,
|
||||
BUS_MSTOP(2, BIT(2))),
|
||||
DEF_MOD("adg_ssi4_clk", CLK_PLLCLN_DIV8, 22, 4, -1, -1,
|
||||
BUS_MSTOP(2, BIT(2))),
|
||||
DEF_MOD("adg_ssi5_clk", CLK_PLLCLN_DIV8, 22, 5, -1, -1,
|
||||
BUS_MSTOP(2, BIT(2))),
|
||||
DEF_MOD("adg_ssi6_clk", CLK_PLLCLN_DIV8, 22, 6, -1, -1,
|
||||
BUS_MSTOP(2, BIT(2))),
|
||||
DEF_MOD("adg_ssi7_clk", CLK_PLLCLN_DIV8, 22, 7, -1, -1,
|
||||
BUS_MSTOP(2, BIT(2))),
|
||||
DEF_MOD("adg_ssi8_clk", CLK_PLLCLN_DIV8, 22, 8, -1, -1,
|
||||
BUS_MSTOP(2, BIT(2))),
|
||||
DEF_MOD("adg_ssi9_clk", CLK_PLLCLN_DIV8, 22, 9, -1, -1,
|
||||
BUS_MSTOP(2, BIT(2))),
|
||||
DEF_MOD("dvc0_clk", CLK_PLLCLN_DIV8, 23, 0, -1, -1,
|
||||
BUS_MSTOP(2, BIT(0) | BIT(1))),
|
||||
DEF_MOD("dvc1_clk", CLK_PLLCLN_DIV8, 23, 1, -1, -1,
|
||||
BUS_MSTOP(2, BIT(0) | BIT(1))),
|
||||
DEF_MOD("ctu0_mix0_clk", CLK_PLLCLN_DIV8, 23, 2, -1, -1,
|
||||
BUS_MSTOP(2, BIT(0) | BIT(1))),
|
||||
DEF_MOD("ctu1_mix1_clk", CLK_PLLCLN_DIV8, 23, 3, -1, -1,
|
||||
BUS_MSTOP(2, BIT(0) | BIT(1))),
|
||||
DEF_MOD("src0_clk", CLK_PLLCLN_DIV8, 23, 4, -1, -1,
|
||||
BUS_MSTOP(2, BIT(0) | BIT(1))),
|
||||
DEF_MOD("src1_clk", CLK_PLLCLN_DIV8, 23, 5, -1, -1,
|
||||
BUS_MSTOP(2, BIT(0) | BIT(1))),
|
||||
DEF_MOD("src2_clk", CLK_PLLCLN_DIV8, 23, 6, -1, -1,
|
||||
BUS_MSTOP(2, BIT(0) | BIT(1))),
|
||||
DEF_MOD("src3_clk", CLK_PLLCLN_DIV8, 23, 7, -1, -1,
|
||||
BUS_MSTOP(2, BIT(0) | BIT(1))),
|
||||
DEF_MOD("src4_clk", CLK_PLLCLN_DIV8, 23, 8, -1, -1,
|
||||
BUS_MSTOP(2, BIT(0) | BIT(1))),
|
||||
DEF_MOD("src5_clk", CLK_PLLCLN_DIV8, 23, 9, -1, -1,
|
||||
BUS_MSTOP(2, BIT(0) | BIT(1))),
|
||||
DEF_MOD("src6_clk", CLK_PLLCLN_DIV8, 23, 10, -1, -1,
|
||||
BUS_MSTOP(2, BIT(0) | BIT(1))),
|
||||
DEF_MOD("src7_clk", CLK_PLLCLN_DIV8, 23, 11, -1, -1,
|
||||
BUS_MSTOP(2, BIT(0) | BIT(1))),
|
||||
DEF_MOD("src8_clk", CLK_PLLCLN_DIV8, 23, 12, -1, -1,
|
||||
BUS_MSTOP(2, BIT(0) | BIT(1))),
|
||||
DEF_MOD("src9_clk", CLK_PLLCLN_DIV8, 23, 13, -1, -1,
|
||||
BUS_MSTOP(2, BIT(0) | BIT(1))),
|
||||
DEF_MOD("scu_supply_clk", CLK_PLLCLN_DIV8, 23, 14, -1, -1,
|
||||
BUS_MSTOP(2, BIT(0) | BIT(1))),
|
||||
DEF_MOD("ssiu_supply_clk", CLK_PLLCLN_DIV8, 24, 0, -1, -1,
|
||||
BUS_MSTOP(2, BIT(3) | BIT(4))),
|
||||
DEF_MOD("ssi0_clk", CLK_PLLCLN_DIV8, 24, 1, -1, -1,
|
||||
BUS_MSTOP(2, BIT(3) | BIT(4))),
|
||||
DEF_MOD("ssi1_clk", CLK_PLLCLN_DIV8, 24, 2, -1, -1,
|
||||
BUS_MSTOP(2, BIT(3) | BIT(4))),
|
||||
DEF_MOD("ssi2_clk", CLK_PLLCLN_DIV8, 24, 3, -1, -1,
|
||||
BUS_MSTOP(2, BIT(3) | BIT(4))),
|
||||
DEF_MOD("ssi3_clk", CLK_PLLCLN_DIV8, 24, 4, -1, -1,
|
||||
BUS_MSTOP(2, BIT(3) | BIT(4))),
|
||||
DEF_MOD("ssi4_clk", CLK_PLLCLN_DIV8, 24, 5, -1, -1,
|
||||
BUS_MSTOP(2, BIT(3) | BIT(4))),
|
||||
DEF_MOD("ssi5_clk", CLK_PLLCLN_DIV8, 24, 6, -1, -1,
|
||||
BUS_MSTOP(2, BIT(3) | BIT(4))),
|
||||
DEF_MOD("ssi6_clk", CLK_PLLCLN_DIV8, 24, 7, -1, -1,
|
||||
BUS_MSTOP(2, BIT(3) | BIT(4))),
|
||||
DEF_MOD("ssi7_clk", CLK_PLLCLN_DIV8, 24, 8, -1, -1,
|
||||
BUS_MSTOP(2, BIT(3) | BIT(4))),
|
||||
DEF_MOD("ssi8_clk", CLK_PLLCLN_DIV8, 24, 9, -1, -1,
|
||||
BUS_MSTOP(2, BIT(3) | BIT(4))),
|
||||
DEF_MOD("ssi9_clk", CLK_PLLCLN_DIV8, 24, 10, -1, -1,
|
||||
BUS_MSTOP(2, BIT(3) | BIT(4))),
|
||||
DEF_MOD("dsi_0_vclk2", CLK_SMUX2_DSI1_CLK, 25, 0, 10, 21,
|
||||
BUS_MSTOP(9, BIT(15) | BIT(14))),
|
||||
DEF_MOD("lvds_top_clk_ch0", CLK_PLLDSI0, 26, 0, 10, 22,
|
||||
BUS_MSTOP(13, BIT(0))),
|
||||
DEF_MOD("lvds_top_clk_ch1", CLK_PLLDSI1, 26, 1, 10, 23,
|
||||
BUS_MSTOP(13, BIT(0))),
|
||||
DEF_MOD("lvds_top_clk_dot_ch0", CLK_SMUX2_DSI0_CLK, 26, 2, 10, 24,
|
||||
BUS_MSTOP(13, BIT(0))),
|
||||
DEF_MOD("lvds_top_clk_dot_ch1", CLK_SMUX2_DSI1_CLK, 26, 3, 10, 25,
|
||||
BUS_MSTOP(13, BIT(0))),
|
||||
DEF_MOD("lvds_top_pclk", CLK_PLLDTY_DIV16, 26, 4, 10, 26,
|
||||
BUS_MSTOP(13, BIT(0))),
|
||||
DEF_MOD("lcdc_1_clk_a", CLK_PLLDTY_ACPU_DIV2, 26, 8, 10, 30,
|
||||
BUS_MSTOP(13, BIT(5) | BIT(4) | BIT(3))),
|
||||
DEF_MOD("lcdc_1_clk_p", CLK_PLLDTY_DIV16, 26, 9, 10, 31,
|
||||
@@ -621,7 +727,22 @@ static const struct rzv2h_reset r9a09g047_resets[] __initconst = {
|
||||
DEF_RST(13, 13, 6, 14), /* GE3D_RESETN */
|
||||
DEF_RST(13, 14, 6, 15), /* GE3D_AXI_RESETN */
|
||||
DEF_RST(13, 15, 6, 16), /* GE3D_ACE_RESETN */
|
||||
DEF_RST(14, 1, 6, 18), /* SSIF_0_ASYNC_RESET_SSI */
|
||||
DEF_RST(14, 2, 6, 19), /* SSIF_0_SYNC_RESET_SSI0 */
|
||||
DEF_RST(14, 3, 6, 20), /* SSIF_0_SYNC_RESET_SSI1 */
|
||||
DEF_RST(14, 4, 6, 21), /* SSIF_0_SYNC_RESET_SSI2 */
|
||||
DEF_RST(14, 5, 6, 22), /* SSIF_0_SYNC_RESET_SSI3 */
|
||||
DEF_RST(14, 6, 6, 23), /* SSIF_0_SYNC_RESET_SSI4 */
|
||||
DEF_RST(14, 7, 6, 24), /* SSIF_0_SYNC_RESET_SSI5 */
|
||||
DEF_RST(14, 8, 6, 25), /* SSIF_0_SYNC_RESET_SSI6 */
|
||||
DEF_RST(14, 9, 6, 26), /* SSIF_0_SYNC_RESET_SSI7 */
|
||||
DEF_RST(14, 10, 6, 27), /* SSIF_0_SYNC_RESET_SSI8 */
|
||||
DEF_RST(14, 11, 6, 28), /* SSIF_0_SYNC_RESET_SSI9 */
|
||||
DEF_RST(14, 12, 6, 29), /* SCU_0_RESET_SRU */
|
||||
DEF_RST(14, 13, 6, 30), /* DMACpp_0_ARST */
|
||||
DEF_RST(14, 14, 6, 31), /* ADG_0_RST_RESET_ADG */
|
||||
DEF_RST(15, 8, 7, 9), /* TSU_1_PRESETN */
|
||||
DEF_RST(17, 10, 8, 11), /* LVDS_TOP_RESET_N */
|
||||
DEF_RST(17, 14, 8, 15), /* LCDC_1_RESET_N */
|
||||
};
|
||||
|
||||
|
||||
@@ -8,16 +8,23 @@
|
||||
|
||||
#include <linux/bitfield.h>
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/clk/renesas.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/iopoll.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/math.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/units.h>
|
||||
|
||||
#include <dt-bindings/clock/renesas,r9a09g077-cpg-mssr.h>
|
||||
#include <dt-bindings/clock/renesas,r9a09g087-cpg-mssr.h>
|
||||
#include "renesas-cpg-mssr.h"
|
||||
|
||||
MODULE_IMPORT_NS("RZV2H_CPG");
|
||||
|
||||
#define RZT2H_REG_BLOCK_SHIFT 11
|
||||
#define RZT2H_REG_OFFSET_MASK GENMASK(10, 0)
|
||||
#define RZT2H_REG_CONF(block, offset) (((block) << RZT2H_REG_BLOCK_SHIFT) | \
|
||||
@@ -66,11 +73,26 @@
|
||||
#define DIVSCI2ASYNC CONF_PACK(SCKCR3, 10, 2)
|
||||
#define DIVSCI3ASYNC CONF_PACK(SCKCR3, 12, 2)
|
||||
#define DIVSCI4ASYNC CONF_PACK(SCKCR3, 14, 2)
|
||||
#define LCDCDIVSEL CONF_PACK(SCKCR3, 20, 4)
|
||||
|
||||
#define PLL3EN FIELD_PREP_CONST(OFFSET_MASK, (0xc0))
|
||||
|
||||
#define CPG_PLL_EN_EN BIT(0)
|
||||
#define CPG_PLL3_VCO_CTR0(x) ((x) + 0x4)
|
||||
#define CPG_PLL3_VCO_CTR0_PDIV GENMASK(21, 16)
|
||||
#define CPG_PLL3_VCO_CTR0_MDIV GENMASK(9, 0)
|
||||
#define CPG_PLL3_VCO_CTR1(x) ((x) + 0x8)
|
||||
#define CPG_PLL3_VCO_CTR1_KDIV GENMASK(31, 16)
|
||||
#define CPG_PLL3_VCO_CTR1_SDIV GENMASK(2, 0)
|
||||
#define CPG_PLL_MON(x) ((x) - 0x10)
|
||||
#define CPG_PLL_MON_LOCK BIT(0)
|
||||
|
||||
enum rzt2h_clk_types {
|
||||
CLK_TYPE_RZT2H_DIV = CLK_TYPE_CUSTOM, /* Clock with divider */
|
||||
CLK_TYPE_RZT2H_MUX, /* Clock with clock source selector */
|
||||
CLK_TYPE_RZT2H_FSELXSPI, /* Clock with FSELXSPIn source selector */
|
||||
CLK_TYPE_RZT2H_PLL3, /* PLL3 Clock */
|
||||
CLK_TYPE_RZT2H_LCDCDIV, /* LCDC divider clock */
|
||||
};
|
||||
|
||||
#define DEF_DIV(_name, _id, _parent, _conf, _dtable) \
|
||||
@@ -83,10 +105,51 @@ enum rzt2h_clk_types {
|
||||
#define DEF_DIV_FSELXSPI(_name, _id, _parent, _conf, _dtable) \
|
||||
DEF_TYPE(_name, _id, CLK_TYPE_RZT2H_FSELXSPI, .conf = _conf, \
|
||||
.parent = _parent, .dtable = _dtable, .flag = 0)
|
||||
#define DEF_PLL3(_name, _id, _parent, _conf) \
|
||||
DEF_TYPE(_name, _id, CLK_TYPE_RZT2H_PLL3, .conf = _conf, \
|
||||
.parent = _parent)
|
||||
#define DEF_DIV_LCDC(_name, _id, _parent, _conf, _dtable) \
|
||||
DEF_TYPE(_name, _id, CLK_TYPE_RZT2H_LCDCDIV, .conf = _conf, \
|
||||
.parent = _parent, .dtable = _dtable, .flag = CLK_SET_RATE_PARENT)
|
||||
|
||||
struct pll_clk {
|
||||
void __iomem *reg;
|
||||
const struct rzv2h_pll_limits *limits;
|
||||
struct device *dev;
|
||||
struct rzv2h_pll_pars pll_parameters;
|
||||
struct clk_hw hw;
|
||||
unsigned long cur_rate;
|
||||
};
|
||||
|
||||
#define to_pll(_hw) container_of(_hw, struct pll_clk, hw)
|
||||
|
||||
struct r9a09g077_lcdc_div_clk {
|
||||
const struct clk_div_table *dtable;
|
||||
void __iomem *reg;
|
||||
struct device *dev;
|
||||
struct clk_hw hw;
|
||||
u32 conf;
|
||||
u8 divider;
|
||||
};
|
||||
|
||||
#define to_lcdc_div_clk(_hw) \
|
||||
container_of(_hw, struct r9a09g077_lcdc_div_clk, hw)
|
||||
|
||||
#define RZT2H_MAX_LCDC_DIV_TABLES 16
|
||||
|
||||
static const struct rzv2h_pll_limits r9a09g077_cpg_pll3_limits = {
|
||||
.input_fref = 48 * MEGA,
|
||||
.fout = { .min = 25 * MEGA, .max = 430 * MEGA },
|
||||
.fvco = { .min = 1600 * MEGA, .max = 3200 * MEGA },
|
||||
.m = { .min = 0x40, .max = 0x3ff },
|
||||
.p = { .min = 0x2, .max = 0x8 },
|
||||
.s = { .min = 0x0, .max = 0x6 },
|
||||
.k = { .min = -32768, .max = 32767 },
|
||||
};
|
||||
|
||||
enum clk_ids {
|
||||
/* Core Clock Outputs exported to DT */
|
||||
LAST_DT_CORE_CLK = R9A09G077_PCLKCAN,
|
||||
LAST_DT_CORE_CLK = R9A09G077_PCLKRTC,
|
||||
|
||||
/* External Input Clocks */
|
||||
CLK_EXTAL,
|
||||
@@ -96,10 +159,12 @@ enum clk_ids {
|
||||
CLK_PLL0,
|
||||
CLK_PLL1,
|
||||
CLK_PLL2,
|
||||
CLK_PLL3,
|
||||
CLK_PLL4,
|
||||
CLK_SEL_CLK_PLL0,
|
||||
CLK_SEL_CLK_PLL1,
|
||||
CLK_SEL_CLK_PLL2,
|
||||
CLK_SEL_CLK_PLL3,
|
||||
CLK_SEL_CLK_PLL4,
|
||||
CLK_PLL4D1,
|
||||
CLK_PLL4D1_DIV3,
|
||||
@@ -107,6 +172,7 @@ enum clk_ids {
|
||||
CLK_PLL4D3,
|
||||
CLK_PLL4D3_DIV10,
|
||||
CLK_PLL4D3_DIV20,
|
||||
CLK_PLL4D50,
|
||||
CLK_SCI0ASYNC,
|
||||
CLK_SCI1ASYNC,
|
||||
CLK_SCI2ASYNC,
|
||||
@@ -119,6 +185,7 @@ enum clk_ids {
|
||||
CLK_SPI3ASYNC,
|
||||
CLK_DIVSELXSPI0_SCKCR,
|
||||
CLK_DIVSELXSPI1_SCKCR,
|
||||
CLK_LCDDIVSEL,
|
||||
|
||||
/* Module Clocks */
|
||||
MOD_CLK_BASE,
|
||||
@@ -130,6 +197,26 @@ static const struct clk_div_table dtable_1_2[] = {
|
||||
{0, 0},
|
||||
};
|
||||
|
||||
static const struct clk_div_table dtable_2_32[] = {
|
||||
{0, 2},
|
||||
{1, 4},
|
||||
{2, 6},
|
||||
{3, 8},
|
||||
{4, 10},
|
||||
{5, 12},
|
||||
{6, 14},
|
||||
{7, 16},
|
||||
{8, 18},
|
||||
{9, 20},
|
||||
{10, 22},
|
||||
{11, 24},
|
||||
{12, 26},
|
||||
{13, 28},
|
||||
{14, 30},
|
||||
{15, 32},
|
||||
{0, 0},
|
||||
};
|
||||
|
||||
static const struct clk_div_table dtable_6_8_16_32_64[] = {
|
||||
{6, 64},
|
||||
{5, 32},
|
||||
@@ -152,6 +239,7 @@ static const struct clk_div_table dtable_24_25_30_32[] = {
|
||||
static const char * const sel_clk_pll0[] = { ".loco", ".pll0" };
|
||||
static const char * const sel_clk_pll1[] = { ".loco", ".pll1" };
|
||||
static const char * const sel_clk_pll2[] = { ".loco", ".pll2" };
|
||||
static const char * const sel_clk_pll3[] = { ".loco", ".pll3" };
|
||||
static const char * const sel_clk_pll4[] = { ".loco", ".pll4" };
|
||||
static const char * const sel_clk_pll4d1_div3_div4[] = { ".pll4d1_div3", ".pll4d1_div4" };
|
||||
static const char * const sel_clk_pll4d3_div10_div20[] = { ".pll4d3_div10", ".pll4d3_div20" };
|
||||
@@ -173,10 +261,14 @@ static const struct cpg_core_clk r9a09g077_core_clks[] __initconst = {
|
||||
sel_clk_pll1, ARRAY_SIZE(sel_clk_pll1), CLK_MUX_READ_ONLY),
|
||||
DEF_MUX(".sel_clk_pll2", CLK_SEL_CLK_PLL2, SEL_PLL,
|
||||
sel_clk_pll2, ARRAY_SIZE(sel_clk_pll2), CLK_MUX_READ_ONLY),
|
||||
DEF_MUX(".sel_clk_pll3", CLK_SEL_CLK_PLL3, SEL_PLL,
|
||||
sel_clk_pll3, ARRAY_SIZE(sel_clk_pll3), CLK_MUX_READ_ONLY),
|
||||
DEF_MUX(".sel_clk_pll4", CLK_SEL_CLK_PLL4, SEL_PLL,
|
||||
sel_clk_pll4, ARRAY_SIZE(sel_clk_pll4), CLK_MUX_READ_ONLY),
|
||||
|
||||
DEF_FIXED(".pll4d1", CLK_PLL4D1, CLK_SEL_CLK_PLL4, 1, 1),
|
||||
DEF_FIXED(".pll4d50", CLK_PLL4D50, CLK_SEL_CLK_PLL4, 50, 1),
|
||||
DEF_PLL3(".pll3", CLK_PLL3, CLK_PLL4D50, PLL3EN),
|
||||
DEF_FIXED(".pll4d1_div3", CLK_PLL4D1_DIV3, CLK_PLL4D1, 3, 1),
|
||||
DEF_FIXED(".pll4d1_div4", CLK_PLL4D1_DIV4, CLK_PLL4D1, 4, 1),
|
||||
DEF_FIXED(".pll4d3", CLK_PLL4D3, CLK_SEL_CLK_PLL4, 3, 1),
|
||||
@@ -229,6 +321,7 @@ static const struct cpg_core_clk r9a09g077_core_clks[] __initconst = {
|
||||
DEF_FIXED("PCLKL", R9A09G077_CLK_PCLKL, CLK_SEL_CLK_PLL1, 16, 1),
|
||||
DEF_FIXED("PCLKAH", R9A09G077_CLK_PCLKAH, CLK_PLL4D1, 6, 1),
|
||||
DEF_FIXED("PCLKAM", R9A09G077_CLK_PCLKAM, CLK_PLL4D1, 12, 1),
|
||||
DEF_FIXED("PCLKAL", R9A09G077_CLK_PCLKAL, CLK_PLL4D1, 24, 1),
|
||||
DEF_FIXED("SDHI_CLKHS", R9A09G077_SDHI_CLKHS, CLK_SEL_CLK_PLL2, 1, 1),
|
||||
DEF_FIXED("USB_CLK", R9A09G077_USB_CLK, CLK_PLL4D1, 48, 1),
|
||||
DEF_FIXED("ETCLKA", R9A09G077_ETCLKA, CLK_SEL_CLK_PLL1, 5, 1),
|
||||
@@ -242,6 +335,9 @@ static const struct cpg_core_clk r9a09g077_core_clks[] __initconst = {
|
||||
FSELXSPI1, dtable_6_8_16_32_64),
|
||||
DEF_MUX("PCLKCAN", R9A09G077_PCLKCAN, FSELCANFD,
|
||||
sel_clk_pll4d3_div10_div20, ARRAY_SIZE(sel_clk_pll4d3_div10_div20), 0),
|
||||
DEF_DIV_LCDC("LCDC_CLKD", R9A09G077_LCDC_CLKD, CLK_SEL_CLK_PLL3, LCDCDIVSEL,
|
||||
dtable_2_32),
|
||||
DEF_FIXED("PCLKRTC", R9A09G077_PCLKRTC, CLK_EXTAL, 128, 1),
|
||||
};
|
||||
|
||||
static const struct mssr_mod_clk r9a09g077_mod_clks[] __initconst = {
|
||||
@@ -272,6 +368,8 @@ static const struct mssr_mod_clk r9a09g077_mod_clks[] __initconst = {
|
||||
DEF_MOD("sci5fck", 600, CLK_SCI5ASYNC),
|
||||
DEF_MOD("iic2", 601, R9A09G077_CLK_PCLKL),
|
||||
DEF_MOD("spi3", 602, CLK_SPI3ASYNC),
|
||||
DEF_MOD("rtc", 605, R9A09G077_CLK_PCLKL),
|
||||
DEF_MOD("lcdc", 1204, R9A09G077_CLK_PCLKAL),
|
||||
DEF_MOD("sdhi0", 1212, R9A09G077_CLK_PCLKAM),
|
||||
DEF_MOD("sdhi1", 1213, R9A09G077_CLK_PCLKAM),
|
||||
};
|
||||
@@ -481,6 +579,276 @@ r9a09g077_cpg_fselxspi_div_clk_register(struct device *dev,
|
||||
return hw->clk;
|
||||
}
|
||||
|
||||
static unsigned long r9a09g077_cpg_pll3_clk_recalc_rate(struct clk_hw *hw,
|
||||
unsigned long parent_rate)
|
||||
{
|
||||
struct pll_clk *pll_clk = to_pll(hw);
|
||||
u32 ctr0, ctr1;
|
||||
u8 pdiv, sdiv;
|
||||
u64 rate;
|
||||
u16 mdiv;
|
||||
s16 kdiv;
|
||||
|
||||
ctr0 = readl(CPG_PLL3_VCO_CTR0(pll_clk->reg));
|
||||
ctr1 = readl(CPG_PLL3_VCO_CTR1(pll_clk->reg));
|
||||
|
||||
pdiv = FIELD_GET(CPG_PLL3_VCO_CTR0_PDIV, ctr0);
|
||||
mdiv = FIELD_GET(CPG_PLL3_VCO_CTR0_MDIV, ctr0);
|
||||
kdiv = (s16)FIELD_GET(CPG_PLL3_VCO_CTR1_KDIV, ctr1);
|
||||
sdiv = FIELD_GET(CPG_PLL3_VCO_CTR1_SDIV, ctr1);
|
||||
|
||||
rate = mul_u64_u32_shr(parent_rate, (mdiv << 16) + kdiv, 16 + sdiv);
|
||||
|
||||
return DIV_ROUND_CLOSEST_ULL(rate, pdiv);
|
||||
}
|
||||
|
||||
static int r9a09g077_cpg_pll3_determine_rate(struct clk_hw *hw,
|
||||
struct clk_rate_request *req)
|
||||
{
|
||||
struct pll_clk *pll_clk = to_pll(hw);
|
||||
u64 rate_millihz;
|
||||
|
||||
if (req->rate == pll_clk->cur_rate)
|
||||
return 0;
|
||||
|
||||
rate_millihz = mul_u32_u32(req->rate, MILLI);
|
||||
if (!rzv2h_cpg_get_pll_pars(pll_clk->limits, &pll_clk->pll_parameters,
|
||||
rate_millihz)) {
|
||||
dev_dbg(pll_clk->dev,
|
||||
"failed to determine rate for req->rate: %lu\n",
|
||||
req->rate);
|
||||
return -EINVAL;
|
||||
}
|
||||
req->rate = DIV_ROUND_CLOSEST_ULL(pll_clk->pll_parameters.freq_millihz, MILLI);
|
||||
pll_clk->cur_rate = req->rate;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int r9a09g077_cpg_pll3_set_rate(struct clk_hw *hw, unsigned long rate,
|
||||
unsigned long parent_rate)
|
||||
{
|
||||
struct pll_clk *pll_clk = to_pll(hw);
|
||||
struct rzv2h_pll_pars *params = &pll_clk->pll_parameters;
|
||||
void __iomem *offset = pll_clk->reg;
|
||||
u32 val;
|
||||
int ret;
|
||||
|
||||
/* Put PLL into standby mode */
|
||||
writel(0, offset);
|
||||
ret = readl_poll_timeout_atomic(CPG_PLL_MON(offset),
|
||||
val, !(val & CPG_PLL_MON_LOCK),
|
||||
100, 2000);
|
||||
if (ret) {
|
||||
dev_err(pll_clk->dev, "Failed to put PLL into standby mode");
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Output clock setting 1 */
|
||||
val = readl(CPG_PLL3_VCO_CTR0(offset));
|
||||
FIELD_MODIFY(CPG_PLL3_VCO_CTR0_MDIV, &val, params->m);
|
||||
FIELD_MODIFY(CPG_PLL3_VCO_CTR0_PDIV, &val, params->p);
|
||||
writel(val, CPG_PLL3_VCO_CTR0(offset));
|
||||
|
||||
/* Output clock setting 2 */
|
||||
val = readl(CPG_PLL3_VCO_CTR1(offset));
|
||||
FIELD_MODIFY(CPG_PLL3_VCO_CTR1_KDIV, &val, params->k);
|
||||
FIELD_MODIFY(CPG_PLL3_VCO_CTR1_SDIV, &val, params->s);
|
||||
writel(val, CPG_PLL3_VCO_CTR1(offset));
|
||||
|
||||
writel(CPG_PLL_EN_EN, offset);
|
||||
|
||||
/* PLL normal mode transition, output clock stability check */
|
||||
ret = readl_poll_timeout_atomic(CPG_PLL_MON(offset),
|
||||
val, (val & CPG_PLL_MON_LOCK),
|
||||
100, 2000);
|
||||
if (ret) {
|
||||
writel(0, offset);
|
||||
dev_err(pll_clk->dev, "Failed to put PLL into normal mode");
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct clk_ops r9a09g077_cpg_pll3_ops = {
|
||||
.recalc_rate = r9a09g077_cpg_pll3_clk_recalc_rate,
|
||||
.determine_rate = r9a09g077_cpg_pll3_determine_rate,
|
||||
.set_rate = r9a09g077_cpg_pll3_set_rate,
|
||||
};
|
||||
|
||||
static struct clk * __init
|
||||
r9a09g077_cpg_pll3_clk_register(struct device *dev,
|
||||
const struct cpg_core_clk *core,
|
||||
void __iomem *addr,
|
||||
struct cpg_mssr_pub *pub,
|
||||
const struct rzv2h_pll_limits *limits)
|
||||
{
|
||||
struct clk_init_data init = {};
|
||||
const struct clk *parent;
|
||||
const char *parent_name;
|
||||
struct pll_clk *pll_clk;
|
||||
int ret;
|
||||
|
||||
parent = pub->clks[core->parent];
|
||||
if (IS_ERR(parent))
|
||||
return ERR_CAST(parent);
|
||||
|
||||
pll_clk = devm_kzalloc(dev, sizeof(*pll_clk), GFP_KERNEL);
|
||||
if (!pll_clk)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
parent_name = __clk_get_name(parent);
|
||||
init.name = core->name;
|
||||
init.ops = &r9a09g077_cpg_pll3_ops;
|
||||
init.parent_names = &parent_name;
|
||||
init.num_parents = 1;
|
||||
|
||||
pll_clk->dev = dev;
|
||||
pll_clk->hw.init = &init;
|
||||
pll_clk->reg = addr;
|
||||
pll_clk->limits = limits;
|
||||
|
||||
ret = devm_clk_hw_register(dev, &pll_clk->hw);
|
||||
if (ret)
|
||||
return ERR_PTR(ret);
|
||||
|
||||
return pll_clk->hw.clk;
|
||||
}
|
||||
|
||||
static int r9a09g077_cpg_lcdc_div_determine_rate(struct clk_hw *hw,
|
||||
struct clk_rate_request *req)
|
||||
{
|
||||
struct r9a09g077_lcdc_div_clk *dsi_div = to_lcdc_div_clk(hw);
|
||||
struct clk_hw *mux_hw = clk_hw_get_parent(hw);
|
||||
u8 table[RZT2H_MAX_LCDC_DIV_TABLES] = { 0 };
|
||||
struct rzv2h_pll_div_pars dsi_params;
|
||||
const struct clk_div_table *div;
|
||||
struct pll_clk *pll_clk;
|
||||
unsigned int i = 0;
|
||||
u64 freq_millihz;
|
||||
|
||||
/* index 1 is always .pll3 in sel_clk_pll3[] */
|
||||
pll_clk = to_pll(clk_hw_get_parent_by_index(mux_hw, 1));
|
||||
|
||||
for (div = dsi_div->dtable; div->div; div++) {
|
||||
if (i >= RZT2H_MAX_LCDC_DIV_TABLES)
|
||||
return -EINVAL;
|
||||
table[i++] = div->div;
|
||||
}
|
||||
|
||||
freq_millihz = mul_u32_u32(req->rate, MILLI);
|
||||
|
||||
if (!rzv2h_cpg_get_pll_divs_pars(pll_clk->limits, &dsi_params, table,
|
||||
i, freq_millihz)) {
|
||||
dev_err(dsi_div->dev,
|
||||
"LCDC divider failed to determine rate for req->rate: %lu\n",
|
||||
req->rate);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
req->rate = DIV_ROUND_CLOSEST_ULL(dsi_params.div.freq_millihz, MILLI);
|
||||
req->best_parent_rate = req->rate * dsi_params.div.divider_value;
|
||||
dsi_div->divider = dsi_params.div.divider_value;
|
||||
pll_clk->cur_rate = req->best_parent_rate;
|
||||
pll_clk->pll_parameters = dsi_params.pll;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int r9a09g077_cpg_lcdc_div_set_rate(struct clk_hw *hw,
|
||||
unsigned long rate,
|
||||
unsigned long parent_rate)
|
||||
{
|
||||
struct r9a09g077_lcdc_div_clk *dsi_div = to_lcdc_div_clk(hw);
|
||||
const struct clk_div_table *clkt;
|
||||
bool divider_found = false;
|
||||
u32 val, shift;
|
||||
|
||||
for (clkt = dsi_div->dtable; clkt->div; clkt++) {
|
||||
if (clkt->div == dsi_div->divider) {
|
||||
divider_found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!divider_found)
|
||||
return -EINVAL;
|
||||
|
||||
shift = GET_SHIFT(dsi_div->conf);
|
||||
val = readl(dsi_div->reg);
|
||||
val &= ~(clk_div_mask(GET_WIDTH(dsi_div->conf)) << shift);
|
||||
val |= clkt->val << shift;
|
||||
writel(val, dsi_div->reg);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static unsigned long
|
||||
r9a09g077_cpg_lcdc_div_recalc_rate(struct clk_hw *hw,
|
||||
unsigned long parent_rate)
|
||||
{
|
||||
struct r9a09g077_lcdc_div_clk *dsi_div = to_lcdc_div_clk(hw);
|
||||
u32 div;
|
||||
|
||||
div = readl(dsi_div->reg);
|
||||
div >>= GET_SHIFT(dsi_div->conf);
|
||||
div &= clk_div_mask(GET_WIDTH(dsi_div->conf));
|
||||
div = dsi_div->dtable[div].div;
|
||||
|
||||
return DIV_ROUND_CLOSEST_ULL(parent_rate, div);
|
||||
}
|
||||
|
||||
static const struct clk_ops r9a09g077_cpg_lcdc_div_ops = {
|
||||
.recalc_rate = r9a09g077_cpg_lcdc_div_recalc_rate,
|
||||
.determine_rate = r9a09g077_cpg_lcdc_div_determine_rate,
|
||||
.set_rate = r9a09g077_cpg_lcdc_div_set_rate,
|
||||
};
|
||||
|
||||
static struct clk * __init
|
||||
r9a09g077_cpg_lcdc_div_clk_register(struct device *dev,
|
||||
const struct cpg_core_clk *core,
|
||||
void __iomem *addr,
|
||||
struct cpg_mssr_pub *pub)
|
||||
{
|
||||
struct r9a09g077_lcdc_div_clk *clk_hw_data;
|
||||
struct clk_init_data init = {};
|
||||
struct clk **clks = pub->clks;
|
||||
const struct clk *parent;
|
||||
const char *parent_name;
|
||||
struct clk_hw *hw;
|
||||
int ret;
|
||||
|
||||
parent = clks[core->parent];
|
||||
if (IS_ERR(parent))
|
||||
return ERR_CAST(parent);
|
||||
|
||||
clk_hw_data = devm_kzalloc(dev, sizeof(*clk_hw_data), GFP_KERNEL);
|
||||
if (!clk_hw_data)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
clk_hw_data->dtable = core->dtable;
|
||||
clk_hw_data->reg = addr;
|
||||
clk_hw_data->conf = core->conf;
|
||||
clk_hw_data->dev = dev;
|
||||
clk_hw_data->divider = 32; /* Initialize divider for LCDC */
|
||||
|
||||
parent_name = __clk_get_name(parent);
|
||||
init.name = core->name;
|
||||
init.ops = &r9a09g077_cpg_lcdc_div_ops;
|
||||
init.flags = core->flag;
|
||||
init.parent_names = &parent_name;
|
||||
init.num_parents = 1;
|
||||
|
||||
hw = &clk_hw_data->hw;
|
||||
hw->init = &init;
|
||||
ret = devm_clk_hw_register(dev, hw);
|
||||
if (ret)
|
||||
return ERR_PTR(ret);
|
||||
|
||||
return hw->clk;
|
||||
}
|
||||
|
||||
static struct clk * __init
|
||||
r9a09g077_cpg_clk_register(struct device *dev, const struct cpg_core_clk *core,
|
||||
const struct cpg_mssr_info *info,
|
||||
@@ -497,6 +865,11 @@ r9a09g077_cpg_clk_register(struct device *dev, const struct cpg_core_clk *core,
|
||||
return r9a09g077_cpg_mux_clk_register(dev, core, addr, pub);
|
||||
case CLK_TYPE_RZT2H_FSELXSPI:
|
||||
return r9a09g077_cpg_fselxspi_div_clk_register(dev, core, addr, pub);
|
||||
case CLK_TYPE_RZT2H_PLL3:
|
||||
return r9a09g077_cpg_pll3_clk_register(dev, core, pub->base1 + offset,
|
||||
pub, &r9a09g077_cpg_pll3_limits);
|
||||
case CLK_TYPE_RZT2H_LCDCDIV:
|
||||
return r9a09g077_cpg_lcdc_div_clk_register(dev, core, addr, pub);
|
||||
default:
|
||||
return ERR_PTR(-EINVAL);
|
||||
}
|
||||
|
||||
@@ -252,6 +252,22 @@ static void cpg_rzt2h_mstp_write(struct cpg_mssr_priv *priv, u16 offset, u32 val
|
||||
writel(value, base + RZT2H_MSTPCR_OFFSET(offset));
|
||||
}
|
||||
|
||||
static void cpg_rzt2h_mstp_delay(u32 idx, bool bit_valid)
|
||||
{
|
||||
unsigned int mask = bit_valid ? GENMASK(31, 0) : GENMASK(31, 5);
|
||||
|
||||
if (idx == (MOD_CLK_PACK(1204) & mask)) {
|
||||
/* LCDC needs 100 dummy reads, or 142us */
|
||||
udelay(142);
|
||||
} else if (idx == (MOD_CLK_PACK(605) & mask)) {
|
||||
/* RTC needs 300 dummy reads, or 428us */
|
||||
udelay(428);
|
||||
} else {
|
||||
/* default 7 dummy reads, or 10us */
|
||||
udelay(10);
|
||||
}
|
||||
}
|
||||
|
||||
static int cpg_mstp_clock_endisable(struct clk_hw *hw, bool enable)
|
||||
{
|
||||
struct mstp_clock *clock = to_mstp_clock(hw);
|
||||
@@ -311,7 +327,7 @@ static int cpg_mstp_clock_endisable(struct clk_hw *hw, bool enable)
|
||||
* register, we simply add a delay after the read operation.
|
||||
*/
|
||||
cpg_rzt2h_mstp_read(priv, priv->control_regs[reg]);
|
||||
udelay(10);
|
||||
cpg_rzt2h_mstp_delay(clock->index, true);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1141,7 +1157,7 @@ static int cpg_mssr_resume_noirq(struct device *dev)
|
||||
cpg_rzt2h_mstp_write(priv, priv->control_regs[reg], newval);
|
||||
/* See cpg_mstp_clock_endisable() on why this is necessary. */
|
||||
cpg_rzt2h_mstp_read(priv, priv->control_regs[reg]);
|
||||
udelay(10);
|
||||
cpg_rzt2h_mstp_delay(reg * 32, false);
|
||||
continue;
|
||||
} else
|
||||
writel(newval, priv->pub.base0 + priv->control_regs[reg]);
|
||||
|
||||
@@ -0,0 +1,217 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* RZV2H CPG Library. This library provides common functions to calculate
|
||||
* PLL parameters for the RZV2H SoC.
|
||||
*
|
||||
* Copyright (C) 2026 Renesas Electronics Corp.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/clk/renesas.h>
|
||||
#include <linux/export.h>
|
||||
#include <linux/math.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/units.h>
|
||||
|
||||
/**
|
||||
* rzv2h_cpg_get_pll_pars - Finds the best combination of PLL parameters
|
||||
* for a given frequency.
|
||||
*
|
||||
* @limits: Pointer to the structure containing the limits for the PLL parameters
|
||||
* @pars: Pointer to the structure where the best calculated PLL parameters values
|
||||
* will be stored
|
||||
* @freq_millihz: Target output frequency in millihertz
|
||||
*
|
||||
* This function calculates the best set of PLL parameters (M, K, P, S) to achieve
|
||||
* the desired frequency.
|
||||
* There is no direct formula to calculate the PLL parameters, as it's an open
|
||||
* system of equations, therefore this function uses an iterative approach to
|
||||
* determine the best solution. The best solution is one that minimizes the error
|
||||
* (desired frequency - actual frequency).
|
||||
*
|
||||
* Return: true if a valid set of parameters values is found, false otherwise.
|
||||
*/
|
||||
bool rzv2h_cpg_get_pll_pars(const struct rzv2h_pll_limits *limits,
|
||||
struct rzv2h_pll_pars *pars, u64 freq_millihz)
|
||||
{
|
||||
unsigned long input_fref = limits->input_fref ?: (24 * MEGA);
|
||||
u64 fout_min_millihz = mul_u32_u32(limits->fout.min, MILLI);
|
||||
u64 fout_max_millihz = mul_u32_u32(limits->fout.max, MILLI);
|
||||
struct rzv2h_pll_pars p, best;
|
||||
|
||||
if (freq_millihz > fout_max_millihz ||
|
||||
freq_millihz < fout_min_millihz)
|
||||
return false;
|
||||
|
||||
/* Initialize best error to maximum possible value */
|
||||
best.error_millihz = S64_MAX;
|
||||
|
||||
for (p.p = limits->p.min; p.p <= limits->p.max; p.p++) {
|
||||
u32 fref = input_fref / p.p;
|
||||
u16 divider;
|
||||
|
||||
for (divider = 1 << limits->s.min, p.s = limits->s.min;
|
||||
p.s <= limits->s.max; p.s++, divider <<= 1) {
|
||||
for (p.m = limits->m.min; p.m <= limits->m.max; p.m++) {
|
||||
u64 output_m, output_k_range;
|
||||
s64 pll_k, output_k;
|
||||
u64 fvco, output;
|
||||
|
||||
/*
|
||||
* The frequency generated by the PLL + divider
|
||||
* is calculated as follows:
|
||||
*
|
||||
* With:
|
||||
* Freq = Ffout = Ffvco / 2^(pll_s)
|
||||
* Ffvco = (pll_m + (pll_k / 65536)) * Ffref
|
||||
* Ffref = 24MHz / pll_p
|
||||
*
|
||||
* Freq can also be rewritten as:
|
||||
* Freq = Ffvco / 2^(pll_s)
|
||||
* = ((pll_m + (pll_k / 65536)) * Ffref) / 2^(pll_s)
|
||||
* = (pll_m * Ffref) / 2^(pll_s) + ((pll_k / 65536) * Ffref) / 2^(pll_s)
|
||||
* = output_m + output_k
|
||||
*
|
||||
* Every parameter has been determined at this
|
||||
* point, but pll_k.
|
||||
*
|
||||
* Considering that:
|
||||
* limits->k.min <= pll_k <= limits->k.max
|
||||
* Then:
|
||||
* -0.5 <= (pll_k / 65536) < 0.5
|
||||
* Therefore:
|
||||
* -Ffref / (2 * 2^(pll_s)) <= output_k < Ffref / (2 * 2^(pll_s))
|
||||
*/
|
||||
|
||||
/* Compute output M component (in mHz) */
|
||||
output_m = DIV_ROUND_CLOSEST_ULL(mul_u32_u32(p.m, fref) * MILLI,
|
||||
divider);
|
||||
/* Compute range for output K (in mHz) */
|
||||
output_k_range = DIV_ROUND_CLOSEST_ULL(mul_u32_u32(fref, MILLI),
|
||||
2 * divider);
|
||||
/*
|
||||
* No point in continuing if we can't achieve
|
||||
* the desired frequency
|
||||
*/
|
||||
if (freq_millihz < (output_m - output_k_range) ||
|
||||
freq_millihz >= (output_m + output_k_range)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
* Compute the K component
|
||||
*
|
||||
* Since:
|
||||
* Freq = output_m + output_k
|
||||
* Then:
|
||||
* output_k = Freq - output_m
|
||||
* = ((pll_k / 65536) * Ffref) / 2^(pll_s)
|
||||
* Therefore:
|
||||
* pll_k = (output_k * 65536 * 2^(pll_s)) / Ffref
|
||||
*/
|
||||
output_k = freq_millihz - output_m;
|
||||
pll_k = div_s64(output_k * 65536ULL * divider,
|
||||
fref);
|
||||
pll_k = DIV_S64_ROUND_CLOSEST(pll_k, MILLI);
|
||||
|
||||
/* Validate K value within allowed limits */
|
||||
if (pll_k < limits->k.min ||
|
||||
pll_k > limits->k.max)
|
||||
continue;
|
||||
|
||||
p.k = pll_k;
|
||||
|
||||
/* Compute (Ffvco * 65536) */
|
||||
fvco = mul_u32_u32(p.m * 65536 + p.k, fref);
|
||||
if (fvco < mul_u32_u32(limits->fvco.min, 65536) ||
|
||||
fvco > mul_u32_u32(limits->fvco.max, 65536))
|
||||
continue;
|
||||
|
||||
/* PLL_M component of (output * 65536 * PLL_P) */
|
||||
output = mul_u32_u32(p.m * 65536, input_fref);
|
||||
/* PLL_K component of (output * 65536 * PLL_P) */
|
||||
output += p.k * input_fref;
|
||||
/* Make it in mHz */
|
||||
output *= MILLI;
|
||||
output = DIV_U64_ROUND_CLOSEST(output, 65536 * p.p * divider);
|
||||
|
||||
/* Check output frequency against limits */
|
||||
if (output < fout_min_millihz ||
|
||||
output > fout_max_millihz)
|
||||
continue;
|
||||
|
||||
p.error_millihz = freq_millihz - output;
|
||||
p.freq_millihz = output;
|
||||
|
||||
/* If an exact match is found, return immediately */
|
||||
if (p.error_millihz == 0) {
|
||||
*pars = p;
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Update best match if error is smaller */
|
||||
if (abs(best.error_millihz) > abs(p.error_millihz))
|
||||
best = p;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* If no valid parameters were found, return false */
|
||||
if (best.error_millihz == S64_MAX)
|
||||
return false;
|
||||
|
||||
*pars = best;
|
||||
return true;
|
||||
}
|
||||
EXPORT_SYMBOL_NS_GPL(rzv2h_cpg_get_pll_pars, "RZV2H_CPG");
|
||||
|
||||
/*
|
||||
* rzv2h_cpg_get_pll_divs_pars - Finds the best combination of PLL parameters
|
||||
* and divider value for a given frequency.
|
||||
*
|
||||
* @limits: Pointer to the structure containing the limits for the PLL parameters
|
||||
* @pars: Pointer to the structure where the best calculated PLL parameters and
|
||||
* divider values will be stored
|
||||
* @table: Pointer to the array of valid divider values
|
||||
* @table_size: Size of the divider values array
|
||||
* @freq_millihz: Target output frequency in millihertz
|
||||
*
|
||||
* This function calculates the best set of PLL parameters (M, K, P, S) and divider
|
||||
* value to achieve the desired frequency. See rzv2h_cpg_get_pll_pars() for more
|
||||
* details on how the PLL parameters are calculated.
|
||||
*
|
||||
* freq_millihz is the desired frequency generated by the PLL followed by a
|
||||
* a gear.
|
||||
*/
|
||||
bool rzv2h_cpg_get_pll_divs_pars(const struct rzv2h_pll_limits *limits,
|
||||
struct rzv2h_pll_div_pars *pars,
|
||||
const u8 *table, u8 table_size, u64 freq_millihz)
|
||||
{
|
||||
struct rzv2h_pll_div_pars p, best;
|
||||
|
||||
best.div.error_millihz = S64_MAX;
|
||||
p.div.error_millihz = S64_MAX;
|
||||
for (unsigned int i = 0; i < table_size; i++) {
|
||||
if (!rzv2h_cpg_get_pll_pars(limits, &p.pll, freq_millihz * table[i]))
|
||||
continue;
|
||||
|
||||
p.div.divider_value = table[i];
|
||||
p.div.freq_millihz = DIV_U64_ROUND_CLOSEST(p.pll.freq_millihz, table[i]);
|
||||
p.div.error_millihz = freq_millihz - p.div.freq_millihz;
|
||||
|
||||
if (p.div.error_millihz == 0) {
|
||||
*pars = p;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (abs(best.div.error_millihz) > abs(p.div.error_millihz))
|
||||
best = p;
|
||||
}
|
||||
|
||||
if (best.div.error_millihz == S64_MAX)
|
||||
return false;
|
||||
|
||||
*pars = best;
|
||||
return true;
|
||||
}
|
||||
EXPORT_SYMBOL_NS_GPL(rzv2h_cpg_get_pll_divs_pars, "RZV2H_CPG");
|
||||
@@ -217,211 +217,8 @@ struct rzv2h_plldsi_div_clk {
|
||||
#define to_plldsi_div_clk(_hw) \
|
||||
container_of(_hw, struct rzv2h_plldsi_div_clk, hw)
|
||||
|
||||
#define RZ_V2H_OSC_CLK_IN_MEGA (24 * MEGA)
|
||||
#define RZV2H_MAX_DIV_TABLES (16)
|
||||
|
||||
/**
|
||||
* rzv2h_get_pll_pars - Finds the best combination of PLL parameters
|
||||
* for a given frequency.
|
||||
*
|
||||
* @limits: Pointer to the structure containing the limits for the PLL parameters
|
||||
* @pars: Pointer to the structure where the best calculated PLL parameters values
|
||||
* will be stored
|
||||
* @freq_millihz: Target output frequency in millihertz
|
||||
*
|
||||
* This function calculates the best set of PLL parameters (M, K, P, S) to achieve
|
||||
* the desired frequency.
|
||||
* There is no direct formula to calculate the PLL parameters, as it's an open
|
||||
* system of equations, therefore this function uses an iterative approach to
|
||||
* determine the best solution. The best solution is one that minimizes the error
|
||||
* (desired frequency - actual frequency).
|
||||
*
|
||||
* Return: true if a valid set of parameters values is found, false otherwise.
|
||||
*/
|
||||
bool rzv2h_get_pll_pars(const struct rzv2h_pll_limits *limits,
|
||||
struct rzv2h_pll_pars *pars, u64 freq_millihz)
|
||||
{
|
||||
u64 fout_min_millihz = mul_u32_u32(limits->fout.min, MILLI);
|
||||
u64 fout_max_millihz = mul_u32_u32(limits->fout.max, MILLI);
|
||||
struct rzv2h_pll_pars p, best;
|
||||
|
||||
if (freq_millihz > fout_max_millihz ||
|
||||
freq_millihz < fout_min_millihz)
|
||||
return false;
|
||||
|
||||
/* Initialize best error to maximum possible value */
|
||||
best.error_millihz = S64_MAX;
|
||||
|
||||
for (p.p = limits->p.min; p.p <= limits->p.max; p.p++) {
|
||||
u32 fref = RZ_V2H_OSC_CLK_IN_MEGA / p.p;
|
||||
u16 divider;
|
||||
|
||||
for (divider = 1 << limits->s.min, p.s = limits->s.min;
|
||||
p.s <= limits->s.max; p.s++, divider <<= 1) {
|
||||
for (p.m = limits->m.min; p.m <= limits->m.max; p.m++) {
|
||||
u64 output_m, output_k_range;
|
||||
s64 pll_k, output_k;
|
||||
u64 fvco, output;
|
||||
|
||||
/*
|
||||
* The frequency generated by the PLL + divider
|
||||
* is calculated as follows:
|
||||
*
|
||||
* With:
|
||||
* Freq = Ffout = Ffvco / 2^(pll_s)
|
||||
* Ffvco = (pll_m + (pll_k / 65536)) * Ffref
|
||||
* Ffref = 24MHz / pll_p
|
||||
*
|
||||
* Freq can also be rewritten as:
|
||||
* Freq = Ffvco / 2^(pll_s)
|
||||
* = ((pll_m + (pll_k / 65536)) * Ffref) / 2^(pll_s)
|
||||
* = (pll_m * Ffref) / 2^(pll_s) + ((pll_k / 65536) * Ffref) / 2^(pll_s)
|
||||
* = output_m + output_k
|
||||
*
|
||||
* Every parameter has been determined at this
|
||||
* point, but pll_k.
|
||||
*
|
||||
* Considering that:
|
||||
* limits->k.min <= pll_k <= limits->k.max
|
||||
* Then:
|
||||
* -0.5 <= (pll_k / 65536) < 0.5
|
||||
* Therefore:
|
||||
* -Ffref / (2 * 2^(pll_s)) <= output_k < Ffref / (2 * 2^(pll_s))
|
||||
*/
|
||||
|
||||
/* Compute output M component (in mHz) */
|
||||
output_m = DIV_ROUND_CLOSEST_ULL(mul_u32_u32(p.m, fref) * MILLI,
|
||||
divider);
|
||||
/* Compute range for output K (in mHz) */
|
||||
output_k_range = DIV_ROUND_CLOSEST_ULL(mul_u32_u32(fref, MILLI),
|
||||
2 * divider);
|
||||
/*
|
||||
* No point in continuing if we can't achieve
|
||||
* the desired frequency
|
||||
*/
|
||||
if (freq_millihz < (output_m - output_k_range) ||
|
||||
freq_millihz >= (output_m + output_k_range)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
* Compute the K component
|
||||
*
|
||||
* Since:
|
||||
* Freq = output_m + output_k
|
||||
* Then:
|
||||
* output_k = Freq - output_m
|
||||
* = ((pll_k / 65536) * Ffref) / 2^(pll_s)
|
||||
* Therefore:
|
||||
* pll_k = (output_k * 65536 * 2^(pll_s)) / Ffref
|
||||
*/
|
||||
output_k = freq_millihz - output_m;
|
||||
pll_k = div_s64(output_k * 65536ULL * divider,
|
||||
fref);
|
||||
pll_k = DIV_S64_ROUND_CLOSEST(pll_k, MILLI);
|
||||
|
||||
/* Validate K value within allowed limits */
|
||||
if (pll_k < limits->k.min ||
|
||||
pll_k > limits->k.max)
|
||||
continue;
|
||||
|
||||
p.k = pll_k;
|
||||
|
||||
/* Compute (Ffvco * 65536) */
|
||||
fvco = mul_u32_u32(p.m * 65536 + p.k, fref);
|
||||
if (fvco < mul_u32_u32(limits->fvco.min, 65536) ||
|
||||
fvco > mul_u32_u32(limits->fvco.max, 65536))
|
||||
continue;
|
||||
|
||||
/* PLL_M component of (output * 65536 * PLL_P) */
|
||||
output = mul_u32_u32(p.m * 65536, RZ_V2H_OSC_CLK_IN_MEGA);
|
||||
/* PLL_K component of (output * 65536 * PLL_P) */
|
||||
output += p.k * RZ_V2H_OSC_CLK_IN_MEGA;
|
||||
/* Make it in mHz */
|
||||
output *= MILLI;
|
||||
output = DIV_U64_ROUND_CLOSEST(output, 65536 * p.p * divider);
|
||||
|
||||
/* Check output frequency against limits */
|
||||
if (output < fout_min_millihz ||
|
||||
output > fout_max_millihz)
|
||||
continue;
|
||||
|
||||
p.error_millihz = freq_millihz - output;
|
||||
p.freq_millihz = output;
|
||||
|
||||
/* If an exact match is found, return immediately */
|
||||
if (p.error_millihz == 0) {
|
||||
*pars = p;
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Update best match if error is smaller */
|
||||
if (abs(best.error_millihz) > abs(p.error_millihz))
|
||||
best = p;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* If no valid parameters were found, return false */
|
||||
if (best.error_millihz == S64_MAX)
|
||||
return false;
|
||||
|
||||
*pars = best;
|
||||
return true;
|
||||
}
|
||||
EXPORT_SYMBOL_NS_GPL(rzv2h_get_pll_pars, "RZV2H_CPG");
|
||||
|
||||
/*
|
||||
* rzv2h_get_pll_divs_pars - Finds the best combination of PLL parameters
|
||||
* and divider value for a given frequency.
|
||||
*
|
||||
* @limits: Pointer to the structure containing the limits for the PLL parameters
|
||||
* @pars: Pointer to the structure where the best calculated PLL parameters and
|
||||
* divider values will be stored
|
||||
* @table: Pointer to the array of valid divider values
|
||||
* @table_size: Size of the divider values array
|
||||
* @freq_millihz: Target output frequency in millihertz
|
||||
*
|
||||
* This function calculates the best set of PLL parameters (M, K, P, S) and divider
|
||||
* value to achieve the desired frequency. See rzv2h_get_pll_pars() for more details
|
||||
* on how the PLL parameters are calculated.
|
||||
*
|
||||
* freq_millihz is the desired frequency generated by the PLL followed by a
|
||||
* a gear.
|
||||
*/
|
||||
bool rzv2h_get_pll_divs_pars(const struct rzv2h_pll_limits *limits,
|
||||
struct rzv2h_pll_div_pars *pars,
|
||||
const u8 *table, u8 table_size, u64 freq_millihz)
|
||||
{
|
||||
struct rzv2h_pll_div_pars p, best;
|
||||
|
||||
best.div.error_millihz = S64_MAX;
|
||||
p.div.error_millihz = S64_MAX;
|
||||
for (unsigned int i = 0; i < table_size; i++) {
|
||||
if (!rzv2h_get_pll_pars(limits, &p.pll, freq_millihz * table[i]))
|
||||
continue;
|
||||
|
||||
p.div.divider_value = table[i];
|
||||
p.div.freq_millihz = DIV_U64_ROUND_CLOSEST(p.pll.freq_millihz, table[i]);
|
||||
p.div.error_millihz = freq_millihz - p.div.freq_millihz;
|
||||
|
||||
if (p.div.error_millihz == 0) {
|
||||
*pars = p;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (abs(best.div.error_millihz) > abs(p.div.error_millihz))
|
||||
best = p;
|
||||
}
|
||||
|
||||
if (best.div.error_millihz == S64_MAX)
|
||||
return false;
|
||||
|
||||
*pars = best;
|
||||
return true;
|
||||
}
|
||||
EXPORT_SYMBOL_NS_GPL(rzv2h_get_pll_divs_pars, "RZV2H_CPG");
|
||||
|
||||
/**
|
||||
* struct rzv2h_plldsi_mux_clk - PLL DSI MUX clock
|
||||
*
|
||||
|
||||
@@ -34,5 +34,7 @@
|
||||
#define R9A09G077_XSPI_CLK0 22
|
||||
#define R9A09G077_XSPI_CLK1 23
|
||||
#define R9A09G077_PCLKCAN 24
|
||||
#define R9A09G077_LCDC_CLKD 25
|
||||
#define R9A09G077_PCLKRTC 26
|
||||
|
||||
#endif /* __DT_BINDINGS_CLOCK_RENESAS_R9A09G077_CPG_H__ */
|
||||
|
||||
@@ -34,5 +34,7 @@
|
||||
#define R9A09G087_XSPI_CLK0 22
|
||||
#define R9A09G087_XSPI_CLK1 23
|
||||
#define R9A09G087_PCLKCAN 24
|
||||
#define R9A09G087_LCDC_CLKD 25
|
||||
#define R9A09G087_PCLKRTC 26
|
||||
|
||||
#endif /* __DT_BINDINGS_CLOCK_RENESAS_R9A09G087_CPG_H__ */
|
||||
|
||||
+21
-13
@@ -53,6 +53,9 @@ static inline void rzg2l_cpg_dsi_div_set_divider(u8 divider, int target) { }
|
||||
* various parameters used to configure a PLL. These limits ensure
|
||||
* the PLL operates within valid and stable ranges.
|
||||
*
|
||||
* @input_fref: Reference input frequency to the PLL (in Hz). If set
|
||||
* to 0, a default value of 24MHz is used.
|
||||
*
|
||||
* @fout: Output frequency range (in MHz)
|
||||
* @fout.min: Minimum allowed output frequency
|
||||
* @fout.max: Maximum allowed output frequency
|
||||
@@ -78,6 +81,8 @@ static inline void rzg2l_cpg_dsi_div_set_divider(u8 divider, int target) { }
|
||||
* @k.max: Maximum delta-sigma value
|
||||
*/
|
||||
struct rzv2h_pll_limits {
|
||||
u32 input_fref;
|
||||
|
||||
struct {
|
||||
u32 min;
|
||||
u32 max;
|
||||
@@ -184,28 +189,31 @@ struct rzv2h_pll_div_pars {
|
||||
.k = { .min = -32768, .max = 32767 }, \
|
||||
} \
|
||||
|
||||
#ifdef CONFIG_CLK_RZV2H
|
||||
bool rzv2h_get_pll_pars(const struct rzv2h_pll_limits *limits,
|
||||
struct rzv2h_pll_pars *pars, u64 freq_millihz);
|
||||
#ifdef CONFIG_CLK_RZV2H_CPG_LIB
|
||||
bool rzv2h_cpg_get_pll_pars(const struct rzv2h_pll_limits *limits,
|
||||
struct rzv2h_pll_pars *pars, u64 freq_millihz);
|
||||
|
||||
bool rzv2h_get_pll_divs_pars(const struct rzv2h_pll_limits *limits,
|
||||
struct rzv2h_pll_div_pars *pars,
|
||||
const u8 *table, u8 table_size, u64 freq_millihz);
|
||||
bool rzv2h_cpg_get_pll_divs_pars(const struct rzv2h_pll_limits *limits,
|
||||
struct rzv2h_pll_div_pars *pars,
|
||||
const u8 *table, u8 table_size, u64 freq_millihz);
|
||||
#else
|
||||
static inline bool rzv2h_get_pll_pars(const struct rzv2h_pll_limits *limits,
|
||||
struct rzv2h_pll_pars *pars,
|
||||
u64 freq_millihz)
|
||||
static inline bool rzv2h_cpg_get_pll_pars(const struct rzv2h_pll_limits *limits,
|
||||
struct rzv2h_pll_pars *pars,
|
||||
u64 freq_millihz)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
static inline bool rzv2h_get_pll_divs_pars(const struct rzv2h_pll_limits *limits,
|
||||
struct rzv2h_pll_div_pars *pars,
|
||||
const u8 *table, u8 table_size,
|
||||
u64 freq_millihz)
|
||||
static inline bool rzv2h_cpg_get_pll_divs_pars(const struct rzv2h_pll_limits *limits,
|
||||
struct rzv2h_pll_div_pars *pars,
|
||||
const u8 *table, u8 table_size,
|
||||
u64 freq_millihz)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
#define rzv2h_get_pll_pars rzv2h_cpg_get_pll_pars
|
||||
#define rzv2h_get_pll_divs_pars rzv2h_cpg_get_pll_divs_pars
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user