2019-05-27 14:55:06 +08:00
|
|
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
2015-12-05 05:24:40 +08:00
|
|
|
/*
|
|
|
|
* Copyright (C) 2015 Jens Kuske <jenskuske@gmail.com>
|
|
|
|
*
|
|
|
|
* Based on clk-simple-gates.c, which is:
|
|
|
|
* Copyright 2015 Maxime Ripard
|
|
|
|
*
|
|
|
|
* Maxime Ripard <maxime.ripard@free-electrons.com>
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <linux/clk-provider.h>
|
2019-04-19 06:20:22 +08:00
|
|
|
#include <linux/io.h>
|
2015-12-05 05:24:40 +08:00
|
|
|
#include <linux/of.h>
|
|
|
|
#include <linux/of_address.h>
|
|
|
|
#include <linux/slab.h>
|
|
|
|
#include <linux/spinlock.h>
|
|
|
|
|
|
|
|
static DEFINE_SPINLOCK(gates_lock);
|
|
|
|
|
|
|
|
static void __init sun8i_h3_bus_gates_init(struct device_node *node)
|
|
|
|
{
|
|
|
|
static const char * const names[] = { "ahb1", "ahb2", "apb1", "apb2" };
|
|
|
|
enum { AHB1, AHB2, APB1, APB2, PARENT_MAX } clk_parent;
|
|
|
|
const char *parents[PARENT_MAX];
|
|
|
|
struct clk_onecell_data *clk_data;
|
|
|
|
const char *clk_name;
|
|
|
|
struct property *prop;
|
|
|
|
struct resource res;
|
|
|
|
void __iomem *clk_reg;
|
|
|
|
void __iomem *reg;
|
|
|
|
const __be32 *p;
|
|
|
|
int number, i;
|
|
|
|
u8 clk_bit;
|
2015-12-12 20:43:46 +08:00
|
|
|
int index;
|
2015-12-05 05:24:40 +08:00
|
|
|
|
|
|
|
reg = of_io_request_and_map(node, 0, of_node_full_name(node));
|
|
|
|
if (IS_ERR(reg))
|
|
|
|
return;
|
|
|
|
|
|
|
|
for (i = 0; i < ARRAY_SIZE(names); i++) {
|
2015-12-14 18:06:00 +08:00
|
|
|
int idx = of_property_match_string(node, "clock-names",
|
|
|
|
names[i]);
|
|
|
|
if (idx < 0)
|
2015-12-05 05:24:40 +08:00
|
|
|
return;
|
|
|
|
|
2015-12-14 18:06:00 +08:00
|
|
|
parents[i] = of_clk_get_parent_name(node, idx);
|
2015-12-05 05:24:40 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
clk_data = kmalloc(sizeof(struct clk_onecell_data), GFP_KERNEL);
|
|
|
|
if (!clk_data)
|
|
|
|
goto err_unmap;
|
|
|
|
|
|
|
|
number = of_property_count_u32_elems(node, "clock-indices");
|
|
|
|
of_property_read_u32_index(node, "clock-indices", number - 1, &number);
|
|
|
|
|
|
|
|
clk_data->clks = kcalloc(number + 1, sizeof(struct clk *), GFP_KERNEL);
|
|
|
|
if (!clk_data->clks)
|
|
|
|
goto err_free_data;
|
|
|
|
|
|
|
|
i = 0;
|
|
|
|
of_property_for_each_u32(node, "clock-indices", prop, p, index) {
|
|
|
|
of_property_read_string_index(node, "clock-output-names",
|
|
|
|
i, &clk_name);
|
|
|
|
|
|
|
|
if (index == 17 || (index >= 29 && index <= 31))
|
|
|
|
clk_parent = AHB2;
|
|
|
|
else if (index <= 63 || index >= 128)
|
|
|
|
clk_parent = AHB1;
|
|
|
|
else if (index >= 64 && index <= 95)
|
|
|
|
clk_parent = APB1;
|
|
|
|
else if (index >= 96 && index <= 127)
|
|
|
|
clk_parent = APB2;
|
2017-08-23 22:39:27 +08:00
|
|
|
else {
|
|
|
|
WARN_ON(true);
|
|
|
|
continue;
|
|
|
|
}
|
2015-12-05 05:24:40 +08:00
|
|
|
|
|
|
|
clk_reg = reg + 4 * (index / 32);
|
|
|
|
clk_bit = index % 32;
|
|
|
|
|
|
|
|
clk_data->clks[index] = clk_register_gate(NULL, clk_name,
|
|
|
|
parents[clk_parent],
|
|
|
|
0, clk_reg, clk_bit,
|
|
|
|
0, &gates_lock);
|
|
|
|
i++;
|
|
|
|
|
|
|
|
if (IS_ERR(clk_data->clks[index])) {
|
|
|
|
WARN_ON(true);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
clk_data->clk_num = number + 1;
|
|
|
|
of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
err_free_data:
|
|
|
|
kfree(clk_data);
|
|
|
|
err_unmap:
|
|
|
|
iounmap(reg);
|
|
|
|
of_address_to_resource(node, 0, &res);
|
|
|
|
release_mem_region(res.start, resource_size(&res));
|
|
|
|
}
|
|
|
|
|
|
|
|
CLK_OF_DECLARE(sun8i_h3_bus_gates, "allwinner,sun8i-h3-bus-gates-clk",
|
|
|
|
sun8i_h3_bus_gates_init);
|
clk: sunxi: add bus gates for A83T
A83T has similar bus gates that of H3, including single gating register has
different clock parent.
As per H3 and A83T datasheet, usbhost is under AHB2.
However,below shows allwinner source code assignment:
bits: 26 (ehci0), 27 (ehci1), 29 (ohci0) => AHB1 for A83T.
bits: 26 (ehci0), 27 (ehci1) => AHB1 for H3
bits 29, 30, 31(ohci0,1,2) => AHB2 for H3.
until, this confusion is cleared keep it H3 way.
Signed-off-by: Vishnu Patekar <vishnupatekar0510@gmail.com>
Acked-by: Rob Herring <robh@kernel.org>
Acked-by: Chen-Yu Tsai <wens@csie.org>
Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
2016-01-31 09:20:55 +08:00
|
|
|
CLK_OF_DECLARE(sun8i_a83t_bus_gates, "allwinner,sun8i-a83t-bus-gates-clk",
|
|
|
|
sun8i_h3_bus_gates_init);
|