mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-17 01:04:19 +08:00
Merge branches 'clk-vc5', 'clk-silabs', 'clk-aspeed', 'clk-qoriq' and 'clk-rohm' into clk-next
- Support crystal load capacitance for Versaclock VC5 - Add a "skip recall" DT binding for Silicon Labs' si570 to avoid glitches at boot * clk-vc5: clk: vc5: Add support for optional load capacitance dt-bindings: clk: versaclock5: Add optional load capacitance property * clk-silabs: clk: si570: Skip NVM to RAM recall operation if an optional property is set dt-bindings: clock: si570: Add 'silabs,skip-recall' property * clk-aspeed: clk: aspeed: Fix APLL calculate formula from ast2600-A2 * clk-qoriq: clk: qoriq: use macros to generate pll_mask * clk-rohm: clk: BD718x7: Do not depend on parent driver data
This commit is contained in:
commit
11f83102d8
@ -59,6 +59,12 @@ properties:
|
||||
minItems: 1
|
||||
maxItems: 2
|
||||
|
||||
idt,xtal-load-femtofarads:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
minimum: 9000
|
||||
maximum: 22760
|
||||
description: Optional load capacitor for XTAL1 and XTAL2
|
||||
|
||||
patternProperties:
|
||||
"^OUT[1-4]$":
|
||||
type: object
|
||||
|
@ -28,6 +28,8 @@ Optional properties:
|
||||
- clock-frequency: Output frequency to generate. This defines the output
|
||||
frequency set during boot. It can be reprogrammed during
|
||||
runtime through the common clock framework.
|
||||
- silabs,skip-recall: Do not perform NVM->RAM recall operation. It will rely
|
||||
on hardware loading of RAM from NVM at power on.
|
||||
|
||||
Example:
|
||||
si570: clock-generator@5d {
|
||||
|
@ -17,7 +17,8 @@
|
||||
|
||||
#define ASPEED_G6_NUM_CLKS 71
|
||||
|
||||
#define ASPEED_G6_SILICON_REV 0x004
|
||||
#define ASPEED_G6_SILICON_REV 0x014
|
||||
#define CHIP_REVISION_ID GENMASK(23, 16)
|
||||
|
||||
#define ASPEED_G6_RESET_CTRL 0x040
|
||||
#define ASPEED_G6_RESET_CTRL2 0x050
|
||||
@ -190,18 +191,34 @@ static struct clk_hw *ast2600_calc_pll(const char *name, u32 val)
|
||||
static struct clk_hw *ast2600_calc_apll(const char *name, u32 val)
|
||||
{
|
||||
unsigned int mult, div;
|
||||
u32 chip_id = readl(scu_g6_base + ASPEED_G6_SILICON_REV);
|
||||
|
||||
if (val & BIT(20)) {
|
||||
/* Pass through mode */
|
||||
mult = div = 1;
|
||||
if (((chip_id & CHIP_REVISION_ID) >> 16) >= 2) {
|
||||
if (val & BIT(24)) {
|
||||
/* Pass through mode */
|
||||
mult = div = 1;
|
||||
} else {
|
||||
/* F = 25Mhz * [(m + 1) / (n + 1)] / (p + 1) */
|
||||
u32 m = val & 0x1fff;
|
||||
u32 n = (val >> 13) & 0x3f;
|
||||
u32 p = (val >> 19) & 0xf;
|
||||
|
||||
mult = (m + 1);
|
||||
div = (n + 1) * (p + 1);
|
||||
}
|
||||
} else {
|
||||
/* F = 25Mhz * (2-od) * [(m + 2) / (n + 1)] */
|
||||
u32 m = (val >> 5) & 0x3f;
|
||||
u32 od = (val >> 4) & 0x1;
|
||||
u32 n = val & 0xf;
|
||||
if (val & BIT(20)) {
|
||||
/* Pass through mode */
|
||||
mult = div = 1;
|
||||
} else {
|
||||
/* F = 25Mhz * (2-od) * [(m + 2) / (n + 1)] */
|
||||
u32 m = (val >> 5) & 0x3f;
|
||||
u32 od = (val >> 4) & 0x1;
|
||||
u32 n = val & 0xf;
|
||||
|
||||
mult = (2 - od) * (m + 2);
|
||||
div = n + 1;
|
||||
mult = (2 - od) * (m + 2);
|
||||
div = n + 1;
|
||||
}
|
||||
}
|
||||
return clk_hw_register_fixed_factor(NULL, name, "clkin", 0,
|
||||
mult, div);
|
||||
|
@ -31,12 +31,12 @@ struct bd718xx_clk {
|
||||
u8 reg;
|
||||
u8 mask;
|
||||
struct platform_device *pdev;
|
||||
struct rohm_regmap_dev *mfd;
|
||||
struct regmap *regmap;
|
||||
};
|
||||
|
||||
static int bd71837_clk_set(struct bd718xx_clk *c, unsigned int status)
|
||||
{
|
||||
return regmap_update_bits(c->mfd->regmap, c->reg, c->mask, status);
|
||||
return regmap_update_bits(c->regmap, c->reg, c->mask, status);
|
||||
}
|
||||
|
||||
static void bd71837_clk_disable(struct clk_hw *hw)
|
||||
@ -62,7 +62,7 @@ static int bd71837_clk_is_enabled(struct clk_hw *hw)
|
||||
int rval;
|
||||
struct bd718xx_clk *c = container_of(hw, struct bd718xx_clk, hw);
|
||||
|
||||
rval = regmap_read(c->mfd->regmap, c->reg, &enabled);
|
||||
rval = regmap_read(c->regmap, c->reg, &enabled);
|
||||
|
||||
if (rval)
|
||||
return rval;
|
||||
@ -82,7 +82,6 @@ static int bd71837_clk_probe(struct platform_device *pdev)
|
||||
int rval = -ENOMEM;
|
||||
const char *parent_clk;
|
||||
struct device *parent = pdev->dev.parent;
|
||||
struct rohm_regmap_dev *mfd = dev_get_drvdata(parent);
|
||||
struct clk_init_data init = {
|
||||
.name = "bd718xx-32k-out",
|
||||
.ops = &bd71837_clk_ops,
|
||||
@ -93,6 +92,10 @@ static int bd71837_clk_probe(struct platform_device *pdev)
|
||||
if (!c)
|
||||
return -ENOMEM;
|
||||
|
||||
c->regmap = dev_get_regmap(pdev->dev.parent, NULL);
|
||||
if (!c->regmap)
|
||||
return -ENODEV;
|
||||
|
||||
init.num_parents = 1;
|
||||
parent_clk = of_clk_get_parent_name(parent->of_node, 0);
|
||||
|
||||
@ -119,7 +122,6 @@ static int bd71837_clk_probe(struct platform_device *pdev)
|
||||
dev_err(&pdev->dev, "Unknown clk chip\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
c->mfd = mfd;
|
||||
c->pdev = pdev;
|
||||
c->hw.init = &init;
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright 2013 Freescale Semiconductor, Inc.
|
||||
* Copyright 2021 NXP
|
||||
*
|
||||
* clock driver for Freescale QorIQ SoCs.
|
||||
*/
|
||||
@ -564,7 +565,9 @@ static const struct clockgen_chipinfo chipinfo[] = {
|
||||
.cmux_to_group = {
|
||||
0, 1, 1, 1, -1
|
||||
},
|
||||
.pll_mask = 0x3f,
|
||||
.pll_mask = BIT(PLATFORM_PLL) |
|
||||
BIT(CGA_PLL1) | BIT(CGA_PLL2) | BIT(CGA_PLL3) |
|
||||
BIT(CGB_PLL1) | BIT(CGB_PLL2),
|
||||
.flags = CG_PLL_8BIT,
|
||||
},
|
||||
{
|
||||
@ -580,7 +583,9 @@ static const struct clockgen_chipinfo chipinfo[] = {
|
||||
.cmux_to_group = {
|
||||
0, 1, 1, 1, -1
|
||||
},
|
||||
.pll_mask = 0x3f,
|
||||
.pll_mask = BIT(PLATFORM_PLL) |
|
||||
BIT(CGA_PLL1) | BIT(CGA_PLL2) | BIT(CGA_PLL3) |
|
||||
BIT(CGB_PLL1) | BIT(CGB_PLL2),
|
||||
.flags = CG_PLL_8BIT,
|
||||
},
|
||||
{
|
||||
@ -591,7 +596,8 @@ static const struct clockgen_chipinfo chipinfo[] = {
|
||||
.cmux_to_group = {
|
||||
0, -1
|
||||
},
|
||||
.pll_mask = 0x03,
|
||||
.pll_mask = BIT(PLATFORM_PLL) |
|
||||
BIT(CGA_PLL1) | BIT(CGA_PLL2),
|
||||
},
|
||||
{
|
||||
.compat = "fsl,ls1028a-clockgen",
|
||||
@ -605,7 +611,8 @@ static const struct clockgen_chipinfo chipinfo[] = {
|
||||
.cmux_to_group = {
|
||||
0, 0, 0, 0, -1
|
||||
},
|
||||
.pll_mask = 0x07,
|
||||
.pll_mask = BIT(PLATFORM_PLL) |
|
||||
BIT(CGA_PLL1) | BIT(CGA_PLL2),
|
||||
.flags = CG_VER3 | CG_LITTLE_ENDIAN,
|
||||
},
|
||||
{
|
||||
@ -620,7 +627,8 @@ static const struct clockgen_chipinfo chipinfo[] = {
|
||||
.cmux_to_group = {
|
||||
0, -1
|
||||
},
|
||||
.pll_mask = 0x07,
|
||||
.pll_mask = BIT(PLATFORM_PLL) |
|
||||
BIT(CGA_PLL1) | BIT(CGA_PLL2),
|
||||
.flags = CG_PLL_8BIT,
|
||||
},
|
||||
{
|
||||
@ -635,7 +643,8 @@ static const struct clockgen_chipinfo chipinfo[] = {
|
||||
.cmux_to_group = {
|
||||
0, -1
|
||||
},
|
||||
.pll_mask = 0x07,
|
||||
.pll_mask = BIT(PLATFORM_PLL) |
|
||||
BIT(CGA_PLL1) | BIT(CGA_PLL2),
|
||||
.flags = CG_PLL_8BIT,
|
||||
},
|
||||
{
|
||||
@ -649,7 +658,8 @@ static const struct clockgen_chipinfo chipinfo[] = {
|
||||
.cmux_to_group = {
|
||||
0, 0, -1
|
||||
},
|
||||
.pll_mask = 0x07,
|
||||
.pll_mask = BIT(PLATFORM_PLL) |
|
||||
BIT(CGA_PLL1) | BIT(CGA_PLL2),
|
||||
.flags = CG_VER3 | CG_LITTLE_ENDIAN,
|
||||
},
|
||||
{
|
||||
@ -660,7 +670,7 @@ static const struct clockgen_chipinfo chipinfo[] = {
|
||||
.cmux_to_group = {
|
||||
0, -1
|
||||
},
|
||||
.pll_mask = 0x03,
|
||||
.pll_mask = BIT(PLATFORM_PLL) | BIT(CGA_PLL1),
|
||||
},
|
||||
{
|
||||
.compat = "fsl,ls2080a-clockgen",
|
||||
@ -670,7 +680,9 @@ static const struct clockgen_chipinfo chipinfo[] = {
|
||||
.cmux_to_group = {
|
||||
0, 0, 1, 1, -1
|
||||
},
|
||||
.pll_mask = 0x37,
|
||||
.pll_mask = BIT(PLATFORM_PLL) |
|
||||
BIT(CGA_PLL1) | BIT(CGA_PLL2) |
|
||||
BIT(CGB_PLL1) | BIT(CGB_PLL2),
|
||||
.flags = CG_VER3 | CG_LITTLE_ENDIAN,
|
||||
},
|
||||
{
|
||||
@ -681,7 +693,9 @@ static const struct clockgen_chipinfo chipinfo[] = {
|
||||
.cmux_to_group = {
|
||||
0, 0, 0, 0, 1, 1, 1, 1, -1
|
||||
},
|
||||
.pll_mask = 0x37,
|
||||
.pll_mask = BIT(PLATFORM_PLL) |
|
||||
BIT(CGA_PLL1) | BIT(CGA_PLL2) |
|
||||
BIT(CGB_PLL1) | BIT(CGB_PLL2),
|
||||
.flags = CG_VER3 | CG_LITTLE_ENDIAN,
|
||||
},
|
||||
{
|
||||
@ -694,7 +708,8 @@ static const struct clockgen_chipinfo chipinfo[] = {
|
||||
.cmux_to_group = {
|
||||
0, 0, 1, 1, -1
|
||||
},
|
||||
.pll_mask = 0x07,
|
||||
.pll_mask = BIT(PLATFORM_PLL) |
|
||||
BIT(CGA_PLL1) | BIT(CGA_PLL2),
|
||||
},
|
||||
{
|
||||
.compat = "fsl,p3041-clockgen",
|
||||
@ -706,7 +721,8 @@ static const struct clockgen_chipinfo chipinfo[] = {
|
||||
.cmux_to_group = {
|
||||
0, 0, 1, 1, -1
|
||||
},
|
||||
.pll_mask = 0x07,
|
||||
.pll_mask = BIT(PLATFORM_PLL) |
|
||||
BIT(CGA_PLL1) | BIT(CGA_PLL2),
|
||||
},
|
||||
{
|
||||
.compat = "fsl,p4080-clockgen",
|
||||
@ -718,7 +734,9 @@ static const struct clockgen_chipinfo chipinfo[] = {
|
||||
.cmux_to_group = {
|
||||
0, 0, 0, 0, 1, 1, 1, 1, -1
|
||||
},
|
||||
.pll_mask = 0x1f,
|
||||
.pll_mask = BIT(PLATFORM_PLL) |
|
||||
BIT(CGA_PLL1) | BIT(CGA_PLL2) |
|
||||
BIT(CGA_PLL3) | BIT(CGA_PLL4),
|
||||
},
|
||||
{
|
||||
.compat = "fsl,p5020-clockgen",
|
||||
@ -730,7 +748,8 @@ static const struct clockgen_chipinfo chipinfo[] = {
|
||||
.cmux_to_group = {
|
||||
0, 1, -1
|
||||
},
|
||||
.pll_mask = 0x07,
|
||||
.pll_mask = BIT(PLATFORM_PLL) |
|
||||
BIT(CGA_PLL1) | BIT(CGA_PLL2),
|
||||
},
|
||||
{
|
||||
.compat = "fsl,p5040-clockgen",
|
||||
@ -742,7 +761,8 @@ static const struct clockgen_chipinfo chipinfo[] = {
|
||||
.cmux_to_group = {
|
||||
0, 0, 1, 1, -1
|
||||
},
|
||||
.pll_mask = 0x0f,
|
||||
.pll_mask = BIT(PLATFORM_PLL) |
|
||||
BIT(CGA_PLL1) | BIT(CGA_PLL2) | BIT(CGA_PLL3),
|
||||
},
|
||||
{
|
||||
.compat = "fsl,t1023-clockgen",
|
||||
@ -757,7 +777,7 @@ static const struct clockgen_chipinfo chipinfo[] = {
|
||||
.cmux_to_group = {
|
||||
0, 0, -1
|
||||
},
|
||||
.pll_mask = 0x03,
|
||||
.pll_mask = BIT(PLATFORM_PLL) | BIT(CGA_PLL1),
|
||||
.flags = CG_PLL_8BIT,
|
||||
},
|
||||
{
|
||||
@ -770,7 +790,8 @@ static const struct clockgen_chipinfo chipinfo[] = {
|
||||
.cmux_to_group = {
|
||||
0, 0, 0, 0, -1
|
||||
},
|
||||
.pll_mask = 0x07,
|
||||
.pll_mask = BIT(PLATFORM_PLL) |
|
||||
BIT(CGA_PLL1) | BIT(CGA_PLL2),
|
||||
.flags = CG_PLL_8BIT,
|
||||
},
|
||||
{
|
||||
@ -786,7 +807,8 @@ static const struct clockgen_chipinfo chipinfo[] = {
|
||||
.cmux_to_group = {
|
||||
0, -1
|
||||
},
|
||||
.pll_mask = 0x07,
|
||||
.pll_mask = BIT(PLATFORM_PLL) |
|
||||
BIT(CGA_PLL1) | BIT(CGA_PLL2),
|
||||
.flags = CG_PLL_8BIT,
|
||||
},
|
||||
{
|
||||
@ -802,7 +824,9 @@ static const struct clockgen_chipinfo chipinfo[] = {
|
||||
.cmux_to_group = {
|
||||
0, 0, 1, -1
|
||||
},
|
||||
.pll_mask = 0x3f,
|
||||
.pll_mask = BIT(PLATFORM_PLL) |
|
||||
BIT(CGA_PLL1) | BIT(CGA_PLL2) | BIT(CGA_PLL3) |
|
||||
BIT(CGB_PLL1) | BIT(CGB_PLL2),
|
||||
.flags = CG_PLL_8BIT,
|
||||
},
|
||||
{},
|
||||
|
@ -4,7 +4,7 @@
|
||||
*
|
||||
* Copyright (C) 2010, 2011 Ericsson AB.
|
||||
* Copyright (C) 2011 Guenter Roeck.
|
||||
* Copyright (C) 2011 - 2013 Xilinx Inc.
|
||||
* Copyright (C) 2011 - 2021 Xilinx Inc.
|
||||
*
|
||||
* Author: Guenter Roeck <guenter.roeck@ericsson.com>
|
||||
* Sören Brinkmann <soren.brinkmann@xilinx.com>
|
||||
@ -123,14 +123,18 @@ static int si570_get_divs(struct clk_si570 *data, u64 *rfreq,
|
||||
* si570_get_defaults() - Get default values
|
||||
* @data: Driver data structure
|
||||
* @fout: Factory frequency output
|
||||
* @skip_recall: If true, don't recall NVM into RAM
|
||||
* Returns 0 on success, negative errno otherwise.
|
||||
*/
|
||||
static int si570_get_defaults(struct clk_si570 *data, u64 fout)
|
||||
static int si570_get_defaults(struct clk_si570 *data, u64 fout,
|
||||
bool skip_recall)
|
||||
{
|
||||
int err;
|
||||
u64 fdco;
|
||||
|
||||
regmap_write(data->regmap, SI570_REG_CONTROL, SI570_CNTRL_RECALL);
|
||||
if (!skip_recall)
|
||||
regmap_write(data->regmap, SI570_REG_CONTROL,
|
||||
SI570_CNTRL_RECALL);
|
||||
|
||||
err = si570_get_divs(data, &data->rfreq, &data->n1, &data->hs_div);
|
||||
if (err)
|
||||
@ -400,6 +404,7 @@ static int si570_probe(struct i2c_client *client,
|
||||
struct clk_si570 *data;
|
||||
struct clk_init_data init;
|
||||
u32 initial_fout, factory_fout, stability;
|
||||
bool skip_recall;
|
||||
int err;
|
||||
enum clk_si570_variant variant = id->driver_data;
|
||||
|
||||
@ -441,6 +446,9 @@ static int si570_probe(struct i2c_client *client,
|
||||
return err;
|
||||
}
|
||||
|
||||
skip_recall = of_property_read_bool(client->dev.of_node,
|
||||
"silabs,skip-recall");
|
||||
|
||||
data->regmap = devm_regmap_init_i2c(client, &si570_regmap_config);
|
||||
if (IS_ERR(data->regmap)) {
|
||||
dev_err(&client->dev, "failed to allocate register map\n");
|
||||
@ -448,7 +456,7 @@ static int si570_probe(struct i2c_client *client,
|
||||
}
|
||||
|
||||
i2c_set_clientdata(client, data);
|
||||
err = si570_get_defaults(data, factory_fout);
|
||||
err = si570_get_defaults(data, factory_fout, skip_recall);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
|
@ -759,6 +759,63 @@ static int vc5_update_power(struct device_node *np_output,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int vc5_map_cap_value(u32 femtofarads)
|
||||
{
|
||||
int mapped_value;
|
||||
|
||||
/*
|
||||
* The datasheet explicitly states 9000 - 25000 with 0.5pF
|
||||
* steps, but the Programmer's guide shows the steps are 0.430pF.
|
||||
* After getting feedback from Renesas, the .5pF steps were the
|
||||
* goal, but 430nF was the actual values.
|
||||
* Because of this, the actual range goes to 22760 instead of 25000
|
||||
*/
|
||||
if (femtofarads < 9000 || femtofarads > 22760)
|
||||
return -EINVAL;
|
||||
|
||||
/*
|
||||
* The Programmer's guide shows XTAL[5:0] but in reality,
|
||||
* XTAL[0] and XTAL[1] are both LSB which makes the math
|
||||
* strange. With clarfication from Renesas, setting the
|
||||
* values should be simpler by ignoring XTAL[0]
|
||||
*/
|
||||
mapped_value = DIV_ROUND_CLOSEST(femtofarads - 9000, 430);
|
||||
|
||||
/*
|
||||
* Since the calculation ignores XTAL[0], there is one
|
||||
* special case where mapped_value = 32. In reality, this means
|
||||
* the real mapped value should be 111111b. In other cases,
|
||||
* the mapped_value needs to be shifted 1 to the left.
|
||||
*/
|
||||
if (mapped_value > 31)
|
||||
mapped_value = 0x3f;
|
||||
else
|
||||
mapped_value <<= 1;
|
||||
|
||||
return mapped_value;
|
||||
}
|
||||
static int vc5_update_cap_load(struct device_node *node, struct vc5_driver_data *vc5)
|
||||
{
|
||||
u32 value;
|
||||
int mapped_value;
|
||||
|
||||
if (!of_property_read_u32(node, "idt,xtal-load-femtofarads", &value)) {
|
||||
mapped_value = vc5_map_cap_value(value);
|
||||
if (mapped_value < 0)
|
||||
return mapped_value;
|
||||
|
||||
/*
|
||||
* The mapped_value is really the high 6 bits of
|
||||
* VC5_XTAL_X1_LOAD_CAP and VC5_XTAL_X2_LOAD_CAP, so
|
||||
* shift the value 2 places.
|
||||
*/
|
||||
regmap_update_bits(vc5->regmap, VC5_XTAL_X1_LOAD_CAP, ~0x03, mapped_value << 2);
|
||||
regmap_update_bits(vc5->regmap, VC5_XTAL_X2_LOAD_CAP, ~0x03, mapped_value << 2);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int vc5_update_slew(struct device_node *np_output,
|
||||
struct vc5_out_data *clk_out)
|
||||
{
|
||||
@ -884,6 +941,13 @@ static int vc5_probe(struct i2c_client *client, const struct i2c_device_id *id)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Configure Optional Loading Capacitance for external XTAL */
|
||||
if (!(vc5->chip_info->flags & VC5_HAS_INTERNAL_XTAL)) {
|
||||
ret = vc5_update_cap_load(client->dev.of_node, vc5);
|
||||
if (ret)
|
||||
goto err_clk_register;
|
||||
}
|
||||
|
||||
init.name = kasprintf(GFP_KERNEL, "%pOFn.mux", client->dev.of_node);
|
||||
init.ops = &vc5_mux_ops;
|
||||
init.flags = 0;
|
||||
|
Loading…
Reference in New Issue
Block a user