Allwinner sunxi-ng clk driver parent relation rewrite part 1 - take 2

The first part of ongoing work to convert the sunxi-ng clk driver from
 using global clock name strings to describe clk parenting, to having
 direct struct clk_hw pointers, or local names based on clock-names from
 the device tree binding.
 
 This is based on Stephen Boyd's recent work allowing clk drivers to
 specify clk parents using struct clk_hw * or parsing DT phandles in the
 clk node.
 
 This series can be split into a few major parts:
 
 1) The first patch is a small fix for clk debugfs representation.
 
 2) A bunch of CLK_HW_INIT_* helper macros are added. These cover the
    situations I encountered, or assume I will encounter, such as single
    internal (struct clk_hw *) parent, single DT (struct clk_parent_data
    .fw_name), multiple internal parents, and multiple mixed (internal +
    DT) parents. A special variant for just an internal single parent is
    added, CLK_HW_INIT_HWS, which lets the driver share the singular
    list, instead of having the compiler create a compound literal every
    time. It might even make sense to only keep this variant.
 
 3) A bunch of CLK_FIXED_FACTOR_* helper macros are added. The rationale
    is the same as the single parent CLK_HW_INIT_* helpers.
 
 4) Bulk conversion of CLK_FIXED_FACTOR to use local parent references,
    either struct clk_hw * or DT .fw_name types, whichever the hardware
    requires.
 
 5) The beginning of SUNXI_CCU_GATE conversion to local parent
    references. This part is not done. They are included as justification
    and examples for the shared list of clk parents case.
 -----BEGIN PGP SIGNATURE-----
 
 iQJCBAABCgAsFiEE2nN1m/hhnkhOWjtHOJpUIZwPJDAFAl0NkFUOHHdlbnNAY3Np
 ZS5vcmcACgkQOJpUIZwPJDDs1A/8CxGjEgNUYTQZRfJRdOXARlfwBcejVbBt4YUV
 /BX4weCyrViT/9feOcHlalfdvleG7B3bmB7Q9s7M/UjDDL6uikoIw49idPqF5MLS
 ZK0O+rz4Ok5vsmAkn0cyeDy3W7difWA9/5ic+diLzonjl4j/isQIgiiaIUrjZ35w
 2LnFKLNPHhzfohNP8RdgvMUnZEric/4X5gx6cKUKMx5bBH2gyNaGxqYh5rq5o792
 63SpACc/sMpfhGHyY1c8SPqlL1HR6K6C5Ecp+jvc9Es7mdVeea1fF0qetNt5ZeH2
 kmvA3tWu7Dsy5yLcr/KLLdQjBfrg8dgcDC97t/Ks+u//QeKGaSqho6PskM+BwbnO
 kxSwziVcZC2ZQDjtB4VtLzcw1Td4Sph2+Q7Lt9MeDrLS3pwpimVLS6AtZZ9YIHWg
 tLh2FyxvZRhS/8h8pVb5LiJKqEx2q7e689fVuHAzmEFAiD0nHDzyDbVIjGM7Hqgd
 wp5pTi5NaZhAA416NjaZspzGXhuXubgg72zx9yaFtnrgdEHbCbmdCeAU8fubpcdr
 GAdrMG9k7Fn3Kr/bSXPTzjIlNuSQrB0Tzs6YP090DzaYSs05DbWh4KPVW5eOhjld
 vVXAb6O4467Hcn70hWoN17m2kFpWEE1C9aQbb2m7BexyXqtqsfaZqnCwP2HTLAZJ
 xBAOxqU=
 =VdZo
 -----END PGP SIGNATURE-----

Merge tag 'sunxi-ng-parent-rewrite-part-1-take-2' of https://git.kernel.org/pub/scm/linux/kernel/git/sunxi/linux into clk-allwinner

Pull Allwinner sunxi-ng clk driver parent relation rewrite part 1 - take 2
from Chen-Yu Tsai:

"The first part of ongoing work to convert the sunxi-ng clk driver from
using global clock name strings to describe clk parenting, to having
direct struct clk_hw pointers, or local names based on clock-names from
the device tree binding.

This is based on Stephen Boyd's recent work allowing clk drivers to
specify clk parents using struct clk_hw * or parsing DT phandles in the
clk node.

This series can be split into a few major parts:

1) The first patch is a small fix for clk debugfs representation.

2) A bunch of CLK_HW_INIT_* helper macros are added. These cover the
   situations I encountered, or assume I will encounter, such as single
   internal (struct clk_hw *) parent, single DT (struct clk_parent_data
   .fw_name), multiple internal parents, and multiple mixed (internal +
   DT) parents. A special variant for just an internal single parent is
   added, CLK_HW_INIT_HWS, which lets the driver share the singular
   list, instead of having the compiler create a compound literal every
   time. It might even make sense to only keep this variant.

3) A bunch of CLK_FIXED_FACTOR_* helper macros are added. The rationale
   is the same as the single parent CLK_HW_INIT_* helpers.

4) Bulk conversion of CLK_FIXED_FACTOR to use local parent references,
   either struct clk_hw * or DT .fw_name types, whichever the hardware
   requires.

5) The beginning of SUNXI_CCU_GATE conversion to local parent
   references. This part is not done. They are included as justification
   and examples for the shared list of clk parents case."

* tag 'sunxi-ng-parent-rewrite-part-1-take-2' of https://git.kernel.org/pub/scm/linux/kernel/git/sunxi/linux: (25 commits)
  clk: sunxi-ng: sun8i-r: Use local parent references for SUNXI_CCU_GATE
  clk: sunxi-ng: a80-usb: Use local parent references for SUNXI_CCU_GATE
  clk: sunxi-ng: gate: Add macros for referencing local clock parents
  clk: sunxi-ng: h6-r: Use local parent references for CLK_FIXED_FACTOR
  clk: sunxi-ng: h6: Use local parent references for CLK_FIXED_FACTOR
  clk: sunxi-ng: a64: Use local parent references for CLK_FIXED_FACTOR
  clk: sunxi-ng: f1c100s: Use local parent references for CLK_FIXED_FACTOR
  clk: sunxi-ng: sun8i-r: Use local parent references for CLK_FIXED_FACTOR
  clk: sunxi-ng: v3s: Use local parent references for CLK_FIXED_FACTOR
  clk: sunxi-ng: r40: Use local parent references for CLK_FIXED_FACTOR
  clk: sunxi-ng: h3: Use local parent references for CLK_FIXED_FACTOR
  clk: sunxi-ng: a33: Use local parent references for CLK_FIXED_FACTOR
  clk: sunxi-ng: a23: Use local parent references for CLK_FIXED_FACTOR
  clk: sunxi-ng: a31: Use local parent references for CLK_FIXED_FACTOR
  clk: sunxi-ng: sun5i: Use local parent references for CLK_FIXED_FACTOR
  clk: sunxi-ng: a10: Use local parent references for CLK_FIXED_FACTOR
  clk: sunxi-ng: sun8i-r: Use local parent references for CLK_HW_INIT_*
  clk: sunxi-ng: switch to of_clk_hw_register() for registering clks
  clk: fixed-factor: Add CLK_FIXED_FACTOR_FW_NAME for DT clock-names parent
  clk: fixed-factor: Add CLK_FIXED_FACTOR_HWS which takes list of struct clk_hw *
  ...
This commit is contained in:
Stephen Boyd 2019-06-24 18:28:31 -07:00
Родитель b2f874d27b 89f27fb2dd
Коммит f925a054f0
18 изменённых файлов: 522 добавлений и 219 удалений

Просмотреть файл

