mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2025-01-16 02:14:58 +00:00
Merge branches 'clk-amlogic', 'clk-microchip' and 'clk-imx' into clk-next
* clk-amlogic: clk: meson: introduce symbol namespace for amlogic clocks clk: meson: axg-audio: add sm1 earcrx clocks clk: meson: axg-audio: setup regmap max_register based on the SoC dt-bindings: clock: axg-audio: add earcrx clock ids clk: meson: s4: pll: Constify struct regmap_config clk: meson: s4: peripherals: Constify struct regmap_config clk: meson: c3: pll: Constify struct regmap_config clk: meson: c3: peripherals: Constify struct regmap_config clk: meson: a1: pll: Constify struct regmap_config clk: meson: a1: peripherals: Constify struct regmap_config * clk-microchip: clk: at91: sama7g5: Allocate only the needed amount of memory for PLLs clk: at91: sam9x7: add sam9x7 pmc driver dt-bindings: clock: at91: Allow PLLs to be exported and referenced in DT clk: at91: sama7g5: move mux table macros to header file clk: at91: sam9x7: add support for HW PLL freq dividers clk: at91: clk-sam9x60-pll: re-factor to support individual core freq outputs dt-bindings: clocks: atmel,at91rm9200-pmc: add sam9x7 clock controller dt-bindings: clocks: atmel,at91sam9x5-sckc: add sam9x7 * clk-imx: (27 commits) clk: imx6ul: fix clock parent for IMX6UL_CLK_ENETx_REF_SEL clk: imx95: enable the clock of NETCMIX block control dt-bindings: clock: add RMII clock selection dt-bindings: clock: add i.MX95 NETCMIX block control clk: imx: imx8: Use clk_hw pointer for self registered clock in clk_parent_data clk: imx: composite-7ulp: Use NULL instead of 0 clk: imx: add missing MODULE_DESCRIPTION() macros clk: imx: clk-imx8mp: Allow media_disp pixel clock reconfigure parent rate clk: imx: fracn-gppll: update rate table clk: imx: imx8qxp: Parent should be initialized earlier than the clock clk: imx: imx8qxp: Register dc0_bypass0_clk before disp clk clk: imx: imx8qxp: Add clock muxes for MIPI and PHY ref clocks clk: imx: imx8qxp: Add LVDS bypass clocks clk: imx: imx8mm: Change the 'nand_usdhc_bus' clock to non-critical one clk: imx: imx8mn: add sai7_ipg_clk clock settings clk: imx: add CLK_SET_RATE_PARENT for lcdif_pixel_src for i.MX7D clk: imx: Remove CLK_SET_PARENT_GATE for DRAM mux for i.MX7D clk: imx: imx8mp: fix clock tree update of TF-A managed clocks clk: imx: fracn-gppll: fix fractional part of PLL getting lost clk: imx: composite-7ulp: Check the PCC present bit ...
This commit is contained in:
commit
6629108252
@ -42,6 +42,7 @@ properties:
|
||||
- atmel,sama5d3-pmc
|
||||
- atmel,sama5d4-pmc
|
||||
- microchip,sam9x60-pmc
|
||||
- microchip,sam9x7-pmc
|
||||
- microchip,sama7g5-pmc
|
||||
- const: syscon
|
||||
|
||||
@ -88,6 +89,7 @@ allOf:
|
||||
contains:
|
||||
enum:
|
||||
- microchip,sam9x60-pmc
|
||||
- microchip,sam9x7-pmc
|
||||
- microchip,sama7g5-pmc
|
||||
then:
|
||||
properties:
|
||||
|
@ -18,7 +18,9 @@ properties:
|
||||
- atmel,sama5d4-sckc
|
||||
- microchip,sam9x60-sckc
|
||||
- items:
|
||||
- const: microchip,sama7g5-sckc
|
||||
- enum:
|
||||
- microchip,sam9x7-sckc
|
||||
- microchip,sama7g5-sckc
|
||||
- const: microchip,sam9x60-sckc
|
||||
|
||||
reg:
|
||||
|
@ -44,6 +44,9 @@ properties:
|
||||
ID in its "clocks" phandle cell. See include/dt-bindings/clock/imx8mp-clock.h
|
||||
for the full list of i.MX8MP IMX8MP_CLK_AUDIOMIX_ clock IDs.
|
||||
|
||||
'#reset-cells':
|
||||
const: 1
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
|
@ -16,6 +16,7 @@ properties:
|
||||
- nxp,imx95-lvds-csr
|
||||
- nxp,imx95-display-csr
|
||||
- nxp,imx95-camera-csr
|
||||
- nxp,imx95-netcmix-blk-ctrl
|
||||
- nxp,imx95-vpu-csr
|
||||
- const: syscon
|
||||
|
||||
|
@ -20,6 +20,7 @@ obj-$(CONFIG_SOC_AT91SAM9) += at91sam9260.o at91sam9rl.o at91sam9x5.o dt-compat.
|
||||
obj-$(CONFIG_SOC_AT91SAM9) += at91sam9g45.o dt-compat.o
|
||||
obj-$(CONFIG_SOC_AT91SAM9) += at91sam9n12.o at91sam9x5.o dt-compat.o
|
||||
obj-$(CONFIG_SOC_SAM9X60) += sam9x60.o
|
||||
obj-$(CONFIG_SOC_SAM9X7) += sam9x7.o
|
||||
obj-$(CONFIG_SOC_SAMA5D3) += sama5d3.o dt-compat.o
|
||||
obj-$(CONFIG_SOC_SAMA5D4) += sama5d4.o dt-compat.o
|
||||
obj-$(CONFIG_SOC_SAMA5D2) += sama5d2.o dt-compat.o
|
||||
|
@ -23,9 +23,6 @@
|
||||
#define UPLL_DIV 2
|
||||
#define PLL_MUL_MAX (FIELD_GET(PMC_PLL_CTRL1_MUL_MSK, UINT_MAX) + 1)
|
||||
|
||||
#define FCORE_MIN (600000000)
|
||||
#define FCORE_MAX (1200000000)
|
||||
|
||||
#define PLL_MAX_ID 7
|
||||
|
||||
struct sam9x60_pll_core {
|
||||
@ -76,9 +73,15 @@ static unsigned long sam9x60_frac_pll_recalc_rate(struct clk_hw *hw,
|
||||
{
|
||||
struct sam9x60_pll_core *core = to_sam9x60_pll_core(hw);
|
||||
struct sam9x60_frac *frac = to_sam9x60_frac(core);
|
||||
unsigned long freq;
|
||||
|
||||
return parent_rate * (frac->mul + 1) +
|
||||
freq = parent_rate * (frac->mul + 1) +
|
||||
DIV_ROUND_CLOSEST_ULL((u64)parent_rate * frac->frac, (1 << 22));
|
||||
|
||||
if (core->layout->div2)
|
||||
freq >>= 1;
|
||||
|
||||
return freq;
|
||||
}
|
||||
|
||||
static int sam9x60_frac_pll_set(struct sam9x60_pll_core *core)
|
||||
@ -194,7 +197,8 @@ static long sam9x60_frac_pll_compute_mul_frac(struct sam9x60_pll_core *core,
|
||||
unsigned long nmul = 0;
|
||||
unsigned long nfrac = 0;
|
||||
|
||||
if (rate < FCORE_MIN || rate > FCORE_MAX)
|
||||
if (rate < core->characteristics->core_output[0].min ||
|
||||
rate > core->characteristics->core_output[0].max)
|
||||
return -ERANGE;
|
||||
|
||||
/*
|
||||
@ -214,7 +218,8 @@ static long sam9x60_frac_pll_compute_mul_frac(struct sam9x60_pll_core *core,
|
||||
}
|
||||
|
||||
/* Check if resulted rate is a valid. */
|
||||
if (tmprate < FCORE_MIN || tmprate > FCORE_MAX)
|
||||
if (tmprate < core->characteristics->core_output[0].min ||
|
||||
tmprate > core->characteristics->core_output[0].max)
|
||||
return -ERANGE;
|
||||
|
||||
if (update) {
|
||||
@ -433,6 +438,12 @@ static unsigned long sam9x60_div_pll_recalc_rate(struct clk_hw *hw,
|
||||
return DIV_ROUND_CLOSEST_ULL(parent_rate, (div->div + 1));
|
||||
}
|
||||
|
||||
static unsigned long sam9x60_fixed_div_pll_recalc_rate(struct clk_hw *hw,
|
||||
unsigned long parent_rate)
|
||||
{
|
||||
return parent_rate >> 1;
|
||||
}
|
||||
|
||||
static long sam9x60_div_pll_compute_div(struct sam9x60_pll_core *core,
|
||||
unsigned long *parent_rate,
|
||||
unsigned long rate)
|
||||
@ -607,6 +618,16 @@ static const struct clk_ops sam9x60_div_pll_ops_chg = {
|
||||
.restore_context = sam9x60_div_pll_restore_context,
|
||||
};
|
||||
|
||||
static const struct clk_ops sam9x60_fixed_div_pll_ops = {
|
||||
.prepare = sam9x60_div_pll_prepare,
|
||||
.unprepare = sam9x60_div_pll_unprepare,
|
||||
.is_prepared = sam9x60_div_pll_is_prepared,
|
||||
.recalc_rate = sam9x60_fixed_div_pll_recalc_rate,
|
||||
.round_rate = sam9x60_div_pll_round_rate,
|
||||
.save_context = sam9x60_div_pll_save_context,
|
||||
.restore_context = sam9x60_div_pll_restore_context,
|
||||
};
|
||||
|
||||
struct clk_hw * __init
|
||||
sam9x60_clk_register_frac_pll(struct regmap *regmap, spinlock_t *lock,
|
||||
const char *name, const char *parent_name,
|
||||
@ -669,7 +690,8 @@ sam9x60_clk_register_frac_pll(struct regmap *regmap, spinlock_t *lock,
|
||||
goto free;
|
||||
}
|
||||
|
||||
ret = sam9x60_frac_pll_compute_mul_frac(&frac->core, FCORE_MIN,
|
||||
ret = sam9x60_frac_pll_compute_mul_frac(&frac->core,
|
||||
characteristics->core_output[0].min,
|
||||
parent_rate, true);
|
||||
if (ret < 0) {
|
||||
hw = ERR_PTR(ret);
|
||||
@ -725,10 +747,14 @@ sam9x60_clk_register_div_pll(struct regmap *regmap, spinlock_t *lock,
|
||||
else
|
||||
init.parent_names = &parent_name;
|
||||
init.num_parents = 1;
|
||||
if (flags & CLK_SET_RATE_GATE)
|
||||
|
||||
if (layout->div2)
|
||||
init.ops = &sam9x60_fixed_div_pll_ops;
|
||||
else if (flags & CLK_SET_RATE_GATE)
|
||||
init.ops = &sam9x60_div_pll_ops;
|
||||
else
|
||||
init.ops = &sam9x60_div_pll_ops_chg;
|
||||
|
||||
init.flags = flags;
|
||||
|
||||
div->core.id = id;
|
||||
|
@ -64,6 +64,7 @@ struct clk_pll_layout {
|
||||
u8 frac_shift;
|
||||
u8 div_shift;
|
||||
u8 endiv_shift;
|
||||
u8 div2;
|
||||
};
|
||||
|
||||
extern const struct clk_pll_layout at91rm9200_pll_layout;
|
||||
@ -75,6 +76,7 @@ struct clk_pll_characteristics {
|
||||
struct clk_range input;
|
||||
int num_output;
|
||||
const struct clk_range *output;
|
||||
const struct clk_range *core_output;
|
||||
u16 *icpll;
|
||||
u8 *out;
|
||||
u8 upll : 1;
|
||||
@ -119,6 +121,22 @@ struct at91_clk_pms {
|
||||
|
||||
#define ndck(a, s) (a[s - 1].id + 1)
|
||||
#define nck(a) (a[ARRAY_SIZE(a) - 1].id + 1)
|
||||
|
||||
#define PMC_INIT_TABLE(_table, _count) \
|
||||
do { \
|
||||
u8 _i; \
|
||||
for (_i = 0; _i < (_count); _i++) \
|
||||
(_table)[_i] = _i; \
|
||||
} while (0)
|
||||
|
||||
#define PMC_FILL_TABLE(_to, _from, _count) \
|
||||
do { \
|
||||
u8 _i; \
|
||||
for (_i = 0; _i < (_count); _i++) { \
|
||||
(_to)[_i] = (_from)[_i]; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
struct pmc_data *pmc_data_allocate(unsigned int ncore, unsigned int nsystem,
|
||||
unsigned int nperiph, unsigned int ngck,
|
||||
unsigned int npck);
|
||||
|
@ -26,10 +26,16 @@ static const struct clk_range plla_outputs[] = {
|
||||
{ .min = 2343750, .max = 1200000000 },
|
||||
};
|
||||
|
||||
/* Fractional PLL core output range. */
|
||||
static const struct clk_range core_outputs[] = {
|
||||
{ .min = 600000000, .max = 1200000000 },
|
||||
};
|
||||
|
||||
static const struct clk_pll_characteristics plla_characteristics = {
|
||||
.input = { .min = 12000000, .max = 48000000 },
|
||||
.num_output = ARRAY_SIZE(plla_outputs),
|
||||
.output = plla_outputs,
|
||||
.core_output = core_outputs,
|
||||
};
|
||||
|
||||
static const struct clk_range upll_outputs[] = {
|
||||
@ -40,6 +46,7 @@ static const struct clk_pll_characteristics upll_characteristics = {
|
||||
.input = { .min = 12000000, .max = 48000000 },
|
||||
.num_output = ARRAY_SIZE(upll_outputs),
|
||||
.output = upll_outputs,
|
||||
.core_output = core_outputs,
|
||||
.upll = true,
|
||||
};
|
||||
|
||||
|
946
drivers/clk/at91/sam9x7.c
Normal file
946
drivers/clk/at91/sam9x7.c
Normal file
@ -0,0 +1,946 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* SAM9X7 PMC code.
|
||||
*
|
||||
* Copyright (C) 2023 Microchip Technology Inc. and its subsidiaries
|
||||
*
|
||||
* Author: Varshini Rajendran <varshini.rajendran@microchip.com>
|
||||
*
|
||||
*/
|
||||
#include <linux/clk.h>
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/mfd/syscon.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
#include <dt-bindings/clock/at91.h>
|
||||
|
||||
#include "pmc.h"
|
||||
|
||||
static DEFINE_SPINLOCK(pmc_pll_lock);
|
||||
static DEFINE_SPINLOCK(mck_lock);
|
||||
|
||||
/**
|
||||
* enum pll_ids - PLL clocks identifiers
|
||||
* @PLL_ID_PLLA: PLLA identifier
|
||||
* @PLL_ID_UPLL: UPLL identifier
|
||||
* @PLL_ID_AUDIO: Audio PLL identifier
|
||||
* @PLL_ID_LVDS: LVDS PLL identifier
|
||||
* @PLL_ID_PLLA_DIV2: PLLA DIV2 identifier
|
||||
* @PLL_ID_MAX: Max PLL Identifier
|
||||
*/
|
||||
enum pll_ids {
|
||||
PLL_ID_PLLA,
|
||||
PLL_ID_UPLL,
|
||||
PLL_ID_AUDIO,
|
||||
PLL_ID_LVDS,
|
||||
PLL_ID_PLLA_DIV2,
|
||||
PLL_ID_MAX,
|
||||
};
|
||||
|
||||
/**
|
||||
* enum pll_type - PLL type identifiers
|
||||
* @PLL_TYPE_FRAC: fractional PLL identifier
|
||||
* @PLL_TYPE_DIV: divider PLL identifier
|
||||
*/
|
||||
enum pll_type {
|
||||
PLL_TYPE_FRAC,
|
||||
PLL_TYPE_DIV,
|
||||
};
|
||||
|
||||
static const struct clk_master_characteristics mck_characteristics = {
|
||||
.output = { .min = 32000000, .max = 266666667 },
|
||||
.divisors = { 1, 2, 4, 3, 5},
|
||||
.have_div3_pres = 1,
|
||||
};
|
||||
|
||||
static const struct clk_master_layout sam9x7_master_layout = {
|
||||
.mask = 0x373,
|
||||
.pres_shift = 4,
|
||||
.offset = 0x28,
|
||||
};
|
||||
|
||||
/* Fractional PLL core output range. */
|
||||
static const struct clk_range plla_core_outputs[] = {
|
||||
{ .min = 375000000, .max = 1600000000 },
|
||||
};
|
||||
|
||||
static const struct clk_range upll_core_outputs[] = {
|
||||
{ .min = 600000000, .max = 1200000000 },
|
||||
};
|
||||
|
||||
static const struct clk_range lvdspll_core_outputs[] = {
|
||||
{ .min = 400000000, .max = 800000000 },
|
||||
};
|
||||
|
||||
static const struct clk_range audiopll_core_outputs[] = {
|
||||
{ .min = 400000000, .max = 800000000 },
|
||||
};
|
||||
|
||||
static const struct clk_range plladiv2_core_outputs[] = {
|
||||
{ .min = 375000000, .max = 1600000000 },
|
||||
};
|
||||
|
||||
/* Fractional PLL output range. */
|
||||
static const struct clk_range plla_outputs[] = {
|
||||
{ .min = 732421, .max = 800000000 },
|
||||
};
|
||||
|
||||
static const struct clk_range upll_outputs[] = {
|
||||
{ .min = 300000000, .max = 600000000 },
|
||||
};
|
||||
|
||||
static const struct clk_range lvdspll_outputs[] = {
|
||||
{ .min = 10000000, .max = 800000000 },
|
||||
};
|
||||
|
||||
static const struct clk_range audiopll_outputs[] = {
|
||||
{ .min = 10000000, .max = 800000000 },
|
||||
};
|
||||
|
||||
static const struct clk_range plladiv2_outputs[] = {
|
||||
{ .min = 366210, .max = 400000000 },
|
||||
};
|
||||
|
||||
/* PLL characteristics. */
|
||||
static const struct clk_pll_characteristics plla_characteristics = {
|
||||
.input = { .min = 20000000, .max = 50000000 },
|
||||
.num_output = ARRAY_SIZE(plla_outputs),
|
||||
.output = plla_outputs,
|
||||
.core_output = plla_core_outputs,
|
||||
};
|
||||
|
||||
static const struct clk_pll_characteristics upll_characteristics = {
|
||||
.input = { .min = 20000000, .max = 50000000 },
|
||||
.num_output = ARRAY_SIZE(upll_outputs),
|
||||
.output = upll_outputs,
|
||||
.core_output = upll_core_outputs,
|
||||
.upll = true,
|
||||
};
|
||||
|
||||
static const struct clk_pll_characteristics lvdspll_characteristics = {
|
||||
.input = { .min = 20000000, .max = 50000000 },
|
||||
.num_output = ARRAY_SIZE(lvdspll_outputs),
|
||||
.output = lvdspll_outputs,
|
||||
.core_output = lvdspll_core_outputs,
|
||||
};
|
||||
|
||||
static const struct clk_pll_characteristics audiopll_characteristics = {
|
||||
.input = { .min = 20000000, .max = 50000000 },
|
||||
.num_output = ARRAY_SIZE(audiopll_outputs),
|
||||
.output = audiopll_outputs,
|
||||
.core_output = audiopll_core_outputs,
|
||||
};
|
||||
|
||||
static const struct clk_pll_characteristics plladiv2_characteristics = {
|
||||
.input = { .min = 20000000, .max = 50000000 },
|
||||
.num_output = ARRAY_SIZE(plladiv2_outputs),
|
||||
.output = plladiv2_outputs,
|
||||
.core_output = plladiv2_core_outputs,
|
||||
};
|
||||
|
||||
/* Layout for fractional PLL ID PLLA. */
|
||||
static const struct clk_pll_layout plla_frac_layout = {
|
||||
.mul_mask = GENMASK(31, 24),
|
||||
.frac_mask = GENMASK(21, 0),
|
||||
.mul_shift = 24,
|
||||
.frac_shift = 0,
|
||||
.div2 = 1,
|
||||
};
|
||||
|
||||
/* Layout for fractional PLLs. */
|
||||
static const struct clk_pll_layout pll_frac_layout = {
|
||||
.mul_mask = GENMASK(31, 24),
|
||||
.frac_mask = GENMASK(21, 0),
|
||||
.mul_shift = 24,
|
||||
.frac_shift = 0,
|
||||
};
|
||||
|
||||
/* Layout for DIV PLLs. */
|
||||
static const struct clk_pll_layout pll_divpmc_layout = {
|
||||
.div_mask = GENMASK(7, 0),
|
||||
.endiv_mask = BIT(29),
|
||||
.div_shift = 0,
|
||||
.endiv_shift = 29,
|
||||
};
|
||||
|
||||
/* Layout for DIV PLL ID PLLADIV2. */
|
||||
static const struct clk_pll_layout plladiv2_divpmc_layout = {
|
||||
.div_mask = GENMASK(7, 0),
|
||||
.endiv_mask = BIT(29),
|
||||
.div_shift = 0,
|
||||
.endiv_shift = 29,
|
||||
.div2 = 1,
|
||||
};
|
||||
|
||||
/* Layout for DIVIO dividers. */
|
||||
static const struct clk_pll_layout pll_divio_layout = {
|
||||
.div_mask = GENMASK(19, 12),
|
||||
.endiv_mask = BIT(30),
|
||||
.div_shift = 12,
|
||||
.endiv_shift = 30,
|
||||
};
|
||||
|
||||
/*
|
||||
* PLL clocks description
|
||||
* @n: clock name
|
||||
* @p: clock parent
|
||||
* @l: clock layout
|
||||
* @t: clock type
|
||||
* @c: pll characteristics
|
||||
* @f: clock flags
|
||||
* @eid: export index in sam9x7->chws[] array
|
||||
*/
|
||||
static const struct {
|
||||
const char *n;
|
||||
const char *p;
|
||||
const struct clk_pll_layout *l;
|
||||
u8 t;
|
||||
const struct clk_pll_characteristics *c;
|
||||
unsigned long f;
|
||||
u8 eid;
|
||||
} sam9x7_plls[][3] = {
|
||||
[PLL_ID_PLLA] = {
|
||||
{
|
||||
.n = "plla_fracck",
|
||||
.p = "mainck",
|
||||
.l = &plla_frac_layout,
|
||||
.t = PLL_TYPE_FRAC,
|
||||
/*
|
||||
* This feeds plla_divpmcck which feeds CPU. It should
|
||||
* not be disabled.
|
||||
*/
|
||||
.f = CLK_IS_CRITICAL | CLK_SET_RATE_GATE,
|
||||
.c = &plla_characteristics,
|
||||
},
|
||||
|
||||
{
|
||||
.n = "plla_divpmcck",
|
||||
.p = "plla_fracck",
|
||||
.l = &pll_divpmc_layout,
|
||||
.t = PLL_TYPE_DIV,
|
||||
/* This feeds CPU. It should not be disabled */
|
||||
.f = CLK_IS_CRITICAL | CLK_SET_RATE_GATE,
|
||||
.eid = PMC_PLLACK,
|
||||
.c = &plla_characteristics,
|
||||
},
|
||||
},
|
||||
|
||||
[PLL_ID_UPLL] = {
|
||||
{
|
||||
.n = "upll_fracck",
|
||||
.p = "main_osc",
|
||||
.l = &pll_frac_layout,
|
||||
.t = PLL_TYPE_FRAC,
|
||||
.f = CLK_SET_RATE_GATE,
|
||||
.c = &upll_characteristics,
|
||||
},
|
||||
|
||||
{
|
||||
.n = "upll_divpmcck",
|
||||
.p = "upll_fracck",
|
||||
.l = &pll_divpmc_layout,
|
||||
.t = PLL_TYPE_DIV,
|
||||
.f = CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE |
|
||||
CLK_SET_RATE_PARENT,
|
||||
.eid = PMC_UTMI,
|
||||
.c = &upll_characteristics,
|
||||
},
|
||||
},
|
||||
|
||||
[PLL_ID_AUDIO] = {
|
||||
{
|
||||
.n = "audiopll_fracck",
|
||||
.p = "main_osc",
|
||||
.l = &pll_frac_layout,
|
||||
.f = CLK_SET_RATE_GATE,
|
||||
.c = &audiopll_characteristics,
|
||||
.t = PLL_TYPE_FRAC,
|
||||
},
|
||||
|
||||
{
|
||||
.n = "audiopll_divpmcck",
|
||||
.p = "audiopll_fracck",
|
||||
.l = &pll_divpmc_layout,
|
||||
.f = CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE |
|
||||
CLK_SET_RATE_PARENT,
|
||||
.c = &audiopll_characteristics,
|
||||
.eid = PMC_AUDIOPMCPLL,
|
||||
.t = PLL_TYPE_DIV,
|
||||
},
|
||||
|
||||
{
|
||||
.n = "audiopll_diviock",
|
||||
.p = "audiopll_fracck",
|
||||
.l = &pll_divio_layout,
|
||||
.f = CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE |
|
||||
CLK_SET_RATE_PARENT,
|
||||
.c = &audiopll_characteristics,
|
||||
.eid = PMC_AUDIOIOPLL,
|
||||
.t = PLL_TYPE_DIV,
|
||||
},
|
||||
},
|
||||
|
||||
[PLL_ID_LVDS] = {
|
||||
{
|
||||
.n = "lvdspll_fracck",
|
||||
.p = "main_osc",
|
||||
.l = &pll_frac_layout,
|
||||
.f = CLK_SET_RATE_GATE,
|
||||
.c = &lvdspll_characteristics,
|
||||
.t = PLL_TYPE_FRAC,
|
||||
},
|
||||
|
||||
{
|
||||
.n = "lvdspll_divpmcck",
|
||||
.p = "lvdspll_fracck",
|
||||
.l = &pll_divpmc_layout,
|
||||
.f = CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE |
|
||||
CLK_SET_RATE_PARENT,
|
||||
.c = &lvdspll_characteristics,
|
||||
.eid = PMC_LVDSPLL,
|
||||
.t = PLL_TYPE_DIV,
|
||||
},
|
||||
},
|
||||
|
||||
[PLL_ID_PLLA_DIV2] = {
|
||||
{
|
||||
.n = "plla_div2pmcck",
|
||||
.p = "plla_fracck",
|
||||
.l = &plladiv2_divpmc_layout,
|
||||
/*
|
||||
* This may feed critical parts of the system like timers.
|
||||
* It should not be disabled.
|
||||
*/
|
||||
.f = CLK_IS_CRITICAL | CLK_SET_RATE_GATE,
|
||||
.c = &plladiv2_characteristics,
|
||||
.eid = PMC_PLLADIV2,
|
||||
.t = PLL_TYPE_DIV,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static const struct clk_programmable_layout sam9x7_programmable_layout = {
|
||||
.pres_mask = 0xff,
|
||||
.pres_shift = 8,
|
||||
.css_mask = 0x1f,
|
||||
.have_slck_mck = 0,
|
||||
.is_pres_direct = 1,
|
||||
};
|
||||
|
||||
static const struct clk_pcr_layout sam9x7_pcr_layout = {
|
||||
.offset = 0x88,
|
||||
.cmd = BIT(31),
|
||||
.gckcss_mask = GENMASK(12, 8),
|
||||
.pid_mask = GENMASK(6, 0),
|
||||
};
|
||||
|
||||
static const struct {
|
||||
char *n;
|
||||
char *p;
|
||||
u8 id;
|
||||
unsigned long flags;
|
||||
} sam9x7_systemck[] = {
|
||||
/*
|
||||
* ddrck feeds DDR controller and is enabled by bootloader thus we need
|
||||
* to keep it enabled in case there is no Linux consumer for it.
|
||||
*/
|
||||
{ .n = "ddrck", .p = "masterck_div", .id = 2, .flags = CLK_IS_CRITICAL },
|
||||
{ .n = "uhpck", .p = "usbck", .id = 6 },
|
||||
{ .n = "pck0", .p = "prog0", .id = 8 },
|
||||
{ .n = "pck1", .p = "prog1", .id = 9 },
|
||||
};
|
||||
|
||||
/*
|
||||
* Peripheral clocks description
|
||||
* @n: clock name
|
||||
* @f: clock flags
|
||||
* @id: peripheral id
|
||||
*/
|
||||
static const struct {
|
||||
char *n;
|
||||
unsigned long f;
|
||||
u8 id;
|
||||
} sam9x7_periphck[] = {
|
||||
{ .n = "pioA_clk", .id = 2, },
|
||||
{ .n = "pioB_clk", .id = 3, },
|
||||
{ .n = "pioC_clk", .id = 4, },
|
||||
{ .n = "flex0_clk", .id = 5, },
|
||||
{ .n = "flex1_clk", .id = 6, },
|
||||
{ .n = "flex2_clk", .id = 7, },
|
||||
{ .n = "flex3_clk", .id = 8, },
|
||||
{ .n = "flex6_clk", .id = 9, },
|
||||
{ .n = "flex7_clk", .id = 10, },
|
||||
{ .n = "flex8_clk", .id = 11, },
|
||||
{ .n = "sdmmc0_clk", .id = 12, },
|
||||
{ .n = "flex4_clk", .id = 13, },
|
||||
{ .n = "flex5_clk", .id = 14, },
|
||||
{ .n = "flex9_clk", .id = 15, },
|
||||
{ .n = "flex10_clk", .id = 16, },
|
||||
{ .n = "tcb0_clk", .id = 17, },
|
||||
{ .n = "pwm_clk", .id = 18, },
|
||||
{ .n = "adc_clk", .id = 19, },
|
||||
{ .n = "dma0_clk", .id = 20, },
|
||||
{ .n = "uhphs_clk", .id = 22, },
|
||||
{ .n = "udphs_clk", .id = 23, },
|
||||
{ .n = "macb0_clk", .id = 24, },
|
||||
{ .n = "lcd_clk", .id = 25, },
|
||||
{ .n = "sdmmc1_clk", .id = 26, },
|
||||
{ .n = "ssc_clk", .id = 28, },
|
||||
{ .n = "can0_clk", .id = 29, },
|
||||
{ .n = "can1_clk", .id = 30, },
|
||||
{ .n = "flex11_clk", .id = 32, },
|
||||
{ .n = "flex12_clk", .id = 33, },
|
||||
{ .n = "i2s_clk", .id = 34, },
|
||||
{ .n = "qspi_clk", .id = 35, },
|
||||
{ .n = "gfx2d_clk", .id = 36, },
|
||||
{ .n = "pit64b0_clk", .id = 37, },
|
||||
{ .n = "trng_clk", .id = 38, },
|
||||
{ .n = "aes_clk", .id = 39, },
|
||||
{ .n = "tdes_clk", .id = 40, },
|
||||
{ .n = "sha_clk", .id = 41, },
|
||||
{ .n = "classd_clk", .id = 42, },
|
||||
{ .n = "isi_clk", .id = 43, },
|
||||
{ .n = "pioD_clk", .id = 44, },
|
||||
{ .n = "tcb1_clk", .id = 45, },
|
||||
{ .n = "dbgu_clk", .id = 47, },
|
||||
/*
|
||||
* mpddr_clk feeds DDR controller and is enabled by bootloader thus we
|
||||
* need to keep it enabled in case there is no Linux consumer for it.
|
||||
*/
|
||||
{ .n = "mpddr_clk", .id = 49, .f = CLK_IS_CRITICAL },
|
||||
{ .n = "csi2dc_clk", .id = 52, },
|
||||
{ .n = "csi4l_clk", .id = 53, },
|
||||
{ .n = "dsi4l_clk", .id = 54, },
|
||||
{ .n = "lvdsc_clk", .id = 56, },
|
||||
{ .n = "pit64b1_clk", .id = 58, },
|
||||
{ .n = "puf_clk", .id = 59, },
|
||||
{ .n = "gmactsu_clk", .id = 67, },
|
||||
};
|
||||
|
||||
/*
|
||||
* Generic clock description
|
||||
* @n: clock name
|
||||
* @pp: PLL parents
|
||||
* @pp_mux_table: PLL parents mux table
|
||||
* @r: clock output range
|
||||
* @pp_chg_id: id in parent array of changeable PLL parent
|
||||
* @pp_count: PLL parents count
|
||||
* @id: clock id
|
||||
*/
|
||||
static const struct {
|
||||
const char *n;
|
||||
const char *pp[8];
|
||||
const char pp_mux_table[8];
|
||||
struct clk_range r;
|
||||
int pp_chg_id;
|
||||
u8 pp_count;
|
||||
u8 id;
|
||||
} sam9x7_gck[] = {
|
||||
{
|
||||
.n = "flex0_gclk",
|
||||
.id = 5,
|
||||
.pp = { "plla_div2pmcck", },
|
||||
.pp_mux_table = { 8, },
|
||||
.pp_count = 1,
|
||||
.pp_chg_id = INT_MIN,
|
||||
},
|
||||
|
||||
{
|
||||
.n = "flex1_gclk",
|
||||
.id = 6,
|
||||
.pp = { "plla_div2pmcck", },
|
||||
.pp_mux_table = { 8, },
|
||||
.pp_count = 1,
|
||||
.pp_chg_id = INT_MIN,
|
||||
},
|
||||
|
||||
{
|
||||
.n = "flex2_gclk",
|
||||
.id = 7,
|
||||
.pp = { "plla_div2pmcck", },
|
||||
.pp_mux_table = { 8, },
|
||||
.pp_count = 1,
|
||||
.pp_chg_id = INT_MIN,
|
||||
},
|
||||
|
||||
{
|
||||
.n = "flex3_gclk",
|
||||
.id = 8,
|
||||
.pp = { "plla_div2pmcck", },
|
||||
.pp_mux_table = { 8, },
|
||||
.pp_count = 1,
|
||||
.pp_chg_id = INT_MIN,
|
||||
},
|
||||
|
||||
{
|
||||
.n = "flex6_gclk",
|
||||
.id = 9,
|
||||
.pp = { "plla_div2pmcck", },
|
||||
.pp_mux_table = { 8, },
|
||||
.pp_count = 1,
|
||||
.pp_chg_id = INT_MIN,
|
||||
},
|
||||
|
||||
{
|
||||
.n = "flex7_gclk",
|
||||
.id = 10,
|
||||
.pp = { "plla_div2pmcck", },
|
||||
.pp_mux_table = { 8, },
|
||||
.pp_count = 1,
|
||||
.pp_chg_id = INT_MIN,
|
||||
},
|
||||
|
||||
{
|
||||
.n = "flex8_gclk",
|
||||
.id = 11,
|
||||
.pp = { "plla_div2pmcck", },
|
||||
.pp_mux_table = { 8, },
|
||||
.pp_count = 1,
|
||||
.pp_chg_id = INT_MIN,
|
||||
},
|
||||
|
||||
{
|
||||
.n = "sdmmc0_gclk",
|
||||
.id = 12,
|
||||
.r = { .max = 105000000 },
|
||||
.pp = { "audiopll_divpmcck", "plla_div2pmcck", },
|
||||
.pp_mux_table = { 6, 8, },
|
||||
.pp_count = 2,
|
||||
.pp_chg_id = INT_MIN,
|
||||
},
|
||||
|
||||
{
|
||||
.n = "flex4_gclk",
|
||||
.id = 13,
|
||||
.pp = { "plla_div2pmcck", },
|
||||
.pp_mux_table = { 8, },
|
||||
.pp_count = 1,
|
||||
.pp_chg_id = INT_MIN,
|
||||
},
|
||||
|
||||
{
|
||||
.n = "flex5_gclk",
|
||||
.id = 14,
|
||||
.pp = { "plla_div2pmcck", },
|
||||
.pp_mux_table = { 8, },
|
||||
.pp_count = 1,
|
||||
.pp_chg_id = INT_MIN,
|
||||
},
|
||||
|
||||
{
|
||||
.n = "flex9_gclk",
|
||||
.id = 15,
|
||||
.pp = { "plla_div2pmcck", },
|
||||
.pp_mux_table = { 8, },
|
||||
.pp_count = 1,
|
||||
.pp_chg_id = INT_MIN,
|
||||
},
|
||||
|
||||
{
|
||||
.n = "flex10_gclk",
|
||||
.id = 16,
|
||||
.pp = { "plla_div2pmcck", },
|
||||
.pp_mux_table = { 8, },
|
||||
.pp_count = 1,
|
||||
.pp_chg_id = INT_MIN,
|
||||
},
|
||||
|
||||
{
|
||||
.n = "tcb0_gclk",
|
||||
.id = 17,
|
||||
.pp = { "audiopll_divpmcck", "plla_div2pmcck", },
|
||||
.pp_mux_table = { 6, 8, },
|
||||
.pp_count = 2,
|
||||
.pp_chg_id = INT_MIN,
|
||||
},
|
||||
|
||||
{
|
||||
.n = "adc_gclk",
|
||||
.id = 19,
|
||||
.pp = { "upll_divpmcck", "plla_div2pmcck", },
|
||||
.pp_mux_table = { 5, 8, },
|
||||
.pp_count = 2,
|
||||
.pp_chg_id = INT_MIN,
|
||||
},
|
||||
|
||||
{
|
||||
.n = "lcd_gclk",
|
||||
.id = 25,
|
||||
.r = { .max = 75000000 },
|
||||
.pp = { "audiopll_divpmcck", "plla_div2pmcck", },
|
||||
.pp_mux_table = { 6, 8, },
|
||||
.pp_count = 2,
|
||||
.pp_chg_id = INT_MIN,
|
||||
},
|
||||
|
||||
{
|
||||
.n = "sdmmc1_gclk",
|
||||
.id = 26,
|
||||
.r = { .max = 105000000 },
|
||||
.pp = { "audiopll_divpmcck", "plla_div2pmcck", },
|
||||
.pp_mux_table = { 6, 8, },
|
||||
.pp_count = 2,
|
||||
.pp_chg_id = INT_MIN,
|
||||
},
|
||||
|
||||
{
|
||||
.n = "mcan0_gclk",
|
||||
.id = 29,
|
||||
.r = { .max = 80000000 },
|
||||
.pp = { "upll_divpmcck", "plla_div2pmcck", },
|
||||
.pp_mux_table = { 5, 8, },
|
||||
.pp_count = 2,
|
||||
.pp_chg_id = INT_MIN,
|
||||
},
|
||||
|
||||
{
|
||||
.n = "mcan1_gclk",
|
||||
.id = 30,
|
||||
.r = { .max = 80000000 },
|
||||
.pp = { "upll_divpmcck", "plla_div2pmcck", },
|
||||
.pp_mux_table = { 5, 8, },
|
||||
.pp_count = 2,
|
||||
.pp_chg_id = INT_MIN,
|
||||
},
|
||||
|
||||
{
|
||||
.n = "flex11_gclk",
|
||||
.id = 32,
|
||||
.pp = { "plla_div2pmcck", },
|
||||
.pp_mux_table = { 8, },
|
||||
.pp_count = 1,
|
||||
.pp_chg_id = INT_MIN,
|
||||
},
|
||||
|
||||
{
|
||||
.n = "flex12_gclk",
|
||||
.id = 33,
|
||||
.pp = { "plla_div2pmcck", },
|
||||
.pp_mux_table = { 8, },
|
||||
.pp_count = 1,
|
||||
.pp_chg_id = INT_MIN,
|
||||
},
|
||||
|
||||
{
|
||||
.n = "i2s_gclk",
|
||||
.id = 34,
|
||||
.r = { .max = 100000000 },
|
||||
.pp = { "audiopll_divpmcck", "plla_div2pmcck", },
|
||||
.pp_mux_table = { 6, 8, },
|
||||
.pp_count = 2,
|
||||
.pp_chg_id = INT_MIN,
|
||||
},
|
||||
|
||||
{
|
||||
.n = "qspi_gclk",
|
||||
.id = 35,
|
||||
.r = { .max = 200000000 },
|
||||
.pp = { "audiopll_divpmcck", "plla_div2pmcck", },
|
||||
.pp_mux_table = { 6, 8, },
|
||||
.pp_count = 2,
|
||||
.pp_chg_id = INT_MIN,
|
||||
},
|
||||
|
||||
{
|
||||
.n = "pit64b0_gclk",
|
||||
.id = 37,
|
||||
.pp = { "plla_div2pmcck", },
|
||||
.pp_mux_table = { 8, },
|
||||
.pp_count = 1,
|
||||
.pp_chg_id = INT_MIN,
|
||||
},
|
||||
|
||||
{
|
||||
.n = "classd_gclk",
|
||||
.id = 42,
|
||||
.r = { .max = 100000000 },
|
||||
.pp = { "audiopll_divpmcck", "plla_div2pmcck", },
|
||||
.pp_mux_table = { 6, 8, },
|
||||
.pp_count = 2,
|
||||
.pp_chg_id = INT_MIN,
|
||||
},
|
||||
|
||||
{
|
||||
.n = "tcb1_gclk",
|
||||
.id = 45,
|
||||
.pp = { "audiopll_divpmcck", "plla_div2pmcck", },
|
||||
.pp_mux_table = { 6, 8, },
|
||||
.pp_count = 2,
|
||||
.pp_chg_id = INT_MIN,
|
||||
},
|
||||
|
||||
{
|
||||
.n = "dbgu_gclk",
|
||||
.id = 47,
|
||||
.pp = { "plla_div2pmcck", },
|
||||
.pp_mux_table = { 8, },
|
||||
.pp_count = 1,
|
||||
.pp_chg_id = INT_MIN,
|
||||
},
|
||||
|
||||
{
|
||||
.n = "mipiphy_gclk",
|
||||
.id = 55,
|
||||
.r = { .max = 27000000 },
|
||||
.pp = { "plla_div2pmcck", },
|
||||
.pp_mux_table = { 8, },
|
||||
.pp_count = 1,
|
||||
.pp_chg_id = INT_MIN,
|
||||
},
|
||||
|
||||
{
|
||||
.n = "pit64b1_gclk",
|
||||
.id = 58,
|
||||
.pp = { "plla_div2pmcck", },
|
||||
.pp_mux_table = { 8, },
|
||||
.pp_count = 1,
|
||||
.pp_chg_id = INT_MIN,
|
||||
},
|
||||
|
||||
{
|
||||
.n = "gmac_gclk",
|
||||
.id = 67,
|
||||
.pp = { "audiopll_divpmcck", "plla_div2pmcck", },
|
||||
.pp_mux_table = { 6, 8, },
|
||||
.pp_count = 2,
|
||||
.pp_chg_id = INT_MIN,
|
||||
},
|
||||
};
|
||||
|
||||
static void __init sam9x7_pmc_setup(struct device_node *np)
|
||||
{
|
||||
struct clk_range range = CLK_RANGE(0, 0);
|
||||
const char *td_slck_name, *md_slck_name, *mainxtal_name;
|
||||
struct pmc_data *sam9x7_pmc;
|
||||
const char *parent_names[9];
|
||||
void **clk_mux_buffer = NULL;
|
||||
int clk_mux_buffer_size = 0;
|
||||
struct clk_hw *main_osc_hw;
|
||||
struct regmap *regmap;
|
||||
struct clk_hw *hw;
|
||||
int i, j;
|
||||
|
||||
i = of_property_match_string(np, "clock-names", "td_slck");
|
||||
if (i < 0)
|
||||
return;
|
||||
|
||||
td_slck_name = of_clk_get_parent_name(np, i);
|
||||
|
||||
i = of_property_match_string(np, "clock-names", "md_slck");
|
||||
if (i < 0)
|
||||
return;
|
||||
|
||||
md_slck_name = of_clk_get_parent_name(np, i);
|
||||
|
||||
i = of_property_match_string(np, "clock-names", "main_xtal");
|
||||
if (i < 0)
|
||||
return;
|
||||
mainxtal_name = of_clk_get_parent_name(np, i);
|
||||
|
||||
regmap = device_node_to_regmap(np);
|
||||
if (IS_ERR(regmap))
|
||||
return;
|
||||
|
||||
sam9x7_pmc = pmc_data_allocate(PMC_LVDSPLL + 1,
|
||||
nck(sam9x7_systemck),
|
||||
nck(sam9x7_periphck),
|
||||
nck(sam9x7_gck), 8);
|
||||
if (!sam9x7_pmc)
|
||||
return;
|
||||
|
||||
clk_mux_buffer = kmalloc(sizeof(void *) *
|
||||
(ARRAY_SIZE(sam9x7_gck)),
|
||||
GFP_KERNEL);
|
||||
if (!clk_mux_buffer)
|
||||
goto err_free;
|
||||
|
||||
hw = at91_clk_register_main_rc_osc(regmap, "main_rc_osc", 12000000,
|
||||
50000000);
|
||||
if (IS_ERR(hw))
|
||||
goto err_free;
|
||||
|
||||
hw = at91_clk_register_main_osc(regmap, "main_osc", mainxtal_name, NULL, 0);
|
||||
if (IS_ERR(hw))
|
||||
goto err_free;
|
||||
main_osc_hw = hw;
|
||||
|
||||
parent_names[0] = "main_rc_osc";
|
||||
parent_names[1] = "main_osc";
|
||||
hw = at91_clk_register_sam9x5_main(regmap, "mainck", parent_names, NULL, 2);
|
||||
if (IS_ERR(hw))
|
||||
goto err_free;
|
||||
|
||||
sam9x7_pmc->chws[PMC_MAIN] = hw;
|
||||
|
||||
for (i = 0; i < PLL_ID_MAX; i++) {
|
||||
for (j = 0; j < 3; j++) {
|
||||
struct clk_hw *parent_hw;
|
||||
|
||||
if (!sam9x7_plls[i][j].n)
|
||||
continue;
|
||||
|
||||
switch (sam9x7_plls[i][j].t) {
|
||||
case PLL_TYPE_FRAC:
|
||||
if (!strcmp(sam9x7_plls[i][j].p, "mainck"))
|
||||
parent_hw = sam9x7_pmc->chws[PMC_MAIN];
|
||||
else if (!strcmp(sam9x7_plls[i][j].p, "main_osc"))
|
||||
parent_hw = main_osc_hw;
|
||||
else
|
||||
parent_hw = __clk_get_hw(of_clk_get_by_name
|
||||
(np, sam9x7_plls[i][j].p));
|
||||
|
||||
hw = sam9x60_clk_register_frac_pll(regmap,
|
||||
&pmc_pll_lock,
|
||||
sam9x7_plls[i][j].n,
|
||||
sam9x7_plls[i][j].p,
|
||||
parent_hw, i,
|
||||
sam9x7_plls[i][j].c,
|
||||
sam9x7_plls[i][j].l,
|
||||
sam9x7_plls[i][j].f);
|
||||
break;
|
||||
|
||||
case PLL_TYPE_DIV:
|
||||
hw = sam9x60_clk_register_div_pll(regmap,
|
||||
&pmc_pll_lock,
|
||||
sam9x7_plls[i][j].n,
|
||||
sam9x7_plls[i][j].p, NULL, i,
|
||||
sam9x7_plls[i][j].c,
|
||||
sam9x7_plls[i][j].l,
|
||||
sam9x7_plls[i][j].f, 0);
|
||||
break;
|
||||
|
||||
default:
|
||||
continue;
|
||||
}
|
||||
|
||||
if (IS_ERR(hw))
|
||||
goto err_free;
|
||||
|
||||
if (sam9x7_plls[i][j].eid)
|
||||
sam9x7_pmc->chws[sam9x7_plls[i][j].eid] = hw;
|
||||
}
|
||||
}
|
||||
|
||||
parent_names[0] = md_slck_name;
|
||||
parent_names[1] = "mainck";
|
||||
parent_names[2] = "plla_divpmcck";
|
||||
parent_names[3] = "upll_divpmcck";
|
||||
hw = at91_clk_register_master_pres(regmap, "masterck_pres", 4,
|
||||
parent_names, NULL, &sam9x7_master_layout,
|
||||
&mck_characteristics, &mck_lock);
|
||||
if (IS_ERR(hw))
|
||||
goto err_free;
|
||||
|
||||
hw = at91_clk_register_master_div(regmap, "masterck_div",
|
||||
"masterck_pres", NULL, &sam9x7_master_layout,
|
||||
&mck_characteristics, &mck_lock,
|
||||
CLK_SET_RATE_GATE, 0);
|
||||
if (IS_ERR(hw))
|
||||
goto err_free;
|
||||
|
||||
sam9x7_pmc->chws[PMC_MCK] = hw;
|
||||
|
||||
parent_names[0] = "plla_divpmcck";
|
||||
parent_names[1] = "upll_divpmcck";
|
||||
parent_names[2] = "main_osc";
|
||||
hw = sam9x60_clk_register_usb(regmap, "usbck", parent_names, 3);
|
||||
if (IS_ERR(hw))
|
||||
goto err_free;
|
||||
|
||||
parent_names[0] = md_slck_name;
|
||||
parent_names[1] = td_slck_name;
|
||||
parent_names[2] = "mainck";
|
||||
parent_names[3] = "masterck_div";
|
||||
parent_names[4] = "plla_divpmcck";
|
||||
parent_names[5] = "upll_divpmcck";
|
||||
parent_names[6] = "audiopll_divpmcck";
|
||||
for (i = 0; i < 2; i++) {
|
||||
char name[6];
|
||||
|
||||
snprintf(name, sizeof(name), "prog%d", i);
|
||||
|
||||
hw = at91_clk_register_programmable(regmap, name,
|
||||
parent_names, NULL, 7, i,
|
||||
&sam9x7_programmable_layout,
|
||||
NULL);
|
||||
if (IS_ERR(hw))
|
||||
goto err_free;
|
||||
|
||||
sam9x7_pmc->pchws[i] = hw;
|
||||
}
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(sam9x7_systemck); i++) {
|
||||
hw = at91_clk_register_system(regmap, sam9x7_systemck[i].n,
|
||||
sam9x7_systemck[i].p, NULL,
|
||||
sam9x7_systemck[i].id,
|
||||
sam9x7_systemck[i].flags);
|
||||
if (IS_ERR(hw))
|
||||
goto err_free;
|
||||
|
||||
sam9x7_pmc->shws[sam9x7_systemck[i].id] = hw;
|
||||
}
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(sam9x7_periphck); i++) {
|
||||
hw = at91_clk_register_sam9x5_peripheral(regmap, &pmc_pcr_lock,
|
||||
&sam9x7_pcr_layout,
|
||||
sam9x7_periphck[i].n,
|
||||
"masterck_div", NULL,
|
||||
sam9x7_periphck[i].id,
|
||||
&range, INT_MIN,
|
||||
sam9x7_periphck[i].f);
|
||||
if (IS_ERR(hw))
|
||||
goto err_free;
|
||||
|
||||
sam9x7_pmc->phws[sam9x7_periphck[i].id] = hw;
|
||||
}
|
||||
|
||||
parent_names[0] = md_slck_name;
|
||||
parent_names[1] = td_slck_name;
|
||||
parent_names[2] = "mainck";
|
||||
parent_names[3] = "masterck_div";
|
||||
for (i = 0; i < ARRAY_SIZE(sam9x7_gck); i++) {
|
||||
u8 num_parents = 4 + sam9x7_gck[i].pp_count;
|
||||
u32 *mux_table;
|
||||
|
||||
mux_table = kmalloc_array(num_parents, sizeof(*mux_table),
|
||||
GFP_KERNEL);
|
||||
if (!mux_table)
|
||||
goto err_free;
|
||||
|
||||
PMC_INIT_TABLE(mux_table, 4);
|
||||
PMC_FILL_TABLE(&mux_table[4], sam9x7_gck[i].pp_mux_table,
|
||||
sam9x7_gck[i].pp_count);
|
||||
PMC_FILL_TABLE(&parent_names[4], sam9x7_gck[i].pp,
|
||||
sam9x7_gck[i].pp_count);
|
||||
|
||||
hw = at91_clk_register_generated(regmap, &pmc_pcr_lock,
|
||||
&sam9x7_pcr_layout,
|
||||
sam9x7_gck[i].n,
|
||||
parent_names, NULL, mux_table,
|
||||
num_parents,
|
||||
sam9x7_gck[i].id,
|
||||
&sam9x7_gck[i].r,
|
||||
sam9x7_gck[i].pp_chg_id);
|
||||
if (IS_ERR(hw))
|
||||
goto err_free;
|
||||
|
||||
sam9x7_pmc->ghws[sam9x7_gck[i].id] = hw;
|
||||
clk_mux_buffer[clk_mux_buffer_size++] = mux_table;
|
||||
}
|
||||
|
||||
of_clk_add_hw_provider(np, of_clk_hw_pmc_get, sam9x7_pmc);
|
||||
kfree(clk_mux_buffer);
|
||||
|
||||
return;
|
||||
|
||||
err_free:
|
||||
if (clk_mux_buffer) {
|
||||
for (i = 0; i < clk_mux_buffer_size; i++)
|
||||
kfree(clk_mux_buffer[i]);
|
||||
kfree(clk_mux_buffer);
|
||||
}
|
||||
kfree(sam9x7_pmc);
|
||||
}
|
||||
|
||||
/* Some clks are used for a clocksource */
|
||||
CLK_OF_DECLARE(sam9x7_pmc, "microchip,sam9x7-pmc", sam9x7_pmc_setup);
|
@ -16,21 +16,6 @@
|
||||
|
||||
#include "pmc.h"
|
||||
|
||||
#define SAMA7G5_INIT_TABLE(_table, _count) \
|
||||
do { \
|
||||
u8 _i; \
|
||||
for (_i = 0; _i < (_count); _i++) \
|
||||
(_table)[_i] = _i; \
|
||||
} while (0)
|
||||
|
||||
#define SAMA7G5_FILL_TABLE(_to, _from, _count) \
|
||||
do { \
|
||||
u8 _i; \
|
||||
for (_i = 0; _i < (_count); _i++) { \
|
||||
(_to)[_i] = (_from)[_i]; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
static DEFINE_SPINLOCK(pmc_pll_lock);
|
||||
static DEFINE_SPINLOCK(pmc_mck0_lock);
|
||||
static DEFINE_SPINLOCK(pmc_mckX_lock);
|
||||
@ -66,6 +51,7 @@ enum pll_component_id {
|
||||
PLL_COMPID_FRAC,
|
||||
PLL_COMPID_DIV0,
|
||||
PLL_COMPID_DIV1,
|
||||
PLL_COMPID_MAX,
|
||||
};
|
||||
|
||||
/*
|
||||
@ -116,11 +102,17 @@ static const struct clk_range pll_outputs[] = {
|
||||
{ .min = 2343750, .max = 1200000000 },
|
||||
};
|
||||
|
||||
/* Fractional PLL core output range. */
|
||||
static const struct clk_range core_outputs[] = {
|
||||
{ .min = 600000000, .max = 1200000000 },
|
||||
};
|
||||
|
||||
/* CPU PLL characteristics. */
|
||||
static const struct clk_pll_characteristics cpu_pll_characteristics = {
|
||||
.input = { .min = 12000000, .max = 50000000 },
|
||||
.num_output = ARRAY_SIZE(cpu_pll_outputs),
|
||||
.output = cpu_pll_outputs,
|
||||
.core_output = core_outputs,
|
||||
};
|
||||
|
||||
/* PLL characteristics. */
|
||||
@ -128,6 +120,7 @@ static const struct clk_pll_characteristics pll_characteristics = {
|
||||
.input = { .min = 12000000, .max = 50000000 },
|
||||
.num_output = ARRAY_SIZE(pll_outputs),
|
||||
.output = pll_outputs,
|
||||
.core_output = core_outputs,
|
||||
};
|
||||
|
||||
/*
|
||||
@ -165,7 +158,7 @@ static struct sama7g5_pll {
|
||||
u8 t;
|
||||
u8 eid;
|
||||
u8 safe_div;
|
||||
} sama7g5_plls[][PLL_ID_MAX] = {
|
||||
} sama7g5_plls[][PLL_COMPID_MAX] = {
|
||||
[PLL_ID_CPU] = {
|
||||
[PLL_COMPID_FRAC] = {
|
||||
.n = "cpupll_fracck",
|
||||
@ -1038,7 +1031,7 @@ static void __init sama7g5_pmc_setup(struct device_node *np)
|
||||
sama7g5_pmc->chws[PMC_MAIN] = hw;
|
||||
|
||||
for (i = 0; i < PLL_ID_MAX; i++) {
|
||||
for (j = 0; j < 3; j++) {
|
||||
for (j = 0; j < PLL_COMPID_MAX; j++) {
|
||||
struct clk_hw *parent_hw;
|
||||
|
||||
if (!sama7g5_plls[i][j].n)
|
||||
@ -1112,17 +1105,17 @@ static void __init sama7g5_pmc_setup(struct device_node *np)
|
||||
if (!mux_table)
|
||||
goto err_free;
|
||||
|
||||
SAMA7G5_INIT_TABLE(mux_table, 3);
|
||||
SAMA7G5_FILL_TABLE(&mux_table[3], sama7g5_mckx[i].ep_mux_table,
|
||||
sama7g5_mckx[i].ep_count);
|
||||
PMC_INIT_TABLE(mux_table, 3);
|
||||
PMC_FILL_TABLE(&mux_table[3], sama7g5_mckx[i].ep_mux_table,
|
||||
sama7g5_mckx[i].ep_count);
|
||||
for (j = 0; j < sama7g5_mckx[i].ep_count; j++) {
|
||||
u8 pll_id = sama7g5_mckx[i].ep[j].pll_id;
|
||||
u8 pll_compid = sama7g5_mckx[i].ep[j].pll_compid;
|
||||
|
||||
tmp_parent_hws[j] = sama7g5_plls[pll_id][pll_compid].hw;
|
||||
}
|
||||
SAMA7G5_FILL_TABLE(&parent_hws[3], tmp_parent_hws,
|
||||
sama7g5_mckx[i].ep_count);
|
||||
PMC_FILL_TABLE(&parent_hws[3], tmp_parent_hws,
|
||||
sama7g5_mckx[i].ep_count);
|
||||
|
||||
hw = at91_clk_sama7g5_register_master(regmap, sama7g5_mckx[i].n,
|
||||
num_parents, NULL, parent_hws, mux_table,
|
||||
@ -1208,17 +1201,17 @@ static void __init sama7g5_pmc_setup(struct device_node *np)
|
||||
if (!mux_table)
|
||||
goto err_free;
|
||||
|
||||
SAMA7G5_INIT_TABLE(mux_table, 3);
|
||||
SAMA7G5_FILL_TABLE(&mux_table[3], sama7g5_gck[i].pp_mux_table,
|
||||
sama7g5_gck[i].pp_count);
|
||||
PMC_INIT_TABLE(mux_table, 3);
|
||||
PMC_FILL_TABLE(&mux_table[3], sama7g5_gck[i].pp_mux_table,
|
||||
sama7g5_gck[i].pp_count);
|
||||
for (j = 0; j < sama7g5_gck[i].pp_count; j++) {
|
||||
u8 pll_id = sama7g5_gck[i].pp[j].pll_id;
|
||||
u8 pll_compid = sama7g5_gck[i].pp[j].pll_compid;
|
||||
|
||||
tmp_parent_hws[j] = sama7g5_plls[pll_id][pll_compid].hw;
|
||||
}
|
||||
SAMA7G5_FILL_TABLE(&parent_hws[3], tmp_parent_hws,
|
||||
sama7g5_gck[i].pp_count);
|
||||
PMC_FILL_TABLE(&parent_hws[3], tmp_parent_hws,
|
||||
sama7g5_gck[i].pp_count);
|
||||
|
||||
hw = at91_clk_register_generated(regmap, &pmc_pcr_lock,
|
||||
&sama7g5_pcr_layout,
|
||||
|
@ -81,6 +81,7 @@ config CLK_IMX8MP
|
||||
tristate "IMX8MP CCM Clock Driver"
|
||||
depends on ARCH_MXC || COMPILE_TEST
|
||||
select MXC_CLK
|
||||
select AUXILIARY_BUS if RESET_CONTROLLER
|
||||
help
|
||||
Build the driver for i.MX8MP CCM Clock Driver
|
||||
|
||||
|
@ -14,6 +14,7 @@
|
||||
#include "../clk-fractional-divider.h"
|
||||
#include "clk.h"
|
||||
|
||||
#define PCG_PR_MASK BIT(31)
|
||||
#define PCG_PCS_SHIFT 24
|
||||
#define PCG_PCS_MASK 0x7
|
||||
#define PCG_CGC_SHIFT 30
|
||||
@ -78,6 +79,12 @@ static struct clk_hw *imx_ulp_clk_hw_composite(const char *name,
|
||||
struct clk_hw *hw;
|
||||
u32 val;
|
||||
|
||||
val = readl(reg);
|
||||
if (!(val & PCG_PR_MASK)) {
|
||||
pr_info("PCC PR is 0 for clk:%s, bypass\n", name);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (mux_present) {
|
||||
mux = kzalloc(sizeof(*mux), GFP_KERNEL);
|
||||
if (!mux)
|
||||
|
@ -204,6 +204,34 @@ static const struct clk_ops imx8m_clk_composite_mux_ops = {
|
||||
.determine_rate = imx8m_clk_composite_mux_determine_rate,
|
||||
};
|
||||
|
||||
static int imx8m_clk_composite_gate_enable(struct clk_hw *hw)
|
||||
{
|
||||
struct clk_gate *gate = to_clk_gate(hw);
|
||||
unsigned long flags;
|
||||
u32 val;
|
||||
|
||||
spin_lock_irqsave(gate->lock, flags);
|
||||
|
||||
val = readl(gate->reg);
|
||||
val |= BIT(gate->bit_idx);
|
||||
writel(val, gate->reg);
|
||||
|
||||
spin_unlock_irqrestore(gate->lock, flags);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void imx8m_clk_composite_gate_disable(struct clk_hw *hw)
|
||||
{
|
||||
/* composite clk requires the disable hook */
|
||||
}
|
||||
|
||||
static const struct clk_ops imx8m_clk_composite_gate_ops = {
|
||||
.enable = imx8m_clk_composite_gate_enable,
|
||||
.disable = imx8m_clk_composite_gate_disable,
|
||||
.is_enabled = clk_gate_is_enabled,
|
||||
};
|
||||
|
||||
struct clk_hw *__imx8m_clk_hw_composite(const char *name,
|
||||
const char * const *parent_names,
|
||||
int num_parents, void __iomem *reg,
|
||||
@ -217,6 +245,7 @@ struct clk_hw *__imx8m_clk_hw_composite(const char *name,
|
||||
struct clk_mux *mux;
|
||||
const struct clk_ops *divider_ops;
|
||||
const struct clk_ops *mux_ops;
|
||||
const struct clk_ops *gate_ops;
|
||||
|
||||
mux = kzalloc(sizeof(*mux), GFP_KERNEL);
|
||||
if (!mux)
|
||||
@ -257,20 +286,22 @@ struct clk_hw *__imx8m_clk_hw_composite(const char *name,
|
||||
div->flags = CLK_DIVIDER_ROUND_CLOSEST;
|
||||
|
||||
/* skip registering the gate ops if M4 is enabled */
|
||||
if (!mcore_booted) {
|
||||
gate = kzalloc(sizeof(*gate), GFP_KERNEL);
|
||||
if (!gate)
|
||||
goto free_div;
|
||||
gate = kzalloc(sizeof(*gate), GFP_KERNEL);
|
||||
if (!gate)
|
||||
goto free_div;
|
||||
|
||||
gate_hw = &gate->hw;
|
||||
gate->reg = reg;
|
||||
gate->bit_idx = PCG_CGC_SHIFT;
|
||||
gate->lock = &imx_ccm_lock;
|
||||
}
|
||||
gate_hw = &gate->hw;
|
||||
gate->reg = reg;
|
||||
gate->bit_idx = PCG_CGC_SHIFT;
|
||||
gate->lock = &imx_ccm_lock;
|
||||
if (!mcore_booted)
|
||||
gate_ops = &clk_gate_ops;
|
||||
else
|
||||
gate_ops = &imx8m_clk_composite_gate_ops;
|
||||
|
||||
hw = clk_hw_register_composite(NULL, name, parent_names, num_parents,
|
||||
mux_hw, mux_ops, div_hw,
|
||||
divider_ops, gate_hw, &clk_gate_ops, flags);
|
||||
divider_ops, gate_hw, gate_ops, flags);
|
||||
if (IS_ERR(hw))
|
||||
goto free_gate;
|
||||
|
||||
|
@ -76,6 +76,13 @@ static int imx93_clk_composite_gate_enable(struct clk_hw *hw)
|
||||
|
||||
static void imx93_clk_composite_gate_disable(struct clk_hw *hw)
|
||||
{
|
||||
/*
|
||||
* Skip disable the root clock gate if mcore enabled.
|
||||
* The root clock may be used by the mcore.
|
||||
*/
|
||||
if (mcore_booted)
|
||||
return;
|
||||
|
||||
imx93_clk_composite_gate_endisable(hw, 0);
|
||||
}
|
||||
|
||||
@ -222,7 +229,7 @@ struct clk_hw *imx93_clk_composite_flags(const char *name, const char * const *p
|
||||
hw = clk_hw_register_composite(NULL, name, parent_names, num_parents,
|
||||
mux_hw, &clk_mux_ro_ops, div_hw,
|
||||
&clk_divider_ro_ops, NULL, NULL, flags);
|
||||
} else if (!mcore_booted) {
|
||||
} else {
|
||||
gate = kzalloc(sizeof(*gate), GFP_KERNEL);
|
||||
if (!gate)
|
||||
goto fail;
|
||||
@ -238,12 +245,6 @@ struct clk_hw *imx93_clk_composite_flags(const char *name, const char * const *p
|
||||
&imx93_clk_composite_divider_ops, gate_hw,
|
||||
&imx93_clk_composite_gate_ops,
|
||||
flags | CLK_SET_RATE_NO_REPARENT);
|
||||
} else {
|
||||
hw = clk_hw_register_composite(NULL, name, parent_names, num_parents,
|
||||
mux_hw, &imx93_clk_composite_mux_ops, div_hw,
|
||||
&imx93_clk_composite_divider_ops, NULL,
|
||||
&imx93_clk_composite_gate_ops,
|
||||
flags | CLK_SET_RATE_NO_REPARENT);
|
||||
}
|
||||
|
||||
if (IS_ERR(hw))
|
||||
|
@ -78,6 +78,7 @@ struct clk_fracn_gppll {
|
||||
* The Fvco should be in range 2.5Ghz to 5Ghz
|
||||
*/
|
||||
static const struct imx_fracn_gppll_rate_table fracn_tbl[] = {
|
||||
PLL_FRACN_GP(1039500000U, 173, 25, 100, 1, 4),
|
||||
PLL_FRACN_GP(650000000U, 162, 50, 100, 0, 6),
|
||||
PLL_FRACN_GP(594000000U, 198, 0, 1, 0, 8),
|
||||
PLL_FRACN_GP(560000000U, 140, 0, 1, 0, 6),
|
||||
@ -106,6 +107,7 @@ static const struct imx_fracn_gppll_rate_table int_tbl[] = {
|
||||
PLL_FRACN_GP_INTEGER(1700000000U, 141, 1, 2),
|
||||
PLL_FRACN_GP_INTEGER(1400000000U, 175, 1, 3),
|
||||
PLL_FRACN_GP_INTEGER(900000000U, 150, 1, 4),
|
||||
PLL_FRACN_GP_INTEGER(800000000U, 200, 1, 6),
|
||||
};
|
||||
|
||||
struct imx_fracn_gppll_clk imx_fracn_gppll_integer = {
|
||||
@ -291,6 +293,10 @@ static int clk_fracn_gppll_prepare(struct clk_hw *hw)
|
||||
if (val & POWERUP_MASK)
|
||||
return 0;
|
||||
|
||||
if (pll->flags & CLK_FRACN_GPPLL_FRACN)
|
||||
writel_relaxed(readl_relaxed(pll->base + PLL_NUMERATOR),
|
||||
pll->base + PLL_NUMERATOR);
|
||||
|
||||
val |= CLKMUX_BYPASS;
|
||||
writel_relaxed(val, pll->base + PLL_CTRL);
|
||||
|
||||
|
@ -542,8 +542,8 @@ static void __init imx6ul_clocks_init(struct device_node *ccm_node)
|
||||
|
||||
clk_set_parent(hws[IMX6UL_CLK_ENFC_SEL]->clk, hws[IMX6UL_CLK_PLL2_PFD2]->clk);
|
||||
|
||||
clk_set_parent(hws[IMX6UL_CLK_ENET1_REF_SEL]->clk, hws[IMX6UL_CLK_ENET_REF]->clk);
|
||||
clk_set_parent(hws[IMX6UL_CLK_ENET2_REF_SEL]->clk, hws[IMX6UL_CLK_ENET2_REF]->clk);
|
||||
clk_set_parent(hws[IMX6UL_CLK_ENET1_REF_SEL]->clk, hws[IMX6UL_CLK_ENET1_REF_125M]->clk);
|
||||
clk_set_parent(hws[IMX6UL_CLK_ENET2_REF_SEL]->clk, hws[IMX6UL_CLK_ENET2_REF_125M]->clk);
|
||||
|
||||
imx_register_uart_clocks();
|
||||
}
|
||||
|
@ -498,14 +498,14 @@ static void __init imx7d_clocks_init(struct device_node *ccm_node)
|
||||
hws[IMX7D_ENET_AXI_ROOT_SRC] = imx_clk_hw_mux2_flags("enet_axi_src", base + 0x8900, 24, 3, enet_axi_sel, ARRAY_SIZE(enet_axi_sel), CLK_SET_PARENT_GATE);
|
||||
hws[IMX7D_NAND_USDHC_BUS_ROOT_SRC] = imx_clk_hw_mux2_flags("nand_usdhc_src", base + 0x8980, 24, 3, nand_usdhc_bus_sel, ARRAY_SIZE(nand_usdhc_bus_sel), CLK_SET_PARENT_GATE);
|
||||
hws[IMX7D_DRAM_PHYM_ROOT_SRC] = imx_clk_hw_mux2_flags("dram_phym_src", base + 0x9800, 24, 1, dram_phym_sel, ARRAY_SIZE(dram_phym_sel), CLK_SET_PARENT_GATE);
|
||||
hws[IMX7D_DRAM_ROOT_SRC] = imx_clk_hw_mux2_flags("dram_src", base + 0x9880, 24, 1, dram_sel, ARRAY_SIZE(dram_sel), CLK_SET_PARENT_GATE);
|
||||
hws[IMX7D_DRAM_ROOT_SRC] = imx_clk_hw_mux2("dram_src", base + 0x9880, 24, 1, dram_sel, ARRAY_SIZE(dram_sel));
|
||||
hws[IMX7D_DRAM_PHYM_ALT_ROOT_SRC] = imx_clk_hw_mux2_flags("dram_phym_alt_src", base + 0xa000, 24, 3, dram_phym_alt_sel, ARRAY_SIZE(dram_phym_alt_sel), CLK_SET_PARENT_GATE);
|
||||
hws[IMX7D_DRAM_ALT_ROOT_SRC] = imx_clk_hw_mux2_flags("dram_alt_src", base + 0xa080, 24, 3, dram_alt_sel, ARRAY_SIZE(dram_alt_sel), CLK_SET_PARENT_GATE);
|
||||
hws[IMX7D_DRAM_ALT_ROOT_SRC] = imx_clk_hw_mux2("dram_alt_src", base + 0xa080, 24, 3, dram_alt_sel, ARRAY_SIZE(dram_alt_sel));
|
||||
hws[IMX7D_USB_HSIC_ROOT_SRC] = imx_clk_hw_mux2_flags("usb_hsic_src", base + 0xa100, 24, 3, usb_hsic_sel, ARRAY_SIZE(usb_hsic_sel), CLK_SET_PARENT_GATE);
|
||||
hws[IMX7D_PCIE_CTRL_ROOT_SRC] = imx_clk_hw_mux2_flags("pcie_ctrl_src", base + 0xa180, 24, 3, pcie_ctrl_sel, ARRAY_SIZE(pcie_ctrl_sel), CLK_SET_PARENT_GATE);
|
||||
hws[IMX7D_PCIE_PHY_ROOT_SRC] = imx_clk_hw_mux2_flags("pcie_phy_src", base + 0xa200, 24, 3, pcie_phy_sel, ARRAY_SIZE(pcie_phy_sel), CLK_SET_PARENT_GATE);
|
||||
hws[IMX7D_EPDC_PIXEL_ROOT_SRC] = imx_clk_hw_mux2_flags("epdc_pixel_src", base + 0xa280, 24, 3, epdc_pixel_sel, ARRAY_SIZE(epdc_pixel_sel), CLK_SET_PARENT_GATE);
|
||||
hws[IMX7D_LCDIF_PIXEL_ROOT_SRC] = imx_clk_hw_mux2_flags("lcdif_pixel_src", base + 0xa300, 24, 3, lcdif_pixel_sel, ARRAY_SIZE(lcdif_pixel_sel), CLK_SET_PARENT_GATE);
|
||||
hws[IMX7D_LCDIF_PIXEL_ROOT_SRC] = imx_clk_hw_mux2_flags("lcdif_pixel_src", base + 0xa300, 24, 3, lcdif_pixel_sel, ARRAY_SIZE(lcdif_pixel_sel), CLK_SET_PARENT_GATE | CLK_SET_RATE_PARENT);
|
||||
hws[IMX7D_MIPI_DSI_ROOT_SRC] = imx_clk_hw_mux2_flags("mipi_dsi_src", base + 0xa380, 24, 3, mipi_dsi_sel, ARRAY_SIZE(mipi_dsi_sel), CLK_SET_PARENT_GATE);
|
||||
hws[IMX7D_MIPI_CSI_ROOT_SRC] = imx_clk_hw_mux2_flags("mipi_csi_src", base + 0xa400, 24, 3, mipi_csi_sel, ARRAY_SIZE(mipi_csi_sel), CLK_SET_PARENT_GATE);
|
||||
hws[IMX7D_MIPI_DPHY_ROOT_SRC] = imx_clk_hw_mux2_flags("mipi_dphy_src", base + 0xa480, 24, 3, mipi_dphy_sel, ARRAY_SIZE(mipi_dphy_sel), CLK_SET_PARENT_GATE);
|
||||
|
@ -54,10 +54,12 @@ struct clk_imx8_acm_sel {
|
||||
* struct imx8_acm_soc_data - soc specific data
|
||||
* @sels: pointer to struct clk_imx8_acm_sel
|
||||
* @num_sels: numbers of items
|
||||
* @mclk_sels: pointer to imx8qm/qxp/dxl_mclk_sels
|
||||
*/
|
||||
struct imx8_acm_soc_data {
|
||||
struct clk_imx8_acm_sel *sels;
|
||||
unsigned int num_sels;
|
||||
struct clk_parent_data *mclk_sels;
|
||||
};
|
||||
|
||||
/**
|
||||
@ -111,11 +113,14 @@ static const struct clk_parent_data imx8qm_mclk_out_sels[] = {
|
||||
{ .fw_name = "sai6_rx_bclk" },
|
||||
};
|
||||
|
||||
static const struct clk_parent_data imx8qm_mclk_sels[] = {
|
||||
#define ACM_AUD_CLK0_SEL_INDEX 2
|
||||
#define ACM_AUD_CLK1_SEL_INDEX 3
|
||||
|
||||
static struct clk_parent_data imx8qm_mclk_sels[] = {
|
||||
{ .fw_name = "aud_pll_div_clk0_lpcg_clk" },
|
||||
{ .fw_name = "aud_pll_div_clk1_lpcg_clk" },
|
||||
{ .fw_name = "acm_aud_clk0_sel" },
|
||||
{ .fw_name = "acm_aud_clk1_sel" },
|
||||
{ }, /* clk_hw pointer of "acm_aud_clk0_sel" */
|
||||
{ }, /* clk_hw pointer of "acm_aud_clk1_sel" */
|
||||
};
|
||||
|
||||
static const struct clk_parent_data imx8qm_asrc_mux_clk_sels[] = {
|
||||
@ -176,11 +181,11 @@ static const struct clk_parent_data imx8qxp_mclk_out_sels[] = {
|
||||
{ .fw_name = "sai4_rx_bclk" },
|
||||
};
|
||||
|
||||
static const struct clk_parent_data imx8qxp_mclk_sels[] = {
|
||||
static struct clk_parent_data imx8qxp_mclk_sels[] = {
|
||||
{ .fw_name = "aud_pll_div_clk0_lpcg_clk" },
|
||||
{ .fw_name = "aud_pll_div_clk1_lpcg_clk" },
|
||||
{ .fw_name = "acm_aud_clk0_sel" },
|
||||
{ .fw_name = "acm_aud_clk1_sel" },
|
||||
{ }, /* clk_hw pointer of "acm_aud_clk0_sel" */
|
||||
{ }, /* clk_hw pointer of "acm_aud_clk1_sel" */
|
||||
};
|
||||
|
||||
static struct clk_imx8_acm_sel imx8qxp_sels[] = {
|
||||
@ -228,11 +233,11 @@ static const struct clk_parent_data imx8dxl_mclk_out_sels[] = {
|
||||
{ .index = -1 },
|
||||
};
|
||||
|
||||
static const struct clk_parent_data imx8dxl_mclk_sels[] = {
|
||||
static struct clk_parent_data imx8dxl_mclk_sels[] = {
|
||||
{ .fw_name = "aud_pll_div_clk0_lpcg_clk" },
|
||||
{ .fw_name = "aud_pll_div_clk1_lpcg_clk" },
|
||||
{ .fw_name = "acm_aud_clk0_sel" },
|
||||
{ .fw_name = "acm_aud_clk1_sel" },
|
||||
{ }, /* clk_hw pointer of "acm_aud_clk0_sel" */
|
||||
{ }, /* clk_hw pointer of "acm_aud_clk1_sel" */
|
||||
};
|
||||
|
||||
static struct clk_imx8_acm_sel imx8dxl_sels[] = {
|
||||
@ -375,6 +380,18 @@ static int imx8_acm_clk_probe(struct platform_device *pdev)
|
||||
imx_check_clk_hws(hws, IMX_ADMA_ACM_CLK_END);
|
||||
goto err_clk_register;
|
||||
}
|
||||
|
||||
/*
|
||||
* The IMX_ADMA_ACM_AUD_CLK0_SEL and IMX_ADMA_ACM_AUD_CLK1_SEL are
|
||||
* registered first. After registration, update the clk_hw pointer
|
||||
* to imx8qm/qxp/dxl_mclk_sels structures.
|
||||
*/
|
||||
if (sels[i].clkid == IMX_ADMA_ACM_AUD_CLK0_SEL)
|
||||
priv->soc_data->mclk_sels[ACM_AUD_CLK0_SEL_INDEX].hw =
|
||||
hws[IMX_ADMA_ACM_AUD_CLK0_SEL];
|
||||
if (sels[i].clkid == IMX_ADMA_ACM_AUD_CLK1_SEL)
|
||||
priv->soc_data->mclk_sels[ACM_AUD_CLK1_SEL_INDEX].hw =
|
||||
hws[IMX_ADMA_ACM_AUD_CLK1_SEL];
|
||||
}
|
||||
|
||||
ret = devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get, clk_hw_data);
|
||||
@ -406,16 +423,19 @@ static void imx8_acm_clk_remove(struct platform_device *pdev)
|
||||
static const struct imx8_acm_soc_data imx8qm_acm_data = {
|
||||
.sels = imx8qm_sels,
|
||||
.num_sels = ARRAY_SIZE(imx8qm_sels),
|
||||
.mclk_sels = imx8qm_mclk_sels,
|
||||
};
|
||||
|
||||
static const struct imx8_acm_soc_data imx8qxp_acm_data = {
|
||||
.sels = imx8qxp_sels,
|
||||
.num_sels = ARRAY_SIZE(imx8qxp_sels),
|
||||
.mclk_sels = imx8qxp_mclk_sels,
|
||||
};
|
||||
|
||||
static const struct imx8_acm_soc_data imx8dxl_acm_data = {
|
||||
.sels = imx8dxl_sels,
|
||||
.num_sels = ARRAY_SIZE(imx8dxl_sels),
|
||||
.mclk_sels = imx8dxl_mclk_sels,
|
||||
};
|
||||
|
||||
static const struct of_device_id imx8_acm_match[] = {
|
||||
|
@ -432,7 +432,7 @@ static int imx8mm_clocks_probe(struct platform_device *pdev)
|
||||
/* BUS */
|
||||
hws[IMX8MM_CLK_MAIN_AXI] = imx8m_clk_hw_composite_bus_critical("main_axi", imx8mm_main_axi_sels, base + 0x8800);
|
||||
hws[IMX8MM_CLK_ENET_AXI] = imx8m_clk_hw_composite_bus("enet_axi", imx8mm_enet_axi_sels, base + 0x8880);
|
||||
hws[IMX8MM_CLK_NAND_USDHC_BUS] = imx8m_clk_hw_composite_bus_critical("nand_usdhc_bus", imx8mm_nand_usdhc_sels, base + 0x8900);
|
||||
hws[IMX8MM_CLK_NAND_USDHC_BUS] = imx8m_clk_hw_composite("nand_usdhc_bus", imx8mm_nand_usdhc_sels, base + 0x8900);
|
||||
hws[IMX8MM_CLK_VPU_BUS] = imx8m_clk_hw_composite_bus("vpu_bus", imx8mm_vpu_bus_sels, base + 0x8980);
|
||||
hws[IMX8MM_CLK_DISP_AXI] = imx8m_clk_hw_composite_bus("disp_axi", imx8mm_disp_axi_sels, base + 0x8a00);
|
||||
hws[IMX8MM_CLK_DISP_APB] = imx8m_clk_hw_composite_bus("disp_apb", imx8mm_disp_apb_sels, base + 0x8a80);
|
||||
|
@ -583,6 +583,7 @@ static int imx8mn_clocks_probe(struct platform_device *pdev)
|
||||
hws[IMX8MN_CLK_SDMA2_ROOT] = imx_clk_hw_gate4("sdma2_clk", "ipg_audio_root", base + 0x43b0, 0);
|
||||
hws[IMX8MN_CLK_SDMA3_ROOT] = imx_clk_hw_gate4("sdma3_clk", "ipg_audio_root", base + 0x45f0, 0);
|
||||
hws[IMX8MN_CLK_SAI7_ROOT] = imx_clk_hw_gate2_shared2("sai7_root_clk", "sai7", base + 0x4650, 0, &share_count_sai7);
|
||||
hws[IMX8MN_CLK_SAI7_IPG] = imx_clk_hw_gate2_shared2("sai7_ipg_clk", "ipg_audio_root", base + 0x4650, 0, &share_count_sai7);
|
||||
|
||||
hws[IMX8MN_CLK_GPT_3M] = imx_clk_hw_fixed_factor("gpt_3m", "osc_24m", 1, 8);
|
||||
|
||||
|
@ -5,6 +5,7 @@
|
||||
* Copyright (C) 2022 Marek Vasut <marex@denx.de>
|
||||
*/
|
||||
|
||||
#include <linux/auxiliary_bus.h>
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/io.h>
|
||||
@ -13,6 +14,7 @@
|
||||
#include <linux/of.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
#include <dt-bindings/clock/imx8mp-clock.h>
|
||||
|
||||
@ -154,6 +156,15 @@ static const struct clk_parent_data clk_imx8mp_audiomix_pll_bypass_sels[] = {
|
||||
PDM_SEL, 2, 0 \
|
||||
}
|
||||
|
||||
#define CLK_GATE_PARENT(gname, cname, pname) \
|
||||
{ \
|
||||
gname"_cg", \
|
||||
IMX8MP_CLK_AUDIOMIX_##cname, \
|
||||
{ .fw_name = pname, .name = pname }, NULL, 1, \
|
||||
CLKEN0 + 4 * !!(IMX8MP_CLK_AUDIOMIX_##cname / 32), \
|
||||
1, IMX8MP_CLK_AUDIOMIX_##cname % 32 \
|
||||
}
|
||||
|
||||
struct clk_imx8mp_audiomix_sel {
|
||||
const char *name;
|
||||
int clkid;
|
||||
@ -171,14 +182,14 @@ static struct clk_imx8mp_audiomix_sel sels[] = {
|
||||
CLK_GATE("earc", EARC_IPG),
|
||||
CLK_GATE("ocrama", OCRAMA_IPG),
|
||||
CLK_GATE("aud2htx", AUD2HTX_IPG),
|
||||
CLK_GATE("earc_phy", EARC_PHY),
|
||||
CLK_GATE_PARENT("earc_phy", EARC_PHY, "sai_pll_out_div2"),
|
||||
CLK_GATE("sdma2", SDMA2_ROOT),
|
||||
CLK_GATE("sdma3", SDMA3_ROOT),
|
||||
CLK_GATE("spba2", SPBA2_ROOT),
|
||||
CLK_GATE("dsp", DSP_ROOT),
|
||||
CLK_GATE("dspdbg", DSPDBG_ROOT),
|
||||
CLK_GATE("edma", EDMA_ROOT),
|
||||
CLK_GATE("audpll", AUDPLL_ROOT),
|
||||
CLK_GATE_PARENT("audpll", AUDPLL_ROOT, "osc_24m"),
|
||||
CLK_GATE("mu2", MU2_ROOT),
|
||||
CLK_GATE("mu3", MU3_ROOT),
|
||||
CLK_PDM,
|
||||
@ -217,6 +228,63 @@ struct clk_imx8mp_audiomix_priv {
|
||||
struct clk_hw_onecell_data clk_data;
|
||||
};
|
||||
|
||||
#if IS_ENABLED(CONFIG_RESET_CONTROLLER)
|
||||
|
||||
static void clk_imx8mp_audiomix_reset_unregister_adev(void *_adev)
|
||||
{
|
||||
struct auxiliary_device *adev = _adev;
|
||||
|
||||
auxiliary_device_delete(adev);
|
||||
auxiliary_device_uninit(adev);
|
||||
}
|
||||
|
||||
static void clk_imx8mp_audiomix_reset_adev_release(struct device *dev)
|
||||
{
|
||||
struct auxiliary_device *adev = to_auxiliary_dev(dev);
|
||||
|
||||
kfree(adev);
|
||||
}
|
||||
|
||||
static int clk_imx8mp_audiomix_reset_controller_register(struct device *dev,
|
||||
struct clk_imx8mp_audiomix_priv *priv)
|
||||
{
|
||||
struct auxiliary_device *adev __free(kfree) = NULL;
|
||||
int ret;
|
||||
|
||||
if (!of_property_present(dev->of_node, "#reset-cells"))
|
||||
return 0;
|
||||
|
||||
adev = kzalloc(sizeof(*adev), GFP_KERNEL);
|
||||
if (!adev)
|
||||
return -ENOMEM;
|
||||
|
||||
adev->name = "reset";
|
||||
adev->dev.parent = dev;
|
||||
adev->dev.release = clk_imx8mp_audiomix_reset_adev_release;
|
||||
|
||||
ret = auxiliary_device_init(adev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = auxiliary_device_add(adev);
|
||||
if (ret) {
|
||||
auxiliary_device_uninit(adev);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return devm_add_action_or_reset(dev, clk_imx8mp_audiomix_reset_unregister_adev,
|
||||
no_free_ptr(adev));
|
||||
}
|
||||
|
||||
#else /* !CONFIG_RESET_CONTROLLER */
|
||||
|
||||
static int clk_imx8mp_audiomix_reset_controller_register(struct clk_imx8mp_audiomix_priv *priv)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* !CONFIG_RESET_CONTROLLER */
|
||||
|
||||
static void clk_imx8mp_audiomix_save_restore(struct device *dev, bool save)
|
||||
{
|
||||
struct clk_imx8mp_audiomix_priv *priv = dev_get_drvdata(dev);
|
||||
@ -269,12 +337,12 @@ static int clk_imx8mp_audiomix_probe(struct platform_device *pdev)
|
||||
for (i = 0; i < ARRAY_SIZE(sels); i++) {
|
||||
if (sels[i].num_parents == 1) {
|
||||
hw = devm_clk_hw_register_gate_parent_data(dev,
|
||||
sels[i].name, &sels[i].parent, 0,
|
||||
sels[i].name, &sels[i].parent, CLK_SET_RATE_PARENT,
|
||||
base + sels[i].reg, sels[i].shift, 0, NULL);
|
||||
} else {
|
||||
hw = devm_clk_hw_register_mux_parent_data_table(dev,
|
||||
sels[i].name, sels[i].parents,
|
||||
sels[i].num_parents, 0,
|
||||
sels[i].num_parents, CLK_SET_RATE_PARENT,
|
||||
base + sels[i].reg,
|
||||
sels[i].shift, sels[i].width,
|
||||
0, NULL, NULL);
|
||||
@ -317,7 +385,8 @@ static int clk_imx8mp_audiomix_probe(struct platform_device *pdev)
|
||||
clk_hw_data->hws[IMX8MP_CLK_AUDIOMIX_SAI_PLL_BYPASS] = hw;
|
||||
|
||||
hw = devm_clk_hw_register_gate(dev, "sai_pll_out", "sai_pll_bypass",
|
||||
0, base + SAI_PLL_GNRL_CTL, 13,
|
||||
CLK_SET_RATE_PARENT,
|
||||
base + SAI_PLL_GNRL_CTL, 13,
|
||||
0, NULL);
|
||||
if (IS_ERR(hw)) {
|
||||
ret = PTR_ERR(hw);
|
||||
@ -326,7 +395,8 @@ static int clk_imx8mp_audiomix_probe(struct platform_device *pdev)
|
||||
clk_hw_data->hws[IMX8MP_CLK_AUDIOMIX_SAI_PLL_OUT] = hw;
|
||||
|
||||
hw = devm_clk_hw_register_fixed_factor(dev, "sai_pll_out_div2",
|
||||
"sai_pll_out", 0, 1, 2);
|
||||
"sai_pll_out",
|
||||
CLK_SET_RATE_PARENT, 1, 2);
|
||||
if (IS_ERR(hw)) {
|
||||
ret = PTR_ERR(hw);
|
||||
goto err_clk_register;
|
||||
@ -337,6 +407,10 @@ static int clk_imx8mp_audiomix_probe(struct platform_device *pdev)
|
||||
if (ret)
|
||||
goto err_clk_register;
|
||||
|
||||
ret = clk_imx8mp_audiomix_reset_controller_register(dev, priv);
|
||||
if (ret)
|
||||
goto err_clk_register;
|
||||
|
||||
pm_runtime_put_sync(dev);
|
||||
return 0;
|
||||
|
||||
|
@ -547,12 +547,12 @@ static int imx8mp_clocks_probe(struct platform_device *pdev)
|
||||
hws[IMX8MP_CLK_AHB] = imx8m_clk_hw_composite_bus_critical("ahb_root", imx8mp_ahb_sels, ccm_base + 0x9000);
|
||||
hws[IMX8MP_CLK_AUDIO_AHB] = imx8m_clk_hw_composite_bus("audio_ahb", imx8mp_audio_ahb_sels, ccm_base + 0x9100);
|
||||
hws[IMX8MP_CLK_MIPI_DSI_ESC_RX] = imx8m_clk_hw_composite_bus("mipi_dsi_esc_rx", imx8mp_mipi_dsi_esc_rx_sels, ccm_base + 0x9200);
|
||||
hws[IMX8MP_CLK_MEDIA_DISP2_PIX] = imx8m_clk_hw_composite_bus("media_disp2_pix", imx8mp_media_disp_pix_sels, ccm_base + 0x9300);
|
||||
hws[IMX8MP_CLK_MEDIA_DISP2_PIX] = imx8m_clk_hw_composite_bus_flags("media_disp2_pix", imx8mp_media_disp_pix_sels, ccm_base + 0x9300, CLK_SET_RATE_PARENT);
|
||||
|
||||
hws[IMX8MP_CLK_IPG_ROOT] = imx_clk_hw_divider2("ipg_root", "ahb_root", ccm_base + 0x9080, 0, 1);
|
||||
|
||||
hws[IMX8MP_CLK_DRAM_ALT] = imx8m_clk_hw_composite("dram_alt", imx8mp_dram_alt_sels, ccm_base + 0xa000);
|
||||
hws[IMX8MP_CLK_DRAM_APB] = imx8m_clk_hw_composite_critical("dram_apb", imx8mp_dram_apb_sels, ccm_base + 0xa080);
|
||||
hws[IMX8MP_CLK_DRAM_ALT] = imx8m_clk_hw_fw_managed_composite("dram_alt", imx8mp_dram_alt_sels, ccm_base + 0xa000);
|
||||
hws[IMX8MP_CLK_DRAM_APB] = imx8m_clk_hw_fw_managed_composite_critical("dram_apb", imx8mp_dram_apb_sels, ccm_base + 0xa080);
|
||||
hws[IMX8MP_CLK_VPU_G1] = imx8m_clk_hw_composite("vpu_g1", imx8mp_vpu_g1_sels, ccm_base + 0xa100);
|
||||
hws[IMX8MP_CLK_VPU_G2] = imx8m_clk_hw_composite("vpu_g2", imx8mp_vpu_g2_sels, ccm_base + 0xa180);
|
||||
hws[IMX8MP_CLK_CAN1] = imx8m_clk_hw_composite("can1", imx8mp_can1_sels, ccm_base + 0xa200);
|
||||
@ -609,7 +609,7 @@ static int imx8mp_clocks_probe(struct platform_device *pdev)
|
||||
hws[IMX8MP_CLK_USDHC3] = imx8m_clk_hw_composite("usdhc3", imx8mp_usdhc3_sels, ccm_base + 0xbc80);
|
||||
hws[IMX8MP_CLK_MEDIA_CAM1_PIX] = imx8m_clk_hw_composite("media_cam1_pix", imx8mp_media_cam1_pix_sels, ccm_base + 0xbd00);
|
||||
hws[IMX8MP_CLK_MEDIA_MIPI_PHY1_REF] = imx8m_clk_hw_composite("media_mipi_phy1_ref", imx8mp_media_mipi_phy1_ref_sels, ccm_base + 0xbd80);
|
||||
hws[IMX8MP_CLK_MEDIA_DISP1_PIX] = imx8m_clk_hw_composite("media_disp1_pix", imx8mp_media_disp_pix_sels, ccm_base + 0xbe00);
|
||||
hws[IMX8MP_CLK_MEDIA_DISP1_PIX] = imx8m_clk_hw_composite_bus_flags("media_disp1_pix", imx8mp_media_disp_pix_sels, ccm_base + 0xbe00, CLK_SET_RATE_PARENT);
|
||||
hws[IMX8MP_CLK_MEDIA_CAM2_PIX] = imx8m_clk_hw_composite("media_cam2_pix", imx8mp_media_cam2_pix_sels, ccm_base + 0xbe80);
|
||||
hws[IMX8MP_CLK_MEDIA_LDB] = imx8m_clk_hw_composite("media_ldb", imx8mp_media_ldb_sels, ccm_base + 0xbf00);
|
||||
hws[IMX8MP_CLK_MEMREPAIR] = imx8m_clk_hw_composite_critical("mem_repair", imx8mp_memrepair_sels, ccm_base + 0xbf80);
|
||||
|
@ -71,7 +71,7 @@ static const char *const lvds0_sels[] = {
|
||||
"clk_dummy",
|
||||
"clk_dummy",
|
||||
"clk_dummy",
|
||||
"mipi0_lvds_bypass_clk",
|
||||
"lvds0_bypass_clk",
|
||||
};
|
||||
|
||||
static const char *const lvds1_sels[] = {
|
||||
@ -79,7 +79,7 @@ static const char *const lvds1_sels[] = {
|
||||
"clk_dummy",
|
||||
"clk_dummy",
|
||||
"clk_dummy",
|
||||
"mipi1_lvds_bypass_clk",
|
||||
"lvds1_bypass_clk",
|
||||
};
|
||||
|
||||
static const char * const mipi_sels[] = {
|
||||
@ -90,6 +90,22 @@ static const char * const mipi_sels[] = {
|
||||
"clk_dummy",
|
||||
};
|
||||
|
||||
static const char * const mipi0_phy_sels[] = {
|
||||
"clk_dummy",
|
||||
"clk_dummy",
|
||||
"mipi_pll_div2_clk",
|
||||
"clk_dummy",
|
||||
"mipi0_bypass_clk",
|
||||
};
|
||||
|
||||
static const char * const mipi1_phy_sels[] = {
|
||||
"clk_dummy",
|
||||
"clk_dummy",
|
||||
"mipi_pll_div2_clk",
|
||||
"clk_dummy",
|
||||
"mipi1_bypass_clk",
|
||||
};
|
||||
|
||||
static const char * const lcd_sels[] = {
|
||||
"clk_dummy",
|
||||
"clk_dummy",
|
||||
@ -170,8 +186,8 @@ static int imx8qxp_clk_probe(struct platform_device *pdev)
|
||||
imx_clk_scu("pwm_clk", IMX_SC_R_LCD_0_PWM_0, IMX_SC_PM_CLK_PER);
|
||||
imx_clk_scu("elcdif_pll", IMX_SC_R_ELCDIF_PLL, IMX_SC_PM_CLK_PLL);
|
||||
imx_clk_scu2("lcd_clk", lcd_sels, ARRAY_SIZE(lcd_sels), IMX_SC_R_LCD_0, IMX_SC_PM_CLK_PER);
|
||||
imx_clk_scu2("lcd_pxl_clk", lcd_pxl_sels, ARRAY_SIZE(lcd_pxl_sels), IMX_SC_R_LCD_0, IMX_SC_PM_CLK_MISC0);
|
||||
imx_clk_scu("lcd_pxl_bypass_div_clk", IMX_SC_R_LCD_0, IMX_SC_PM_CLK_BYPASS);
|
||||
imx_clk_scu2("lcd_pxl_clk", lcd_pxl_sels, ARRAY_SIZE(lcd_pxl_sels), IMX_SC_R_LCD_0, IMX_SC_PM_CLK_MISC0);
|
||||
|
||||
/* Audio SS */
|
||||
imx_clk_scu("audio_pll0_clk", IMX_SC_R_AUDIO_PLL_0, IMX_SC_PM_CLK_PLL);
|
||||
@ -206,42 +222,41 @@ static int imx8qxp_clk_probe(struct platform_device *pdev)
|
||||
imx_clk_scu("usb3_lpm_div", IMX_SC_R_USB_2, IMX_SC_PM_CLK_MISC);
|
||||
|
||||
/* Display controller SS */
|
||||
imx_clk_scu2("dc0_disp0_clk", dc0_sels, ARRAY_SIZE(dc0_sels), IMX_SC_R_DC_0, IMX_SC_PM_CLK_MISC0);
|
||||
imx_clk_scu2("dc0_disp1_clk", dc0_sels, ARRAY_SIZE(dc0_sels), IMX_SC_R_DC_0, IMX_SC_PM_CLK_MISC1);
|
||||
imx_clk_scu("dc0_pll0_clk", IMX_SC_R_DC_0_PLL_0, IMX_SC_PM_CLK_PLL);
|
||||
imx_clk_scu("dc0_pll1_clk", IMX_SC_R_DC_0_PLL_1, IMX_SC_PM_CLK_PLL);
|
||||
imx_clk_scu("dc0_bypass0_clk", IMX_SC_R_DC_0_VIDEO0, IMX_SC_PM_CLK_BYPASS);
|
||||
imx_clk_scu2("dc0_disp0_clk", dc0_sels, ARRAY_SIZE(dc0_sels), IMX_SC_R_DC_0, IMX_SC_PM_CLK_MISC0);
|
||||
imx_clk_scu2("dc0_disp1_clk", dc0_sels, ARRAY_SIZE(dc0_sels), IMX_SC_R_DC_0, IMX_SC_PM_CLK_MISC1);
|
||||
imx_clk_scu("dc0_bypass1_clk", IMX_SC_R_DC_0_VIDEO1, IMX_SC_PM_CLK_BYPASS);
|
||||
|
||||
imx_clk_scu2("dc1_disp0_clk", dc1_sels, ARRAY_SIZE(dc1_sels), IMX_SC_R_DC_1, IMX_SC_PM_CLK_MISC0);
|
||||
imx_clk_scu2("dc1_disp1_clk", dc1_sels, ARRAY_SIZE(dc1_sels), IMX_SC_R_DC_1, IMX_SC_PM_CLK_MISC1);
|
||||
imx_clk_scu("dc1_pll0_clk", IMX_SC_R_DC_1_PLL_0, IMX_SC_PM_CLK_PLL);
|
||||
imx_clk_scu("dc1_pll1_clk", IMX_SC_R_DC_1_PLL_1, IMX_SC_PM_CLK_PLL);
|
||||
imx_clk_scu("dc1_bypass0_clk", IMX_SC_R_DC_1_VIDEO0, IMX_SC_PM_CLK_BYPASS);
|
||||
imx_clk_scu2("dc1_disp0_clk", dc1_sels, ARRAY_SIZE(dc1_sels), IMX_SC_R_DC_1, IMX_SC_PM_CLK_MISC0);
|
||||
imx_clk_scu2("dc1_disp1_clk", dc1_sels, ARRAY_SIZE(dc1_sels), IMX_SC_R_DC_1, IMX_SC_PM_CLK_MISC1);
|
||||
imx_clk_scu("dc1_bypass1_clk", IMX_SC_R_DC_1_VIDEO1, IMX_SC_PM_CLK_BYPASS);
|
||||
|
||||
/* MIPI-LVDS SS */
|
||||
imx_clk_scu("mipi0_bypass_clk", IMX_SC_R_MIPI_0, IMX_SC_PM_CLK_BYPASS);
|
||||
imx_clk_scu("mipi0_pixel_clk", IMX_SC_R_MIPI_0, IMX_SC_PM_CLK_PER);
|
||||
imx_clk_scu("mipi0_lvds_bypass_clk", IMX_SC_R_LVDS_0, IMX_SC_PM_CLK_BYPASS);
|
||||
imx_clk_scu2("mipi0_lvds_pixel_clk", lvds0_sels, ARRAY_SIZE(lvds0_sels), IMX_SC_R_LVDS_0, IMX_SC_PM_CLK_MISC2);
|
||||
imx_clk_scu2("mipi0_lvds_phy_clk", lvds0_sels, ARRAY_SIZE(lvds0_sels), IMX_SC_R_LVDS_0, IMX_SC_PM_CLK_MISC3);
|
||||
imx_clk_scu2("mipi0_pixel_clk", mipi0_phy_sels, ARRAY_SIZE(mipi0_phy_sels), IMX_SC_R_MIPI_0, IMX_SC_PM_CLK_PER);
|
||||
imx_clk_scu("lvds0_bypass_clk", IMX_SC_R_LVDS_0, IMX_SC_PM_CLK_BYPASS);
|
||||
imx_clk_scu2("lvds0_pixel_clk", lvds0_sels, ARRAY_SIZE(lvds0_sels), IMX_SC_R_LVDS_0, IMX_SC_PM_CLK_MISC2);
|
||||
imx_clk_scu2("lvds0_phy_clk", lvds0_sels, ARRAY_SIZE(lvds0_sels), IMX_SC_R_LVDS_0, IMX_SC_PM_CLK_MISC3);
|
||||
imx_clk_scu2("mipi0_dsi_tx_esc_clk", mipi_sels, ARRAY_SIZE(mipi_sels), IMX_SC_R_MIPI_0, IMX_SC_PM_CLK_MST_BUS);
|
||||
imx_clk_scu2("mipi0_dsi_rx_esc_clk", mipi_sels, ARRAY_SIZE(mipi_sels), IMX_SC_R_MIPI_0, IMX_SC_PM_CLK_SLV_BUS);
|
||||
imx_clk_scu2("mipi0_dsi_phy_clk", mipi_sels, ARRAY_SIZE(mipi_sels), IMX_SC_R_MIPI_0, IMX_SC_PM_CLK_PHY);
|
||||
imx_clk_scu2("mipi0_dsi_phy_clk", mipi0_phy_sels, ARRAY_SIZE(mipi0_phy_sels), IMX_SC_R_MIPI_0, IMX_SC_PM_CLK_PHY);
|
||||
imx_clk_scu("mipi0_i2c0_clk", IMX_SC_R_MIPI_0_I2C_0, IMX_SC_PM_CLK_MISC2);
|
||||
imx_clk_scu("mipi0_i2c1_clk", IMX_SC_R_MIPI_0_I2C_1, IMX_SC_PM_CLK_MISC2);
|
||||
imx_clk_scu("mipi0_pwm0_clk", IMX_SC_R_MIPI_0_PWM_0, IMX_SC_PM_CLK_PER);
|
||||
|
||||
imx_clk_scu("mipi1_bypass_clk", IMX_SC_R_MIPI_1, IMX_SC_PM_CLK_BYPASS);
|
||||
imx_clk_scu("mipi1_pixel_clk", IMX_SC_R_MIPI_1, IMX_SC_PM_CLK_PER);
|
||||
imx_clk_scu("mipi1_lvds_bypass_clk", IMX_SC_R_LVDS_1, IMX_SC_PM_CLK_BYPASS);
|
||||
imx_clk_scu2("mipi1_lvds_pixel_clk", lvds1_sels, ARRAY_SIZE(lvds1_sels), IMX_SC_R_LVDS_1, IMX_SC_PM_CLK_MISC2);
|
||||
imx_clk_scu2("mipi1_lvds_phy_clk", lvds1_sels, ARRAY_SIZE(lvds1_sels), IMX_SC_R_LVDS_1, IMX_SC_PM_CLK_MISC3);
|
||||
|
||||
imx_clk_scu2("mipi1_pixel_clk", mipi1_phy_sels, ARRAY_SIZE(mipi1_phy_sels), IMX_SC_R_MIPI_1, IMX_SC_PM_CLK_PER);
|
||||
imx_clk_scu("lvds1_bypass_clk", IMX_SC_R_LVDS_1, IMX_SC_PM_CLK_BYPASS);
|
||||
imx_clk_scu2("lvds1_pixel_clk", lvds1_sels, ARRAY_SIZE(lvds1_sels), IMX_SC_R_LVDS_1, IMX_SC_PM_CLK_MISC2);
|
||||
imx_clk_scu2("lvds1_phy_clk", lvds1_sels, ARRAY_SIZE(lvds1_sels), IMX_SC_R_LVDS_1, IMX_SC_PM_CLK_MISC3);
|
||||
imx_clk_scu2("mipi1_dsi_tx_esc_clk", mipi_sels, ARRAY_SIZE(mipi_sels), IMX_SC_R_MIPI_1, IMX_SC_PM_CLK_MST_BUS);
|
||||
imx_clk_scu2("mipi1_dsi_rx_esc_clk", mipi_sels, ARRAY_SIZE(mipi_sels), IMX_SC_R_MIPI_1, IMX_SC_PM_CLK_SLV_BUS);
|
||||
imx_clk_scu2("mipi1_dsi_phy_clk", mipi_sels, ARRAY_SIZE(mipi_sels), IMX_SC_R_MIPI_1, IMX_SC_PM_CLK_PHY);
|
||||
imx_clk_scu2("mipi1_dsi_phy_clk", mipi1_phy_sels, ARRAY_SIZE(mipi1_phy_sels), IMX_SC_R_MIPI_1, IMX_SC_PM_CLK_PHY);
|
||||
imx_clk_scu("mipi1_i2c0_clk", IMX_SC_R_MIPI_1_I2C_0, IMX_SC_PM_CLK_MISC2);
|
||||
imx_clk_scu("mipi1_i2c1_clk", IMX_SC_R_MIPI_1_I2C_1, IMX_SC_PM_CLK_MISC2);
|
||||
imx_clk_scu("mipi1_pwm0_clk", IMX_SC_R_MIPI_1_PWM_0, IMX_SC_PM_CLK_PER);
|
||||
|
@ -248,6 +248,35 @@ static const struct imx95_blk_ctl_dev_data dispmix_csr_dev_data = {
|
||||
.clk_reg_offset = 0,
|
||||
};
|
||||
|
||||
static const struct imx95_blk_ctl_clk_dev_data netxmix_clk_dev_data[] = {
|
||||
[IMX95_CLK_NETCMIX_ENETC0_RMII] = {
|
||||
.name = "enetc0_rmii_sel",
|
||||
.parent_names = (const char *[]){"ext_enetref", "enetref"},
|
||||
.num_parents = 2,
|
||||
.reg = 4,
|
||||
.bit_idx = 5,
|
||||
.bit_width = 1,
|
||||
.type = CLK_MUX,
|
||||
.flags = CLK_SET_RATE_NO_REPARENT | CLK_SET_RATE_PARENT,
|
||||
},
|
||||
[IMX95_CLK_NETCMIX_ENETC1_RMII] = {
|
||||
.name = "enetc1_rmii_sel",
|
||||
.parent_names = (const char *[]){"ext_enetref", "enetref"},
|
||||
.num_parents = 2,
|
||||
.reg = 4,
|
||||
.bit_idx = 10,
|
||||
.bit_width = 1,
|
||||
.type = CLK_MUX,
|
||||
.flags = CLK_SET_RATE_NO_REPARENT | CLK_SET_RATE_PARENT,
|
||||
},
|
||||
};
|
||||
|
||||
static const struct imx95_blk_ctl_dev_data netcmix_dev_data = {
|
||||
.num_clks = ARRAY_SIZE(netxmix_clk_dev_data),
|
||||
.clk_dev_data = netxmix_clk_dev_data,
|
||||
.clk_reg_offset = 0,
|
||||
};
|
||||
|
||||
static int imx95_bc_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct device *dev = &pdev->dev;
|
||||
@ -419,6 +448,7 @@ static const struct of_device_id imx95_bc_of_match[] = {
|
||||
{ .compatible = "nxp,imx95-lvds-csr", .data = &lvds_csr_dev_data },
|
||||
{ .compatible = "nxp,imx95-display-csr", .data = &dispmix_csr_dev_data },
|
||||
{ .compatible = "nxp,imx95-vpu-csr", .data = &vpublk_dev_data },
|
||||
{ .compatible = "nxp,imx95-netcmix-blk-ctrl", .data = &netcmix_dev_data},
|
||||
{ /* Sentinel */ },
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, imx95_bc_of_match);
|
||||
|
@ -176,6 +176,7 @@ static struct platform_driver imxrt1050_clk_driver = {
|
||||
};
|
||||
module_platform_driver(imxrt1050_clk_driver);
|
||||
|
||||
MODULE_DESCRIPTION("NXP i.MX RT1050 clock driver");
|
||||
MODULE_LICENSE("Dual BSD/GPL");
|
||||
MODULE_AUTHOR("Jesse Taube <Mr.Bossman075@gmail.com>");
|
||||
MODULE_AUTHOR("Giulio Benetti <giulio.benetti@benettiengineering.com>");
|
||||
|
@ -226,4 +226,5 @@ static int __init imx_clk_disable_uart(void)
|
||||
late_initcall_sync(imx_clk_disable_uart);
|
||||
#endif
|
||||
|
||||
MODULE_DESCRIPTION("Common clock support for NXP i.MX SoC family");
|
||||
MODULE_LICENSE("GPL v2");
|
||||
|
@ -442,6 +442,10 @@ struct clk_hw *__imx8m_clk_hw_composite(const char *name,
|
||||
_imx8m_clk_hw_composite(name, parent_names, reg, \
|
||||
IMX_COMPOSITE_BUS, IMX_COMPOSITE_CLK_FLAGS_DEFAULT)
|
||||
|
||||
#define imx8m_clk_hw_composite_bus_flags(name, parent_names, reg, flags) \
|
||||
_imx8m_clk_hw_composite(name, parent_names, reg, \
|
||||
IMX_COMPOSITE_BUS, IMX_COMPOSITE_CLK_FLAGS_DEFAULT | flags)
|
||||
|
||||
#define imx8m_clk_hw_composite_bus_critical(name, parent_names, reg) \
|
||||
_imx8m_clk_hw_composite(name, parent_names, reg, \
|
||||
IMX_COMPOSITE_BUS, IMX_COMPOSITE_CLK_FLAGS_CRITICAL)
|
||||
|
@ -2183,7 +2183,7 @@ static struct clk_regmap *const a1_periphs_regmaps[] = {
|
||||
&dmc_sel2,
|
||||
};
|
||||
|
||||
static struct regmap_config a1_periphs_regmap_cfg = {
|
||||
static const struct regmap_config a1_periphs_regmap_cfg = {
|
||||
.reg_bits = 32,
|
||||
.val_bits = 32,
|
||||
.reg_stride = 4,
|
||||
@ -2246,3 +2246,4 @@ MODULE_DESCRIPTION("Amlogic A1 Peripherals Clock Controller driver");
|
||||
MODULE_AUTHOR("Jian Hu <jian.hu@amlogic.com>");
|
||||
MODULE_AUTHOR("Dmitry Rokosov <ddrokosov@sberdevices.ru>");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_IMPORT_NS(CLK_MESON);
|
||||
|
@ -295,7 +295,7 @@ static struct clk_regmap *const a1_pll_regmaps[] = {
|
||||
&hifi_pll,
|
||||
};
|
||||
|
||||
static struct regmap_config a1_pll_regmap_cfg = {
|
||||
static const struct regmap_config a1_pll_regmap_cfg = {
|
||||
.reg_bits = 32,
|
||||
.val_bits = 32,
|
||||
.reg_stride = 4,
|
||||
@ -360,3 +360,4 @@ MODULE_DESCRIPTION("Amlogic S4 PLL Clock Controller driver");
|
||||
MODULE_AUTHOR("Jian Hu <jian.hu@amlogic.com>");
|
||||
MODULE_AUTHOR("Dmitry Rokosov <ddrokosov@sberdevices.ru>");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_IMPORT_NS(CLK_MESON);
|
||||
|
@ -342,3 +342,4 @@ module_platform_driver(axg_aoclkc_driver);
|
||||
|
||||
MODULE_DESCRIPTION("Amlogic AXG Always-ON Clock Controller driver");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_IMPORT_NS(CLK_MESON);
|
||||
|
@ -753,6 +753,9 @@ static struct clk_regmap toddr_d =
|
||||
AUD_PCLK_GATE(toddr_d, AUDIO_CLK_GATE_EN1, 1);
|
||||
static struct clk_regmap loopback_b =
|
||||
AUD_PCLK_GATE(loopback_b, AUDIO_CLK_GATE_EN1, 2);
|
||||
static struct clk_regmap earcrx =
|
||||
AUD_PCLK_GATE(earcrx, AUDIO_CLK_GATE_EN1, 6);
|
||||
|
||||
|
||||
static struct clk_regmap sm1_mst_a_mclk_sel =
|
||||
AUD_MST_MCLK_MUX(mst_a_mclk, AUDIO_SM1_MCLK_A_CTRL);
|
||||
@ -766,6 +769,10 @@ static struct clk_regmap sm1_mst_e_mclk_sel =
|
||||
AUD_MST_MCLK_MUX(mst_e_mclk, AUDIO_SM1_MCLK_E_CTRL);
|
||||
static struct clk_regmap sm1_mst_f_mclk_sel =
|
||||
AUD_MST_MCLK_MUX(mst_f_mclk, AUDIO_SM1_MCLK_F_CTRL);
|
||||
static struct clk_regmap sm1_earcrx_cmdc_clk_sel =
|
||||
AUD_MST_MCLK_MUX(earcrx_cmdc_clk, AUDIO_EARCRX_CMDC_CLK_CTRL);
|
||||
static struct clk_regmap sm1_earcrx_dmac_clk_sel =
|
||||
AUD_MST_MCLK_MUX(earcrx_dmac_clk, AUDIO_EARCRX_DMAC_CLK_CTRL);
|
||||
|
||||
static struct clk_regmap sm1_mst_a_mclk_div =
|
||||
AUD_MST_MCLK_DIV(mst_a_mclk, AUDIO_SM1_MCLK_A_CTRL);
|
||||
@ -779,6 +786,11 @@ static struct clk_regmap sm1_mst_e_mclk_div =
|
||||
AUD_MST_MCLK_DIV(mst_e_mclk, AUDIO_SM1_MCLK_E_CTRL);
|
||||
static struct clk_regmap sm1_mst_f_mclk_div =
|
||||
AUD_MST_MCLK_DIV(mst_f_mclk, AUDIO_SM1_MCLK_F_CTRL);
|
||||
static struct clk_regmap sm1_earcrx_cmdc_clk_div =
|
||||
AUD_MST_MCLK_DIV(earcrx_cmdc_clk, AUDIO_EARCRX_CMDC_CLK_CTRL);
|
||||
static struct clk_regmap sm1_earcrx_dmac_clk_div =
|
||||
AUD_MST_MCLK_DIV(earcrx_dmac_clk, AUDIO_EARCRX_DMAC_CLK_CTRL);
|
||||
|
||||
|
||||
static struct clk_regmap sm1_mst_a_mclk =
|
||||
AUD_MST_MCLK_GATE(mst_a_mclk, AUDIO_SM1_MCLK_A_CTRL);
|
||||
@ -792,6 +804,10 @@ static struct clk_regmap sm1_mst_e_mclk =
|
||||
AUD_MST_MCLK_GATE(mst_e_mclk, AUDIO_SM1_MCLK_E_CTRL);
|
||||
static struct clk_regmap sm1_mst_f_mclk =
|
||||
AUD_MST_MCLK_GATE(mst_f_mclk, AUDIO_SM1_MCLK_F_CTRL);
|
||||
static struct clk_regmap sm1_earcrx_cmdc_clk =
|
||||
AUD_MST_MCLK_GATE(earcrx_cmdc_clk, AUDIO_EARCRX_CMDC_CLK_CTRL);
|
||||
static struct clk_regmap sm1_earcrx_dmac_clk =
|
||||
AUD_MST_MCLK_GATE(earcrx_dmac_clk, AUDIO_EARCRX_DMAC_CLK_CTRL);
|
||||
|
||||
static struct clk_regmap sm1_tdm_mclk_pad_0 = AUD_TDM_PAD_CTRL(
|
||||
tdm_mclk_pad_0, AUDIO_SM1_MST_PAD_CTRL0, 0, mclk_pad_ctrl_parent_data);
|
||||
@ -1232,6 +1248,13 @@ static struct clk_hw *sm1_audio_hw_clks[] = {
|
||||
[AUD_CLKID_SYSCLK_A_EN] = &sm1_sysclk_a_en.hw,
|
||||
[AUD_CLKID_SYSCLK_B_DIV] = &sm1_sysclk_b_div.hw,
|
||||
[AUD_CLKID_SYSCLK_B_EN] = &sm1_sysclk_b_en.hw,
|
||||
[AUD_CLKID_EARCRX] = &earcrx.hw,
|
||||
[AUD_CLKID_EARCRX_CMDC_SEL] = &sm1_earcrx_cmdc_clk_sel.hw,
|
||||
[AUD_CLKID_EARCRX_CMDC_DIV] = &sm1_earcrx_cmdc_clk_div.hw,
|
||||
[AUD_CLKID_EARCRX_CMDC] = &sm1_earcrx_cmdc_clk.hw,
|
||||
[AUD_CLKID_EARCRX_DMAC_SEL] = &sm1_earcrx_dmac_clk_sel.hw,
|
||||
[AUD_CLKID_EARCRX_DMAC_DIV] = &sm1_earcrx_dmac_clk_div.hw,
|
||||
[AUD_CLKID_EARCRX_DMAC] = &sm1_earcrx_dmac_clk.hw,
|
||||
};
|
||||
|
||||
|
||||
@ -1646,6 +1669,13 @@ static struct clk_regmap *const sm1_clk_regmaps[] = {
|
||||
&sm1_sysclk_a_en,
|
||||
&sm1_sysclk_b_div,
|
||||
&sm1_sysclk_b_en,
|
||||
&earcrx,
|
||||
&sm1_earcrx_cmdc_clk_sel,
|
||||
&sm1_earcrx_cmdc_clk_div,
|
||||
&sm1_earcrx_cmdc_clk,
|
||||
&sm1_earcrx_dmac_clk_sel,
|
||||
&sm1_earcrx_dmac_clk_div,
|
||||
&sm1_earcrx_dmac_clk,
|
||||
};
|
||||
|
||||
struct axg_audio_reset_data {
|
||||
@ -1726,11 +1756,10 @@ static const struct reset_control_ops axg_audio_rstc_ops = {
|
||||
.status = axg_audio_reset_status,
|
||||
};
|
||||
|
||||
static const struct regmap_config axg_audio_regmap_cfg = {
|
||||
static struct regmap_config axg_audio_regmap_cfg = {
|
||||
.reg_bits = 32,
|
||||
.val_bits = 32,
|
||||
.reg_stride = 4,
|
||||
.max_register = AUDIO_CLK_SPDIFOUT_B_CTRL,
|
||||
};
|
||||
|
||||
struct audioclk_data {
|
||||
@ -1739,6 +1768,7 @@ struct audioclk_data {
|
||||
struct meson_clk_hw_data hw_clks;
|
||||
unsigned int reset_offset;
|
||||
unsigned int reset_num;
|
||||
unsigned int max_register;
|
||||
};
|
||||
|
||||
static int axg_audio_clkc_probe(struct platform_device *pdev)
|
||||
@ -1760,6 +1790,7 @@ static int axg_audio_clkc_probe(struct platform_device *pdev)
|
||||
if (IS_ERR(regs))
|
||||
return PTR_ERR(regs);
|
||||
|
||||
axg_audio_regmap_cfg.max_register = data->max_register;
|
||||
map = devm_regmap_init_mmio(dev, regs, &axg_audio_regmap_cfg);
|
||||
if (IS_ERR(map)) {
|
||||
dev_err(dev, "failed to init regmap: %ld\n", PTR_ERR(map));
|
||||
@ -1828,6 +1859,7 @@ static const struct audioclk_data axg_audioclk_data = {
|
||||
.hws = axg_audio_hw_clks,
|
||||
.num = ARRAY_SIZE(axg_audio_hw_clks),
|
||||
},
|
||||
.max_register = AUDIO_CLK_PDMIN_CTRL1,
|
||||
};
|
||||
|
||||
static const struct audioclk_data g12a_audioclk_data = {
|
||||
@ -1839,6 +1871,7 @@ static const struct audioclk_data g12a_audioclk_data = {
|
||||
},
|
||||
.reset_offset = AUDIO_SW_RESET,
|
||||
.reset_num = 26,
|
||||
.max_register = AUDIO_CLK_SPDIFOUT_B_CTRL,
|
||||
};
|
||||
|
||||
static const struct audioclk_data sm1_audioclk_data = {
|
||||
@ -1850,6 +1883,7 @@ static const struct audioclk_data sm1_audioclk_data = {
|
||||
},
|
||||
.reset_offset = AUDIO_SM1_SW_RESET0,
|
||||
.reset_num = 39,
|
||||
.max_register = AUDIO_EARCRX_DMAC_CLK_CTRL,
|
||||
};
|
||||
|
||||
static const struct of_device_id clkc_match_table[] = {
|
||||
@ -1878,3 +1912,4 @@ module_platform_driver(axg_audio_driver);
|
||||
MODULE_DESCRIPTION("Amlogic AXG/G12A/SM1 Audio Clock driver");
|
||||
MODULE_AUTHOR("Jerome Brunet <jbrunet@baylibre.com>");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_IMPORT_NS(CLK_MESON);
|
||||
|
@ -64,5 +64,7 @@
|
||||
#define AUDIO_SM1_SW_RESET1 0x02C
|
||||
#define AUDIO_CLK81_CTRL 0x030
|
||||
#define AUDIO_CLK81_EN 0x034
|
||||
#define AUDIO_EARCRX_CMDC_CLK_CTRL 0x0D0
|
||||
#define AUDIO_EARCRX_DMAC_CLK_CTRL 0x0D4
|
||||
|
||||
#endif /*__AXG_AUDIO_CLKC_H */
|
||||
|
@ -2187,3 +2187,4 @@ module_platform_driver(axg_driver);
|
||||
|
||||
MODULE_DESCRIPTION("Amlogic AXG Main Clock Controller driver");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_IMPORT_NS(CLK_MESON);
|
||||
|
@ -2296,7 +2296,7 @@ static struct clk_regmap *const c3_periphs_clk_regmaps[] = {
|
||||
&vapb,
|
||||
};
|
||||
|
||||
static struct regmap_config clkc_regmap_config = {
|
||||
static const struct regmap_config clkc_regmap_config = {
|
||||
.reg_bits = 32,
|
||||
.val_bits = 32,
|
||||
.reg_stride = 4,
|
||||
@ -2364,3 +2364,4 @@ module_platform_driver(c3_peripherals_driver);
|
||||
MODULE_DESCRIPTION("Amlogic C3 Peripherals Clock Controller driver");
|
||||
MODULE_AUTHOR("Chuan Liu <chuan.liu@amlogic.com>");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_IMPORT_NS(CLK_MESON);
|
||||
|
@ -678,7 +678,7 @@ static struct clk_regmap *const c3_pll_clk_regmaps[] = {
|
||||
&mclk1,
|
||||
};
|
||||
|
||||
static struct regmap_config clkc_regmap_config = {
|
||||
static const struct regmap_config clkc_regmap_config = {
|
||||
.reg_bits = 32,
|
||||
.val_bits = 32,
|
||||
.reg_stride = 4,
|
||||
@ -745,3 +745,4 @@ module_platform_driver(c3_pll_driver);
|
||||
MODULE_DESCRIPTION("Amlogic C3 PLL Clock Controller driver");
|
||||
MODULE_AUTHOR("Chuan Liu <chuan.liu@amlogic.com>");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_IMPORT_NS(CLK_MESON);
|
||||
|
@ -65,8 +65,9 @@ const struct clk_ops meson_clk_cpu_dyndiv_ops = {
|
||||
.determine_rate = meson_clk_cpu_dyndiv_determine_rate,
|
||||
.set_rate = meson_clk_cpu_dyndiv_set_rate,
|
||||
};
|
||||
EXPORT_SYMBOL_GPL(meson_clk_cpu_dyndiv_ops);
|
||||
EXPORT_SYMBOL_NS_GPL(meson_clk_cpu_dyndiv_ops, CLK_MESON);
|
||||
|
||||
MODULE_DESCRIPTION("Amlogic CPU Dynamic Clock divider");
|
||||
MODULE_AUTHOR("Neil Armstrong <narmstrong@baylibre.com>");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_IMPORT_NS(CLK_MESON);
|
||||
|
@ -130,14 +130,15 @@ const struct clk_ops meson_clk_dualdiv_ops = {
|
||||
.determine_rate = meson_clk_dualdiv_determine_rate,
|
||||
.set_rate = meson_clk_dualdiv_set_rate,
|
||||
};
|
||||
EXPORT_SYMBOL_GPL(meson_clk_dualdiv_ops);
|
||||
EXPORT_SYMBOL_NS_GPL(meson_clk_dualdiv_ops, CLK_MESON);
|
||||
|
||||
const struct clk_ops meson_clk_dualdiv_ro_ops = {
|
||||
.recalc_rate = meson_clk_dualdiv_recalc_rate,
|
||||
};
|
||||
EXPORT_SYMBOL_GPL(meson_clk_dualdiv_ro_ops);
|
||||
EXPORT_SYMBOL_NS_GPL(meson_clk_dualdiv_ro_ops, CLK_MESON);
|
||||
|
||||
MODULE_DESCRIPTION("Amlogic dual divider driver");
|
||||
MODULE_AUTHOR("Neil Armstrong <narmstrong@baylibre.com>");
|
||||
MODULE_AUTHOR("Jerome Brunet <jbrunet@baylibre.com>");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_IMPORT_NS(CLK_MESON);
|
||||
|
@ -165,7 +165,7 @@ const struct clk_ops meson_clk_mpll_ro_ops = {
|
||||
.recalc_rate = mpll_recalc_rate,
|
||||
.determine_rate = mpll_determine_rate,
|
||||
};
|
||||
EXPORT_SYMBOL_GPL(meson_clk_mpll_ro_ops);
|
||||
EXPORT_SYMBOL_NS_GPL(meson_clk_mpll_ro_ops, CLK_MESON);
|
||||
|
||||
const struct clk_ops meson_clk_mpll_ops = {
|
||||
.recalc_rate = mpll_recalc_rate,
|
||||
@ -173,8 +173,9 @@ const struct clk_ops meson_clk_mpll_ops = {
|
||||
.set_rate = mpll_set_rate,
|
||||
.init = mpll_init,
|
||||
};
|
||||
EXPORT_SYMBOL_GPL(meson_clk_mpll_ops);
|
||||
EXPORT_SYMBOL_NS_GPL(meson_clk_mpll_ops, CLK_MESON);
|
||||
|
||||
MODULE_DESCRIPTION("Amlogic MPLL driver");
|
||||
MODULE_AUTHOR("Michael Turquette <mturquette@baylibre.com>");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_IMPORT_NS(CLK_MESON);
|
||||
|
@ -61,7 +61,7 @@ const struct clk_ops meson_clk_phase_ops = {
|
||||
.get_phase = meson_clk_phase_get_phase,
|
||||
.set_phase = meson_clk_phase_set_phase,
|
||||
};
|
||||
EXPORT_SYMBOL_GPL(meson_clk_phase_ops);
|
||||
EXPORT_SYMBOL_NS_GPL(meson_clk_phase_ops, CLK_MESON);
|
||||
|
||||
/*
|
||||
* This is a special clock for the audio controller.
|
||||
@ -123,7 +123,7 @@ const struct clk_ops meson_clk_triphase_ops = {
|
||||
.get_phase = meson_clk_triphase_get_phase,
|
||||
.set_phase = meson_clk_triphase_set_phase,
|
||||
};
|
||||
EXPORT_SYMBOL_GPL(meson_clk_triphase_ops);
|
||||
EXPORT_SYMBOL_NS_GPL(meson_clk_triphase_ops, CLK_MESON);
|
||||
|
||||
/*
|
||||
* This is a special clock for the audio controller.
|
||||
@ -178,9 +178,9 @@ const struct clk_ops meson_sclk_ws_inv_ops = {
|
||||
.get_phase = meson_sclk_ws_inv_get_phase,
|
||||
.set_phase = meson_sclk_ws_inv_set_phase,
|
||||
};
|
||||
EXPORT_SYMBOL_GPL(meson_sclk_ws_inv_ops);
|
||||
|
||||
EXPORT_SYMBOL_NS_GPL(meson_sclk_ws_inv_ops, CLK_MESON);
|
||||
|
||||
MODULE_DESCRIPTION("Amlogic phase driver");
|
||||
MODULE_AUTHOR("Jerome Brunet <jbrunet@baylibre.com>");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_IMPORT_NS(CLK_MESON);
|
||||
|
@ -472,7 +472,7 @@ const struct clk_ops meson_clk_pcie_pll_ops = {
|
||||
.enable = meson_clk_pcie_pll_enable,
|
||||
.disable = meson_clk_pll_disable
|
||||
};
|
||||
EXPORT_SYMBOL_GPL(meson_clk_pcie_pll_ops);
|
||||
EXPORT_SYMBOL_NS_GPL(meson_clk_pcie_pll_ops, CLK_MESON);
|
||||
|
||||
const struct clk_ops meson_clk_pll_ops = {
|
||||
.init = meson_clk_pll_init,
|
||||
@ -483,15 +483,16 @@ const struct clk_ops meson_clk_pll_ops = {
|
||||
.enable = meson_clk_pll_enable,
|
||||
.disable = meson_clk_pll_disable
|
||||
};
|
||||
EXPORT_SYMBOL_GPL(meson_clk_pll_ops);
|
||||
EXPORT_SYMBOL_NS_GPL(meson_clk_pll_ops, CLK_MESON);
|
||||
|
||||
const struct clk_ops meson_clk_pll_ro_ops = {
|
||||
.recalc_rate = meson_clk_pll_recalc_rate,
|
||||
.is_enabled = meson_clk_pll_is_enabled,
|
||||
};
|
||||
EXPORT_SYMBOL_GPL(meson_clk_pll_ro_ops);
|
||||
EXPORT_SYMBOL_NS_GPL(meson_clk_pll_ro_ops, CLK_MESON);
|
||||
|
||||
MODULE_DESCRIPTION("Amlogic PLL driver");
|
||||
MODULE_AUTHOR("Carlo Caione <carlo@endlessm.com>");
|
||||
MODULE_AUTHOR("Jerome Brunet <jbrunet@baylibre.com>");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_IMPORT_NS(CLK_MESON);
|
||||
|
@ -49,12 +49,12 @@ const struct clk_ops clk_regmap_gate_ops = {
|
||||
.disable = clk_regmap_gate_disable,
|
||||
.is_enabled = clk_regmap_gate_is_enabled,
|
||||
};
|
||||
EXPORT_SYMBOL_GPL(clk_regmap_gate_ops);
|
||||
EXPORT_SYMBOL_NS_GPL(clk_regmap_gate_ops, CLK_MESON);
|
||||
|
||||
const struct clk_ops clk_regmap_gate_ro_ops = {
|
||||
.is_enabled = clk_regmap_gate_is_enabled,
|
||||
};
|
||||
EXPORT_SYMBOL_GPL(clk_regmap_gate_ro_ops);
|
||||
EXPORT_SYMBOL_NS_GPL(clk_regmap_gate_ro_ops, CLK_MESON);
|
||||
|
||||
static unsigned long clk_regmap_div_recalc_rate(struct clk_hw *hw,
|
||||
unsigned long prate)
|
||||
@ -125,13 +125,13 @@ const struct clk_ops clk_regmap_divider_ops = {
|
||||
.determine_rate = clk_regmap_div_determine_rate,
|
||||
.set_rate = clk_regmap_div_set_rate,
|
||||
};
|
||||
EXPORT_SYMBOL_GPL(clk_regmap_divider_ops);
|
||||
EXPORT_SYMBOL_NS_GPL(clk_regmap_divider_ops, CLK_MESON);
|
||||
|
||||
const struct clk_ops clk_regmap_divider_ro_ops = {
|
||||
.recalc_rate = clk_regmap_div_recalc_rate,
|
||||
.determine_rate = clk_regmap_div_determine_rate,
|
||||
};
|
||||
EXPORT_SYMBOL_GPL(clk_regmap_divider_ro_ops);
|
||||
EXPORT_SYMBOL_NS_GPL(clk_regmap_divider_ro_ops, CLK_MESON);
|
||||
|
||||
static u8 clk_regmap_mux_get_parent(struct clk_hw *hw)
|
||||
{
|
||||
@ -174,13 +174,14 @@ const struct clk_ops clk_regmap_mux_ops = {
|
||||
.set_parent = clk_regmap_mux_set_parent,
|
||||
.determine_rate = clk_regmap_mux_determine_rate,
|
||||
};
|
||||
EXPORT_SYMBOL_GPL(clk_regmap_mux_ops);
|
||||
EXPORT_SYMBOL_NS_GPL(clk_regmap_mux_ops, CLK_MESON);
|
||||
|
||||
const struct clk_ops clk_regmap_mux_ro_ops = {
|
||||
.get_parent = clk_regmap_mux_get_parent,
|
||||
};
|
||||
EXPORT_SYMBOL_GPL(clk_regmap_mux_ro_ops);
|
||||
EXPORT_SYMBOL_NS_GPL(clk_regmap_mux_ro_ops, CLK_MESON);
|
||||
|
||||
MODULE_DESCRIPTION("Amlogic regmap backed clock driver");
|
||||
MODULE_AUTHOR("Jerome Brunet <jbrunet@baylibre.com>");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_IMPORT_NS(CLK_MESON);
|
||||
|
@ -477,3 +477,4 @@ module_platform_driver(g12a_aoclkc_driver);
|
||||
|
||||
MODULE_DESCRIPTION("Amlogic G12A Always-ON Clock Controller driver");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_IMPORT_NS(CLK_MESON);
|
||||
|
@ -5616,3 +5616,4 @@ module_platform_driver(g12a_driver);
|
||||
|
||||
MODULE_DESCRIPTION("Amlogic G12/SM1 Main Clock Controller driver");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_IMPORT_NS(CLK_MESON);
|
||||
|
@ -303,3 +303,4 @@ module_platform_driver(gxbb_aoclkc_driver);
|
||||
|
||||
MODULE_DESCRIPTION("Amlogic GXBB Always-ON Clock Controller driver");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_IMPORT_NS(CLK_MESON);
|
||||
|
@ -3571,3 +3571,4 @@ module_platform_driver(gxbb_driver);
|
||||
|
||||
MODULE_DESCRIPTION("Amlogic GXBB Main Clock Controller driver");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_IMPORT_NS(CLK_MESON);
|
||||
|
@ -88,7 +88,8 @@ int meson_aoclkc_probe(struct platform_device *pdev)
|
||||
|
||||
return devm_of_clk_add_hw_provider(dev, meson_clk_hw_get, (void *)&data->hw_clks);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(meson_aoclkc_probe);
|
||||
EXPORT_SYMBOL_NS_GPL(meson_aoclkc_probe, CLK_MESON);
|
||||
|
||||
MODULE_DESCRIPTION("Amlogic Always-ON Clock Controller helpers");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_IMPORT_NS(CLK_MESON);
|
||||
|
@ -20,7 +20,8 @@ struct clk_hw *meson_clk_hw_get(struct of_phandle_args *clkspec, void *clk_hw_da
|
||||
|
||||
return data->hws[idx];
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(meson_clk_hw_get);
|
||||
EXPORT_SYMBOL_NS_GPL(meson_clk_hw_get, CLK_MESON);
|
||||
|
||||
MODULE_DESCRIPTION("Amlogic Clock Controller Utilities");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_IMPORT_NS(CLK_MESON);
|
||||
|
@ -57,7 +57,8 @@ int meson_eeclkc_probe(struct platform_device *pdev)
|
||||
|
||||
return devm_of_clk_add_hw_provider(dev, meson_clk_hw_get, (void *)&data->hw_clks);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(meson_eeclkc_probe);
|
||||
EXPORT_SYMBOL_NS_GPL(meson_eeclkc_probe, CLK_MESON);
|
||||
|
||||
MODULE_DESCRIPTION("Amlogic Main Clock Controller Helpers");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_IMPORT_NS(CLK_MESON);
|
||||
|
@ -3747,7 +3747,7 @@ static struct clk_regmap *const s4_periphs_clk_regmaps[] = {
|
||||
&s4_adc_extclk_in_gate,
|
||||
};
|
||||
|
||||
static struct regmap_config clkc_regmap_config = {
|
||||
static const struct regmap_config clkc_regmap_config = {
|
||||
.reg_bits = 32,
|
||||
.val_bits = 32,
|
||||
.reg_stride = 4,
|
||||
@ -3814,3 +3814,4 @@ module_platform_driver(s4_driver);
|
||||
MODULE_DESCRIPTION("Amlogic S4 Peripherals Clock Controller driver");
|
||||
MODULE_AUTHOR("Yu Tu <yu.tu@amlogic.com>");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_IMPORT_NS(CLK_MESON);
|
||||
|
@ -799,7 +799,7 @@ static const struct reg_sequence s4_init_regs[] = {
|
||||
{ .reg = ANACTRL_MPLL_CTRL0, .def = 0x00000543 },
|
||||
};
|
||||
|
||||
static struct regmap_config clkc_regmap_config = {
|
||||
static const struct regmap_config clkc_regmap_config = {
|
||||
.reg_bits = 32,
|
||||
.val_bits = 32,
|
||||
.reg_stride = 4,
|
||||
@ -873,3 +873,4 @@ module_platform_driver(s4_driver);
|
||||
MODULE_DESCRIPTION("Amlogic S4 PLL Clock Controller driver");
|
||||
MODULE_AUTHOR("Yu Tu <yu.tu@amlogic.com>");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_IMPORT_NS(CLK_MESON);
|
||||
|
@ -247,8 +247,9 @@ const struct clk_ops meson_sclk_div_ops = {
|
||||
.set_duty_cycle = sclk_div_set_duty_cycle,
|
||||
.init = sclk_div_init,
|
||||
};
|
||||
EXPORT_SYMBOL_GPL(meson_sclk_div_ops);
|
||||
EXPORT_SYMBOL_NS_GPL(meson_sclk_div_ops, CLK_MESON);
|
||||
|
||||
MODULE_DESCRIPTION("Amlogic Sample divider driver");
|
||||
MODULE_AUTHOR("Jerome Brunet <jbrunet@baylibre.com>");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_IMPORT_NS(CLK_MESON);
|
||||
|
@ -49,7 +49,7 @@ const struct clk_ops meson_vclk_gate_ops = {
|
||||
.disable = meson_vclk_gate_disable,
|
||||
.is_enabled = meson_vclk_gate_is_enabled,
|
||||
};
|
||||
EXPORT_SYMBOL_GPL(meson_vclk_gate_ops);
|
||||
EXPORT_SYMBOL_NS_GPL(meson_vclk_gate_ops, CLK_MESON);
|
||||
|
||||
/* The VCLK Divider has supplementary reset & enable bits */
|
||||
|
||||
@ -134,8 +134,9 @@ const struct clk_ops meson_vclk_div_ops = {
|
||||
.disable = meson_vclk_div_disable,
|
||||
.is_enabled = meson_vclk_div_is_enabled,
|
||||
};
|
||||
EXPORT_SYMBOL_GPL(meson_vclk_div_ops);
|
||||
EXPORT_SYMBOL_NS_GPL(meson_vclk_div_ops, CLK_MESON);
|
||||
|
||||
MODULE_DESCRIPTION("Amlogic vclk clock driver");
|
||||
MODULE_AUTHOR("Neil Armstrong <neil.armstrong@linaro.org>");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_IMPORT_NS(CLK_MESON);
|
||||
|
@ -92,8 +92,9 @@ static unsigned long meson_vid_pll_div_recalc_rate(struct clk_hw *hw,
|
||||
const struct clk_ops meson_vid_pll_div_ro_ops = {
|
||||
.recalc_rate = meson_vid_pll_div_recalc_rate,
|
||||
};
|
||||
EXPORT_SYMBOL_GPL(meson_vid_pll_div_ro_ops);
|
||||
EXPORT_SYMBOL_NS_GPL(meson_vid_pll_div_ro_ops, CLK_MESON);
|
||||
|
||||
MODULE_DESCRIPTION("Amlogic video pll divider driver");
|
||||
MODULE_AUTHOR("Neil Armstrong <narmstrong@baylibre.com>");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_IMPORT_NS(CLK_MESON);
|
||||
|
@ -38,6 +38,10 @@
|
||||
#define PMC_CPU (PMC_MAIN + 9)
|
||||
#define PMC_MCK1 (PMC_MAIN + 10)
|
||||
|
||||
/* SAM9X7 */
|
||||
#define PMC_PLLADIV2 (PMC_MAIN + 11)
|
||||
#define PMC_LVDSPLL (PMC_MAIN + 12)
|
||||
|
||||
#ifndef AT91_PMC_MOSCS
|
||||
#define AT91_PMC_MOSCS 0 /* MOSCS Flag */
|
||||
#define AT91_PMC_LOCKA 1 /* PLLA Lock */
|
||||
|
@ -155,5 +155,12 @@
|
||||
#define AUD_CLKID_SYSCLK_B_DIV 175
|
||||
#define AUD_CLKID_SYSCLK_A_EN 176
|
||||
#define AUD_CLKID_SYSCLK_B_EN 177
|
||||
#define AUD_CLKID_EARCRX 178
|
||||
#define AUD_CLKID_EARCRX_CMDC_SEL 179
|
||||
#define AUD_CLKID_EARCRX_CMDC_DIV 180
|
||||
#define AUD_CLKID_EARCRX_CMDC 181
|
||||
#define AUD_CLKID_EARCRX_DMAC_SEL 182
|
||||
#define AUD_CLKID_EARCRX_DMAC_DIV 183
|
||||
#define AUD_CLKID_EARCRX_DMAC 184
|
||||
|
||||
#endif /* __AXG_AUDIO_CLKC_BINDINGS_H */
|
||||
|
@ -25,4 +25,7 @@
|
||||
#define IMX95_CLK_DISPMIX_ENG0_SEL 0
|
||||
#define IMX95_CLK_DISPMIX_ENG1_SEL 1
|
||||
|
||||
#define IMX95_CLK_NETCMIX_ENETC0_RMII 0
|
||||
#define IMX95_CLK_NETCMIX_ENETC1_RMII 1
|
||||
|
||||
#endif /* __DT_BINDINGS_CLOCK_IMX95_H */
|
||||
|
Loading…
x
Reference in New Issue
Block a user