Skip to content

Commit

Permalink
clk: lan966x: Extend lan966x clock driver for clock gating support
Browse files Browse the repository at this point in the history
Extend the clock driver to add support also for clock gating. The
following peripherals can be gated: UHPHS, UDPHS, MCRAMC, HMATRIX.

Signed-off-by: Horatiu Vultur <horatiu.vultur@microchip.com>
Acked-by: Nicolas Ferre <nicolas.ferre@microchip.com>
Signed-off-by: Nicolas Ferre <nicolas.ferre@microchip.com>
Link: https://lore.kernel.org/r/20211103085102.1656081-5-horatiu.vultur@microchip.com
  • Loading branch information
Horatiu Vultur authored and Nicolas Ferre committed Dec 8, 2021
1 parent 51d0a37 commit 5ad5915
Showing 1 changed file with 56 additions and 3 deletions.
59 changes: 56 additions & 3 deletions drivers/clk/clk-lan966x.c
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,20 @@ static struct clk_init_data init = {
.num_parents = ARRAY_SIZE(lan966x_gck_pdata),
};

struct clk_gate_soc_desc {
const char *name;
int bit_idx;
};

static const struct clk_gate_soc_desc clk_gate_desc[] = {
{ "uhphs", 11 },
{ "udphs", 10 },
{ "mcramc", 9 },
{ "hmatrix", 8 },
{ }
};

static DEFINE_SPINLOCK(clk_gate_lock);
static void __iomem *base;

static int lan966x_gck_enable(struct clk_hw *hw)
Expand Down Expand Up @@ -188,11 +202,37 @@ static struct clk_hw *lan966x_gck_clk_register(struct device *dev, int i)
return &priv->hw;
};

static int lan966x_gate_clk_register(struct device *dev,
struct clk_hw_onecell_data *hw_data,
void __iomem *gate_base)
{
int i;

for (i = GCK_GATE_UHPHS; i < N_CLOCKS; ++i) {
int idx = i - GCK_GATE_UHPHS;

hw_data->hws[i] =
devm_clk_hw_register_gate(dev, clk_gate_desc[idx].name,
"lan966x", 0, base,
clk_gate_desc[idx].bit_idx,
0, &clk_gate_lock);

if (IS_ERR(hw_data->hws[i]))
return dev_err_probe(dev, PTR_ERR(hw_data->hws[i]),
"failed to register %s clock\n",
clk_gate_desc[idx].name);
}

return 0;
}

static int lan966x_clk_probe(struct platform_device *pdev)
{
struct clk_hw_onecell_data *hw_data;
struct device *dev = &pdev->dev;
int i;
void __iomem *gate_base;
struct resource *res;
int i, ret;

hw_data = devm_kzalloc(dev, struct_size(hw_data, hws, N_CLOCKS),
GFP_KERNEL);
Expand All @@ -205,9 +245,9 @@ static int lan966x_clk_probe(struct platform_device *pdev)

init.ops = &lan966x_gck_ops;

hw_data->num = N_CLOCKS;
hw_data->num = GCK_GATE_UHPHS;

for (i = 0; i < N_CLOCKS; i++) {
for (i = 0; i < GCK_GATE_UHPHS; i++) {
init.name = clk_names[i];
hw_data->hws[i] = lan966x_gck_clk_register(dev, i);
if (IS_ERR(hw_data->hws[i])) {
Expand All @@ -217,6 +257,19 @@ static int lan966x_clk_probe(struct platform_device *pdev)
}
}

res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
if (res) {
gate_base = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(gate_base))
return PTR_ERR(gate_base);

hw_data->num = N_CLOCKS;

ret = lan966x_gate_clk_register(dev, hw_data, gate_base);
if (ret)
return ret;
}

return devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get, hw_data);
}

Expand Down

0 comments on commit 5ad5915

Please sign in to comment.