2 * Copyright (C) 2016 Imagination Technologies
4 * SPDX-License-Identifier: GPL-2.0
8 #include <clk-uclass.h>
10 #include <dt-bindings/clock/boston-clock.h>
15 struct regmap *regmap;
18 #define BOSTON_PLAT_MMCMDIV 0x30
19 # define BOSTON_PLAT_MMCMDIV_CLK0DIV (0xff << 0)
20 # define BOSTON_PLAT_MMCMDIV_INPUT (0xff << 8)
21 # define BOSTON_PLAT_MMCMDIV_MUL (0xff << 16)
22 # define BOSTON_PLAT_MMCMDIV_CLK1DIV (0xff << 24)
24 static uint32_t ext_field(uint32_t val, uint32_t mask)
26 return (val & mask) >> (ffs(mask) - 1);
29 static ulong clk_boston_get_rate(struct clk *clk)
31 struct clk_boston *state = dev_get_platdata(clk->dev);
32 uint32_t in_rate, mul, div;
36 err = regmap_read(state->regmap, BOSTON_PLAT_MMCMDIV, &mmcmdiv);
40 in_rate = ext_field(mmcmdiv, BOSTON_PLAT_MMCMDIV_INPUT);
41 mul = ext_field(mmcmdiv, BOSTON_PLAT_MMCMDIV_MUL);
45 div = ext_field(mmcmdiv, BOSTON_PLAT_MMCMDIV_CLK0DIV);
48 div = ext_field(mmcmdiv, BOSTON_PLAT_MMCMDIV_CLK1DIV);
54 return (in_rate * mul * 1000000) / div;
57 const struct clk_ops clk_boston_ops = {
58 .get_rate = clk_boston_get_rate,
61 static int clk_boston_ofdata_to_platdata(struct udevice *dev)
63 struct clk_boston *state = dev_get_platdata(dev);
64 struct udevice *syscon;
67 err = uclass_get_device_by_phandle(UCLASS_SYSCON, dev,
70 error("unable to find syscon device\n");
74 state->regmap = syscon_get_regmap(syscon);
76 error("unable to find regmap\n");
83 static const struct udevice_id clk_boston_match[] = {
85 .compatible = "img,boston-clock",
90 U_BOOT_DRIVER(clk_boston) = {
91 .name = "boston_clock",
93 .of_match = clk_boston_match,
94 .ofdata_to_platdata = clk_boston_ofdata_to_platdata,
95 .platdata_auto_alloc_size = sizeof(struct clk_boston),
96 .ops = &clk_boston_ops,