clk: uniphier: rework UniPhier clk driver
The initial design of the UniPhier clk driver for U-Boot was not very nice. Here is a re-work to sync it with Linux's clk and reset drivers, maximizing the code reuse from Linux's clk data. Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
This commit is contained in:
parent
f666a65824
commit
805dc44cc8
@ -1,13 +1,10 @@
|
|||||||
config CLK_UNIPHIER
|
config CLK_UNIPHIER
|
||||||
bool
|
bool "Clock driver for UniPhier SoCs"
|
||||||
|
depends on ARCH_UNIPHIER
|
||||||
select CLK
|
select CLK
|
||||||
select SPL_CLK
|
select SPL_CLK
|
||||||
|
|
||||||
menu "Clock drivers for UniPhier SoCs"
|
|
||||||
depends on CLK_UNIPHIER
|
|
||||||
|
|
||||||
config CLK_UNIPHIER_MIO
|
|
||||||
bool "Clock driver for UniPhier Media I/O block"
|
|
||||||
default y
|
default y
|
||||||
|
help
|
||||||
endmenu
|
Support for clock controllers on UniPhier SoCs.
|
||||||
|
Say Y if you want to control clocks provided by System Control
|
||||||
|
block, Media I/O block, Peripheral Block.
|
||||||
|
@ -1,3 +1,2 @@
|
|||||||
obj-y += clk-uniphier-core.o
|
obj-y += clk-uniphier-core.o
|
||||||
|
obj-y += clk-uniphier-mio.o
|
||||||
obj-$(CONFIG_CLK_UNIPHIER_MIO) += clk-uniphier-mio.o
|
|
||||||
|
@ -6,11 +6,11 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <common.h>
|
#include <common.h>
|
||||||
|
#include <clk-uclass.h>
|
||||||
|
#include <dm/device.h>
|
||||||
#include <linux/bitops.h>
|
#include <linux/bitops.h>
|
||||||
#include <linux/io.h>
|
#include <linux/io.h>
|
||||||
#include <linux/sizes.h>
|
#include <linux/sizes.h>
|
||||||
#include <clk-uclass.h>
|
|
||||||
#include <dm/device.h>
|
|
||||||
|
|
||||||
#include "clk-uniphier.h"
|
#include "clk-uniphier.h"
|
||||||
|
|
||||||
@ -18,14 +18,116 @@
|
|||||||
* struct uniphier_clk_priv - private data for UniPhier clock driver
|
* struct uniphier_clk_priv - private data for UniPhier clock driver
|
||||||
*
|
*
|
||||||
* @base: base address of the clock provider
|
* @base: base address of the clock provider
|
||||||
* @socdata: SoC specific data
|
* @data: SoC specific data
|
||||||
*/
|
*/
|
||||||
struct uniphier_clk_priv {
|
struct uniphier_clk_priv {
|
||||||
void __iomem *base;
|
void __iomem *base;
|
||||||
const struct uniphier_clk_soc_data *socdata;
|
const struct uniphier_clk_data *data;
|
||||||
};
|
};
|
||||||
|
|
||||||
int uniphier_clk_probe(struct udevice *dev)
|
static int uniphier_clk_enable(struct clk *clk)
|
||||||
|
{
|
||||||
|
struct uniphier_clk_priv *priv = dev_get_priv(clk->dev);
|
||||||
|
unsigned long id = clk->id;
|
||||||
|
const struct uniphier_clk_gate_data *p;
|
||||||
|
|
||||||
|
for (p = priv->data->gate; p->id != UNIPHIER_CLK_ID_END; p++) {
|
||||||
|
u32 val;
|
||||||
|
|
||||||
|
if (p->id != id)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
val = readl(priv->base + p->reg);
|
||||||
|
val |= BIT(p->bit);
|
||||||
|
writel(val, priv->base + p->reg);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
dev_err(priv->dev, "clk_id=%lu was not handled\n", id);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct uniphier_clk_mux_data *
|
||||||
|
uniphier_clk_get_mux_data(struct uniphier_clk_priv *priv, unsigned long id)
|
||||||
|
{
|
||||||
|
const struct uniphier_clk_mux_data *p;
|
||||||
|
|
||||||
|
for (p = priv->data->mux; p->id != UNIPHIER_CLK_ID_END; p++) {
|
||||||
|
if (p->id == id)
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ulong uniphier_clk_get_rate(struct clk *clk)
|
||||||
|
{
|
||||||
|
struct uniphier_clk_priv *priv = dev_get_priv(clk->dev);
|
||||||
|
const struct uniphier_clk_mux_data *mux;
|
||||||
|
u32 val;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
mux = uniphier_clk_get_mux_data(priv, clk->id);
|
||||||
|
if (!mux)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (!mux->nr_muxs) /* fixed-rate */
|
||||||
|
return mux->rates[0];
|
||||||
|
|
||||||
|
val = readl(priv->base + mux->reg);
|
||||||
|
|
||||||
|
for (i = 0; i < mux->nr_muxs; i++)
|
||||||
|
if ((mux->masks[i] & val) == mux->vals[i])
|
||||||
|
return mux->rates[i];
|
||||||
|
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ulong uniphier_clk_set_rate(struct clk *clk, ulong rate)
|
||||||
|
{
|
||||||
|
struct uniphier_clk_priv *priv = dev_get_priv(clk->dev);
|
||||||
|
const struct uniphier_clk_mux_data *mux;
|
||||||
|
u32 val;
|
||||||
|
int i, best_rate_id = -1;
|
||||||
|
ulong best_rate = 0;
|
||||||
|
|
||||||
|
mux = uniphier_clk_get_mux_data(priv, clk->id);
|
||||||
|
if (!mux)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (!mux->nr_muxs) /* fixed-rate */
|
||||||
|
return mux->rates[0];
|
||||||
|
|
||||||
|
/* first, decide the best match rate */
|
||||||
|
for (i = 0; i < mux->nr_muxs; i++) {
|
||||||
|
if (mux->rates[i] > best_rate && mux->rates[i] <= rate) {
|
||||||
|
best_rate = mux->rates[i];
|
||||||
|
best_rate_id = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (best_rate_id < 0)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
val = readl(priv->base + mux->reg);
|
||||||
|
val &= ~mux->masks[best_rate_id];
|
||||||
|
val |= mux->vals[best_rate_id];
|
||||||
|
writel(val, priv->base + mux->reg);
|
||||||
|
|
||||||
|
debug("%s: requested rate = %lu, set rate = %lu\n", __func__,
|
||||||
|
rate, best_rate);
|
||||||
|
|
||||||
|
return best_rate;
|
||||||
|
}
|
||||||
|
|
||||||
|
const struct clk_ops uniphier_clk_ops = {
|
||||||
|
.enable = uniphier_clk_enable,
|
||||||
|
.get_rate = uniphier_clk_get_rate,
|
||||||
|
.set_rate = uniphier_clk_set_rate,
|
||||||
|
};
|
||||||
|
|
||||||
|
static int uniphier_clk_probe(struct udevice *dev)
|
||||||
{
|
{
|
||||||
struct uniphier_clk_priv *priv = dev_get_priv(dev);
|
struct uniphier_clk_priv *priv = dev_get_priv(dev);
|
||||||
fdt_addr_t addr;
|
fdt_addr_t addr;
|
||||||
@ -38,125 +140,11 @@ int uniphier_clk_probe(struct udevice *dev)
|
|||||||
if (!priv->base)
|
if (!priv->base)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
priv->socdata = (void *)dev_get_driver_data(dev);
|
priv->data = (void *)dev_get_driver_data(dev);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int uniphier_clk_enable(struct clk *clk)
|
|
||||||
{
|
|
||||||
struct uniphier_clk_priv *priv = dev_get_priv(clk->dev);
|
|
||||||
const struct uniphier_clk_gate_data *gate = priv->socdata->gate;
|
|
||||||
unsigned int nr_gate = priv->socdata->nr_gate;
|
|
||||||
void __iomem *reg;
|
|
||||||
u32 mask, data, tmp;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
for (i = 0; i < nr_gate; i++) {
|
|
||||||
if (gate[i].index != clk->id)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
reg = priv->base + gate[i].reg;
|
|
||||||
mask = gate[i].mask;
|
|
||||||
data = gate[i].data & mask;
|
|
||||||
|
|
||||||
tmp = readl(reg);
|
|
||||||
tmp &= ~mask;
|
|
||||||
tmp |= data & mask;
|
|
||||||
debug("%s: %p: %08x\n", __func__, reg, tmp);
|
|
||||||
writel(tmp, reg);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static ulong uniphier_clk_get_rate(struct clk *clk)
|
|
||||||
{
|
|
||||||
struct uniphier_clk_priv *priv = dev_get_priv(clk->dev);
|
|
||||||
const struct uniphier_clk_rate_data *rdata = priv->socdata->rate;
|
|
||||||
unsigned int nr_rdata = priv->socdata->nr_rate;
|
|
||||||
void __iomem *reg;
|
|
||||||
u32 mask, data;
|
|
||||||
ulong matched_rate = 0;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
for (i = 0; i < nr_rdata; i++) {
|
|
||||||
if (rdata[i].index != clk->id)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (rdata[i].reg == UNIPHIER_CLK_RATE_IS_FIXED)
|
|
||||||
return rdata[i].rate;
|
|
||||||
|
|
||||||
reg = priv->base + rdata[i].reg;
|
|
||||||
mask = rdata[i].mask;
|
|
||||||
data = rdata[i].data & mask;
|
|
||||||
if ((readl(reg) & mask) == data) {
|
|
||||||
if (matched_rate && rdata[i].rate != matched_rate) {
|
|
||||||
printf("failed to get clk rate for insane register values\n");
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
matched_rate = rdata[i].rate;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
debug("%s: rate = %lu\n", __func__, matched_rate);
|
|
||||||
|
|
||||||
return matched_rate;
|
|
||||||
}
|
|
||||||
|
|
||||||
static ulong uniphier_clk_set_rate(struct clk *clk, ulong rate)
|
|
||||||
{
|
|
||||||
struct uniphier_clk_priv *priv = dev_get_priv(clk->dev);
|
|
||||||
const struct uniphier_clk_rate_data *rdata = priv->socdata->rate;
|
|
||||||
unsigned int nr_rdata = priv->socdata->nr_rate;
|
|
||||||
void __iomem *reg;
|
|
||||||
u32 mask, data, tmp;
|
|
||||||
ulong best_rate = 0;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
/* first, decide the best match rate */
|
|
||||||
for (i = 0; i < nr_rdata; i++) {
|
|
||||||
if (rdata[i].index != clk->id)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (rdata[i].reg == UNIPHIER_CLK_RATE_IS_FIXED)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
if (rdata[i].rate > best_rate && rdata[i].rate <= rate)
|
|
||||||
best_rate = rdata[i].rate;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!best_rate)
|
|
||||||
return -ENODEV;
|
|
||||||
|
|
||||||
debug("%s: requested rate = %lu, set rate = %lu\n", __func__,
|
|
||||||
rate, best_rate);
|
|
||||||
|
|
||||||
/* second, really set registers */
|
|
||||||
for (i = 0; i < nr_rdata; i++) {
|
|
||||||
if (rdata[i].index != clk->id || rdata[i].rate != best_rate)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
reg = priv->base + rdata[i].reg;
|
|
||||||
mask = rdata[i].mask;
|
|
||||||
data = rdata[i].data & mask;
|
|
||||||
|
|
||||||
tmp = readl(reg);
|
|
||||||
tmp &= ~mask;
|
|
||||||
tmp |= data;
|
|
||||||
debug("%s: %p: %08x\n", __func__, reg, tmp);
|
|
||||||
writel(tmp, reg);
|
|
||||||
}
|
|
||||||
|
|
||||||
return best_rate;
|
|
||||||
}
|
|
||||||
|
|
||||||
const struct clk_ops uniphier_clk_ops = {
|
|
||||||
.enable = uniphier_clk_enable,
|
|
||||||
.get_rate = uniphier_clk_get_rate,
|
|
||||||
.set_rate = uniphier_clk_set_rate,
|
|
||||||
};
|
|
||||||
|
|
||||||
static const struct udevice_id uniphier_clk_match[] = {
|
static const struct udevice_id uniphier_clk_match[] = {
|
||||||
{
|
{
|
||||||
.compatible = "socionext,uniphier-sld3-mio-clock",
|
.compatible = "socionext,uniphier-sld3-mio-clock",
|
||||||
|
@ -5,136 +5,81 @@
|
|||||||
* SPDX-License-Identifier: GPL-2.0+
|
* SPDX-License-Identifier: GPL-2.0+
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <dm/device.h>
|
|
||||||
|
|
||||||
#include "clk-uniphier.h"
|
#include "clk-uniphier.h"
|
||||||
|
|
||||||
#define UNIPHIER_MIO_CLK_GATE_SD(ch, idx) \
|
#define UNIPHIER_MIO_CLK_SD_GATE(id, ch) \
|
||||||
{ \
|
UNIPHIER_CLK_GATE((id), 0x20 + 0x200 * (ch), 8)
|
||||||
.index = (idx), \
|
|
||||||
.reg = 0x20 + 0x200 * (ch), \
|
|
||||||
.mask = 0x00000100, \
|
|
||||||
.data = 0x00000100, \
|
|
||||||
}, \
|
|
||||||
{ \
|
|
||||||
.index = (idx), \
|
|
||||||
.reg = 0x110 + 0x200 * (ch), \
|
|
||||||
.mask = 0x00000001, \
|
|
||||||
.data = 0x00000001, \
|
|
||||||
}
|
|
||||||
|
|
||||||
#define UNIPHIER_MIO_CLK_RATE_SD(ch, idx) \
|
#define UNIPHIER_MIO_CLK_USB2(id, ch) \
|
||||||
{ \
|
UNIPHIER_CLK_GATE((id), 0x20 + 0x200 * (ch), 28)
|
||||||
.index = (idx), \
|
|
||||||
.reg = 0x30 + 0x200 * (ch), \
|
|
||||||
.mask = 0x00031300, \
|
|
||||||
.data = 0x00000000, \
|
|
||||||
.rate = 44444444, \
|
|
||||||
}, \
|
|
||||||
{ \
|
|
||||||
.index = (idx), \
|
|
||||||
.reg = 0x30 + 0x200 * (ch), \
|
|
||||||
.mask = 0x00031300, \
|
|
||||||
.data = 0x00010000, \
|
|
||||||
.rate = 33333333, \
|
|
||||||
}, \
|
|
||||||
{ \
|
|
||||||
.index = (idx), \
|
|
||||||
.reg = 0x30 + 0x200 * (ch), \
|
|
||||||
.mask = 0x00031300, \
|
|
||||||
.data = 0x00020000, \
|
|
||||||
.rate = 50000000, \
|
|
||||||
}, \
|
|
||||||
{ \
|
|
||||||
.index = (idx), \
|
|
||||||
.reg = 0x30 + 0x200 * (ch), \
|
|
||||||
.mask = 0x00031300, \
|
|
||||||
.data = 0x00020000, \
|
|
||||||
.rate = 66666666, \
|
|
||||||
}, \
|
|
||||||
{ \
|
|
||||||
.index = (idx), \
|
|
||||||
.reg = 0x30 + 0x200 * (ch), \
|
|
||||||
.mask = 0x00031300, \
|
|
||||||
.data = 0x00001000, \
|
|
||||||
.rate = 100000000, \
|
|
||||||
}, \
|
|
||||||
{ \
|
|
||||||
.index = (idx), \
|
|
||||||
.reg = 0x30 + 0x200 * (ch), \
|
|
||||||
.mask = 0x00031300, \
|
|
||||||
.data = 0x00001100, \
|
|
||||||
.rate = 40000000, \
|
|
||||||
}, \
|
|
||||||
{ \
|
|
||||||
.index = (idx), \
|
|
||||||
.reg = 0x30 + 0x200 * (ch), \
|
|
||||||
.mask = 0x00031300, \
|
|
||||||
.data = 0x00001200, \
|
|
||||||
.rate = 25000000, \
|
|
||||||
}, \
|
|
||||||
{ \
|
|
||||||
.index = (idx), \
|
|
||||||
.reg = 0x30 + 0x200 * (ch), \
|
|
||||||
.mask = 0x00031300, \
|
|
||||||
.data = 0x00001300, \
|
|
||||||
.rate = 22222222, \
|
|
||||||
}
|
|
||||||
|
|
||||||
#define UNIPHIER_MIO_CLK_GATE_USB(ch, idx) \
|
#define UNIPHIER_MIO_CLK_USB2_PHY(id, ch) \
|
||||||
{ \
|
UNIPHIER_CLK_GATE((id), 0x20 + 0x200 * (ch), 29)
|
||||||
.index = (idx), \
|
|
||||||
.reg = 0x20 + 0x200 * (ch), \
|
|
||||||
.mask = 0x30000000, \
|
|
||||||
.data = 0x30000000, \
|
|
||||||
}, \
|
|
||||||
{ \
|
|
||||||
.index = (idx), \
|
|
||||||
.reg = 0x110 + 0x200 * (ch), \
|
|
||||||
.mask = 0x01000000, \
|
|
||||||
.data = 0x01000000, \
|
|
||||||
}, \
|
|
||||||
{ \
|
|
||||||
.index = (idx), \
|
|
||||||
.reg = 0x114 + 0x200 * (ch), \
|
|
||||||
.mask = 0x00000001, \
|
|
||||||
.data = 0x00000001, \
|
|
||||||
}
|
|
||||||
|
|
||||||
#define UNIPHIER_MIO_CLK_GATE_DMAC(idx) \
|
#define UNIPHIER_MIO_CLK_DMAC(id) \
|
||||||
|
UNIPHIER_CLK_GATE((id), 0x20, 25)
|
||||||
|
|
||||||
|
#define UNIPHIER_MIO_CLK_SD_MUX(_id, ch) \
|
||||||
{ \
|
{ \
|
||||||
.index = (idx), \
|
.id = (_id), \
|
||||||
.reg = 0x20, \
|
.nr_muxs = 8, \
|
||||||
.mask = 0x02000000, \
|
.reg = 0x30 + 0x200 * (ch), \
|
||||||
.data = 0x02000000, \
|
.masks = { \
|
||||||
|
0x00031000, \
|
||||||
|
0x00031000, \
|
||||||
|
0x00031000, \
|
||||||
|
0x00031000, \
|
||||||
|
0x00001300, \
|
||||||
|
0x00001300, \
|
||||||
|
0x00001300, \
|
||||||
|
0x00001300, \
|
||||||
|
}, \
|
||||||
|
.vals = { \
|
||||||
|
0x00000000, \
|
||||||
|
0x00010000, \
|
||||||
|
0x00020000, \
|
||||||
|
0x00030000, \
|
||||||
|
0x00001000, \
|
||||||
|
0x00001100, \
|
||||||
|
0x00001200, \
|
||||||
|
0x00001300, \
|
||||||
|
}, \
|
||||||
|
.rates = { \
|
||||||
|
44444444, \
|
||||||
|
33333333, \
|
||||||
|
50000000, \
|
||||||
|
66666666, \
|
||||||
|
100000000, \
|
||||||
|
40000000, \
|
||||||
|
25000000, \
|
||||||
|
22222222, \
|
||||||
}, \
|
}, \
|
||||||
{ \
|
|
||||||
.index = (idx), \
|
|
||||||
.reg = 0x110, \
|
|
||||||
.mask = 0x00020000, \
|
|
||||||
.data = 0x00020000, \
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct uniphier_clk_gate_data uniphier_mio_clk_gate[] = {
|
static const struct uniphier_clk_gate_data uniphier_mio_clk_gate[] = {
|
||||||
UNIPHIER_MIO_CLK_GATE_SD(0, 0),
|
UNIPHIER_MIO_CLK_SD_GATE(0, 0),
|
||||||
UNIPHIER_MIO_CLK_GATE_SD(1, 1),
|
UNIPHIER_MIO_CLK_SD_GATE(1, 1),
|
||||||
UNIPHIER_MIO_CLK_GATE_SD(2, 2), /* for PH1-Pro4 only */
|
UNIPHIER_MIO_CLK_SD_GATE(2, 2), /* for PH1-Pro4 only */
|
||||||
UNIPHIER_MIO_CLK_GATE_USB(0, 3),
|
UNIPHIER_MIO_CLK_DMAC(7),
|
||||||
UNIPHIER_MIO_CLK_GATE_USB(1, 4),
|
UNIPHIER_MIO_CLK_USB2(8, 0),
|
||||||
UNIPHIER_MIO_CLK_GATE_USB(2, 5),
|
UNIPHIER_MIO_CLK_USB2(9, 1),
|
||||||
UNIPHIER_MIO_CLK_GATE_DMAC(6),
|
UNIPHIER_MIO_CLK_USB2(10, 2),
|
||||||
UNIPHIER_MIO_CLK_GATE_USB(3, 7), /* for PH1-sLD3 only */
|
UNIPHIER_MIO_CLK_USB2(11, 3), /* for PH1-sLD3 only */
|
||||||
|
UNIPHIER_MIO_CLK_USB2_PHY(12, 0),
|
||||||
|
UNIPHIER_MIO_CLK_USB2_PHY(13, 1),
|
||||||
|
UNIPHIER_MIO_CLK_USB2_PHY(14, 2),
|
||||||
|
UNIPHIER_MIO_CLK_USB2_PHY(15, 3), /* for PH1-sLD3 only */
|
||||||
|
UNIPHIER_CLK_END
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct uniphier_clk_rate_data uniphier_mio_clk_rate[] = {
|
static const struct uniphier_clk_mux_data uniphier_mio_clk_mux[] = {
|
||||||
UNIPHIER_MIO_CLK_RATE_SD(0, 0),
|
UNIPHIER_MIO_CLK_SD_MUX(0, 0),
|
||||||
UNIPHIER_MIO_CLK_RATE_SD(1, 1),
|
UNIPHIER_MIO_CLK_SD_MUX(1, 1),
|
||||||
UNIPHIER_MIO_CLK_RATE_SD(2, 2), /* for PH1-Pro4 only */
|
UNIPHIER_MIO_CLK_SD_MUX(2, 2), /* for PH1-Pro4 only */
|
||||||
|
UNIPHIER_CLK_END
|
||||||
};
|
};
|
||||||
|
|
||||||
const struct uniphier_clk_soc_data uniphier_mio_clk_data = {
|
const struct uniphier_clk_data uniphier_mio_clk_data = {
|
||||||
.gate = uniphier_mio_clk_gate,
|
.gate = uniphier_mio_clk_gate,
|
||||||
.nr_gate = ARRAY_SIZE(uniphier_mio_clk_gate),
|
.mux = uniphier_mio_clk_mux,
|
||||||
.rate = uniphier_mio_clk_rate,
|
|
||||||
.nr_rate = ARRAY_SIZE(uniphier_mio_clk_rate),
|
|
||||||
};
|
};
|
||||||
|
@ -10,36 +10,46 @@
|
|||||||
|
|
||||||
#include <linux/kernel.h>
|
#include <linux/kernel.h>
|
||||||
|
|
||||||
|
#define UNIPHIER_CLK_MAX_NR_MUXS 8
|
||||||
|
|
||||||
struct uniphier_clk_gate_data {
|
struct uniphier_clk_gate_data {
|
||||||
int index;
|
unsigned int id;
|
||||||
unsigned int reg;
|
unsigned int reg;
|
||||||
u32 mask;
|
unsigned int bit;
|
||||||
u32 data;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct uniphier_clk_rate_data {
|
struct uniphier_clk_mux_data {
|
||||||
int index;
|
unsigned int id;
|
||||||
|
unsigned int nr_muxs;
|
||||||
unsigned int reg;
|
unsigned int reg;
|
||||||
#define UNIPHIER_CLK_RATE_IS_FIXED UINT_MAX
|
unsigned int masks[UNIPHIER_CLK_MAX_NR_MUXS];
|
||||||
u32 mask;
|
unsigned int vals[UNIPHIER_CLK_MAX_NR_MUXS];
|
||||||
u32 data;
|
unsigned long rates[UNIPHIER_CLK_MAX_NR_MUXS];
|
||||||
unsigned long rate;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct uniphier_clk_soc_data {
|
struct uniphier_clk_data {
|
||||||
const struct uniphier_clk_gate_data *gate;
|
const struct uniphier_clk_gate_data *gate;
|
||||||
unsigned int nr_gate;
|
const struct uniphier_clk_mux_data *mux;
|
||||||
const struct uniphier_clk_rate_data *rate;
|
|
||||||
unsigned int nr_rate;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#define UNIPHIER_CLK_FIXED_RATE(i, f) \
|
#define UNIPHIER_CLK_ID_END (unsigned int)(-1)
|
||||||
|
|
||||||
|
#define UNIPHIER_CLK_END \
|
||||||
|
{ .id = UNIPHIER_CLK_ID_END }
|
||||||
|
|
||||||
|
#define UNIPHIER_CLK_GATE(_id, _reg, _bit) \
|
||||||
{ \
|
{ \
|
||||||
.index = i, \
|
.id = (_id), \
|
||||||
.reg = UNIPHIER_CLK_RATE_IS_FIXED, \
|
.reg = (_reg), \
|
||||||
.rate = f, \
|
.bit = (_bit), \
|
||||||
}
|
}
|
||||||
|
|
||||||
extern const struct uniphier_clk_soc_data uniphier_mio_clk_data;
|
#define UNIPHIER_CLK_FIXED_RATE(_id, _rate) \
|
||||||
|
{ \
|
||||||
|
.id = (_id), \
|
||||||
|
.rates = {(_reg),}, \
|
||||||
|
}
|
||||||
|
|
||||||
|
extern const struct uniphier_clk_data uniphier_mio_clk_data;
|
||||||
|
|
||||||
#endif /* __CLK_UNIPHIER_H__ */
|
#endif /* __CLK_UNIPHIER_H__ */
|
||||||
|
Loading…
Reference in New Issue
Block a user