Commit b6c444de authored by Stephen Boyd's avatar Stephen Boyd

Merge branches 'clk-cdce-regulator', 'clk-bcm', 'clk-evict-parent-cache' and...

Merge branches 'clk-cdce-regulator', 'clk-bcm', 'clk-evict-parent-cache' and 'clk-actions' into clk-next

 - Add regulator support to the cdce925 clk driver
 - Add support for Raspberry Pi 4 bcm2711 SoCs
 - Evict parents from parent cache when they're unregistered

* clk-cdce-regulator:
  clk: clk-cdce925: Add regulator support
  dt-bindings: clock: cdce925: Add regulator documentation

* clk-bcm:
  clk: bcm2835: Mark PLLD_PER as CRITICAL
  clk: bcm2835: Add BCM2711_CLOCK_EMMC2 support
  clk: bcm2835: Introduce SoC specific clock registration
  dt-bindings: bcm2835-cprman: Add bcm2711 support

* clk-evict-parent-cache:
  clk: Evict unregistered clks from parent caches

* clk-actions:
  clk: actions: Fix factor clk struct member access
......@@ -12,7 +12,9 @@ clock generators, but a few (like the ARM or HDMI) will source from
the PLL dividers directly.
Required properties:
- compatible: Should be "brcm,bcm2835-cprman"
- compatible: should be one of the following,
"brcm,bcm2711-cprman"
"brcm,bcm2835-cprman"
- #clock-cells: Should be <1>. The permitted clock-specifier values can be
found in include/dt-bindings/clock/bcm2835.h
- reg: Specifies base physical address and size of the registers
......
......@@ -24,6 +24,8 @@ Required properties:
Optional properties:
- xtal-load-pf: Crystal load-capacitor value to fine-tune performance on a
board, or to compensate for external influences.
- vdd-supply: A regulator node for Vdd
- vddout-supply: A regulator node for Vddout
For all PLL1, PLL2, ... an optional child node can be used to specify spread
spectrum clocking parameters for a board.
......@@ -41,6 +43,8 @@ Example:
clocks = <&xtal_27Mhz>;
#clock-cells = <1>;
xtal-load-pf = <5>;
vdd-supply = <&1v8-reg>;
vddout-supply = <&3v3-reg>;
/* PLL options to get SSC 1% centered */
PLL2 {
spread-spectrum = <4>;
......
......@@ -64,11 +64,10 @@ static unsigned int _get_table_val(const struct clk_factor_table *table,
return val;
}
static int clk_val_best(struct clk_hw *hw, unsigned long rate,
static int owl_clk_val_best(const struct owl_factor_hw *factor_hw,
struct clk_hw *hw, unsigned long rate,
unsigned long *best_parent_rate)
{
struct owl_factor *factor = hw_to_owl_factor(hw);
struct owl_factor_hw *factor_hw = &factor->factor_hw;
const struct clk_factor_table *clkt = factor_hw->table;
unsigned long parent_rate, try_parent_rate, best = 0, cur_rate;
unsigned long parent_rate_saved = *best_parent_rate;
......@@ -126,7 +125,7 @@ long owl_factor_helper_round_rate(struct owl_clk_common *common,
const struct clk_factor_table *clkt = factor_hw->table;
unsigned int val, mul = 0, div = 1;
val = clk_val_best(&common->hw, rate, parent_rate);
val = owl_clk_val_best(factor_hw, &common->hw, rate, parent_rate);
_get_table_div_mul(clkt, val, &mul, &div);
return *parent_rate * mul / div;
......
This diff is collapsed.
......@@ -16,6 +16,7 @@
#include <linux/module.h>
#include <linux/i2c.h>
#include <linux/regmap.h>
#include <linux/regulator/consumer.h>
#include <linux/slab.h>
#include <linux/gcd.h>
......@@ -602,6 +603,30 @@ of_clk_cdce925_get(struct of_phandle_args *clkspec, void *_data)
return &data->clk[idx].hw;
}
static void cdce925_regulator_disable(void *regulator)
{
regulator_disable(regulator);
}
static int cdce925_regulator_enable(struct device *dev, const char *name)
{
struct regulator *regulator;
int err;
regulator = devm_regulator_get(dev, name);
if (IS_ERR(regulator))
return PTR_ERR(regulator);
err = regulator_enable(regulator);
if (err) {
dev_err(dev, "Failed to enable %s: %d\n", name, err);
return err;
}
return devm_add_action_or_reset(dev, cdce925_regulator_disable,
regulator);
}
/* The CDCE925 uses a funky way to read/write registers. Bulk mode is
* just weird, so just use the single byte mode exclusively. */
static struct regmap_bus regmap_cdce925_bus = {
......@@ -630,6 +655,15 @@ static int cdce925_probe(struct i2c_client *client,
};
dev_dbg(&client->dev, "%s\n", __func__);
err = cdce925_regulator_enable(&client->dev, "vdd");
if (err)
return err;
err = cdce925_regulator_enable(&client->dev, "vddout");
if (err)
return err;
data = devm_kzalloc(&client->dev, sizeof(*data), GFP_KERNEL);
if (!data)
return -ENOMEM;
......
......@@ -37,6 +37,12 @@ static HLIST_HEAD(clk_root_list);
static HLIST_HEAD(clk_orphan_list);
static LIST_HEAD(clk_notifier_list);
static struct hlist_head *all_lists[] = {
&clk_root_list,
&clk_orphan_list,
NULL,
};
/*** private data structures ***/
struct clk_parent_map {
......@@ -2841,12 +2847,6 @@ static int inited = 0;
static DEFINE_MUTEX(clk_debug_lock);
static HLIST_HEAD(clk_debug_list);
static struct hlist_head *all_lists[] = {
&clk_root_list,
&clk_orphan_list,
NULL,
};
static struct hlist_head *orphan_list[] = {
&clk_orphan_list,
NULL,
......@@ -3777,6 +3777,34 @@ static const struct clk_ops clk_nodrv_ops = {
.set_parent = clk_nodrv_set_parent,
};
static void clk_core_evict_parent_cache_subtree(struct clk_core *root,
struct clk_core *target)
{
int i;
struct clk_core *child;
for (i = 0; i < root->num_parents; i++)
if (root->parents[i].core == target)
root->parents[i].core = NULL;
hlist_for_each_entry(child, &root->children, child_node)
clk_core_evict_parent_cache_subtree(child, target);
}
/* Remove this clk from all parent caches */
static void clk_core_evict_parent_cache(struct clk_core *core)
{
struct hlist_head **lists;
struct clk_core *root;
lockdep_assert_held(&prepare_lock);
for (lists = all_lists; *lists; lists++)
hlist_for_each_entry(root, *lists, child_node)
clk_core_evict_parent_cache_subtree(root, core);
}
/**
* clk_unregister - unregister a currently registered clock
* @clk: clock to unregister
......@@ -3815,6 +3843,8 @@ void clk_unregister(struct clk *clk)
clk_core_set_parent_nolock(child, NULL);
}
clk_core_evict_parent_cache(clk->core);
hlist_del_init(&clk->core->child_node);
if (clk->core->prepare_count)
......
......@@ -58,3 +58,5 @@
#define BCM2835_CLOCK_DSI1E 48
#define BCM2835_CLOCK_DSI0P 49
#define BCM2835_CLOCK_DSI1P 50
#define BCM2711_CLOCK_EMMC2 51
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment