summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Documentation/devicetree/bindings/clock/idt,versaclock5.yaml6
-rw-r--r--Documentation/devicetree/bindings/clock/silabs,si570.txt2
-rw-r--r--drivers/clk/clk-ast2600.c37
-rw-r--r--drivers/clk/clk-bd718x7.c12
-rw-r--r--drivers/clk/clk-qoriq.c62
-rw-r--r--drivers/clk/clk-si570.c16
-rw-r--r--drivers/clk/clk-versaclock5.c64
7 files changed, 161 insertions, 38 deletions
diff --git a/Documentation/devicetree/bindings/clock/idt,versaclock5.yaml b/Documentation/devicetree/bindings/clock/idt,versaclock5.yaml
index 2ac1131fd922..c268debe5b8d 100644
--- a/Documentation/devicetree/bindings/clock/idt,versaclock5.yaml
+++ b/Documentation/devicetree/bindings/clock/idt,versaclock5.yaml
@@ -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
diff --git a/Documentation/devicetree/bindings/clock/silabs,si570.txt b/Documentation/devicetree/bindings/clock/silabs,si570.txt
index 901935e929d2..5dda17df1ac5 100644
--- a/Documentation/devicetree/bindings/clock/silabs,si570.txt
+++ b/Documentation/devicetree/bindings/clock/silabs,si570.txt
@@ -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 {
diff --git a/drivers/clk/clk-ast2600.c b/drivers/clk/clk-ast2600.c
index 177368cac6dd..a55b37fc2c8b 100644
--- a/drivers/clk/clk-ast2600.c
+++ b/drivers/clk/clk-ast2600.c
@@ -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);
diff --git a/drivers/clk/clk-bd718x7.c b/drivers/clk/clk-bd718x7.c
index b52e8d6f660c..17d90e09f1c0 100644
--- a/drivers/clk/clk-bd718x7.c
+++ b/drivers/clk/clk-bd718x7.c
@@ -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;
diff --git a/drivers/clk/clk-qoriq.c b/drivers/clk/clk-qoriq.c
index 70aa521e7e7f..88898b97a443 100644
--- a/drivers/clk/clk-qoriq.c
+++ b/drivers/clk/clk-qoriq.c
@@ -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,
},
{},
diff --git a/drivers/clk/clk-si570.c b/drivers/clk/clk-si570.c
index 34b25609f55f..eea50121718a 100644
--- a/drivers/clk/clk-si570.c
+++ b/drivers/clk/clk-si570.c
@@ -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;
diff --git a/drivers/clk/clk-versaclock5.c b/drivers/clk/clk-versaclock5.c
index 43db67337bc0..344cd6c61188 100644
--- a/drivers/clk/clk-versaclock5.c
+++ b/drivers/clk/clk-versaclock5.c
@@ -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;