clk: bcm2835: reorganize bcm2835_clock_array assignment
Reorganize bcm2835_clock_array so that there is no more need for separate bcm2835_*_data structures to be defined. Instead the required structures are generated inline via helper macros. To allow this to also work for pll alone it was required that the parent_pll was changed from a pointer to bcm2835_pll_data to the name of the pll instead. Signed-off-by: Martin Sperl <kernel@martin.sperl.org> Signed-off-by: Eric Anholt <eric@anholt.net> Reviewed-by: Eric Anholt <eric@anholt.net>
This commit is contained in:
parent
56eb3a2ed9
commit
3b15afefbe
|
@ -415,115 +415,10 @@ static const struct bcm2835_pll_ana_bits bcm2835_ana_pllh = {
|
|||
.fb_prediv_mask = BIT(11),
|
||||
};
|
||||
|
||||
/*
|
||||
* PLLA is the auxiliary PLL, used to drive the CCP2 (Compact Camera
|
||||
* Port 2) transmitter clock.
|
||||
*
|
||||
* It is in the PX LDO power domain, which is on when the AUDIO domain
|
||||
* is on.
|
||||
*/
|
||||
static const struct bcm2835_pll_data bcm2835_plla_data = {
|
||||
.name = "plla",
|
||||
.cm_ctrl_reg = CM_PLLA,
|
||||
.a2w_ctrl_reg = A2W_PLLA_CTRL,
|
||||
.frac_reg = A2W_PLLA_FRAC,
|
||||
.ana_reg_base = A2W_PLLA_ANA0,
|
||||
.reference_enable_mask = A2W_XOSC_CTRL_PLLA_ENABLE,
|
||||
.lock_mask = CM_LOCK_FLOCKA,
|
||||
|
||||
.ana = &bcm2835_ana_default,
|
||||
|
||||
.min_rate = 600000000u,
|
||||
.max_rate = 2400000000u,
|
||||
.max_fb_rate = BCM2835_MAX_FB_RATE,
|
||||
};
|
||||
|
||||
/* PLLB is used for the ARM's clock. */
|
||||
static const struct bcm2835_pll_data bcm2835_pllb_data = {
|
||||
.name = "pllb",
|
||||
.cm_ctrl_reg = CM_PLLB,
|
||||
.a2w_ctrl_reg = A2W_PLLB_CTRL,
|
||||
.frac_reg = A2W_PLLB_FRAC,
|
||||
.ana_reg_base = A2W_PLLB_ANA0,
|
||||
.reference_enable_mask = A2W_XOSC_CTRL_PLLB_ENABLE,
|
||||
.lock_mask = CM_LOCK_FLOCKB,
|
||||
|
||||
.ana = &bcm2835_ana_default,
|
||||
|
||||
.min_rate = 600000000u,
|
||||
.max_rate = 3000000000u,
|
||||
.max_fb_rate = BCM2835_MAX_FB_RATE,
|
||||
};
|
||||
|
||||
/*
|
||||
* PLLC is the core PLL, used to drive the core VPU clock.
|
||||
*
|
||||
* It is in the PX LDO power domain, which is on when the AUDIO domain
|
||||
* is on.
|
||||
*/
|
||||
static const struct bcm2835_pll_data bcm2835_pllc_data = {
|
||||
.name = "pllc",
|
||||
.cm_ctrl_reg = CM_PLLC,
|
||||
.a2w_ctrl_reg = A2W_PLLC_CTRL,
|
||||
.frac_reg = A2W_PLLC_FRAC,
|
||||
.ana_reg_base = A2W_PLLC_ANA0,
|
||||
.reference_enable_mask = A2W_XOSC_CTRL_PLLC_ENABLE,
|
||||
.lock_mask = CM_LOCK_FLOCKC,
|
||||
|
||||
.ana = &bcm2835_ana_default,
|
||||
|
||||
.min_rate = 600000000u,
|
||||
.max_rate = 3000000000u,
|
||||
.max_fb_rate = BCM2835_MAX_FB_RATE,
|
||||
};
|
||||
|
||||
/*
|
||||
* PLLD is the display PLL, used to drive DSI display panels.
|
||||
*
|
||||
* It is in the PX LDO power domain, which is on when the AUDIO domain
|
||||
* is on.
|
||||
*/
|
||||
static const struct bcm2835_pll_data bcm2835_plld_data = {
|
||||
.name = "plld",
|
||||
.cm_ctrl_reg = CM_PLLD,
|
||||
.a2w_ctrl_reg = A2W_PLLD_CTRL,
|
||||
.frac_reg = A2W_PLLD_FRAC,
|
||||
.ana_reg_base = A2W_PLLD_ANA0,
|
||||
.reference_enable_mask = A2W_XOSC_CTRL_DDR_ENABLE,
|
||||
.lock_mask = CM_LOCK_FLOCKD,
|
||||
|
||||
.ana = &bcm2835_ana_default,
|
||||
|
||||
.min_rate = 600000000u,
|
||||
.max_rate = 2400000000u,
|
||||
.max_fb_rate = BCM2835_MAX_FB_RATE,
|
||||
};
|
||||
|
||||
/*
|
||||
* PLLH is used to supply the pixel clock or the AUX clock for the TV
|
||||
* encoder.
|
||||
*
|
||||
* It is in the HDMI power domain.
|
||||
*/
|
||||
static const struct bcm2835_pll_data bcm2835_pllh_data = {
|
||||
"pllh",
|
||||
.cm_ctrl_reg = CM_PLLH,
|
||||
.a2w_ctrl_reg = A2W_PLLH_CTRL,
|
||||
.frac_reg = A2W_PLLH_FRAC,
|
||||
.ana_reg_base = A2W_PLLH_ANA0,
|
||||
.reference_enable_mask = A2W_XOSC_CTRL_PLLC_ENABLE,
|
||||
.lock_mask = CM_LOCK_FLOCKH,
|
||||
|
||||
.ana = &bcm2835_ana_pllh,
|
||||
|
||||
.min_rate = 600000000u,
|
||||
.max_rate = 3000000000u,
|
||||
.max_fb_rate = BCM2835_MAX_FB_RATE,
|
||||
};
|
||||
|
||||
struct bcm2835_pll_divider_data {
|
||||
const char *name;
|
||||
const struct bcm2835_pll_data *source_pll;
|
||||
const char *source_pll;
|
||||
|
||||
u32 cm_reg;
|
||||
u32 a2w_reg;
|
||||
|
||||
|
@ -532,124 +427,6 @@ struct bcm2835_pll_divider_data {
|
|||
u32 fixed_divider;
|
||||
};
|
||||
|
||||
static const struct bcm2835_pll_divider_data bcm2835_plla_core_data = {
|
||||
.name = "plla_core",
|
||||
.source_pll = &bcm2835_plla_data,
|
||||
.cm_reg = CM_PLLA,
|
||||
.a2w_reg = A2W_PLLA_CORE,
|
||||
.load_mask = CM_PLLA_LOADCORE,
|
||||
.hold_mask = CM_PLLA_HOLDCORE,
|
||||
.fixed_divider = 1,
|
||||
};
|
||||
|
||||
static const struct bcm2835_pll_divider_data bcm2835_plla_per_data = {
|
||||
.name = "plla_per",
|
||||
.source_pll = &bcm2835_plla_data,
|
||||
.cm_reg = CM_PLLA,
|
||||
.a2w_reg = A2W_PLLA_PER,
|
||||
.load_mask = CM_PLLA_LOADPER,
|
||||
.hold_mask = CM_PLLA_HOLDPER,
|
||||
.fixed_divider = 1,
|
||||
};
|
||||
|
||||
static const struct bcm2835_pll_divider_data bcm2835_pllb_arm_data = {
|
||||
.name = "pllb_arm",
|
||||
.source_pll = &bcm2835_pllb_data,
|
||||
.cm_reg = CM_PLLB,
|
||||
.a2w_reg = A2W_PLLB_ARM,
|
||||
.load_mask = CM_PLLB_LOADARM,
|
||||
.hold_mask = CM_PLLB_HOLDARM,
|
||||
.fixed_divider = 1,
|
||||
};
|
||||
|
||||
static const struct bcm2835_pll_divider_data bcm2835_pllc_core0_data = {
|
||||
.name = "pllc_core0",
|
||||
.source_pll = &bcm2835_pllc_data,
|
||||
.cm_reg = CM_PLLC,
|
||||
.a2w_reg = A2W_PLLC_CORE0,
|
||||
.load_mask = CM_PLLC_LOADCORE0,
|
||||
.hold_mask = CM_PLLC_HOLDCORE0,
|
||||
.fixed_divider = 1,
|
||||
};
|
||||
|
||||
static const struct bcm2835_pll_divider_data bcm2835_pllc_core1_data = {
|
||||
.name = "pllc_core1", .source_pll = &bcm2835_pllc_data,
|
||||
.cm_reg = CM_PLLC, A2W_PLLC_CORE1,
|
||||
.load_mask = CM_PLLC_LOADCORE1,
|
||||
.hold_mask = CM_PLLC_HOLDCORE1,
|
||||
.fixed_divider = 1,
|
||||
};
|
||||
|
||||
static const struct bcm2835_pll_divider_data bcm2835_pllc_core2_data = {
|
||||
.name = "pllc_core2",
|
||||
.source_pll = &bcm2835_pllc_data,
|
||||
.cm_reg = CM_PLLC,
|
||||
.a2w_reg = A2W_PLLC_CORE2,
|
||||
.load_mask = CM_PLLC_LOADCORE2,
|
||||
.hold_mask = CM_PLLC_HOLDCORE2,
|
||||
.fixed_divider = 1,
|
||||
};
|
||||
|
||||
static const struct bcm2835_pll_divider_data bcm2835_pllc_per_data = {
|
||||
.name = "pllc_per",
|
||||
.source_pll = &bcm2835_pllc_data,
|
||||
.cm_reg = CM_PLLC,
|
||||
.a2w_reg = A2W_PLLC_PER,
|
||||
.load_mask = CM_PLLC_LOADPER,
|
||||
.hold_mask = CM_PLLC_HOLDPER,
|
||||
.fixed_divider = 1,
|
||||
};
|
||||
|
||||
static const struct bcm2835_pll_divider_data bcm2835_plld_core_data = {
|
||||
.name = "plld_core",
|
||||
.source_pll = &bcm2835_plld_data,
|
||||
.cm_reg = CM_PLLD,
|
||||
.a2w_reg = A2W_PLLD_CORE,
|
||||
.load_mask = CM_PLLD_LOADCORE,
|
||||
.hold_mask = CM_PLLD_HOLDCORE,
|
||||
.fixed_divider = 1,
|
||||
};
|
||||
|
||||
static const struct bcm2835_pll_divider_data bcm2835_plld_per_data = {
|
||||
.name = "plld_per",
|
||||
.source_pll = &bcm2835_plld_data,
|
||||
.cm_reg = CM_PLLD,
|
||||
.a2w_reg = A2W_PLLD_PER,
|
||||
.load_mask = CM_PLLD_LOADPER,
|
||||
.hold_mask = CM_PLLD_HOLDPER,
|
||||
.fixed_divider = 1,
|
||||
};
|
||||
|
||||
static const struct bcm2835_pll_divider_data bcm2835_pllh_rcal_data = {
|
||||
.name = "pllh_rcal",
|
||||
.source_pll = &bcm2835_pllh_data,
|
||||
.cm_reg = CM_PLLH,
|
||||
.a2w_reg = A2W_PLLH_RCAL,
|
||||
.load_mask = CM_PLLH_LOADRCAL,
|
||||
.hold_mask = 0,
|
||||
.fixed_divider = 10,
|
||||
};
|
||||
|
||||
static const struct bcm2835_pll_divider_data bcm2835_pllh_aux_data = {
|
||||
.name = "pllh_aux",
|
||||
.source_pll = &bcm2835_pllh_data,
|
||||
.cm_reg = CM_PLLH,
|
||||
.a2w_reg = A2W_PLLH_AUX,
|
||||
.load_mask = CM_PLLH_LOADAUX,
|
||||
.hold_mask = 0,
|
||||
.fixed_divider = 10,
|
||||
};
|
||||
|
||||
static const struct bcm2835_pll_divider_data bcm2835_pllh_pix_data = {
|
||||
.name = "pllh_pix",
|
||||
.source_pll = &bcm2835_pllh_data,
|
||||
.cm_reg = CM_PLLH,
|
||||
.a2w_reg = A2W_PLLH_PIX,
|
||||
.load_mask = CM_PLLH_LOADPIX,
|
||||
.hold_mask = 0,
|
||||
.fixed_divider = 10,
|
||||
};
|
||||
|
||||
struct bcm2835_clock_data {
|
||||
const char *name;
|
||||
|
||||
|
@ -668,188 +445,6 @@ struct bcm2835_clock_data {
|
|||
bool is_mash_clock;
|
||||
};
|
||||
|
||||
static const char *const bcm2835_clock_per_parents[] = {
|
||||
"gnd",
|
||||
"xosc",
|
||||
"testdebug0",
|
||||
"testdebug1",
|
||||
"plla_per",
|
||||
"pllc_per",
|
||||
"plld_per",
|
||||
"pllh_aux",
|
||||
};
|
||||
|
||||
static const char *const bcm2835_clock_vpu_parents[] = {
|
||||
"gnd",
|
||||
"xosc",
|
||||
"testdebug0",
|
||||
"testdebug1",
|
||||
"plla_core",
|
||||
"pllc_core0",
|
||||
"plld_core",
|
||||
"pllh_aux",
|
||||
"pllc_core1",
|
||||
"pllc_core2",
|
||||
};
|
||||
|
||||
static const char *const bcm2835_clock_osc_parents[] = {
|
||||
"gnd",
|
||||
"xosc",
|
||||
"testdebug0",
|
||||
"testdebug1"
|
||||
};
|
||||
|
||||
/*
|
||||
* Used for a 1Mhz clock for the system clocksource, and also used by
|
||||
* the watchdog timer and the camera pulse generator.
|
||||
*/
|
||||
static const struct bcm2835_clock_data bcm2835_clock_timer_data = {
|
||||
.name = "timer",
|
||||
.num_mux_parents = ARRAY_SIZE(bcm2835_clock_osc_parents),
|
||||
.parents = bcm2835_clock_osc_parents,
|
||||
.ctl_reg = CM_TIMERCTL,
|
||||
.div_reg = CM_TIMERDIV,
|
||||
.int_bits = 6,
|
||||
.frac_bits = 12,
|
||||
};
|
||||
|
||||
/* One Time Programmable Memory clock. Maximum 10Mhz. */
|
||||
static const struct bcm2835_clock_data bcm2835_clock_otp_data = {
|
||||
.name = "otp",
|
||||
.num_mux_parents = ARRAY_SIZE(bcm2835_clock_osc_parents),
|
||||
.parents = bcm2835_clock_osc_parents,
|
||||
.ctl_reg = CM_OTPCTL,
|
||||
.div_reg = CM_OTPDIV,
|
||||
.int_bits = 4,
|
||||
.frac_bits = 0,
|
||||
};
|
||||
|
||||
/*
|
||||
* VPU clock. This doesn't have an enable bit, since it drives the
|
||||
* bus for everything else, and is special so it doesn't need to be
|
||||
* gated for rate changes. It is also known as "clk_audio" in various
|
||||
* hardware documentation.
|
||||
*/
|
||||
static const struct bcm2835_clock_data bcm2835_clock_vpu_data = {
|
||||
.name = "vpu",
|
||||
.num_mux_parents = ARRAY_SIZE(bcm2835_clock_vpu_parents),
|
||||
.parents = bcm2835_clock_vpu_parents,
|
||||
.ctl_reg = CM_VPUCTL,
|
||||
.div_reg = CM_VPUDIV,
|
||||
.int_bits = 12,
|
||||
.frac_bits = 8,
|
||||
.is_vpu_clock = true,
|
||||
};
|
||||
|
||||
static const struct bcm2835_clock_data bcm2835_clock_v3d_data = {
|
||||
.name = "v3d",
|
||||
.num_mux_parents = ARRAY_SIZE(bcm2835_clock_vpu_parents),
|
||||
.parents = bcm2835_clock_vpu_parents,
|
||||
.ctl_reg = CM_V3DCTL,
|
||||
.div_reg = CM_V3DDIV,
|
||||
.int_bits = 4,
|
||||
.frac_bits = 8,
|
||||
};
|
||||
|
||||
static const struct bcm2835_clock_data bcm2835_clock_isp_data = {
|
||||
.name = "isp",
|
||||
.num_mux_parents = ARRAY_SIZE(bcm2835_clock_vpu_parents),
|
||||
.parents = bcm2835_clock_vpu_parents,
|
||||
.ctl_reg = CM_ISPCTL,
|
||||
.div_reg = CM_ISPDIV,
|
||||
.int_bits = 4,
|
||||
.frac_bits = 8,
|
||||
};
|
||||
|
||||
static const struct bcm2835_clock_data bcm2835_clock_h264_data = {
|
||||
.name = "h264",
|
||||
.num_mux_parents = ARRAY_SIZE(bcm2835_clock_vpu_parents),
|
||||
.parents = bcm2835_clock_vpu_parents,
|
||||
.ctl_reg = CM_H264CTL,
|
||||
.div_reg = CM_H264DIV,
|
||||
.int_bits = 4,
|
||||
.frac_bits = 8,
|
||||
};
|
||||
|
||||
/* TV encoder clock. Only operating frequency is 108Mhz. */
|
||||
static const struct bcm2835_clock_data bcm2835_clock_vec_data = {
|
||||
.name = "vec",
|
||||
.num_mux_parents = ARRAY_SIZE(bcm2835_clock_per_parents),
|
||||
.parents = bcm2835_clock_per_parents,
|
||||
.ctl_reg = CM_VECCTL,
|
||||
.div_reg = CM_VECDIV,
|
||||
.int_bits = 4,
|
||||
.frac_bits = 0,
|
||||
};
|
||||
|
||||
static const struct bcm2835_clock_data bcm2835_clock_uart_data = {
|
||||
.name = "uart",
|
||||
.num_mux_parents = ARRAY_SIZE(bcm2835_clock_per_parents),
|
||||
.parents = bcm2835_clock_per_parents,
|
||||
.ctl_reg = CM_UARTCTL,
|
||||
.div_reg = CM_UARTDIV,
|
||||
.int_bits = 10,
|
||||
.frac_bits = 12,
|
||||
};
|
||||
|
||||
/* HDMI state machine */
|
||||
static const struct bcm2835_clock_data bcm2835_clock_hsm_data = {
|
||||
.name = "hsm",
|
||||
.num_mux_parents = ARRAY_SIZE(bcm2835_clock_per_parents),
|
||||
.parents = bcm2835_clock_per_parents,
|
||||
.ctl_reg = CM_HSMCTL,
|
||||
.div_reg = CM_HSMDIV,
|
||||
.int_bits = 4,
|
||||
.frac_bits = 8,
|
||||
};
|
||||
|
||||
/*
|
||||
* Secondary SDRAM clock. Used for low-voltage modes when the PLL in
|
||||
* the SDRAM controller can't be used.
|
||||
*/
|
||||
static const struct bcm2835_clock_data bcm2835_clock_sdram_data = {
|
||||
.name = "sdram",
|
||||
.num_mux_parents = ARRAY_SIZE(bcm2835_clock_vpu_parents),
|
||||
.parents = bcm2835_clock_vpu_parents,
|
||||
.ctl_reg = CM_SDCCTL,
|
||||
.div_reg = CM_SDCDIV,
|
||||
.int_bits = 6,
|
||||
.frac_bits = 0,
|
||||
};
|
||||
|
||||
/* Clock for the temperature sensor. Generally run at 2Mhz, max 5Mhz. */
|
||||
static const struct bcm2835_clock_data bcm2835_clock_tsens_data = {
|
||||
.name = "tsens",
|
||||
.num_mux_parents = ARRAY_SIZE(bcm2835_clock_osc_parents),
|
||||
.parents = bcm2835_clock_osc_parents,
|
||||
.ctl_reg = CM_TSENSCTL,
|
||||
.div_reg = CM_TSENSDIV,
|
||||
.int_bits = 5,
|
||||
.frac_bits = 0,
|
||||
};
|
||||
|
||||
/* Arasan EMMC clock */
|
||||
static const struct bcm2835_clock_data bcm2835_clock_emmc_data = {
|
||||
.name = "emmc",
|
||||
.num_mux_parents = ARRAY_SIZE(bcm2835_clock_per_parents),
|
||||
.parents = bcm2835_clock_per_parents,
|
||||
.ctl_reg = CM_EMMCCTL,
|
||||
.div_reg = CM_EMMCDIV,
|
||||
.int_bits = 4,
|
||||
.frac_bits = 8,
|
||||
};
|
||||
|
||||
static const struct bcm2835_clock_data bcm2835_clock_pwm_data = {
|
||||
.name = "pwm",
|
||||
.num_mux_parents = ARRAY_SIZE(bcm2835_clock_per_parents),
|
||||
.parents = bcm2835_clock_per_parents,
|
||||
.ctl_reg = CM_PWMCTL,
|
||||
.div_reg = CM_PWMDIV,
|
||||
.int_bits = 12,
|
||||
.frac_bits = 12,
|
||||
.is_mash_clock = true,
|
||||
};
|
||||
|
||||
struct bcm2835_gate_data {
|
||||
const char *name;
|
||||
const char *parent;
|
||||
|
@ -857,18 +452,6 @@ struct bcm2835_gate_data {
|
|||
u32 ctl_reg;
|
||||
};
|
||||
|
||||
/*
|
||||
* CM_PERIICTL (and CM_PERIACTL, CM_SYSCTL and CM_VPUCTL if
|
||||
* you have the debug bit set in the power manager, which we
|
||||
* don't bother exposing) are individual gates off of the
|
||||
* non-stop vpu clock.
|
||||
*/
|
||||
static const struct bcm2835_gate_data bcm2835_clock_peri_image_data = {
|
||||
.name = "peri_image",
|
||||
.parent = "vpu",
|
||||
.ctl_reg = CM_PERIICTL,
|
||||
};
|
||||
|
||||
struct bcm2835_pll {
|
||||
struct clk_hw hw;
|
||||
struct bcm2835_cprman *cprman;
|
||||
|
@ -1578,7 +1161,7 @@ bcm2835_register_pll_divider(struct bcm2835_cprman *cprman,
|
|||
|
||||
memset(&init, 0, sizeof(init));
|
||||
|
||||
init.parent_names = &data->source_pll->name;
|
||||
init.parent_names = &data->source_pll;
|
||||
init.num_parents = 1;
|
||||
init.name = divider_name;
|
||||
init.ops = &bcm2835_pll_divider_clk_ops;
|
||||
|
@ -1677,50 +1260,401 @@ struct bcm2835_clk_desc {
|
|||
const void *data;
|
||||
};
|
||||
|
||||
#define _REGISTER(f, d) { .clk_register = (bcm2835_clk_register)f, \
|
||||
.data = d }
|
||||
#define REGISTER_PLL(d) _REGISTER(&bcm2835_register_pll, d)
|
||||
#define REGISTER_PLL_DIV(d) _REGISTER(&bcm2835_register_pll_divider, d)
|
||||
#define REGISTER_CLK(d) _REGISTER(&bcm2835_register_clock, d)
|
||||
#define REGISTER_GATE(d) _REGISTER(&bcm2835_register_gate, d)
|
||||
/* assignment helper macros for different clock types */
|
||||
#define _REGISTER(f, ...) { .clk_register = (bcm2835_clk_register)f, \
|
||||
.data = __VA_ARGS__ }
|
||||
#define REGISTER_PLL(...) _REGISTER(&bcm2835_register_pll, \
|
||||
&(struct bcm2835_pll_data) \
|
||||
{__VA_ARGS__})
|
||||
#define REGISTER_PLL_DIV(...) _REGISTER(&bcm2835_register_pll_divider, \
|
||||
&(struct bcm2835_pll_divider_data) \
|
||||
{__VA_ARGS__})
|
||||
#define REGISTER_CLK(...) _REGISTER(&bcm2835_register_clock, \
|
||||
&(struct bcm2835_clock_data) \
|
||||
{__VA_ARGS__})
|
||||
#define REGISTER_GATE(...) _REGISTER(&bcm2835_register_gate, \
|
||||
&(struct bcm2835_gate_data) \
|
||||
{__VA_ARGS__})
|
||||
|
||||
/* parent mux arrays plus helper macros */
|
||||
|
||||
/* main oscillator parent mux */
|
||||
static const char *const bcm2835_clock_osc_parents[] = {
|
||||
"gnd",
|
||||
"xosc",
|
||||
"testdebug0",
|
||||
"testdebug1"
|
||||
};
|
||||
|
||||
#define REGISTER_OSC_CLK(...) REGISTER_CLK( \
|
||||
.num_mux_parents = ARRAY_SIZE(bcm2835_clock_osc_parents), \
|
||||
.parents = bcm2835_clock_osc_parents, \
|
||||
__VA_ARGS__)
|
||||
|
||||
/* main peripherial parent mux */
|
||||
static const char *const bcm2835_clock_per_parents[] = {
|
||||
"gnd",
|
||||
"xosc",
|
||||
"testdebug0",
|
||||
"testdebug1",
|
||||
"plla_per",
|
||||
"pllc_per",
|
||||
"plld_per",
|
||||
"pllh_aux",
|
||||
};
|
||||
|
||||
#define REGISTER_PER_CLK(...) REGISTER_CLK( \
|
||||
.num_mux_parents = ARRAY_SIZE(bcm2835_clock_per_parents), \
|
||||
.parents = bcm2835_clock_per_parents, \
|
||||
__VA_ARGS__)
|
||||
|
||||
/* main vpu parent mux */
|
||||
static const char *const bcm2835_clock_vpu_parents[] = {
|
||||
"gnd",
|
||||
"xosc",
|
||||
"testdebug0",
|
||||
"testdebug1",
|
||||
"plla_core",
|
||||
"pllc_core0",
|
||||
"plld_core",
|
||||
"pllh_aux",
|
||||
"pllc_core1",
|
||||
"pllc_core2",
|
||||
};
|
||||
|
||||
#define REGISTER_VPU_CLK(...) REGISTER_CLK( \
|
||||
.num_mux_parents = ARRAY_SIZE(bcm2835_clock_vpu_parents), \
|
||||
.parents = bcm2835_clock_vpu_parents, \
|
||||
__VA_ARGS__)
|
||||
|
||||
/*
|
||||
* the real definition of all the pll, pll_dividers and clocks
|
||||
* these make use of the above REGISTER_* macros
|
||||
*/
|
||||
static const struct bcm2835_clk_desc clk_desc_array[] = {
|
||||
/* register PLL */
|
||||
[BCM2835_PLLA] = REGISTER_PLL(&bcm2835_plla_data),
|
||||
[BCM2835_PLLB] = REGISTER_PLL(&bcm2835_pllb_data),
|
||||
[BCM2835_PLLC] = REGISTER_PLL(&bcm2835_pllc_data),
|
||||
[BCM2835_PLLD] = REGISTER_PLL(&bcm2835_plld_data),
|
||||
[BCM2835_PLLH] = REGISTER_PLL(&bcm2835_pllh_data),
|
||||
/* the PLL dividers */
|
||||
[BCM2835_PLLA_CORE] = REGISTER_PLL_DIV(&bcm2835_plla_core_data),
|
||||
[BCM2835_PLLA_PER] = REGISTER_PLL_DIV(&bcm2835_plla_per_data),
|
||||
[BCM2835_PLLC_CORE0] = REGISTER_PLL_DIV(&bcm2835_pllc_core0_data),
|
||||
[BCM2835_PLLC_CORE1] = REGISTER_PLL_DIV(&bcm2835_pllc_core1_data),
|
||||
[BCM2835_PLLC_CORE2] = REGISTER_PLL_DIV(&bcm2835_pllc_core2_data),
|
||||
[BCM2835_PLLC_PER] = REGISTER_PLL_DIV(&bcm2835_pllc_per_data),
|
||||
[BCM2835_PLLD_CORE] = REGISTER_PLL_DIV(&bcm2835_plld_core_data),
|
||||
[BCM2835_PLLD_PER] = REGISTER_PLL_DIV(&bcm2835_plld_per_data),
|
||||
[BCM2835_PLLH_RCAL] = REGISTER_PLL_DIV(&bcm2835_pllh_rcal_data),
|
||||
[BCM2835_PLLH_AUX] = REGISTER_PLL_DIV(&bcm2835_pllh_aux_data),
|
||||
[BCM2835_PLLH_PIX] = REGISTER_PLL_DIV(&bcm2835_pllh_pix_data),
|
||||
/* the PLL + PLL dividers */
|
||||
|
||||
/*
|
||||
* PLLA is the auxiliary PLL, used to drive the CCP2
|
||||
* (Compact Camera Port 2) transmitter clock.
|
||||
*
|
||||
* It is in the PX LDO power domain, which is on when the
|
||||
* AUDIO domain is on.
|
||||
*/
|
||||
[BCM2835_PLLA] = REGISTER_PLL(
|
||||
.name = "plla",
|
||||
.cm_ctrl_reg = CM_PLLA,
|
||||
.a2w_ctrl_reg = A2W_PLLA_CTRL,
|
||||
.frac_reg = A2W_PLLA_FRAC,
|
||||
.ana_reg_base = A2W_PLLA_ANA0,
|
||||
.reference_enable_mask = A2W_XOSC_CTRL_PLLA_ENABLE,
|
||||
.lock_mask = CM_LOCK_FLOCKA,
|
||||
|
||||
.ana = &bcm2835_ana_default,
|
||||
|
||||
.min_rate = 600000000u,
|
||||
.max_rate = 2400000000u,
|
||||
.max_fb_rate = BCM2835_MAX_FB_RATE),
|
||||
[BCM2835_PLLA_CORE] = REGISTER_PLL_DIV(
|
||||
.name = "plla_core",
|
||||
.source_pll = "plla",
|
||||
.cm_reg = CM_PLLA,
|
||||
.a2w_reg = A2W_PLLA_CORE,
|
||||
.load_mask = CM_PLLA_LOADCORE,
|
||||
.hold_mask = CM_PLLA_HOLDCORE,
|
||||
.fixed_divider = 1),
|
||||
[BCM2835_PLLA_PER] = REGISTER_PLL_DIV(
|
||||
.name = "plla_per",
|
||||
.source_pll = "plla",
|
||||
.cm_reg = CM_PLLA,
|
||||
.a2w_reg = A2W_PLLA_PER,
|
||||
.load_mask = CM_PLLA_LOADPER,
|
||||
.hold_mask = CM_PLLA_HOLDPER,
|
||||
.fixed_divider = 1),
|
||||
|
||||
/* PLLB is used for the ARM's clock. */
|
||||
[BCM2835_PLLB] = REGISTER_PLL(
|
||||
.name = "pllb",
|
||||
.cm_ctrl_reg = CM_PLLB,
|
||||
.a2w_ctrl_reg = A2W_PLLB_CTRL,
|
||||
.frac_reg = A2W_PLLB_FRAC,
|
||||
.ana_reg_base = A2W_PLLB_ANA0,
|
||||
.reference_enable_mask = A2W_XOSC_CTRL_PLLB_ENABLE,
|
||||
.lock_mask = CM_LOCK_FLOCKB,
|
||||
|
||||
.ana = &bcm2835_ana_default,
|
||||
|
||||
.min_rate = 600000000u,
|
||||
.max_rate = 3000000000u,
|
||||
.max_fb_rate = BCM2835_MAX_FB_RATE),
|
||||
[BCM2835_PLLB_ARM] = REGISTER_PLL_DIV(
|
||||
.name = "pllb_arm",
|
||||
.source_pll = "pllb",
|
||||
.cm_reg = CM_PLLB,
|
||||
.a2w_reg = A2W_PLLB_ARM,
|
||||
.load_mask = CM_PLLB_LOADARM,
|
||||
.hold_mask = CM_PLLB_HOLDARM,
|
||||
.fixed_divider = 1),
|
||||
|
||||
/*
|
||||
* PLLC is the core PLL, used to drive the core VPU clock.
|
||||
*
|
||||
* It is in the PX LDO power domain, which is on when the
|
||||
* AUDIO domain is on.
|
||||
*/
|
||||
[BCM2835_PLLC] = REGISTER_PLL(
|
||||
.name = "pllc",
|
||||
.cm_ctrl_reg = CM_PLLC,
|
||||
.a2w_ctrl_reg = A2W_PLLC_CTRL,
|
||||
.frac_reg = A2W_PLLC_FRAC,
|
||||
.ana_reg_base = A2W_PLLC_ANA0,
|
||||
.reference_enable_mask = A2W_XOSC_CTRL_PLLC_ENABLE,
|
||||
.lock_mask = CM_LOCK_FLOCKC,
|
||||
|
||||
.ana = &bcm2835_ana_default,
|
||||
|
||||
.min_rate = 600000000u,
|
||||
.max_rate = 3000000000u,
|
||||
.max_fb_rate = BCM2835_MAX_FB_RATE),
|
||||
[BCM2835_PLLC_CORE0] = REGISTER_PLL_DIV(
|
||||
.name = "pllc_core0",
|
||||
.source_pll = "pllc",
|
||||
.cm_reg = CM_PLLC,
|
||||
.a2w_reg = A2W_PLLC_CORE0,
|
||||
.load_mask = CM_PLLC_LOADCORE0,
|
||||
.hold_mask = CM_PLLC_HOLDCORE0,
|
||||
.fixed_divider = 1),
|
||||
[BCM2835_PLLC_CORE1] = REGISTER_PLL_DIV(
|
||||
.name = "pllc_core1",
|
||||
.source_pll = "pllc",
|
||||
.cm_reg = CM_PLLC,
|
||||
.a2w_reg = A2W_PLLC_CORE1,
|
||||
.load_mask = CM_PLLC_LOADCORE1,
|
||||
.hold_mask = CM_PLLC_HOLDCORE1,
|
||||
.fixed_divider = 1),
|
||||
[BCM2835_PLLC_CORE2] = REGISTER_PLL_DIV(
|
||||
.name = "pllc_core2",
|
||||
.source_pll = "pllc",
|
||||
.cm_reg = CM_PLLC,
|
||||
.a2w_reg = A2W_PLLC_CORE2,
|
||||
.load_mask = CM_PLLC_LOADCORE2,
|
||||
.hold_mask = CM_PLLC_HOLDCORE2,
|
||||
.fixed_divider = 1),
|
||||
[BCM2835_PLLC_PER] = REGISTER_PLL_DIV(
|
||||
.name = "pllc_per",
|
||||
.source_pll = "pllc",
|
||||
.cm_reg = CM_PLLC,
|
||||
.a2w_reg = A2W_PLLC_PER,
|
||||
.load_mask = CM_PLLC_LOADPER,
|
||||
.hold_mask = CM_PLLC_HOLDPER,
|
||||
.fixed_divider = 1),
|
||||
|
||||
/*
|
||||
* PLLD is the display PLL, used to drive DSI display panels.
|
||||
*
|
||||
* It is in the PX LDO power domain, which is on when the
|
||||
* AUDIO domain is on.
|
||||
*/
|
||||
[BCM2835_PLLD] = REGISTER_PLL(
|
||||
.name = "plld",
|
||||
.cm_ctrl_reg = CM_PLLD,
|
||||
.a2w_ctrl_reg = A2W_PLLD_CTRL,
|
||||
.frac_reg = A2W_PLLD_FRAC,
|
||||
.ana_reg_base = A2W_PLLD_ANA0,
|
||||
.reference_enable_mask = A2W_XOSC_CTRL_DDR_ENABLE,
|
||||
.lock_mask = CM_LOCK_FLOCKD,
|
||||
|
||||
.ana = &bcm2835_ana_default,
|
||||
|
||||
.min_rate = 600000000u,
|
||||
.max_rate = 2400000000u,
|
||||
.max_fb_rate = BCM2835_MAX_FB_RATE),
|
||||
[BCM2835_PLLD_CORE] = REGISTER_PLL_DIV(
|
||||
.name = "plld_core",
|
||||
.source_pll = "plld",
|
||||
.cm_reg = CM_PLLD,
|
||||
.a2w_reg = A2W_PLLD_CORE,
|
||||
.load_mask = CM_PLLD_LOADCORE,
|
||||
.hold_mask = CM_PLLD_HOLDCORE,
|
||||
.fixed_divider = 1),
|
||||
[BCM2835_PLLD_PER] = REGISTER_PLL_DIV(
|
||||
.name = "plld_per",
|
||||
.source_pll = "plld",
|
||||
.cm_reg = CM_PLLD,
|
||||
.a2w_reg = A2W_PLLD_PER,
|
||||
.load_mask = CM_PLLD_LOADPER,
|
||||
.hold_mask = CM_PLLD_HOLDPER,
|
||||
.fixed_divider = 1),
|
||||
|
||||
/*
|
||||
* PLLH is used to supply the pixel clock or the AUX clock for the
|
||||
* TV encoder.
|
||||
*
|
||||
* It is in the HDMI power domain.
|
||||
*/
|
||||
[BCM2835_PLLH] = REGISTER_PLL(
|
||||
"pllh",
|
||||
.cm_ctrl_reg = CM_PLLH,
|
||||
.a2w_ctrl_reg = A2W_PLLH_CTRL,
|
||||
.frac_reg = A2W_PLLH_FRAC,
|
||||
.ana_reg_base = A2W_PLLH_ANA0,
|
||||
.reference_enable_mask = A2W_XOSC_CTRL_PLLC_ENABLE,
|
||||
.lock_mask = CM_LOCK_FLOCKH,
|
||||
|
||||
.ana = &bcm2835_ana_pllh,
|
||||
|
||||
.min_rate = 600000000u,
|
||||
.max_rate = 3000000000u,
|
||||
.max_fb_rate = BCM2835_MAX_FB_RATE),
|
||||
[BCM2835_PLLH_RCAL] = REGISTER_PLL_DIV(
|
||||
.name = "pllh_rcal",
|
||||
.source_pll = "pllh",
|
||||
.cm_reg = CM_PLLH,
|
||||
.a2w_reg = A2W_PLLH_RCAL,
|
||||
.load_mask = CM_PLLH_LOADRCAL,
|
||||
.hold_mask = 0,
|
||||
.fixed_divider = 10),
|
||||
[BCM2835_PLLH_AUX] = REGISTER_PLL_DIV(
|
||||
.name = "pllh_aux",
|
||||
.source_pll = "pllh",
|
||||
.cm_reg = CM_PLLH,
|
||||
.a2w_reg = A2W_PLLH_AUX,
|
||||
.load_mask = CM_PLLH_LOADAUX,
|
||||
.hold_mask = 0,
|
||||
.fixed_divider = 10),
|
||||
[BCM2835_PLLH_PIX] = REGISTER_PLL_DIV(
|
||||
.name = "pllh_pix",
|
||||
.source_pll = "pllh",
|
||||
.cm_reg = CM_PLLH,
|
||||
.a2w_reg = A2W_PLLH_PIX,
|
||||
.load_mask = CM_PLLH_LOADPIX,
|
||||
.hold_mask = 0,
|
||||
.fixed_divider = 10),
|
||||
|
||||
/* the clocks */
|
||||
[BCM2835_CLOCK_TIMER] = REGISTER_CLK(&bcm2835_clock_timer_data),
|
||||
[BCM2835_CLOCK_OTP] = REGISTER_CLK(&bcm2835_clock_otp_data),
|
||||
[BCM2835_CLOCK_TSENS] = REGISTER_CLK(&bcm2835_clock_tsens_data),
|
||||
[BCM2835_CLOCK_VPU] = REGISTER_CLK(&bcm2835_clock_vpu_data),
|
||||
[BCM2835_CLOCK_V3D] = REGISTER_CLK(&bcm2835_clock_v3d_data),
|
||||
[BCM2835_CLOCK_ISP] = REGISTER_CLK(&bcm2835_clock_isp_data),
|
||||
[BCM2835_CLOCK_H264] = REGISTER_CLK(&bcm2835_clock_h264_data),
|
||||
[BCM2835_CLOCK_V3D] = REGISTER_CLK(&bcm2835_clock_v3d_data),
|
||||
[BCM2835_CLOCK_SDRAM] = REGISTER_CLK(&bcm2835_clock_sdram_data),
|
||||
[BCM2835_CLOCK_UART] = REGISTER_CLK(&bcm2835_clock_uart_data),
|
||||
[BCM2835_CLOCK_VEC] = REGISTER_CLK(&bcm2835_clock_vec_data),
|
||||
[BCM2835_CLOCK_HSM] = REGISTER_CLK(&bcm2835_clock_hsm_data),
|
||||
[BCM2835_CLOCK_EMMC] = REGISTER_CLK(&bcm2835_clock_emmc_data),
|
||||
[BCM2835_CLOCK_PWM] = REGISTER_CLK(&bcm2835_clock_pwm_data),
|
||||
|
||||
/* clocks with oscillator parent mux */
|
||||
|
||||
/* One Time Programmable Memory clock. Maximum 10Mhz. */
|
||||
[BCM2835_CLOCK_OTP] = REGISTER_OSC_CLK(
|
||||
.name = "otp",
|
||||
.ctl_reg = CM_OTPCTL,
|
||||
.div_reg = CM_OTPDIV,
|
||||
.int_bits = 4,
|
||||
.frac_bits = 0),
|
||||
/*
|
||||
* Used for a 1Mhz clock for the system clocksource, and also used
|
||||
* bythe watchdog timer and the camera pulse generator.
|
||||
*/
|
||||
[BCM2835_CLOCK_TIMER] = REGISTER_OSC_CLK(
|
||||
.name = "timer",
|
||||
.ctl_reg = CM_TIMERCTL,
|
||||
.div_reg = CM_TIMERDIV,
|
||||
.int_bits = 6,
|
||||
.frac_bits = 12),
|
||||
/*
|
||||
* Clock for the temperature sensor.
|
||||
* Generally run at 2Mhz, max 5Mhz.
|
||||
*/
|
||||
[BCM2835_CLOCK_TSENS] = REGISTER_OSC_CLK(
|
||||
.name = "tsens",
|
||||
.ctl_reg = CM_TSENSCTL,
|
||||
.div_reg = CM_TSENSDIV,
|
||||
.int_bits = 5,
|
||||
.frac_bits = 0),
|
||||
|
||||
/* clocks with vpu parent mux */
|
||||
[BCM2835_CLOCK_H264] = REGISTER_VPU_CLK(
|
||||
.name = "h264",
|
||||
.ctl_reg = CM_H264CTL,
|
||||
.div_reg = CM_H264DIV,
|
||||
.int_bits = 4,
|
||||
.frac_bits = 8),
|
||||
[BCM2835_CLOCK_ISP] = REGISTER_VPU_CLK(
|
||||
.name = "isp",
|
||||
.ctl_reg = CM_ISPCTL,
|
||||
.div_reg = CM_ISPDIV,
|
||||
.int_bits = 4,
|
||||
.frac_bits = 8),
|
||||
/*
|
||||
* Secondary SDRAM clock. Used for low-voltage modes when the PLL
|
||||
* in the SDRAM controller can't be used.
|
||||
*/
|
||||
[BCM2835_CLOCK_SDRAM] = REGISTER_VPU_CLK(
|
||||
.name = "sdram",
|
||||
.ctl_reg = CM_SDCCTL,
|
||||
.div_reg = CM_SDCDIV,
|
||||
.int_bits = 6,
|
||||
.frac_bits = 0),
|
||||
[BCM2835_CLOCK_V3D] = REGISTER_VPU_CLK(
|
||||
.name = "v3d",
|
||||
.ctl_reg = CM_V3DCTL,
|
||||
.div_reg = CM_V3DDIV,
|
||||
.int_bits = 4,
|
||||
.frac_bits = 8),
|
||||
/*
|
||||
* VPU clock. This doesn't have an enable bit, since it drives
|
||||
* the bus for everything else, and is special so it doesn't need
|
||||
* to be gated for rate changes. It is also known as "clk_audio"
|
||||
* in various hardware documentation.
|
||||
*/
|
||||
[BCM2835_CLOCK_VPU] = REGISTER_VPU_CLK(
|
||||
.name = "vpu",
|
||||
.ctl_reg = CM_VPUCTL,
|
||||
.div_reg = CM_VPUDIV,
|
||||
.int_bits = 12,
|
||||
.frac_bits = 8,
|
||||
.is_vpu_clock = true),
|
||||
|
||||
/* clocks with per parent mux */
|
||||
|
||||
/* Arasan EMMC clock */
|
||||
[BCM2835_CLOCK_EMMC] = REGISTER_PER_CLK(
|
||||
.name = "emmc",
|
||||
.ctl_reg = CM_EMMCCTL,
|
||||
.div_reg = CM_EMMCDIV,
|
||||
.int_bits = 4,
|
||||
.frac_bits = 8),
|
||||
/* HDMI state machine */
|
||||
[BCM2835_CLOCK_HSM] = REGISTER_PER_CLK(
|
||||
.name = "hsm",
|
||||
.ctl_reg = CM_HSMCTL,
|
||||
.div_reg = CM_HSMDIV,
|
||||
.int_bits = 4,
|
||||
.frac_bits = 8),
|
||||
[BCM2835_CLOCK_PWM] = REGISTER_PER_CLK(
|
||||
.name = "pwm",
|
||||
.ctl_reg = CM_PWMCTL,
|
||||
.div_reg = CM_PWMDIV,
|
||||
.int_bits = 12,
|
||||
.frac_bits = 12,
|
||||
.is_mash_clock = true),
|
||||
[BCM2835_CLOCK_UART] = REGISTER_PER_CLK(
|
||||
.name = "uart",
|
||||
.ctl_reg = CM_UARTCTL,
|
||||
.div_reg = CM_UARTDIV,
|
||||
.int_bits = 10,
|
||||
.frac_bits = 12),
|
||||
/* TV encoder clock. Only operating frequency is 108Mhz. */
|
||||
[BCM2835_CLOCK_VEC] = REGISTER_PER_CLK(
|
||||
.name = "vec",
|
||||
.ctl_reg = CM_VECCTL,
|
||||
.div_reg = CM_VECDIV,
|
||||
.int_bits = 4,
|
||||
.frac_bits = 0),
|
||||
|
||||
/* the gates */
|
||||
|
||||
/*
|
||||
* CM_PERIICTL (and CM_PERIACTL, CM_SYSCTL and CM_VPUCTL if
|
||||
* you have the debug bit set in the power manager, which we
|
||||
* don't bother exposing) are individual gates off of the
|
||||
* non-stop vpu clock.
|
||||
*/
|
||||
[BCM2835_CLOCK_PERI_IMAGE] = REGISTER_GATE(
|
||||
&bcm2835_clock_peri_image_data),
|
||||
.name = "peri_image",
|
||||
.parent = "vpu",
|
||||
.ctl_reg = CM_PERIICTL),
|
||||
};
|
||||
|
||||
static int bcm2835_clk_probe(struct platform_device *pdev)
|
||||
|
|
Loading…
Reference in New Issue