2018-05-16 16:50:40 +08:00
|
|
|
// SPDX-License-Identifier: GPL-2.0
|
2015-06-01 19:13:55 +08:00
|
|
|
/*
|
|
|
|
* Copyright (c) 2015 Endless Mobile, Inc.
|
|
|
|
* Author: Carlo Caione <carlo@endlessm.com>
|
|
|
|
*
|
2016-05-12 02:11:18 +08:00
|
|
|
* Copyright (c) 2016 BayLibre, Inc.
|
|
|
|
* Michael Turquette <mturquette@baylibre.com>
|
2015-06-01 19:13:55 +08:00
|
|
|
*/
|
|
|
|
|
2016-05-01 03:47:36 +08:00
|
|
|
#include <linux/clk.h>
|
2015-06-01 19:13:55 +08:00
|
|
|
#include <linux/clk-provider.h>
|
2018-02-12 22:58:35 +08:00
|
|
|
#include <linux/init.h>
|
2018-10-28 20:08:58 +08:00
|
|
|
#include <linux/mfd/syscon.h>
|
2015-06-01 19:13:55 +08:00
|
|
|
#include <linux/of_address.h>
|
2017-07-29 05:13:12 +08:00
|
|
|
#include <linux/reset-controller.h>
|
|
|
|
#include <linux/slab.h>
|
2018-02-12 22:58:35 +08:00
|
|
|
#include <linux/regmap.h>
|
2015-06-01 19:13:55 +08:00
|
|
|
|
2016-08-28 01:40:50 +08:00
|
|
|
#include "meson8b.h"
|
2018-02-12 22:58:36 +08:00
|
|
|
#include "clk-regmap.h"
|
clk: meson: rework and clean drivers dependencies
Initially, the meson clock directory only hosted 2 controllers drivers,
for meson8 and gxbb. At the time, both used the same set of clock drivers
so managing the dependencies was not a big concern.
Since this ancient time, entropy did its job, controllers with different
requirement and specific clock drivers have been added. Unfortunately, we
did not do a great job at managing the dependencies between the
controllers and the different clock drivers. Some drivers, such as
clk-phase or vid-pll-div, are compiled even if they are useless on the
target (meson8). As we are adding new controllers, we need to be able to
pick a driver w/o pulling the whole thing.
The patch aims to clean things up by:
* providing a dedicated CONFIG_ for each clock drivers
* allowing clock drivers to be compiled as a modules, if possible
* stating explicitly which drivers are required by each controller.
Signed-off-by: Jerome Brunet <jbrunet@baylibre.com>
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
Link: https://lkml.kernel.org/r/20190201125841.26785-5-jbrunet@baylibre.com
2019-02-01 20:58:41 +08:00
|
|
|
#include "clk-pll.h"
|
|
|
|
#include "clk-mpll.h"
|
2015-06-01 19:13:55 +08:00
|
|
|
|
2017-12-11 22:13:43 +08:00
|
|
|
static DEFINE_SPINLOCK(meson_clk_lock);
|
2016-04-29 03:01:51 +08:00
|
|
|
|
2017-07-29 05:13:12 +08:00
|
|
|
struct meson8b_clk_reset {
|
|
|
|
struct reset_controller_dev reset;
|
2018-07-22 03:14:00 +08:00
|
|
|
struct regmap *regmap;
|
2017-07-29 05:13:12 +08:00
|
|
|
};
|
|
|
|
|
2018-08-01 22:00:53 +08:00
|
|
|
static const struct pll_params_table sys_pll_params_table[] = {
|
|
|
|
PLL_PARAMS(50, 1),
|
|
|
|
PLL_PARAMS(51, 1),
|
|
|
|
PLL_PARAMS(52, 1),
|
|
|
|
PLL_PARAMS(53, 1),
|
|
|
|
PLL_PARAMS(54, 1),
|
|
|
|
PLL_PARAMS(55, 1),
|
|
|
|
PLL_PARAMS(56, 1),
|
|
|
|
PLL_PARAMS(57, 1),
|
|
|
|
PLL_PARAMS(58, 1),
|
|
|
|
PLL_PARAMS(59, 1),
|
|
|
|
PLL_PARAMS(60, 1),
|
|
|
|
PLL_PARAMS(61, 1),
|
|
|
|
PLL_PARAMS(62, 1),
|
|
|
|
PLL_PARAMS(63, 1),
|
|
|
|
PLL_PARAMS(64, 1),
|
clk: meson: meson8b: add support for more M/N values in sys_pll
The sys_pll on the EC-100 board is configured to 1584MHz at boot
(either by u-boot, firmware or chip defaults). This is achieved by using
M = 66, N = 1 (24MHz * 66 / 1).
At boot the CPU clock is running off sys_pll divided by 2 which results
in 792MHz. Thus M = 66 is considered to be a "safe" value for Meson8b.
To achieve 1608MHz (one of the CPU OPPs on Meson8 and Meson8m2) we need
M = 67, N = 1. I ran "stress --cpu 4" while infinitely cycling through
all available frequencies on my Meson8m2 board and could not spot any
issues with this setting (after ~12 hours of running this).
On Meson8, Meson8b and Meson8m2 we also want to be able to use 408MHz
and 816MHz CPU frequencies. These can be achieved by dividing sys_pll by
4 (for 408MHz) or 2 (for 816MHz). That means that sys_pll has to run at
1632MHz which can be generated using M = 68, N = 1.
Similarily we also want to be able to use 1008MHz as CPU frequency. This
means that sys_pll has to run either at 1008MHz or 2016MHz. The former
would result in an M value of 42, which is lower than the smallest value
used by the 3.10 GPL kernel sources from Amlogic (50 is the lower limit
there). Thus we need to run sys_pll at 2016MHz which can ge generated
using M = 84, N = 1.
I tested M = 68 and M = 84 on my Meson8b Odroid-C1 and my Meson8m2 board
by running "stress --cpu 4" while infinitely cycling thorugh all
available frequencies. I could not spot any issues after ~12 hours of
running this.
Amlogic's 3.10 GPL kernel sources have more M/N combinations. I did not
add them yet because M = 74 (to achieve close to 1800MHz on Meson8) and
M = 82 (to achieve close to 1992MHz on Meson8 as well) caused my
Meson8m2 board to hang randomly. It's not clear why this is (for example
because the board's voltage regulator design is bad, some missing bits
for these values in our clk-pll driver, etc.). Thus the following M
values from the Amlogic 3.10 GPL kernel sources are skipped as of now:
69, 70, 71, 72, 73, 74, 76, 78, 80, 82, 84, 86, 88, 90, 92, 94, 96, 98
Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
Acked-by: Jerome Brunet <jbrunet@baylibre.com>
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
Link: https://lkml.kernel.org/r/20181115224048.13511-5-martin.blumenstingl@googlemail.com
2018-11-16 06:40:46 +08:00
|
|
|
PLL_PARAMS(65, 1),
|
|
|
|
PLL_PARAMS(66, 1),
|
|
|
|
PLL_PARAMS(67, 1),
|
|
|
|
PLL_PARAMS(68, 1),
|
|
|
|
PLL_PARAMS(84, 1),
|
2015-06-01 19:13:55 +08:00
|
|
|
{ /* sentinel */ },
|
|
|
|
};
|
|
|
|
|
2016-04-29 03:00:52 +08:00
|
|
|
static struct clk_fixed_rate meson8b_xtal = {
|
|
|
|
.fixed_rate = 24000000,
|
|
|
|
.hw.init = &(struct clk_init_data){
|
|
|
|
.name = "xtal",
|
|
|
|
.num_parents = 0,
|
|
|
|
.ops = &clk_fixed_rate_ops,
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
2018-08-01 22:00:52 +08:00
|
|
|
static struct clk_regmap meson8b_fixed_pll_dco = {
|
2018-02-12 22:58:42 +08:00
|
|
|
.data = &(struct meson_clk_pll_data){
|
2018-08-01 22:00:50 +08:00
|
|
|
.en = {
|
|
|
|
.reg_off = HHI_MPLL_CNTL,
|
|
|
|
.shift = 30,
|
|
|
|
.width = 1,
|
|
|
|
},
|
2018-02-12 22:58:42 +08:00
|
|
|
.m = {
|
|
|
|
.reg_off = HHI_MPLL_CNTL,
|
|
|
|
.shift = 0,
|
|
|
|
.width = 9,
|
|
|
|
},
|
|
|
|
.n = {
|
|
|
|
.reg_off = HHI_MPLL_CNTL,
|
|
|
|
.shift = 9,
|
|
|
|
.width = 5,
|
|
|
|
},
|
2018-02-19 19:21:36 +08:00
|
|
|
.frac = {
|
|
|
|
.reg_off = HHI_MPLL_CNTL2,
|
|
|
|
.shift = 0,
|
|
|
|
.width = 12,
|
|
|
|
},
|
2018-02-12 22:58:42 +08:00
|
|
|
.l = {
|
|
|
|
.reg_off = HHI_MPLL_CNTL,
|
|
|
|
.shift = 31,
|
|
|
|
.width = 1,
|
|
|
|
},
|
|
|
|
.rst = {
|
|
|
|
.reg_off = HHI_MPLL_CNTL,
|
|
|
|
.shift = 29,
|
|
|
|
.width = 1,
|
|
|
|
},
|
|
|
|
},
|
2016-04-29 03:01:42 +08:00
|
|
|
.hw.init = &(struct clk_init_data){
|
2018-08-01 22:00:52 +08:00
|
|
|
.name = "fixed_pll_dco",
|
2016-04-29 03:01:42 +08:00
|
|
|
.ops = &meson_clk_pll_ro_ops,
|
|
|
|
.parent_names = (const char *[]){ "xtal" },
|
|
|
|
.num_parents = 1,
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
2018-08-01 22:00:52 +08:00
|
|
|
static struct clk_regmap meson8b_fixed_pll = {
|
|
|
|
.data = &(struct clk_regmap_div_data){
|
|
|
|
.offset = HHI_MPLL_CNTL,
|
|
|
|
.shift = 16,
|
|
|
|
.width = 2,
|
|
|
|
.flags = CLK_DIVIDER_POWER_OF_TWO,
|
|
|
|
},
|
|
|
|
.hw.init = &(struct clk_init_data){
|
|
|
|
.name = "fixed_pll",
|
|
|
|
.ops = &clk_regmap_divider_ro_ops,
|
|
|
|
.parent_names = (const char *[]){ "fixed_pll_dco" },
|
|
|
|
.num_parents = 1,
|
|
|
|
/*
|
|
|
|
* This clock won't ever change at runtime so
|
|
|
|
* CLK_SET_RATE_PARENT is not required
|
|
|
|
*/
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
clk: meson: meson8b: add the read-only video clock trees
Add all clocks to give us the final video clocks within the Meson8,
Meson8b and Meson8m2 SoCs. The final video clocks are:
- cts_enct
- cts_encl
- cts_encp
- cts_enci
- cts_vdac0
- hdmi_tx_pixel
- hdmi_sys
Add multiple clocks in between which are needed to implement these
clocks:
- Opposed to GXBB there is no pre-multiplier for the PLL input. The
assumption here is that the multiplier is required to achieve the HDMI
2.0 clock rates (which are up to twice the rate of the HDMI 1.4
rates).
- The main PLL is called "HDMI PLL" or "HPLL" in the datasheet. Rename
our existing "vid_pll_dco" to "hdmi_pll_dco". The actual VID_PLL clock
also exists further down the tree.
- Rename the existing "vid_pll" clock (which is the OD divider at
HHI_VID_PLL_CNTL[17:16]) to "hdmi_pll_lvds_out" to match the naming
from the datasheet.
- Add the second OD divider called "hdmi_pll_hdmi_out" at
HHI_VID_PLL_CNTL[19:18].
- Add the "vid_pll_in_sel" which can choose between "hdmi_pll_dco" and
another parent. However, the second parent is not use on Amlogic's
3.10 kernel for HDMI or CVBS output so just leave a TODO in the code.
- Add the "vid_pll_in_en" which is located after "vid_pll_in_sel"
according to the datasheet.
- Add "vid_pll_pre_div" which is used for divide-by-5 and divide-by-6 in
Amlogic's 3.10 kernel sources.
- Add "vid_pll_post_div" which divides the output of "vid_pll_pre_div"
further down. The Amlogic 3.10 kernel configures this as divide-by-2
with "vid_pll_pre_div" being configured as divide-by-5 to achieve a
total divider of 10.
- Add the real "vid_pll" clock which selects between "vid_pll_pre_div",
"vid_pll_post_div" and a third "vid_pll_pre_div_mult7_div2" (which is
"vid_pll_pre_div" divided by 3.5). The latter is not supported yet
because it's not used in Amlogic's 3.10 kernel. The "vid_pll" clock
rate can also be measured by clkmsr to check whether this
implementation is correct.
- Add "vid_pll_final_div" which is a post-divider for "vid_pll" and it's
used as input for "vclk" and "vclk2"
- Add the two symmetric "vclk" and "vclk" clock trees, each with a
divide-by-1, divide-by-2, divide-by-4, divide-by-6 and divide-by-12
clock and a divider for each clock.
- Add the "cts_enct", "cts_encp" and "hdmi_tx_pixel" clocks which each
have their own gate and can select between any of the five "vclk"
dividers.
- Add the "cts_encl" and "cts_vdac0" clocks which each have their own
gate and can select between any of the five "vclk2" dividers.
The "hdmi_sys" clock is a different than these video clocks. It takes
"xtal" as input (there are three more but unknown parents). Add this
clock as well as it's used by the HDMI controller. Amlogic's 3.10 kernel
always configures this as "xtal divided by 1", so we can ignore the
other parents for now.
This was tested on Meson8b and Meson8m2 boards by comparing the common
clock framework output with the clock measurer output. The following
video modes were first set in u-boot (by running "video dev open $mode")
before booting Linux:
4K2K30HZ (only supported by Meson8m2, not tested on Meson8b):
- vid_pll: 297000000Hz
- cts_encp: 297000000Hz
- hdmi_tx_pixel: 297000000Hz
1080P:
- vid_pll: 148500000Hz
- cts_encp: 148500000Hz
- hdmi_tx_pixel: 148500000Hz
720P:
- vid_pll: 148500000Hz
- cts_encp: 148500000Hz
- hdmi_tx_pixel: 74250000Hz
480P:
- vid_pll: 216000000Hz
- cts_encp: 54000000Hz
- hdmi_tx_pixel: 27000000Hz
Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
Link: https://lkml.kernel.org/r/20181202214220.7715-4-martin.blumenstingl@googlemail.com
2018-12-03 05:42:20 +08:00
|
|
|
static struct clk_regmap meson8b_hdmi_pll_dco = {
|
2018-02-12 22:58:42 +08:00
|
|
|
.data = &(struct meson_clk_pll_data){
|
2018-08-01 22:00:50 +08:00
|
|
|
.en = {
|
|
|
|
.reg_off = HHI_VID_PLL_CNTL,
|
|
|
|
.shift = 30,
|
|
|
|
.width = 1,
|
|
|
|
},
|
2018-02-12 22:58:42 +08:00
|
|
|
.m = {
|
|
|
|
.reg_off = HHI_VID_PLL_CNTL,
|
|
|
|
.shift = 0,
|
|
|
|
.width = 9,
|
|
|
|
},
|
|
|
|
.n = {
|
|
|
|
.reg_off = HHI_VID_PLL_CNTL,
|
2018-12-03 05:42:18 +08:00
|
|
|
.shift = 10,
|
2018-02-12 22:58:42 +08:00
|
|
|
.width = 5,
|
|
|
|
},
|
2018-12-03 05:42:19 +08:00
|
|
|
.frac = {
|
|
|
|
.reg_off = HHI_VID_PLL_CNTL2,
|
|
|
|
.shift = 0,
|
|
|
|
.width = 12,
|
|
|
|
},
|
2018-02-12 22:58:42 +08:00
|
|
|
.l = {
|
|
|
|
.reg_off = HHI_VID_PLL_CNTL,
|
|
|
|
.shift = 31,
|
|
|
|
.width = 1,
|
|
|
|
},
|
|
|
|
.rst = {
|
|
|
|
.reg_off = HHI_VID_PLL_CNTL,
|
|
|
|
.shift = 29,
|
|
|
|
.width = 1,
|
|
|
|
},
|
2016-04-29 03:01:42 +08:00
|
|
|
},
|
|
|
|
.hw.init = &(struct clk_init_data){
|
clk: meson: meson8b: add the read-only video clock trees
Add all clocks to give us the final video clocks within the Meson8,
Meson8b and Meson8m2 SoCs. The final video clocks are:
- cts_enct
- cts_encl
- cts_encp
- cts_enci
- cts_vdac0
- hdmi_tx_pixel
- hdmi_sys
Add multiple clocks in between which are needed to implement these
clocks:
- Opposed to GXBB there is no pre-multiplier for the PLL input. The
assumption here is that the multiplier is required to achieve the HDMI
2.0 clock rates (which are up to twice the rate of the HDMI 1.4
rates).
- The main PLL is called "HDMI PLL" or "HPLL" in the datasheet. Rename
our existing "vid_pll_dco" to "hdmi_pll_dco". The actual VID_PLL clock
also exists further down the tree.
- Rename the existing "vid_pll" clock (which is the OD divider at
HHI_VID_PLL_CNTL[17:16]) to "hdmi_pll_lvds_out" to match the naming
from the datasheet.
- Add the second OD divider called "hdmi_pll_hdmi_out" at
HHI_VID_PLL_CNTL[19:18].
- Add the "vid_pll_in_sel" which can choose between "hdmi_pll_dco" and
another parent. However, the second parent is not use on Amlogic's
3.10 kernel for HDMI or CVBS output so just leave a TODO in the code.
- Add the "vid_pll_in_en" which is located after "vid_pll_in_sel"
according to the datasheet.
- Add "vid_pll_pre_div" which is used for divide-by-5 and divide-by-6 in
Amlogic's 3.10 kernel sources.
- Add "vid_pll_post_div" which divides the output of "vid_pll_pre_div"
further down. The Amlogic 3.10 kernel configures this as divide-by-2
with "vid_pll_pre_div" being configured as divide-by-5 to achieve a
total divider of 10.
- Add the real "vid_pll" clock which selects between "vid_pll_pre_div",
"vid_pll_post_div" and a third "vid_pll_pre_div_mult7_div2" (which is
"vid_pll_pre_div" divided by 3.5). The latter is not supported yet
because it's not used in Amlogic's 3.10 kernel. The "vid_pll" clock
rate can also be measured by clkmsr to check whether this
implementation is correct.
- Add "vid_pll_final_div" which is a post-divider for "vid_pll" and it's
used as input for "vclk" and "vclk2"
- Add the two symmetric "vclk" and "vclk" clock trees, each with a
divide-by-1, divide-by-2, divide-by-4, divide-by-6 and divide-by-12
clock and a divider for each clock.
- Add the "cts_enct", "cts_encp" and "hdmi_tx_pixel" clocks which each
have their own gate and can select between any of the five "vclk"
dividers.
- Add the "cts_encl" and "cts_vdac0" clocks which each have their own
gate and can select between any of the five "vclk2" dividers.
The "hdmi_sys" clock is a different than these video clocks. It takes
"xtal" as input (there are three more but unknown parents). Add this
clock as well as it's used by the HDMI controller. Amlogic's 3.10 kernel
always configures this as "xtal divided by 1", so we can ignore the
other parents for now.
This was tested on Meson8b and Meson8m2 boards by comparing the common
clock framework output with the clock measurer output. The following
video modes were first set in u-boot (by running "video dev open $mode")
before booting Linux:
4K2K30HZ (only supported by Meson8m2, not tested on Meson8b):
- vid_pll: 297000000Hz
- cts_encp: 297000000Hz
- hdmi_tx_pixel: 297000000Hz
1080P:
- vid_pll: 148500000Hz
- cts_encp: 148500000Hz
- hdmi_tx_pixel: 148500000Hz
720P:
- vid_pll: 148500000Hz
- cts_encp: 148500000Hz
- hdmi_tx_pixel: 74250000Hz
480P:
- vid_pll: 216000000Hz
- cts_encp: 54000000Hz
- hdmi_tx_pixel: 27000000Hz
Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
Link: https://lkml.kernel.org/r/20181202214220.7715-4-martin.blumenstingl@googlemail.com
2018-12-03 05:42:20 +08:00
|
|
|
/* sometimes also called "HPLL" or "HPLL PLL" */
|
|
|
|
.name = "hdmi_pll_dco",
|
2016-04-29 03:01:42 +08:00
|
|
|
.ops = &meson_clk_pll_ro_ops,
|
|
|
|
.parent_names = (const char *[]){ "xtal" },
|
|
|
|
.num_parents = 1,
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
clk: meson: meson8b: add the read-only video clock trees
Add all clocks to give us the final video clocks within the Meson8,
Meson8b and Meson8m2 SoCs. The final video clocks are:
- cts_enct
- cts_encl
- cts_encp
- cts_enci
- cts_vdac0
- hdmi_tx_pixel
- hdmi_sys
Add multiple clocks in between which are needed to implement these
clocks:
- Opposed to GXBB there is no pre-multiplier for the PLL input. The
assumption here is that the multiplier is required to achieve the HDMI
2.0 clock rates (which are up to twice the rate of the HDMI 1.4
rates).
- The main PLL is called "HDMI PLL" or "HPLL" in the datasheet. Rename
our existing "vid_pll_dco" to "hdmi_pll_dco". The actual VID_PLL clock
also exists further down the tree.
- Rename the existing "vid_pll" clock (which is the OD divider at
HHI_VID_PLL_CNTL[17:16]) to "hdmi_pll_lvds_out" to match the naming
from the datasheet.
- Add the second OD divider called "hdmi_pll_hdmi_out" at
HHI_VID_PLL_CNTL[19:18].
- Add the "vid_pll_in_sel" which can choose between "hdmi_pll_dco" and
another parent. However, the second parent is not use on Amlogic's
3.10 kernel for HDMI or CVBS output so just leave a TODO in the code.
- Add the "vid_pll_in_en" which is located after "vid_pll_in_sel"
according to the datasheet.
- Add "vid_pll_pre_div" which is used for divide-by-5 and divide-by-6 in
Amlogic's 3.10 kernel sources.
- Add "vid_pll_post_div" which divides the output of "vid_pll_pre_div"
further down. The Amlogic 3.10 kernel configures this as divide-by-2
with "vid_pll_pre_div" being configured as divide-by-5 to achieve a
total divider of 10.
- Add the real "vid_pll" clock which selects between "vid_pll_pre_div",
"vid_pll_post_div" and a third "vid_pll_pre_div_mult7_div2" (which is
"vid_pll_pre_div" divided by 3.5). The latter is not supported yet
because it's not used in Amlogic's 3.10 kernel. The "vid_pll" clock
rate can also be measured by clkmsr to check whether this
implementation is correct.
- Add "vid_pll_final_div" which is a post-divider for "vid_pll" and it's
used as input for "vclk" and "vclk2"
- Add the two symmetric "vclk" and "vclk" clock trees, each with a
divide-by-1, divide-by-2, divide-by-4, divide-by-6 and divide-by-12
clock and a divider for each clock.
- Add the "cts_enct", "cts_encp" and "hdmi_tx_pixel" clocks which each
have their own gate and can select between any of the five "vclk"
dividers.
- Add the "cts_encl" and "cts_vdac0" clocks which each have their own
gate and can select between any of the five "vclk2" dividers.
The "hdmi_sys" clock is a different than these video clocks. It takes
"xtal" as input (there are three more but unknown parents). Add this
clock as well as it's used by the HDMI controller. Amlogic's 3.10 kernel
always configures this as "xtal divided by 1", so we can ignore the
other parents for now.
This was tested on Meson8b and Meson8m2 boards by comparing the common
clock framework output with the clock measurer output. The following
video modes were first set in u-boot (by running "video dev open $mode")
before booting Linux:
4K2K30HZ (only supported by Meson8m2, not tested on Meson8b):
- vid_pll: 297000000Hz
- cts_encp: 297000000Hz
- hdmi_tx_pixel: 297000000Hz
1080P:
- vid_pll: 148500000Hz
- cts_encp: 148500000Hz
- hdmi_tx_pixel: 148500000Hz
720P:
- vid_pll: 148500000Hz
- cts_encp: 148500000Hz
- hdmi_tx_pixel: 74250000Hz
480P:
- vid_pll: 216000000Hz
- cts_encp: 54000000Hz
- hdmi_tx_pixel: 27000000Hz
Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
Link: https://lkml.kernel.org/r/20181202214220.7715-4-martin.blumenstingl@googlemail.com
2018-12-03 05:42:20 +08:00
|
|
|
static struct clk_regmap meson8b_hdmi_pll_lvds_out = {
|
2018-08-01 22:00:52 +08:00
|
|
|
.data = &(struct clk_regmap_div_data){
|
|
|
|
.offset = HHI_VID_PLL_CNTL,
|
|
|
|
.shift = 16,
|
|
|
|
.width = 2,
|
|
|
|
.flags = CLK_DIVIDER_POWER_OF_TWO,
|
|
|
|
},
|
|
|
|
.hw.init = &(struct clk_init_data){
|
clk: meson: meson8b: add the read-only video clock trees
Add all clocks to give us the final video clocks within the Meson8,
Meson8b and Meson8m2 SoCs. The final video clocks are:
- cts_enct
- cts_encl
- cts_encp
- cts_enci
- cts_vdac0
- hdmi_tx_pixel
- hdmi_sys
Add multiple clocks in between which are needed to implement these
clocks:
- Opposed to GXBB there is no pre-multiplier for the PLL input. The
assumption here is that the multiplier is required to achieve the HDMI
2.0 clock rates (which are up to twice the rate of the HDMI 1.4
rates).
- The main PLL is called "HDMI PLL" or "HPLL" in the datasheet. Rename
our existing "vid_pll_dco" to "hdmi_pll_dco". The actual VID_PLL clock
also exists further down the tree.
- Rename the existing "vid_pll" clock (which is the OD divider at
HHI_VID_PLL_CNTL[17:16]) to "hdmi_pll_lvds_out" to match the naming
from the datasheet.
- Add the second OD divider called "hdmi_pll_hdmi_out" at
HHI_VID_PLL_CNTL[19:18].
- Add the "vid_pll_in_sel" which can choose between "hdmi_pll_dco" and
another parent. However, the second parent is not use on Amlogic's
3.10 kernel for HDMI or CVBS output so just leave a TODO in the code.
- Add the "vid_pll_in_en" which is located after "vid_pll_in_sel"
according to the datasheet.
- Add "vid_pll_pre_div" which is used for divide-by-5 and divide-by-6 in
Amlogic's 3.10 kernel sources.
- Add "vid_pll_post_div" which divides the output of "vid_pll_pre_div"
further down. The Amlogic 3.10 kernel configures this as divide-by-2
with "vid_pll_pre_div" being configured as divide-by-5 to achieve a
total divider of 10.
- Add the real "vid_pll" clock which selects between "vid_pll_pre_div",
"vid_pll_post_div" and a third "vid_pll_pre_div_mult7_div2" (which is
"vid_pll_pre_div" divided by 3.5). The latter is not supported yet
because it's not used in Amlogic's 3.10 kernel. The "vid_pll" clock
rate can also be measured by clkmsr to check whether this
implementation is correct.
- Add "vid_pll_final_div" which is a post-divider for "vid_pll" and it's
used as input for "vclk" and "vclk2"
- Add the two symmetric "vclk" and "vclk" clock trees, each with a
divide-by-1, divide-by-2, divide-by-4, divide-by-6 and divide-by-12
clock and a divider for each clock.
- Add the "cts_enct", "cts_encp" and "hdmi_tx_pixel" clocks which each
have their own gate and can select between any of the five "vclk"
dividers.
- Add the "cts_encl" and "cts_vdac0" clocks which each have their own
gate and can select between any of the five "vclk2" dividers.
The "hdmi_sys" clock is a different than these video clocks. It takes
"xtal" as input (there are three more but unknown parents). Add this
clock as well as it's used by the HDMI controller. Amlogic's 3.10 kernel
always configures this as "xtal divided by 1", so we can ignore the
other parents for now.
This was tested on Meson8b and Meson8m2 boards by comparing the common
clock framework output with the clock measurer output. The following
video modes were first set in u-boot (by running "video dev open $mode")
before booting Linux:
4K2K30HZ (only supported by Meson8m2, not tested on Meson8b):
- vid_pll: 297000000Hz
- cts_encp: 297000000Hz
- hdmi_tx_pixel: 297000000Hz
1080P:
- vid_pll: 148500000Hz
- cts_encp: 148500000Hz
- hdmi_tx_pixel: 148500000Hz
720P:
- vid_pll: 148500000Hz
- cts_encp: 148500000Hz
- hdmi_tx_pixel: 74250000Hz
480P:
- vid_pll: 216000000Hz
- cts_encp: 54000000Hz
- hdmi_tx_pixel: 27000000Hz
Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
Link: https://lkml.kernel.org/r/20181202214220.7715-4-martin.blumenstingl@googlemail.com
2018-12-03 05:42:20 +08:00
|
|
|
.name = "hdmi_pll_lvds_out",
|
|
|
|
.ops = &clk_regmap_divider_ro_ops,
|
|
|
|
.parent_names = (const char *[]){ "hdmi_pll_dco" },
|
|
|
|
.num_parents = 1,
|
|
|
|
.flags = CLK_SET_RATE_PARENT,
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
|
|
|
static struct clk_regmap meson8b_hdmi_pll_hdmi_out = {
|
|
|
|
.data = &(struct clk_regmap_div_data){
|
|
|
|
.offset = HHI_VID_PLL_CNTL,
|
|
|
|
.shift = 18,
|
|
|
|
.width = 2,
|
|
|
|
.flags = CLK_DIVIDER_POWER_OF_TWO,
|
|
|
|
},
|
|
|
|
.hw.init = &(struct clk_init_data){
|
|
|
|
.name = "hdmi_pll_hdmi_out",
|
2018-08-01 22:00:52 +08:00
|
|
|
.ops = &clk_regmap_divider_ro_ops,
|
clk: meson: meson8b: add the read-only video clock trees
Add all clocks to give us the final video clocks within the Meson8,
Meson8b and Meson8m2 SoCs. The final video clocks are:
- cts_enct
- cts_encl
- cts_encp
- cts_enci
- cts_vdac0
- hdmi_tx_pixel
- hdmi_sys
Add multiple clocks in between which are needed to implement these
clocks:
- Opposed to GXBB there is no pre-multiplier for the PLL input. The
assumption here is that the multiplier is required to achieve the HDMI
2.0 clock rates (which are up to twice the rate of the HDMI 1.4
rates).
- The main PLL is called "HDMI PLL" or "HPLL" in the datasheet. Rename
our existing "vid_pll_dco" to "hdmi_pll_dco". The actual VID_PLL clock
also exists further down the tree.
- Rename the existing "vid_pll" clock (which is the OD divider at
HHI_VID_PLL_CNTL[17:16]) to "hdmi_pll_lvds_out" to match the naming
from the datasheet.
- Add the second OD divider called "hdmi_pll_hdmi_out" at
HHI_VID_PLL_CNTL[19:18].
- Add the "vid_pll_in_sel" which can choose between "hdmi_pll_dco" and
another parent. However, the second parent is not use on Amlogic's
3.10 kernel for HDMI or CVBS output so just leave a TODO in the code.
- Add the "vid_pll_in_en" which is located after "vid_pll_in_sel"
according to the datasheet.
- Add "vid_pll_pre_div" which is used for divide-by-5 and divide-by-6 in
Amlogic's 3.10 kernel sources.
- Add "vid_pll_post_div" which divides the output of "vid_pll_pre_div"
further down. The Amlogic 3.10 kernel configures this as divide-by-2
with "vid_pll_pre_div" being configured as divide-by-5 to achieve a
total divider of 10.
- Add the real "vid_pll" clock which selects between "vid_pll_pre_div",
"vid_pll_post_div" and a third "vid_pll_pre_div_mult7_div2" (which is
"vid_pll_pre_div" divided by 3.5). The latter is not supported yet
because it's not used in Amlogic's 3.10 kernel. The "vid_pll" clock
rate can also be measured by clkmsr to check whether this
implementation is correct.
- Add "vid_pll_final_div" which is a post-divider for "vid_pll" and it's
used as input for "vclk" and "vclk2"
- Add the two symmetric "vclk" and "vclk" clock trees, each with a
divide-by-1, divide-by-2, divide-by-4, divide-by-6 and divide-by-12
clock and a divider for each clock.
- Add the "cts_enct", "cts_encp" and "hdmi_tx_pixel" clocks which each
have their own gate and can select between any of the five "vclk"
dividers.
- Add the "cts_encl" and "cts_vdac0" clocks which each have their own
gate and can select between any of the five "vclk2" dividers.
The "hdmi_sys" clock is a different than these video clocks. It takes
"xtal" as input (there are three more but unknown parents). Add this
clock as well as it's used by the HDMI controller. Amlogic's 3.10 kernel
always configures this as "xtal divided by 1", so we can ignore the
other parents for now.
This was tested on Meson8b and Meson8m2 boards by comparing the common
clock framework output with the clock measurer output. The following
video modes were first set in u-boot (by running "video dev open $mode")
before booting Linux:
4K2K30HZ (only supported by Meson8m2, not tested on Meson8b):
- vid_pll: 297000000Hz
- cts_encp: 297000000Hz
- hdmi_tx_pixel: 297000000Hz
1080P:
- vid_pll: 148500000Hz
- cts_encp: 148500000Hz
- hdmi_tx_pixel: 148500000Hz
720P:
- vid_pll: 148500000Hz
- cts_encp: 148500000Hz
- hdmi_tx_pixel: 74250000Hz
480P:
- vid_pll: 216000000Hz
- cts_encp: 54000000Hz
- hdmi_tx_pixel: 27000000Hz
Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
Link: https://lkml.kernel.org/r/20181202214220.7715-4-martin.blumenstingl@googlemail.com
2018-12-03 05:42:20 +08:00
|
|
|
.parent_names = (const char *[]){ "hdmi_pll_dco" },
|
2018-08-01 22:00:52 +08:00
|
|
|
.num_parents = 1,
|
|
|
|
.flags = CLK_SET_RATE_PARENT,
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
|
|
|
static struct clk_regmap meson8b_sys_pll_dco = {
|
2018-02-12 22:58:42 +08:00
|
|
|
.data = &(struct meson_clk_pll_data){
|
2018-08-01 22:00:50 +08:00
|
|
|
.en = {
|
|
|
|
.reg_off = HHI_SYS_PLL_CNTL,
|
|
|
|
.shift = 30,
|
|
|
|
.width = 1,
|
|
|
|
},
|
2018-02-12 22:58:42 +08:00
|
|
|
.m = {
|
|
|
|
.reg_off = HHI_SYS_PLL_CNTL,
|
|
|
|
.shift = 0,
|
|
|
|
.width = 9,
|
|
|
|
},
|
|
|
|
.n = {
|
|
|
|
.reg_off = HHI_SYS_PLL_CNTL,
|
|
|
|
.shift = 9,
|
|
|
|
.width = 5,
|
|
|
|
},
|
|
|
|
.l = {
|
|
|
|
.reg_off = HHI_SYS_PLL_CNTL,
|
|
|
|
.shift = 31,
|
|
|
|
.width = 1,
|
|
|
|
},
|
|
|
|
.rst = {
|
|
|
|
.reg_off = HHI_SYS_PLL_CNTL,
|
|
|
|
.shift = 29,
|
|
|
|
.width = 1,
|
|
|
|
},
|
2018-08-01 22:00:53 +08:00
|
|
|
.table = sys_pll_params_table,
|
2018-02-12 22:58:42 +08:00
|
|
|
},
|
2016-04-29 03:01:42 +08:00
|
|
|
.hw.init = &(struct clk_init_data){
|
2018-08-01 22:00:52 +08:00
|
|
|
.name = "sys_pll_dco",
|
2018-11-16 06:40:48 +08:00
|
|
|
.ops = &meson_clk_pll_ops,
|
2016-04-29 03:01:42 +08:00
|
|
|
.parent_names = (const char *[]){ "xtal" },
|
|
|
|
.num_parents = 1,
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
2018-08-01 22:00:52 +08:00
|
|
|
static struct clk_regmap meson8b_sys_pll = {
|
|
|
|
.data = &(struct clk_regmap_div_data){
|
|
|
|
.offset = HHI_SYS_PLL_CNTL,
|
|
|
|
.shift = 16,
|
|
|
|
.width = 2,
|
|
|
|
.flags = CLK_DIVIDER_POWER_OF_TWO,
|
|
|
|
},
|
|
|
|
.hw.init = &(struct clk_init_data){
|
|
|
|
.name = "sys_pll",
|
2018-11-16 06:40:48 +08:00
|
|
|
.ops = &clk_regmap_divider_ops,
|
2018-08-01 22:00:52 +08:00
|
|
|
.parent_names = (const char *[]){ "sys_pll_dco" },
|
|
|
|
.num_parents = 1,
|
|
|
|
.flags = CLK_SET_RATE_PARENT,
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
2018-02-19 19:21:45 +08:00
|
|
|
static struct clk_fixed_factor meson8b_fclk_div2_div = {
|
2016-04-29 03:01:58 +08:00
|
|
|
.mult = 1,
|
|
|
|
.div = 2,
|
|
|
|
.hw.init = &(struct clk_init_data){
|
2018-02-19 19:21:45 +08:00
|
|
|
.name = "fclk_div2_div",
|
2016-04-29 03:01:58 +08:00
|
|
|
.ops = &clk_fixed_factor_ops,
|
|
|
|
.parent_names = (const char *[]){ "fixed_pll" },
|
|
|
|
.num_parents = 1,
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
2018-02-19 19:21:45 +08:00
|
|
|
static struct clk_regmap meson8b_fclk_div2 = {
|
|
|
|
.data = &(struct clk_regmap_gate_data){
|
|
|
|
.offset = HHI_MPLL_CNTL6,
|
|
|
|
.bit_idx = 27,
|
|
|
|
},
|
|
|
|
.hw.init = &(struct clk_init_data){
|
|
|
|
.name = "fclk_div2",
|
|
|
|
.ops = &clk_regmap_gate_ops,
|
|
|
|
.parent_names = (const char *[]){ "fclk_div2_div" },
|
|
|
|
.num_parents = 1,
|
2018-05-21 01:16:06 +08:00
|
|
|
/*
|
|
|
|
* FIXME: Ethernet with a RGMII PHYs is not working if
|
|
|
|
* fclk_div2 is disabled. it is currently unclear why this
|
|
|
|
* is. keep it enabled until the Ethernet driver knows how
|
|
|
|
* to manage this clock.
|
|
|
|
*/
|
|
|
|
.flags = CLK_IS_CRITICAL,
|
2018-02-19 19:21:45 +08:00
|
|
|
},
|
|
|
|
};
|
|
|
|
|
|
|
|
static struct clk_fixed_factor meson8b_fclk_div3_div = {
|
2016-04-29 03:01:58 +08:00
|
|
|
.mult = 1,
|
|
|
|
.div = 3,
|
|
|
|
.hw.init = &(struct clk_init_data){
|
2018-04-22 18:28:43 +08:00
|
|
|
.name = "fclk_div3_div",
|
2016-04-29 03:01:58 +08:00
|
|
|
.ops = &clk_fixed_factor_ops,
|
|
|
|
.parent_names = (const char *[]){ "fixed_pll" },
|
|
|
|
.num_parents = 1,
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
2018-02-19 19:21:45 +08:00
|
|
|
static struct clk_regmap meson8b_fclk_div3 = {
|
|
|
|
.data = &(struct clk_regmap_gate_data){
|
|
|
|
.offset = HHI_MPLL_CNTL6,
|
|
|
|
.bit_idx = 28,
|
|
|
|
},
|
|
|
|
.hw.init = &(struct clk_init_data){
|
|
|
|
.name = "fclk_div3",
|
|
|
|
.ops = &clk_regmap_gate_ops,
|
|
|
|
.parent_names = (const char *[]){ "fclk_div3_div" },
|
|
|
|
.num_parents = 1,
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
|
|
|
static struct clk_fixed_factor meson8b_fclk_div4_div = {
|
2016-04-29 03:01:58 +08:00
|
|
|
.mult = 1,
|
|
|
|
.div = 4,
|
|
|
|
.hw.init = &(struct clk_init_data){
|
2018-02-19 19:21:45 +08:00
|
|
|
.name = "fclk_div4_div",
|
2016-04-29 03:01:58 +08:00
|
|
|
.ops = &clk_fixed_factor_ops,
|
|
|
|
.parent_names = (const char *[]){ "fixed_pll" },
|
|
|
|
.num_parents = 1,
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
2018-02-19 19:21:45 +08:00
|
|
|
static struct clk_regmap meson8b_fclk_div4 = {
|
|
|
|
.data = &(struct clk_regmap_gate_data){
|
|
|
|
.offset = HHI_MPLL_CNTL6,
|
|
|
|
.bit_idx = 29,
|
|
|
|
},
|
|
|
|
.hw.init = &(struct clk_init_data){
|
|
|
|
.name = "fclk_div4",
|
|
|
|
.ops = &clk_regmap_gate_ops,
|
|
|
|
.parent_names = (const char *[]){ "fclk_div4_div" },
|
|
|
|
.num_parents = 1,
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
|
|
|
static struct clk_fixed_factor meson8b_fclk_div5_div = {
|
2016-04-29 03:01:58 +08:00
|
|
|
.mult = 1,
|
|
|
|
.div = 5,
|
|
|
|
.hw.init = &(struct clk_init_data){
|
2018-02-19 19:21:45 +08:00
|
|
|
.name = "fclk_div5_div",
|
2016-04-29 03:01:58 +08:00
|
|
|
.ops = &clk_fixed_factor_ops,
|
|
|
|
.parent_names = (const char *[]){ "fixed_pll" },
|
|
|
|
.num_parents = 1,
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
2018-02-19 19:21:45 +08:00
|
|
|
static struct clk_regmap meson8b_fclk_div5 = {
|
|
|
|
.data = &(struct clk_regmap_gate_data){
|
|
|
|
.offset = HHI_MPLL_CNTL6,
|
|
|
|
.bit_idx = 30,
|
|
|
|
},
|
|
|
|
.hw.init = &(struct clk_init_data){
|
|
|
|
.name = "fclk_div5",
|
|
|
|
.ops = &clk_regmap_gate_ops,
|
|
|
|
.parent_names = (const char *[]){ "fclk_div5_div" },
|
|
|
|
.num_parents = 1,
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
|
|
|
static struct clk_fixed_factor meson8b_fclk_div7_div = {
|
2016-04-29 03:01:58 +08:00
|
|
|
.mult = 1,
|
|
|
|
.div = 7,
|
|
|
|
.hw.init = &(struct clk_init_data){
|
2018-02-19 19:21:45 +08:00
|
|
|
.name = "fclk_div7_div",
|
2016-04-29 03:01:58 +08:00
|
|
|
.ops = &clk_fixed_factor_ops,
|
|
|
|
.parent_names = (const char *[]){ "fixed_pll" },
|
|
|
|
.num_parents = 1,
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
2018-02-19 19:21:45 +08:00
|
|
|
static struct clk_regmap meson8b_fclk_div7 = {
|
|
|
|
.data = &(struct clk_regmap_gate_data){
|
|
|
|
.offset = HHI_MPLL_CNTL6,
|
|
|
|
.bit_idx = 31,
|
|
|
|
},
|
|
|
|
.hw.init = &(struct clk_init_data){
|
|
|
|
.name = "fclk_div7",
|
|
|
|
.ops = &clk_regmap_gate_ops,
|
|
|
|
.parent_names = (const char *[]){ "fclk_div7_div" },
|
|
|
|
.num_parents = 1,
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
2018-02-19 19:21:44 +08:00
|
|
|
static struct clk_regmap meson8b_mpll_prediv = {
|
|
|
|
.data = &(struct clk_regmap_div_data){
|
|
|
|
.offset = HHI_MPLL_CNTL5,
|
|
|
|
.shift = 12,
|
|
|
|
.width = 1,
|
|
|
|
},
|
|
|
|
.hw.init = &(struct clk_init_data){
|
|
|
|
.name = "mpll_prediv",
|
|
|
|
.ops = &clk_regmap_divider_ro_ops,
|
|
|
|
.parent_names = (const char *[]){ "fixed_pll" },
|
|
|
|
.num_parents = 1,
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
2018-02-12 22:58:43 +08:00
|
|
|
static struct clk_regmap meson8b_mpll0_div = {
|
2018-02-12 22:58:40 +08:00
|
|
|
.data = &(struct meson_clk_mpll_data){
|
|
|
|
.sdm = {
|
|
|
|
.reg_off = HHI_MPLL_CNTL7,
|
|
|
|
.shift = 0,
|
|
|
|
.width = 14,
|
|
|
|
},
|
|
|
|
.sdm_en = {
|
|
|
|
.reg_off = HHI_MPLL_CNTL7,
|
|
|
|
.shift = 15,
|
|
|
|
.width = 1,
|
|
|
|
},
|
|
|
|
.n2 = {
|
|
|
|
.reg_off = HHI_MPLL_CNTL7,
|
|
|
|
.shift = 16,
|
|
|
|
.width = 9,
|
|
|
|
},
|
|
|
|
.ssen = {
|
|
|
|
.reg_off = HHI_MPLL_CNTL,
|
|
|
|
.shift = 25,
|
|
|
|
.width = 1,
|
|
|
|
},
|
|
|
|
.lock = &meson_clk_lock,
|
2017-07-29 00:32:28 +08:00
|
|
|
},
|
2017-03-09 18:41:52 +08:00
|
|
|
.hw.init = &(struct clk_init_data){
|
2018-02-12 22:58:43 +08:00
|
|
|
.name = "mpll0_div",
|
2017-03-09 18:41:52 +08:00
|
|
|
.ops = &meson_clk_mpll_ops,
|
2018-02-19 19:21:44 +08:00
|
|
|
.parent_names = (const char *[]){ "mpll_prediv" },
|
2017-03-09 18:41:52 +08:00
|
|
|
.num_parents = 1,
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
2018-02-12 22:58:43 +08:00
|
|
|
static struct clk_regmap meson8b_mpll0 = {
|
|
|
|
.data = &(struct clk_regmap_gate_data){
|
|
|
|
.offset = HHI_MPLL_CNTL7,
|
|
|
|
.bit_idx = 14,
|
|
|
|
},
|
|
|
|
.hw.init = &(struct clk_init_data){
|
|
|
|
.name = "mpll0",
|
|
|
|
.ops = &clk_regmap_gate_ops,
|
|
|
|
.parent_names = (const char *[]){ "mpll0_div" },
|
|
|
|
.num_parents = 1,
|
|
|
|
.flags = CLK_SET_RATE_PARENT,
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
|
|
|
static struct clk_regmap meson8b_mpll1_div = {
|
2018-02-12 22:58:40 +08:00
|
|
|
.data = &(struct meson_clk_mpll_data){
|
|
|
|
.sdm = {
|
|
|
|
.reg_off = HHI_MPLL_CNTL8,
|
|
|
|
.shift = 0,
|
|
|
|
.width = 14,
|
|
|
|
},
|
|
|
|
.sdm_en = {
|
|
|
|
.reg_off = HHI_MPLL_CNTL8,
|
|
|
|
.shift = 15,
|
|
|
|
.width = 1,
|
|
|
|
},
|
|
|
|
.n2 = {
|
|
|
|
.reg_off = HHI_MPLL_CNTL8,
|
|
|
|
.shift = 16,
|
|
|
|
.width = 9,
|
|
|
|
},
|
|
|
|
.lock = &meson_clk_lock,
|
2017-03-09 18:41:52 +08:00
|
|
|
},
|
|
|
|
.hw.init = &(struct clk_init_data){
|
2018-02-12 22:58:43 +08:00
|
|
|
.name = "mpll1_div",
|
2017-03-09 18:41:52 +08:00
|
|
|
.ops = &meson_clk_mpll_ops,
|
2018-02-19 19:21:44 +08:00
|
|
|
.parent_names = (const char *[]){ "mpll_prediv" },
|
2017-03-09 18:41:52 +08:00
|
|
|
.num_parents = 1,
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
2018-02-12 22:58:43 +08:00
|
|
|
static struct clk_regmap meson8b_mpll1 = {
|
|
|
|
.data = &(struct clk_regmap_gate_data){
|
|
|
|
.offset = HHI_MPLL_CNTL8,
|
|
|
|
.bit_idx = 14,
|
|
|
|
},
|
|
|
|
.hw.init = &(struct clk_init_data){
|
|
|
|
.name = "mpll1",
|
|
|
|
.ops = &clk_regmap_gate_ops,
|
|
|
|
.parent_names = (const char *[]){ "mpll1_div" },
|
|
|
|
.num_parents = 1,
|
|
|
|
.flags = CLK_SET_RATE_PARENT,
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
|
|
|
static struct clk_regmap meson8b_mpll2_div = {
|
2018-02-12 22:58:40 +08:00
|
|
|
.data = &(struct meson_clk_mpll_data){
|
|
|
|
.sdm = {
|
|
|
|
.reg_off = HHI_MPLL_CNTL9,
|
|
|
|
.shift = 0,
|
|
|
|
.width = 14,
|
|
|
|
},
|
|
|
|
.sdm_en = {
|
|
|
|
.reg_off = HHI_MPLL_CNTL9,
|
|
|
|
.shift = 15,
|
|
|
|
.width = 1,
|
|
|
|
},
|
|
|
|
.n2 = {
|
|
|
|
.reg_off = HHI_MPLL_CNTL9,
|
|
|
|
.shift = 16,
|
|
|
|
.width = 9,
|
|
|
|
},
|
|
|
|
.lock = &meson_clk_lock,
|
2017-03-09 18:41:52 +08:00
|
|
|
},
|
|
|
|
.hw.init = &(struct clk_init_data){
|
2018-02-12 22:58:43 +08:00
|
|
|
.name = "mpll2_div",
|
2017-03-09 18:41:52 +08:00
|
|
|
.ops = &meson_clk_mpll_ops,
|
2018-02-19 19:21:44 +08:00
|
|
|
.parent_names = (const char *[]){ "mpll_prediv" },
|
2017-03-09 18:41:52 +08:00
|
|
|
.num_parents = 1,
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
2018-02-12 22:58:43 +08:00
|
|
|
static struct clk_regmap meson8b_mpll2 = {
|
|
|
|
.data = &(struct clk_regmap_gate_data){
|
|
|
|
.offset = HHI_MPLL_CNTL9,
|
|
|
|
.bit_idx = 14,
|
|
|
|
},
|
|
|
|
.hw.init = &(struct clk_init_data){
|
|
|
|
.name = "mpll2",
|
|
|
|
.ops = &clk_regmap_gate_ops,
|
|
|
|
.parent_names = (const char *[]){ "mpll2_div" },
|
|
|
|
.num_parents = 1,
|
|
|
|
.flags = CLK_SET_RATE_PARENT,
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
2016-04-29 03:01:51 +08:00
|
|
|
static u32 mux_table_clk81[] = { 6, 5, 7 };
|
2018-02-12 22:58:38 +08:00
|
|
|
static struct clk_regmap meson8b_mpeg_clk_sel = {
|
|
|
|
.data = &(struct clk_regmap_mux_data){
|
|
|
|
.offset = HHI_MPEG_CLK_CNTL,
|
|
|
|
.mask = 0x7,
|
|
|
|
.shift = 12,
|
|
|
|
.table = mux_table_clk81,
|
|
|
|
},
|
2016-04-29 03:01:51 +08:00
|
|
|
.hw.init = &(struct clk_init_data){
|
|
|
|
.name = "mpeg_clk_sel",
|
2018-02-12 22:58:38 +08:00
|
|
|
.ops = &clk_regmap_mux_ro_ops,
|
2016-04-29 03:01:51 +08:00
|
|
|
/*
|
|
|
|
* FIXME bits 14:12 selects from 8 possible parents:
|
|
|
|
* xtal, 1'b0 (wtf), fclk_div7, mpll_clkout1, mpll_clkout2,
|
|
|
|
* fclk_div4, fclk_div3, fclk_div5
|
|
|
|
*/
|
|
|
|
.parent_names = (const char *[]){ "fclk_div3", "fclk_div4",
|
|
|
|
"fclk_div5" },
|
|
|
|
.num_parents = 3,
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
2018-03-15 06:36:31 +08:00
|
|
|
static struct clk_regmap meson8b_mpeg_clk_div = {
|
2018-02-12 22:58:37 +08:00
|
|
|
.data = &(struct clk_regmap_div_data){
|
|
|
|
.offset = HHI_MPEG_CLK_CNTL,
|
|
|
|
.shift = 0,
|
|
|
|
.width = 7,
|
|
|
|
},
|
2016-04-29 03:01:51 +08:00
|
|
|
.hw.init = &(struct clk_init_data){
|
|
|
|
.name = "mpeg_clk_div",
|
2018-02-19 19:21:46 +08:00
|
|
|
.ops = &clk_regmap_divider_ro_ops,
|
2016-04-29 03:01:51 +08:00
|
|
|
.parent_names = (const char *[]){ "mpeg_clk_sel" },
|
|
|
|
.num_parents = 1,
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
2018-03-15 06:36:31 +08:00
|
|
|
static struct clk_regmap meson8b_clk81 = {
|
2018-02-12 22:58:36 +08:00
|
|
|
.data = &(struct clk_regmap_gate_data){
|
|
|
|
.offset = HHI_MPEG_CLK_CNTL,
|
|
|
|
.bit_idx = 7,
|
|
|
|
},
|
2016-04-29 03:01:51 +08:00
|
|
|
.hw.init = &(struct clk_init_data){
|
|
|
|
.name = "clk81",
|
2018-02-12 22:58:36 +08:00
|
|
|
.ops = &clk_regmap_gate_ops,
|
2016-04-29 03:01:51 +08:00
|
|
|
.parent_names = (const char *[]){ "mpeg_clk_div" },
|
|
|
|
.num_parents = 1,
|
2018-02-19 19:21:46 +08:00
|
|
|
.flags = CLK_IS_CRITICAL,
|
2016-04-29 03:01:51 +08:00
|
|
|
},
|
2015-06-01 19:13:55 +08:00
|
|
|
};
|
|
|
|
|
2018-03-15 06:36:31 +08:00
|
|
|
static struct clk_regmap meson8b_cpu_in_sel = {
|
2018-02-12 22:58:44 +08:00
|
|
|
.data = &(struct clk_regmap_mux_data){
|
|
|
|
.offset = HHI_SYS_CPU_CLK_CNTL0,
|
|
|
|
.mask = 0x1,
|
|
|
|
.shift = 0,
|
|
|
|
},
|
|
|
|
.hw.init = &(struct clk_init_data){
|
|
|
|
.name = "cpu_in_sel",
|
2018-11-16 06:40:48 +08:00
|
|
|
.ops = &clk_regmap_mux_ops,
|
2018-02-12 22:58:44 +08:00
|
|
|
.parent_names = (const char *[]){ "xtal", "sys_pll" },
|
|
|
|
.num_parents = 2,
|
|
|
|
.flags = (CLK_SET_RATE_PARENT |
|
|
|
|
CLK_SET_RATE_NO_REPARENT),
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
2018-11-23 05:40:16 +08:00
|
|
|
static struct clk_fixed_factor meson8b_cpu_in_div2 = {
|
2018-02-12 22:58:44 +08:00
|
|
|
.mult = 1,
|
|
|
|
.div = 2,
|
|
|
|
.hw.init = &(struct clk_init_data){
|
2018-11-23 05:40:16 +08:00
|
|
|
.name = "cpu_in_div2",
|
2018-02-12 22:58:44 +08:00
|
|
|
.ops = &clk_fixed_factor_ops,
|
|
|
|
.parent_names = (const char *[]){ "cpu_in_sel" },
|
|
|
|
.num_parents = 1,
|
|
|
|
.flags = CLK_SET_RATE_PARENT,
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
2018-11-23 05:40:16 +08:00
|
|
|
static struct clk_fixed_factor meson8b_cpu_in_div3 = {
|
2018-02-12 22:58:44 +08:00
|
|
|
.mult = 1,
|
|
|
|
.div = 3,
|
|
|
|
.hw.init = &(struct clk_init_data){
|
2018-11-23 05:40:16 +08:00
|
|
|
.name = "cpu_in_div3",
|
2018-02-12 22:58:44 +08:00
|
|
|
.ops = &clk_fixed_factor_ops,
|
|
|
|
.parent_names = (const char *[]){ "cpu_in_sel" },
|
|
|
|
.num_parents = 1,
|
|
|
|
.flags = CLK_SET_RATE_PARENT,
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
|
|
|
static const struct clk_div_table cpu_scale_table[] = {
|
2018-09-27 16:59:20 +08:00
|
|
|
{ .val = 1, .div = 4 },
|
|
|
|
{ .val = 2, .div = 6 },
|
|
|
|
{ .val = 3, .div = 8 },
|
|
|
|
{ .val = 4, .div = 10 },
|
|
|
|
{ .val = 5, .div = 12 },
|
|
|
|
{ .val = 6, .div = 14 },
|
|
|
|
{ .val = 7, .div = 16 },
|
|
|
|
{ .val = 8, .div = 18 },
|
2018-02-12 22:58:44 +08:00
|
|
|
{ /* sentinel */ },
|
|
|
|
};
|
|
|
|
|
2018-03-15 06:36:31 +08:00
|
|
|
static struct clk_regmap meson8b_cpu_scale_div = {
|
2018-02-12 22:58:44 +08:00
|
|
|
.data = &(struct clk_regmap_div_data){
|
|
|
|
.offset = HHI_SYS_CPU_CLK_CNTL1,
|
|
|
|
.shift = 20,
|
2018-09-27 16:59:21 +08:00
|
|
|
.width = 10,
|
2018-02-12 22:58:44 +08:00
|
|
|
.table = cpu_scale_table,
|
|
|
|
.flags = CLK_DIVIDER_ALLOW_ZERO,
|
|
|
|
},
|
|
|
|
.hw.init = &(struct clk_init_data){
|
|
|
|
.name = "cpu_scale_div",
|
2018-11-16 06:40:48 +08:00
|
|
|
.ops = &clk_regmap_divider_ops,
|
2018-02-12 22:58:44 +08:00
|
|
|
.parent_names = (const char *[]){ "cpu_in_sel" },
|
|
|
|
.num_parents = 1,
|
|
|
|
.flags = CLK_SET_RATE_PARENT,
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
2018-11-16 06:40:44 +08:00
|
|
|
static u32 mux_table_cpu_scale_out_sel[] = { 0, 1, 3 };
|
2018-03-15 06:36:31 +08:00
|
|
|
static struct clk_regmap meson8b_cpu_scale_out_sel = {
|
2018-02-12 22:58:44 +08:00
|
|
|
.data = &(struct clk_regmap_mux_data){
|
|
|
|
.offset = HHI_SYS_CPU_CLK_CNTL0,
|
|
|
|
.mask = 0x3,
|
|
|
|
.shift = 2,
|
2018-11-16 06:40:44 +08:00
|
|
|
.table = mux_table_cpu_scale_out_sel,
|
2018-02-12 22:58:44 +08:00
|
|
|
},
|
|
|
|
.hw.init = &(struct clk_init_data){
|
|
|
|
.name = "cpu_scale_out_sel",
|
2018-11-16 06:40:48 +08:00
|
|
|
.ops = &clk_regmap_mux_ops,
|
2018-11-16 06:40:44 +08:00
|
|
|
/*
|
|
|
|
* NOTE: We are skipping the parent with value 0x2 (which is
|
2018-11-23 05:40:16 +08:00
|
|
|
* "cpu_in_div3") because it results in a duty cycle of 33%
|
|
|
|
* which makes the system unstable and can result in a lockup
|
|
|
|
* of the whole system.
|
2018-11-16 06:40:44 +08:00
|
|
|
*/
|
2018-02-12 22:58:44 +08:00
|
|
|
.parent_names = (const char *[]) { "cpu_in_sel",
|
2018-11-23 05:40:16 +08:00
|
|
|
"cpu_in_div2",
|
2018-02-12 22:58:44 +08:00
|
|
|
"cpu_scale_div" },
|
2018-11-16 06:40:44 +08:00
|
|
|
.num_parents = 3,
|
2018-02-12 22:58:44 +08:00
|
|
|
.flags = CLK_SET_RATE_PARENT,
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
2018-03-15 06:36:31 +08:00
|
|
|
static struct clk_regmap meson8b_cpu_clk = {
|
2018-02-12 22:58:44 +08:00
|
|
|
.data = &(struct clk_regmap_mux_data){
|
|
|
|
.offset = HHI_SYS_CPU_CLK_CNTL0,
|
|
|
|
.mask = 0x1,
|
|
|
|
.shift = 7,
|
|
|
|
},
|
|
|
|
.hw.init = &(struct clk_init_data){
|
|
|
|
.name = "cpu_clk",
|
2018-11-16 06:40:48 +08:00
|
|
|
.ops = &clk_regmap_mux_ops,
|
2018-04-24 03:30:29 +08:00
|
|
|
.parent_names = (const char *[]){ "xtal",
|
|
|
|
"cpu_scale_out_sel" },
|
2018-02-12 22:58:44 +08:00
|
|
|
.num_parents = 2,
|
|
|
|
.flags = (CLK_SET_RATE_PARENT |
|
2018-11-16 06:40:45 +08:00
|
|
|
CLK_SET_RATE_NO_REPARENT |
|
|
|
|
CLK_IS_CRITICAL),
|
2018-02-12 22:58:44 +08:00
|
|
|
},
|
|
|
|
};
|
|
|
|
|
2018-04-24 03:35:09 +08:00
|
|
|
static struct clk_regmap meson8b_nand_clk_sel = {
|
|
|
|
.data = &(struct clk_regmap_mux_data){
|
|
|
|
.offset = HHI_NAND_CLK_CNTL,
|
|
|
|
.mask = 0x7,
|
|
|
|
.shift = 9,
|
|
|
|
.flags = CLK_MUX_ROUND_CLOSEST,
|
|
|
|
},
|
|
|
|
.hw.init = &(struct clk_init_data){
|
|
|
|
.name = "nand_clk_sel",
|
|
|
|
.ops = &clk_regmap_mux_ops,
|
|
|
|
/* FIXME all other parents are unknown: */
|
|
|
|
.parent_names = (const char *[]){ "fclk_div4", "fclk_div3",
|
|
|
|
"fclk_div5", "fclk_div7", "xtal" },
|
|
|
|
.num_parents = 5,
|
|
|
|
.flags = CLK_SET_RATE_PARENT,
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
|
|
|
static struct clk_regmap meson8b_nand_clk_div = {
|
|
|
|
.data = &(struct clk_regmap_div_data){
|
|
|
|
.offset = HHI_NAND_CLK_CNTL,
|
|
|
|
.shift = 0,
|
|
|
|
.width = 7,
|
|
|
|
.flags = CLK_DIVIDER_ROUND_CLOSEST,
|
|
|
|
},
|
|
|
|
.hw.init = &(struct clk_init_data){
|
|
|
|
.name = "nand_clk_div",
|
|
|
|
.ops = &clk_regmap_divider_ops,
|
|
|
|
.parent_names = (const char *[]){ "nand_clk_sel" },
|
|
|
|
.num_parents = 1,
|
|
|
|
.flags = CLK_SET_RATE_PARENT,
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
|
|
|
static struct clk_regmap meson8b_nand_clk_gate = {
|
|
|
|
.data = &(struct clk_regmap_gate_data){
|
|
|
|
.offset = HHI_NAND_CLK_CNTL,
|
|
|
|
.bit_idx = 8,
|
|
|
|
},
|
|
|
|
.hw.init = &(struct clk_init_data){
|
|
|
|
.name = "nand_clk_gate",
|
|
|
|
.ops = &clk_regmap_gate_ops,
|
|
|
|
.parent_names = (const char *[]){ "nand_clk_div" },
|
|
|
|
.num_parents = 1,
|
|
|
|
.flags = CLK_SET_RATE_PARENT,
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
2018-11-23 05:40:17 +08:00
|
|
|
static struct clk_fixed_factor meson8b_cpu_clk_div2 = {
|
|
|
|
.mult = 1,
|
|
|
|
.div = 2,
|
|
|
|
.hw.init = &(struct clk_init_data){
|
|
|
|
.name = "cpu_clk_div2",
|
|
|
|
.ops = &clk_fixed_factor_ops,
|
|
|
|
.parent_names = (const char *[]){ "cpu_clk" },
|
|
|
|
.num_parents = 1,
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
|
|
|
static struct clk_fixed_factor meson8b_cpu_clk_div3 = {
|
|
|
|
.mult = 1,
|
|
|
|
.div = 3,
|
|
|
|
.hw.init = &(struct clk_init_data){
|
|
|
|
.name = "cpu_clk_div3",
|
|
|
|
.ops = &clk_fixed_factor_ops,
|
|
|
|
.parent_names = (const char *[]){ "cpu_clk" },
|
|
|
|
.num_parents = 1,
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
|
|
|
static struct clk_fixed_factor meson8b_cpu_clk_div4 = {
|
|
|
|
.mult = 1,
|
|
|
|
.div = 4,
|
|
|
|
.hw.init = &(struct clk_init_data){
|
|
|
|
.name = "cpu_clk_div4",
|
|
|
|
.ops = &clk_fixed_factor_ops,
|
|
|
|
.parent_names = (const char *[]){ "cpu_clk" },
|
|
|
|
.num_parents = 1,
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
|
|
|
static struct clk_fixed_factor meson8b_cpu_clk_div5 = {
|
|
|
|
.mult = 1,
|
|
|
|
.div = 5,
|
|
|
|
.hw.init = &(struct clk_init_data){
|
|
|
|
.name = "cpu_clk_div5",
|
|
|
|
.ops = &clk_fixed_factor_ops,
|
|
|
|
.parent_names = (const char *[]){ "cpu_clk" },
|
|
|
|
.num_parents = 1,
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
|
|
|
static struct clk_fixed_factor meson8b_cpu_clk_div6 = {
|
|
|
|
.mult = 1,
|
|
|
|
.div = 6,
|
|
|
|
.hw.init = &(struct clk_init_data){
|
|
|
|
.name = "cpu_clk_div6",
|
|
|
|
.ops = &clk_fixed_factor_ops,
|
|
|
|
.parent_names = (const char *[]){ "cpu_clk" },
|
|
|
|
.num_parents = 1,
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
|
|
|
static struct clk_fixed_factor meson8b_cpu_clk_div7 = {
|
|
|
|
.mult = 1,
|
|
|
|
.div = 7,
|
|
|
|
.hw.init = &(struct clk_init_data){
|
|
|
|
.name = "cpu_clk_div7",
|
|
|
|
.ops = &clk_fixed_factor_ops,
|
|
|
|
.parent_names = (const char *[]){ "cpu_clk" },
|
|
|
|
.num_parents = 1,
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
|
|
|
static struct clk_fixed_factor meson8b_cpu_clk_div8 = {
|
|
|
|
.mult = 1,
|
|
|
|
.div = 8,
|
|
|
|
.hw.init = &(struct clk_init_data){
|
|
|
|
.name = "cpu_clk_div8",
|
|
|
|
.ops = &clk_fixed_factor_ops,
|
|
|
|
.parent_names = (const char *[]){ "cpu_clk" },
|
|
|
|
.num_parents = 1,
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
2019-02-11 06:26:03 +08:00
|
|
|
static u32 mux_table_apb[] = { 1, 2, 3, 4, 5, 6, 7 };
|
|
|
|
static struct clk_regmap meson8b_apb_clk_sel = {
|
2018-11-23 05:40:17 +08:00
|
|
|
.data = &(struct clk_regmap_mux_data){
|
|
|
|
.offset = HHI_SYS_CPU_CLK_CNTL1,
|
|
|
|
.mask = 0x7,
|
|
|
|
.shift = 3,
|
2019-02-11 06:26:03 +08:00
|
|
|
.table = mux_table_apb,
|
2018-11-23 05:40:17 +08:00
|
|
|
},
|
|
|
|
.hw.init = &(struct clk_init_data){
|
2019-02-11 06:26:03 +08:00
|
|
|
.name = "apb_clk_sel",
|
2018-11-23 05:40:17 +08:00
|
|
|
.ops = &clk_regmap_mux_ops,
|
|
|
|
.parent_names = (const char *[]){ "cpu_clk_div2",
|
|
|
|
"cpu_clk_div3",
|
|
|
|
"cpu_clk_div4",
|
|
|
|
"cpu_clk_div5",
|
|
|
|
"cpu_clk_div6",
|
|
|
|
"cpu_clk_div7",
|
|
|
|
"cpu_clk_div8", },
|
|
|
|
.num_parents = 7,
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
2019-02-11 06:26:03 +08:00
|
|
|
static struct clk_regmap meson8b_apb_clk_gate = {
|
2018-11-23 05:40:17 +08:00
|
|
|
.data = &(struct clk_regmap_gate_data){
|
|
|
|
.offset = HHI_SYS_CPU_CLK_CNTL1,
|
|
|
|
.bit_idx = 16,
|
|
|
|
.flags = CLK_GATE_SET_TO_DISABLE,
|
|
|
|
},
|
|
|
|
.hw.init = &(struct clk_init_data){
|
2019-02-11 06:26:03 +08:00
|
|
|
.name = "apb_clk_dis",
|
2018-11-23 05:40:17 +08:00
|
|
|
.ops = &clk_regmap_gate_ro_ops,
|
2019-02-11 06:26:03 +08:00
|
|
|
.parent_names = (const char *[]){ "apb_clk_sel" },
|
2018-11-23 05:40:17 +08:00
|
|
|
.num_parents = 1,
|
|
|
|
.flags = CLK_SET_RATE_PARENT,
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
|
|
|
static struct clk_regmap meson8b_periph_clk_sel = {
|
|
|
|
.data = &(struct clk_regmap_mux_data){
|
|
|
|
.offset = HHI_SYS_CPU_CLK_CNTL1,
|
|
|
|
.mask = 0x7,
|
|
|
|
.shift = 6,
|
|
|
|
},
|
|
|
|
.hw.init = &(struct clk_init_data){
|
|
|
|
.name = "periph_clk_sel",
|
|
|
|
.ops = &clk_regmap_mux_ops,
|
|
|
|
.parent_names = (const char *[]){ "cpu_clk_div2",
|
|
|
|
"cpu_clk_div3",
|
|
|
|
"cpu_clk_div4",
|
|
|
|
"cpu_clk_div5",
|
|
|
|
"cpu_clk_div6",
|
|
|
|
"cpu_clk_div7",
|
|
|
|
"cpu_clk_div8", },
|
|
|
|
.num_parents = 7,
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
|
|
|
static struct clk_regmap meson8b_periph_clk_gate = {
|
|
|
|
.data = &(struct clk_regmap_gate_data){
|
|
|
|
.offset = HHI_SYS_CPU_CLK_CNTL1,
|
|
|
|
.bit_idx = 17,
|
|
|
|
.flags = CLK_GATE_SET_TO_DISABLE,
|
|
|
|
},
|
|
|
|
.hw.init = &(struct clk_init_data){
|
|
|
|
.name = "periph_clk_dis",
|
|
|
|
.ops = &clk_regmap_gate_ro_ops,
|
|
|
|
.parent_names = (const char *[]){ "periph_clk_sel" },
|
|
|
|
.num_parents = 1,
|
|
|
|
.flags = CLK_SET_RATE_PARENT,
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
|
|
|
static u32 mux_table_axi[] = { 1, 2, 3, 4, 5, 6, 7 };
|
|
|
|
static struct clk_regmap meson8b_axi_clk_sel = {
|
|
|
|
.data = &(struct clk_regmap_mux_data){
|
|
|
|
.offset = HHI_SYS_CPU_CLK_CNTL1,
|
|
|
|
.mask = 0x7,
|
|
|
|
.shift = 9,
|
|
|
|
.table = mux_table_axi,
|
|
|
|
},
|
|
|
|
.hw.init = &(struct clk_init_data){
|
|
|
|
.name = "axi_clk_sel",
|
|
|
|
.ops = &clk_regmap_mux_ops,
|
|
|
|
.parent_names = (const char *[]){ "cpu_clk_div2",
|
|
|
|
"cpu_clk_div3",
|
|
|
|
"cpu_clk_div4",
|
|
|
|
"cpu_clk_div5",
|
|
|
|
"cpu_clk_div6",
|
|
|
|
"cpu_clk_div7",
|
|
|
|
"cpu_clk_div8", },
|
|
|
|
.num_parents = 7,
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
|
|
|
static struct clk_regmap meson8b_axi_clk_gate = {
|
|
|
|
.data = &(struct clk_regmap_gate_data){
|
|
|
|
.offset = HHI_SYS_CPU_CLK_CNTL1,
|
|
|
|
.bit_idx = 18,
|
|
|
|
.flags = CLK_GATE_SET_TO_DISABLE,
|
|
|
|
},
|
|
|
|
.hw.init = &(struct clk_init_data){
|
|
|
|
.name = "axi_clk_dis",
|
|
|
|
.ops = &clk_regmap_gate_ro_ops,
|
|
|
|
.parent_names = (const char *[]){ "axi_clk_sel" },
|
|
|
|
.num_parents = 1,
|
|
|
|
.flags = CLK_SET_RATE_PARENT,
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
|
|
|
static struct clk_regmap meson8b_l2_dram_clk_sel = {
|
|
|
|
.data = &(struct clk_regmap_mux_data){
|
|
|
|
.offset = HHI_SYS_CPU_CLK_CNTL1,
|
|
|
|
.mask = 0x7,
|
|
|
|
.shift = 12,
|
|
|
|
},
|
|
|
|
.hw.init = &(struct clk_init_data){
|
|
|
|
.name = "l2_dram_clk_sel",
|
|
|
|
.ops = &clk_regmap_mux_ops,
|
|
|
|
.parent_names = (const char *[]){ "cpu_clk_div2",
|
|
|
|
"cpu_clk_div3",
|
|
|
|
"cpu_clk_div4",
|
|
|
|
"cpu_clk_div5",
|
|
|
|
"cpu_clk_div6",
|
|
|
|
"cpu_clk_div7",
|
|
|
|
"cpu_clk_div8", },
|
|
|
|
.num_parents = 7,
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
|
|
|
static struct clk_regmap meson8b_l2_dram_clk_gate = {
|
|
|
|
.data = &(struct clk_regmap_gate_data){
|
|
|
|
.offset = HHI_SYS_CPU_CLK_CNTL1,
|
|
|
|
.bit_idx = 19,
|
|
|
|
.flags = CLK_GATE_SET_TO_DISABLE,
|
|
|
|
},
|
|
|
|
.hw.init = &(struct clk_init_data){
|
|
|
|
.name = "l2_dram_clk_dis",
|
|
|
|
.ops = &clk_regmap_gate_ro_ops,
|
|
|
|
.parent_names = (const char *[]){ "l2_dram_clk_sel" },
|
|
|
|
.num_parents = 1,
|
|
|
|
.flags = CLK_SET_RATE_PARENT,
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
clk: meson: meson8b: add the read-only video clock trees
Add all clocks to give us the final video clocks within the Meson8,
Meson8b and Meson8m2 SoCs. The final video clocks are:
- cts_enct
- cts_encl
- cts_encp
- cts_enci
- cts_vdac0
- hdmi_tx_pixel
- hdmi_sys
Add multiple clocks in between which are needed to implement these
clocks:
- Opposed to GXBB there is no pre-multiplier for the PLL input. The
assumption here is that the multiplier is required to achieve the HDMI
2.0 clock rates (which are up to twice the rate of the HDMI 1.4
rates).
- The main PLL is called "HDMI PLL" or "HPLL" in the datasheet. Rename
our existing "vid_pll_dco" to "hdmi_pll_dco". The actual VID_PLL clock
also exists further down the tree.
- Rename the existing "vid_pll" clock (which is the OD divider at
HHI_VID_PLL_CNTL[17:16]) to "hdmi_pll_lvds_out" to match the naming
from the datasheet.
- Add the second OD divider called "hdmi_pll_hdmi_out" at
HHI_VID_PLL_CNTL[19:18].
- Add the "vid_pll_in_sel" which can choose between "hdmi_pll_dco" and
another parent. However, the second parent is not use on Amlogic's
3.10 kernel for HDMI or CVBS output so just leave a TODO in the code.
- Add the "vid_pll_in_en" which is located after "vid_pll_in_sel"
according to the datasheet.
- Add "vid_pll_pre_div" which is used for divide-by-5 and divide-by-6 in
Amlogic's 3.10 kernel sources.
- Add "vid_pll_post_div" which divides the output of "vid_pll_pre_div"
further down. The Amlogic 3.10 kernel configures this as divide-by-2
with "vid_pll_pre_div" being configured as divide-by-5 to achieve a
total divider of 10.
- Add the real "vid_pll" clock which selects between "vid_pll_pre_div",
"vid_pll_post_div" and a third "vid_pll_pre_div_mult7_div2" (which is
"vid_pll_pre_div" divided by 3.5). The latter is not supported yet
because it's not used in Amlogic's 3.10 kernel. The "vid_pll" clock
rate can also be measured by clkmsr to check whether this
implementation is correct.
- Add "vid_pll_final_div" which is a post-divider for "vid_pll" and it's
used as input for "vclk" and "vclk2"
- Add the two symmetric "vclk" and "vclk" clock trees, each with a
divide-by-1, divide-by-2, divide-by-4, divide-by-6 and divide-by-12
clock and a divider for each clock.
- Add the "cts_enct", "cts_encp" and "hdmi_tx_pixel" clocks which each
have their own gate and can select between any of the five "vclk"
dividers.
- Add the "cts_encl" and "cts_vdac0" clocks which each have their own
gate and can select between any of the five "vclk2" dividers.
The "hdmi_sys" clock is a different than these video clocks. It takes
"xtal" as input (there are three more but unknown parents). Add this
clock as well as it's used by the HDMI controller. Amlogic's 3.10 kernel
always configures this as "xtal divided by 1", so we can ignore the
other parents for now.
This was tested on Meson8b and Meson8m2 boards by comparing the common
clock framework output with the clock measurer output. The following
video modes were first set in u-boot (by running "video dev open $mode")
before booting Linux:
4K2K30HZ (only supported by Meson8m2, not tested on Meson8b):
- vid_pll: 297000000Hz
- cts_encp: 297000000Hz
- hdmi_tx_pixel: 297000000Hz
1080P:
- vid_pll: 148500000Hz
- cts_encp: 148500000Hz
- hdmi_tx_pixel: 148500000Hz
720P:
- vid_pll: 148500000Hz
- cts_encp: 148500000Hz
- hdmi_tx_pixel: 74250000Hz
480P:
- vid_pll: 216000000Hz
- cts_encp: 54000000Hz
- hdmi_tx_pixel: 27000000Hz
Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
Link: https://lkml.kernel.org/r/20181202214220.7715-4-martin.blumenstingl@googlemail.com
2018-12-03 05:42:20 +08:00
|
|
|
static struct clk_regmap meson8b_vid_pll_in_sel = {
|
|
|
|
.data = &(struct clk_regmap_mux_data){
|
|
|
|
.offset = HHI_VID_DIVIDER_CNTL,
|
|
|
|
.mask = 0x1,
|
|
|
|
.shift = 15,
|
|
|
|
},
|
|
|
|
.hw.init = &(struct clk_init_data){
|
|
|
|
.name = "vid_pll_in_sel",
|
|
|
|
.ops = &clk_regmap_mux_ro_ops,
|
|
|
|
/*
|
|
|
|
* TODO: depending on the SoC there is also a second parent:
|
|
|
|
* Meson8: unknown
|
|
|
|
* Meson8b: hdmi_pll_dco
|
|
|
|
* Meson8m2: vid2_pll
|
|
|
|
*/
|
|
|
|
.parent_names = (const char *[]){ "hdmi_pll_dco" },
|
|
|
|
.num_parents = 1,
|
|
|
|
.flags = CLK_SET_RATE_PARENT,
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
|
|
|
static struct clk_regmap meson8b_vid_pll_in_en = {
|
|
|
|
.data = &(struct clk_regmap_gate_data){
|
|
|
|
.offset = HHI_VID_DIVIDER_CNTL,
|
|
|
|
.bit_idx = 16,
|
|
|
|
},
|
|
|
|
.hw.init = &(struct clk_init_data){
|
|
|
|
.name = "vid_pll_in_en",
|
|
|
|
.ops = &clk_regmap_gate_ro_ops,
|
|
|
|
.parent_names = (const char *[]){ "vid_pll_in_sel" },
|
|
|
|
.num_parents = 1,
|
|
|
|
.flags = CLK_SET_RATE_PARENT,
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
|
|
|
static struct clk_regmap meson8b_vid_pll_pre_div = {
|
|
|
|
.data = &(struct clk_regmap_div_data){
|
|
|
|
.offset = HHI_VID_DIVIDER_CNTL,
|
|
|
|
.shift = 4,
|
|
|
|
.width = 3,
|
|
|
|
},
|
|
|
|
.hw.init = &(struct clk_init_data){
|
|
|
|
.name = "vid_pll_pre_div",
|
|
|
|
.ops = &clk_regmap_divider_ro_ops,
|
|
|
|
.parent_names = (const char *[]){ "vid_pll_in_en" },
|
|
|
|
.num_parents = 1,
|
|
|
|
.flags = CLK_SET_RATE_PARENT,
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
|
|
|
static struct clk_regmap meson8b_vid_pll_post_div = {
|
|
|
|
.data = &(struct clk_regmap_div_data){
|
|
|
|
.offset = HHI_VID_DIVIDER_CNTL,
|
|
|
|
.shift = 12,
|
|
|
|
.width = 3,
|
|
|
|
},
|
|
|
|
.hw.init = &(struct clk_init_data){
|
|
|
|
.name = "vid_pll_post_div",
|
|
|
|
.ops = &clk_regmap_divider_ro_ops,
|
|
|
|
.parent_names = (const char *[]){ "vid_pll_pre_div" },
|
|
|
|
.num_parents = 1,
|
|
|
|
.flags = CLK_SET_RATE_PARENT,
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
|
|
|
static struct clk_regmap meson8b_vid_pll = {
|
|
|
|
.data = &(struct clk_regmap_mux_data){
|
|
|
|
.offset = HHI_VID_DIVIDER_CNTL,
|
|
|
|
.mask = 0x3,
|
|
|
|
.shift = 8,
|
|
|
|
},
|
|
|
|
.hw.init = &(struct clk_init_data){
|
|
|
|
.name = "vid_pll",
|
|
|
|
.ops = &clk_regmap_mux_ro_ops,
|
|
|
|
/* TODO: parent 0x2 is vid_pll_pre_div_mult7_div2 */
|
|
|
|
.parent_names = (const char *[]){ "vid_pll_pre_div",
|
|
|
|
"vid_pll_post_div" },
|
|
|
|
.num_parents = 2,
|
|
|
|
.flags = CLK_SET_RATE_PARENT,
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
|
|
|
static struct clk_regmap meson8b_vid_pll_final_div = {
|
|
|
|
.data = &(struct clk_regmap_div_data){
|
|
|
|
.offset = HHI_VID_CLK_DIV,
|
|
|
|
.shift = 0,
|
|
|
|
.width = 8,
|
|
|
|
},
|
|
|
|
.hw.init = &(struct clk_init_data){
|
|
|
|
.name = "vid_pll_final_div",
|
|
|
|
.ops = &clk_regmap_divider_ro_ops,
|
|
|
|
.parent_names = (const char *[]){ "vid_pll" },
|
|
|
|
.num_parents = 1,
|
|
|
|
.flags = CLK_SET_RATE_PARENT,
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
|
|
|
static const char * const meson8b_vclk_mux_parents[] = {
|
|
|
|
"vid_pll_final_div", "fclk_div4", "fclk_div3", "fclk_div5",
|
|
|
|
"vid_pll_final_div", "fclk_div7", "mpll1"
|
|
|
|
};
|
|
|
|
|
|
|
|
static struct clk_regmap meson8b_vclk_in_sel = {
|
|
|
|
.data = &(struct clk_regmap_mux_data){
|
|
|
|
.offset = HHI_VID_CLK_CNTL,
|
|
|
|
.mask = 0x7,
|
|
|
|
.shift = 16,
|
|
|
|
},
|
|
|
|
.hw.init = &(struct clk_init_data){
|
|
|
|
.name = "vclk_in_sel",
|
|
|
|
.ops = &clk_regmap_mux_ro_ops,
|
|
|
|
.parent_names = meson8b_vclk_mux_parents,
|
|
|
|
.num_parents = ARRAY_SIZE(meson8b_vclk_mux_parents),
|
|
|
|
.flags = CLK_SET_RATE_PARENT,
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
|
|
|
static struct clk_regmap meson8b_vclk_in_en = {
|
|
|
|
.data = &(struct clk_regmap_gate_data){
|
|
|
|
.offset = HHI_VID_CLK_DIV,
|
|
|
|
.bit_idx = 16,
|
|
|
|
},
|
|
|
|
.hw.init = &(struct clk_init_data){
|
|
|
|
.name = "vclk_in_en",
|
|
|
|
.ops = &clk_regmap_gate_ro_ops,
|
|
|
|
.parent_names = (const char *[]){ "vclk_in_sel" },
|
|
|
|
.num_parents = 1,
|
|
|
|
.flags = CLK_SET_RATE_PARENT,
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
|
|
|
static struct clk_regmap meson8b_vclk_div1_gate = {
|
|
|
|
.data = &(struct clk_regmap_gate_data){
|
|
|
|
.offset = HHI_VID_CLK_DIV,
|
|
|
|
.bit_idx = 0,
|
|
|
|
},
|
|
|
|
.hw.init = &(struct clk_init_data){
|
|
|
|
.name = "vclk_div1_en",
|
|
|
|
.ops = &clk_regmap_gate_ro_ops,
|
|
|
|
.parent_names = (const char *[]){ "vclk_in_en" },
|
|
|
|
.num_parents = 1,
|
|
|
|
.flags = CLK_SET_RATE_PARENT,
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
|
|
|
static struct clk_fixed_factor meson8b_vclk_div2_div = {
|
|
|
|
.mult = 1,
|
|
|
|
.div = 2,
|
|
|
|
.hw.init = &(struct clk_init_data){
|
|
|
|
.name = "vclk_div2",
|
|
|
|
.ops = &clk_fixed_factor_ops,
|
|
|
|
.parent_names = (const char *[]){ "vclk_in_en" },
|
|
|
|
.num_parents = 1,
|
|
|
|
.flags = CLK_SET_RATE_PARENT,
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
static struct clk_regmap meson8b_vclk_div2_div_gate = {
|
|
|
|
.data = &(struct clk_regmap_gate_data){
|
|
|
|
.offset = HHI_VID_CLK_DIV,
|
|
|
|
.bit_idx = 1,
|
|
|
|
},
|
|
|
|
.hw.init = &(struct clk_init_data){
|
|
|
|
.name = "vclk_div2_en",
|
|
|
|
.ops = &clk_regmap_gate_ro_ops,
|
|
|
|
.parent_names = (const char *[]){ "vclk_div2" },
|
|
|
|
.num_parents = 1,
|
|
|
|
.flags = CLK_SET_RATE_PARENT,
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
|
|
|
static struct clk_fixed_factor meson8b_vclk_div4_div = {
|
|
|
|
.mult = 1,
|
|
|
|
.div = 4,
|
|
|
|
.hw.init = &(struct clk_init_data){
|
|
|
|
.name = "vclk_div4",
|
|
|
|
.ops = &clk_fixed_factor_ops,
|
|
|
|
.parent_names = (const char *[]){ "vclk_in_en" },
|
|
|
|
.num_parents = 1,
|
|
|
|
.flags = CLK_SET_RATE_PARENT,
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
static struct clk_regmap meson8b_vclk_div4_div_gate = {
|
|
|
|
.data = &(struct clk_regmap_gate_data){
|
|
|
|
.offset = HHI_VID_CLK_DIV,
|
|
|
|
.bit_idx = 2,
|
|
|
|
},
|
|
|
|
.hw.init = &(struct clk_init_data){
|
|
|
|
.name = "vclk_div4_en",
|
|
|
|
.ops = &clk_regmap_gate_ro_ops,
|
|
|
|
.parent_names = (const char *[]){ "vclk_div4" },
|
|
|
|
.num_parents = 1,
|
|
|
|
.flags = CLK_SET_RATE_PARENT,
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
|
|
|
static struct clk_fixed_factor meson8b_vclk_div6_div = {
|
|
|
|
.mult = 1,
|
|
|
|
.div = 6,
|
|
|
|
.hw.init = &(struct clk_init_data){
|
|
|
|
.name = "vclk_div6",
|
|
|
|
.ops = &clk_fixed_factor_ops,
|
|
|
|
.parent_names = (const char *[]){ "vclk_in_en" },
|
|
|
|
.num_parents = 1,
|
|
|
|
.flags = CLK_SET_RATE_PARENT,
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
static struct clk_regmap meson8b_vclk_div6_div_gate = {
|
|
|
|
.data = &(struct clk_regmap_gate_data){
|
|
|
|
.offset = HHI_VID_CLK_DIV,
|
|
|
|
.bit_idx = 3,
|
|
|
|
},
|
|
|
|
.hw.init = &(struct clk_init_data){
|
|
|
|
.name = "vclk_div6_en",
|
|
|
|
.ops = &clk_regmap_gate_ro_ops,
|
|
|
|
.parent_names = (const char *[]){ "vclk_div6" },
|
|
|
|
.num_parents = 1,
|
|
|
|
.flags = CLK_SET_RATE_PARENT,
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
|
|
|
static struct clk_fixed_factor meson8b_vclk_div12_div = {
|
|
|
|
.mult = 1,
|
|
|
|
.div = 12,
|
|
|
|
.hw.init = &(struct clk_init_data){
|
|
|
|
.name = "vclk_div12",
|
|
|
|
.ops = &clk_fixed_factor_ops,
|
|
|
|
.parent_names = (const char *[]){ "vclk_in_en" },
|
|
|
|
.num_parents = 1,
|
|
|
|
.flags = CLK_SET_RATE_PARENT,
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
static struct clk_regmap meson8b_vclk_div12_div_gate = {
|
|
|
|
.data = &(struct clk_regmap_gate_data){
|
|
|
|
.offset = HHI_VID_CLK_DIV,
|
|
|
|
.bit_idx = 4,
|
|
|
|
},
|
|
|
|
.hw.init = &(struct clk_init_data){
|
|
|
|
.name = "vclk_div12_en",
|
|
|
|
.ops = &clk_regmap_gate_ro_ops,
|
|
|
|
.parent_names = (const char *[]){ "vclk_div12" },
|
|
|
|
.num_parents = 1,
|
|
|
|
.flags = CLK_SET_RATE_PARENT,
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
|
|
|
static struct clk_regmap meson8b_vclk2_in_sel = {
|
|
|
|
.data = &(struct clk_regmap_mux_data){
|
|
|
|
.offset = HHI_VIID_CLK_CNTL,
|
|
|
|
.mask = 0x7,
|
|
|
|
.shift = 16,
|
|
|
|
},
|
|
|
|
.hw.init = &(struct clk_init_data){
|
|
|
|
.name = "vclk2_in_sel",
|
|
|
|
.ops = &clk_regmap_mux_ro_ops,
|
|
|
|
.parent_names = meson8b_vclk_mux_parents,
|
|
|
|
.num_parents = ARRAY_SIZE(meson8b_vclk_mux_parents),
|
|
|
|
.flags = CLK_SET_RATE_PARENT,
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
|
|
|
static struct clk_regmap meson8b_vclk2_clk_in_en = {
|
|
|
|
.data = &(struct clk_regmap_gate_data){
|
|
|
|
.offset = HHI_VIID_CLK_DIV,
|
|
|
|
.bit_idx = 16,
|
|
|
|
},
|
|
|
|
.hw.init = &(struct clk_init_data){
|
|
|
|
.name = "vclk2_in_en",
|
|
|
|
.ops = &clk_regmap_gate_ro_ops,
|
|
|
|
.parent_names = (const char *[]){ "vclk2_in_sel" },
|
|
|
|
.num_parents = 1,
|
|
|
|
.flags = CLK_SET_RATE_PARENT,
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
|
|
|
static struct clk_regmap meson8b_vclk2_div1_gate = {
|
|
|
|
.data = &(struct clk_regmap_gate_data){
|
|
|
|
.offset = HHI_VIID_CLK_DIV,
|
|
|
|
.bit_idx = 0,
|
|
|
|
},
|
|
|
|
.hw.init = &(struct clk_init_data){
|
|
|
|
.name = "vclk2_div1_en",
|
|
|
|
.ops = &clk_regmap_gate_ro_ops,
|
|
|
|
.parent_names = (const char *[]){ "vclk2_in_en" },
|
|
|
|
.num_parents = 1,
|
|
|
|
.flags = CLK_SET_RATE_PARENT,
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
|
|
|
static struct clk_fixed_factor meson8b_vclk2_div2_div = {
|
|
|
|
.mult = 1,
|
|
|
|
.div = 2,
|
|
|
|
.hw.init = &(struct clk_init_data){
|
|
|
|
.name = "vclk2_div2",
|
|
|
|
.ops = &clk_fixed_factor_ops,
|
|
|
|
.parent_names = (const char *[]){ "vclk2_in_en" },
|
|
|
|
.num_parents = 1,
|
|
|
|
.flags = CLK_SET_RATE_PARENT,
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
static struct clk_regmap meson8b_vclk2_div2_div_gate = {
|
|
|
|
.data = &(struct clk_regmap_gate_data){
|
|
|
|
.offset = HHI_VIID_CLK_DIV,
|
|
|
|
.bit_idx = 1,
|
|
|
|
},
|
|
|
|
.hw.init = &(struct clk_init_data){
|
|
|
|
.name = "vclk2_div2_en",
|
|
|
|
.ops = &clk_regmap_gate_ro_ops,
|
|
|
|
.parent_names = (const char *[]){ "vclk2_div2" },
|
|
|
|
.num_parents = 1,
|
|
|
|
.flags = CLK_SET_RATE_PARENT,
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
|
|
|
static struct clk_fixed_factor meson8b_vclk2_div4_div = {
|
|
|
|
.mult = 1,
|
|
|
|
.div = 4,
|
|
|
|
.hw.init = &(struct clk_init_data){
|
|
|
|
.name = "vclk2_div4",
|
|
|
|
.ops = &clk_fixed_factor_ops,
|
|
|
|
.parent_names = (const char *[]){ "vclk2_in_en" },
|
|
|
|
.num_parents = 1,
|
|
|
|
.flags = CLK_SET_RATE_PARENT,
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
static struct clk_regmap meson8b_vclk2_div4_div_gate = {
|
|
|
|
.data = &(struct clk_regmap_gate_data){
|
|
|
|
.offset = HHI_VIID_CLK_DIV,
|
|
|
|
.bit_idx = 2,
|
|
|
|
},
|
|
|
|
.hw.init = &(struct clk_init_data){
|
|
|
|
.name = "vclk2_div4_en",
|
|
|
|
.ops = &clk_regmap_gate_ro_ops,
|
|
|
|
.parent_names = (const char *[]){ "vclk2_div4" },
|
|
|
|
.num_parents = 1,
|
|
|
|
.flags = CLK_SET_RATE_PARENT,
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
|
|
|
static struct clk_fixed_factor meson8b_vclk2_div6_div = {
|
|
|
|
.mult = 1,
|
|
|
|
.div = 6,
|
|
|
|
.hw.init = &(struct clk_init_data){
|
|
|
|
.name = "vclk2_div6",
|
|
|
|
.ops = &clk_fixed_factor_ops,
|
|
|
|
.parent_names = (const char *[]){ "vclk2_in_en" },
|
|
|
|
.num_parents = 1,
|
|
|
|
.flags = CLK_SET_RATE_PARENT,
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
static struct clk_regmap meson8b_vclk2_div6_div_gate = {
|
|
|
|
.data = &(struct clk_regmap_gate_data){
|
|
|
|
.offset = HHI_VIID_CLK_DIV,
|
|
|
|
.bit_idx = 3,
|
|
|
|
},
|
|
|
|
.hw.init = &(struct clk_init_data){
|
|
|
|
.name = "vclk2_div6_en",
|
|
|
|
.ops = &clk_regmap_gate_ro_ops,
|
|
|
|
.parent_names = (const char *[]){ "vclk2_div6" },
|
|
|
|
.num_parents = 1,
|
|
|
|
.flags = CLK_SET_RATE_PARENT,
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
|
|
|
static struct clk_fixed_factor meson8b_vclk2_div12_div = {
|
|
|
|
.mult = 1,
|
|
|
|
.div = 12,
|
|
|
|
.hw.init = &(struct clk_init_data){
|
|
|
|
.name = "vclk2_div12",
|
|
|
|
.ops = &clk_fixed_factor_ops,
|
|
|
|
.parent_names = (const char *[]){ "vclk2_in_en" },
|
|
|
|
.num_parents = 1,
|
|
|
|
.flags = CLK_SET_RATE_PARENT,
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
static struct clk_regmap meson8b_vclk2_div12_div_gate = {
|
|
|
|
.data = &(struct clk_regmap_gate_data){
|
|
|
|
.offset = HHI_VIID_CLK_DIV,
|
|
|
|
.bit_idx = 4,
|
|
|
|
},
|
|
|
|
.hw.init = &(struct clk_init_data){
|
|
|
|
.name = "vclk2_div12_en",
|
|
|
|
.ops = &clk_regmap_gate_ro_ops,
|
|
|
|
.parent_names = (const char *[]){ "vclk2_div12" },
|
|
|
|
.num_parents = 1,
|
|
|
|
.flags = CLK_SET_RATE_PARENT,
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
|
|
|
static const char * const meson8b_vclk_enc_mux_parents[] = {
|
|
|
|
"vclk_div1_en", "vclk_div2_en", "vclk_div4_en", "vclk_div6_en",
|
|
|
|
"vclk_div12_en",
|
|
|
|
};
|
|
|
|
|
|
|
|
static struct clk_regmap meson8b_cts_enct_sel = {
|
|
|
|
.data = &(struct clk_regmap_mux_data){
|
|
|
|
.offset = HHI_VID_CLK_DIV,
|
|
|
|
.mask = 0xf,
|
|
|
|
.shift = 20,
|
|
|
|
},
|
|
|
|
.hw.init = &(struct clk_init_data){
|
|
|
|
.name = "cts_enct_sel",
|
|
|
|
.ops = &clk_regmap_mux_ro_ops,
|
|
|
|
.parent_names = meson8b_vclk_enc_mux_parents,
|
|
|
|
.num_parents = ARRAY_SIZE(meson8b_vclk_enc_mux_parents),
|
|
|
|
.flags = CLK_SET_RATE_PARENT,
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
|
|
|
static struct clk_regmap meson8b_cts_enct = {
|
|
|
|
.data = &(struct clk_regmap_gate_data){
|
|
|
|
.offset = HHI_VID_CLK_CNTL2,
|
|
|
|
.bit_idx = 1,
|
|
|
|
},
|
|
|
|
.hw.init = &(struct clk_init_data){
|
|
|
|
.name = "cts_enct",
|
|
|
|
.ops = &clk_regmap_gate_ro_ops,
|
|
|
|
.parent_names = (const char *[]){ "cts_enct_sel" },
|
|
|
|
.num_parents = 1,
|
|
|
|
.flags = CLK_SET_RATE_PARENT,
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
|
|
|
static struct clk_regmap meson8b_cts_encp_sel = {
|
|
|
|
.data = &(struct clk_regmap_mux_data){
|
|
|
|
.offset = HHI_VID_CLK_DIV,
|
|
|
|
.mask = 0xf,
|
|
|
|
.shift = 24,
|
|
|
|
},
|
|
|
|
.hw.init = &(struct clk_init_data){
|
|
|
|
.name = "cts_encp_sel",
|
|
|
|
.ops = &clk_regmap_mux_ro_ops,
|
|
|
|
.parent_names = meson8b_vclk_enc_mux_parents,
|
|
|
|
.num_parents = ARRAY_SIZE(meson8b_vclk_enc_mux_parents),
|
|
|
|
.flags = CLK_SET_RATE_PARENT,
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
|
|
|
static struct clk_regmap meson8b_cts_encp = {
|
|
|
|
.data = &(struct clk_regmap_gate_data){
|
|
|
|
.offset = HHI_VID_CLK_CNTL2,
|
|
|
|
.bit_idx = 2,
|
|
|
|
},
|
|
|
|
.hw.init = &(struct clk_init_data){
|
|
|
|
.name = "cts_encp",
|
|
|
|
.ops = &clk_regmap_gate_ro_ops,
|
|
|
|
.parent_names = (const char *[]){ "cts_encp_sel" },
|
|
|
|
.num_parents = 1,
|
|
|
|
.flags = CLK_SET_RATE_PARENT,
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
|
|
|
static struct clk_regmap meson8b_cts_enci_sel = {
|
|
|
|
.data = &(struct clk_regmap_mux_data){
|
|
|
|
.offset = HHI_VID_CLK_DIV,
|
|
|
|
.mask = 0xf,
|
|
|
|
.shift = 28,
|
|
|
|
},
|
|
|
|
.hw.init = &(struct clk_init_data){
|
|
|
|
.name = "cts_enci_sel",
|
|
|
|
.ops = &clk_regmap_mux_ro_ops,
|
|
|
|
.parent_names = meson8b_vclk_enc_mux_parents,
|
|
|
|
.num_parents = ARRAY_SIZE(meson8b_vclk_enc_mux_parents),
|
|
|
|
.flags = CLK_SET_RATE_PARENT,
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
|
|
|
static struct clk_regmap meson8b_cts_enci = {
|
|
|
|
.data = &(struct clk_regmap_gate_data){
|
|
|
|
.offset = HHI_VID_CLK_CNTL2,
|
|
|
|
.bit_idx = 0,
|
|
|
|
},
|
|
|
|
.hw.init = &(struct clk_init_data){
|
|
|
|
.name = "cts_enci",
|
|
|
|
.ops = &clk_regmap_gate_ro_ops,
|
|
|
|
.parent_names = (const char *[]){ "cts_enci_sel" },
|
|
|
|
.num_parents = 1,
|
|
|
|
.flags = CLK_SET_RATE_PARENT,
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
|
|
|
static struct clk_regmap meson8b_hdmi_tx_pixel_sel = {
|
|
|
|
.data = &(struct clk_regmap_mux_data){
|
|
|
|
.offset = HHI_HDMI_CLK_CNTL,
|
|
|
|
.mask = 0xf,
|
|
|
|
.shift = 16,
|
|
|
|
},
|
|
|
|
.hw.init = &(struct clk_init_data){
|
|
|
|
.name = "hdmi_tx_pixel_sel",
|
|
|
|
.ops = &clk_regmap_mux_ro_ops,
|
|
|
|
.parent_names = meson8b_vclk_enc_mux_parents,
|
|
|
|
.num_parents = ARRAY_SIZE(meson8b_vclk_enc_mux_parents),
|
|
|
|
.flags = CLK_SET_RATE_PARENT,
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
|
|
|
static struct clk_regmap meson8b_hdmi_tx_pixel = {
|
|
|
|
.data = &(struct clk_regmap_gate_data){
|
|
|
|
.offset = HHI_VID_CLK_CNTL2,
|
|
|
|
.bit_idx = 5,
|
|
|
|
},
|
|
|
|
.hw.init = &(struct clk_init_data){
|
|
|
|
.name = "hdmi_tx_pixel",
|
|
|
|
.ops = &clk_regmap_gate_ro_ops,
|
|
|
|
.parent_names = (const char *[]){ "hdmi_tx_pixel_sel" },
|
|
|
|
.num_parents = 1,
|
|
|
|
.flags = CLK_SET_RATE_PARENT,
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
|
|
|
static const char * const meson8b_vclk2_enc_mux_parents[] = {
|
|
|
|
"vclk2_div1_en", "vclk2_div2_en", "vclk2_div4_en", "vclk2_div6_en",
|
|
|
|
"vclk2_div12_en",
|
|
|
|
};
|
|
|
|
|
|
|
|
static struct clk_regmap meson8b_cts_encl_sel = {
|
|
|
|
.data = &(struct clk_regmap_mux_data){
|
|
|
|
.offset = HHI_VIID_CLK_DIV,
|
|
|
|
.mask = 0xf,
|
|
|
|
.shift = 12,
|
|
|
|
},
|
|
|
|
.hw.init = &(struct clk_init_data){
|
|
|
|
.name = "cts_encl_sel",
|
|
|
|
.ops = &clk_regmap_mux_ro_ops,
|
|
|
|
.parent_names = meson8b_vclk2_enc_mux_parents,
|
|
|
|
.num_parents = ARRAY_SIZE(meson8b_vclk2_enc_mux_parents),
|
|
|
|
.flags = CLK_SET_RATE_PARENT,
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
|
|
|
static struct clk_regmap meson8b_cts_encl = {
|
|
|
|
.data = &(struct clk_regmap_gate_data){
|
|
|
|
.offset = HHI_VID_CLK_CNTL2,
|
|
|
|
.bit_idx = 3,
|
|
|
|
},
|
|
|
|
.hw.init = &(struct clk_init_data){
|
|
|
|
.name = "cts_encl",
|
|
|
|
.ops = &clk_regmap_gate_ro_ops,
|
|
|
|
.parent_names = (const char *[]){ "cts_encl_sel" },
|
|
|
|
.num_parents = 1,
|
|
|
|
.flags = CLK_SET_RATE_PARENT,
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
|
|
|
static struct clk_regmap meson8b_cts_vdac0_sel = {
|
|
|
|
.data = &(struct clk_regmap_mux_data){
|
|
|
|
.offset = HHI_VIID_CLK_DIV,
|
|
|
|
.mask = 0xf,
|
|
|
|
.shift = 28,
|
|
|
|
},
|
|
|
|
.hw.init = &(struct clk_init_data){
|
|
|
|
.name = "cts_vdac0_sel",
|
|
|
|
.ops = &clk_regmap_mux_ro_ops,
|
|
|
|
.parent_names = meson8b_vclk2_enc_mux_parents,
|
|
|
|
.num_parents = ARRAY_SIZE(meson8b_vclk2_enc_mux_parents),
|
|
|
|
.flags = CLK_SET_RATE_PARENT,
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
|
|
|
static struct clk_regmap meson8b_cts_vdac0 = {
|
|
|
|
.data = &(struct clk_regmap_gate_data){
|
|
|
|
.offset = HHI_VID_CLK_CNTL2,
|
|
|
|
.bit_idx = 4,
|
|
|
|
},
|
|
|
|
.hw.init = &(struct clk_init_data){
|
|
|
|
.name = "cts_vdac0",
|
|
|
|
.ops = &clk_regmap_gate_ro_ops,
|
|
|
|
.parent_names = (const char *[]){ "cts_vdac0_sel" },
|
|
|
|
.num_parents = 1,
|
|
|
|
.flags = CLK_SET_RATE_PARENT,
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
|
|
|
static struct clk_regmap meson8b_hdmi_sys_sel = {
|
|
|
|
.data = &(struct clk_regmap_mux_data){
|
|
|
|
.offset = HHI_HDMI_CLK_CNTL,
|
|
|
|
.mask = 0x3,
|
|
|
|
.shift = 9,
|
|
|
|
.flags = CLK_MUX_ROUND_CLOSEST,
|
|
|
|
},
|
|
|
|
.hw.init = &(struct clk_init_data){
|
|
|
|
.name = "hdmi_sys_sel",
|
|
|
|
.ops = &clk_regmap_mux_ro_ops,
|
|
|
|
/* FIXME: all other parents are unknown */
|
|
|
|
.parent_names = (const char *[]){ "xtal" },
|
|
|
|
.num_parents = 1,
|
|
|
|
.flags = CLK_SET_RATE_NO_REPARENT,
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
|
|
|
static struct clk_regmap meson8b_hdmi_sys_div = {
|
|
|
|
.data = &(struct clk_regmap_div_data){
|
|
|
|
.offset = HHI_HDMI_CLK_CNTL,
|
|
|
|
.shift = 0,
|
|
|
|
.width = 7,
|
|
|
|
},
|
|
|
|
.hw.init = &(struct clk_init_data){
|
|
|
|
.name = "hdmi_sys_div",
|
|
|
|
.ops = &clk_regmap_divider_ro_ops,
|
|
|
|
.parent_names = (const char *[]){ "hdmi_sys_sel" },
|
|
|
|
.num_parents = 1,
|
|
|
|
.flags = CLK_SET_RATE_PARENT,
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
|
|
|
static struct clk_regmap meson8b_hdmi_sys = {
|
|
|
|
.data = &(struct clk_regmap_gate_data){
|
|
|
|
.offset = HHI_HDMI_CLK_CNTL,
|
|
|
|
.bit_idx = 8,
|
|
|
|
},
|
|
|
|
.hw.init = &(struct clk_init_data) {
|
|
|
|
.name = "hdmi_sys",
|
|
|
|
.ops = &clk_regmap_gate_ro_ops,
|
|
|
|
.parent_names = (const char *[]){ "hdmi_sys_div" },
|
|
|
|
.num_parents = 1,
|
|
|
|
.flags = CLK_SET_RATE_PARENT,
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
2018-12-09 01:12:45 +08:00
|
|
|
/*
|
|
|
|
* The MALI IP is clocked by two identical clocks (mali_0 and mali_1)
|
|
|
|
* muxed by a glitch-free switch on Meson8b and Meson8m2. Meson8 only
|
|
|
|
* has mali_0 and no glitch-free mux.
|
|
|
|
*/
|
|
|
|
static const char * const meson8b_mali_0_1_parent_names[] = {
|
|
|
|
"xtal", "mpll2", "mpll1", "fclk_div7", "fclk_div4", "fclk_div3",
|
|
|
|
"fclk_div5"
|
|
|
|
};
|
|
|
|
|
|
|
|
static u32 meson8b_mali_0_1_mux_table[] = { 0, 2, 3, 4, 5, 6, 7 };
|
|
|
|
|
|
|
|
static struct clk_regmap meson8b_mali_0_sel = {
|
|
|
|
.data = &(struct clk_regmap_mux_data){
|
|
|
|
.offset = HHI_MALI_CLK_CNTL,
|
|
|
|
.mask = 0x7,
|
|
|
|
.shift = 9,
|
|
|
|
.table = meson8b_mali_0_1_mux_table,
|
|
|
|
},
|
|
|
|
.hw.init = &(struct clk_init_data){
|
|
|
|
.name = "mali_0_sel",
|
|
|
|
.ops = &clk_regmap_mux_ops,
|
|
|
|
.parent_names = meson8b_mali_0_1_parent_names,
|
|
|
|
.num_parents = ARRAY_SIZE(meson8b_mali_0_1_parent_names),
|
|
|
|
/*
|
|
|
|
* Don't propagate rate changes up because the only changeable
|
|
|
|
* parents are mpll1 and mpll2 but we need those for audio and
|
|
|
|
* RGMII (Ethernet). We don't want to change the audio or
|
|
|
|
* Ethernet clocks when setting the GPU frequency.
|
|
|
|
*/
|
|
|
|
.flags = 0,
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
|
|
|
static struct clk_regmap meson8b_mali_0_div = {
|
|
|
|
.data = &(struct clk_regmap_div_data){
|
|
|
|
.offset = HHI_MALI_CLK_CNTL,
|
|
|
|
.shift = 0,
|
|
|
|
.width = 7,
|
|
|
|
},
|
|
|
|
.hw.init = &(struct clk_init_data){
|
|
|
|
.name = "mali_0_div",
|
|
|
|
.ops = &clk_regmap_divider_ops,
|
|
|
|
.parent_names = (const char *[]){ "mali_0_sel" },
|
|
|
|
.num_parents = 1,
|
|
|
|
.flags = CLK_SET_RATE_PARENT,
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
|
|
|
static struct clk_regmap meson8b_mali_0 = {
|
|
|
|
.data = &(struct clk_regmap_gate_data){
|
|
|
|
.offset = HHI_MALI_CLK_CNTL,
|
|
|
|
.bit_idx = 8,
|
|
|
|
},
|
|
|
|
.hw.init = &(struct clk_init_data){
|
|
|
|
.name = "mali_0",
|
|
|
|
.ops = &clk_regmap_gate_ops,
|
|
|
|
.parent_names = (const char *[]){ "mali_0_div" },
|
|
|
|
.num_parents = 1,
|
|
|
|
.flags = CLK_SET_RATE_PARENT,
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
|
|
|
static struct clk_regmap meson8b_mali_1_sel = {
|
|
|
|
.data = &(struct clk_regmap_mux_data){
|
|
|
|
.offset = HHI_MALI_CLK_CNTL,
|
|
|
|
.mask = 0x7,
|
|
|
|
.shift = 25,
|
|
|
|
.table = meson8b_mali_0_1_mux_table,
|
|
|
|
},
|
|
|
|
.hw.init = &(struct clk_init_data){
|
|
|
|
.name = "mali_1_sel",
|
|
|
|
.ops = &clk_regmap_mux_ops,
|
|
|
|
.parent_names = meson8b_mali_0_1_parent_names,
|
|
|
|
.num_parents = ARRAY_SIZE(meson8b_mali_0_1_parent_names),
|
|
|
|
/*
|
|
|
|
* Don't propagate rate changes up because the only changeable
|
|
|
|
* parents are mpll1 and mpll2 but we need those for audio and
|
|
|
|
* RGMII (Ethernet). We don't want to change the audio or
|
|
|
|
* Ethernet clocks when setting the GPU frequency.
|
|
|
|
*/
|
|
|
|
.flags = 0,
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
|
|
|
static struct clk_regmap meson8b_mali_1_div = {
|
|
|
|
.data = &(struct clk_regmap_div_data){
|
|
|
|
.offset = HHI_MALI_CLK_CNTL,
|
|
|
|
.shift = 16,
|
|
|
|
.width = 7,
|
|
|
|
},
|
|
|
|
.hw.init = &(struct clk_init_data){
|
|
|
|
.name = "mali_1_div",
|
|
|
|
.ops = &clk_regmap_divider_ops,
|
|
|
|
.parent_names = (const char *[]){ "mali_1_sel" },
|
|
|
|
.num_parents = 1,
|
|
|
|
.flags = CLK_SET_RATE_PARENT,
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
|
|
|
static struct clk_regmap meson8b_mali_1 = {
|
|
|
|
.data = &(struct clk_regmap_gate_data){
|
|
|
|
.offset = HHI_MALI_CLK_CNTL,
|
|
|
|
.bit_idx = 24,
|
|
|
|
},
|
|
|
|
.hw.init = &(struct clk_init_data){
|
|
|
|
.name = "mali_1",
|
|
|
|
.ops = &clk_regmap_gate_ops,
|
|
|
|
.parent_names = (const char *[]){ "mali_1_div" },
|
|
|
|
.num_parents = 1,
|
|
|
|
.flags = CLK_SET_RATE_PARENT,
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
|
|
|
static struct clk_regmap meson8b_mali = {
|
|
|
|
.data = &(struct clk_regmap_mux_data){
|
|
|
|
.offset = HHI_MALI_CLK_CNTL,
|
|
|
|
.mask = 1,
|
|
|
|
.shift = 31,
|
|
|
|
},
|
|
|
|
.hw.init = &(struct clk_init_data){
|
|
|
|
.name = "mali",
|
|
|
|
.ops = &clk_regmap_mux_ops,
|
|
|
|
.parent_names = (const char *[]){ "mali_0", "mali_1" },
|
|
|
|
.num_parents = 2,
|
|
|
|
.flags = CLK_SET_RATE_PARENT,
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
2016-08-28 01:40:54 +08:00
|
|
|
/* Everything Else (EE) domain gates */
|
|
|
|
|
|
|
|
static MESON_GATE(meson8b_ddr, HHI_GCLK_MPEG0, 0);
|
|
|
|
static MESON_GATE(meson8b_dos, HHI_GCLK_MPEG0, 1);
|
|
|
|
static MESON_GATE(meson8b_isa, HHI_GCLK_MPEG0, 5);
|
|
|
|
static MESON_GATE(meson8b_pl301, HHI_GCLK_MPEG0, 6);
|
|
|
|
static MESON_GATE(meson8b_periphs, HHI_GCLK_MPEG0, 7);
|
|
|
|
static MESON_GATE(meson8b_spicc, HHI_GCLK_MPEG0, 8);
|
|
|
|
static MESON_GATE(meson8b_i2c, HHI_GCLK_MPEG0, 9);
|
|
|
|
static MESON_GATE(meson8b_sar_adc, HHI_GCLK_MPEG0, 10);
|
|
|
|
static MESON_GATE(meson8b_smart_card, HHI_GCLK_MPEG0, 11);
|
|
|
|
static MESON_GATE(meson8b_rng0, HHI_GCLK_MPEG0, 12);
|
|
|
|
static MESON_GATE(meson8b_uart0, HHI_GCLK_MPEG0, 13);
|
|
|
|
static MESON_GATE(meson8b_sdhc, HHI_GCLK_MPEG0, 14);
|
|
|
|
static MESON_GATE(meson8b_stream, HHI_GCLK_MPEG0, 15);
|
|
|
|
static MESON_GATE(meson8b_async_fifo, HHI_GCLK_MPEG0, 16);
|
|
|
|
static MESON_GATE(meson8b_sdio, HHI_GCLK_MPEG0, 17);
|
|
|
|
static MESON_GATE(meson8b_abuf, HHI_GCLK_MPEG0, 18);
|
|
|
|
static MESON_GATE(meson8b_hiu_iface, HHI_GCLK_MPEG0, 19);
|
|
|
|
static MESON_GATE(meson8b_assist_misc, HHI_GCLK_MPEG0, 23);
|
|
|
|
static MESON_GATE(meson8b_spi, HHI_GCLK_MPEG0, 30);
|
|
|
|
|
|
|
|
static MESON_GATE(meson8b_i2s_spdif, HHI_GCLK_MPEG1, 2);
|
|
|
|
static MESON_GATE(meson8b_eth, HHI_GCLK_MPEG1, 3);
|
|
|
|
static MESON_GATE(meson8b_demux, HHI_GCLK_MPEG1, 4);
|
|
|
|
static MESON_GATE(meson8b_aiu_glue, HHI_GCLK_MPEG1, 6);
|
|
|
|
static MESON_GATE(meson8b_iec958, HHI_GCLK_MPEG1, 7);
|
|
|
|
static MESON_GATE(meson8b_i2s_out, HHI_GCLK_MPEG1, 8);
|
|
|
|
static MESON_GATE(meson8b_amclk, HHI_GCLK_MPEG1, 9);
|
|
|
|
static MESON_GATE(meson8b_aififo2, HHI_GCLK_MPEG1, 10);
|
|
|
|
static MESON_GATE(meson8b_mixer, HHI_GCLK_MPEG1, 11);
|
|
|
|
static MESON_GATE(meson8b_mixer_iface, HHI_GCLK_MPEG1, 12);
|
|
|
|
static MESON_GATE(meson8b_adc, HHI_GCLK_MPEG1, 13);
|
|
|
|
static MESON_GATE(meson8b_blkmv, HHI_GCLK_MPEG1, 14);
|
|
|
|
static MESON_GATE(meson8b_aiu, HHI_GCLK_MPEG1, 15);
|
|
|
|
static MESON_GATE(meson8b_uart1, HHI_GCLK_MPEG1, 16);
|
|
|
|
static MESON_GATE(meson8b_g2d, HHI_GCLK_MPEG1, 20);
|
|
|
|
static MESON_GATE(meson8b_usb0, HHI_GCLK_MPEG1, 21);
|
|
|
|
static MESON_GATE(meson8b_usb1, HHI_GCLK_MPEG1, 22);
|
|
|
|
static MESON_GATE(meson8b_reset, HHI_GCLK_MPEG1, 23);
|
|
|
|
static MESON_GATE(meson8b_nand, HHI_GCLK_MPEG1, 24);
|
|
|
|
static MESON_GATE(meson8b_dos_parser, HHI_GCLK_MPEG1, 25);
|
|
|
|
static MESON_GATE(meson8b_usb, HHI_GCLK_MPEG1, 26);
|
|
|
|
static MESON_GATE(meson8b_vdin1, HHI_GCLK_MPEG1, 28);
|
|
|
|
static MESON_GATE(meson8b_ahb_arb0, HHI_GCLK_MPEG1, 29);
|
|
|
|
static MESON_GATE(meson8b_efuse, HHI_GCLK_MPEG1, 30);
|
|
|
|
static MESON_GATE(meson8b_boot_rom, HHI_GCLK_MPEG1, 31);
|
|
|
|
|
|
|
|
static MESON_GATE(meson8b_ahb_data_bus, HHI_GCLK_MPEG2, 1);
|
|
|
|
static MESON_GATE(meson8b_ahb_ctrl_bus, HHI_GCLK_MPEG2, 2);
|
|
|
|
static MESON_GATE(meson8b_hdmi_intr_sync, HHI_GCLK_MPEG2, 3);
|
|
|
|
static MESON_GATE(meson8b_hdmi_pclk, HHI_GCLK_MPEG2, 4);
|
|
|
|
static MESON_GATE(meson8b_usb1_ddr_bridge, HHI_GCLK_MPEG2, 8);
|
|
|
|
static MESON_GATE(meson8b_usb0_ddr_bridge, HHI_GCLK_MPEG2, 9);
|
|
|
|
static MESON_GATE(meson8b_mmc_pclk, HHI_GCLK_MPEG2, 11);
|
|
|
|
static MESON_GATE(meson8b_dvin, HHI_GCLK_MPEG2, 12);
|
|
|
|
static MESON_GATE(meson8b_uart2, HHI_GCLK_MPEG2, 15);
|
|
|
|
static MESON_GATE(meson8b_sana, HHI_GCLK_MPEG2, 22);
|
|
|
|
static MESON_GATE(meson8b_vpu_intr, HHI_GCLK_MPEG2, 25);
|
|
|
|
static MESON_GATE(meson8b_sec_ahb_ahb3_bridge, HHI_GCLK_MPEG2, 26);
|
|
|
|
static MESON_GATE(meson8b_clk81_a9, HHI_GCLK_MPEG2, 29);
|
|
|
|
|
|
|
|
static MESON_GATE(meson8b_vclk2_venci0, HHI_GCLK_OTHER, 1);
|
|
|
|
static MESON_GATE(meson8b_vclk2_venci1, HHI_GCLK_OTHER, 2);
|
|
|
|
static MESON_GATE(meson8b_vclk2_vencp0, HHI_GCLK_OTHER, 3);
|
|
|
|
static MESON_GATE(meson8b_vclk2_vencp1, HHI_GCLK_OTHER, 4);
|
|
|
|
static MESON_GATE(meson8b_gclk_venci_int, HHI_GCLK_OTHER, 8);
|
|
|
|
static MESON_GATE(meson8b_gclk_vencp_int, HHI_GCLK_OTHER, 9);
|
|
|
|
static MESON_GATE(meson8b_dac_clk, HHI_GCLK_OTHER, 10);
|
|
|
|
static MESON_GATE(meson8b_aoclk_gate, HHI_GCLK_OTHER, 14);
|
|
|
|
static MESON_GATE(meson8b_iec958_gate, HHI_GCLK_OTHER, 16);
|
|
|
|
static MESON_GATE(meson8b_enc480p, HHI_GCLK_OTHER, 20);
|
|
|
|
static MESON_GATE(meson8b_rng1, HHI_GCLK_OTHER, 21);
|
|
|
|
static MESON_GATE(meson8b_gclk_vencl_int, HHI_GCLK_OTHER, 22);
|
|
|
|
static MESON_GATE(meson8b_vclk2_venclmcc, HHI_GCLK_OTHER, 24);
|
|
|
|
static MESON_GATE(meson8b_vclk2_vencl, HHI_GCLK_OTHER, 25);
|
|
|
|
static MESON_GATE(meson8b_vclk2_other, HHI_GCLK_OTHER, 26);
|
|
|
|
static MESON_GATE(meson8b_edp, HHI_GCLK_OTHER, 31);
|
|
|
|
|
|
|
|
/* Always On (AO) domain gates */
|
|
|
|
|
|
|
|
static MESON_GATE(meson8b_ao_media_cpu, HHI_GCLK_AO, 0);
|
|
|
|
static MESON_GATE(meson8b_ao_ahb_sram, HHI_GCLK_AO, 1);
|
|
|
|
static MESON_GATE(meson8b_ao_ahb_bus, HHI_GCLK_AO, 2);
|
|
|
|
static MESON_GATE(meson8b_ao_iface, HHI_GCLK_AO, 3);
|
|
|
|
|
2018-12-09 01:12:44 +08:00
|
|
|
static struct clk_hw_onecell_data meson8_hw_onecell_data = {
|
|
|
|
.hws = {
|
|
|
|
[CLKID_XTAL] = &meson8b_xtal.hw,
|
|
|
|
[CLKID_PLL_FIXED] = &meson8b_fixed_pll.hw,
|
|
|
|
[CLKID_PLL_VID] = &meson8b_vid_pll.hw,
|
|
|
|
[CLKID_PLL_SYS] = &meson8b_sys_pll.hw,
|
|
|
|
[CLKID_FCLK_DIV2] = &meson8b_fclk_div2.hw,
|
|
|
|
[CLKID_FCLK_DIV3] = &meson8b_fclk_div3.hw,
|
|
|
|
[CLKID_FCLK_DIV4] = &meson8b_fclk_div4.hw,
|
|
|
|
[CLKID_FCLK_DIV5] = &meson8b_fclk_div5.hw,
|
|
|
|
[CLKID_FCLK_DIV7] = &meson8b_fclk_div7.hw,
|
|
|
|
[CLKID_CPUCLK] = &meson8b_cpu_clk.hw,
|
|
|
|
[CLKID_MPEG_SEL] = &meson8b_mpeg_clk_sel.hw,
|
|
|
|
[CLKID_MPEG_DIV] = &meson8b_mpeg_clk_div.hw,
|
|
|
|
[CLKID_CLK81] = &meson8b_clk81.hw,
|
|
|
|
[CLKID_DDR] = &meson8b_ddr.hw,
|
|
|
|
[CLKID_DOS] = &meson8b_dos.hw,
|
|
|
|
[CLKID_ISA] = &meson8b_isa.hw,
|
|
|
|
[CLKID_PL301] = &meson8b_pl301.hw,
|
|
|
|
[CLKID_PERIPHS] = &meson8b_periphs.hw,
|
|
|
|
[CLKID_SPICC] = &meson8b_spicc.hw,
|
|
|
|
[CLKID_I2C] = &meson8b_i2c.hw,
|
|
|
|
[CLKID_SAR_ADC] = &meson8b_sar_adc.hw,
|
|
|
|
[CLKID_SMART_CARD] = &meson8b_smart_card.hw,
|
|
|
|
[CLKID_RNG0] = &meson8b_rng0.hw,
|
|
|
|
[CLKID_UART0] = &meson8b_uart0.hw,
|
|
|
|
[CLKID_SDHC] = &meson8b_sdhc.hw,
|
|
|
|
[CLKID_STREAM] = &meson8b_stream.hw,
|
|
|
|
[CLKID_ASYNC_FIFO] = &meson8b_async_fifo.hw,
|
|
|
|
[CLKID_SDIO] = &meson8b_sdio.hw,
|
|
|
|
[CLKID_ABUF] = &meson8b_abuf.hw,
|
|
|
|
[CLKID_HIU_IFACE] = &meson8b_hiu_iface.hw,
|
|
|
|
[CLKID_ASSIST_MISC] = &meson8b_assist_misc.hw,
|
|
|
|
[CLKID_SPI] = &meson8b_spi.hw,
|
|
|
|
[CLKID_I2S_SPDIF] = &meson8b_i2s_spdif.hw,
|
|
|
|
[CLKID_ETH] = &meson8b_eth.hw,
|
|
|
|
[CLKID_DEMUX] = &meson8b_demux.hw,
|
|
|
|
[CLKID_AIU_GLUE] = &meson8b_aiu_glue.hw,
|
|
|
|
[CLKID_IEC958] = &meson8b_iec958.hw,
|
|
|
|
[CLKID_I2S_OUT] = &meson8b_i2s_out.hw,
|
|
|
|
[CLKID_AMCLK] = &meson8b_amclk.hw,
|
|
|
|
[CLKID_AIFIFO2] = &meson8b_aififo2.hw,
|
|
|
|
[CLKID_MIXER] = &meson8b_mixer.hw,
|
|
|
|
[CLKID_MIXER_IFACE] = &meson8b_mixer_iface.hw,
|
|
|
|
[CLKID_ADC] = &meson8b_adc.hw,
|
|
|
|
[CLKID_BLKMV] = &meson8b_blkmv.hw,
|
|
|
|
[CLKID_AIU] = &meson8b_aiu.hw,
|
|
|
|
[CLKID_UART1] = &meson8b_uart1.hw,
|
|
|
|
[CLKID_G2D] = &meson8b_g2d.hw,
|
|
|
|
[CLKID_USB0] = &meson8b_usb0.hw,
|
|
|
|
[CLKID_USB1] = &meson8b_usb1.hw,
|
|
|
|
[CLKID_RESET] = &meson8b_reset.hw,
|
|
|
|
[CLKID_NAND] = &meson8b_nand.hw,
|
|
|
|
[CLKID_DOS_PARSER] = &meson8b_dos_parser.hw,
|
|
|
|
[CLKID_USB] = &meson8b_usb.hw,
|
|
|
|
[CLKID_VDIN1] = &meson8b_vdin1.hw,
|
|
|
|
[CLKID_AHB_ARB0] = &meson8b_ahb_arb0.hw,
|
|
|
|
[CLKID_EFUSE] = &meson8b_efuse.hw,
|
|
|
|
[CLKID_BOOT_ROM] = &meson8b_boot_rom.hw,
|
|
|
|
[CLKID_AHB_DATA_BUS] = &meson8b_ahb_data_bus.hw,
|
|
|
|
[CLKID_AHB_CTRL_BUS] = &meson8b_ahb_ctrl_bus.hw,
|
|
|
|
[CLKID_HDMI_INTR_SYNC] = &meson8b_hdmi_intr_sync.hw,
|
|
|
|
[CLKID_HDMI_PCLK] = &meson8b_hdmi_pclk.hw,
|
|
|
|
[CLKID_USB1_DDR_BRIDGE] = &meson8b_usb1_ddr_bridge.hw,
|
|
|
|
[CLKID_USB0_DDR_BRIDGE] = &meson8b_usb0_ddr_bridge.hw,
|
|
|
|
[CLKID_MMC_PCLK] = &meson8b_mmc_pclk.hw,
|
|
|
|
[CLKID_DVIN] = &meson8b_dvin.hw,
|
|
|
|
[CLKID_UART2] = &meson8b_uart2.hw,
|
|
|
|
[CLKID_SANA] = &meson8b_sana.hw,
|
|
|
|
[CLKID_VPU_INTR] = &meson8b_vpu_intr.hw,
|
|
|
|
[CLKID_SEC_AHB_AHB3_BRIDGE] = &meson8b_sec_ahb_ahb3_bridge.hw,
|
|
|
|
[CLKID_CLK81_A9] = &meson8b_clk81_a9.hw,
|
|
|
|
[CLKID_VCLK2_VENCI0] = &meson8b_vclk2_venci0.hw,
|
|
|
|
[CLKID_VCLK2_VENCI1] = &meson8b_vclk2_venci1.hw,
|
|
|
|
[CLKID_VCLK2_VENCP0] = &meson8b_vclk2_vencp0.hw,
|
|
|
|
[CLKID_VCLK2_VENCP1] = &meson8b_vclk2_vencp1.hw,
|
|
|
|
[CLKID_GCLK_VENCI_INT] = &meson8b_gclk_venci_int.hw,
|
|
|
|
[CLKID_GCLK_VENCP_INT] = &meson8b_gclk_vencp_int.hw,
|
|
|
|
[CLKID_DAC_CLK] = &meson8b_dac_clk.hw,
|
|
|
|
[CLKID_AOCLK_GATE] = &meson8b_aoclk_gate.hw,
|
|
|
|
[CLKID_IEC958_GATE] = &meson8b_iec958_gate.hw,
|
|
|
|
[CLKID_ENC480P] = &meson8b_enc480p.hw,
|
|
|
|
[CLKID_RNG1] = &meson8b_rng1.hw,
|
|
|
|
[CLKID_GCLK_VENCL_INT] = &meson8b_gclk_vencl_int.hw,
|
|
|
|
[CLKID_VCLK2_VENCLMCC] = &meson8b_vclk2_venclmcc.hw,
|
|
|
|
[CLKID_VCLK2_VENCL] = &meson8b_vclk2_vencl.hw,
|
|
|
|
[CLKID_VCLK2_OTHER] = &meson8b_vclk2_other.hw,
|
|
|
|
[CLKID_EDP] = &meson8b_edp.hw,
|
|
|
|
[CLKID_AO_MEDIA_CPU] = &meson8b_ao_media_cpu.hw,
|
|
|
|
[CLKID_AO_AHB_SRAM] = &meson8b_ao_ahb_sram.hw,
|
|
|
|
[CLKID_AO_AHB_BUS] = &meson8b_ao_ahb_bus.hw,
|
|
|
|
[CLKID_AO_IFACE] = &meson8b_ao_iface.hw,
|
|
|
|
[CLKID_MPLL0] = &meson8b_mpll0.hw,
|
|
|
|
[CLKID_MPLL1] = &meson8b_mpll1.hw,
|
|
|
|
[CLKID_MPLL2] = &meson8b_mpll2.hw,
|
|
|
|
[CLKID_MPLL0_DIV] = &meson8b_mpll0_div.hw,
|
|
|
|
[CLKID_MPLL1_DIV] = &meson8b_mpll1_div.hw,
|
|
|
|
[CLKID_MPLL2_DIV] = &meson8b_mpll2_div.hw,
|
|
|
|
[CLKID_CPU_IN_SEL] = &meson8b_cpu_in_sel.hw,
|
|
|
|
[CLKID_CPU_IN_DIV2] = &meson8b_cpu_in_div2.hw,
|
|
|
|
[CLKID_CPU_IN_DIV3] = &meson8b_cpu_in_div3.hw,
|
|
|
|
[CLKID_CPU_SCALE_DIV] = &meson8b_cpu_scale_div.hw,
|
|
|
|
[CLKID_CPU_SCALE_OUT_SEL] = &meson8b_cpu_scale_out_sel.hw,
|
|
|
|
[CLKID_MPLL_PREDIV] = &meson8b_mpll_prediv.hw,
|
|
|
|
[CLKID_FCLK_DIV2_DIV] = &meson8b_fclk_div2_div.hw,
|
|
|
|
[CLKID_FCLK_DIV3_DIV] = &meson8b_fclk_div3_div.hw,
|
|
|
|
[CLKID_FCLK_DIV4_DIV] = &meson8b_fclk_div4_div.hw,
|
|
|
|
[CLKID_FCLK_DIV5_DIV] = &meson8b_fclk_div5_div.hw,
|
|
|
|
[CLKID_FCLK_DIV7_DIV] = &meson8b_fclk_div7_div.hw,
|
|
|
|
[CLKID_NAND_SEL] = &meson8b_nand_clk_sel.hw,
|
|
|
|
[CLKID_NAND_DIV] = &meson8b_nand_clk_div.hw,
|
|
|
|
[CLKID_NAND_CLK] = &meson8b_nand_clk_gate.hw,
|
|
|
|
[CLKID_PLL_FIXED_DCO] = &meson8b_fixed_pll_dco.hw,
|
|
|
|
[CLKID_HDMI_PLL_DCO] = &meson8b_hdmi_pll_dco.hw,
|
|
|
|
[CLKID_PLL_SYS_DCO] = &meson8b_sys_pll_dco.hw,
|
|
|
|
[CLKID_CPU_CLK_DIV2] = &meson8b_cpu_clk_div2.hw,
|
|
|
|
[CLKID_CPU_CLK_DIV3] = &meson8b_cpu_clk_div3.hw,
|
|
|
|
[CLKID_CPU_CLK_DIV4] = &meson8b_cpu_clk_div4.hw,
|
|
|
|
[CLKID_CPU_CLK_DIV5] = &meson8b_cpu_clk_div5.hw,
|
|
|
|
[CLKID_CPU_CLK_DIV6] = &meson8b_cpu_clk_div6.hw,
|
|
|
|
[CLKID_CPU_CLK_DIV7] = &meson8b_cpu_clk_div7.hw,
|
|
|
|
[CLKID_CPU_CLK_DIV8] = &meson8b_cpu_clk_div8.hw,
|
2019-02-11 06:26:03 +08:00
|
|
|
[CLKID_APB_SEL] = &meson8b_apb_clk_sel.hw,
|
|
|
|
[CLKID_APB] = &meson8b_apb_clk_gate.hw,
|
2018-12-09 01:12:44 +08:00
|
|
|
[CLKID_PERIPH_SEL] = &meson8b_periph_clk_sel.hw,
|
|
|
|
[CLKID_PERIPH] = &meson8b_periph_clk_gate.hw,
|
|
|
|
[CLKID_AXI_SEL] = &meson8b_axi_clk_sel.hw,
|
|
|
|
[CLKID_AXI] = &meson8b_axi_clk_gate.hw,
|
|
|
|
[CLKID_L2_DRAM_SEL] = &meson8b_l2_dram_clk_sel.hw,
|
|
|
|
[CLKID_L2_DRAM] = &meson8b_l2_dram_clk_gate.hw,
|
|
|
|
[CLKID_HDMI_PLL_LVDS_OUT] = &meson8b_hdmi_pll_lvds_out.hw,
|
|
|
|
[CLKID_HDMI_PLL_HDMI_OUT] = &meson8b_hdmi_pll_hdmi_out.hw,
|
|
|
|
[CLKID_VID_PLL_IN_SEL] = &meson8b_vid_pll_in_sel.hw,
|
|
|
|
[CLKID_VID_PLL_IN_EN] = &meson8b_vid_pll_in_en.hw,
|
|
|
|
[CLKID_VID_PLL_PRE_DIV] = &meson8b_vid_pll_pre_div.hw,
|
|
|
|
[CLKID_VID_PLL_POST_DIV] = &meson8b_vid_pll_post_div.hw,
|
|
|
|
[CLKID_VID_PLL_FINAL_DIV] = &meson8b_vid_pll_final_div.hw,
|
|
|
|
[CLKID_VCLK_IN_SEL] = &meson8b_vclk_in_sel.hw,
|
|
|
|
[CLKID_VCLK_IN_EN] = &meson8b_vclk_in_en.hw,
|
|
|
|
[CLKID_VCLK_DIV1] = &meson8b_vclk_div1_gate.hw,
|
|
|
|
[CLKID_VCLK_DIV2_DIV] = &meson8b_vclk_div2_div.hw,
|
|
|
|
[CLKID_VCLK_DIV2] = &meson8b_vclk_div2_div_gate.hw,
|
|
|
|
[CLKID_VCLK_DIV4_DIV] = &meson8b_vclk_div4_div.hw,
|
|
|
|
[CLKID_VCLK_DIV4] = &meson8b_vclk_div4_div_gate.hw,
|
|
|
|
[CLKID_VCLK_DIV6_DIV] = &meson8b_vclk_div6_div.hw,
|
|
|
|
[CLKID_VCLK_DIV6] = &meson8b_vclk_div6_div_gate.hw,
|
|
|
|
[CLKID_VCLK_DIV12_DIV] = &meson8b_vclk_div12_div.hw,
|
|
|
|
[CLKID_VCLK_DIV12] = &meson8b_vclk_div12_div_gate.hw,
|
|
|
|
[CLKID_VCLK2_IN_SEL] = &meson8b_vclk2_in_sel.hw,
|
|
|
|
[CLKID_VCLK2_IN_EN] = &meson8b_vclk2_clk_in_en.hw,
|
|
|
|
[CLKID_VCLK2_DIV1] = &meson8b_vclk2_div1_gate.hw,
|
|
|
|
[CLKID_VCLK2_DIV2_DIV] = &meson8b_vclk2_div2_div.hw,
|
|
|
|
[CLKID_VCLK2_DIV2] = &meson8b_vclk2_div2_div_gate.hw,
|
|
|
|
[CLKID_VCLK2_DIV4_DIV] = &meson8b_vclk2_div4_div.hw,
|
|
|
|
[CLKID_VCLK2_DIV4] = &meson8b_vclk2_div4_div_gate.hw,
|
|
|
|
[CLKID_VCLK2_DIV6_DIV] = &meson8b_vclk2_div6_div.hw,
|
|
|
|
[CLKID_VCLK2_DIV6] = &meson8b_vclk2_div6_div_gate.hw,
|
|
|
|
[CLKID_VCLK2_DIV12_DIV] = &meson8b_vclk2_div12_div.hw,
|
|
|
|
[CLKID_VCLK2_DIV12] = &meson8b_vclk2_div12_div_gate.hw,
|
|
|
|
[CLKID_CTS_ENCT_SEL] = &meson8b_cts_enct_sel.hw,
|
|
|
|
[CLKID_CTS_ENCT] = &meson8b_cts_enct.hw,
|
|
|
|
[CLKID_CTS_ENCP_SEL] = &meson8b_cts_encp_sel.hw,
|
|
|
|
[CLKID_CTS_ENCP] = &meson8b_cts_encp.hw,
|
|
|
|
[CLKID_CTS_ENCI_SEL] = &meson8b_cts_enci_sel.hw,
|
|
|
|
[CLKID_CTS_ENCI] = &meson8b_cts_enci.hw,
|
|
|
|
[CLKID_HDMI_TX_PIXEL_SEL] = &meson8b_hdmi_tx_pixel_sel.hw,
|
|
|
|
[CLKID_HDMI_TX_PIXEL] = &meson8b_hdmi_tx_pixel.hw,
|
|
|
|
[CLKID_CTS_ENCL_SEL] = &meson8b_cts_encl_sel.hw,
|
|
|
|
[CLKID_CTS_ENCL] = &meson8b_cts_encl.hw,
|
|
|
|
[CLKID_CTS_VDAC0_SEL] = &meson8b_cts_vdac0_sel.hw,
|
|
|
|
[CLKID_CTS_VDAC0] = &meson8b_cts_vdac0.hw,
|
|
|
|
[CLKID_HDMI_SYS_SEL] = &meson8b_hdmi_sys_sel.hw,
|
|
|
|
[CLKID_HDMI_SYS_DIV] = &meson8b_hdmi_sys_div.hw,
|
|
|
|
[CLKID_HDMI_SYS] = &meson8b_hdmi_sys.hw,
|
2018-12-09 01:12:45 +08:00
|
|
|
[CLKID_MALI_0_SEL] = &meson8b_mali_0_sel.hw,
|
|
|
|
[CLKID_MALI_0_DIV] = &meson8b_mali_0_div.hw,
|
|
|
|
[CLKID_MALI] = &meson8b_mali_0.hw,
|
2018-12-09 01:12:44 +08:00
|
|
|
[CLK_NR_CLKS] = NULL,
|
|
|
|
},
|
|
|
|
.num = CLK_NR_CLKS,
|
|
|
|
};
|
|
|
|
|
2016-04-29 03:00:52 +08:00
|
|
|
static struct clk_hw_onecell_data meson8b_hw_onecell_data = {
|
|
|
|
.hws = {
|
|
|
|
[CLKID_XTAL] = &meson8b_xtal.hw,
|
2016-04-29 03:01:42 +08:00
|
|
|
[CLKID_PLL_FIXED] = &meson8b_fixed_pll.hw,
|
|
|
|
[CLKID_PLL_VID] = &meson8b_vid_pll.hw,
|
|
|
|
[CLKID_PLL_SYS] = &meson8b_sys_pll.hw,
|
2016-04-29 03:01:58 +08:00
|
|
|
[CLKID_FCLK_DIV2] = &meson8b_fclk_div2.hw,
|
|
|
|
[CLKID_FCLK_DIV3] = &meson8b_fclk_div3.hw,
|
|
|
|
[CLKID_FCLK_DIV4] = &meson8b_fclk_div4.hw,
|
|
|
|
[CLKID_FCLK_DIV5] = &meson8b_fclk_div5.hw,
|
|
|
|
[CLKID_FCLK_DIV7] = &meson8b_fclk_div7.hw,
|
2016-05-01 03:47:36 +08:00
|
|
|
[CLKID_CPUCLK] = &meson8b_cpu_clk.hw,
|
2016-04-29 03:01:51 +08:00
|
|
|
[CLKID_MPEG_SEL] = &meson8b_mpeg_clk_sel.hw,
|
|
|
|
[CLKID_MPEG_DIV] = &meson8b_mpeg_clk_div.hw,
|
|
|
|
[CLKID_CLK81] = &meson8b_clk81.hw,
|
2016-08-28 01:40:54 +08:00
|
|
|
[CLKID_DDR] = &meson8b_ddr.hw,
|
|
|
|
[CLKID_DOS] = &meson8b_dos.hw,
|
|
|
|
[CLKID_ISA] = &meson8b_isa.hw,
|
|
|
|
[CLKID_PL301] = &meson8b_pl301.hw,
|
|
|
|
[CLKID_PERIPHS] = &meson8b_periphs.hw,
|
|
|
|
[CLKID_SPICC] = &meson8b_spicc.hw,
|
|
|
|
[CLKID_I2C] = &meson8b_i2c.hw,
|
|
|
|
[CLKID_SAR_ADC] = &meson8b_sar_adc.hw,
|
|
|
|
[CLKID_SMART_CARD] = &meson8b_smart_card.hw,
|
|
|
|
[CLKID_RNG0] = &meson8b_rng0.hw,
|
|
|
|
[CLKID_UART0] = &meson8b_uart0.hw,
|
|
|
|
[CLKID_SDHC] = &meson8b_sdhc.hw,
|
|
|
|
[CLKID_STREAM] = &meson8b_stream.hw,
|
|
|
|
[CLKID_ASYNC_FIFO] = &meson8b_async_fifo.hw,
|
|
|
|
[CLKID_SDIO] = &meson8b_sdio.hw,
|
|
|
|
[CLKID_ABUF] = &meson8b_abuf.hw,
|
|
|
|
[CLKID_HIU_IFACE] = &meson8b_hiu_iface.hw,
|
|
|
|
[CLKID_ASSIST_MISC] = &meson8b_assist_misc.hw,
|
|
|
|
[CLKID_SPI] = &meson8b_spi.hw,
|
|
|
|
[CLKID_I2S_SPDIF] = &meson8b_i2s_spdif.hw,
|
|
|
|
[CLKID_ETH] = &meson8b_eth.hw,
|
|
|
|
[CLKID_DEMUX] = &meson8b_demux.hw,
|
|
|
|
[CLKID_AIU_GLUE] = &meson8b_aiu_glue.hw,
|
|
|
|
[CLKID_IEC958] = &meson8b_iec958.hw,
|
|
|
|
[CLKID_I2S_OUT] = &meson8b_i2s_out.hw,
|
|
|
|
[CLKID_AMCLK] = &meson8b_amclk.hw,
|
|
|
|
[CLKID_AIFIFO2] = &meson8b_aififo2.hw,
|
|
|
|
[CLKID_MIXER] = &meson8b_mixer.hw,
|
|
|
|
[CLKID_MIXER_IFACE] = &meson8b_mixer_iface.hw,
|
|
|
|
[CLKID_ADC] = &meson8b_adc.hw,
|
|
|
|
[CLKID_BLKMV] = &meson8b_blkmv.hw,
|
|
|
|
[CLKID_AIU] = &meson8b_aiu.hw,
|
|
|
|
[CLKID_UART1] = &meson8b_uart1.hw,
|
|
|
|
[CLKID_G2D] = &meson8b_g2d.hw,
|
|
|
|
[CLKID_USB0] = &meson8b_usb0.hw,
|
|
|
|
[CLKID_USB1] = &meson8b_usb1.hw,
|
|
|
|
[CLKID_RESET] = &meson8b_reset.hw,
|
|
|
|
[CLKID_NAND] = &meson8b_nand.hw,
|
|
|
|
[CLKID_DOS_PARSER] = &meson8b_dos_parser.hw,
|
|
|
|
[CLKID_USB] = &meson8b_usb.hw,
|
|
|
|
[CLKID_VDIN1] = &meson8b_vdin1.hw,
|
|
|
|
[CLKID_AHB_ARB0] = &meson8b_ahb_arb0.hw,
|
|
|
|
[CLKID_EFUSE] = &meson8b_efuse.hw,
|
|
|
|
[CLKID_BOOT_ROM] = &meson8b_boot_rom.hw,
|
|
|
|
[CLKID_AHB_DATA_BUS] = &meson8b_ahb_data_bus.hw,
|
|
|
|
[CLKID_AHB_CTRL_BUS] = &meson8b_ahb_ctrl_bus.hw,
|
|
|
|
[CLKID_HDMI_INTR_SYNC] = &meson8b_hdmi_intr_sync.hw,
|
|
|
|
[CLKID_HDMI_PCLK] = &meson8b_hdmi_pclk.hw,
|
|
|
|
[CLKID_USB1_DDR_BRIDGE] = &meson8b_usb1_ddr_bridge.hw,
|
|
|
|
[CLKID_USB0_DDR_BRIDGE] = &meson8b_usb0_ddr_bridge.hw,
|
|
|
|
[CLKID_MMC_PCLK] = &meson8b_mmc_pclk.hw,
|
|
|
|
[CLKID_DVIN] = &meson8b_dvin.hw,
|
|
|
|
[CLKID_UART2] = &meson8b_uart2.hw,
|
|
|
|
[CLKID_SANA] = &meson8b_sana.hw,
|
|
|
|
[CLKID_VPU_INTR] = &meson8b_vpu_intr.hw,
|
|
|
|
[CLKID_SEC_AHB_AHB3_BRIDGE] = &meson8b_sec_ahb_ahb3_bridge.hw,
|
|
|
|
[CLKID_CLK81_A9] = &meson8b_clk81_a9.hw,
|
|
|
|
[CLKID_VCLK2_VENCI0] = &meson8b_vclk2_venci0.hw,
|
|
|
|
[CLKID_VCLK2_VENCI1] = &meson8b_vclk2_venci1.hw,
|
|
|
|
[CLKID_VCLK2_VENCP0] = &meson8b_vclk2_vencp0.hw,
|
|
|
|
[CLKID_VCLK2_VENCP1] = &meson8b_vclk2_vencp1.hw,
|
|
|
|
[CLKID_GCLK_VENCI_INT] = &meson8b_gclk_venci_int.hw,
|
2016-09-06 21:01:10 +08:00
|
|
|
[CLKID_GCLK_VENCP_INT] = &meson8b_gclk_vencp_int.hw,
|
2016-08-28 01:40:54 +08:00
|
|
|
[CLKID_DAC_CLK] = &meson8b_dac_clk.hw,
|
|
|
|
[CLKID_AOCLK_GATE] = &meson8b_aoclk_gate.hw,
|
|
|
|
[CLKID_IEC958_GATE] = &meson8b_iec958_gate.hw,
|
|
|
|
[CLKID_ENC480P] = &meson8b_enc480p.hw,
|
|
|
|
[CLKID_RNG1] = &meson8b_rng1.hw,
|
|
|
|
[CLKID_GCLK_VENCL_INT] = &meson8b_gclk_vencl_int.hw,
|
|
|
|
[CLKID_VCLK2_VENCLMCC] = &meson8b_vclk2_venclmcc.hw,
|
|
|
|
[CLKID_VCLK2_VENCL] = &meson8b_vclk2_vencl.hw,
|
|
|
|
[CLKID_VCLK2_OTHER] = &meson8b_vclk2_other.hw,
|
|
|
|
[CLKID_EDP] = &meson8b_edp.hw,
|
|
|
|
[CLKID_AO_MEDIA_CPU] = &meson8b_ao_media_cpu.hw,
|
|
|
|
[CLKID_AO_AHB_SRAM] = &meson8b_ao_ahb_sram.hw,
|
|
|
|
[CLKID_AO_AHB_BUS] = &meson8b_ao_ahb_bus.hw,
|
|
|
|
[CLKID_AO_IFACE] = &meson8b_ao_iface.hw,
|
2017-03-09 18:41:52 +08:00
|
|
|
[CLKID_MPLL0] = &meson8b_mpll0.hw,
|
|
|
|
[CLKID_MPLL1] = &meson8b_mpll1.hw,
|
|
|
|
[CLKID_MPLL2] = &meson8b_mpll2.hw,
|
2018-02-12 22:58:43 +08:00
|
|
|
[CLKID_MPLL0_DIV] = &meson8b_mpll0_div.hw,
|
|
|
|
[CLKID_MPLL1_DIV] = &meson8b_mpll1_div.hw,
|
|
|
|
[CLKID_MPLL2_DIV] = &meson8b_mpll2_div.hw,
|
2018-02-12 22:58:44 +08:00
|
|
|
[CLKID_CPU_IN_SEL] = &meson8b_cpu_in_sel.hw,
|
2018-11-23 05:40:16 +08:00
|
|
|
[CLKID_CPU_IN_DIV2] = &meson8b_cpu_in_div2.hw,
|
|
|
|
[CLKID_CPU_IN_DIV3] = &meson8b_cpu_in_div3.hw,
|
2018-02-12 22:58:44 +08:00
|
|
|
[CLKID_CPU_SCALE_DIV] = &meson8b_cpu_scale_div.hw,
|
|
|
|
[CLKID_CPU_SCALE_OUT_SEL] = &meson8b_cpu_scale_out_sel.hw,
|
2018-02-19 19:21:44 +08:00
|
|
|
[CLKID_MPLL_PREDIV] = &meson8b_mpll_prediv.hw,
|
2018-02-19 19:21:45 +08:00
|
|
|
[CLKID_FCLK_DIV2_DIV] = &meson8b_fclk_div2_div.hw,
|
|
|
|
[CLKID_FCLK_DIV3_DIV] = &meson8b_fclk_div3_div.hw,
|
|
|
|
[CLKID_FCLK_DIV4_DIV] = &meson8b_fclk_div4_div.hw,
|
|
|
|
[CLKID_FCLK_DIV5_DIV] = &meson8b_fclk_div5_div.hw,
|
|
|
|
[CLKID_FCLK_DIV7_DIV] = &meson8b_fclk_div7_div.hw,
|
2018-04-24 03:35:09 +08:00
|
|
|
[CLKID_NAND_SEL] = &meson8b_nand_clk_sel.hw,
|
|
|
|
[CLKID_NAND_DIV] = &meson8b_nand_clk_div.hw,
|
|
|
|
[CLKID_NAND_CLK] = &meson8b_nand_clk_gate.hw,
|
2018-08-01 22:00:52 +08:00
|
|
|
[CLKID_PLL_FIXED_DCO] = &meson8b_fixed_pll_dco.hw,
|
clk: meson: meson8b: add the read-only video clock trees
Add all clocks to give us the final video clocks within the Meson8,
Meson8b and Meson8m2 SoCs. The final video clocks are:
- cts_enct
- cts_encl
- cts_encp
- cts_enci
- cts_vdac0
- hdmi_tx_pixel
- hdmi_sys
Add multiple clocks in between which are needed to implement these
clocks:
- Opposed to GXBB there is no pre-multiplier for the PLL input. The
assumption here is that the multiplier is required to achieve the HDMI
2.0 clock rates (which are up to twice the rate of the HDMI 1.4
rates).
- The main PLL is called "HDMI PLL" or "HPLL" in the datasheet. Rename
our existing "vid_pll_dco" to "hdmi_pll_dco". The actual VID_PLL clock
also exists further down the tree.
- Rename the existing "vid_pll" clock (which is the OD divider at
HHI_VID_PLL_CNTL[17:16]) to "hdmi_pll_lvds_out" to match the naming
from the datasheet.
- Add the second OD divider called "hdmi_pll_hdmi_out" at
HHI_VID_PLL_CNTL[19:18].
- Add the "vid_pll_in_sel" which can choose between "hdmi_pll_dco" and
another parent. However, the second parent is not use on Amlogic's
3.10 kernel for HDMI or CVBS output so just leave a TODO in the code.
- Add the "vid_pll_in_en" which is located after "vid_pll_in_sel"
according to the datasheet.
- Add "vid_pll_pre_div" which is used for divide-by-5 and divide-by-6 in
Amlogic's 3.10 kernel sources.
- Add "vid_pll_post_div" which divides the output of "vid_pll_pre_div"
further down. The Amlogic 3.10 kernel configures this as divide-by-2
with "vid_pll_pre_div" being configured as divide-by-5 to achieve a
total divider of 10.
- Add the real "vid_pll" clock which selects between "vid_pll_pre_div",
"vid_pll_post_div" and a third "vid_pll_pre_div_mult7_div2" (which is
"vid_pll_pre_div" divided by 3.5). The latter is not supported yet
because it's not used in Amlogic's 3.10 kernel. The "vid_pll" clock
rate can also be measured by clkmsr to check whether this
implementation is correct.
- Add "vid_pll_final_div" which is a post-divider for "vid_pll" and it's
used as input for "vclk" and "vclk2"
- Add the two symmetric "vclk" and "vclk" clock trees, each with a
divide-by-1, divide-by-2, divide-by-4, divide-by-6 and divide-by-12
clock and a divider for each clock.
- Add the "cts_enct", "cts_encp" and "hdmi_tx_pixel" clocks which each
have their own gate and can select between any of the five "vclk"
dividers.
- Add the "cts_encl" and "cts_vdac0" clocks which each have their own
gate and can select between any of the five "vclk2" dividers.
The "hdmi_sys" clock is a different than these video clocks. It takes
"xtal" as input (there are three more but unknown parents). Add this
clock as well as it's used by the HDMI controller. Amlogic's 3.10 kernel
always configures this as "xtal divided by 1", so we can ignore the
other parents for now.
This was tested on Meson8b and Meson8m2 boards by comparing the common
clock framework output with the clock measurer output. The following
video modes were first set in u-boot (by running "video dev open $mode")
before booting Linux:
4K2K30HZ (only supported by Meson8m2, not tested on Meson8b):
- vid_pll: 297000000Hz
- cts_encp: 297000000Hz
- hdmi_tx_pixel: 297000000Hz
1080P:
- vid_pll: 148500000Hz
- cts_encp: 148500000Hz
- hdmi_tx_pixel: 148500000Hz
720P:
- vid_pll: 148500000Hz
- cts_encp: 148500000Hz
- hdmi_tx_pixel: 74250000Hz
480P:
- vid_pll: 216000000Hz
- cts_encp: 54000000Hz
- hdmi_tx_pixel: 27000000Hz
Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
Link: https://lkml.kernel.org/r/20181202214220.7715-4-martin.blumenstingl@googlemail.com
2018-12-03 05:42:20 +08:00
|
|
|
[CLKID_HDMI_PLL_DCO] = &meson8b_hdmi_pll_dco.hw,
|
2018-08-01 22:00:52 +08:00
|
|
|
[CLKID_PLL_SYS_DCO] = &meson8b_sys_pll_dco.hw,
|
2018-11-23 05:40:17 +08:00
|
|
|
[CLKID_CPU_CLK_DIV2] = &meson8b_cpu_clk_div2.hw,
|
|
|
|
[CLKID_CPU_CLK_DIV3] = &meson8b_cpu_clk_div3.hw,
|
|
|
|
[CLKID_CPU_CLK_DIV4] = &meson8b_cpu_clk_div4.hw,
|
|
|
|
[CLKID_CPU_CLK_DIV5] = &meson8b_cpu_clk_div5.hw,
|
|
|
|
[CLKID_CPU_CLK_DIV6] = &meson8b_cpu_clk_div6.hw,
|
|
|
|
[CLKID_CPU_CLK_DIV7] = &meson8b_cpu_clk_div7.hw,
|
|
|
|
[CLKID_CPU_CLK_DIV8] = &meson8b_cpu_clk_div8.hw,
|
2019-02-11 06:26:03 +08:00
|
|
|
[CLKID_APB_SEL] = &meson8b_apb_clk_sel.hw,
|
|
|
|
[CLKID_APB] = &meson8b_apb_clk_gate.hw,
|
2018-11-23 05:40:17 +08:00
|
|
|
[CLKID_PERIPH_SEL] = &meson8b_periph_clk_sel.hw,
|
|
|
|
[CLKID_PERIPH] = &meson8b_periph_clk_gate.hw,
|
|
|
|
[CLKID_AXI_SEL] = &meson8b_axi_clk_sel.hw,
|
|
|
|
[CLKID_AXI] = &meson8b_axi_clk_gate.hw,
|
|
|
|
[CLKID_L2_DRAM_SEL] = &meson8b_l2_dram_clk_sel.hw,
|
|
|
|
[CLKID_L2_DRAM] = &meson8b_l2_dram_clk_gate.hw,
|
clk: meson: meson8b: add the read-only video clock trees
Add all clocks to give us the final video clocks within the Meson8,
Meson8b and Meson8m2 SoCs. The final video clocks are:
- cts_enct
- cts_encl
- cts_encp
- cts_enci
- cts_vdac0
- hdmi_tx_pixel
- hdmi_sys
Add multiple clocks in between which are needed to implement these
clocks:
- Opposed to GXBB there is no pre-multiplier for the PLL input. The
assumption here is that the multiplier is required to achieve the HDMI
2.0 clock rates (which are up to twice the rate of the HDMI 1.4
rates).
- The main PLL is called "HDMI PLL" or "HPLL" in the datasheet. Rename
our existing "vid_pll_dco" to "hdmi_pll_dco". The actual VID_PLL clock
also exists further down the tree.
- Rename the existing "vid_pll" clock (which is the OD divider at
HHI_VID_PLL_CNTL[17:16]) to "hdmi_pll_lvds_out" to match the naming
from the datasheet.
- Add the second OD divider called "hdmi_pll_hdmi_out" at
HHI_VID_PLL_CNTL[19:18].
- Add the "vid_pll_in_sel" which can choose between "hdmi_pll_dco" and
another parent. However, the second parent is not use on Amlogic's
3.10 kernel for HDMI or CVBS output so just leave a TODO in the code.
- Add the "vid_pll_in_en" which is located after "vid_pll_in_sel"
according to the datasheet.
- Add "vid_pll_pre_div" which is used for divide-by-5 and divide-by-6 in
Amlogic's 3.10 kernel sources.
- Add "vid_pll_post_div" which divides the output of "vid_pll_pre_div"
further down. The Amlogic 3.10 kernel configures this as divide-by-2
with "vid_pll_pre_div" being configured as divide-by-5 to achieve a
total divider of 10.
- Add the real "vid_pll" clock which selects between "vid_pll_pre_div",
"vid_pll_post_div" and a third "vid_pll_pre_div_mult7_div2" (which is
"vid_pll_pre_div" divided by 3.5). The latter is not supported yet
because it's not used in Amlogic's 3.10 kernel. The "vid_pll" clock
rate can also be measured by clkmsr to check whether this
implementation is correct.
- Add "vid_pll_final_div" which is a post-divider for "vid_pll" and it's
used as input for "vclk" and "vclk2"
- Add the two symmetric "vclk" and "vclk" clock trees, each with a
divide-by-1, divide-by-2, divide-by-4, divide-by-6 and divide-by-12
clock and a divider for each clock.
- Add the "cts_enct", "cts_encp" and "hdmi_tx_pixel" clocks which each
have their own gate and can select between any of the five "vclk"
dividers.
- Add the "cts_encl" and "cts_vdac0" clocks which each have their own
gate and can select between any of the five "vclk2" dividers.
The "hdmi_sys" clock is a different than these video clocks. It takes
"xtal" as input (there are three more but unknown parents). Add this
clock as well as it's used by the HDMI controller. Amlogic's 3.10 kernel
always configures this as "xtal divided by 1", so we can ignore the
other parents for now.
This was tested on Meson8b and Meson8m2 boards by comparing the common
clock framework output with the clock measurer output. The following
video modes were first set in u-boot (by running "video dev open $mode")
before booting Linux:
4K2K30HZ (only supported by Meson8m2, not tested on Meson8b):
- vid_pll: 297000000Hz
- cts_encp: 297000000Hz
- hdmi_tx_pixel: 297000000Hz
1080P:
- vid_pll: 148500000Hz
- cts_encp: 148500000Hz
- hdmi_tx_pixel: 148500000Hz
720P:
- vid_pll: 148500000Hz
- cts_encp: 148500000Hz
- hdmi_tx_pixel: 74250000Hz
480P:
- vid_pll: 216000000Hz
- cts_encp: 54000000Hz
- hdmi_tx_pixel: 27000000Hz
Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
Link: https://lkml.kernel.org/r/20181202214220.7715-4-martin.blumenstingl@googlemail.com
2018-12-03 05:42:20 +08:00
|
|
|
[CLKID_HDMI_PLL_LVDS_OUT] = &meson8b_hdmi_pll_lvds_out.hw,
|
|
|
|
[CLKID_HDMI_PLL_HDMI_OUT] = &meson8b_hdmi_pll_hdmi_out.hw,
|
|
|
|
[CLKID_VID_PLL_IN_SEL] = &meson8b_vid_pll_in_sel.hw,
|
|
|
|
[CLKID_VID_PLL_IN_EN] = &meson8b_vid_pll_in_en.hw,
|
|
|
|
[CLKID_VID_PLL_PRE_DIV] = &meson8b_vid_pll_pre_div.hw,
|
|
|
|
[CLKID_VID_PLL_POST_DIV] = &meson8b_vid_pll_post_div.hw,
|
|
|
|
[CLKID_VID_PLL_FINAL_DIV] = &meson8b_vid_pll_final_div.hw,
|
|
|
|
[CLKID_VCLK_IN_SEL] = &meson8b_vclk_in_sel.hw,
|
|
|
|
[CLKID_VCLK_IN_EN] = &meson8b_vclk_in_en.hw,
|
|
|
|
[CLKID_VCLK_DIV1] = &meson8b_vclk_div1_gate.hw,
|
|
|
|
[CLKID_VCLK_DIV2_DIV] = &meson8b_vclk_div2_div.hw,
|
|
|
|
[CLKID_VCLK_DIV2] = &meson8b_vclk_div2_div_gate.hw,
|
|
|
|
[CLKID_VCLK_DIV4_DIV] = &meson8b_vclk_div4_div.hw,
|
|
|
|
[CLKID_VCLK_DIV4] = &meson8b_vclk_div4_div_gate.hw,
|
|
|
|
[CLKID_VCLK_DIV6_DIV] = &meson8b_vclk_div6_div.hw,
|
|
|
|
[CLKID_VCLK_DIV6] = &meson8b_vclk_div6_div_gate.hw,
|
|
|
|
[CLKID_VCLK_DIV12_DIV] = &meson8b_vclk_div12_div.hw,
|
|
|
|
[CLKID_VCLK_DIV12] = &meson8b_vclk_div12_div_gate.hw,
|
|
|
|
[CLKID_VCLK2_IN_SEL] = &meson8b_vclk2_in_sel.hw,
|
|
|
|
[CLKID_VCLK2_IN_EN] = &meson8b_vclk2_clk_in_en.hw,
|
|
|
|
[CLKID_VCLK2_DIV1] = &meson8b_vclk2_div1_gate.hw,
|
|
|
|
[CLKID_VCLK2_DIV2_DIV] = &meson8b_vclk2_div2_div.hw,
|
|
|
|
[CLKID_VCLK2_DIV2] = &meson8b_vclk2_div2_div_gate.hw,
|
|
|
|
[CLKID_VCLK2_DIV4_DIV] = &meson8b_vclk2_div4_div.hw,
|
|
|
|
[CLKID_VCLK2_DIV4] = &meson8b_vclk2_div4_div_gate.hw,
|
|
|
|
[CLKID_VCLK2_DIV6_DIV] = &meson8b_vclk2_div6_div.hw,
|
|
|
|
[CLKID_VCLK2_DIV6] = &meson8b_vclk2_div6_div_gate.hw,
|
|
|
|
[CLKID_VCLK2_DIV12_DIV] = &meson8b_vclk2_div12_div.hw,
|
|
|
|
[CLKID_VCLK2_DIV12] = &meson8b_vclk2_div12_div_gate.hw,
|
|
|
|
[CLKID_CTS_ENCT_SEL] = &meson8b_cts_enct_sel.hw,
|
|
|
|
[CLKID_CTS_ENCT] = &meson8b_cts_enct.hw,
|
|
|
|
[CLKID_CTS_ENCP_SEL] = &meson8b_cts_encp_sel.hw,
|
|
|
|
[CLKID_CTS_ENCP] = &meson8b_cts_encp.hw,
|
|
|
|
[CLKID_CTS_ENCI_SEL] = &meson8b_cts_enci_sel.hw,
|
|
|
|
[CLKID_CTS_ENCI] = &meson8b_cts_enci.hw,
|
|
|
|
[CLKID_HDMI_TX_PIXEL_SEL] = &meson8b_hdmi_tx_pixel_sel.hw,
|
|
|
|
[CLKID_HDMI_TX_PIXEL] = &meson8b_hdmi_tx_pixel.hw,
|
|
|
|
[CLKID_CTS_ENCL_SEL] = &meson8b_cts_encl_sel.hw,
|
|
|
|
[CLKID_CTS_ENCL] = &meson8b_cts_encl.hw,
|
|
|
|
[CLKID_CTS_VDAC0_SEL] = &meson8b_cts_vdac0_sel.hw,
|
|
|
|
[CLKID_CTS_VDAC0] = &meson8b_cts_vdac0.hw,
|
|
|
|
[CLKID_HDMI_SYS_SEL] = &meson8b_hdmi_sys_sel.hw,
|
|
|
|
[CLKID_HDMI_SYS_DIV] = &meson8b_hdmi_sys_div.hw,
|
|
|
|
[CLKID_HDMI_SYS] = &meson8b_hdmi_sys.hw,
|
2018-12-09 01:12:45 +08:00
|
|
|
[CLKID_MALI_0_SEL] = &meson8b_mali_0_sel.hw,
|
|
|
|
[CLKID_MALI_0_DIV] = &meson8b_mali_0_div.hw,
|
|
|
|
[CLKID_MALI_0] = &meson8b_mali_0.hw,
|
|
|
|
[CLKID_MALI_1_SEL] = &meson8b_mali_1_sel.hw,
|
|
|
|
[CLKID_MALI_1_DIV] = &meson8b_mali_1_div.hw,
|
|
|
|
[CLKID_MALI_1] = &meson8b_mali_1.hw,
|
|
|
|
[CLKID_MALI] = &meson8b_mali.hw,
|
2017-07-28 00:17:54 +08:00
|
|
|
[CLK_NR_CLKS] = NULL,
|
2016-04-29 03:00:52 +08:00
|
|
|
},
|
|
|
|
.num = CLK_NR_CLKS,
|
|
|
|
};
|
|
|
|
|
2018-02-12 22:58:36 +08:00
|
|
|
static struct clk_regmap *const meson8b_clk_regmaps[] = {
|
2016-08-28 01:40:54 +08:00
|
|
|
&meson8b_clk81,
|
|
|
|
&meson8b_ddr,
|
|
|
|
&meson8b_dos,
|
|
|
|
&meson8b_isa,
|
|
|
|
&meson8b_pl301,
|
|
|
|
&meson8b_periphs,
|
|
|
|
&meson8b_spicc,
|
|
|
|
&meson8b_i2c,
|
|
|
|
&meson8b_sar_adc,
|
|
|
|
&meson8b_smart_card,
|
|
|
|
&meson8b_rng0,
|
|
|
|
&meson8b_uart0,
|
|
|
|
&meson8b_sdhc,
|
|
|
|
&meson8b_stream,
|
|
|
|
&meson8b_async_fifo,
|
|
|
|
&meson8b_sdio,
|
|
|
|
&meson8b_abuf,
|
|
|
|
&meson8b_hiu_iface,
|
|
|
|
&meson8b_assist_misc,
|
|
|
|
&meson8b_spi,
|
|
|
|
&meson8b_i2s_spdif,
|
|
|
|
&meson8b_eth,
|
|
|
|
&meson8b_demux,
|
|
|
|
&meson8b_aiu_glue,
|
|
|
|
&meson8b_iec958,
|
|
|
|
&meson8b_i2s_out,
|
|
|
|
&meson8b_amclk,
|
|
|
|
&meson8b_aififo2,
|
|
|
|
&meson8b_mixer,
|
|
|
|
&meson8b_mixer_iface,
|
|
|
|
&meson8b_adc,
|
|
|
|
&meson8b_blkmv,
|
|
|
|
&meson8b_aiu,
|
|
|
|
&meson8b_uart1,
|
|
|
|
&meson8b_g2d,
|
|
|
|
&meson8b_usb0,
|
|
|
|
&meson8b_usb1,
|
|
|
|
&meson8b_reset,
|
|
|
|
&meson8b_nand,
|
|
|
|
&meson8b_dos_parser,
|
|
|
|
&meson8b_usb,
|
|
|
|
&meson8b_vdin1,
|
|
|
|
&meson8b_ahb_arb0,
|
|
|
|
&meson8b_efuse,
|
|
|
|
&meson8b_boot_rom,
|
|
|
|
&meson8b_ahb_data_bus,
|
|
|
|
&meson8b_ahb_ctrl_bus,
|
|
|
|
&meson8b_hdmi_intr_sync,
|
|
|
|
&meson8b_hdmi_pclk,
|
|
|
|
&meson8b_usb1_ddr_bridge,
|
|
|
|
&meson8b_usb0_ddr_bridge,
|
|
|
|
&meson8b_mmc_pclk,
|
|
|
|
&meson8b_dvin,
|
|
|
|
&meson8b_uart2,
|
|
|
|
&meson8b_sana,
|
|
|
|
&meson8b_vpu_intr,
|
|
|
|
&meson8b_sec_ahb_ahb3_bridge,
|
|
|
|
&meson8b_clk81_a9,
|
|
|
|
&meson8b_vclk2_venci0,
|
|
|
|
&meson8b_vclk2_venci1,
|
|
|
|
&meson8b_vclk2_vencp0,
|
|
|
|
&meson8b_vclk2_vencp1,
|
|
|
|
&meson8b_gclk_venci_int,
|
|
|
|
&meson8b_gclk_vencp_int,
|
|
|
|
&meson8b_dac_clk,
|
|
|
|
&meson8b_aoclk_gate,
|
|
|
|
&meson8b_iec958_gate,
|
|
|
|
&meson8b_enc480p,
|
|
|
|
&meson8b_rng1,
|
|
|
|
&meson8b_gclk_vencl_int,
|
|
|
|
&meson8b_vclk2_venclmcc,
|
|
|
|
&meson8b_vclk2_vencl,
|
|
|
|
&meson8b_vclk2_other,
|
|
|
|
&meson8b_edp,
|
|
|
|
&meson8b_ao_media_cpu,
|
|
|
|
&meson8b_ao_ahb_sram,
|
|
|
|
&meson8b_ao_ahb_bus,
|
|
|
|
&meson8b_ao_iface,
|
2018-02-12 22:58:37 +08:00
|
|
|
&meson8b_mpeg_clk_div,
|
2018-02-12 22:58:38 +08:00
|
|
|
&meson8b_mpeg_clk_sel,
|
2018-02-12 22:58:40 +08:00
|
|
|
&meson8b_mpll0,
|
|
|
|
&meson8b_mpll1,
|
|
|
|
&meson8b_mpll2,
|
2018-02-12 22:58:43 +08:00
|
|
|
&meson8b_mpll0_div,
|
|
|
|
&meson8b_mpll1_div,
|
|
|
|
&meson8b_mpll2_div,
|
2018-02-12 22:58:42 +08:00
|
|
|
&meson8b_fixed_pll,
|
|
|
|
&meson8b_sys_pll,
|
2018-02-12 22:58:44 +08:00
|
|
|
&meson8b_cpu_in_sel,
|
|
|
|
&meson8b_cpu_scale_div,
|
|
|
|
&meson8b_cpu_scale_out_sel,
|
|
|
|
&meson8b_cpu_clk,
|
2018-02-19 19:21:44 +08:00
|
|
|
&meson8b_mpll_prediv,
|
2018-02-19 19:21:45 +08:00
|
|
|
&meson8b_fclk_div2,
|
|
|
|
&meson8b_fclk_div3,
|
|
|
|
&meson8b_fclk_div4,
|
|
|
|
&meson8b_fclk_div5,
|
|
|
|
&meson8b_fclk_div7,
|
2018-04-24 03:35:09 +08:00
|
|
|
&meson8b_nand_clk_sel,
|
|
|
|
&meson8b_nand_clk_div,
|
|
|
|
&meson8b_nand_clk_gate,
|
2018-08-01 22:00:52 +08:00
|
|
|
&meson8b_fixed_pll_dco,
|
clk: meson: meson8b: add the read-only video clock trees
Add all clocks to give us the final video clocks within the Meson8,
Meson8b and Meson8m2 SoCs. The final video clocks are:
- cts_enct
- cts_encl
- cts_encp
- cts_enci
- cts_vdac0
- hdmi_tx_pixel
- hdmi_sys
Add multiple clocks in between which are needed to implement these
clocks:
- Opposed to GXBB there is no pre-multiplier for the PLL input. The
assumption here is that the multiplier is required to achieve the HDMI
2.0 clock rates (which are up to twice the rate of the HDMI 1.4
rates).
- The main PLL is called "HDMI PLL" or "HPLL" in the datasheet. Rename
our existing "vid_pll_dco" to "hdmi_pll_dco". The actual VID_PLL clock
also exists further down the tree.
- Rename the existing "vid_pll" clock (which is the OD divider at
HHI_VID_PLL_CNTL[17:16]) to "hdmi_pll_lvds_out" to match the naming
from the datasheet.
- Add the second OD divider called "hdmi_pll_hdmi_out" at
HHI_VID_PLL_CNTL[19:18].
- Add the "vid_pll_in_sel" which can choose between "hdmi_pll_dco" and
another parent. However, the second parent is not use on Amlogic's
3.10 kernel for HDMI or CVBS output so just leave a TODO in the code.
- Add the "vid_pll_in_en" which is located after "vid_pll_in_sel"
according to the datasheet.
- Add "vid_pll_pre_div" which is used for divide-by-5 and divide-by-6 in
Amlogic's 3.10 kernel sources.
- Add "vid_pll_post_div" which divides the output of "vid_pll_pre_div"
further down. The Amlogic 3.10 kernel configures this as divide-by-2
with "vid_pll_pre_div" being configured as divide-by-5 to achieve a
total divider of 10.
- Add the real "vid_pll" clock which selects between "vid_pll_pre_div",
"vid_pll_post_div" and a third "vid_pll_pre_div_mult7_div2" (which is
"vid_pll_pre_div" divided by 3.5). The latter is not supported yet
because it's not used in Amlogic's 3.10 kernel. The "vid_pll" clock
rate can also be measured by clkmsr to check whether this
implementation is correct.
- Add "vid_pll_final_div" which is a post-divider for "vid_pll" and it's
used as input for "vclk" and "vclk2"
- Add the two symmetric "vclk" and "vclk" clock trees, each with a
divide-by-1, divide-by-2, divide-by-4, divide-by-6 and divide-by-12
clock and a divider for each clock.
- Add the "cts_enct", "cts_encp" and "hdmi_tx_pixel" clocks which each
have their own gate and can select between any of the five "vclk"
dividers.
- Add the "cts_encl" and "cts_vdac0" clocks which each have their own
gate and can select between any of the five "vclk2" dividers.
The "hdmi_sys" clock is a different than these video clocks. It takes
"xtal" as input (there are three more but unknown parents). Add this
clock as well as it's used by the HDMI controller. Amlogic's 3.10 kernel
always configures this as "xtal divided by 1", so we can ignore the
other parents for now.
This was tested on Meson8b and Meson8m2 boards by comparing the common
clock framework output with the clock measurer output. The following
video modes were first set in u-boot (by running "video dev open $mode")
before booting Linux:
4K2K30HZ (only supported by Meson8m2, not tested on Meson8b):
- vid_pll: 297000000Hz
- cts_encp: 297000000Hz
- hdmi_tx_pixel: 297000000Hz
1080P:
- vid_pll: 148500000Hz
- cts_encp: 148500000Hz
- hdmi_tx_pixel: 148500000Hz
720P:
- vid_pll: 148500000Hz
- cts_encp: 148500000Hz
- hdmi_tx_pixel: 74250000Hz
480P:
- vid_pll: 216000000Hz
- cts_encp: 54000000Hz
- hdmi_tx_pixel: 27000000Hz
Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
Link: https://lkml.kernel.org/r/20181202214220.7715-4-martin.blumenstingl@googlemail.com
2018-12-03 05:42:20 +08:00
|
|
|
&meson8b_hdmi_pll_dco,
|
2018-08-01 22:00:52 +08:00
|
|
|
&meson8b_sys_pll_dco,
|
2019-02-11 06:26:03 +08:00
|
|
|
&meson8b_apb_clk_sel,
|
|
|
|
&meson8b_apb_clk_gate,
|
2018-11-23 05:40:17 +08:00
|
|
|
&meson8b_periph_clk_sel,
|
|
|
|
&meson8b_periph_clk_gate,
|
|
|
|
&meson8b_axi_clk_sel,
|
|
|
|
&meson8b_axi_clk_gate,
|
|
|
|
&meson8b_l2_dram_clk_sel,
|
|
|
|
&meson8b_l2_dram_clk_gate,
|
clk: meson: meson8b: add the read-only video clock trees
Add all clocks to give us the final video clocks within the Meson8,
Meson8b and Meson8m2 SoCs. The final video clocks are:
- cts_enct
- cts_encl
- cts_encp
- cts_enci
- cts_vdac0
- hdmi_tx_pixel
- hdmi_sys
Add multiple clocks in between which are needed to implement these
clocks:
- Opposed to GXBB there is no pre-multiplier for the PLL input. The
assumption here is that the multiplier is required to achieve the HDMI
2.0 clock rates (which are up to twice the rate of the HDMI 1.4
rates).
- The main PLL is called "HDMI PLL" or "HPLL" in the datasheet. Rename
our existing "vid_pll_dco" to "hdmi_pll_dco". The actual VID_PLL clock
also exists further down the tree.
- Rename the existing "vid_pll" clock (which is the OD divider at
HHI_VID_PLL_CNTL[17:16]) to "hdmi_pll_lvds_out" to match the naming
from the datasheet.
- Add the second OD divider called "hdmi_pll_hdmi_out" at
HHI_VID_PLL_CNTL[19:18].
- Add the "vid_pll_in_sel" which can choose between "hdmi_pll_dco" and
another parent. However, the second parent is not use on Amlogic's
3.10 kernel for HDMI or CVBS output so just leave a TODO in the code.
- Add the "vid_pll_in_en" which is located after "vid_pll_in_sel"
according to the datasheet.
- Add "vid_pll_pre_div" which is used for divide-by-5 and divide-by-6 in
Amlogic's 3.10 kernel sources.
- Add "vid_pll_post_div" which divides the output of "vid_pll_pre_div"
further down. The Amlogic 3.10 kernel configures this as divide-by-2
with "vid_pll_pre_div" being configured as divide-by-5 to achieve a
total divider of 10.
- Add the real "vid_pll" clock which selects between "vid_pll_pre_div",
"vid_pll_post_div" and a third "vid_pll_pre_div_mult7_div2" (which is
"vid_pll_pre_div" divided by 3.5). The latter is not supported yet
because it's not used in Amlogic's 3.10 kernel. The "vid_pll" clock
rate can also be measured by clkmsr to check whether this
implementation is correct.
- Add "vid_pll_final_div" which is a post-divider for "vid_pll" and it's
used as input for "vclk" and "vclk2"
- Add the two symmetric "vclk" and "vclk" clock trees, each with a
divide-by-1, divide-by-2, divide-by-4, divide-by-6 and divide-by-12
clock and a divider for each clock.
- Add the "cts_enct", "cts_encp" and "hdmi_tx_pixel" clocks which each
have their own gate and can select between any of the five "vclk"
dividers.
- Add the "cts_encl" and "cts_vdac0" clocks which each have their own
gate and can select between any of the five "vclk2" dividers.
The "hdmi_sys" clock is a different than these video clocks. It takes
"xtal" as input (there are three more but unknown parents). Add this
clock as well as it's used by the HDMI controller. Amlogic's 3.10 kernel
always configures this as "xtal divided by 1", so we can ignore the
other parents for now.
This was tested on Meson8b and Meson8m2 boards by comparing the common
clock framework output with the clock measurer output. The following
video modes were first set in u-boot (by running "video dev open $mode")
before booting Linux:
4K2K30HZ (only supported by Meson8m2, not tested on Meson8b):
- vid_pll: 297000000Hz
- cts_encp: 297000000Hz
- hdmi_tx_pixel: 297000000Hz
1080P:
- vid_pll: 148500000Hz
- cts_encp: 148500000Hz
- hdmi_tx_pixel: 148500000Hz
720P:
- vid_pll: 148500000Hz
- cts_encp: 148500000Hz
- hdmi_tx_pixel: 74250000Hz
480P:
- vid_pll: 216000000Hz
- cts_encp: 54000000Hz
- hdmi_tx_pixel: 27000000Hz
Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
Link: https://lkml.kernel.org/r/20181202214220.7715-4-martin.blumenstingl@googlemail.com
2018-12-03 05:42:20 +08:00
|
|
|
&meson8b_hdmi_pll_lvds_out,
|
|
|
|
&meson8b_hdmi_pll_hdmi_out,
|
|
|
|
&meson8b_vid_pll_in_sel,
|
|
|
|
&meson8b_vid_pll_in_en,
|
|
|
|
&meson8b_vid_pll_pre_div,
|
|
|
|
&meson8b_vid_pll_post_div,
|
|
|
|
&meson8b_vid_pll,
|
|
|
|
&meson8b_vid_pll_final_div,
|
|
|
|
&meson8b_vclk_in_sel,
|
|
|
|
&meson8b_vclk_in_en,
|
|
|
|
&meson8b_vclk_div1_gate,
|
|
|
|
&meson8b_vclk_div2_div_gate,
|
|
|
|
&meson8b_vclk_div4_div_gate,
|
|
|
|
&meson8b_vclk_div6_div_gate,
|
|
|
|
&meson8b_vclk_div12_div_gate,
|
|
|
|
&meson8b_vclk2_in_sel,
|
|
|
|
&meson8b_vclk2_clk_in_en,
|
|
|
|
&meson8b_vclk2_div1_gate,
|
|
|
|
&meson8b_vclk2_div2_div_gate,
|
|
|
|
&meson8b_vclk2_div4_div_gate,
|
|
|
|
&meson8b_vclk2_div6_div_gate,
|
|
|
|
&meson8b_vclk2_div12_div_gate,
|
|
|
|
&meson8b_cts_enct_sel,
|
|
|
|
&meson8b_cts_enct,
|
|
|
|
&meson8b_cts_encp_sel,
|
|
|
|
&meson8b_cts_encp,
|
|
|
|
&meson8b_cts_enci_sel,
|
|
|
|
&meson8b_cts_enci,
|
|
|
|
&meson8b_hdmi_tx_pixel_sel,
|
|
|
|
&meson8b_hdmi_tx_pixel,
|
|
|
|
&meson8b_cts_encl_sel,
|
|
|
|
&meson8b_cts_encl,
|
|
|
|
&meson8b_cts_vdac0_sel,
|
|
|
|
&meson8b_cts_vdac0,
|
|
|
|
&meson8b_hdmi_sys_sel,
|
|
|
|
&meson8b_hdmi_sys_div,
|
|
|
|
&meson8b_hdmi_sys,
|
2018-12-09 01:12:45 +08:00
|
|
|
&meson8b_mali_0_sel,
|
|
|
|
&meson8b_mali_0_div,
|
|
|
|
&meson8b_mali_0,
|
|
|
|
&meson8b_mali_1_sel,
|
|
|
|
&meson8b_mali_1_div,
|
|
|
|
&meson8b_mali_1,
|
|
|
|
&meson8b_mali,
|
2016-08-28 01:40:54 +08:00
|
|
|
};
|
|
|
|
|
2017-07-29 05:13:12 +08:00
|
|
|
static const struct meson8b_clk_reset_line {
|
|
|
|
u32 reg;
|
|
|
|
u8 bit_idx;
|
|
|
|
} meson8b_clk_reset_bits[] = {
|
|
|
|
[CLKC_RESET_L2_CACHE_SOFT_RESET] = {
|
|
|
|
.reg = HHI_SYS_CPU_CLK_CNTL0, .bit_idx = 30
|
|
|
|
},
|
|
|
|
[CLKC_RESET_AXI_64_TO_128_BRIDGE_A5_SOFT_RESET] = {
|
|
|
|
.reg = HHI_SYS_CPU_CLK_CNTL0, .bit_idx = 29
|
|
|
|
},
|
|
|
|
[CLKC_RESET_SCU_SOFT_RESET] = {
|
|
|
|
.reg = HHI_SYS_CPU_CLK_CNTL0, .bit_idx = 28
|
|
|
|
},
|
|
|
|
[CLKC_RESET_CPU3_SOFT_RESET] = {
|
|
|
|
.reg = HHI_SYS_CPU_CLK_CNTL0, .bit_idx = 27
|
|
|
|
},
|
|
|
|
[CLKC_RESET_CPU2_SOFT_RESET] = {
|
|
|
|
.reg = HHI_SYS_CPU_CLK_CNTL0, .bit_idx = 26
|
|
|
|
},
|
|
|
|
[CLKC_RESET_CPU1_SOFT_RESET] = {
|
|
|
|
.reg = HHI_SYS_CPU_CLK_CNTL0, .bit_idx = 25
|
|
|
|
},
|
|
|
|
[CLKC_RESET_CPU0_SOFT_RESET] = {
|
|
|
|
.reg = HHI_SYS_CPU_CLK_CNTL0, .bit_idx = 24
|
|
|
|
},
|
|
|
|
[CLKC_RESET_A5_GLOBAL_RESET] = {
|
|
|
|
.reg = HHI_SYS_CPU_CLK_CNTL0, .bit_idx = 18
|
|
|
|
},
|
|
|
|
[CLKC_RESET_A5_AXI_SOFT_RESET] = {
|
|
|
|
.reg = HHI_SYS_CPU_CLK_CNTL0, .bit_idx = 17
|
|
|
|
},
|
|
|
|
[CLKC_RESET_A5_ABP_SOFT_RESET] = {
|
|
|
|
.reg = HHI_SYS_CPU_CLK_CNTL0, .bit_idx = 16
|
|
|
|
},
|
|
|
|
[CLKC_RESET_AXI_64_TO_128_BRIDGE_MMC_SOFT_RESET] = {
|
|
|
|
.reg = HHI_SYS_CPU_CLK_CNTL1, .bit_idx = 30
|
|
|
|
},
|
|
|
|
[CLKC_RESET_VID_CLK_CNTL_SOFT_RESET] = {
|
|
|
|
.reg = HHI_VID_CLK_CNTL, .bit_idx = 15
|
|
|
|
},
|
|
|
|
[CLKC_RESET_VID_DIVIDER_CNTL_SOFT_RESET_POST] = {
|
|
|
|
.reg = HHI_VID_DIVIDER_CNTL, .bit_idx = 7
|
|
|
|
},
|
|
|
|
[CLKC_RESET_VID_DIVIDER_CNTL_SOFT_RESET_PRE] = {
|
|
|
|
.reg = HHI_VID_DIVIDER_CNTL, .bit_idx = 3
|
|
|
|
},
|
|
|
|
[CLKC_RESET_VID_DIVIDER_CNTL_RESET_N_POST] = {
|
|
|
|
.reg = HHI_VID_DIVIDER_CNTL, .bit_idx = 1
|
|
|
|
},
|
|
|
|
[CLKC_RESET_VID_DIVIDER_CNTL_RESET_N_PRE] = {
|
|
|
|
.reg = HHI_VID_DIVIDER_CNTL, .bit_idx = 0
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
|
|
|
static int meson8b_clk_reset_update(struct reset_controller_dev *rcdev,
|
|
|
|
unsigned long id, bool assert)
|
|
|
|
{
|
|
|
|
struct meson8b_clk_reset *meson8b_clk_reset =
|
|
|
|
container_of(rcdev, struct meson8b_clk_reset, reset);
|
|
|
|
unsigned long flags;
|
|
|
|
const struct meson8b_clk_reset_line *reset;
|
|
|
|
|
|
|
|
if (id >= ARRAY_SIZE(meson8b_clk_reset_bits))
|
|
|
|
return -EINVAL;
|
|
|
|
|
|
|
|
reset = &meson8b_clk_reset_bits[id];
|
|
|
|
|
2017-12-11 22:13:43 +08:00
|
|
|
spin_lock_irqsave(&meson_clk_lock, flags);
|
2017-07-29 05:13:12 +08:00
|
|
|
|
|
|
|
if (assert)
|
2018-07-22 03:14:00 +08:00
|
|
|
regmap_update_bits(meson8b_clk_reset->regmap, reset->reg,
|
|
|
|
BIT(reset->bit_idx), BIT(reset->bit_idx));
|
2017-07-29 05:13:12 +08:00
|
|
|
else
|
2018-07-22 03:14:00 +08:00
|
|
|
regmap_update_bits(meson8b_clk_reset->regmap, reset->reg,
|
|
|
|
BIT(reset->bit_idx), 0);
|
2017-07-29 05:13:12 +08:00
|
|
|
|
2017-12-11 22:13:43 +08:00
|
|
|
spin_unlock_irqrestore(&meson_clk_lock, flags);
|
2017-07-29 05:13:12 +08:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int meson8b_clk_reset_assert(struct reset_controller_dev *rcdev,
|
|
|
|
unsigned long id)
|
|
|
|
{
|
|
|
|
return meson8b_clk_reset_update(rcdev, id, true);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int meson8b_clk_reset_deassert(struct reset_controller_dev *rcdev,
|
|
|
|
unsigned long id)
|
|
|
|
{
|
|
|
|
return meson8b_clk_reset_update(rcdev, id, false);
|
|
|
|
}
|
|
|
|
|
|
|
|
static const struct reset_control_ops meson8b_clk_reset_ops = {
|
|
|
|
.assert = meson8b_clk_reset_assert,
|
|
|
|
.deassert = meson8b_clk_reset_deassert,
|
|
|
|
};
|
|
|
|
|
2018-11-16 06:40:47 +08:00
|
|
|
struct meson8b_nb_data {
|
|
|
|
struct notifier_block nb;
|
|
|
|
struct clk_hw_onecell_data *onecell_data;
|
|
|
|
};
|
|
|
|
|
|
|
|
static int meson8b_cpu_clk_notifier_cb(struct notifier_block *nb,
|
|
|
|
unsigned long event, void *data)
|
|
|
|
{
|
|
|
|
struct meson8b_nb_data *nb_data =
|
|
|
|
container_of(nb, struct meson8b_nb_data, nb);
|
|
|
|
struct clk_hw **hws = nb_data->onecell_data->hws;
|
|
|
|
struct clk_hw *cpu_clk_hw, *parent_clk_hw;
|
|
|
|
struct clk *cpu_clk, *parent_clk;
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
switch (event) {
|
|
|
|
case PRE_RATE_CHANGE:
|
|
|
|
parent_clk_hw = hws[CLKID_XTAL];
|
|
|
|
break;
|
|
|
|
|
|
|
|
case POST_RATE_CHANGE:
|
|
|
|
parent_clk_hw = hws[CLKID_CPU_SCALE_OUT_SEL];
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
return NOTIFY_DONE;
|
|
|
|
}
|
|
|
|
|
|
|
|
cpu_clk_hw = hws[CLKID_CPUCLK];
|
|
|
|
cpu_clk = __clk_lookup(clk_hw_get_name(cpu_clk_hw));
|
|
|
|
|
|
|
|
parent_clk = __clk_lookup(clk_hw_get_name(parent_clk_hw));
|
|
|
|
|
|
|
|
ret = clk_set_parent(cpu_clk, parent_clk);
|
|
|
|
if (ret)
|
|
|
|
return notifier_from_errno(ret);
|
|
|
|
|
|
|
|
udelay(100);
|
|
|
|
|
|
|
|
return NOTIFY_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
static struct meson8b_nb_data meson8b_cpu_nb_data = {
|
|
|
|
.nb.notifier_call = meson8b_cpu_clk_notifier_cb,
|
|
|
|
};
|
|
|
|
|
2018-02-12 22:58:35 +08:00
|
|
|
static const struct regmap_config clkc_regmap_config = {
|
|
|
|
.reg_bits = 32,
|
|
|
|
.val_bits = 32,
|
|
|
|
.reg_stride = 4,
|
|
|
|
};
|
|
|
|
|
2018-12-09 01:12:44 +08:00
|
|
|
static void __init meson8b_clkc_init_common(struct device_node *np,
|
|
|
|
struct clk_hw_onecell_data *clk_hw_onecell_data)
|
2017-07-29 05:13:12 +08:00
|
|
|
{
|
|
|
|
struct meson8b_clk_reset *rstc;
|
2018-11-16 06:40:47 +08:00
|
|
|
const char *notifier_clk_name;
|
|
|
|
struct clk *notifier_clk;
|
2018-07-22 03:13:59 +08:00
|
|
|
void __iomem *clk_base;
|
|
|
|
struct regmap *map;
|
|
|
|
int i, ret;
|
2017-07-29 05:13:12 +08:00
|
|
|
|
2018-10-28 20:08:58 +08:00
|
|
|
map = syscon_node_to_regmap(of_get_parent(np));
|
|
|
|
if (IS_ERR(map)) {
|
|
|
|
pr_info("failed to get HHI regmap - Trying obsolete regs\n");
|
2017-07-29 05:13:12 +08:00
|
|
|
|
2018-10-28 20:08:58 +08:00
|
|
|
/* Generic clocks, PLLs and some of the reset-bits */
|
|
|
|
clk_base = of_iomap(np, 1);
|
|
|
|
if (!clk_base) {
|
|
|
|
pr_err("%s: Unable to map clk base\n", __func__);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
map = regmap_init_mmio(NULL, clk_base, &clkc_regmap_config);
|
|
|
|
if (IS_ERR(map))
|
|
|
|
return;
|
|
|
|
}
|
2018-07-22 03:13:59 +08:00
|
|
|
|
2017-07-29 05:13:12 +08:00
|
|
|
rstc = kzalloc(sizeof(*rstc), GFP_KERNEL);
|
|
|
|
if (!rstc)
|
|
|
|
return;
|
|
|
|
|
|
|
|
/* Reset Controller */
|
2018-07-22 03:14:00 +08:00
|
|
|
rstc->regmap = map;
|
2017-07-29 05:13:12 +08:00
|
|
|
rstc->reset.ops = &meson8b_clk_reset_ops;
|
|
|
|
rstc->reset.nr_resets = ARRAY_SIZE(meson8b_clk_reset_bits);
|
|
|
|
rstc->reset.of_node = np;
|
|
|
|
ret = reset_controller_register(&rstc->reset);
|
|
|
|
if (ret) {
|
|
|
|
pr_err("%s: Failed to register clkc reset controller: %d\n",
|
|
|
|
__func__, ret);
|
|
|
|
return;
|
|
|
|
}
|
2018-07-22 03:13:59 +08:00
|
|
|
|
|
|
|
/* Populate regmap for the regmap backed clocks */
|
|
|
|
for (i = 0; i < ARRAY_SIZE(meson8b_clk_regmaps); i++)
|
|
|
|
meson8b_clk_regmaps[i]->map = map;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* register all clks
|
|
|
|
* CLKID_UNUSED = 0, so skip it and start with CLKID_XTAL = 1
|
|
|
|
*/
|
|
|
|
for (i = CLKID_XTAL; i < CLK_NR_CLKS; i++) {
|
|
|
|
/* array might be sparse */
|
2018-12-09 01:12:44 +08:00
|
|
|
if (!clk_hw_onecell_data->hws[i])
|
2018-07-22 03:13:59 +08:00
|
|
|
continue;
|
|
|
|
|
2018-12-09 01:12:44 +08:00
|
|
|
ret = clk_hw_register(NULL, clk_hw_onecell_data->hws[i]);
|
2018-07-22 03:13:59 +08:00
|
|
|
if (ret)
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2018-12-09 01:12:44 +08:00
|
|
|
meson8b_cpu_nb_data.onecell_data = clk_hw_onecell_data;
|
|
|
|
|
2018-11-16 06:40:47 +08:00
|
|
|
/*
|
|
|
|
* FIXME we shouldn't program the muxes in notifier handlers. The
|
|
|
|
* tricky programming sequence will be handled by the forthcoming
|
|
|
|
* coordinated clock rates mechanism once that feature is released.
|
|
|
|
*/
|
|
|
|
notifier_clk_name = clk_hw_get_name(&meson8b_cpu_scale_out_sel.hw);
|
|
|
|
notifier_clk = __clk_lookup(notifier_clk_name);
|
|
|
|
ret = clk_notifier_register(notifier_clk, &meson8b_cpu_nb_data.nb);
|
|
|
|
if (ret) {
|
|
|
|
pr_err("%s: failed to register the CPU clock notifier\n",
|
|
|
|
__func__);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2018-07-22 03:13:59 +08:00
|
|
|
ret = of_clk_add_hw_provider(np, of_clk_hw_onecell_get,
|
2018-12-09 01:12:44 +08:00
|
|
|
clk_hw_onecell_data);
|
2018-07-22 03:13:59 +08:00
|
|
|
if (ret)
|
|
|
|
pr_err("%s: failed to register clock provider\n", __func__);
|
2017-07-29 05:13:12 +08:00
|
|
|
}
|
|
|
|
|
2018-12-09 01:12:44 +08:00
|
|
|
static void __init meson8_clkc_init(struct device_node *np)
|
|
|
|
{
|
|
|
|
return meson8b_clkc_init_common(np, &meson8_hw_onecell_data);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void __init meson8b_clkc_init(struct device_node *np)
|
|
|
|
{
|
|
|
|
return meson8b_clkc_init_common(np, &meson8b_hw_onecell_data);
|
|
|
|
}
|
|
|
|
|
2017-07-29 05:13:12 +08:00
|
|
|
CLK_OF_DECLARE_DRIVER(meson8_clkc, "amlogic,meson8-clkc",
|
2018-12-09 01:12:44 +08:00
|
|
|
meson8_clkc_init);
|
2017-07-29 05:13:12 +08:00
|
|
|
CLK_OF_DECLARE_DRIVER(meson8b_clkc, "amlogic,meson8b-clkc",
|
2018-07-22 03:13:59 +08:00
|
|
|
meson8b_clkc_init);
|
2017-07-29 05:13:12 +08:00
|
|
|
CLK_OF_DECLARE_DRIVER(meson8m2_clkc, "amlogic,meson8m2-clkc",
|
2018-07-22 03:13:59 +08:00
|
|
|
meson8b_clkc_init);
|