@ -3000,12 +3000,50 @@ DEFINE_SHOW_ATTRIBUTE(clk_flags);
static int possible_parents_show(struct seq_file *s, void *data) static int possible_parents_show(struct seq_file *s, void *data)
{ {
struct clk_core *core = s->private; struct clk_core *core = s->private;
struct clk_core *parent;
int i; int i;
for (i = 0; i < core->num_parents - 1; i++) /*
seq_printf(s, "%s ", core->parents[i].name); * Go through the following options to fetch a parent's name.
*
* 1. Fetch the registered parent clock and use its name
* 2. Use the global (fallback) name if specified
* 3. Use the local fw_name if provided
* 4. Fetch parent clock's clock-output-name if DT index was set
*
* This may still fail in some cases, such as when the parent is
* specified directly via a struct clk_hw pointer, but it isn't
* registered (yet).
*/
for (i = 0; i < core->num_parents - 1; i++) {
parent = clk_core_get_parent_by_index(core, i);
if (parent)
seq_printf(s, "%s ", parent->name);
else if (core->parents[i].name)
seq_printf(s, "%s ", core->parents[i].name);
else if (core->parents[i].fw_name)
seq_printf(s, "<%s>(fw) ", core->parents[i].fw_name);
else if (core->parents[i].index >= 0)
seq_printf(s, "%s ",
of_clk_get_parent_name(core->of_node,
core->parents[i].index));
else
seq_puts(s, "(missing) ");
}
seq_printf(s, "%s\n", core->parents[i].name); parent = clk_core_get_parent_by_index(core, i);
if (parent)
seq_printf(s, "%s", parent->name);
else if (core->parents[i].name)
seq_printf(s, "%s", core->parents[i].name);
else if (core->parents[i].fw_name)
seq_printf(s, "<%s>(fw)", core->parents[i].fw_name);
else if (core->parents[i].index >= 0)
seq_printf(s, "%s",
of_clk_get_parent_name(core->of_node,
core->parents[i].index));
else
seq_puts(s, "(missing)");
return 0; return 0;
} }

Просмотреть файл

