Skip to content

Commit 1bc9597

Browse files
mripardbebarino
authored andcommitted
clk: bcm: Add BCM2711 DVP driver
The HDMI block has a block that controls clocks and reset signals to the HDMI0 and HDMI1 controllers. Let's expose that through a clock driver implementing a clock and reset provider. Cc: Michael Turquette <[email protected]> Cc: Stephen Boyd <[email protected]> Cc: Rob Herring <[email protected]> Cc: [email protected] Cc: [email protected] Reviewed-by: Stephen Boyd <[email protected]> Signed-off-by: Maxime Ripard <[email protected]> Link: https://lore.kernel.org/r/bb60d97fc76b61c2eabef5a02ebd664c0f57ede0.1591867332.git-series.maxime@cerno.tech Acked-by: Stefan Wahren <[email protected]> Reviewed-by: Nicolas Saenz Julienne <[email protected]> Signed-off-by: Stephen Boyd <[email protected]>
1 parent 8dda000 commit 1bc9597

File tree

3 files changed

+132
-0
lines changed

3 files changed

+132
-0
lines changed

drivers/clk/bcm/Kconfig

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,15 @@
11
# SPDX-License-Identifier: GPL-2.0-only
2+
3+
config CLK_BCM2711_DVP
4+
tristate "Broadcom BCM2711 DVP support"
5+
depends on ARCH_BCM2835 ||COMPILE_TEST
6+
depends on COMMON_CLK
7+
default ARCH_BCM2835
8+
select RESET_SIMPLE
9+
help
10+
Enable common clock framework support for the Broadcom BCM2711
11+
DVP Controller.
12+
213
config CLK_BCM2835
314
bool "Broadcom BCM2835 clock support"
415
depends on ARCH_BCM2835 || ARCH_BRCMSTB || COMPILE_TEST

drivers/clk/bcm/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ obj-$(CONFIG_CLK_BCM_KONA) += clk-kona-setup.o
66
obj-$(CONFIG_CLK_BCM_KONA) += clk-bcm281xx.o
77
obj-$(CONFIG_CLK_BCM_KONA) += clk-bcm21664.o
88
obj-$(CONFIG_COMMON_CLK_IPROC) += clk-iproc-armpll.o clk-iproc-pll.o clk-iproc-asiu.o
9+
obj-$(CONFIG_CLK_BCM2711_DVP) += clk-bcm2711-dvp.o
910
obj-$(CONFIG_CLK_BCM2835) += clk-bcm2835.o
1011
obj-$(CONFIG_CLK_BCM2835) += clk-bcm2835-aux.o
1112
obj-$(CONFIG_CLK_RASPBERRYPI) += clk-raspberrypi.o

drivers/clk/bcm/clk-bcm2711-dvp.c

Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
// SPDX-License-Identifier: GPL-2.0-or-later
2+
// Copyright 2020 Cerno
3+
4+
#include <linux/clk-provider.h>
5+
#include <linux/module.h>
6+
#include <linux/platform_device.h>
7+
#include <linux/reset-controller.h>
8+
#include <linux/reset/reset-simple.h>
9+
10+
#define DVP_HT_RPI_SW_INIT 0x04
11+
#define DVP_HT_RPI_MISC_CONFIG 0x08
12+
13+
#define NR_CLOCKS 2
14+
#define NR_RESETS 6
15+
16+
struct clk_dvp {
17+
struct clk_hw_onecell_data *data;
18+
struct reset_simple_data reset;
19+
};
20+
21+
static const struct clk_parent_data clk_dvp_parent = {
22+
.index = 0,
23+
};
24+
25+
static int clk_dvp_probe(struct platform_device *pdev)
26+
{
27+
struct clk_hw_onecell_data *data;
28+
struct resource *res;
29+
struct clk_dvp *dvp;
30+
void __iomem *base;
31+
int ret;
32+
33+
dvp = devm_kzalloc(&pdev->dev, sizeof(*dvp), GFP_KERNEL);
34+
if (!dvp)
35+
return -ENOMEM;
36+
platform_set_drvdata(pdev, dvp);
37+
38+
dvp->data = devm_kzalloc(&pdev->dev,
39+
struct_size(dvp->data, hws, NR_CLOCKS),
40+
GFP_KERNEL);
41+
if (!dvp->data)
42+
return -ENOMEM;
43+
data = dvp->data;
44+
45+
base = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
46+
if (IS_ERR(base))
47+
return PTR_ERR(base);
48+
49+
dvp->reset.rcdev.owner = THIS_MODULE;
50+
dvp->reset.rcdev.nr_resets = NR_RESETS;
51+
dvp->reset.rcdev.ops = &reset_simple_ops;
52+
dvp->reset.rcdev.of_node = pdev->dev.of_node;
53+
dvp->reset.membase = base + DVP_HT_RPI_SW_INIT;
54+
spin_lock_init(&dvp->reset.lock);
55+
56+
ret = devm_reset_controller_register(&pdev->dev, &dvp->reset.rcdev);
57+
if (ret)
58+
return ret;
59+
60+
data->hws[0] = clk_hw_register_gate_parent_data(&pdev->dev,
61+
"hdmi0-108MHz",
62+
&clk_dvp_parent, 0,
63+
base + DVP_HT_RPI_MISC_CONFIG, 3,
64+
CLK_GATE_SET_TO_DISABLE,
65+
&dvp->reset.lock);
66+
if (IS_ERR(data->hws[0]))
67+
return PTR_ERR(data->hws[0]);
68+
69+
data->hws[1] = clk_hw_register_gate_parent_data(&pdev->dev,
70+
"hdmi1-108MHz",
71+
&clk_dvp_parent, 0,
72+
base + DVP_HT_RPI_MISC_CONFIG, 4,
73+
CLK_GATE_SET_TO_DISABLE,
74+
&dvp->reset.lock);
75+
if (IS_ERR(data->hws[1])) {
76+
ret = PTR_ERR(data->hws[1]);
77+
goto unregister_clk0;
78+
}
79+
80+
data->num = NR_CLOCKS;
81+
ret = of_clk_add_hw_provider(pdev->dev.of_node, of_clk_hw_onecell_get,
82+
data);
83+
if (ret)
84+
goto unregister_clk1;
85+
86+
return 0;
87+
88+
unregister_clk1:
89+
clk_hw_unregister_gate(data->hws[1]);
90+
91+
unregister_clk0:
92+
clk_hw_unregister_gate(data->hws[0]);
93+
return ret;
94+
};
95+
96+
static int clk_dvp_remove(struct platform_device *pdev)
97+
{
98+
struct clk_dvp *dvp = platform_get_drvdata(pdev);
99+
struct clk_hw_onecell_data *data = dvp->data;
100+
101+
clk_hw_unregister_gate(data->hws[1]);
102+
clk_hw_unregister_gate(data->hws[0]);
103+
104+
return 0;
105+
}
106+
107+
static const struct of_device_id clk_dvp_dt_ids[] = {
108+
{ .compatible = "brcm,brcm2711-dvp", },
109+
{ /* sentinel */ }
110+
};
111+
112+
static struct platform_driver clk_dvp_driver = {
113+
.probe = clk_dvp_probe,
114+
.remove = clk_dvp_remove,
115+
.driver = {
116+
.name = "brcm2711-dvp",
117+
.of_match_table = clk_dvp_dt_ids,
118+
},
119+
};
120+
module_platform_driver(clk_dvp_driver);

0 commit comments

Comments
 (0)