• R/O
  • HTTP
  • SSH
  • HTTPS

Commit

Tags
No Tags

Frequently used words (click to add to your profile)

javac++androidlinuxc#windowsobjective-ccocoa誰得qtpythonphprubygameguibathyscaphec計画中(planning stage)翻訳omegatframeworktwitterdomtestvb.netdirectxゲームエンジンbtronarduinopreviewer

Commit MetaInfo

Revisioneafc727f106e09a9ded921f5dc23daa2015cad3c (tree)
Time2020-07-26 17:58:23
AuthorYoshinori Sato <ysato@user...>
CommiterYoshinori Sato

Log Message

Add RX62N CPG

Change Summary

Incremental Difference

--- a/drivers/clk/Kconfig
+++ b/drivers/clk/Kconfig
@@ -187,4 +187,10 @@ config SANDBOX_CLK_CCF
187187 Enable this option if you want to test the Linux kernel's Common
188188 Clock Framework [CCF] code in U-Boot's Sandbox clock driver.
189189
190+config CLK_RX62N
191+ bool "Enable clock driver support for Renesas RX62N"
192+ depends on CLK && RX
193+ help
194+ Enable this to support the clocks on Renesas RX62N MCU.
195+
190196 endmenu
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@ -47,3 +47,4 @@ obj-$(CONFIG_STM32H7) += clk_stm32h7.o
4747 obj-$(CONFIG_CLK_TI_SCI) += clk-ti-sci.o
4848 obj-$(CONFIG_CLK_VERSAL) += clk_versal.o
4949 obj-$(CONFIG_CLK_CDCE9XX) += clk-cdce9xx.o
50+obj-$(CONFIG_CLK_RX62N) += rx62n-cpg.o
--- /dev/null
+++ b/drivers/clk/rx62n-cpg.c
@@ -0,0 +1,109 @@
1+// SPDX-License-Identifier: GPL-2.0+
2+/*
3+ * Copyright (c) 2020 Yoshinori Sato <ysato@users.sourceforge.jp>
4+ */
5+
6+#include <common.h>
7+#include <clk-uclass.h>
8+#include <div64.h>
9+#include <dm.h>
10+#include <linux/err.h>
11+#include <asm/io.h>
12+
13+struct rx62n_cpg_priv {
14+ struct clk parent;
15+ void *base;
16+ int out;
17+};
18+
19+static ulong rx62n_cpg_get_rate(struct clk *clk)
20+{
21+ struct rx62n_cpg_priv *priv = dev_get_priv(clk->dev);
22+ u64 rate;
23+ int shift;
24+ int divrate;
25+
26+ rate = clk_get_rate(&priv->parent);
27+ if (IS_ERR_VALUE(rate))
28+ return rate;
29+ shift = 8 * (priv->out + 1);
30+ divrate = readl(priv->base);
31+ divrate = (divrate >> shift) & 0x0f;
32+ divrate = 1 << divrate;
33+
34+ do_div(rate, divrate);
35+ return rate;
36+}
37+
38+static ulong rx62n_cpg_set_rate(struct clk *clk, ulong rate)
39+{
40+ struct rx62n_cpg_priv *priv = dev_get_priv(clk->dev);
41+ u32 sckcr;
42+ int shift;
43+ u64 divrate;
44+ int i;
45+
46+ divrate = clk_get_rate(&priv->parent);
47+ if (IS_ERR_VALUE(divrate))
48+ return divrate;
49+
50+ shift = 8 * (priv->out + 1);
51+ do_div(divrate, rate);
52+ for (i = 0; i < 4; i++) {
53+ if (divrate == 1) {
54+ sckcr = readl(priv->base);
55+ sckcr &= ~(0x0f << shift);
56+ sckcr |= i << shift;
57+ writel(sckcr, priv->base);
58+ return 0;
59+ }
60+ divrate >>= 1;
61+ }
62+ return -EINVAL;
63+}
64+
65+const struct clk_ops rx62n_cpg_ops = {
66+ .get_rate = rx62n_cpg_get_rate,
67+ .set_rate = rx62n_cpg_set_rate,
68+};
69+
70+
71+static int rx62n_cpg_probe(struct udevice *dev)
72+{
73+ struct rx62n_cpg_priv *priv = dev_get_priv(dev);
74+ int err;
75+ fdt_addr_t addr;
76+ static char *names[] = {"pck", "bck", "ick"};
77+ int id;
78+
79+ addr = dev_read_addr(dev);
80+ if (addr == FDT_ADDR_T_NONE)
81+ return -EINVAL;
82+ priv->base = (void *)addr;
83+ err = clk_get_by_index(dev, 0, &priv->parent);
84+ if (err)
85+ return err;
86+ for (id = 0; id < 3; id++) {
87+ if (strcmp(dev->name, names[id]) == 0) {
88+ priv->out = id;
89+ break;
90+ }
91+ }
92+ return 0;
93+}
94+
95+static const struct udevice_id rx62n_cpg_ids[] = {
96+ {
97+ .compatible = "renesas,rx62n-cpg",
98+ },
99+ { }
100+};
101+
102+U_BOOT_DRIVER(rx62n_cpg) = {
103+ .name = "rx62n_cpg",
104+ .id = UCLASS_CLK,
105+ .of_match = rx62n_cpg_ids,
106+ .ops = &rx62n_cpg_ops,
107+ .probe = rx62n_cpg_probe,
108+ .priv_auto_alloc_size = sizeof(struct rx62n_cpg_priv),
109+};