@ -168,8 +168,9 @@ static struct ccu_nk pll_periph_base_clk = {
}, },
}; };
static CLK_FIXED_FACTOR(pll_periph_clk, "pll-periph", "pll-periph-base", static CLK_FIXED_FACTOR_HW(pll_periph_clk, "pll-periph",
2, 1, CLK_SET_RATE_PARENT); &pll_periph_base_clk.common.hw,
2, 1, CLK_SET_RATE_PARENT);
/* Not documented on A10 */ /* Not documented on A10 */
static struct ccu_div pll_periph_sata_clk = { static struct ccu_div pll_periph_sata_clk = {
@ -1036,19 +1037,29 @@ static struct ccu_common *sun4i_sun7i_ccu_clks[] = {
&out_b_clk.common &out_b_clk.common
}; };
static const struct clk_hw *clk_parent_pll_audio[] = {
&pll_audio_base_clk.common.hw
};
/* Post-divider for pll-audio is hardcoded to 1 */ /* Post-divider for pll-audio is hardcoded to 1 */
static CLK_FIXED_FACTOR(pll_audio_clk, "pll-audio", static CLK_FIXED_FACTOR_HWS(pll_audio_clk, "pll-audio",
"pll-audio-base", 1, 1, CLK_SET_RATE_PARENT); clk_parent_pll_audio,
static CLK_FIXED_FACTOR(pll_audio_2x_clk, "pll-audio-2x", 1, 1, CLK_SET_RATE_PARENT);
"pll-audio-base", 2, 1, CLK_SET_RATE_PARENT); static CLK_FIXED_FACTOR_HWS(pll_audio_2x_clk, "pll-audio-2x",
static CLK_FIXED_FACTOR(pll_audio_4x_clk, "pll-audio-4x", clk_parent_pll_audio,
"pll-audio-base", 1, 1, CLK_SET_RATE_PARENT); 2, 1, CLK_SET_RATE_PARENT);
static CLK_FIXED_FACTOR(pll_audio_8x_clk, "pll-audio-8x", static CLK_FIXED_FACTOR_HWS(pll_audio_4x_clk, "pll-audio-4x",
"pll-audio-base", 1, 2, CLK_SET_RATE_PARENT); clk_parent_pll_audio,
static CLK_FIXED_FACTOR(pll_video0_2x_clk, "pll-video0-2x", 1, 1, CLK_SET_RATE_PARENT);
"pll-video0", 1, 2, CLK_SET_RATE_PARENT); static CLK_FIXED_FACTOR_HWS(pll_audio_8x_clk, "pll-audio-8x",
static CLK_FIXED_FACTOR(pll_video1_2x_clk, "pll-video1-2x", clk_parent_pll_audio,
"pll-video1", 1, 2, CLK_SET_RATE_PARENT); 1, 2, CLK_SET_RATE_PARENT);
static CLK_FIXED_FACTOR_HW(pll_video0_2x_clk, "pll-video0-2x",
&pll_video0_clk.common.hw,
1, 2, CLK_SET_RATE_PARENT);
static CLK_FIXED_FACTOR_HW(pll_video1_2x_clk, "pll-video1-2x",
&pll_video1_clk.common.hw,
1, 2, CLK_SET_RATE_PARENT);
static struct clk_hw_onecell_data sun4i_a10_hw_clks = { static struct clk_hw_onecell_data sun4i_a10_hw_clks = {

Просмотреть файл

@ -605,23 +605,34 @@ static SUNXI_CCU_M_WITH_GATE(gpu_clk, "gpu", "pll-gpu",
0x1a0, 0, 3, BIT(31), CLK_SET_RATE_PARENT); 0x1a0, 0, 3, BIT(31), CLK_SET_RATE_PARENT);
/* Fixed Factor clocks */ /* Fixed Factor clocks */
static CLK_FIXED_FACTOR(osc12M_clk, "osc12M", "osc24M", 2, 1, 0); static CLK_FIXED_FACTOR_FW_NAME(osc12M_clk, "osc12M", "hosc", 2, 1, 0);
static const struct clk_hw *clk_parent_pll_audio[] = {
&pll_audio_base_clk.common.hw
};
/* We hardcode the divider to 1 for now */ /* We hardcode the divider to 1 for now */
static CLK_FIXED_FACTOR(pll_audio_clk, "pll-audio", static CLK_FIXED_FACTOR_HWS(pll_audio_clk, "pll-audio",
"pll-audio-base", 1, 1, CLK_SET_RATE_PARENT); clk_parent_pll_audio,
static CLK_FIXED_FACTOR(pll_audio_2x_clk, "pll-audio-2x", 1, 1, CLK_SET_RATE_PARENT);
"pll-audio-base", 2, 1, CLK_SET_RATE_PARENT); static CLK_FIXED_FACTOR_HWS(pll_audio_2x_clk, "pll-audio-2x",
static CLK_FIXED_FACTOR(pll_audio_4x_clk, "pll-audio-4x", clk_parent_pll_audio,
"pll-audio-base", 1, 1, CLK_SET_RATE_PARENT); 2, 1, CLK_SET_RATE_PARENT);
static CLK_FIXED_FACTOR(pll_audio_8x_clk, "pll-audio-8x", static CLK_FIXED_FACTOR_HWS(pll_audio_4x_clk, "pll-audio-4x",
"pll-audio-base", 1, 2, CLK_SET_RATE_PARENT); clk_parent_pll_audio,
static CLK_FIXED_FACTOR(pll_periph0_2x_clk, "pll-periph0-2x", 1, 1, CLK_SET_RATE_PARENT);
"pll-periph0", 1, 2, 0); static CLK_FIXED_FACTOR_HWS(pll_audio_8x_clk, "pll-audio-8x",
static CLK_FIXED_FACTOR(pll_periph1_2x_clk, "pll-periph1-2x", clk_parent_pll_audio,
"pll-periph1", 1, 2, 0); 1, 2, CLK_SET_RATE_PARENT);
static CLK_FIXED_FACTOR(pll_video0_2x_clk, "pll-video0-2x", static CLK_FIXED_FACTOR_HW(pll_periph0_2x_clk, "pll-periph0-2x",
"pll-video0", 1, 2, CLK_SET_RATE_PARENT); &pll_periph0_clk.common.hw,
1, 2, 0);
static CLK_FIXED_FACTOR_HW(pll_periph1_2x_clk, "pll-periph1-2x",
&pll_periph1_clk.common.hw,
1, 2, 0);
static CLK_FIXED_FACTOR_HW(pll_video0_2x_clk, "pll-video0-2x",
&pll_video0_clk.common.hw,
1, 2, CLK_SET_RATE_PARENT);
static struct ccu_common *sun50i_a64_ccu_clks[] = { static struct ccu_common *sun50i_a64_ccu_clks[] = {
&pll_cpux_clk.common, &pll_cpux_clk.common,

Просмотреть файл

@ -49,7 +49,7 @@ static struct ccu_div ar100_clk = {
}, },
}; };
static CLK_FIXED_FACTOR(r_ahb_clk, "r-ahb", "ar100", 1, 1, 0); static CLK_FIXED_FACTOR_HW(r_ahb_clk, "r-ahb", &ar100_clk.common.hw, 1, 1, 0);
static struct ccu_div r_apb1_clk = { static struct ccu_div r_apb1_clk = {
.div = _SUNXI_CCU_DIV(0, 2), .div = _SUNXI_CCU_DIV(0, 2),

Просмотреть файл

@ -622,8 +622,9 @@ static SUNXI_CCU_GATE(bus_xhci_clk, "bus-xhci", "ahb3", 0xa8c, BIT(5), 0);
static SUNXI_CCU_GATE(bus_ehci3_clk, "bus-ehci3", "ahb3", 0xa8c, BIT(7), 0); static SUNXI_CCU_GATE(bus_ehci3_clk, "bus-ehci3", "ahb3", 0xa8c, BIT(7), 0);
static SUNXI_CCU_GATE(bus_otg_clk, "bus-otg", "ahb3", 0xa8c, BIT(8), 0); static SUNXI_CCU_GATE(bus_otg_clk, "bus-otg", "ahb3", 0xa8c, BIT(8), 0);
static CLK_FIXED_FACTOR(pcie_ref_100m_clk, "pcie-ref-100M", static struct clk_fixed_factor pll_periph0_4x_clk;
"pll-periph0-4x", 24, 1, 0); static CLK_FIXED_FACTOR_HW(pcie_ref_100m_clk, "pcie-ref-100M",
&pll_periph0_4x_clk.hw, 24, 1, 0);
static SUNXI_CCU_GATE(pcie_ref_clk, "pcie-ref", "pcie-ref-100M", static SUNXI_CCU_GATE(pcie_ref_clk, "pcie-ref", "pcie-ref-100M",
0xab0, BIT(31), 0); 0xab0, BIT(31), 0);
static SUNXI_CCU_GATE(pcie_ref_out_clk, "pcie-ref-out", "pcie-ref", static SUNXI_CCU_GATE(pcie_ref_out_clk, "pcie-ref-out", "pcie-ref",
@ -745,34 +746,52 @@ static SUNXI_CCU_M_WITH_MUX_GATE(hdcp_clk, "hdcp", hdcp_parents, 0xc40,
static SUNXI_CCU_GATE(bus_hdcp_clk, "bus-hdcp", "ahb3", 0xc4c, BIT(0), 0); static SUNXI_CCU_GATE(bus_hdcp_clk, "bus-hdcp", "ahb3", 0xc4c, BIT(0), 0);
/* Fixed factor clocks */ /* Fixed factor clocks */
static CLK_FIXED_FACTOR(osc12M_clk, "osc12M", "osc24M", 2, 1, 0); static CLK_FIXED_FACTOR_FW_NAME(osc12M_clk, "osc12M", "hosc", 2, 1, 0);
static const struct clk_hw *clk_parent_pll_audio[] = {
&pll_audio_base_clk.common.hw
};
/* /*
* The divider of pll-audio is fixed to 8 now, as pll-audio-4x has a * The divider of pll-audio is fixed to 8 now, as pll-audio-4x has a
* fixed post-divider 2. * fixed post-divider 2.
*/ */
static CLK_FIXED_FACTOR(pll_audio_clk, "pll-audio", static CLK_FIXED_FACTOR_HWS(pll_audio_clk, "pll-audio",
"pll-audio-base", 8, 1, CLK_SET_RATE_PARENT); clk_parent_pll_audio,
static CLK_FIXED_FACTOR(pll_audio_2x_clk, "pll-audio-2x", 8, 1, CLK_SET_RATE_PARENT);
"pll-audio-base", 4, 1, CLK_SET_RATE_PARENT); static CLK_FIXED_FACTOR_HWS(pll_audio_2x_clk, "pll-audio-2x",
static CLK_FIXED_FACTOR(pll_audio_4x_clk, "pll-audio-4x", clk_parent_pll_audio,
"pll-audio-base", 2, 1, CLK_SET_RATE_PARENT); 4, 1, CLK_SET_RATE_PARENT);
static CLK_FIXED_FACTOR_HWS(pll_audio_4x_clk, "pll-audio-4x",
clk_parent_pll_audio,
2, 1, CLK_SET_RATE_PARENT);
static CLK_FIXED_FACTOR(pll_periph0_4x_clk, "pll-periph0-4x", static const struct clk_hw *pll_periph0_parents[] = {
"pll-periph0", 1, 4, 0); &pll_periph0_clk.common.hw
static CLK_FIXED_FACTOR(pll_periph0_2x_clk, "pll-periph0-2x", };
"pll-periph0", 1, 2, 0); static CLK_FIXED_FACTOR_HWS(pll_periph0_4x_clk, "pll-periph0-4x",
pll_periph0_parents,
1, 4, 0);
static CLK_FIXED_FACTOR_HWS(pll_periph0_2x_clk, "pll-periph0-2x",
pll_periph0_parents,
1, 2, 0);
static CLK_FIXED_FACTOR(pll_periph1_4x_clk, "pll-periph1-4x", static const struct clk_hw *pll_periph1_parents[] = {
"pll-periph1", 1, 4, 0); &pll_periph1_clk.common.hw
static CLK_FIXED_FACTOR(pll_periph1_2x_clk, "pll-periph1-2x", };
"pll-periph1", 1, 2, 0); static CLK_FIXED_FACTOR_HWS(pll_periph1_4x_clk, "pll-periph1-4x",
pll_periph1_parents,
1, 4, 0);
static CLK_FIXED_FACTOR_HWS(pll_periph1_2x_clk, "pll-periph1-2x",
pll_periph1_parents,
1, 2, 0);
static CLK_FIXED_FACTOR(pll_video0_4x_clk, "pll-video0-4x", static CLK_FIXED_FACTOR_HW(pll_video0_4x_clk, "pll-video0-4x",
"pll-video0", 1, 4, CLK_SET_RATE_PARENT); &pll_video0_clk.common.hw,
1, 4, CLK_SET_RATE_PARENT);
static CLK_FIXED_FACTOR(pll_video1_4x_clk, "pll-video1-4x", static CLK_FIXED_FACTOR_HW(pll_video1_4x_clk, "pll-video1-4x",
"pll-video1", 1, 4, CLK_SET_RATE_PARENT); &pll_video1_clk.common.hw,
1, 4, CLK_SET_RATE_PARENT);
static struct ccu_common *sun50i_h6_ccu_clks[] = { static struct ccu_common *sun50i_h6_ccu_clks[] = {
&pll_cpux_clk.common, &pll_cpux_clk.common,

Просмотреть файл

@ -611,19 +611,29 @@ static struct ccu_common *sun5i_a10s_ccu_clks[] = {
&iep_clk.common, &iep_clk.common,
}; };
static const struct clk_hw *clk_parent_pll_audio[] = {
&pll_audio_base_clk.common.hw
};
/* We hardcode the divider to 1 for now */ /* We hardcode the divider to 1 for now */
static CLK_FIXED_FACTOR(pll_audio_clk, "pll-audio", static CLK_FIXED_FACTOR_HWS(pll_audio_clk, "pll-audio",
"pll-audio-base", 1, 1, CLK_SET_RATE_PARENT); clk_parent_pll_audio,
static CLK_FIXED_FACTOR(pll_audio_2x_clk, "pll-audio-2x", 1, 1, CLK_SET_RATE_PARENT);
"pll-audio-base", 2, 1, CLK_SET_RATE_PARENT); static CLK_FIXED_FACTOR_HWS(pll_audio_2x_clk, "pll-audio-2x",
static CLK_FIXED_FACTOR(pll_audio_4x_clk, "pll-audio-4x", clk_parent_pll_audio,
"pll-audio-base", 1, 1, CLK_SET_RATE_PARENT); 2, 1, CLK_SET_RATE_PARENT);
static CLK_FIXED_FACTOR(pll_audio_8x_clk, "pll-audio-8x", static CLK_FIXED_FACTOR_HWS(pll_audio_4x_clk, "pll-audio-4x",
"pll-audio-base", 1, 2, CLK_SET_RATE_PARENT); clk_parent_pll_audio,
static CLK_FIXED_FACTOR(pll_video0_2x_clk, "pll-video0-2x", 1, 1, CLK_SET_RATE_PARENT);
"pll-video0", 1, 2, CLK_SET_RATE_PARENT); static CLK_FIXED_FACTOR_HWS(pll_audio_8x_clk, "pll-audio-8x",
static CLK_FIXED_FACTOR(pll_video1_2x_clk, "pll-video1-2x", clk_parent_pll_audio,
"pll-video1", 1, 2, CLK_SET_RATE_PARENT); 1, 2, CLK_SET_RATE_PARENT);
static CLK_FIXED_FACTOR_HW(pll_video0_2x_clk, "pll-video0-2x",
&pll_video0_clk.common.hw,
1, 2, CLK_SET_RATE_PARENT);
static CLK_FIXED_FACTOR_HW(pll_video1_2x_clk, "pll-video1-2x",
&pll_video1_clk.common.hw,
1, 2, CLK_SET_RATE_PARENT);
static struct clk_hw_onecell_data sun5i_a10s_hw_clks = { static struct clk_hw_onecell_data sun5i_a10s_hw_clks = {
.hws = { .hws = {

Просмотреть файл

@ -963,21 +963,32 @@ static struct ccu_common *sun6i_a31_ccu_clks[] = {
&out_c_clk.common, &out_c_clk.common,
}; };
static const struct clk_hw *clk_parent_pll_audio[] = {
&pll_audio_base_clk.common.hw
};
/* We hardcode the divider to 1 for now */ /* We hardcode the divider to 1 for now */
static CLK_FIXED_FACTOR(pll_audio_clk, "pll-audio", static CLK_FIXED_FACTOR_HWS(pll_audio_clk, "pll-audio",
"pll-audio-base", 1, 1, CLK_SET_RATE_PARENT); clk_parent_pll_audio,
static CLK_FIXED_FACTOR(pll_audio_2x_clk, "pll-audio-2x", 1, 1, CLK_SET_RATE_PARENT);
"pll-audio-base", 2, 1, CLK_SET_RATE_PARENT); static CLK_FIXED_FACTOR_HWS(pll_audio_2x_clk, "pll-audio-2x",
static CLK_FIXED_FACTOR(pll_audio_4x_clk, "pll-audio-4x", clk_parent_pll_audio,
"pll-audio-base", 1, 1, CLK_SET_RATE_PARENT); 2, 1, CLK_SET_RATE_PARENT);
static CLK_FIXED_FACTOR(pll_audio_8x_clk, "pll-audio-8x", static CLK_FIXED_FACTOR_HWS(pll_audio_4x_clk, "pll-audio-4x",
"pll-audio-base", 1, 2, CLK_SET_RATE_PARENT); clk_parent_pll_audio,
static CLK_FIXED_FACTOR(pll_periph_2x_clk, "pll-periph-2x", 1, 1, CLK_SET_RATE_PARENT);
"pll-periph", 1, 2, 0); static CLK_FIXED_FACTOR_HWS(pll_audio_8x_clk, "pll-audio-8x",
static CLK_FIXED_FACTOR(pll_video0_2x_clk, "pll-video0-2x", clk_parent_pll_audio,
"pll-video0", 1, 2, CLK_SET_RATE_PARENT); 1, 2, CLK_SET_RATE_PARENT);
static CLK_FIXED_FACTOR(pll_video1_2x_clk, "pll-video1-2x", static CLK_FIXED_FACTOR_HW(pll_periph_2x_clk, "pll-periph-2x",
"pll-video1", 1, 2, CLK_SET_RATE_PARENT); &pll_periph_clk.common.hw,
1, 2, 0);
static CLK_FIXED_FACTOR_HW(pll_video0_2x_clk, "pll-video0-2x",
&pll_video0_clk.common.hw,
1, 2, CLK_SET_RATE_PARENT);
static CLK_FIXED_FACTOR_HW(pll_video1_2x_clk, "pll-video1-2x",
&pll_video1_clk.common.hw,
1, 2, CLK_SET_RATE_PARENT);
static struct clk_hw_onecell_data sun6i_a31_hw_clks = { static struct clk_hw_onecell_data sun6i_a31_hw_clks = {
.hws = { .hws = {

Просмотреть файл

@ -551,19 +551,29 @@ static struct ccu_common *sun8i_a23_ccu_clks[] = {
&ats_clk.common, &ats_clk.common,
}; };
static const struct clk_hw *clk_parent_pll_audio[] = {
&pll_audio_base_clk.common.hw
};
/* We hardcode the divider to 1 for now */ /* We hardcode the divider to 1 for now */
static CLK_FIXED_FACTOR(pll_audio_clk, "pll-audio", static CLK_FIXED_FACTOR_HWS(pll_audio_clk, "pll-audio",
"pll-audio-base", 1, 1, CLK_SET_RATE_PARENT); clk_parent_pll_audio,
static CLK_FIXED_FACTOR(pll_audio_2x_clk, "pll-audio-2x", 1, 1, CLK_SET_RATE_PARENT);
"pll-audio-base", 2, 1, CLK_SET_RATE_PARENT); static CLK_FIXED_FACTOR_HWS(pll_audio_2x_clk, "pll-audio-2x",
static CLK_FIXED_FACTOR(pll_audio_4x_clk, "pll-audio-4x", clk_parent_pll_audio,
"pll-audio-base", 1, 1, CLK_SET_RATE_PARENT); 2, 1, CLK_SET_RATE_PARENT);
static CLK_FIXED_FACTOR(pll_audio_8x_clk, "pll-audio-8x", static CLK_FIXED_FACTOR_HWS(pll_audio_4x_clk, "pll-audio-4x",
"pll-audio-base", 1, 2, CLK_SET_RATE_PARENT); clk_parent_pll_audio,
static CLK_FIXED_FACTOR(pll_periph_2x_clk, "pll-periph-2x", 1, 1, CLK_SET_RATE_PARENT);
"pll-periph", 1, 2, 0); static CLK_FIXED_FACTOR_HWS(pll_audio_8x_clk, "pll-audio-8x",
static CLK_FIXED_FACTOR(pll_video_2x_clk, "pll-video-2x", clk_parent_pll_audio,
"pll-video", 1, 2, 0); 1, 2, CLK_SET_RATE_PARENT);
static CLK_FIXED_FACTOR_HW(pll_periph_2x_clk, "pll-periph-2x",
&pll_periph_clk.common.hw,
1, 2, 0);
static CLK_FIXED_FACTOR_HW(pll_video_2x_clk, "pll-video-2x",
&pll_video_clk.common.hw,
1, 2, 0);
static struct clk_hw_onecell_data sun8i_a23_hw_clks = { static struct clk_hw_onecell_data sun8i_a23_hw_clks = {
.hws = { .hws = {

Просмотреть файл

@ -588,19 +588,29 @@ static struct ccu_common *sun8i_a33_ccu_clks[] = {
&ats_clk.common, &ats_clk.common,
}; };
static const struct clk_hw *clk_parent_pll_audio[] = {
&pll_audio_base_clk.common.hw
};
/* We hardcode the divider to 1 for now */ /* We hardcode the divider to 1 for now */
static CLK_FIXED_FACTOR(pll_audio_clk, "pll-audio", static CLK_FIXED_FACTOR_HWS(pll_audio_clk, "pll-audio",
"pll-audio-base", 1, 1, CLK_SET_RATE_PARENT); clk_parent_pll_audio,
static CLK_FIXED_FACTOR(pll_audio_2x_clk, "pll-audio-2x", 1, 1, CLK_SET_RATE_PARENT);
"pll-audio-base", 2, 1, CLK_SET_RATE_PARENT); static CLK_FIXED_FACTOR_HWS(pll_audio_2x_clk, "pll-audio-2x",
static CLK_FIXED_FACTOR(pll_audio_4x_clk, "pll-audio-4x", clk_parent_pll_audio,
"pll-audio-base", 1, 1, CLK_SET_RATE_PARENT); 2, 1, CLK_SET_RATE_PARENT);
static CLK_FIXED_FACTOR(pll_audio_8x_clk, "pll-audio-8x", static CLK_FIXED_FACTOR_HWS(pll_audio_4x_clk, "pll-audio-4x",
"pll-audio-base", 1, 2, CLK_SET_RATE_PARENT); clk_parent_pll_audio,
static CLK_FIXED_FACTOR(pll_periph_2x_clk, "pll-periph-2x", 1, 1, CLK_SET_RATE_PARENT);
"pll-periph", 1, 2, 0); static CLK_FIXED_FACTOR_HWS(pll_audio_8x_clk, "pll-audio-8x",
static CLK_FIXED_FACTOR(pll_video_2x_clk, "pll-video-2x", clk_parent_pll_audio,
"pll-video", 1, 2, 0); 1, 2, CLK_SET_RATE_PARENT);
static CLK_FIXED_FACTOR_HW(pll_periph_2x_clk, "pll-periph-2x",
&pll_periph_clk.common.hw,
1, 2, 0);
static CLK_FIXED_FACTOR_HW(pll_video_2x_clk, "pll-video-2x",
&pll_video_clk.common.hw,
1, 2, 0);
static struct clk_hw_onecell_data sun8i_a33_hw_clks = { static struct clk_hw_onecell_data sun8i_a33_hw_clks = {
.hws = { .hws = {

Просмотреть файл

@ -725,17 +725,26 @@ static struct ccu_common *sun50i_h5_ccu_clks[] = {
&gpu_clk.common, &gpu_clk.common,
}; };
static const struct clk_hw *clk_parent_pll_audio[] = {
&pll_audio_base_clk.common.hw
};
/* We hardcode the divider to 1 for now */ /* We hardcode the divider to 1 for now */
static CLK_FIXED_FACTOR(pll_audio_clk, "pll-audio", static CLK_FIXED_FACTOR_HWS(pll_audio_clk, "pll-audio",
"pll-audio-base", 1, 1, CLK_SET_RATE_PARENT); clk_parent_pll_audio,
static CLK_FIXED_FACTOR(pll_audio_2x_clk, "pll-audio-2x", 1, 1, CLK_SET_RATE_PARENT);
"pll-audio-base", 2, 1, CLK_SET_RATE_PARENT); static CLK_FIXED_FACTOR_HWS(pll_audio_2x_clk, "pll-audio-2x",
static CLK_FIXED_FACTOR(pll_audio_4x_clk, "pll-audio-4x", clk_parent_pll_audio,
"pll-audio-base", 1, 1, CLK_SET_RATE_PARENT); 2, 1, CLK_SET_RATE_PARENT);
static CLK_FIXED_FACTOR(pll_audio_8x_clk, "pll-audio-8x", static CLK_FIXED_FACTOR_HWS(pll_audio_4x_clk, "pll-audio-4x",
"pll-audio-base", 1, 2, CLK_SET_RATE_PARENT); clk_parent_pll_audio,
static CLK_FIXED_FACTOR(pll_periph0_2x_clk, "pll-periph0-2x", 1, 1, CLK_SET_RATE_PARENT);
"pll-periph0", 1, 2, 0); static CLK_FIXED_FACTOR_HWS(pll_audio_8x_clk, "pll-audio-8x",
clk_parent_pll_audio,
1, 2, CLK_SET_RATE_PARENT);
static CLK_FIXED_FACTOR_HW(pll_periph0_2x_clk, "pll-periph0-2x",
&pll_periph0_clk.common.hw,
1, 2, 0);
static struct clk_hw_onecell_data sun8i_h3_hw_clks = { static struct clk_hw_onecell_data sun8i_h3_hw_clks = {
.hws = { .hws = {

Просмотреть файл

@ -25,10 +25,13 @@
#include "ccu-sun8i-r.h" #include "ccu-sun8i-r.h"
static const char * const ar100_parents[] = { "osc32k", "osc24M", static const struct clk_parent_data ar100_parents[] = {
"pll-periph0", "iosc" }; { .fw_name = "losc" },
static const char * const a83t_ar100_parents[] = { "osc16M-d512", "osc24M", { .fw_name = "hosc" },
"pll-periph0", "iosc" }; { .fw_name = "pll-periph" },
{ .fw_name = "iosc" },
};
static const struct ccu_mux_var_prediv ar100_predivs[] = { static const struct ccu_mux_var_prediv ar100_predivs[] = {
{ .index = 2, .shift = 8, .width = 5 }, { .index = 2, .shift = 8, .width = 5 },
}; };
@ -47,64 +50,49 @@ static struct ccu_div ar100_clk = {
.common = { .common = {
.reg = 0x00, .reg = 0x00,
.features = CCU_FEATURE_VARIABLE_PREDIV, .features = CCU_FEATURE_VARIABLE_PREDIV,
.hw.init = CLK_HW_INIT_PARENTS("ar100", .hw.init = CLK_HW_INIT_PARENTS_DATA("ar100",
ar100_parents, ar100_parents,
&ccu_div_ops, &ccu_div_ops,
0), 0),
}, },
}; };
static struct ccu_div a83t_ar100_clk = { static CLK_FIXED_FACTOR_HW(ahb0_clk, "ahb0", &ar100_clk.common.hw, 1, 1, 0);
.div = _SUNXI_CCU_DIV_FLAGS(4, 2, CLK_DIVIDER_POWER_OF_TWO),
.mux = {
.shift = 16,
.width = 2,
.var_predivs = ar100_predivs,
.n_var_predivs = ARRAY_SIZE(ar100_predivs),
},
.common = {
.reg = 0x00,
.features = CCU_FEATURE_VARIABLE_PREDIV,
.hw.init = CLK_HW_INIT_PARENTS("ar100",
a83t_ar100_parents,
&ccu_div_ops,
0),
},
};
static CLK_FIXED_FACTOR(ahb0_clk, "ahb0", "ar100", 1, 1, 0);
static struct ccu_div apb0_clk = { static struct ccu_div apb0_clk = {
.div = _SUNXI_CCU_DIV_FLAGS(0, 2, CLK_DIVIDER_POWER_OF_TWO), .div = _SUNXI_CCU_DIV_FLAGS(0, 2, CLK_DIVIDER_POWER_OF_TWO),
.common = { .common = {
.reg = 0x0c, .reg = 0x0c,
.hw.init = CLK_HW_INIT("apb0", .hw.init = CLK_HW_INIT_HW("apb0",
"ahb0", &ahb0_clk.hw,
&ccu_div_ops, &ccu_div_ops,
0), 0),
}, },
}; };
static SUNXI_CCU_M(a83t_apb0_clk, "apb0", "ahb0", 0x0c, 0, 2, 0); static SUNXI_CCU_M(a83t_apb0_clk, "apb0", "ahb0", 0x0c, 0, 2, 0);
static SUNXI_CCU_GATE(apb0_pio_clk, "apb0-pio", "apb0", /*
0x28, BIT(0), 0); * Define the parent as an array that can be reused to save space
static SUNXI_CCU_GATE(apb0_ir_clk, "apb0-ir", "apb0", * instead of having compound literals for each gate. Also have it
0x28, BIT(1), 0); * non-const so we can change it on the A83T.
static SUNXI_CCU_GATE(apb0_timer_clk, "apb0-timer", "apb0", */
0x28, BIT(2), 0); static const struct clk_hw *apb0_gate_parent[] = { &apb0_clk.common.hw };
static SUNXI_CCU_GATE(apb0_rsb_clk, "apb0-rsb", "apb0", static SUNXI_CCU_GATE_HWS(apb0_pio_clk, "apb0-pio",
0x28, BIT(3), 0); apb0_gate_parent, 0x28, BIT(0), 0);
static SUNXI_CCU_GATE(apb0_uart_clk, "apb0-uart", "apb0", static SUNXI_CCU_GATE_HWS(apb0_ir_clk, "apb0-ir",
0x28, BIT(4), 0); apb0_gate_parent, 0x28, BIT(1), 0);
static SUNXI_CCU_GATE(apb0_i2c_clk, "apb0-i2c", "apb0", static SUNXI_CCU_GATE_HWS(apb0_timer_clk, "apb0-timer",
0x28, BIT(6), 0); apb0_gate_parent, 0x28, BIT(2), 0);
static SUNXI_CCU_GATE(apb0_twd_clk, "apb0-twd", "apb0", static SUNXI_CCU_GATE_HWS(apb0_rsb_clk, "apb0-rsb",
0x28, BIT(7), 0); apb0_gate_parent, 0x28, BIT(3), 0);
static SUNXI_CCU_GATE_HWS(apb0_uart_clk, "apb0-uart",
apb0_gate_parent, 0x28, BIT(4), 0);
static SUNXI_CCU_GATE_HWS(apb0_i2c_clk, "apb0-i2c",
apb0_gate_parent, 0x28, BIT(6), 0);
static SUNXI_CCU_GATE_HWS(apb0_twd_clk, "apb0-twd",
apb0_gate_parent, 0x28, BIT(7), 0);
static const char * const r_mod0_default_parents[] = { "osc32k", "osc24M" }; static const char * const r_mod0_default_parents[] = { "osc32k", "osc24M" };
static SUNXI_CCU_MP_WITH_MUX_GATE(ir_clk, "ir", static SUNXI_CCU_MP_WITH_MUX_GATE(ir_clk, "ir",
@ -115,7 +103,10 @@ static SUNXI_CCU_MP_WITH_MUX_GATE(ir_clk, "ir",
BIT(31), /* gate */ BIT(31), /* gate */
0); 0);
static const char *const a83t_r_mod0_parents[] = { "osc16M", "osc24M" }; static const struct clk_parent_data a83t_r_mod0_parents[] = {
{ .fw_name = "iosc" },
{ .fw_name = "hosc" },
};
static const struct ccu_mux_fixed_prediv a83t_ir_predivs[] = { static const struct ccu_mux_fixed_prediv a83t_ir_predivs[] = {
{ .index = 0, .div = 16 }, { .index = 0, .div = 16 },
}; };
@ -135,15 +126,15 @@ static struct ccu_mp a83t_ir_clk = {
.common = { .common = {
.reg = 0x54, .reg = 0x54,
.features = CCU_FEATURE_VARIABLE_PREDIV, .features = CCU_FEATURE_VARIABLE_PREDIV,
.hw.init = CLK_HW_INIT_PARENTS("ir", .hw.init = CLK_HW_INIT_PARENTS_DATA("ir",
a83t_r_mod0_parents, a83t_r_mod0_parents,
&ccu_mp_ops, &ccu_mp_ops,
0), 0),
}, },
}; };
static struct ccu_common *sun8i_a83t_r_ccu_clks[] = { static struct ccu_common *sun8i_a83t_r_ccu_clks[] = {
&a83t_ar100_clk.common, &ar100_clk.common,
&a83t_apb0_clk.common, &a83t_apb0_clk.common,
&apb0_pio_clk.common, &apb0_pio_clk.common,
&apb0_ir_clk.common, &apb0_ir_clk.common,
@ -182,7 +173,7 @@ static struct ccu_common *sun50i_a64_r_ccu_clks[] = {
static struct clk_hw_onecell_data sun8i_a83t_r_hw_clks = { static struct clk_hw_onecell_data sun8i_a83t_r_hw_clks = {
.hws = { .hws = {
[CLK_AR100] = &a83t_ar100_clk.common.hw, [CLK_AR100] = &ar100_clk.common.hw,
[CLK_AHB0] = &ahb0_clk.hw, [CLK_AHB0] = &ahb0_clk.hw,
[CLK_APB0] = &a83t_apb0_clk.common.hw, [CLK_APB0] = &a83t_apb0_clk.common.hw,
[CLK_APB0_PIO] = &apb0_pio_clk.common.hw, [CLK_APB0_PIO] = &apb0_pio_clk.common.hw,
@ -299,6 +290,9 @@ static void __init sunxi_r_ccu_init(struct device_node *node,
static void __init sun8i_a83t_r_ccu_setup(struct device_node *node) static void __init sun8i_a83t_r_ccu_setup(struct device_node *node)
{ {
/* Fix apb0 bus gate parents here */
apb0_gate_parent[0] = &a83t_apb0_clk.common.hw;
sunxi_r_ccu_init(node, &sun8i_a83t_r_ccu_desc); sunxi_r_ccu_init(node, &sun8i_a83t_r_ccu_desc);
} }
CLK_OF_DECLARE(sun8i_a83t_r_ccu, "allwinner,sun8i-a83t-r-ccu", CLK_OF_DECLARE(sun8i_a83t_r_ccu, "allwinner,sun8i-a83t-r-ccu",

Просмотреть файл

@ -952,25 +952,37 @@ static struct ccu_common *sun8i_r40_ccu_clks[] = {
}; };
/* Fixed Factor clocks */ /* Fixed Factor clocks */
static CLK_FIXED_FACTOR(osc12M_clk, "osc12M", "osc24M", 2, 1, 0); static CLK_FIXED_FACTOR_FW_NAME(osc12M_clk, "osc12M", "hosc", 2, 1, 0);
static const struct clk_hw *clk_parent_pll_audio[] = {
&pll_audio_base_clk.common.hw
};
/* We hardcode the divider to 4 for now */ /* We hardcode the divider to 4 for now */
static CLK_FIXED_FACTOR(pll_audio_clk, "pll-audio", static CLK_FIXED_FACTOR_HWS(pll_audio_clk, "pll-audio",
"pll-audio-base", 4, 1, CLK_SET_RATE_PARENT); clk_parent_pll_audio,
static CLK_FIXED_FACTOR(pll_audio_2x_clk, "pll-audio-2x", 4, 1, CLK_SET_RATE_PARENT);
"pll-audio-base", 2, 1, CLK_SET_RATE_PARENT); static CLK_FIXED_FACTOR_HWS(pll_audio_2x_clk, "pll-audio-2x",
static CLK_FIXED_FACTOR(pll_audio_4x_clk, "pll-audio-4x", clk_parent_pll_audio,
"pll-audio-base", 1, 1, CLK_SET_RATE_PARENT); 2, 1, CLK_SET_RATE_PARENT);
static CLK_FIXED_FACTOR(pll_audio_8x_clk, "pll-audio-8x", static CLK_FIXED_FACTOR_HWS(pll_audio_4x_clk, "pll-audio-4x",
"pll-audio-base", 1, 2, CLK_SET_RATE_PARENT); clk_parent_pll_audio,
static CLK_FIXED_FACTOR(pll_periph0_2x_clk, "pll-periph0-2x", 1, 1, CLK_SET_RATE_PARENT);
"pll-periph0", 1, 2, 0); static CLK_FIXED_FACTOR_HWS(pll_audio_8x_clk, "pll-audio-8x",
static CLK_FIXED_FACTOR(pll_periph1_2x_clk, "pll-periph1-2x", clk_parent_pll_audio,
"pll-periph1", 1, 2, 0); 1, 2, CLK_SET_RATE_PARENT);
static CLK_FIXED_FACTOR(pll_video0_2x_clk, "pll-video0-2x", static CLK_FIXED_FACTOR_HW(pll_periph0_2x_clk, "pll-periph0-2x",
"pll-video0", 1, 2, 0); &pll_periph0_clk.common.hw,
static CLK_FIXED_FACTOR(pll_video1_2x_clk, "pll-video1-2x", 1, 2, 0);
"pll-video1", 1, 2, 0); static CLK_FIXED_FACTOR_HW(pll_periph1_2x_clk, "pll-periph1-2x",
&pll_periph1_clk.common.hw,
1, 2, 0);
static CLK_FIXED_FACTOR_HW(pll_video0_2x_clk, "pll-video0-2x",
&pll_video0_clk.common.hw,
1, 2, 0);
static CLK_FIXED_FACTOR_HW(pll_video1_2x_clk, "pll-video1-2x",
&pll_video1_clk.common.hw,
1, 2, 0);
static struct clk_hw_onecell_data sun8i_r40_hw_clks = { static struct clk_hw_onecell_data sun8i_r40_hw_clks = {
.hws = { .hws = {

Просмотреть файл

@ -437,17 +437,26 @@ static struct ccu_common *sun8i_v3s_ccu_clks[] = {
&mipi_csi_clk.common, &mipi_csi_clk.common,
}; };
static const struct clk_hw *clk_parent_pll_audio[] = {
&pll_audio_base_clk.common.hw
};
/* We hardcode the divider to 4 for now */ /* We hardcode the divider to 4 for now */
static CLK_FIXED_FACTOR(pll_audio_clk, "pll-audio", static CLK_FIXED_FACTOR_HWS(pll_audio_clk, "pll-audio",
"pll-audio-base", 4, 1, CLK_SET_RATE_PARENT); clk_parent_pll_audio,
static CLK_FIXED_FACTOR(pll_audio_2x_clk, "pll-audio-2x", 4, 1, CLK_SET_RATE_PARENT);
"pll-audio-base", 2, 1, CLK_SET_RATE_PARENT); static CLK_FIXED_FACTOR_HWS(pll_audio_2x_clk, "pll-audio-2x",
static CLK_FIXED_FACTOR(pll_audio_4x_clk, "pll-audio-4x", clk_parent_pll_audio,
"pll-audio-base", 1, 1, CLK_SET_RATE_PARENT); 2, 1, CLK_SET_RATE_PARENT);
static CLK_FIXED_FACTOR(pll_audio_8x_clk, "pll-audio-8x", static CLK_FIXED_FACTOR_HWS(pll_audio_4x_clk, "pll-audio-4x",
"pll-audio-base", 1, 2, CLK_SET_RATE_PARENT); clk_parent_pll_audio,
static CLK_FIXED_FACTOR(pll_periph0_2x_clk, "pll-periph0-2x", 1, 1, CLK_SET_RATE_PARENT);
"pll-periph0", 1, 2, 0); static CLK_FIXED_FACTOR_HWS(pll_audio_8x_clk, "pll-audio-8x",
clk_parent_pll_audio,
1, 2, CLK_SET_RATE_PARENT);
static CLK_FIXED_FACTOR_HW(pll_periph0_2x_clk, "pll-periph0-2x",
&pll_periph0_clk.common.hw,
1, 2, 0);
static struct clk_hw_onecell_data sun8i_v3s_hw_clks = { static struct clk_hw_onecell_data sun8i_v3s_hw_clks = {
.hws = { .hws = {

Просмотреть файл

@ -22,18 +22,26 @@
#include "ccu-sun9i-a80-usb.h" #include "ccu-sun9i-a80-usb.h"
static SUNXI_CCU_GATE(bus_hci0_clk, "bus-hci0", "bus-usb", 0x0, BIT(1), 0); static const struct clk_parent_data clk_parent_hosc[] = {
static SUNXI_CCU_GATE(usb_ohci0_clk, "usb-ohci0", "osc24M", 0x0, BIT(2), 0); { .fw_name = "hosc" },
static SUNXI_CCU_GATE(bus_hci1_clk, "bus-hci1", "bus-usb", 0x0, BIT(3), 0); };
static SUNXI_CCU_GATE(bus_hci2_clk, "bus-hci2", "bus-usb", 0x0, BIT(5), 0);
static SUNXI_CCU_GATE(usb_ohci2_clk, "usb-ohci2", "osc24M", 0x0, BIT(6), 0);
static SUNXI_CCU_GATE(usb0_phy_clk, "usb0-phy", "osc24M", 0x4, BIT(1), 0); static const struct clk_parent_data clk_parent_bus[] = {
static SUNXI_CCU_GATE(usb1_hsic_clk, "usb1-hsic", "osc24M", 0x4, BIT(2), 0); { .fw_name = "bus" },
static SUNXI_CCU_GATE(usb1_phy_clk, "usb1-phy", "osc24M", 0x4, BIT(3), 0); };
static SUNXI_CCU_GATE(usb2_hsic_clk, "usb2-hsic", "osc24M", 0x4, BIT(4), 0);
static SUNXI_CCU_GATE(usb2_phy_clk, "usb2-phy", "osc24M", 0x4, BIT(5), 0); static SUNXI_CCU_GATE_DATA(bus_hci0_clk, "bus-hci0", clk_parent_bus, 0x0, BIT(1), 0);
static SUNXI_CCU_GATE(usb_hsic_clk, "usb-hsic", "osc24M", 0x4, BIT(10), 0); static SUNXI_CCU_GATE_DATA(usb_ohci0_clk, "usb-ohci0", clk_parent_hosc, 0x0, BIT(2), 0);
static SUNXI_CCU_GATE_DATA(bus_hci1_clk, "bus-hci1", clk_parent_bus, 0x0, BIT(3), 0);
static SUNXI_CCU_GATE_DATA(bus_hci2_clk, "bus-hci2", clk_parent_bus, 0x0, BIT(5), 0);
static SUNXI_CCU_GATE_DATA(usb_ohci2_clk, "usb-ohci2", clk_parent_hosc, 0x0, BIT(6), 0);
static SUNXI_CCU_GATE_DATA(usb0_phy_clk, "usb0-phy", clk_parent_hosc, 0x4, BIT(1), 0);
static SUNXI_CCU_GATE_DATA(usb1_hsic_clk, "usb1-hsic", clk_parent_hosc, 0x4, BIT(2), 0);
static SUNXI_CCU_GATE_DATA(usb1_phy_clk, "usb1-phy", clk_parent_hosc, 0x4, BIT(3), 0);
static SUNXI_CCU_GATE_DATA(usb2_hsic_clk, "usb2-hsic", clk_parent_hosc, 0x4, BIT(4), 0);
static SUNXI_CCU_GATE_DATA(usb2_phy_clk, "usb2-phy", clk_parent_hosc, 0x4, BIT(5), 0);
static SUNXI_CCU_GATE_DATA(usb_hsic_clk, "usb-hsic", clk_parent_hosc, 0x4, BIT(10), 0);
static struct ccu_common *sun9i_a80_usb_clks[] = { static struct ccu_common *sun9i_a80_usb_clks[] = {
&bus_hci0_clk.common, &bus_hci0_clk.common,

Просмотреть файл

@ -374,16 +374,25 @@ static struct ccu_common *suniv_ccu_clks[] = {
&avs_clk.common, &avs_clk.common,
}; };
static CLK_FIXED_FACTOR(pll_audio_clk, "pll-audio", static const struct clk_hw *clk_parent_pll_audio[] = {
"pll-audio-base", 4, 1, CLK_SET_RATE_PARENT); &pll_audio_base_clk.common.hw
static CLK_FIXED_FACTOR(pll_audio_2x_clk, "pll-audio-2x", };
"pll-audio-base", 2, 1, CLK_SET_RATE_PARENT);
static CLK_FIXED_FACTOR(pll_audio_4x_clk, "pll-audio-4x", static CLK_FIXED_FACTOR_HWS(pll_audio_clk, "pll-audio",
"pll-audio-base", 1, 1, CLK_SET_RATE_PARENT); clk_parent_pll_audio,
static CLK_FIXED_FACTOR(pll_audio_8x_clk, "pll-audio-8x", 4, 1, CLK_SET_RATE_PARENT);
"pll-audio-base", 1, 2, CLK_SET_RATE_PARENT); static CLK_FIXED_FACTOR_HWS(pll_audio_2x_clk, "pll-audio-2x",
static CLK_FIXED_FACTOR(pll_video_2x_clk, "pll-video-2x", clk_parent_pll_audio,
"pll-video", 1, 2, 0); 2, 1, CLK_SET_RATE_PARENT);
static CLK_FIXED_FACTOR_HWS(pll_audio_4x_clk, "pll-audio-4x",
clk_parent_pll_audio,
1, 1, CLK_SET_RATE_PARENT);
static CLK_FIXED_FACTOR_HWS(pll_audio_8x_clk, "pll-audio-8x",
clk_parent_pll_audio,
1, 2, CLK_SET_RATE_PARENT);
static CLK_FIXED_FACTOR_HW(pll_video_2x_clk, "pll-video-2x",
&pll_video_clk.common.hw,
1, 2, 0);
static struct clk_hw_onecell_data suniv_hw_clks = { static struct clk_hw_onecell_data suniv_hw_clks = {
.hws = { .hws = {

Просмотреть файл

@ -110,7 +110,7 @@ int sunxi_ccu_probe(struct device_node *node, void __iomem *reg,
if (!hw) if (!hw)
continue; continue;
ret = clk_hw_register(NULL, hw); ret = of_clk_hw_register(node, hw);
if (ret) { if (ret) {
pr_err("Couldn't register clock %d - %s\n", pr_err("Couldn't register clock %d - %s\n",
i, clk_hw_get_name(hw)); i, clk_hw_get_name(hw));

Просмотреть файл

@ -36,6 +36,59 @@ struct ccu_gate {
} \ } \
} }
#define SUNXI_CCU_GATE_HW(_struct, _name, _parent, _reg, _gate, _flags) \
struct ccu_gate _struct = { \
.enable = _gate, \
.common = { \
.reg = _reg, \
.hw.init = CLK_HW_INIT_HW(_name, \
_parent, \
&ccu_gate_ops, \
_flags), \
} \
}
#define SUNXI_CCU_GATE_FW(_struct, _name, _parent, _reg, _gate, _flags) \
struct ccu_gate _struct = { \
.enable = _gate, \
.common = { \
.reg = _reg, \
.hw.init = CLK_HW_INIT_FW_NAME(_name, \
_parent, \
&ccu_gate_ops, \
_flags), \
} \
}
/*
* The following two macros allow the re-use of the data structure
* holding the parent info.
*/
#define SUNXI_CCU_GATE_HWS(_struct, _name, _parent, _reg, _gate, _flags) \
struct ccu_gate _struct = { \
.enable = _gate, \
.common = { \
.reg = _reg, \
.hw.init = CLK_HW_INIT_HWS(_name, \
_parent, \
&ccu_gate_ops, \
_flags), \
} \
}
#define SUNXI_CCU_GATE_DATA(_struct, _name, _data, _reg, _gate, _flags) \
struct ccu_gate _struct = { \
.enable = _gate, \
.common = { \
.reg = _reg, \
.hw.init = \
CLK_HW_INIT_PARENTS_DATA(_name, \
_data, \
&ccu_gate_ops, \
_flags), \
} \
}
static inline struct ccu_gate *hw_to_ccu_gate(struct clk_hw *hw) static inline struct ccu_gate *hw_to_ccu_gate(struct clk_hw *hw)
{ {
struct ccu_common *common = hw_to_ccu_common(hw); struct ccu_common *common = hw_to_ccu_common(hw);

Просмотреть файл

@ -904,6 +904,40 @@ extern struct of_device_id __clk_of_table;
.ops = _ops, \ .ops = _ops, \
}) })
#define CLK_HW_INIT_HW(_name, _parent, _ops, _flags) \
(&(struct clk_init_data) { \
.flags = _flags, \
.name = _name, \
.parent_hws = (const struct clk_hw*[]) { _parent }, \
.num_parents = 1, \
.ops = _ops, \
})
/*
* This macro is intended for drivers to be able to share the otherwise
* individual struct clk_hw[] compound literals created by the compiler
* when using CLK_HW_INIT_HW. It does NOT support multiple parents.
*/
#define CLK_HW_INIT_HWS(_name, _parent, _ops, _flags) \
(&(struct clk_init_data) { \
.flags = _flags, \
.name = _name, \
.parent_hws = _parent, \
.num_parents = 1, \
.ops = _ops, \
})
#define CLK_HW_INIT_FW_NAME(_name, _parent, _ops, _flags) \
(&(struct clk_init_data) { \
.flags = _flags, \
.name = _name, \
.parent_data = (const struct clk_parent_data[]) { \
{ .fw_name = _parent }, \
}, \
.num_parents = 1, \
.ops = _ops, \
})
#define CLK_HW_INIT_PARENTS(_name, _parents, _ops, _flags) \ #define CLK_HW_INIT_PARENTS(_name, _parents, _ops, _flags) \
(&(struct clk_init_data) { \ (&(struct clk_init_data) { \
.flags = _flags, \ .flags = _flags, \
@ -913,6 +947,24 @@ extern struct of_device_id __clk_of_table;
.ops = _ops, \ .ops = _ops, \
}) })
#define CLK_HW_INIT_PARENTS_HW(_name, _parents, _ops, _flags) \
(&(struct clk_init_data) { \
.flags = _flags, \
.name = _name, \
.parent_hws = _parents, \
.num_parents = ARRAY_SIZE(_parents), \
.ops = _ops, \
})
#define CLK_HW_INIT_PARENTS_DATA(_name, _parents, _ops, _flags) \
(&(struct clk_init_data) { \
.flags = _flags, \
.name = _name, \
.parent_data = _parents, \
.num_parents = ARRAY_SIZE(_parents), \
.ops = _ops, \
})
#define CLK_HW_INIT_NO_PARENT(_name, _ops, _flags) \ #define CLK_HW_INIT_NO_PARENT(_name, _ops, _flags) \
(&(struct clk_init_data) { \ (&(struct clk_init_data) { \
.flags = _flags, \ .flags = _flags, \
@ -933,6 +985,43 @@ extern struct of_device_id __clk_of_table;
_flags), \ _flags), \
} }
#define CLK_FIXED_FACTOR_HW(_struct, _name, _parent, \
_div, _mult, _flags) \
struct clk_fixed_factor _struct = { \
.div = _div, \
.mult = _mult, \
.hw.init = CLK_HW_INIT_HW(_name, \
_parent, \
&clk_fixed_factor_ops, \
_flags), \
}
/*
* This macro allows the driver to reuse the _parent array for multiple
* fixed factor clk declarations.
*/
#define CLK_FIXED_FACTOR_HWS(_struct, _name, _parent, \
_div, _mult, _flags) \
struct clk_fixed_factor _struct = { \
.div = _div, \
.mult = _mult, \
.hw.init = CLK_HW_INIT_HWS(_name, \
_parent, \
&clk_fixed_factor_ops, \
_flags), \
}
#define CLK_FIXED_FACTOR_FW_NAME(_struct, _name, _parent, \
_div, _mult, _flags) \
struct clk_fixed_factor _struct = { \
.div = _div, \
.mult = _mult, \
.hw.init = CLK_HW_INIT_FW_NAME(_name, \
_parent, \
&clk_fixed_factor_ops, \
_flags), \
}
#ifdef CONFIG_OF #ifdef CONFIG_OF
int of_clk_add_provider(struct device_node *np, int of_clk_add_provider(struct device_node *np,
struct clk *(*clk_src_get)(struct of_phandle_args *args, struct clk *(*clk_src_get)(struct of_phandle_args *args,