diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2026-09-13 12:27:00 -0700 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2026-09-13 12:27:00 -0700 |
| commit | 22098763a10d9c1340827fcf6edab66f153b27f0 (patch) | |
| tree | 3962f95a34df034652ff93686cdd156c7197f2d9 /drivers/clk/sprd | |
| download | linux-stable-22098763a10d9c1340827fcf6edab66f153b27f0.tar.gz linux-stable-22098763a10d9c1340827fcf6edab66f153b27f0.zip | |
Merge tag 'trace-v7.3-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/trace/linux-tracegrafted
Pull tracing fixes from Steven Rostedt:
- Don't destroy user event fields when removal fails
User event fields are destroyed before the event is removed from
visibility. But that can fail leaving the still visible event with no
fields. Move the destroying of the fields to after the event is
successfully removed from visibility.
- Initialize function graph state is fork before calling
copy_exec_state()
For non-CLONE_VM forks, copy_exec_state() allocates a new
task_exec_state. If that allocation fails, ftrace_graph_exit_task()
will free the tasks ret_stack pointer. Since that pointer is still
using the parent's ret_stack, it mistakenly frees the parent's
pointer too.
Call ftrace_graph_init() on the task first which will NULL out the
new tasks's ret_stack and if the copy fails, it will not free
anything.
- Remove FGRAPH_MAX_INDEX
The macro FGRAPH_MAX_INDEX was added but never used. Remove it.
- Save ent_size in function graph printing of nested functions
The function graph tracer needs to look at the next event to see if
the next event is the return of the current function entry. If it is,
it prints a single line:
ktime_get();
Otherwise it prints it like a nested function:
tick_nohz_irq_exit() {
ktime_get();
kcpustat_irq_exit();
}
In order to look at the next event, it must save the current event so
that it has the information to print from it. It saves the event in
the iterator descriptor called "ent". What it doesn't save is the
ent_size of the event which is now used to know if the function graph
arguments are to be printed. The peek doesn't save the size so the
size used happens to be that of the size of the last event that was
seen.
Save the entry event size in the iterator descriptor so that the
correct size is used.
- Fix several errors with freeing data in the histogram code
The histogram code had a lot of leaked or or incorrect accounting
when failures happen. Correct them.
- Fix histogram regression of .percent and .graph modifiers
Up until 6.3 histogram values could have "percent" or "graph"
modifiers that changed how they were printed. But a change that added
restricting histograms values from being strings, stack traces and
other modifiers inadvertently prevented them from using the percent
and graph modifiers, which were legal use cases for values.
Put back the percent and graph modifiers.
- Fix various typos in the comments
- Set the trace_clock before initializing a histogram with clock
argument
The histogram API allows the user to specific which trace clock to
use via a "clock=" string. The histogram is set up first before the
clock is checked. If the passed in clock is not valid, it exits
without fully fixing up the histogram leaving it on the list and a
use-after-free can trigger.
Update the clock argument first and if it fails then exit gracefully
before the histogram trigger is placed on any lists.
- Restore :mod: trailer after parsing in ftrace_set_clr_event
The function ftrace_set_clr_event() modifies the parse string and
needs to put it back to what was passed in. It searches for ":mod:"
via a strsep() but fails to put back the first ':' in the string.
Add back the ':' in the passed in string.
- Take trace_array reference when opening a tracer options file
The options files are dynamically created and some tracers add their
own options. When a tracer adds their own list of options, the
trace_array holding them has an array to hold the list of options for
each tracer. This array increases in size via a krealloc(), and the
new entry gets a newly allocated array to hold the options of the new
tracer being added.
The element in each entry of the tracer's option array holds a
pointer back to the trace_array, a pointer to the tracer it is
associated to, a pointer to the flags of the option.
The issue is that these arrays are freed when the trace_array is
freed when its instance it represents is removed from the instances
directory. There's a race that an open of one of these options files
can happen when the instance is being removed.
Add a new helper function to be called by the open function of the
options file to iterate all existing trace_arrays under a lock and
find the one that has the given option element in one of it's tracer
arrays. If found, then update the associated trace_array's reference
counter to keep it from being freed. If not found, have the open call
return -ENODEV.
- Disable interrupts when acquiring the lock in rb_wake_up_waiters()
The function rb_wake_up_waiters() assumes it will be called in
interrupt context and does not disable irqs when taking
cpu_buffer->reader_lock, which can be called in hard interrupt
context. The issue is in PREEMPT_RT, this function is called in
thread context leaving this lock open to a deadlock.
Take the lock with interrupts disabled.
- Use rcu_assign_pointer() for tmp_ops filter hash
The tmp_ops used in update_ftrace_direct_mod() assigns its
filter_hash field directly, but that field is annotated as __rcu and
sparse complains. Assign it with rcu_assign_pointer()
- Fix use-after-free in enable_trigger_private_data_free()
The trace_event_call is accessed through the event_trigger_data's
trace_event_file pointer to put the trace_event_call on freeing. The
issue is that the trace_event_file data may have been freed already
causing a use-after-free. Add a field to the event_trigger_data that
points directly to the trace_event_call so that it can decrement its
reference directly without needing to go through the
trace_event_file.
- Fix accounting of buffer data remote headers
trace_buffer_desc_size() and trace_remote_alloc_buffer() undercount
the number of pages is needed for the asked for size as it doesn't
take into account the meta data on each page. Add a helper function
to do the calculation properly and use that in these functions.
- Catch nr_page_va overflow in ring_buffer_desc sizing
The number of pages per remote ring buffer is capped by
ring_buffer_desc::nr_page_va (32 bits). A buffer_size large enough to
overflow that field would silently allocate a descriptor smaller than
what was asked for.
- Do not resize the subbuf order if any per_cpu buffer is disabled
The mmapping of ring buffers disables resizing the subbuffers, but it
is done per-cpu whereas the subbuf size change is done for all the
per_cpu buffers under the buffer->mutex. It could change the size of
some while the mapping is happening on others. Have the resize of the
subbuf order check all the per_cpu buffers under the lock to see if
any of them is disabled before starting and causing an inconsistency
between buffers that are being mapped.
* tag 'trace-v7.3-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/trace/linux-trace: (25 commits)
ring-buffer: Check resize_disabled before publishing the new subbuf order
tracing/remotes: Catch nr_page_va overflow in ring_buffer_desc sizing
tracing/remotes: Account for ring buffer page header in size calculation
tracing: Don't dereference trace_event_file in deferred trigger free
ftrace: Use rcu_assign_pointer() for tmp_ops filter hash
ring-buffer: Acquire the lock with irqsave in rb_wake_up_waiters()
tracing: Take trace_array reference when opening a tracer options file
tracing: Fix ring_buffer_read_page_size() kernel-doc
tracing: Restore :mod: trailer after parsing in ftrace_set_clr_event()
tracing: Fix memory corruption from a "STACKTRACE" histogram key
tracing: Fix memory corruption from the histogram stacktrace modifier
tracing: Undo the registration when enabling the histogram trigger fails
tracing: Take the reference before publishing the named histogram trigger
tracing: Set the trace clock before registering the histogram trigger
tracing: Fix typo "preceeded" in comment
tracing: Fix typo "availabe" in comment
tracing: Let histogram values keep the percent and graph modifiers
tracing: Keep the entry count when the histogram stats allocation fails
tracing: Free histogram the field rejected for a bad modifier
tracing: Free histogram the var ref when its initialization fails
...
Diffstat (limited to 'drivers/clk/sprd')
| -rw-r--r-- | drivers/clk/sprd/Kconfig | 32 | ||||
| -rw-r--r-- | drivers/clk/sprd/Makefile | 14 | ||||
| -rw-r--r-- | drivers/clk/sprd/common.c | 113 | ||||
| -rw-r--r-- | drivers/clk/sprd/common.h | 38 | ||||
| -rw-r--r-- | drivers/clk/sprd/composite.c | 59 | ||||
| -rw-r--r-- | drivers/clk/sprd/composite.h | 86 | ||||
| -rw-r--r-- | drivers/clk/sprd/div.c | 80 | ||||
| -rw-r--r-- | drivers/clk/sprd/div.h | 85 | ||||
| -rw-r--r-- | drivers/clk/sprd/gate.c | 135 | ||||
| -rw-r--r-- | drivers/clk/sprd/gate.h | 168 | ||||
| -rw-r--r-- | drivers/clk/sprd/mux.c | 76 | ||||
| -rw-r--r-- | drivers/clk/sprd/mux.h | 88 | ||||
| -rw-r--r-- | drivers/clk/sprd/pll.c | 263 | ||||
| -rw-r--r-- | drivers/clk/sprd/pll.h | 127 | ||||
| -rw-r--r-- | drivers/clk/sprd/sc9860-clk.c | 2049 | ||||
| -rw-r--r-- | drivers/clk/sprd/sc9863a-clk.c | 1805 | ||||
| -rw-r--r-- | drivers/clk/sprd/ums512-clk.c | 2201 |
17 files changed, 7419 insertions, 0 deletions
diff --git a/drivers/clk/sprd/Kconfig b/drivers/clk/sprd/Kconfig new file mode 100644 index 000000000..2f19c8d58 --- /dev/null +++ b/drivers/clk/sprd/Kconfig @@ -0,0 +1,32 @@ +# SPDX-License-Identifier: GPL-2.0-only +config SPRD_COMMON_CLK + tristate "Clock support for Spreadtrum SoCs" + depends on ARCH_SPRD || COMPILE_TEST + default ARCH_SPRD + select REGMAP_MMIO + +if SPRD_COMMON_CLK + +# SoC Drivers + +config SPRD_SC9860_CLK + tristate "Support for the Spreadtrum SC9860 clocks" + depends on (ARM64 && ARCH_SPRD) || COMPILE_TEST + default ARM64 && ARCH_SPRD + +config SPRD_SC9863A_CLK + tristate "Support for the Spreadtrum SC9863A clocks" + depends on (ARM64 && ARCH_SPRD) || COMPILE_TEST + default ARM64 && ARCH_SPRD + help + Support for the global clock controller on sc9863a devices. + Say Y if you want to use peripheral devices on sc9863a SoC. + +config SPRD_UMS512_CLK + tristate "Support for the Spreadtrum UMS512 clocks" + depends on (ARM64 && ARCH_SPRD) || COMPILE_TEST + default ARM64 && ARCH_SPRD + help + Support for the global clock controller on ums512 devices. + Say Y if you want to use peripheral devices on ums512 SoC. +endif diff --git a/drivers/clk/sprd/Makefile b/drivers/clk/sprd/Makefile new file mode 100644 index 000000000..f25b2c390 --- /dev/null +++ b/drivers/clk/sprd/Makefile @@ -0,0 +1,14 @@ +# SPDX-License-Identifier: GPL-2.0-only +obj-$(CONFIG_SPRD_COMMON_CLK) += clk-sprd.o + +clk-sprd-y += common.o +clk-sprd-y += gate.o +clk-sprd-y += mux.o +clk-sprd-y += div.o +clk-sprd-y += composite.o +clk-sprd-y += pll.o + +## SoC support +obj-$(CONFIG_SPRD_SC9860_CLK) += sc9860-clk.o +obj-$(CONFIG_SPRD_SC9863A_CLK) += sc9863a-clk.o +obj-$(CONFIG_SPRD_UMS512_CLK) += ums512-clk.o diff --git a/drivers/clk/sprd/common.c b/drivers/clk/sprd/common.c new file mode 100644 index 000000000..0f2181617 --- /dev/null +++ b/drivers/clk/sprd/common.c @@ -0,0 +1,113 @@ +// SPDX-License-Identifier: GPL-2.0 +// +// Spreadtrum clock infrastructure +// +// Copyright (C) 2017 Spreadtrum, Inc. +// Author: Chunyan Zhang <chunyan.zhang@spreadtrum.com> + +#include <linux/mfd/syscon.h> +#include <linux/module.h> +#include <linux/of_address.h> +#include <linux/platform_device.h> +#include <linux/regmap.h> + +#include "common.h" + +static const struct regmap_config sprdclk_regmap_config = { + .reg_bits = 32, + .reg_stride = 4, + .val_bits = 32, + .fast_io = true, +}; + +static void sprd_clk_set_regmap(const struct sprd_clk_desc *desc, + struct regmap *regmap) +{ + int i; + struct sprd_clk_common *cclk; + + for (i = 0; i < desc->num_clk_clks; i++) { + cclk = desc->clk_clks[i]; + if (!cclk) + continue; + + cclk->regmap = regmap; + } +} + +int sprd_clk_regmap_init(struct platform_device *pdev, + const struct sprd_clk_desc *desc) +{ + void __iomem *base; + struct device *dev = &pdev->dev; + struct device_node *node = dev->of_node, *np; + struct regmap *regmap; + struct resource *res; + struct regmap_config reg_config = sprdclk_regmap_config; + + if (of_property_present(node, "sprd,syscon")) { + regmap = syscon_regmap_lookup_by_phandle(node, "sprd,syscon"); + if (IS_ERR(regmap)) { + pr_err("%s: failed to get syscon regmap\n", __func__); + return PTR_ERR(regmap); + } + } else if (of_device_is_compatible(np = of_get_parent(node), "syscon") || + (of_node_put(np), 0)) { + regmap = device_node_to_regmap(np); + of_node_put(np); + if (IS_ERR(regmap)) { + dev_err(dev, "failed to get regmap from its parent.\n"); + return PTR_ERR(regmap); + } + } else { + base = devm_platform_get_and_ioremap_resource(pdev, 0, &res); + if (IS_ERR(base)) + return PTR_ERR(base); + + reg_config.max_register = resource_size(res) - reg_config.reg_stride; + + regmap = devm_regmap_init_mmio(&pdev->dev, base, + ®_config); + if (IS_ERR(regmap)) { + pr_err("failed to init regmap\n"); + return PTR_ERR(regmap); + } + } + + sprd_clk_set_regmap(desc, regmap); + + return 0; +} +EXPORT_SYMBOL_GPL(sprd_clk_regmap_init); + +int sprd_clk_probe(struct device *dev, struct clk_hw_onecell_data *clkhw) +{ + int i, ret; + struct clk_hw *hw; + + for (i = 0; i < clkhw->num; i++) { + const char *name; + + hw = clkhw->hws[i]; + if (!hw) + continue; + + name = hw->init->name; + ret = devm_clk_hw_register(dev, hw); + if (ret) { + dev_err(dev, "Couldn't register clock %d - %s\n", + i, name); + return ret; + } + } + + ret = devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get, clkhw); + if (ret) + dev_err(dev, "Failed to add clock provider\n"); + + return ret; +} +EXPORT_SYMBOL_GPL(sprd_clk_probe); + +MODULE_DESCRIPTION("Spreadtrum clock infrastructure"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/clk/sprd/common.h b/drivers/clk/sprd/common.h new file mode 100644 index 000000000..1d077b39c --- /dev/null +++ b/drivers/clk/sprd/common.h @@ -0,0 +1,38 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +// +// Spreadtrum clock infrastructure +// +// Copyright (C) 2017 Spreadtrum, Inc. +// Author: Chunyan Zhang <chunyan.zhang@spreadtrum.com> + +#ifndef _SPRD_CLK_COMMON_H_ +#define _SPRD_CLK_COMMON_H_ + +#include <linux/clk-provider.h> +#include <linux/of_platform.h> +#include <linux/regmap.h> + +struct device_node; + +struct sprd_clk_common { + struct regmap *regmap; + u32 reg; + struct clk_hw hw; +}; + +struct sprd_clk_desc { + struct sprd_clk_common **clk_clks; + unsigned long num_clk_clks; + struct clk_hw_onecell_data *hw_clks; +}; + +static inline struct sprd_clk_common * + hw_to_sprd_clk_common(const struct clk_hw *hw) +{ + return container_of(hw, struct sprd_clk_common, hw); +} +int sprd_clk_regmap_init(struct platform_device *pdev, + const struct sprd_clk_desc *desc); +int sprd_clk_probe(struct device *dev, struct clk_hw_onecell_data *clkhw); + +#endif /* _SPRD_CLK_COMMON_H_ */ diff --git a/drivers/clk/sprd/composite.c b/drivers/clk/sprd/composite.c new file mode 100644 index 000000000..ad6b6383e --- /dev/null +++ b/drivers/clk/sprd/composite.c @@ -0,0 +1,59 @@ +// SPDX-License-Identifier: GPL-2.0 +// +// Spreadtrum composite clock driver +// +// Copyright (C) 2017 Spreadtrum, Inc. +// Author: Chunyan Zhang <chunyan.zhang@spreadtrum.com> + +#include <linux/clk-provider.h> + +#include "composite.h" + +static int sprd_comp_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) +{ + struct sprd_comp *cc = hw_to_sprd_comp(hw); + + return divider_determine_rate(hw, req, NULL, cc->div.width, 0); +} + +static unsigned long sprd_comp_recalc_rate(struct clk_hw *hw, + unsigned long parent_rate) +{ + struct sprd_comp *cc = hw_to_sprd_comp(hw); + + return sprd_div_helper_recalc_rate(&cc->common, &cc->div, parent_rate); +} + +static int sprd_comp_set_rate(struct clk_hw *hw, unsigned long rate, + unsigned long parent_rate) +{ + struct sprd_comp *cc = hw_to_sprd_comp(hw); + + return sprd_div_helper_set_rate(&cc->common, &cc->div, + rate, parent_rate); +} + +static u8 sprd_comp_get_parent(struct clk_hw *hw) +{ + struct sprd_comp *cc = hw_to_sprd_comp(hw); + + return sprd_mux_helper_get_parent(&cc->common, &cc->mux); +} + +static int sprd_comp_set_parent(struct clk_hw *hw, u8 index) +{ + struct sprd_comp *cc = hw_to_sprd_comp(hw); + + return sprd_mux_helper_set_parent(&cc->common, &cc->mux, index); +} + +const struct clk_ops sprd_comp_ops = { + .get_parent = sprd_comp_get_parent, + .set_parent = sprd_comp_set_parent, + + .determine_rate = sprd_comp_determine_rate, + .recalc_rate = sprd_comp_recalc_rate, + .set_rate = sprd_comp_set_rate, +}; +EXPORT_SYMBOL_GPL(sprd_comp_ops); diff --git a/drivers/clk/sprd/composite.h b/drivers/clk/sprd/composite.h new file mode 100644 index 000000000..15cec97d2 --- /dev/null +++ b/drivers/clk/sprd/composite.h @@ -0,0 +1,86 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +// +// Spreadtrum composite clock driver +// +// Copyright (C) 2017 Spreadtrum, Inc. +// Author: Chunyan Zhang <chunyan.zhang@spreadtrum.com> + +#ifndef _SPRD_COMPOSITE_H_ +#define _SPRD_COMPOSITE_H_ + +#include "common.h" +#include "mux.h" +#include "div.h" + +struct sprd_comp { + struct sprd_mux_ssel mux; + struct sprd_div_internal div; + struct sprd_clk_common common; +}; + +#define SPRD_COMP_CLK_HW_INIT_FN(_struct, _name, _parent, _reg, _table, \ + _mshift, _mwidth, _doffset, _dshift, \ + _dwidth, _flags, _fn) \ + struct sprd_comp _struct = { \ + .mux = _SPRD_MUX_CLK(_mshift, _mwidth, _table), \ + .div = _SPRD_DIV_CLK(_doffset, _dshift, _dwidth), \ + .common = { \ + .regmap = NULL, \ + .reg = _reg, \ + .hw.init = _fn(_name, _parent, \ + &sprd_comp_ops, _flags), \ + } \ + } + +#define SPRD_COMP_CLK_TABLE(_struct, _name, _parent, _reg, _table, \ + _mshift, _mwidth, _dshift, _dwidth, _flags) \ + SPRD_COMP_CLK_HW_INIT_FN(_struct, _name, _parent, _reg, _table, \ + _mshift, _mwidth, 0x0, _dshift, \ + _dwidth, _flags, CLK_HW_INIT_PARENTS) + +#define SPRD_COMP_CLK(_struct, _name, _parent, _reg, _mshift, \ + _mwidth, _dshift, _dwidth, _flags) \ + SPRD_COMP_CLK_TABLE(_struct, _name, _parent, _reg, NULL, \ + _mshift, _mwidth, _dshift, _dwidth, _flags) + +#define SPRD_COMP_CLK_DATA_TABLE(_struct, _name, _parent, _reg, _table, \ + _mshift, _mwidth, _dshift, \ + _dwidth, _flags) \ + SPRD_COMP_CLK_HW_INIT_FN(_struct, _name, _parent, _reg, _table, \ + _mshift, _mwidth, 0x0, _dshift, \ + _dwidth, _flags, \ + CLK_HW_INIT_PARENTS_DATA) + +#define SPRD_COMP_CLK_DATA(_struct, _name, _parent, _reg, _mshift, \ + _mwidth, _dshift, _dwidth, _flags) \ + SPRD_COMP_CLK_DATA_TABLE(_struct, _name, _parent, _reg, NULL, \ + _mshift, _mwidth, _dshift, _dwidth, \ + _flags) + +#define SPRD_COMP_CLK_DATA_TABLE_OFFSET(_struct, _name, _parent, _reg, \ + _table, _mshift, _mwidth, \ + _doffset, _dshift, _dwidth, \ + _flags) \ + SPRD_COMP_CLK_HW_INIT_FN(_struct, _name, _parent, _reg, _table, \ + _mshift, _mwidth, _doffset, _dshift, \ + _dwidth, _flags, \ + CLK_HW_INIT_PARENTS_DATA) + +#define SPRD_COMP_CLK_DATA_OFFSET(_struct, _name, _parent, _reg, \ + _mshift, _mwidth, _doffset, _dshift, \ + _dwidth, _flags) \ + SPRD_COMP_CLK_DATA_TABLE_OFFSET(_struct, _name, _parent, _reg, \ + NULL, _mshift, _mwidth, \ + _doffset, _dshift, _dwidth, \ + _flags) + +static inline struct sprd_comp *hw_to_sprd_comp(const struct clk_hw *hw) +{ + struct sprd_clk_common *common = hw_to_sprd_clk_common(hw); + + return container_of(common, struct sprd_comp, common); +} + +extern const struct clk_ops sprd_comp_ops; + +#endif /* _SPRD_COMPOSITE_H_ */ diff --git a/drivers/clk/sprd/div.c b/drivers/clk/sprd/div.c new file mode 100644 index 000000000..cd57163a7 --- /dev/null +++ b/drivers/clk/sprd/div.c @@ -0,0 +1,80 @@ +// SPDX-License-Identifier: GPL-2.0 +// +// Spreadtrum divider clock driver +// +// Copyright (C) 2017 Spreadtrum, Inc. +// Author: Chunyan Zhang <chunyan.zhang@spreadtrum.com> + +#include <linux/clk-provider.h> + +#include "div.h" + +static int sprd_div_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) +{ + struct sprd_div *cd = hw_to_sprd_div(hw); + + return divider_determine_rate(&cd->common.hw, req, NULL, cd->div.width, 0); +} + +unsigned long sprd_div_helper_recalc_rate(struct sprd_clk_common *common, + const struct sprd_div_internal *div, + unsigned long parent_rate) +{ + unsigned long val; + unsigned int reg; + + regmap_read(common->regmap, common->reg + div->offset, ®); + val = reg >> div->shift; + val &= (1 << div->width) - 1; + + return divider_recalc_rate(&common->hw, parent_rate, val, NULL, 0, + div->width); +} +EXPORT_SYMBOL_GPL(sprd_div_helper_recalc_rate); + +static unsigned long sprd_div_recalc_rate(struct clk_hw *hw, + unsigned long parent_rate) +{ + struct sprd_div *cd = hw_to_sprd_div(hw); + + return sprd_div_helper_recalc_rate(&cd->common, &cd->div, parent_rate); +} + +int sprd_div_helper_set_rate(const struct sprd_clk_common *common, + const struct sprd_div_internal *div, + unsigned long rate, + unsigned long parent_rate) +{ + unsigned long val; + unsigned int reg; + + val = divider_get_val(rate, parent_rate, NULL, + div->width, 0); + + regmap_read(common->regmap, common->reg + div->offset, ®); + reg &= ~GENMASK(div->width + div->shift - 1, div->shift); + + regmap_write(common->regmap, common->reg + div->offset, + reg | (val << div->shift)); + + return 0; + +} +EXPORT_SYMBOL_GPL(sprd_div_helper_set_rate); + +static int sprd_div_set_rate(struct clk_hw *hw, unsigned long rate, + unsigned long parent_rate) +{ + struct sprd_div *cd = hw_to_sprd_div(hw); + + return sprd_div_helper_set_rate(&cd->common, &cd->div, + rate, parent_rate); +} + +const struct clk_ops sprd_div_ops = { + .recalc_rate = sprd_div_recalc_rate, + .determine_rate = sprd_div_determine_rate, + .set_rate = sprd_div_set_rate, +}; +EXPORT_SYMBOL_GPL(sprd_div_ops); diff --git a/drivers/clk/sprd/div.h b/drivers/clk/sprd/div.h new file mode 100644 index 000000000..a0bcad804 --- /dev/null +++ b/drivers/clk/sprd/div.h @@ -0,0 +1,85 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +// +// Spreadtrum divider clock driver +// +// Copyright (C) 2017 Spreadtrum, Inc. +// Author: Chunyan Zhang <chunyan.zhang@spreadtrum.com> + +#ifndef _SPRD_DIV_H_ +#define _SPRD_DIV_H_ + +#include "common.h" + +/** + * struct sprd_div_internal - Internal divider description + * @shift: Bit offset of the divider in its register + * @width: Width of the divider field in its register + * + * That structure represents a single divider, and is meant to be + * embedded in other structures representing the various clock + * classes. + */ +struct sprd_div_internal { + s32 offset; + u8 shift; + u8 width; +}; + +#define _SPRD_DIV_CLK(_offset, _shift, _width) \ + { \ + .offset = _offset, \ + .shift = _shift, \ + .width = _width, \ + } + +struct sprd_div { + struct sprd_div_internal div; + struct sprd_clk_common common; +}; + +#define SPRD_DIV_CLK_HW_INIT_FN(_struct, _name, _parent, _reg, _offset, \ + _shift, _width, _flags, _fn) \ + struct sprd_div _struct = { \ + .div = _SPRD_DIV_CLK(_offset, _shift, _width), \ + .common = { \ + .regmap = NULL, \ + .reg = _reg, \ + .hw.init = _fn(_name, _parent, \ + &sprd_div_ops, _flags), \ + } \ + } + +#define SPRD_DIV_CLK(_struct, _name, _parent, _reg, \ + _shift, _width, _flags) \ + SPRD_DIV_CLK_HW_INIT_FN(_struct, _name, _parent, _reg, 0x0, \ + _shift, _width, _flags, CLK_HW_INIT) + +#define SPRD_DIV_CLK_FW_NAME(_struct, _name, _parent, _reg, \ + _shift, _width, _flags) \ + SPRD_DIV_CLK_HW_INIT_FN(_struct, _name, _parent, _reg, 0x0, \ + _shift, _width, _flags, CLK_HW_INIT_FW_NAME) + +#define SPRD_DIV_CLK_HW(_struct, _name, _parent, _reg, \ + _shift, _width, _flags) \ + SPRD_DIV_CLK_HW_INIT_FN(_struct, _name, _parent, _reg, 0x0, \ + _shift, _width, _flags, CLK_HW_INIT_HW) + +static inline struct sprd_div *hw_to_sprd_div(const struct clk_hw *hw) +{ + struct sprd_clk_common *common = hw_to_sprd_clk_common(hw); + + return container_of(common, struct sprd_div, common); +} + +unsigned long sprd_div_helper_recalc_rate(struct sprd_clk_common *common, + const struct sprd_div_internal *div, + unsigned long parent_rate); + +int sprd_div_helper_set_rate(const struct sprd_clk_common *common, + const struct sprd_div_internal *div, + unsigned long rate, + unsigned long parent_rate); + +extern const struct clk_ops sprd_div_ops; + +#endif /* _SPRD_DIV_H_ */ diff --git a/drivers/clk/sprd/gate.c b/drivers/clk/sprd/gate.c new file mode 100644 index 000000000..56e1714b5 --- /dev/null +++ b/drivers/clk/sprd/gate.c @@ -0,0 +1,135 @@ +// SPDX-License-Identifier: GPL-2.0 +// +// Spreadtrum gate clock driver +// +// Copyright (C) 2017 Spreadtrum, Inc. +// Author: Chunyan Zhang <chunyan.zhang@spreadtrum.com> + +#include <linux/clk-provider.h> +#include <linux/regmap.h> + +#include "gate.h" + +static void clk_gate_toggle(const struct sprd_gate *sg, bool en) +{ + const struct sprd_clk_common *common = &sg->common; + unsigned int reg; + bool set = sg->flags & CLK_GATE_SET_TO_DISABLE ? true : false; + + set ^= en; + + regmap_read(common->regmap, common->reg, ®); + + if (set) + reg |= sg->enable_mask; + else + reg &= ~sg->enable_mask; + + regmap_write(common->regmap, common->reg, reg); +} + +static void clk_sc_gate_toggle(const struct sprd_gate *sg, bool en) +{ + const struct sprd_clk_common *common = &sg->common; + bool set = sg->flags & CLK_GATE_SET_TO_DISABLE ? 1 : 0; + unsigned int offset; + + set ^= en; + + /* + * Each set/clear gate clock has three registers: + * common->reg - base register + * common->reg + offset - set register + * common->reg + 2 * offset - clear register + */ + offset = set ? sg->sc_offset : sg->sc_offset * 2; + + regmap_write(common->regmap, common->reg + offset, + sg->enable_mask); +} + +static void sprd_gate_disable(struct clk_hw *hw) +{ + struct sprd_gate *sg = hw_to_sprd_gate(hw); + + clk_gate_toggle(sg, false); +} + +static int sprd_gate_enable(struct clk_hw *hw) +{ + struct sprd_gate *sg = hw_to_sprd_gate(hw); + + clk_gate_toggle(sg, true); + + return 0; +} + +static void sprd_sc_gate_disable(struct clk_hw *hw) +{ + struct sprd_gate *sg = hw_to_sprd_gate(hw); + + clk_sc_gate_toggle(sg, false); +} + +static int sprd_sc_gate_enable(struct clk_hw *hw) +{ + struct sprd_gate *sg = hw_to_sprd_gate(hw); + + clk_sc_gate_toggle(sg, true); + + return 0; +} + +static int sprd_pll_sc_gate_prepare(struct clk_hw *hw) +{ + struct sprd_gate *sg = hw_to_sprd_gate(hw); + + clk_sc_gate_toggle(sg, true); + udelay(sg->udelay); + + return 0; +} + +static int sprd_gate_is_enabled(struct clk_hw *hw) +{ + struct sprd_gate *sg = hw_to_sprd_gate(hw); + struct sprd_clk_common *common = &sg->common; + struct clk_hw *parent; + unsigned int reg; + + if (sg->flags & SPRD_GATE_NON_AON) { + parent = clk_hw_get_parent(hw); + if (!parent || !clk_hw_is_enabled(parent)) + return 0; + } + + regmap_read(common->regmap, common->reg, ®); + + if (sg->flags & CLK_GATE_SET_TO_DISABLE) + reg ^= sg->enable_mask; + + reg &= sg->enable_mask; + + return reg ? 1 : 0; +} + +const struct clk_ops sprd_gate_ops = { + .disable = sprd_gate_disable, + .enable = sprd_gate_enable, + .is_enabled = sprd_gate_is_enabled, +}; +EXPORT_SYMBOL_GPL(sprd_gate_ops); + +const struct clk_ops sprd_sc_gate_ops = { + .disable = sprd_sc_gate_disable, + .enable = sprd_sc_gate_enable, + .is_enabled = sprd_gate_is_enabled, +}; +EXPORT_SYMBOL_GPL(sprd_sc_gate_ops); + +const struct clk_ops sprd_pll_sc_gate_ops = { + .unprepare = sprd_sc_gate_disable, + .prepare = sprd_pll_sc_gate_prepare, + .is_enabled = sprd_gate_is_enabled, +}; +EXPORT_SYMBOL_GPL(sprd_pll_sc_gate_ops); diff --git a/drivers/clk/sprd/gate.h b/drivers/clk/sprd/gate.h new file mode 100644 index 000000000..775519eb1 --- /dev/null +++ b/drivers/clk/sprd/gate.h @@ -0,0 +1,168 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +// +// Spreadtrum gate clock driver +// +// Copyright (C) 2017 Spreadtrum, Inc. +// Author: Chunyan Zhang <chunyan.zhang@spreadtrum.com> + +#ifndef _SPRD_GATE_H_ +#define _SPRD_GATE_H_ + +#include "common.h" + +struct sprd_gate { + u32 enable_mask; + u16 flags; + u16 sc_offset; + u16 udelay; + + struct sprd_clk_common common; +}; + +/* + * sprd_gate->flags is used for: + * CLK_GATE_SET_TO_DISABLE BIT(0) + * CLK_GATE_HIWORD_MASK BIT(1) + * CLK_GATE_BIG_ENDIAN BIT(2) + * so we define new flags from BIT(3) + */ +#define SPRD_GATE_NON_AON BIT(3) /* not always powered on, check before read */ + +#define SPRD_SC_GATE_CLK_HW_INIT_FN(_struct, _name, _parent, _reg, \ + _sc_offset, _enable_mask, _flags, \ + _gate_flags, _udelay, _ops, _fn) \ + struct sprd_gate _struct = { \ + .enable_mask = _enable_mask, \ + .sc_offset = _sc_offset, \ + .flags = _gate_flags, \ + .udelay = _udelay, \ + .common = { \ + .regmap = NULL, \ + .reg = _reg, \ + .hw.init = _fn(_name, _parent, \ + _ops, _flags), \ + } \ + } + +#define SPRD_SC_GATE_CLK_OPS_UDELAY(_struct, _name, _parent, _reg, \ + _sc_offset, _enable_mask, _flags, \ + _gate_flags, _udelay, _ops) \ + SPRD_SC_GATE_CLK_HW_INIT_FN(_struct, _name, _parent, _reg, \ + _sc_offset, _enable_mask, _flags, \ + _gate_flags, _udelay, _ops, CLK_HW_INIT) + +#define SPRD_SC_GATE_CLK_OPS(_struct, _name, _parent, _reg, _sc_offset, \ + _enable_mask, _flags, _gate_flags, _ops) \ + SPRD_SC_GATE_CLK_OPS_UDELAY(_struct, _name, _parent, _reg, \ + _sc_offset, _enable_mask, _flags, \ + _gate_flags, 0, _ops) + +#define SPRD_SC_GATE_CLK(_struct, _name, _parent, _reg, _sc_offset, \ + _enable_mask, _flags, _gate_flags) \ + SPRD_SC_GATE_CLK_OPS(_struct, _name, _parent, _reg, _sc_offset, \ + _enable_mask, _flags, _gate_flags, \ + &sprd_sc_gate_ops) + +#define SPRD_GATE_CLK(_struct, _name, _parent, _reg, \ + _enable_mask, _flags, _gate_flags) \ + SPRD_SC_GATE_CLK_OPS(_struct, _name, _parent, _reg, 0, \ + _enable_mask, _flags, _gate_flags, \ + &sprd_gate_ops) + +#define SPRD_PLL_SC_GATE_CLK(_struct, _name, _parent, _reg, _sc_offset, \ + _enable_mask, _flags, _gate_flags, \ + _udelay) \ + SPRD_SC_GATE_CLK_OPS_UDELAY(_struct, _name, _parent, _reg, \ + _sc_offset, _enable_mask, _flags, \ + _gate_flags, _udelay, \ + &sprd_pll_sc_gate_ops) + + +#define SPRD_SC_GATE_CLK_HW_OPS_UDELAY(_struct, _name, _parent, _reg, \ + _sc_offset, _enable_mask, \ + _flags, _gate_flags, \ + _udelay, _ops) \ + SPRD_SC_GATE_CLK_HW_INIT_FN(_struct, _name, _parent, _reg, \ + _sc_offset, _enable_mask, _flags, \ + _gate_flags, _udelay, _ops, \ + CLK_HW_INIT_HW) + +#define SPRD_SC_GATE_CLK_HW_OPS(_struct, _name, _parent, _reg, \ + _sc_offset, _enable_mask, _flags, \ + _gate_flags, _ops) \ + SPRD_SC_GATE_CLK_HW_OPS_UDELAY(_struct, _name, _parent, _reg, \ + _sc_offset, _enable_mask, \ + _flags, _gate_flags, 0, _ops) + +#define SPRD_SC_GATE_CLK_HW(_struct, _name, _parent, _reg, \ + _sc_offset, _enable_mask, _flags, \ + _gate_flags) \ + SPRD_SC_GATE_CLK_HW_OPS(_struct, _name, _parent, _reg, \ + _sc_offset, _enable_mask, _flags, \ + _gate_flags, &sprd_sc_gate_ops) + +#define SPRD_GATE_CLK_HW(_struct, _name, _parent, _reg, \ + _enable_mask, _flags, _gate_flags) \ + SPRD_SC_GATE_CLK_HW_OPS(_struct, _name, _parent, _reg, 0, \ + _enable_mask, _flags, _gate_flags, \ + &sprd_gate_ops) + +#define SPRD_PLL_SC_GATE_CLK_HW(_struct, _name, _parent, _reg, \ + _sc_offset, _enable_mask, _flags, \ + _gate_flags, _udelay) \ + SPRD_SC_GATE_CLK_HW_OPS_UDELAY(_struct, _name, _parent, _reg, \ + _sc_offset, _enable_mask, \ + _flags, _gate_flags, _udelay, \ + &sprd_pll_sc_gate_ops) + +#define SPRD_SC_GATE_CLK_FW_NAME_OPS_UDELAY(_struct, _name, _parent, \ + _reg, _sc_offset, \ + _enable_mask, _flags, \ + _gate_flags, _udelay, _ops) \ + SPRD_SC_GATE_CLK_HW_INIT_FN(_struct, _name, _parent, _reg, \ + _sc_offset, _enable_mask, _flags, \ + _gate_flags, _udelay, _ops, \ + CLK_HW_INIT_FW_NAME) + +#define SPRD_SC_GATE_CLK_FW_NAME_OPS(_struct, _name, _parent, _reg, \ + _sc_offset, _enable_mask, _flags, \ + _gate_flags, _ops) \ + SPRD_SC_GATE_CLK_FW_NAME_OPS_UDELAY(_struct, _name, _parent, \ + _reg, _sc_offset, \ + _enable_mask, _flags, \ + _gate_flags, 0, _ops) + +#define SPRD_SC_GATE_CLK_FW_NAME(_struct, _name, _parent, _reg, \ + _sc_offset, _enable_mask, _flags, \ + _gate_flags) \ + SPRD_SC_GATE_CLK_FW_NAME_OPS(_struct, _name, _parent, _reg, \ + _sc_offset, _enable_mask, _flags, \ + _gate_flags, &sprd_sc_gate_ops) + +#define SPRD_GATE_CLK_FW_NAME(_struct, _name, _parent, _reg, \ + _enable_mask, _flags, _gate_flags) \ + SPRD_SC_GATE_CLK_FW_NAME_OPS(_struct, _name, _parent, _reg, 0, \ + _enable_mask, _flags, _gate_flags, \ + &sprd_gate_ops) + +#define SPRD_PLL_SC_GATE_CLK_FW_NAME(_struct, _name, _parent, _reg, \ + _sc_offset, _enable_mask, _flags, \ + _gate_flags, _udelay) \ + SPRD_SC_GATE_CLK_FW_NAME_OPS_UDELAY(_struct, _name, _parent, \ + _reg, _sc_offset, \ + _enable_mask, _flags, \ + _gate_flags, _udelay, \ + &sprd_pll_sc_gate_ops) + +static inline struct sprd_gate *hw_to_sprd_gate(const struct clk_hw *hw) +{ + struct sprd_clk_common *common = hw_to_sprd_clk_common(hw); + + return container_of(common, struct sprd_gate, common); +} + +extern const struct clk_ops sprd_gate_ops; +extern const struct clk_ops sprd_sc_gate_ops; +extern const struct clk_ops sprd_pll_sc_gate_ops; + +#endif /* _SPRD_GATE_H_ */ diff --git a/drivers/clk/sprd/mux.c b/drivers/clk/sprd/mux.c new file mode 100644 index 000000000..624041b60 --- /dev/null +++ b/drivers/clk/sprd/mux.c @@ -0,0 +1,76 @@ +// SPDX-License-Identifier: GPL-2.0 +// +// Spreadtrum multiplexer clock driver +// +// Copyright (C) 2017 Spreadtrum, Inc. +// Author: Chunyan Zhang <chunyan.zhang@spreadtrum.com> + +#include <linux/clk.h> +#include <linux/clk-provider.h> +#include <linux/regmap.h> + +#include "mux.h" + +u8 sprd_mux_helper_get_parent(const struct sprd_clk_common *common, + const struct sprd_mux_ssel *mux) +{ + unsigned int reg; + u8 parent; + int num_parents; + int i; + + regmap_read(common->regmap, common->reg, ®); + parent = reg >> mux->shift; + parent &= (1 << mux->width) - 1; + + if (!mux->table) + return parent; + + num_parents = clk_hw_get_num_parents(&common->hw); + + for (i = 0; i < num_parents - 1; i++) + if (parent >= mux->table[i] && parent < mux->table[i + 1]) + return i; + + return num_parents - 1; +} +EXPORT_SYMBOL_GPL(sprd_mux_helper_get_parent); + +static u8 sprd_mux_get_parent(struct clk_hw *hw) +{ + struct sprd_mux *cm = hw_to_sprd_mux(hw); + + return sprd_mux_helper_get_parent(&cm->common, &cm->mux); +} + +int sprd_mux_helper_set_parent(const struct sprd_clk_common *common, + const struct sprd_mux_ssel *mux, + u8 index) +{ + unsigned int reg; + + if (mux->table) + index = mux->table[index]; + + regmap_read(common->regmap, common->reg, ®); + reg &= ~GENMASK(mux->width + mux->shift - 1, mux->shift); + regmap_write(common->regmap, common->reg, + reg | (index << mux->shift)); + + return 0; +} +EXPORT_SYMBOL_GPL(sprd_mux_helper_set_parent); + +static int sprd_mux_set_parent(struct clk_hw *hw, u8 index) +{ + struct sprd_mux *cm = hw_to_sprd_mux(hw); + + return sprd_mux_helper_set_parent(&cm->common, &cm->mux, index); +} + +const struct clk_ops sprd_mux_ops = { + .get_parent = sprd_mux_get_parent, + .set_parent = sprd_mux_set_parent, + .determine_rate = __clk_mux_determine_rate, +}; +EXPORT_SYMBOL_GPL(sprd_mux_ops); diff --git a/drivers/clk/sprd/mux.h b/drivers/clk/sprd/mux.h new file mode 100644 index 000000000..f3cc31dae --- /dev/null +++ b/drivers/clk/sprd/mux.h @@ -0,0 +1,88 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +// +// Spreadtrum multiplexer clock driver +// +// Copyright (C) 2017 Spreadtrum, Inc. +// Author: Chunyan Zhang <chunyan.zhang@spreadtrum.com> + +#ifndef _SPRD_MUX_H_ +#define _SPRD_MUX_H_ + +#include "common.h" + +/** + * struct sprd_mux_ssel - Mux clock's source select bits in its register + * @shift: Bit offset of the divider in its register + * @width: Width of the divider field in its register + * @table: For some mux clocks, not all sources are used on some special + * chips, this matches the value of mux clock's register and the + * sources which are used for this mux clock + */ +struct sprd_mux_ssel { + u8 shift; + u8 width; + const u8 *table; +}; + +struct sprd_mux { + struct sprd_mux_ssel mux; + struct sprd_clk_common common; +}; + +#define _SPRD_MUX_CLK(_shift, _width, _table) \ + { \ + .shift = _shift, \ + .width = _width, \ + .table = _table, \ + } + +#define SPRD_MUX_CLK_HW_INIT_FN(_struct, _name, _parents, _table, \ + _reg, _shift, _width, _flags, _fn) \ + struct sprd_mux _struct = { \ + .mux = _SPRD_MUX_CLK(_shift, _width, _table), \ + .common = { \ + .regmap = NULL, \ + .reg = _reg, \ + .hw.init = _fn(_name, _parents, \ + &sprd_mux_ops, _flags), \ + } \ + } + +#define SPRD_MUX_CLK_TABLE(_struct, _name, _parents, _table, \ + _reg, _shift, _width, _flags) \ + SPRD_MUX_CLK_HW_INIT_FN(_struct, _name, _parents, _table, \ + _reg, _shift, _width, _flags, \ + CLK_HW_INIT_PARENTS) + +#define SPRD_MUX_CLK(_struct, _name, _parents, _reg, \ + _shift, _width, _flags) \ + SPRD_MUX_CLK_TABLE(_struct, _name, _parents, NULL, \ + _reg, _shift, _width, _flags) + +#define SPRD_MUX_CLK_DATA_TABLE(_struct, _name, _parents, _table, \ + _reg, _shift, _width, _flags) \ + SPRD_MUX_CLK_HW_INIT_FN(_struct, _name, _parents, _table, \ + _reg, _shift, _width, _flags, \ + CLK_HW_INIT_PARENTS_DATA) + +#define SPRD_MUX_CLK_DATA(_struct, _name, _parents, _reg, \ + _shift, _width, _flags) \ + SPRD_MUX_CLK_DATA_TABLE(_struct, _name, _parents, NULL, \ + _reg, _shift, _width, _flags) + +static inline struct sprd_mux *hw_to_sprd_mux(const struct clk_hw *hw) +{ + struct sprd_clk_common *common = hw_to_sprd_clk_common(hw); + + return container_of(common, struct sprd_mux, common); +} + +extern const struct clk_ops sprd_mux_ops; + +u8 sprd_mux_helper_get_parent(const struct sprd_clk_common *common, + const struct sprd_mux_ssel *mux); +int sprd_mux_helper_set_parent(const struct sprd_clk_common *common, + const struct sprd_mux_ssel *mux, + u8 index); + +#endif /* _SPRD_MUX_H_ */ diff --git a/drivers/clk/sprd/pll.c b/drivers/clk/sprd/pll.c new file mode 100644 index 000000000..4aec30777 --- /dev/null +++ b/drivers/clk/sprd/pll.c @@ -0,0 +1,263 @@ +// SPDX-License-Identifier: GPL-2.0 +// +// Spreadtrum pll clock driver +// +// Copyright (C) 2015~2017 Spreadtrum, Inc. +// Author: Chunyan Zhang <chunyan.zhang@spreadtrum.com> + +#include <linux/delay.h> +#include <linux/err.h> +#include <linux/regmap.h> +#include <linux/slab.h> + +#include "pll.h" + +#define CLK_PLL_1M 1000000 +#define CLK_PLL_10M (CLK_PLL_1M * 10) + +#define pindex(pll, member) \ + (pll->factors[member].shift / (8 * sizeof(pll->regs_num))) + +#define pshift(pll, member) \ + (pll->factors[member].shift % (8 * sizeof(pll->regs_num))) + +#define pwidth(pll, member) \ + pll->factors[member].width + +#define pmask(pll, member) \ + ((pwidth(pll, member)) ? \ + GENMASK(pwidth(pll, member) + pshift(pll, member) - 1, \ + pshift(pll, member)) : 0) + +#define pinternal(pll, cfg, member) \ + (cfg[pindex(pll, member)] & pmask(pll, member)) + +#define pinternal_val(pll, cfg, member) \ + (pinternal(pll, cfg, member) >> pshift(pll, member)) + +static inline unsigned int +sprd_pll_read(const struct sprd_pll *pll, u8 index) +{ + const struct sprd_clk_common *common = &pll->common; + unsigned int val = 0; + + if (WARN_ON(index >= pll->regs_num)) + return 0; + + regmap_read(common->regmap, common->reg + index * 4, &val); + + return val; +} + +static inline void +sprd_pll_write(const struct sprd_pll *pll, u8 index, + u32 msk, u32 val) +{ + const struct sprd_clk_common *common = &pll->common; + unsigned int offset, reg; + int ret = 0; + + if (WARN_ON(index >= pll->regs_num)) + return; + + offset = common->reg + index * 4; + ret = regmap_read(common->regmap, offset, ®); + if (!ret) + regmap_write(common->regmap, offset, (reg & ~msk) | val); +} + +static unsigned long pll_get_refin(const struct sprd_pll *pll) +{ + u32 shift, mask, index, refin_id = 3; + const unsigned long refin[4] = { 2, 4, 13, 26 }; + + if (pwidth(pll, PLL_REFIN)) { + index = pindex(pll, PLL_REFIN); + shift = pshift(pll, PLL_REFIN); + mask = pmask(pll, PLL_REFIN); + refin_id = (sprd_pll_read(pll, index) & mask) >> shift; + if (refin_id > 3) + refin_id = 3; + } + + return refin[refin_id]; +} + +static u32 pll_get_ibias(u64 rate, const u64 *table) +{ + u32 i, num = table[0]; + + /* table[0] indicates the number of items in this table */ + for (i = 0; i < num; i++) + if (rate <= table[i + 1]) + break; + + return i == num ? num - 1 : i; +} + +static unsigned long _sprd_pll_recalc_rate(const struct sprd_pll *pll, + unsigned long parent_rate) +{ + u32 *cfg; + u32 i, mask, regs_num = pll->regs_num; + unsigned long rate, nint, kint = 0; + u64 refin; + u16 k1, k2; + + cfg = kcalloc(regs_num, sizeof(*cfg), GFP_KERNEL); + if (!cfg) + return parent_rate; + + for (i = 0; i < regs_num; i++) + cfg[i] = sprd_pll_read(pll, i); + + refin = pll_get_refin(pll); + + if (pinternal(pll, cfg, PLL_PREDIV)) + refin = refin * 2; + + if (pwidth(pll, PLL_POSTDIV) && + ((pll->fflag == 1 && pinternal(pll, cfg, PLL_POSTDIV)) || + (!pll->fflag && !pinternal(pll, cfg, PLL_POSTDIV)))) + refin = refin / 2; + + if (!pinternal(pll, cfg, PLL_DIV_S)) { + rate = refin * pinternal_val(pll, cfg, PLL_N) * CLK_PLL_10M; + } else { + nint = pinternal_val(pll, cfg, PLL_NINT); + if (pinternal(pll, cfg, PLL_SDM_EN)) + kint = pinternal_val(pll, cfg, PLL_KINT); + + mask = pmask(pll, PLL_KINT); + + k1 = pll->k1; + k2 = pll->k2; + rate = DIV_ROUND_CLOSEST_ULL(refin * kint * k1, + ((mask >> __ffs(mask)) + 1)) * + k2 + refin * nint * CLK_PLL_1M; + } + + kfree(cfg); + return rate; +} + +#define SPRD_PLL_WRITE_CHECK(pll, i, mask, val) \ + (((sprd_pll_read(pll, i) & mask) == val) ? 0 : (-EFAULT)) + +static int _sprd_pll_set_rate(const struct sprd_pll *pll, + unsigned long rate, + unsigned long parent_rate) +{ + struct reg_cfg *cfg; + int ret = 0; + u32 mask, shift, width, ibias_val, index; + u32 regs_num = pll->regs_num, i = 0; + unsigned long kint, nint; + u64 tmp, refin, fvco = rate; + + cfg = kzalloc_objs(*cfg, regs_num); + if (!cfg) + return -ENOMEM; + + refin = pll_get_refin(pll); + + mask = pmask(pll, PLL_PREDIV); + index = pindex(pll, PLL_PREDIV); + width = pwidth(pll, PLL_PREDIV); + if (width && (sprd_pll_read(pll, index) & mask)) + refin = refin * 2; + + mask = pmask(pll, PLL_POSTDIV); + index = pindex(pll, PLL_POSTDIV); + width = pwidth(pll, PLL_POSTDIV); + cfg[index].msk = mask; + if (width && ((pll->fflag == 1 && fvco <= pll->fvco) || + (pll->fflag == 0 && fvco > pll->fvco))) + cfg[index].val |= mask; + + if (width && fvco <= pll->fvco) + fvco = fvco * 2; + + mask = pmask(pll, PLL_DIV_S); + index = pindex(pll, PLL_DIV_S); + cfg[index].val |= mask; + cfg[index].msk |= mask; + + mask = pmask(pll, PLL_SDM_EN); + index = pindex(pll, PLL_SDM_EN); + cfg[index].val |= mask; + cfg[index].msk |= mask; + + nint = do_div(fvco, refin * CLK_PLL_1M); + mask = pmask(pll, PLL_NINT); + index = pindex(pll, PLL_NINT); + shift = pshift(pll, PLL_NINT); + cfg[index].val |= (nint << shift) & mask; + cfg[index].msk |= mask; + + mask = pmask(pll, PLL_KINT); + index = pindex(pll, PLL_KINT); + width = pwidth(pll, PLL_KINT); + shift = pshift(pll, PLL_KINT); + tmp = fvco - refin * nint * CLK_PLL_1M; + tmp = do_div(tmp, 10000) * ((mask >> shift) + 1); + kint = DIV_ROUND_CLOSEST_ULL(tmp, refin * 100); + cfg[index].val |= (kint << shift) & mask; + cfg[index].msk |= mask; + + ibias_val = pll_get_ibias(fvco, pll->itable); + + mask = pmask(pll, PLL_IBIAS); + index = pindex(pll, PLL_IBIAS); + shift = pshift(pll, PLL_IBIAS); + cfg[index].val |= ibias_val << shift & mask; + cfg[index].msk |= mask; + + for (i = 0; i < regs_num; i++) { + if (cfg[i].msk) { + sprd_pll_write(pll, i, cfg[i].msk, cfg[i].val); + ret |= SPRD_PLL_WRITE_CHECK(pll, i, cfg[i].msk, + cfg[i].val); + } + } + + if (!ret) + udelay(pll->udelay); + + kfree(cfg); + return ret; +} + +static unsigned long sprd_pll_recalc_rate(struct clk_hw *hw, + unsigned long parent_rate) +{ + struct sprd_pll *pll = hw_to_sprd_pll(hw); + + return _sprd_pll_recalc_rate(pll, parent_rate); +} + +static int sprd_pll_set_rate(struct clk_hw *hw, + unsigned long rate, + unsigned long parent_rate) +{ + struct sprd_pll *pll = hw_to_sprd_pll(hw); + + return _sprd_pll_set_rate(pll, rate, parent_rate); +} + +static int sprd_pll_clk_prepare(struct clk_hw *hw) +{ + struct sprd_pll *pll = hw_to_sprd_pll(hw); + + udelay(pll->udelay); + + return 0; +} + +const struct clk_ops sprd_pll_ops = { + .prepare = sprd_pll_clk_prepare, + .recalc_rate = sprd_pll_recalc_rate, + .determine_rate = clk_determine_rate_noop, + .set_rate = sprd_pll_set_rate, +}; +EXPORT_SYMBOL_GPL(sprd_pll_ops); diff --git a/drivers/clk/sprd/pll.h b/drivers/clk/sprd/pll.h new file mode 100644 index 000000000..6558f50d0 --- /dev/null +++ b/drivers/clk/sprd/pll.h @@ -0,0 +1,127 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +// +// Spreadtrum pll clock driver +// +// Copyright (C) 2015~2017 Spreadtrum, Inc. +// Author: Chunyan Zhang <chunyan.zhang@spreadtrum.com> + +#ifndef _SPRD_PLL_H_ +#define _SPRD_PLL_H_ + +#include "common.h" + +struct reg_cfg { + u32 val; + u32 msk; +}; + +struct clk_bit_field { + u8 shift; + u8 width; +}; + +enum { + PLL_LOCK_DONE, + PLL_DIV_S, + PLL_MOD_EN, + PLL_SDM_EN, + PLL_REFIN, + PLL_IBIAS, + PLL_N, + PLL_NINT, + PLL_KINT, + PLL_PREDIV, + PLL_POSTDIV, + + PLL_FACT_MAX +}; + +/* + * struct sprd_pll - definition of adjustable pll clock + * + * @reg: registers used to set the configuration of pll clock, + * reg[0] shows how many registers this pll clock uses. + * @itable: pll ibias table, itable[0] means how many items this + * table includes + * @udelay delay time after setting rate + * @factors used to calculate the pll clock rate + * @fvco: fvco threshold rate + * @fflag: fvco flag + */ +struct sprd_pll { + u32 regs_num; + const u64 *itable; + const struct clk_bit_field *factors; + u16 udelay; + u16 k1; + u16 k2; + u16 fflag; + u64 fvco; + + struct sprd_clk_common common; +}; + +#define SPRD_PLL_HW_INIT_FN(_struct, _name, _parent, _reg, \ + _regs_num, _itable, _factors, \ + _udelay, _k1, _k2, _fflag, \ + _fvco, _fn) \ + struct sprd_pll _struct = { \ + .regs_num = _regs_num, \ + .itable = _itable, \ + .factors = _factors, \ + .udelay = _udelay, \ + .k1 = _k1, \ + .k2 = _k2, \ + .fflag = _fflag, \ + .fvco = _fvco, \ + .common = { \ + .regmap = NULL, \ + .reg = _reg, \ + .hw.init = _fn(_name, _parent, \ + &sprd_pll_ops, 0),\ + }, \ + } + +#define SPRD_PLL_WITH_ITABLE_K_FVCO(_struct, _name, _parent, _reg, \ + _regs_num, _itable, _factors, \ + _udelay, _k1, _k2, _fflag, _fvco) \ + SPRD_PLL_HW_INIT_FN(_struct, _name, _parent, _reg, _regs_num, \ + _itable, _factors, _udelay, _k1, _k2, \ + _fflag, _fvco, CLK_HW_INIT) + +#define SPRD_PLL_WITH_ITABLE_K(_struct, _name, _parent, _reg, \ + _regs_num, _itable, _factors, \ + _udelay, _k1, _k2) \ + SPRD_PLL_WITH_ITABLE_K_FVCO(_struct, _name, _parent, _reg, \ + _regs_num, _itable, _factors, \ + _udelay, _k1, _k2, 0, 0) + +#define SPRD_PLL_WITH_ITABLE_1K(_struct, _name, _parent, _reg, \ + _regs_num, _itable, _factors, _udelay) \ + SPRD_PLL_WITH_ITABLE_K_FVCO(_struct, _name, _parent, _reg, \ + _regs_num, _itable, _factors, \ + _udelay, 1000, 1000, 0, 0) + +#define SPRD_PLL_FW_NAME(_struct, _name, _parent, _reg, _regs_num, \ + _itable, _factors, _udelay, _k1, _k2, \ + _fflag, _fvco) \ + SPRD_PLL_HW_INIT_FN(_struct, _name, _parent, _reg, _regs_num, \ + _itable, _factors, _udelay, _k1, _k2, \ + _fflag, _fvco, CLK_HW_INIT_FW_NAME) + +#define SPRD_PLL_HW(_struct, _name, _parent, _reg, _regs_num, _itable, \ + _factors, _udelay, _k1, _k2, _fflag, _fvco) \ + SPRD_PLL_HW_INIT_FN(_struct, _name, _parent, _reg, _regs_num, \ + _itable, _factors, _udelay, _k1, _k2, \ + _fflag, _fvco, CLK_HW_INIT_HW) + +static inline struct sprd_pll *hw_to_sprd_pll(struct clk_hw *hw) +{ + struct sprd_clk_common *common = hw_to_sprd_clk_common(hw); + + return container_of(common, struct sprd_pll, common); +} + +extern const struct clk_ops sprd_pll_ops; + +#endif /* _SPRD_PLL_H_ */ diff --git a/drivers/clk/sprd/sc9860-clk.c b/drivers/clk/sprd/sc9860-clk.c new file mode 100644 index 000000000..d7fe924fb --- /dev/null +++ b/drivers/clk/sprd/sc9860-clk.c @@ -0,0 +1,2049 @@ +// SPDX-License-Identifier: GPL-2.0 +// +// Spreatrum SC9860 clock driver +// +// Copyright (C) 2017 Spreadtrum, Inc. +// Author: Chunyan Zhang <chunyan.zhang@spreadtrum.com> + +#include <linux/clk-provider.h> +#include <linux/err.h> +#include <linux/io.h> +#include <linux/module.h> +#include <linux/of.h> +#include <linux/platform_device.h> +#include <linux/slab.h> + +#include <dt-bindings/clock/sprd,sc9860-clk.h> + +#include "common.h" +#include "composite.h" +#include "div.h" +#include "gate.h" +#include "mux.h" +#include "pll.h" + +static CLK_FIXED_FACTOR(fac_4m, "fac-4m", "ext-26m", + 6, 1, 0); +static CLK_FIXED_FACTOR(fac_2m, "fac-2m", "ext-26m", + 13, 1, 0); +static CLK_FIXED_FACTOR(fac_1m, "fac-1m", "ext-26m", + 26, 1, 0); +static CLK_FIXED_FACTOR(fac_250k, "fac-250k", "ext-26m", + 104, 1, 0); +static CLK_FIXED_FACTOR(fac_rpll0_26m, "rpll0-26m", "ext-26m", + 1, 1, 0); +static CLK_FIXED_FACTOR(fac_rpll1_26m, "rpll1-26m", "ext-26m", + 1, 1, 0); +static CLK_FIXED_FACTOR(fac_rco_25m, "rco-25m", "ext-rc0-100m", + 4, 1, 0); +static CLK_FIXED_FACTOR(fac_rco_4m, "rco-4m", "ext-rc0-100m", + 25, 1, 0); +static CLK_FIXED_FACTOR(fac_rco_2m, "rco-2m", "ext-rc0-100m", + 50, 1, 0); +static CLK_FIXED_FACTOR(fac_3k2, "fac-3k2", "ext-32k", + 10, 1, 0); +static CLK_FIXED_FACTOR(fac_1k, "fac-1k", "ext-32k", + 32, 1, 0); + +static SPRD_SC_GATE_CLK(mpll0_gate, "mpll0-gate", "ext-26m", 0xb0, + 0x1000, BIT(2), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK(mpll1_gate, "mpll1-gate", "ext-26m", 0xb0, + 0x1000, BIT(18), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK(dpll0_gate, "dpll0-gate", "ext-26m", 0xb4, + 0x1000, BIT(2), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK(dpll1_gate, "dpll1-gate", "ext-26m", 0xb4, + 0x1000, BIT(18), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK(ltepll0_gate, "ltepll0-gate", "ext-26m", 0xb8, + 0x1000, BIT(2), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK(twpll_gate, "twpll-gate", "ext-26m", 0xbc, + 0x1000, BIT(2), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK(ltepll1_gate, "ltepll1-gate", "ext-26m", 0x10c, + 0x1000, BIT(2), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK(rpll0_gate, "rpll0-gate", "ext-26m", 0x16c, + 0x1000, BIT(2), 0, 0); +static SPRD_SC_GATE_CLK(rpll1_gate, "rpll1-gate", "ext-26m", 0x16c, + 0x1000, BIT(18), 0, 0); +static SPRD_SC_GATE_CLK(cppll_gate, "cppll-gate", "ext-26m", 0x2b4, + 0x1000, BIT(2), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK(gpll_gate, "gpll-gate", "ext-26m", 0x32c, + 0x1000, BIT(0), CLK_IGNORE_UNUSED, CLK_GATE_SET_TO_DISABLE); + +static struct sprd_clk_common *sc9860_pmu_gate_clks[] = { + /* address base is 0x402b0000 */ + &mpll0_gate.common, + &mpll1_gate.common, + &dpll0_gate.common, + &dpll1_gate.common, + <epll0_gate.common, + &twpll_gate.common, + <epll1_gate.common, + &rpll0_gate.common, + &rpll1_gate.common, + &cppll_gate.common, + &gpll_gate.common, +}; + +static struct clk_hw_onecell_data sc9860_pmu_gate_hws = { + .hws = { + [CLK_FAC_4M] = &fac_4m.hw, + [CLK_FAC_2M] = &fac_2m.hw, + [CLK_FAC_1M] = &fac_1m.hw, + [CLK_FAC_250K] = &fac_250k.hw, + [CLK_FAC_RPLL0_26M] = &fac_rpll0_26m.hw, + [CLK_FAC_RPLL1_26M] = &fac_rpll1_26m.hw, + [CLK_FAC_RCO25M] = &fac_rco_25m.hw, + [CLK_FAC_RCO4M] = &fac_rco_4m.hw, + [CLK_FAC_RCO2M] = &fac_rco_2m.hw, + [CLK_FAC_3K2] = &fac_3k2.hw, + [CLK_FAC_1K] = &fac_1k.hw, + [CLK_MPLL0_GATE] = &mpll0_gate.common.hw, + [CLK_MPLL1_GATE] = &mpll1_gate.common.hw, + [CLK_DPLL0_GATE] = &dpll0_gate.common.hw, + [CLK_DPLL1_GATE] = &dpll1_gate.common.hw, + [CLK_LTEPLL0_GATE] = <epll0_gate.common.hw, + [CLK_TWPLL_GATE] = &twpll_gate.common.hw, + [CLK_LTEPLL1_GATE] = <epll1_gate.common.hw, + [CLK_RPLL0_GATE] = &rpll0_gate.common.hw, + [CLK_RPLL1_GATE] = &rpll1_gate.common.hw, + [CLK_CPPLL_GATE] = &cppll_gate.common.hw, + [CLK_GPLL_GATE] = &gpll_gate.common.hw, + }, + .num = CLK_PMU_GATE_NUM, +}; + +static const struct sprd_clk_desc sc9860_pmu_gate_desc = { + .clk_clks = sc9860_pmu_gate_clks, + .num_clk_clks = ARRAY_SIZE(sc9860_pmu_gate_clks), + .hw_clks = &sc9860_pmu_gate_hws, +}; + +/* GPLL/LPLL/DPLL/RPLL/CPLL */ +static const u64 itable1[4] = {3, 780000000, 988000000, 1196000000}; + +/* TWPLL/MPLL0/MPLL1 */ +static const u64 itable2[4] = {3, 1638000000, 2080000000, 2600000000UL}; + +static const struct clk_bit_field f_mpll0[PLL_FACT_MAX] = { + { .shift = 20, .width = 1 }, /* lock_done */ + { .shift = 19, .width = 1 }, /* div_s */ + { .shift = 18, .width = 1 }, /* mod_en */ + { .shift = 17, .width = 1 }, /* sdm_en */ + { .shift = 0, .width = 0 }, /* refin */ + { .shift = 11, .width = 2 }, /* ibias */ + { .shift = 0, .width = 7 }, /* n */ + { .shift = 57, .width = 7 }, /* nint */ + { .shift = 32, .width = 23}, /* kint */ + { .shift = 0, .width = 0 }, /* prediv */ + { .shift = 56, .width = 1 }, /* postdiv */ +}; +static SPRD_PLL_WITH_ITABLE_K_FVCO(mpll0_clk, "mpll0", "mpll0-gate", 0x24, + 2, itable2, f_mpll0, 200, + 1000, 1000, 1, 1300000000); + +static const struct clk_bit_field f_mpll1[PLL_FACT_MAX] = { + { .shift = 20, .width = 1 }, /* lock_done */ + { .shift = 19, .width = 1 }, /* div_s */ + { .shift = 18, .width = 1 }, /* mod_en */ + { .shift = 17, .width = 1 }, /* sdm_en */ + { .shift = 0, .width = 0 }, /* refin */ + { .shift = 11, .width = 2 }, /* ibias */ + { .shift = 0, .width = 7 }, /* n */ + { .shift = 57, .width = 7 }, /* nint */ + { .shift = 32, .width = 23}, /* kint */ + { .shift = 56, .width = 1 }, /* prediv */ + { .shift = 0, .width = 0 }, /* postdiv */ +}; +static SPRD_PLL_WITH_ITABLE_1K(mpll1_clk, "mpll1", "mpll1-gate", 0x2c, + 2, itable2, f_mpll1, 200); + +static const struct clk_bit_field f_dpll[PLL_FACT_MAX] = { + { .shift = 16, .width = 1 }, /* lock_done */ + { .shift = 15, .width = 1 }, /* div_s */ + { .shift = 14, .width = 1 }, /* mod_en */ + { .shift = 13, .width = 1 }, /* sdm_en */ + { .shift = 0, .width = 0 }, /* refin */ + { .shift = 8, .width = 2 }, /* ibias */ + { .shift = 0, .width = 7 }, /* n */ + { .shift = 57, .width = 7 }, /* nint */ + { .shift = 32, .width = 23}, /* kint */ + { .shift = 0, .width = 0 }, /* prediv */ + { .shift = 0, .width = 0 }, /* postdiv */ +}; +static SPRD_PLL_WITH_ITABLE_1K(dpll0_clk, "dpll0", "dpll0-gate", 0x34, + 2, itable1, f_dpll, 200); + +static SPRD_PLL_WITH_ITABLE_1K(dpll1_clk, "dpll1", "dpll1-gate", 0x3c, + 2, itable1, f_dpll, 200); + +static const struct clk_bit_field f_rpll[PLL_FACT_MAX] = { + { .shift = 0, .width = 1 }, /* lock_done */ + { .shift = 3, .width = 1 }, /* div_s */ + { .shift = 80, .width = 1 }, /* mod_en */ + { .shift = 81, .width = 1 }, /* sdm_en */ + { .shift = 0, .width = 0 }, /* refin */ + { .shift = 14, .width = 2 }, /* ibias */ + { .shift = 16, .width = 7 }, /* n */ + { .shift = 4, .width = 7 }, /* nint */ + { .shift = 32, .width = 23}, /* kint */ + { .shift = 0, .width = 0 }, /* prediv */ + { .shift = 0, .width = 0 }, /* postdiv */ +}; +static SPRD_PLL_WITH_ITABLE_1K(rpll0_clk, "rpll0", "rpll0-gate", 0x44, + 3, itable1, f_rpll, 200); + +static SPRD_PLL_WITH_ITABLE_1K(rpll1_clk, "rpll1", "rpll1-gate", 0x50, + 3, itable1, f_rpll, 200); + +static const struct clk_bit_field f_twpll[PLL_FACT_MAX] = { + { .shift = 21, .width = 1 }, /* lock_done */ + { .shift = 20, .width = 1 }, /* div_s */ + { .shift = 19, .width = 1 }, /* mod_en */ + { .shift = 18, .width = 1 }, /* sdm_en */ + { .shift = 0, .width = 0 }, /* refin */ + { .shift = 13, .width = 2 }, /* ibias */ + { .shift = 0, .width = 7 }, /* n */ + { .shift = 57, .width = 7 }, /* nint */ + { .shift = 32, .width = 23}, /* kint */ + { .shift = 0, .width = 0 }, /* prediv */ + { .shift = 0, .width = 0 }, /* postdiv */ +}; +static SPRD_PLL_WITH_ITABLE_1K(twpll_clk, "twpll", "twpll-gate", 0x5c, + 2, itable2, f_twpll, 200); + +static const struct clk_bit_field f_ltepll[PLL_FACT_MAX] = { + { .shift = 31, .width = 1 }, /* lock_done */ + { .shift = 27, .width = 1 }, /* div_s */ + { .shift = 26, .width = 1 }, /* mod_en */ + { .shift = 25, .width = 1 }, /* sdm_en */ + { .shift = 0, .width = 0 }, /* refin */ + { .shift = 20, .width = 2 }, /* ibias */ + { .shift = 0, .width = 7 }, /* n */ + { .shift = 57, .width = 7 }, /* nint */ + { .shift = 32, .width = 23}, /* kint */ + { .shift = 0, .width = 0 }, /* prediv */ + { .shift = 0, .width = 0 }, /* postdiv */ +}; +static SPRD_PLL_WITH_ITABLE_1K(ltepll0_clk, "ltepll0", "ltepll0-gate", + 0x64, 2, itable1, + f_ltepll, 200); +static SPRD_PLL_WITH_ITABLE_1K(ltepll1_clk, "ltepll1", "ltepll1-gate", + 0x6c, 2, itable1, + f_ltepll, 200); + +static const struct clk_bit_field f_gpll[PLL_FACT_MAX] = { + { .shift = 18, .width = 1 }, /* lock_done */ + { .shift = 15, .width = 1 }, /* div_s */ + { .shift = 14, .width = 1 }, /* mod_en */ + { .shift = 13, .width = 1 }, /* sdm_en */ + { .shift = 0, .width = 0 }, /* refin */ + { .shift = 8, .width = 2 }, /* ibias */ + { .shift = 0, .width = 7 }, /* n */ + { .shift = 57, .width = 7 }, /* nint */ + { .shift = 32, .width = 23}, /* kint */ + { .shift = 0, .width = 0 }, /* prediv */ + { .shift = 17, .width = 1 }, /* postdiv */ +}; +static SPRD_PLL_WITH_ITABLE_K_FVCO(gpll_clk, "gpll", "gpll-gate", 0x9c, + 2, itable1, f_gpll, 200, + 1000, 1000, 1, 600000000); + +static const struct clk_bit_field f_cppll[PLL_FACT_MAX] = { + { .shift = 17, .width = 1 }, /* lock_done */ + { .shift = 15, .width = 1 }, /* div_s */ + { .shift = 14, .width = 1 }, /* mod_en */ + { .shift = 13, .width = 1 }, /* sdm_en */ + { .shift = 0, .width = 0 }, /* refin */ + { .shift = 8, .width = 2 }, /* ibias */ + { .shift = 0, .width = 7 }, /* n */ + { .shift = 57, .width = 7 }, /* nint */ + { .shift = 32, .width = 23}, /* kint */ + { .shift = 0, .width = 0 }, /* prediv */ + { .shift = 0, .width = 0 }, /* postdiv */ +}; +static SPRD_PLL_WITH_ITABLE_1K(cppll_clk, "cppll", "cppll-gate", 0xc4, + 2, itable1, f_cppll, 200); + +static CLK_FIXED_FACTOR(gpll_42m5, "gpll-42m5", "gpll", 20, 1, 0); +static CLK_FIXED_FACTOR(twpll_768m, "twpll-768m", "twpll", 2, 1, 0); +static CLK_FIXED_FACTOR(twpll_384m, "twpll-384m", "twpll", 4, 1, 0); +static CLK_FIXED_FACTOR(twpll_192m, "twpll-192m", "twpll", 8, 1, 0); +static CLK_FIXED_FACTOR(twpll_96m, "twpll-96m", "twpll", 16, 1, 0); +static CLK_FIXED_FACTOR(twpll_48m, "twpll-48m", "twpll", 32, 1, 0); +static CLK_FIXED_FACTOR(twpll_24m, "twpll-24m", "twpll", 64, 1, 0); +static CLK_FIXED_FACTOR(twpll_12m, "twpll-12m", "twpll", 128, 1, 0); +static CLK_FIXED_FACTOR(twpll_512m, "twpll-512m", "twpll", 3, 1, 0); +static CLK_FIXED_FACTOR(twpll_256m, "twpll-256m", "twpll", 6, 1, 0); +static CLK_FIXED_FACTOR(twpll_128m, "twpll-128m", "twpll", 12, 1, 0); +static CLK_FIXED_FACTOR(twpll_64m, "twpll-64m", "twpll", 24, 1, 0); +static CLK_FIXED_FACTOR(twpll_307m2, "twpll-307m2", "twpll", 5, 1, 0); +static CLK_FIXED_FACTOR(twpll_153m6, "twpll-153m6", "twpll", 10, 1, 0); +static CLK_FIXED_FACTOR(twpll_76m8, "twpll-76m8", "twpll", 20, 1, 0); +static CLK_FIXED_FACTOR(twpll_51m2, "twpll-51m2", "twpll", 30, 1, 0); +static CLK_FIXED_FACTOR(twpll_38m4, "twpll-38m4", "twpll", 40, 1, 0); +static CLK_FIXED_FACTOR(twpll_19m2, "twpll-19m2", "twpll", 80, 1, 0); +static CLK_FIXED_FACTOR(l0_614m4, "l0-614m4", "ltepll0", 2, 1, 0); +static CLK_FIXED_FACTOR(l0_409m6, "l0-409m6", "ltepll0", 3, 1, 0); +static CLK_FIXED_FACTOR(l0_38m, "l0-38m", "ltepll0", 32, 1, 0); +static CLK_FIXED_FACTOR(l1_38m, "l1-38m", "ltepll1", 32, 1, 0); +static CLK_FIXED_FACTOR(rpll0_192m, "rpll0-192m", "rpll0", 6, 1, 0); +static CLK_FIXED_FACTOR(rpll0_96m, "rpll0-96m", "rpll0", 12, 1, 0); +static CLK_FIXED_FACTOR(rpll0_48m, "rpll0-48m", "rpll0", 24, 1, 0); +static CLK_FIXED_FACTOR(rpll1_468m, "rpll1-468m", "rpll1", 2, 1, 0); +static CLK_FIXED_FACTOR(rpll1_192m, "rpll1-192m", "rpll1", 6, 1, 0); +static CLK_FIXED_FACTOR(rpll1_96m, "rpll1-96m", "rpll1", 12, 1, 0); +static CLK_FIXED_FACTOR(rpll1_64m, "rpll1-64m", "rpll1", 18, 1, 0); +static CLK_FIXED_FACTOR(rpll1_48m, "rpll1-48m", "rpll1", 24, 1, 0); +static CLK_FIXED_FACTOR(dpll0_50m, "dpll0-50m", "dpll0", 16, 1, 0); +static CLK_FIXED_FACTOR(dpll1_50m, "dpll1-50m", "dpll1", 16, 1, 0); +static CLK_FIXED_FACTOR(cppll_50m, "cppll-50m", "cppll", 18, 1, 0); +static CLK_FIXED_FACTOR(m0_39m, "m0-39m", "mpll0", 32, 1, 0); +static CLK_FIXED_FACTOR(m1_63m, "m1-63m", "mpll1", 32, 1, 0); + +static struct sprd_clk_common *sc9860_pll_clks[] = { + /* address base is 0x40400000 */ + &mpll0_clk.common, + &mpll1_clk.common, + &dpll0_clk.common, + &dpll1_clk.common, + &rpll0_clk.common, + &rpll1_clk.common, + &twpll_clk.common, + <epll0_clk.common, + <epll1_clk.common, + &gpll_clk.common, + &cppll_clk.common, +}; + +static struct clk_hw_onecell_data sc9860_pll_hws = { + .hws = { + [CLK_MPLL0] = &mpll0_clk.common.hw, + [CLK_MPLL1] = &mpll1_clk.common.hw, + [CLK_DPLL0] = &dpll0_clk.common.hw, + [CLK_DPLL1] = &dpll1_clk.common.hw, + [CLK_RPLL0] = &rpll0_clk.common.hw, + [CLK_RPLL1] = &rpll1_clk.common.hw, + [CLK_TWPLL] = &twpll_clk.common.hw, + [CLK_LTEPLL0] = <epll0_clk.common.hw, + [CLK_LTEPLL1] = <epll1_clk.common.hw, + [CLK_GPLL] = &gpll_clk.common.hw, + [CLK_CPPLL] = &cppll_clk.common.hw, + [CLK_GPLL_42M5] = &gpll_42m5.hw, + [CLK_TWPLL_768M] = &twpll_768m.hw, + [CLK_TWPLL_384M] = &twpll_384m.hw, + [CLK_TWPLL_192M] = &twpll_192m.hw, + [CLK_TWPLL_96M] = &twpll_96m.hw, + [CLK_TWPLL_48M] = &twpll_48m.hw, + [CLK_TWPLL_24M] = &twpll_24m.hw, + [CLK_TWPLL_12M] = &twpll_12m.hw, + [CLK_TWPLL_512M] = &twpll_512m.hw, + [CLK_TWPLL_256M] = &twpll_256m.hw, + [CLK_TWPLL_128M] = &twpll_128m.hw, + [CLK_TWPLL_64M] = &twpll_64m.hw, + [CLK_TWPLL_307M2] = &twpll_307m2.hw, + [CLK_TWPLL_153M6] = &twpll_153m6.hw, + [CLK_TWPLL_76M8] = &twpll_76m8.hw, + [CLK_TWPLL_51M2] = &twpll_51m2.hw, + [CLK_TWPLL_38M4] = &twpll_38m4.hw, + [CLK_TWPLL_19M2] = &twpll_19m2.hw, + [CLK_L0_614M4] = &l0_614m4.hw, + [CLK_L0_409M6] = &l0_409m6.hw, + [CLK_L0_38M] = &l0_38m.hw, + [CLK_L1_38M] = &l1_38m.hw, + [CLK_RPLL0_192M] = &rpll0_192m.hw, + [CLK_RPLL0_96M] = &rpll0_96m.hw, + [CLK_RPLL0_48M] = &rpll0_48m.hw, + [CLK_RPLL1_468M] = &rpll1_468m.hw, + [CLK_RPLL1_192M] = &rpll1_192m.hw, + [CLK_RPLL1_96M] = &rpll1_96m.hw, + [CLK_RPLL1_64M] = &rpll1_64m.hw, + [CLK_RPLL1_48M] = &rpll1_48m.hw, + [CLK_DPLL0_50M] = &dpll0_50m.hw, + [CLK_DPLL1_50M] = &dpll1_50m.hw, + [CLK_CPPLL_50M] = &cppll_50m.hw, + [CLK_M0_39M] = &m0_39m.hw, + [CLK_M1_63M] = &m1_63m.hw, + }, + .num = CLK_PLL_NUM, +}; + +static const struct sprd_clk_desc sc9860_pll_desc = { + .clk_clks = sc9860_pll_clks, + .num_clk_clks = ARRAY_SIZE(sc9860_pll_clks), + .hw_clks = &sc9860_pll_hws, +}; + +#define SC9860_MUX_FLAG \ + (CLK_GET_RATE_NOCACHE | CLK_SET_RATE_NO_REPARENT) + +static const char * const ap_apb_parents[] = { "ext-26m", "twpll-64m", + "twpll-96m", "twpll-128m" }; +static SPRD_MUX_CLK(ap_apb, "ap-apb", ap_apb_parents, + 0x20, 0, 1, SC9860_MUX_FLAG); + +static const char * const ap_apb_usb3[] = { "ext-32k", "twpll-24m" }; +static SPRD_MUX_CLK(ap_usb3, "ap-usb3", ap_apb_usb3, + 0x2c, 0, 1, SC9860_MUX_FLAG); + +static const char * const uart_parents[] = { "ext-26m", "twpll-48m", + "twpll-51m2", "twpll-96m" }; +static SPRD_COMP_CLK(uart0_clk, "uart0", uart_parents, 0x30, + 0, 2, 8, 3, 0); +static SPRD_COMP_CLK(uart1_clk, "uart1", uart_parents, 0x34, + 0, 2, 8, 3, 0); +static SPRD_COMP_CLK(uart2_clk, "uart2", uart_parents, 0x38, + 0, 2, 8, 3, 0); +static SPRD_COMP_CLK(uart3_clk, "uart3", uart_parents, 0x3c, + 0, 2, 8, 3, 0); +static SPRD_COMP_CLK(uart4_clk, "uart4", uart_parents, 0x40, + 0, 2, 8, 3, 0); + +static const char * const i2c_parents[] = { "ext-26m", "twpll-48m", + "twpll-51m2", "twpll-153m6" }; +static SPRD_COMP_CLK(i2c0_clk, "i2c0", i2c_parents, 0x44, + 0, 2, 8, 3, 0); +static SPRD_COMP_CLK(i2c1_clk, "i2c1", i2c_parents, 0x48, + 0, 2, 8, 3, 0); +static SPRD_COMP_CLK(i2c2_clk, "i2c2", i2c_parents, 0x4c, + 0, 2, 8, 3, 0); +static SPRD_COMP_CLK(i2c3_clk, "i2c3", i2c_parents, 0x50, + 0, 2, 8, 3, 0); +static SPRD_COMP_CLK(i2c4_clk, "i2c4", i2c_parents, 0x54, + 0, 2, 8, 3, 0); +static SPRD_COMP_CLK(i2c5_clk, "i2c5", i2c_parents, 0x58, + 0, 2, 8, 3, 0); + +static const char * const spi_parents[] = { "ext-26m", "twpll-128m", + "twpll-153m6", "twpll-192m" }; +static SPRD_COMP_CLK(spi0_clk, "spi0", spi_parents, 0x5c, + 0, 2, 8, 3, 0); +static SPRD_COMP_CLK(spi1_clk, "spi1", spi_parents, 0x60, + 0, 2, 8, 3, 0); +static SPRD_COMP_CLK(spi2_clk, "spi2", spi_parents, 0x64, + 0, 2, 8, 3, 0); +static SPRD_COMP_CLK(spi3_clk, "spi3", spi_parents, 0x68, + 0, 2, 8, 3, 0); + +static const char * const iis_parents[] = { "ext-26m", + "twpll-128m", + "twpll-153m6" }; +static SPRD_COMP_CLK(iis0_clk, "iis0", iis_parents, 0x6c, + 0, 2, 8, 6, 0); +static SPRD_COMP_CLK(iis1_clk, "iis1", iis_parents, 0x70, + 0, 2, 8, 6, 0); +static SPRD_COMP_CLK(iis2_clk, "iis2", iis_parents, 0x74, + 0, 2, 8, 6, 0); +static SPRD_COMP_CLK(iis3_clk, "iis3", iis_parents, 0x78, + 0, 2, 8, 6, 0); + +static struct sprd_clk_common *sc9860_ap_clks[] = { + /* address base is 0x20000000 */ + &ap_apb.common, + &ap_usb3.common, + &uart0_clk.common, + &uart1_clk.common, + &uart2_clk.common, + &uart3_clk.common, + &uart4_clk.common, + &i2c0_clk.common, + &i2c1_clk.common, + &i2c2_clk.common, + &i2c3_clk.common, + &i2c4_clk.common, + &i2c5_clk.common, + &spi0_clk.common, + &spi1_clk.common, + &spi2_clk.common, + &spi3_clk.common, + &iis0_clk.common, + &iis1_clk.common, + &iis2_clk.common, + &iis3_clk.common, +}; + +static struct clk_hw_onecell_data sc9860_ap_clk_hws = { + .hws = { + [CLK_AP_APB] = &ap_apb.common.hw, + [CLK_AP_USB3] = &ap_usb3.common.hw, + [CLK_UART0] = &uart0_clk.common.hw, + [CLK_UART1] = &uart1_clk.common.hw, + [CLK_UART2] = &uart2_clk.common.hw, + [CLK_UART3] = &uart3_clk.common.hw, + [CLK_UART4] = &uart4_clk.common.hw, + [CLK_I2C0] = &i2c0_clk.common.hw, + [CLK_I2C1] = &i2c1_clk.common.hw, + [CLK_I2C2] = &i2c2_clk.common.hw, + [CLK_I2C3] = &i2c3_clk.common.hw, + [CLK_I2C4] = &i2c4_clk.common.hw, + [CLK_I2C5] = &i2c5_clk.common.hw, + [CLK_SPI0] = &spi0_clk.common.hw, + [CLK_SPI1] = &spi1_clk.common.hw, + [CLK_SPI2] = &spi2_clk.common.hw, + [CLK_SPI3] = &spi3_clk.common.hw, + [CLK_IIS0] = &iis0_clk.common.hw, + [CLK_IIS1] = &iis1_clk.common.hw, + [CLK_IIS2] = &iis2_clk.common.hw, + [CLK_IIS3] = &iis3_clk.common.hw, + }, + .num = CLK_AP_CLK_NUM, +}; + +static const struct sprd_clk_desc sc9860_ap_clk_desc = { + .clk_clks = sc9860_ap_clks, + .num_clk_clks = ARRAY_SIZE(sc9860_ap_clks), + .hw_clks = &sc9860_ap_clk_hws, +}; + +static const char * const aon_apb_parents[] = { "rco-25m", "ext-26m", + "ext-rco-100m", "twpll-96m", + "twpll-128m", + "twpll-153m6" }; +static SPRD_COMP_CLK(aon_apb, "aon-apb", aon_apb_parents, 0x230, + 0, 3, 8, 2, 0); + +static const char * const aux_parents[] = { "ext-32k", "rpll0-26m", + "rpll1-26m", "ext-26m", + "cppll-50m", "rco-25m", + "dpll0-50m", "dpll1-50m", + "gpll-42m5", "twpll-48m", + "m0-39m", "m1-63m", + "l0-38m", "l1-38m" }; + +static SPRD_COMP_CLK(aux0_clk, "aux0", aux_parents, 0x238, + 0, 5, 8, 4, 0); +static SPRD_COMP_CLK(aux1_clk, "aux1", aux_parents, 0x23c, + 0, 5, 8, 4, 0); +static SPRD_COMP_CLK(aux2_clk, "aux2", aux_parents, 0x240, + 0, 5, 8, 4, 0); +static SPRD_COMP_CLK(probe_clk, "probe", aux_parents, 0x244, + 0, 5, 8, 4, 0); + +static const char * const sp_ahb_parents[] = { "rco-4m", "ext-26m", + "ext-rco-100m", "twpll-96m", + "twpll-128m", + "twpll-153m6" }; +static SPRD_COMP_CLK(sp_ahb, "sp-ahb", sp_ahb_parents, 0x2d0, + 0, 3, 8, 2, 0); + +static const char * const cci_parents[] = { "ext-26m", "twpll-384m", + "l0-614m4", "twpll-768m" }; +static SPRD_COMP_CLK(cci_clk, "cci", cci_parents, 0x300, + 0, 2, 8, 2, 0); +static SPRD_COMP_CLK(gic_clk, "gic", cci_parents, 0x304, + 0, 2, 8, 2, 0); +static SPRD_COMP_CLK(cssys_clk, "cssys", cci_parents, 0x310, + 0, 2, 8, 2, 0); + +static const char * const sdio_2x_parents[] = { "fac-1m", "ext-26m", + "twpll-307m2", "twpll-384m", + "l0-409m6" }; +static SPRD_COMP_CLK(sdio0_2x, "sdio0-2x", sdio_2x_parents, 0x328, + 0, 3, 8, 4, 0); +static SPRD_COMP_CLK(sdio1_2x, "sdio1-2x", sdio_2x_parents, 0x330, + 0, 3, 8, 4, 0); +static SPRD_COMP_CLK(sdio2_2x, "sdio2-2x", sdio_2x_parents, 0x338, + 0, 3, 8, 4, 0); +static SPRD_COMP_CLK(emmc_2x, "emmc-2x", sdio_2x_parents, 0x340, + 0, 3, 8, 4, 0); + +static SPRD_DIV_CLK(sdio0_1x, "sdio0-1x", "sdio0-2x", 0x32c, + 8, 1, 0); +static SPRD_DIV_CLK(sdio1_1x, "sdio1-1x", "sdio1-2x", 0x334, + 8, 1, 0); +static SPRD_DIV_CLK(sdio2_1x, "sdio2-1x", "sdio2-2x", 0x33c, + 8, 1, 0); +static SPRD_DIV_CLK(emmc_1x, "emmc-1x", "emmc-2x", 0x344, + 8, 1, 0); + +static const char * const adi_parents[] = { "rco-4m", "ext-26m", + "rco-25m", "twpll-38m4", + "twpll-51m2" }; +static SPRD_MUX_CLK(adi_clk, "adi", adi_parents, 0x234, + 0, 3, SC9860_MUX_FLAG); + +static const char * const pwm_parents[] = { "ext-32k", "ext-26m", + "rco-4m", "rco-25m", + "twpll-48m" }; +static SPRD_MUX_CLK(pwm0_clk, "pwm0", pwm_parents, 0x248, + 0, 3, SC9860_MUX_FLAG); +static SPRD_MUX_CLK(pwm1_clk, "pwm1", pwm_parents, 0x24c, + 0, 3, SC9860_MUX_FLAG); +static SPRD_MUX_CLK(pwm2_clk, "pwm2", pwm_parents, 0x250, + 0, 3, SC9860_MUX_FLAG); +static SPRD_MUX_CLK(pwm3_clk, "pwm3", pwm_parents, 0x254, + 0, 3, SC9860_MUX_FLAG); + +static const char * const efuse_parents[] = { "rco-25m", "ext-26m" }; +static SPRD_MUX_CLK(efuse_clk, "efuse", efuse_parents, 0x258, + 0, 1, SC9860_MUX_FLAG); + +static const char * const cm3_uart_parents[] = { "rco-4m", "ext-26m", + "rco-100m", "twpll-48m", + "twpll-51m2", "twpll-96m", + "twpll-128m" }; +static SPRD_MUX_CLK(cm3_uart0, "cm3-uart0", cm3_uart_parents, 0x25c, + 0, 3, SC9860_MUX_FLAG); +static SPRD_MUX_CLK(cm3_uart1, "cm3-uart1", cm3_uart_parents, 0x260, + 0, 3, SC9860_MUX_FLAG); + +static const char * const thm_parents[] = { "ext-32k", "fac-250k" }; +static SPRD_MUX_CLK(thm_clk, "thm", thm_parents, 0x270, + 0, 1, SC9860_MUX_FLAG); + +static const char * const cm3_i2c_parents[] = { "rco-4m", + "ext-26m", + "rco-100m", + "twpll-48m", + "twpll-51m2", + "twpll-153m6" }; +static SPRD_MUX_CLK(cm3_i2c0, "cm3-i2c0", cm3_i2c_parents, 0x274, + 0, 3, SC9860_MUX_FLAG); +static SPRD_MUX_CLK(cm3_i2c1, "cm3-i2c1", cm3_i2c_parents, 0x278, + 0, 3, SC9860_MUX_FLAG); +static SPRD_MUX_CLK(aon_i2c, "aon-i2c", cm3_i2c_parents, 0x280, + 0, 3, SC9860_MUX_FLAG); + +static const char * const cm4_spi_parents[] = { "ext-26m", "twpll-96m", + "rco-100m", "twpll-128m", + "twpll-153m6", "twpll-192m" }; +static SPRD_MUX_CLK(cm4_spi, "cm4-spi", cm4_spi_parents, 0x27c, + 0, 3, SC9860_MUX_FLAG); + +static SPRD_MUX_CLK(avs_clk, "avs", uart_parents, 0x284, + 0, 2, SC9860_MUX_FLAG); + +static const char * const ca53_dap_parents[] = { "ext-26m", "rco-4m", + "rco-100m", "twpll-76m8", + "twpll-128m", "twpll-153m6" }; +static SPRD_MUX_CLK(ca53_dap, "ca53-dap", ca53_dap_parents, 0x288, + 0, 3, SC9860_MUX_FLAG); + +static const char * const ca53_ts_parents[] = { "ext-32k", "ext-26m", + "clk-twpll-128m", + "clk-twpll-153m6" }; +static SPRD_MUX_CLK(ca53_ts, "ca53-ts", ca53_ts_parents, 0x290, + 0, 2, SC9860_MUX_FLAG); + +static const char * const djtag_tck_parents[] = { "rco-4m", "ext-26m" }; +static SPRD_MUX_CLK(djtag_tck, "djtag-tck", djtag_tck_parents, 0x2c8, + 0, 1, SC9860_MUX_FLAG); + +static const char * const pmu_parents[] = { "ext-32k", "rco-4m", "clk-4m" }; +static SPRD_MUX_CLK(pmu_clk, "pmu", pmu_parents, 0x2e0, + 0, 2, SC9860_MUX_FLAG); + +static const char * const pmu_26m_parents[] = { "rco-25m", "ext-26m" }; +static SPRD_MUX_CLK(pmu_26m, "pmu-26m", pmu_26m_parents, 0x2e4, + 0, 1, SC9860_MUX_FLAG); + +static const char * const debounce_parents[] = { "ext-32k", "rco-4m", + "rco-25m", "ext-26m" }; +static SPRD_MUX_CLK(debounce_clk, "debounce", debounce_parents, 0x2e8, + 0, 2, SC9860_MUX_FLAG); + +static const char * const otg2_ref_parents[] = { "twpll-12m", "twpll-24m" }; +static SPRD_MUX_CLK(otg2_ref, "otg2-ref", otg2_ref_parents, 0x2f4, + 0, 1, SC9860_MUX_FLAG); + +static const char * const usb3_ref_parents[] = { "twpll-24m", "twpll-19m2", + "twpll-48m" }; +static SPRD_MUX_CLK(usb3_ref, "usb3-ref", usb3_ref_parents, 0x2f8, + 0, 2, SC9860_MUX_FLAG); + +static const char * const ap_axi_parents[] = { "ext-26m", "twpll-76m8", + "twpll-128m", "twpll-256m" }; +static SPRD_MUX_CLK(ap_axi, "ap-axi", ap_axi_parents, 0x324, + 0, 2, SC9860_MUX_FLAG); + +static struct sprd_clk_common *sc9860_aon_prediv[] = { + /* address base is 0x402d0000 */ + &aon_apb.common, + &aux0_clk.common, + &aux1_clk.common, + &aux2_clk.common, + &probe_clk.common, + &sp_ahb.common, + &cci_clk.common, + &gic_clk.common, + &cssys_clk.common, + &sdio0_2x.common, + &sdio1_2x.common, + &sdio2_2x.common, + &emmc_2x.common, + &sdio0_1x.common, + &sdio1_1x.common, + &sdio2_1x.common, + &emmc_1x.common, + &adi_clk.common, + &pwm0_clk.common, + &pwm1_clk.common, + &pwm2_clk.common, + &pwm3_clk.common, + &efuse_clk.common, + &cm3_uart0.common, + &cm3_uart1.common, + &thm_clk.common, + &cm3_i2c0.common, + &cm3_i2c1.common, + &cm4_spi.common, + &aon_i2c.common, + &avs_clk.common, + &ca53_dap.common, + &ca53_ts.common, + &djtag_tck.common, + &pmu_clk.common, + &pmu_26m.common, + &debounce_clk.common, + &otg2_ref.common, + &usb3_ref.common, + &ap_axi.common, +}; + +static struct clk_hw_onecell_data sc9860_aon_prediv_hws = { + .hws = { + [CLK_AON_APB] = &aon_apb.common.hw, + [CLK_AUX0] = &aux0_clk.common.hw, + [CLK_AUX1] = &aux1_clk.common.hw, + [CLK_AUX2] = &aux2_clk.common.hw, + [CLK_PROBE] = &probe_clk.common.hw, + [CLK_SP_AHB] = &sp_ahb.common.hw, + [CLK_CCI] = &cci_clk.common.hw, + [CLK_GIC] = &gic_clk.common.hw, + [CLK_CSSYS] = &cssys_clk.common.hw, + [CLK_SDIO0_2X] = &sdio0_2x.common.hw, + [CLK_SDIO1_2X] = &sdio1_2x.common.hw, + [CLK_SDIO2_2X] = &sdio2_2x.common.hw, + [CLK_EMMC_2X] = &emmc_2x.common.hw, + [CLK_SDIO0_1X] = &sdio0_1x.common.hw, + [CLK_SDIO1_1X] = &sdio1_1x.common.hw, + [CLK_SDIO2_1X] = &sdio2_1x.common.hw, + [CLK_EMMC_1X] = &emmc_1x.common.hw, + [CLK_ADI] = &adi_clk.common.hw, + [CLK_PWM0] = &pwm0_clk.common.hw, + [CLK_PWM1] = &pwm1_clk.common.hw, + [CLK_PWM2] = &pwm2_clk.common.hw, + [CLK_PWM3] = &pwm3_clk.common.hw, + [CLK_EFUSE] = &efuse_clk.common.hw, + [CLK_CM3_UART0] = &cm3_uart0.common.hw, + [CLK_CM3_UART1] = &cm3_uart1.common.hw, + [CLK_THM] = &thm_clk.common.hw, + [CLK_CM3_I2C0] = &cm3_i2c0.common.hw, + [CLK_CM3_I2C1] = &cm3_i2c1.common.hw, + [CLK_CM4_SPI] = &cm4_spi.common.hw, + [CLK_AON_I2C] = &aon_i2c.common.hw, + [CLK_AVS] = &avs_clk.common.hw, + [CLK_CA53_DAP] = &ca53_dap.common.hw, + [CLK_CA53_TS] = &ca53_ts.common.hw, + [CLK_DJTAG_TCK] = &djtag_tck.common.hw, + [CLK_PMU] = &pmu_clk.common.hw, + [CLK_PMU_26M] = &pmu_26m.common.hw, + [CLK_DEBOUNCE] = &debounce_clk.common.hw, + [CLK_OTG2_REF] = &otg2_ref.common.hw, + [CLK_USB3_REF] = &usb3_ref.common.hw, + [CLK_AP_AXI] = &ap_axi.common.hw, + }, + .num = CLK_AON_PREDIV_NUM, +}; + +static const struct sprd_clk_desc sc9860_aon_prediv_desc = { + .clk_clks = sc9860_aon_prediv, + .num_clk_clks = ARRAY_SIZE(sc9860_aon_prediv), + .hw_clks = &sc9860_aon_prediv_hws, +}; + +static SPRD_SC_GATE_CLK(usb3_eb, "usb3-eb", "ap-axi", 0x0, + 0x1000, BIT(2), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK(usb3_suspend, "usb3-suspend", "ap-axi", 0x0, + 0x1000, BIT(3), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK(usb3_ref_eb, "usb3-ref-eb", "ap-axi", 0x0, + 0x1000, BIT(4), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK(dma_eb, "dma-eb", "ap-axi", 0x0, + 0x1000, BIT(5), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK(sdio0_eb, "sdio0-eb", "ap-axi", 0x0, + 0x1000, BIT(7), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK(sdio1_eb, "sdio1-eb", "ap-axi", 0x0, + 0x1000, BIT(8), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK(sdio2_eb, "sdio2-eb", "ap-axi", 0x0, + 0x1000, BIT(9), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK(emmc_eb, "emmc-eb", "ap-axi", 0x0, + 0x1000, BIT(10), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK(rom_eb, "rom-eb", "ap-axi", 0x0, + 0x1000, BIT(12), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK(busmon_eb, "busmon-eb", "ap-axi", 0x0, + 0x1000, BIT(13), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK(cc63s_eb, "cc63s-eb", "ap-axi", 0x0, + 0x1000, BIT(22), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK(cc63p_eb, "cc63p-eb", "ap-axi", 0x0, + 0x1000, BIT(23), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK(ce0_eb, "ce0-eb", "ap-axi", 0x0, + 0x1000, BIT(24), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK(ce1_eb, "ce1-eb", "ap-axi", 0x0, + 0x1000, BIT(25), CLK_IGNORE_UNUSED, 0); + +static struct sprd_clk_common *sc9860_apahb_gate[] = { + /* address base is 0x20210000 */ + &usb3_eb.common, + &usb3_suspend.common, + &usb3_ref_eb.common, + &dma_eb.common, + &sdio0_eb.common, + &sdio1_eb.common, + &sdio2_eb.common, + &emmc_eb.common, + &rom_eb.common, + &busmon_eb.common, + &cc63s_eb.common, + &cc63p_eb.common, + &ce0_eb.common, + &ce1_eb.common, +}; + +static struct clk_hw_onecell_data sc9860_apahb_gate_hws = { + .hws = { + [CLK_USB3_EB] = &usb3_eb.common.hw, + [CLK_USB3_SUSPEND_EB] = &usb3_suspend.common.hw, + [CLK_USB3_REF_EB] = &usb3_ref_eb.common.hw, + [CLK_DMA_EB] = &dma_eb.common.hw, + [CLK_SDIO0_EB] = &sdio0_eb.common.hw, + [CLK_SDIO1_EB] = &sdio1_eb.common.hw, + [CLK_SDIO2_EB] = &sdio2_eb.common.hw, + [CLK_EMMC_EB] = &emmc_eb.common.hw, + [CLK_ROM_EB] = &rom_eb.common.hw, + [CLK_BUSMON_EB] = &busmon_eb.common.hw, + [CLK_CC63S_EB] = &cc63s_eb.common.hw, + [CLK_CC63P_EB] = &cc63p_eb.common.hw, + [CLK_CE0_EB] = &ce0_eb.common.hw, + [CLK_CE1_EB] = &ce1_eb.common.hw, + }, + .num = CLK_APAHB_GATE_NUM, +}; + +static const struct sprd_clk_desc sc9860_apahb_gate_desc = { + .clk_clks = sc9860_apahb_gate, + .num_clk_clks = ARRAY_SIZE(sc9860_apahb_gate), + .hw_clks = &sc9860_apahb_gate_hws, +}; + +static SPRD_SC_GATE_CLK(avs_lit_eb, "avs-lit-eb", "aon-apb", 0x0, + 0x1000, BIT(0), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK(avs_big_eb, "avs-big-eb", "aon-apb", 0x0, + 0x1000, BIT(1), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK(ap_intc5_eb, "ap-intc5-eb", "aon-apb", 0x0, + 0x1000, BIT(2), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK(gpio_eb, "gpio-eb", "aon-apb", 0x0, + 0x1000, BIT(3), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK(pwm0_eb, "pwm0-eb", "aon-apb", 0x0, + 0x1000, BIT(4), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK(pwm1_eb, "pwm1-eb", "aon-apb", 0x0, + 0x1000, BIT(5), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK(pwm2_eb, "pwm2-eb", "aon-apb", 0x0, + 0x1000, BIT(6), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK(pwm3_eb, "pwm3-eb", "aon-apb", 0x0, + 0x1000, BIT(7), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK(kpd_eb, "kpd-eb", "aon-apb", 0x0, + 0x1000, BIT(8), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK(aon_sys_eb, "aon-sys-eb", "aon-apb", 0x0, + 0x1000, BIT(9), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK(ap_sys_eb, "ap-sys-eb", "aon-apb", 0x0, + 0x1000, BIT(10), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK(aon_tmr_eb, "aon-tmr-eb", "aon-apb", 0x0, + 0x1000, BIT(11), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK(ap_tmr0_eb, "ap-tmr0-eb", "aon-apb", 0x0, + 0x1000, BIT(12), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK(efuse_eb, "efuse-eb", "aon-apb", 0x0, + 0x1000, BIT(13), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK(eic_eb, "eic-eb", "aon-apb", 0x0, + 0x1000, BIT(14), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK(pub1_reg_eb, "pub1-reg-eb", "aon-apb", 0x0, + 0x1000, BIT(15), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK(adi_eb, "adi-eb", "aon-apb", 0x0, + 0x1000, BIT(16), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK(ap_intc0_eb, "ap-intc0-eb", "aon-apb", 0x0, + 0x1000, BIT(17), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK(ap_intc1_eb, "ap-intc1-eb", "aon-apb", 0x0, + 0x1000, BIT(18), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK(ap_intc2_eb, "ap-intc2-eb", "aon-apb", 0x0, + 0x1000, BIT(19), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK(ap_intc3_eb, "ap-intc3-eb", "aon-apb", 0x0, + 0x1000, BIT(20), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK(ap_intc4_eb, "ap-intc4-eb", "aon-apb", 0x0, + 0x1000, BIT(21), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK(splk_eb, "splk-eb", "aon-apb", 0x0, + 0x1000, BIT(22), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK(mspi_eb, "mspi-eb", "aon-apb", 0x0, + 0x1000, BIT(23), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK(pub0_reg_eb, "pub0-reg-eb", "aon-apb", 0x0, + 0x1000, BIT(24), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK(pin_eb, "pin-eb", "aon-apb", 0x0, + 0x1000, BIT(25), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK(aon_ckg_eb, "aon-ckg-eb", "aon-apb", 0x0, + 0x1000, BIT(26), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK(gpu_eb, "gpu-eb", "aon-apb", 0x0, + 0x1000, BIT(27), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK(apcpu_ts0_eb, "apcpu-ts0-eb", "aon-apb", 0x0, + 0x1000, BIT(28), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK(apcpu_ts1_eb, "apcpu-ts1-eb", "aon-apb", 0x0, + 0x1000, BIT(29), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK(dap_eb, "dap-eb", "aon-apb", 0x0, + 0x1000, BIT(30), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK(i2c_eb, "i2c-eb", "aon-apb", 0x0, + 0x1000, BIT(31), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK(pmu_eb, "pmu-eb", "aon-apb", 0x4, + 0x1000, BIT(0), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK(thm_eb, "thm-eb", "aon-apb", 0x4, + 0x1000, BIT(1), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK(aux0_eb, "aux0-eb", "aon-apb", 0x4, + 0x1000, BIT(2), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK(aux1_eb, "aux1-eb", "aon-apb", 0x4, + 0x1000, BIT(3), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK(aux2_eb, "aux2-eb", "aon-apb", 0x4, + 0x1000, BIT(4), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK(probe_eb, "probe-eb", "aon-apb", 0x4, + 0x1000, BIT(5), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK(gpu0_avs_eb, "gpu0-avs-eb", "aon-apb", 0x4, + 0x1000, BIT(6), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK(gpu1_avs_eb, "gpu1-avs-eb", "aon-apb", 0x4, + 0x1000, BIT(7), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK(apcpu_wdg_eb, "apcpu-wdg-eb", "aon-apb", 0x4, + 0x1000, BIT(8), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK(ap_tmr1_eb, "ap-tmr1-eb", "aon-apb", 0x4, + 0x1000, BIT(9), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK(ap_tmr2_eb, "ap-tmr2-eb", "aon-apb", 0x4, + 0x1000, BIT(10), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK(disp_emc_eb, "disp-emc-eb", "aon-apb", 0x4, + 0x1000, BIT(11), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK(zip_emc_eb, "zip-emc-eb", "aon-apb", 0x4, + 0x1000, BIT(12), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK(gsp_emc_eb, "gsp-emc-eb", "aon-apb", 0x4, + 0x1000, BIT(13), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK(osc_aon_eb, "osc-aon-eb", "aon-apb", 0x4, + 0x1000, BIT(14), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK(lvds_trx_eb, "lvds-trx-eb", "aon-apb", 0x4, + 0x1000, BIT(15), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK(lvds_tcxo_eb, "lvds-tcxo-eb", "aon-apb", 0x4, + 0x1000, BIT(16), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK(mdar_eb, "mdar-eb", "aon-apb", 0x4, + 0x1000, BIT(17), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK(rtc4m0_cal_eb, "rtc4m0-cal-eb", "aon-apb", 0x4, + 0x1000, BIT(18), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK(rct100m_cal_eb, "rct100m-cal-eb", "aon-apb", 0x4, + 0x1000, BIT(19), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK(djtag_eb, "djtag-eb", "aon-apb", 0x4, + 0x1000, BIT(20), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK(mbox_eb, "mbox-eb", "aon-apb", 0x4, + 0x1000, BIT(21), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK(aon_dma_eb, "aon-dma-eb", "aon-apb", 0x4, + 0x1000, BIT(22), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK(dbg_emc_eb, "dbg-emc-eb", "aon-apb", 0x4, + 0x1000, BIT(23), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK(lvds_pll_div_en, "lvds-pll-div-en", "aon-apb", 0x4, + 0x1000, BIT(24), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK(def_eb, "def-eb", "aon-apb", 0x4, + 0x1000, BIT(25), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK(aon_apb_rsv0, "aon-apb-rsv0", "aon-apb", 0x4, + 0x1000, BIT(26), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK(orp_jtag_eb, "orp-jtag-eb", "aon-apb", 0x4, + 0x1000, BIT(27), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK(vsp_eb, "vsp-eb", "aon-apb", 0x4, + 0x1000, BIT(28), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK(cam_eb, "cam-eb", "aon-apb", 0x4, + 0x1000, BIT(29), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK(disp_eb, "disp-eb", "aon-apb", 0x4, + 0x1000, BIT(30), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK(dbg_axi_if_eb, "dbg-axi-if-eb", "aon-apb", 0x4, + 0x1000, BIT(31), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK(sdio0_2x_en, "sdio0-2x-en", "aon-apb", 0x13c, + 0x1000, BIT(2), 0, 0); +static SPRD_SC_GATE_CLK(sdio1_2x_en, "sdio1-2x-en", "aon-apb", 0x13c, + 0x1000, BIT(4), 0, 0); +static SPRD_SC_GATE_CLK(sdio2_2x_en, "sdio2-2x-en", "aon-apb", 0x13c, + 0x1000, BIT(6), 0, 0); +static SPRD_SC_GATE_CLK(emmc_2x_en, "emmc-2x-en", "aon-apb", 0x13c, + 0x1000, BIT(9), 0, 0); +static SPRD_SC_GATE_CLK(arch_rtc_eb, "arch-rtc-eb", "aon-apb", 0x10, + 0x1000, BIT(0), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK(kpb_rtc_eb, "kpb-rtc-eb", "aon-apb", 0x10, + 0x1000, BIT(1), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK(aon_syst_rtc_eb, "aon-syst-rtc-eb", "aon-apb", 0x10, + 0x1000, BIT(2), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK(ap_syst_rtc_eb, "ap-syst-rtc-eb", "aon-apb", 0x10, + 0x1000, BIT(3), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK(aon_tmr_rtc_eb, "aon-tmr-rtc-eb", "aon-apb", 0x10, + 0x1000, BIT(4), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK(ap_tmr0_rtc_eb, "ap-tmr0-rtc-eb", "aon-apb", 0x10, + 0x1000, BIT(5), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK(eic_rtc_eb, "eic-rtc-eb", "aon-apb", 0x10, + 0x1000, BIT(6), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK(eic_rtcdv5_eb, "eic-rtcdv5-eb", "aon-apb", 0x10, + 0x1000, BIT(7), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK(ap_wdg_rtc_eb, "ap-wdg-rtc-eb", "aon-apb", 0x10, + 0x1000, BIT(9), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK(ap_tmr1_rtc_eb, "ap-tmr1-rtc-eb", "aon-apb", 0x10, + 0x1000, BIT(15), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK(ap_tmr2_rtc_eb, "ap-tmr2-rtc-eb", "aon-apb", 0x10, + 0x1000, BIT(16), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK(dcxo_tmr_rtc_eb, "dcxo-tmr-rtc-eb", "aon-apb", 0x10, + 0x1000, BIT(17), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK(bb_cal_rtc_eb, "bb-cal-rtc-eb", "aon-apb", 0x10, + 0x1000, BIT(18), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK(avs_big_rtc_eb, "avs-big-rtc-eb", "aon-apb", 0x10, + 0x1000, BIT(20), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK(avs_lit_rtc_eb, "avs-lit-rtc-eb", "aon-apb", 0x10, + 0x1000, BIT(21), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK(avs_gpu0_rtc_eb, "avs-gpu0-rtc-eb", "aon-apb", 0x10, + 0x1000, BIT(22), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK(avs_gpu1_rtc_eb, "avs-gpu1-rtc-eb", "aon-apb", 0x10, + 0x1000, BIT(23), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK(gpu_ts_eb, "gpu-ts-eb", "aon-apb", 0x10, + 0x1000, BIT(24), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK(rtcdv10_eb, "rtcdv10-eb", "aon-apb", 0x10, + 0x1000, BIT(27), CLK_IGNORE_UNUSED, 0); + +static struct sprd_clk_common *sc9860_aon_gate[] = { + /* address base is 0x402e0000 */ + &avs_lit_eb.common, + &avs_big_eb.common, + &ap_intc5_eb.common, + &gpio_eb.common, + &pwm0_eb.common, + &pwm1_eb.common, + &pwm2_eb.common, + &pwm3_eb.common, + &kpd_eb.common, + &aon_sys_eb.common, + &ap_sys_eb.common, + &aon_tmr_eb.common, + &ap_tmr0_eb.common, + &efuse_eb.common, + &eic_eb.common, + &pub1_reg_eb.common, + &adi_eb.common, + &ap_intc0_eb.common, + &ap_intc1_eb.common, + &ap_intc2_eb.common, + &ap_intc3_eb.common, + &ap_intc4_eb.common, + &splk_eb.common, + &mspi_eb.common, + &pub0_reg_eb.common, + &pin_eb.common, + &aon_ckg_eb.common, + &gpu_eb.common, + &apcpu_ts0_eb.common, + &apcpu_ts1_eb.common, + &dap_eb.common, + &i2c_eb.common, + &pmu_eb.common, + &thm_eb.common, + &aux0_eb.common, + &aux1_eb.common, + &aux2_eb.common, + &probe_eb.common, + &gpu0_avs_eb.common, + &gpu1_avs_eb.common, + &apcpu_wdg_eb.common, + &ap_tmr1_eb.common, + &ap_tmr2_eb.common, + &disp_emc_eb.common, + &zip_emc_eb.common, + &gsp_emc_eb.common, + &osc_aon_eb.common, + &lvds_trx_eb.common, + &lvds_tcxo_eb.common, + &mdar_eb.common, + &rtc4m0_cal_eb.common, + &rct100m_cal_eb.common, + &djtag_eb.common, + &mbox_eb.common, + &aon_dma_eb.common, + &dbg_emc_eb.common, + &lvds_pll_div_en.common, + &def_eb.common, + &aon_apb_rsv0.common, + &orp_jtag_eb.common, + &vsp_eb.common, + &cam_eb.common, + &disp_eb.common, + &dbg_axi_if_eb.common, + &sdio0_2x_en.common, + &sdio1_2x_en.common, + &sdio2_2x_en.common, + &emmc_2x_en.common, + &arch_rtc_eb.common, + &kpb_rtc_eb.common, + &aon_syst_rtc_eb.common, + &ap_syst_rtc_eb.common, + &aon_tmr_rtc_eb.common, + &ap_tmr0_rtc_eb.common, + &eic_rtc_eb.common, + &eic_rtcdv5_eb.common, + &ap_wdg_rtc_eb.common, + &ap_tmr1_rtc_eb.common, + &ap_tmr2_rtc_eb.common, + &dcxo_tmr_rtc_eb.common, + &bb_cal_rtc_eb.common, + &avs_big_rtc_eb.common, + &avs_lit_rtc_eb.common, + &avs_gpu0_rtc_eb.common, + &avs_gpu1_rtc_eb.common, + &gpu_ts_eb.common, + &rtcdv10_eb.common, +}; + +static struct clk_hw_onecell_data sc9860_aon_gate_hws = { + .hws = { + [CLK_AVS_LIT_EB] = &avs_lit_eb.common.hw, + [CLK_AVS_BIG_EB] = &avs_big_eb.common.hw, + [CLK_AP_INTC5_EB] = &ap_intc5_eb.common.hw, + [CLK_GPIO_EB] = &gpio_eb.common.hw, + [CLK_PWM0_EB] = &pwm0_eb.common.hw, + [CLK_PWM1_EB] = &pwm1_eb.common.hw, + [CLK_PWM2_EB] = &pwm2_eb.common.hw, + [CLK_PWM3_EB] = &pwm3_eb.common.hw, + [CLK_KPD_EB] = &kpd_eb.common.hw, + [CLK_AON_SYS_EB] = &aon_sys_eb.common.hw, + [CLK_AP_SYS_EB] = &ap_sys_eb.common.hw, + [CLK_AON_TMR_EB] = &aon_tmr_eb.common.hw, + [CLK_AP_TMR0_EB] = &ap_tmr0_eb.common.hw, + [CLK_EFUSE_EB] = &efuse_eb.common.hw, + [CLK_EIC_EB] = &eic_eb.common.hw, + [CLK_PUB1_REG_EB] = &pub1_reg_eb.common.hw, + [CLK_ADI_EB] = &adi_eb.common.hw, + [CLK_AP_INTC0_EB] = &ap_intc0_eb.common.hw, + [CLK_AP_INTC1_EB] = &ap_intc1_eb.common.hw, + [CLK_AP_INTC2_EB] = &ap_intc2_eb.common.hw, + [CLK_AP_INTC3_EB] = &ap_intc3_eb.common.hw, + [CLK_AP_INTC4_EB] = &ap_intc4_eb.common.hw, + [CLK_SPLK_EB] = &splk_eb.common.hw, + [CLK_MSPI_EB] = &mspi_eb.common.hw, + [CLK_PUB0_REG_EB] = &pub0_reg_eb.common.hw, + [CLK_PIN_EB] = &pin_eb.common.hw, + [CLK_AON_CKG_EB] = &aon_ckg_eb.common.hw, + [CLK_GPU_EB] = &gpu_eb.common.hw, + [CLK_APCPU_TS0_EB] = &apcpu_ts0_eb.common.hw, + [CLK_APCPU_TS1_EB] = &apcpu_ts1_eb.common.hw, + [CLK_DAP_EB] = &dap_eb.common.hw, + [CLK_I2C_EB] = &i2c_eb.common.hw, + [CLK_PMU_EB] = &pmu_eb.common.hw, + [CLK_THM_EB] = &thm_eb.common.hw, + [CLK_AUX0_EB] = &aux0_eb.common.hw, + [CLK_AUX1_EB] = &aux1_eb.common.hw, + [CLK_AUX2_EB] = &aux2_eb.common.hw, + [CLK_PROBE_EB] = &probe_eb.common.hw, + [CLK_GPU0_AVS_EB] = &gpu0_avs_eb.common.hw, + [CLK_GPU1_AVS_EB] = &gpu1_avs_eb.common.hw, + [CLK_APCPU_WDG_EB] = &apcpu_wdg_eb.common.hw, + [CLK_AP_TMR1_EB] = &ap_tmr1_eb.common.hw, + [CLK_AP_TMR2_EB] = &ap_tmr2_eb.common.hw, + [CLK_DISP_EMC_EB] = &disp_emc_eb.common.hw, + [CLK_ZIP_EMC_EB] = &zip_emc_eb.common.hw, + [CLK_GSP_EMC_EB] = &gsp_emc_eb.common.hw, + [CLK_OSC_AON_EB] = &osc_aon_eb.common.hw, + [CLK_LVDS_TRX_EB] = &lvds_trx_eb.common.hw, + [CLK_LVDS_TCXO_EB] = &lvds_tcxo_eb.common.hw, + [CLK_MDAR_EB] = &mdar_eb.common.hw, + [CLK_RTC4M0_CAL_EB] = &rtc4m0_cal_eb.common.hw, + [CLK_RCT100M_CAL_EB] = &rct100m_cal_eb.common.hw, + [CLK_DJTAG_EB] = &djtag_eb.common.hw, + [CLK_MBOX_EB] = &mbox_eb.common.hw, + [CLK_AON_DMA_EB] = &aon_dma_eb.common.hw, + [CLK_DBG_EMC_EB] = &dbg_emc_eb.common.hw, + [CLK_LVDS_PLL_DIV_EN] = &lvds_pll_div_en.common.hw, + [CLK_DEF_EB] = &def_eb.common.hw, + [CLK_AON_APB_RSV0] = &aon_apb_rsv0.common.hw, + [CLK_ORP_JTAG_EB] = &orp_jtag_eb.common.hw, + [CLK_VSP_EB] = &vsp_eb.common.hw, + [CLK_CAM_EB] = &cam_eb.common.hw, + [CLK_DISP_EB] = &disp_eb.common.hw, + [CLK_DBG_AXI_IF_EB] = &dbg_axi_if_eb.common.hw, + [CLK_SDIO0_2X_EN] = &sdio0_2x_en.common.hw, + [CLK_SDIO1_2X_EN] = &sdio1_2x_en.common.hw, + [CLK_SDIO2_2X_EN] = &sdio2_2x_en.common.hw, + [CLK_EMMC_2X_EN] = &emmc_2x_en.common.hw, + [CLK_ARCH_RTC_EB] = &arch_rtc_eb.common.hw, + [CLK_KPB_RTC_EB] = &kpb_rtc_eb.common.hw, + [CLK_AON_SYST_RTC_EB] = &aon_syst_rtc_eb.common.hw, + [CLK_AP_SYST_RTC_EB] = &ap_syst_rtc_eb.common.hw, + [CLK_AON_TMR_RTC_EB] = &aon_tmr_rtc_eb.common.hw, + [CLK_AP_TMR0_RTC_EB] = &ap_tmr0_rtc_eb.common.hw, + [CLK_EIC_RTC_EB] = &eic_rtc_eb.common.hw, + [CLK_EIC_RTCDV5_EB] = &eic_rtcdv5_eb.common.hw, + [CLK_AP_WDG_RTC_EB] = &ap_wdg_rtc_eb.common.hw, + [CLK_AP_TMR1_RTC_EB] = &ap_tmr1_rtc_eb.common.hw, + [CLK_AP_TMR2_RTC_EB] = &ap_tmr2_rtc_eb.common.hw, + [CLK_DCXO_TMR_RTC_EB] = &dcxo_tmr_rtc_eb.common.hw, + [CLK_BB_CAL_RTC_EB] = &bb_cal_rtc_eb.common.hw, + [CLK_AVS_BIG_RTC_EB] = &avs_big_rtc_eb.common.hw, + [CLK_AVS_LIT_RTC_EB] = &avs_lit_rtc_eb.common.hw, + [CLK_AVS_GPU0_RTC_EB] = &avs_gpu0_rtc_eb.common.hw, + [CLK_AVS_GPU1_RTC_EB] = &avs_gpu1_rtc_eb.common.hw, + [CLK_GPU_TS_EB] = &gpu_ts_eb.common.hw, + [CLK_RTCDV10_EB] = &rtcdv10_eb.common.hw, + }, + .num = CLK_AON_GATE_NUM, +}; + +static const struct sprd_clk_desc sc9860_aon_gate_desc = { + .clk_clks = sc9860_aon_gate, + .num_clk_clks = ARRAY_SIZE(sc9860_aon_gate), + .hw_clks = &sc9860_aon_gate_hws, +}; + +static const u8 mcu_table[] = { 0, 1, 2, 3, 4, 8 }; +static const char * const lit_mcu_parents[] = { "ext-26m", "twpll-512m", + "twpll-768m", "ltepll0", + "twpll", "mpll0" }; +static SPRD_COMP_CLK_TABLE(lit_mcu, "lit-mcu", lit_mcu_parents, 0x20, + mcu_table, 0, 4, 4, 3, 0); + +static const char * const big_mcu_parents[] = { "ext-26m", "twpll-512m", + "twpll-768m", "ltepll0", + "twpll", "mpll1" }; +static SPRD_COMP_CLK_TABLE(big_mcu, "big-mcu", big_mcu_parents, 0x24, + mcu_table, 0, 4, 4, 3, 0); + +static struct sprd_clk_common *sc9860_aonsecure_clk[] = { + /* address base is 0x40880000 */ + &lit_mcu.common, + &big_mcu.common, +}; + +static struct clk_hw_onecell_data sc9860_aonsecure_clk_hws = { + .hws = { + [CLK_LIT_MCU] = &lit_mcu.common.hw, + [CLK_BIG_MCU] = &big_mcu.common.hw, + }, + .num = CLK_AONSECURE_NUM, +}; + +static const struct sprd_clk_desc sc9860_aonsecure_clk_desc = { + .clk_clks = sc9860_aonsecure_clk, + .num_clk_clks = ARRAY_SIZE(sc9860_aonsecure_clk), + .hw_clks = &sc9860_aonsecure_clk_hws, +}; + +static SPRD_SC_GATE_CLK(agcp_iis0_eb, "agcp-iis0-eb", "aon-apb", + 0x0, 0x100, BIT(0), 0, 0); +static SPRD_SC_GATE_CLK(agcp_iis1_eb, "agcp-iis1-eb", "aon-apb", + 0x0, 0x100, BIT(1), 0, 0); +static SPRD_SC_GATE_CLK(agcp_iis2_eb, "agcp-iis2-eb", "aon-apb", + 0x0, 0x100, BIT(2), 0, 0); +static SPRD_SC_GATE_CLK(agcp_iis3_eb, "agcp-iis3-eb", "aon-apb", + 0x0, 0x100, BIT(3), 0, 0); +static SPRD_SC_GATE_CLK(agcp_uart_eb, "agcp-uart-eb", "aon-apb", + 0x0, 0x100, BIT(4), 0, 0); +static SPRD_SC_GATE_CLK(agcp_dmacp_eb, "agcp-dmacp-eb", "aon-apb", + 0x0, 0x100, BIT(5), 0, 0); +static SPRD_SC_GATE_CLK(agcp_dmaap_eb, "agcp-dmaap-eb", "aon-apb", + 0x0, 0x100, BIT(6), 0, 0); +static SPRD_SC_GATE_CLK(agcp_arc48k_eb, "agcp-arc48k-eb", "aon-apb", + 0x0, 0x100, BIT(10), 0, 0); +static SPRD_SC_GATE_CLK(agcp_src44p1k_eb, "agcp-src44p1k-eb", "aon-apb", + 0x0, 0x100, BIT(11), 0, 0); +static SPRD_SC_GATE_CLK(agcp_mcdt_eb, "agcp-mcdt-eb", "aon-apb", + 0x0, 0x100, BIT(12), 0, 0); +static SPRD_SC_GATE_CLK(agcp_vbcifd_eb, "agcp-vbcifd-eb", "aon-apb", + 0x0, 0x100, BIT(13), 0, 0); +static SPRD_SC_GATE_CLK(agcp_vbc_eb, "agcp-vbc-eb", "aon-apb", + 0x0, 0x100, BIT(14), 0, 0); +static SPRD_SC_GATE_CLK(agcp_spinlock_eb, "agcp-spinlock-eb", "aon-apb", + 0x0, 0x100, BIT(15), 0, 0); +static SPRD_SC_GATE_CLK(agcp_icu_eb, "agcp-icu-eb", "aon-apb", + 0x0, 0x100, BIT(16), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK(agcp_ap_ashb_eb, "agcp-ap-ashb-eb", "aon-apb", + 0x0, 0x100, BIT(17), 0, 0); +static SPRD_SC_GATE_CLK(agcp_cp_ashb_eb, "agcp-cp-ashb-eb", "aon-apb", + 0x0, 0x100, BIT(18), 0, 0); +static SPRD_SC_GATE_CLK(agcp_aud_eb, "agcp-aud-eb", "aon-apb", + 0x0, 0x100, BIT(19), 0, 0); +static SPRD_SC_GATE_CLK(agcp_audif_eb, "agcp-audif-eb", "aon-apb", + 0x0, 0x100, BIT(20), 0, 0); + +static struct sprd_clk_common *sc9860_agcp_gate[] = { + /* address base is 0x415e0000 */ + &agcp_iis0_eb.common, + &agcp_iis1_eb.common, + &agcp_iis2_eb.common, + &agcp_iis3_eb.common, + &agcp_uart_eb.common, + &agcp_dmacp_eb.common, + &agcp_dmaap_eb.common, + &agcp_arc48k_eb.common, + &agcp_src44p1k_eb.common, + &agcp_mcdt_eb.common, + &agcp_vbcifd_eb.common, + &agcp_vbc_eb.common, + &agcp_spinlock_eb.common, + &agcp_icu_eb.common, + &agcp_ap_ashb_eb.common, + &agcp_cp_ashb_eb.common, + &agcp_aud_eb.common, + &agcp_audif_eb.common, +}; + +static struct clk_hw_onecell_data sc9860_agcp_gate_hws = { + .hws = { + [CLK_AGCP_IIS0_EB] = &agcp_iis0_eb.common.hw, + [CLK_AGCP_IIS1_EB] = &agcp_iis1_eb.common.hw, + [CLK_AGCP_IIS2_EB] = &agcp_iis2_eb.common.hw, + [CLK_AGCP_IIS3_EB] = &agcp_iis3_eb.common.hw, + [CLK_AGCP_UART_EB] = &agcp_uart_eb.common.hw, + [CLK_AGCP_DMACP_EB] = &agcp_dmacp_eb.common.hw, + [CLK_AGCP_DMAAP_EB] = &agcp_dmaap_eb.common.hw, + [CLK_AGCP_ARC48K_EB] = &agcp_arc48k_eb.common.hw, + [CLK_AGCP_SRC44P1K_EB] = &agcp_src44p1k_eb.common.hw, + [CLK_AGCP_MCDT_EB] = &agcp_mcdt_eb.common.hw, + [CLK_AGCP_VBCIFD_EB] = &agcp_vbcifd_eb.common.hw, + [CLK_AGCP_VBC_EB] = &agcp_vbc_eb.common.hw, + [CLK_AGCP_SPINLOCK_EB] = &agcp_spinlock_eb.common.hw, + [CLK_AGCP_ICU_EB] = &agcp_icu_eb.common.hw, + [CLK_AGCP_AP_ASHB_EB] = &agcp_ap_ashb_eb.common.hw, + [CLK_AGCP_CP_ASHB_EB] = &agcp_cp_ashb_eb.common.hw, + [CLK_AGCP_AUD_EB] = &agcp_aud_eb.common.hw, + [CLK_AGCP_AUDIF_EB] = &agcp_audif_eb.common.hw, + }, + .num = CLK_AGCP_GATE_NUM, +}; + +static const struct sprd_clk_desc sc9860_agcp_gate_desc = { + .clk_clks = sc9860_agcp_gate, + .num_clk_clks = ARRAY_SIZE(sc9860_agcp_gate), + .hw_clks = &sc9860_agcp_gate_hws, +}; + +static const char * const gpu_parents[] = { "twpll-512m", + "twpll-768m", + "gpll" }; +static SPRD_COMP_CLK(gpu_clk, "gpu", gpu_parents, 0x20, + 0, 2, 8, 4, 0); + +static struct sprd_clk_common *sc9860_gpu_clk[] = { + /* address base is 0x60200000 */ + &gpu_clk.common, +}; + +static struct clk_hw_onecell_data sc9860_gpu_clk_hws = { + .hws = { + [CLK_GPU] = &gpu_clk.common.hw, + }, + .num = CLK_GPU_NUM, +}; + +static const struct sprd_clk_desc sc9860_gpu_clk_desc = { + .clk_clks = sc9860_gpu_clk, + .num_clk_clks = ARRAY_SIZE(sc9860_gpu_clk), + .hw_clks = &sc9860_gpu_clk_hws, +}; + +static const char * const ahb_parents[] = { "ext-26m", "twpll-96m", + "twpll-128m", "twpll-153m6" }; +static SPRD_MUX_CLK(ahb_vsp, "ahb-vsp", ahb_parents, 0x20, + 0, 2, SC9860_MUX_FLAG); + +static const char * const vsp_parents[] = { "twpll-76m8", "twpll-128m", + "twpll-256m", "twpll-307m2", + "twpll-384m" }; +static SPRD_COMP_CLK(vsp_clk, "vsp", vsp_parents, 0x24, 0, 3, 8, 2, 0); + +static const char * const dispc_parents[] = { "twpll-76m8", "twpll-128m", + "twpll-256m", "twpll-307m2" }; +static SPRD_COMP_CLK(vsp_enc, "vsp-enc", dispc_parents, 0x28, 0, 2, 8, 2, 0); + +static const char * const vpp_parents[] = { "twpll-96m", "twpll-153m6", + "twpll-192m", "twpll-256m" }; +static SPRD_MUX_CLK(vpp_clk, "vpp", vpp_parents, 0x2c, + 0, 2, SC9860_MUX_FLAG); +static const char * const vsp_26m_parents[] = { "ext-26m" }; +static SPRD_MUX_CLK(vsp_26m, "vsp-26m", vsp_26m_parents, 0x30, + 0, 1, SC9860_MUX_FLAG); + +static struct sprd_clk_common *sc9860_vsp_clk[] = { + /* address base is 0x61000000 */ + &ahb_vsp.common, + &vsp_clk.common, + &vsp_enc.common, + &vpp_clk.common, + &vsp_26m.common, +}; + +static struct clk_hw_onecell_data sc9860_vsp_clk_hws = { + .hws = { + [CLK_AHB_VSP] = &ahb_vsp.common.hw, + [CLK_VSP] = &vsp_clk.common.hw, + [CLK_VSP_ENC] = &vsp_enc.common.hw, + [CLK_VPP] = &vpp_clk.common.hw, + [CLK_VSP_26M] = &vsp_26m.common.hw, + }, + .num = CLK_VSP_NUM, +}; + +static const struct sprd_clk_desc sc9860_vsp_clk_desc = { + .clk_clks = sc9860_vsp_clk, + .num_clk_clks = ARRAY_SIZE(sc9860_vsp_clk), + .hw_clks = &sc9860_vsp_clk_hws, +}; + +static SPRD_SC_GATE_CLK(vsp_dec_eb, "vsp-dec-eb", "ahb-vsp", 0x0, + 0x1000, BIT(0), 0, 0); +static SPRD_SC_GATE_CLK(vsp_ckg_eb, "vsp-ckg-eb", "ahb-vsp", 0x0, + 0x1000, BIT(1), 0, 0); +static SPRD_SC_GATE_CLK(vsp_mmu_eb, "vsp-mmu-eb", "ahb-vsp", 0x0, + 0x1000, BIT(2), 0, 0); +static SPRD_SC_GATE_CLK(vsp_enc_eb, "vsp-enc-eb", "ahb-vsp", 0x0, + 0x1000, BIT(3), 0, 0); +static SPRD_SC_GATE_CLK(vpp_eb, "vpp-eb", "ahb-vsp", 0x0, + 0x1000, BIT(4), 0, 0); +static SPRD_SC_GATE_CLK(vsp_26m_eb, "vsp-26m-eb", "ahb-vsp", 0x0, + 0x1000, BIT(5), 0, 0); +static SPRD_GATE_CLK(vsp_axi_gate, "vsp-axi-gate", "ahb-vsp", 0x8, + BIT(0), 0, 0); +static SPRD_GATE_CLK(vsp_enc_gate, "vsp-enc-gate", "ahb-vsp", 0x8, + BIT(1), 0, 0); +static SPRD_GATE_CLK(vpp_axi_gate, "vpp-axi-gate", "ahb-vsp", 0x8, + BIT(2), 0, 0); +static SPRD_GATE_CLK(vsp_bm_gate, "vsp-bm-gate", "ahb-vsp", 0x8, + BIT(8), 0, 0); +static SPRD_GATE_CLK(vsp_enc_bm_gate, "vsp-enc-bm-gate", "ahb-vsp", 0x8, + BIT(9), 0, 0); +static SPRD_GATE_CLK(vpp_bm_gate, "vpp-bm-gate", "ahb-vsp", 0x8, + BIT(10), 0, 0); + +static struct sprd_clk_common *sc9860_vsp_gate[] = { + /* address base is 0x61100000 */ + &vsp_dec_eb.common, + &vsp_ckg_eb.common, + &vsp_mmu_eb.common, + &vsp_enc_eb.common, + &vpp_eb.common, + &vsp_26m_eb.common, + &vsp_axi_gate.common, + &vsp_enc_gate.common, + &vpp_axi_gate.common, + &vsp_bm_gate.common, + &vsp_enc_bm_gate.common, + &vpp_bm_gate.common, +}; + +static struct clk_hw_onecell_data sc9860_vsp_gate_hws = { + .hws = { + [CLK_VSP_DEC_EB] = &vsp_dec_eb.common.hw, + [CLK_VSP_CKG_EB] = &vsp_ckg_eb.common.hw, + [CLK_VSP_MMU_EB] = &vsp_mmu_eb.common.hw, + [CLK_VSP_ENC_EB] = &vsp_enc_eb.common.hw, + [CLK_VPP_EB] = &vpp_eb.common.hw, + [CLK_VSP_26M_EB] = &vsp_26m_eb.common.hw, + [CLK_VSP_AXI_GATE] = &vsp_axi_gate.common.hw, + [CLK_VSP_ENC_GATE] = &vsp_enc_gate.common.hw, + [CLK_VPP_AXI_GATE] = &vpp_axi_gate.common.hw, + [CLK_VSP_BM_GATE] = &vsp_bm_gate.common.hw, + [CLK_VSP_ENC_BM_GATE] = &vsp_enc_bm_gate.common.hw, + [CLK_VPP_BM_GATE] = &vpp_bm_gate.common.hw, + }, + .num = CLK_VSP_GATE_NUM, +}; + +static const struct sprd_clk_desc sc9860_vsp_gate_desc = { + .clk_clks = sc9860_vsp_gate, + .num_clk_clks = ARRAY_SIZE(sc9860_vsp_gate), + .hw_clks = &sc9860_vsp_gate_hws, +}; + +static SPRD_MUX_CLK(ahb_cam, "ahb-cam", ahb_parents, 0x20, + 0, 2, SC9860_MUX_FLAG); +static const char * const sensor_parents[] = { "ext-26m", "twpll-48m", + "twpll-76m8", "twpll-96m" }; +static SPRD_COMP_CLK(sensor0_clk, "sensor0", sensor_parents, 0x24, + 0, 2, 8, 3, 0); +static SPRD_COMP_CLK(sensor1_clk, "sensor1", sensor_parents, 0x28, + 0, 2, 8, 3, 0); +static SPRD_COMP_CLK(sensor2_clk, "sensor2", sensor_parents, 0x2c, + 0, 2, 8, 3, 0); +static SPRD_GATE_CLK(mipi_csi0_eb, "mipi-csi0-eb", "ahb-cam", 0x4c, + BIT(16), 0, 0); +static SPRD_GATE_CLK(mipi_csi1_eb, "mipi-csi1-eb", "ahb-cam", 0x50, + BIT(16), 0, 0); + +static struct sprd_clk_common *sc9860_cam_clk[] = { + /* address base is 0x62000000 */ + &ahb_cam.common, + &sensor0_clk.common, + &sensor1_clk.common, + &sensor2_clk.common, + &mipi_csi0_eb.common, + &mipi_csi1_eb.common, +}; + +static struct clk_hw_onecell_data sc9860_cam_clk_hws = { + .hws = { + [CLK_AHB_CAM] = &ahb_cam.common.hw, + [CLK_SENSOR0] = &sensor0_clk.common.hw, + [CLK_SENSOR1] = &sensor1_clk.common.hw, + [CLK_SENSOR2] = &sensor2_clk.common.hw, + [CLK_MIPI_CSI0_EB] = &mipi_csi0_eb.common.hw, + [CLK_MIPI_CSI1_EB] = &mipi_csi1_eb.common.hw, + }, + .num = CLK_CAM_NUM, +}; + +static const struct sprd_clk_desc sc9860_cam_clk_desc = { + .clk_clks = sc9860_cam_clk, + .num_clk_clks = ARRAY_SIZE(sc9860_cam_clk), + .hw_clks = &sc9860_cam_clk_hws, +}; + +static SPRD_SC_GATE_CLK(dcam0_eb, "dcam0-eb", "ahb-cam", 0x0, + 0x1000, BIT(0), 0, 0); +static SPRD_SC_GATE_CLK(dcam1_eb, "dcam1-eb", "ahb-cam", 0x0, + 0x1000, BIT(1), 0, 0); +static SPRD_SC_GATE_CLK(isp0_eb, "isp0-eb", "ahb-cam", 0x0, + 0x1000, BIT(2), 0, 0); +static SPRD_SC_GATE_CLK(csi0_eb, "csi0-eb", "ahb-cam", 0x0, + 0x1000, BIT(3), 0, 0); +static SPRD_SC_GATE_CLK(csi1_eb, "csi1-eb", "ahb-cam", 0x0, + 0x1000, BIT(4), 0, 0); +static SPRD_SC_GATE_CLK(jpg0_eb, "jpg0-eb", "ahb-cam", 0x0, + 0x1000, BIT(5), 0, 0); +static SPRD_SC_GATE_CLK(jpg1_eb, "jpg1-eb", "ahb-cam", 0x0, + 0x1000, BIT(6), 0, 0); +static SPRD_SC_GATE_CLK(cam_ckg_eb, "cam-ckg-eb", "ahb-cam", 0x0, + 0x1000, BIT(7), 0, 0); +static SPRD_SC_GATE_CLK(cam_mmu_eb, "cam-mmu-eb", "ahb-cam", 0x0, + 0x1000, BIT(8), 0, 0); +static SPRD_SC_GATE_CLK(isp1_eb, "isp1-eb", "ahb-cam", 0x0, + 0x1000, BIT(9), 0, 0); +static SPRD_SC_GATE_CLK(cpp_eb, "cpp-eb", "ahb-cam", 0x0, + 0x1000, BIT(10), 0, 0); +static SPRD_SC_GATE_CLK(mmu_pf_eb, "mmu-pf-eb", "ahb-cam", 0x0, + 0x1000, BIT(11), 0, 0); +static SPRD_SC_GATE_CLK(isp2_eb, "isp2-eb", "ahb-cam", 0x0, + 0x1000, BIT(12), 0, 0); +static SPRD_SC_GATE_CLK(dcam2isp_if_eb, "dcam2isp-if-eb", "ahb-cam", 0x0, + 0x1000, BIT(13), 0, 0); +static SPRD_SC_GATE_CLK(isp2dcam_if_eb, "isp2dcam-if-eb", "ahb-cam", 0x0, + 0x1000, BIT(14), 0, 0); +static SPRD_SC_GATE_CLK(isp_lclk_eb, "isp-lclk-eb", "ahb-cam", 0x0, + 0x1000, BIT(15), 0, 0); +static SPRD_SC_GATE_CLK(isp_iclk_eb, "isp-iclk-eb", "ahb-cam", 0x0, + 0x1000, BIT(16), 0, 0); +static SPRD_SC_GATE_CLK(isp_mclk_eb, "isp-mclk-eb", "ahb-cam", 0x0, + 0x1000, BIT(17), 0, 0); +static SPRD_SC_GATE_CLK(isp_pclk_eb, "isp-pclk-eb", "ahb-cam", 0x0, + 0x1000, BIT(18), 0, 0); +static SPRD_SC_GATE_CLK(isp_isp2dcam_eb, "isp-isp2dcam-eb", "ahb-cam", 0x0, + 0x1000, BIT(19), 0, 0); +static SPRD_SC_GATE_CLK(dcam0_if_eb, "dcam0-if-eb", "ahb-cam", 0x0, + 0x1000, BIT(20), 0, 0); +static SPRD_SC_GATE_CLK(clk26m_if_eb, "clk26m-if-eb", "ahb-cam", 0x0, + 0x1000, BIT(21), 0, 0); +static SPRD_GATE_CLK(cphy0_gate, "cphy0-gate", "ahb-cam", 0x8, + BIT(0), 0, 0); +static SPRD_GATE_CLK(mipi_csi0_gate, "mipi-csi0-gate", "ahb-cam", 0x8, + BIT(1), 0, 0); +static SPRD_GATE_CLK(cphy1_gate, "cphy1-gate", "ahb-cam", 0x8, + BIT(2), 0, 0); +static SPRD_GATE_CLK(mipi_csi1, "mipi-csi1", "ahb-cam", 0x8, + BIT(3), 0, 0); +static SPRD_GATE_CLK(dcam0_axi_gate, "dcam0-axi-gate", "ahb-cam", 0x8, + BIT(4), 0, 0); +static SPRD_GATE_CLK(dcam1_axi_gate, "dcam1-axi-gate", "ahb-cam", 0x8, + BIT(5), 0, 0); +static SPRD_GATE_CLK(sensor0_gate, "sensor0-gate", "ahb-cam", 0x8, + BIT(6), 0, 0); +static SPRD_GATE_CLK(sensor1_gate, "sensor1-gate", "ahb-cam", 0x8, + BIT(7), 0, 0); +static SPRD_GATE_CLK(jpg0_axi_gate, "jpg0-axi-gate", "ahb-cam", 0x8, + BIT(8), 0, 0); +static SPRD_GATE_CLK(gpg1_axi_gate, "gpg1-axi-gate", "ahb-cam", 0x8, + BIT(9), 0, 0); +static SPRD_GATE_CLK(isp0_axi_gate, "isp0-axi-gate", "ahb-cam", 0x8, + BIT(10), 0, 0); +static SPRD_GATE_CLK(isp1_axi_gate, "isp1-axi-gate", "ahb-cam", 0x8, + BIT(11), 0, 0); +static SPRD_GATE_CLK(isp2_axi_gate, "isp2-axi-gate", "ahb-cam", 0x8, + BIT(12), 0, 0); +static SPRD_GATE_CLK(cpp_axi_gate, "cpp-axi-gate", "ahb-cam", 0x8, + BIT(13), 0, 0); +static SPRD_GATE_CLK(d0_if_axi_gate, "d0-if-axi-gate", "ahb-cam", 0x8, + BIT(14), 0, 0); +static SPRD_GATE_CLK(d2i_if_axi_gate, "d2i-if-axi-gate", "ahb-cam", 0x8, + BIT(15), 0, 0); +static SPRD_GATE_CLK(i2d_if_axi_gate, "i2d-if-axi-gate", "ahb-cam", 0x8, + BIT(16), 0, 0); +static SPRD_GATE_CLK(spare_axi_gate, "spare-axi-gate", "ahb-cam", 0x8, + BIT(17), 0, 0); +static SPRD_GATE_CLK(sensor2_gate, "sensor2-gate", "ahb-cam", 0x8, + BIT(18), 0, 0); +static SPRD_SC_GATE_CLK(d0if_in_d_en, "d0if-in-d-en", "ahb-cam", 0x28, + 0x1000, BIT(0), 0, 0); +static SPRD_SC_GATE_CLK(d1if_in_d_en, "d1if-in-d-en", "ahb-cam", 0x28, + 0x1000, BIT(1), 0, 0); +static SPRD_SC_GATE_CLK(d0if_in_d2i_en, "d0if-in-d2i-en", "ahb-cam", 0x28, + 0x1000, BIT(2), 0, 0); +static SPRD_SC_GATE_CLK(d1if_in_d2i_en, "d1if-in-d2i-en", "ahb-cam", 0x28, + 0x1000, BIT(3), 0, 0); +static SPRD_SC_GATE_CLK(ia_in_d2i_en, "ia-in-d2i-en", "ahb-cam", 0x28, + 0x1000, BIT(4), 0, 0); +static SPRD_SC_GATE_CLK(ib_in_d2i_en, "ib-in-d2i-en", "ahb-cam", 0x28, + 0x1000, BIT(5), 0, 0); +static SPRD_SC_GATE_CLK(ic_in_d2i_en, "ic-in-d2i-en", "ahb-cam", 0x28, + 0x1000, BIT(6), 0, 0); +static SPRD_SC_GATE_CLK(ia_in_i_en, "ia-in-i-en", "ahb-cam", 0x28, + 0x1000, BIT(7), 0, 0); +static SPRD_SC_GATE_CLK(ib_in_i_en, "ib-in-i-en", "ahb-cam", 0x28, + 0x1000, BIT(8), 0, 0); +static SPRD_SC_GATE_CLK(ic_in_i_en, "ic-in-i-en", "ahb-cam", 0x28, + 0x1000, BIT(9), 0, 0); + +static struct sprd_clk_common *sc9860_cam_gate[] = { + /* address base is 0x62100000 */ + &dcam0_eb.common, + &dcam1_eb.common, + &isp0_eb.common, + &csi0_eb.common, + &csi1_eb.common, + &jpg0_eb.common, + &jpg1_eb.common, + &cam_ckg_eb.common, + &cam_mmu_eb.common, + &isp1_eb.common, + &cpp_eb.common, + &mmu_pf_eb.common, + &isp2_eb.common, + &dcam2isp_if_eb.common, + &isp2dcam_if_eb.common, + &isp_lclk_eb.common, + &isp_iclk_eb.common, + &isp_mclk_eb.common, + &isp_pclk_eb.common, + &isp_isp2dcam_eb.common, + &dcam0_if_eb.common, + &clk26m_if_eb.common, + &cphy0_gate.common, + &mipi_csi0_gate.common, + &cphy1_gate.common, + &mipi_csi1.common, + &dcam0_axi_gate.common, + &dcam1_axi_gate.common, + &sensor0_gate.common, + &sensor1_gate.common, + &jpg0_axi_gate.common, + &gpg1_axi_gate.common, + &isp0_axi_gate.common, + &isp1_axi_gate.common, + &isp2_axi_gate.common, + &cpp_axi_gate.common, + &d0_if_axi_gate.common, + &d2i_if_axi_gate.common, + &i2d_if_axi_gate.common, + &spare_axi_gate.common, + &sensor2_gate.common, + &d0if_in_d_en.common, + &d1if_in_d_en.common, + &d0if_in_d2i_en.common, + &d1if_in_d2i_en.common, + &ia_in_d2i_en.common, + &ib_in_d2i_en.common, + &ic_in_d2i_en.common, + &ia_in_i_en.common, + &ib_in_i_en.common, + &ic_in_i_en.common, +}; + +static struct clk_hw_onecell_data sc9860_cam_gate_hws = { + .hws = { + [CLK_DCAM0_EB] = &dcam0_eb.common.hw, + [CLK_DCAM1_EB] = &dcam1_eb.common.hw, + [CLK_ISP0_EB] = &isp0_eb.common.hw, + [CLK_CSI0_EB] = &csi0_eb.common.hw, + [CLK_CSI1_EB] = &csi1_eb.common.hw, + [CLK_JPG0_EB] = &jpg0_eb.common.hw, + [CLK_JPG1_EB] = &jpg1_eb.common.hw, + [CLK_CAM_CKG_EB] = &cam_ckg_eb.common.hw, + [CLK_CAM_MMU_EB] = &cam_mmu_eb.common.hw, + [CLK_ISP1_EB] = &isp1_eb.common.hw, + [CLK_CPP_EB] = &cpp_eb.common.hw, + [CLK_MMU_PF_EB] = &mmu_pf_eb.common.hw, + [CLK_ISP2_EB] = &isp2_eb.common.hw, + [CLK_DCAM2ISP_IF_EB] = &dcam2isp_if_eb.common.hw, + [CLK_ISP2DCAM_IF_EB] = &isp2dcam_if_eb.common.hw, + [CLK_ISP_LCLK_EB] = &isp_lclk_eb.common.hw, + [CLK_ISP_ICLK_EB] = &isp_iclk_eb.common.hw, + [CLK_ISP_MCLK_EB] = &isp_mclk_eb.common.hw, + [CLK_ISP_PCLK_EB] = &isp_pclk_eb.common.hw, + [CLK_ISP_ISP2DCAM_EB] = &isp_isp2dcam_eb.common.hw, + [CLK_DCAM0_IF_EB] = &dcam0_if_eb.common.hw, + [CLK_CLK26M_IF_EB] = &clk26m_if_eb.common.hw, + [CLK_CPHY0_GATE] = &cphy0_gate.common.hw, + [CLK_MIPI_CSI0_GATE] = &mipi_csi0_gate.common.hw, + [CLK_CPHY1_GATE] = &cphy1_gate.common.hw, + [CLK_MIPI_CSI1] = &mipi_csi1.common.hw, + [CLK_DCAM0_AXI_GATE] = &dcam0_axi_gate.common.hw, + [CLK_DCAM1_AXI_GATE] = &dcam1_axi_gate.common.hw, + [CLK_SENSOR0_GATE] = &sensor0_gate.common.hw, + [CLK_SENSOR1_GATE] = &sensor1_gate.common.hw, + [CLK_JPG0_AXI_GATE] = &jpg0_axi_gate.common.hw, + [CLK_GPG1_AXI_GATE] = &gpg1_axi_gate.common.hw, + [CLK_ISP0_AXI_GATE] = &isp0_axi_gate.common.hw, + [CLK_ISP1_AXI_GATE] = &isp1_axi_gate.common.hw, + [CLK_ISP2_AXI_GATE] = &isp2_axi_gate.common.hw, + [CLK_CPP_AXI_GATE] = &cpp_axi_gate.common.hw, + [CLK_D0_IF_AXI_GATE] = &d0_if_axi_gate.common.hw, + [CLK_D2I_IF_AXI_GATE] = &d2i_if_axi_gate.common.hw, + [CLK_I2D_IF_AXI_GATE] = &i2d_if_axi_gate.common.hw, + [CLK_SPARE_AXI_GATE] = &spare_axi_gate.common.hw, + [CLK_SENSOR2_GATE] = &sensor2_gate.common.hw, + [CLK_D0IF_IN_D_EN] = &d0if_in_d_en.common.hw, + [CLK_D1IF_IN_D_EN] = &d1if_in_d_en.common.hw, + [CLK_D0IF_IN_D2I_EN] = &d0if_in_d2i_en.common.hw, + [CLK_D1IF_IN_D2I_EN] = &d1if_in_d2i_en.common.hw, + [CLK_IA_IN_D2I_EN] = &ia_in_d2i_en.common.hw, + [CLK_IB_IN_D2I_EN] = &ib_in_d2i_en.common.hw, + [CLK_IC_IN_D2I_EN] = &ic_in_d2i_en.common.hw, + [CLK_IA_IN_I_EN] = &ia_in_i_en.common.hw, + [CLK_IB_IN_I_EN] = &ib_in_i_en.common.hw, + [CLK_IC_IN_I_EN] = &ic_in_i_en.common.hw, + }, + .num = CLK_CAM_GATE_NUM, +}; + +static const struct sprd_clk_desc sc9860_cam_gate_desc = { + .clk_clks = sc9860_cam_gate, + .num_clk_clks = ARRAY_SIZE(sc9860_cam_gate), + .hw_clks = &sc9860_cam_gate_hws, +}; + +static SPRD_MUX_CLK(ahb_disp, "ahb-disp", ahb_parents, 0x20, + 0, 2, SC9860_MUX_FLAG); +static SPRD_COMP_CLK(dispc0_dpi, "dispc0-dpi", dispc_parents, 0x34, + 0, 2, 8, 2, 0); +static SPRD_COMP_CLK(dispc1_dpi, "dispc1-dpi", dispc_parents, 0x40, + 0, 2, 8, 2, 0); + +static struct sprd_clk_common *sc9860_disp_clk[] = { + /* address base is 0x63000000 */ + &ahb_disp.common, + &dispc0_dpi.common, + &dispc1_dpi.common, +}; + +static struct clk_hw_onecell_data sc9860_disp_clk_hws = { + .hws = { + [CLK_AHB_DISP] = &ahb_disp.common.hw, + [CLK_DISPC0_DPI] = &dispc0_dpi.common.hw, + [CLK_DISPC1_DPI] = &dispc1_dpi.common.hw, + }, + .num = CLK_DISP_NUM, +}; + +static const struct sprd_clk_desc sc9860_disp_clk_desc = { + .clk_clks = sc9860_disp_clk, + .num_clk_clks = ARRAY_SIZE(sc9860_disp_clk), + .hw_clks = &sc9860_disp_clk_hws, +}; + +static SPRD_SC_GATE_CLK(dispc0_eb, "dispc0-eb", "ahb-disp", 0x0, + 0x1000, BIT(0), 0, 0); +static SPRD_SC_GATE_CLK(dispc1_eb, "dispc1-eb", "ahb-disp", 0x0, + 0x1000, BIT(1), 0, 0); +static SPRD_SC_GATE_CLK(dispc_mmu_eb, "dispc-mmu-eb", "ahb-disp", 0x0, + 0x1000, BIT(2), 0, 0); +static SPRD_SC_GATE_CLK(gsp0_eb, "gsp0-eb", "ahb-disp", 0x0, + 0x1000, BIT(3), 0, 0); +static SPRD_SC_GATE_CLK(gsp1_eb, "gsp1-eb", "ahb-disp", 0x0, + 0x1000, BIT(4), 0, 0); +static SPRD_SC_GATE_CLK(gsp0_mmu_eb, "gsp0-mmu-eb", "ahb-disp", 0x0, + 0x1000, BIT(5), 0, 0); +static SPRD_SC_GATE_CLK(gsp1_mmu_eb, "gsp1-mmu-eb", "ahb-disp", 0x0, + 0x1000, BIT(6), 0, 0); +static SPRD_SC_GATE_CLK(dsi0_eb, "dsi0-eb", "ahb-disp", 0x0, + 0x1000, BIT(7), 0, 0); +static SPRD_SC_GATE_CLK(dsi1_eb, "dsi1-eb", "ahb-disp", 0x0, + 0x1000, BIT(8), 0, 0); +static SPRD_SC_GATE_CLK(disp_ckg_eb, "disp-ckg-eb", "ahb-disp", 0x0, + 0x1000, BIT(9), 0, 0); +static SPRD_SC_GATE_CLK(disp_gpu_eb, "disp-gpu-eb", "ahb-disp", 0x0, + 0x1000, BIT(10), 0, 0); +static SPRD_SC_GATE_CLK(gpu_mtx_eb, "gpu-mtx-eb", "ahb-disp", 0x0, + 0x1000, BIT(13), 0, 0); +static SPRD_SC_GATE_CLK(gsp_mtx_eb, "gsp-mtx-eb", "ahb-disp", 0x0, + 0x1000, BIT(14), 0, 0); +static SPRD_SC_GATE_CLK(tmc_mtx_eb, "tmc-mtx-eb", "ahb-disp", 0x0, + 0x1000, BIT(15), 0, 0); +static SPRD_SC_GATE_CLK(dispc_mtx_eb, "dispc-mtx-eb", "ahb-disp", 0x0, + 0x1000, BIT(16), 0, 0); +static SPRD_GATE_CLK(dphy0_gate, "dphy0-gate", "ahb-disp", 0x8, + BIT(0), 0, 0); +static SPRD_GATE_CLK(dphy1_gate, "dphy1-gate", "ahb-disp", 0x8, + BIT(1), 0, 0); +static SPRD_GATE_CLK(gsp0_a_gate, "gsp0-a-gate", "ahb-disp", 0x8, + BIT(2), 0, 0); +static SPRD_GATE_CLK(gsp1_a_gate, "gsp1-a-gate", "ahb-disp", 0x8, + BIT(3), 0, 0); +static SPRD_GATE_CLK(gsp0_f_gate, "gsp0-f-gate", "ahb-disp", 0x8, + BIT(4), 0, 0); +static SPRD_GATE_CLK(gsp1_f_gate, "gsp1-f-gate", "ahb-disp", 0x8, + BIT(5), 0, 0); +static SPRD_GATE_CLK(d_mtx_f_gate, "d-mtx-f-gate", "ahb-disp", 0x8, + BIT(6), 0, 0); +static SPRD_GATE_CLK(d_mtx_a_gate, "d-mtx-a-gate", "ahb-disp", 0x8, + BIT(7), 0, 0); +static SPRD_GATE_CLK(d_noc_f_gate, "d-noc-f-gate", "ahb-disp", 0x8, + BIT(8), 0, 0); +static SPRD_GATE_CLK(d_noc_a_gate, "d-noc-a-gate", "ahb-disp", 0x8, + BIT(9), 0, 0); +static SPRD_GATE_CLK(gsp_mtx_f_gate, "gsp-mtx-f-gate", "ahb-disp", 0x8, + BIT(10), 0, 0); +static SPRD_GATE_CLK(gsp_mtx_a_gate, "gsp-mtx-a-gate", "ahb-disp", 0x8, + BIT(11), 0, 0); +static SPRD_GATE_CLK(gsp_noc_f_gate, "gsp-noc-f-gate", "ahb-disp", 0x8, + BIT(12), 0, 0); +static SPRD_GATE_CLK(gsp_noc_a_gate, "gsp-noc-a-gate", "ahb-disp", 0x8, + BIT(13), 0, 0); +static SPRD_GATE_CLK(dispm0idle_gate, "dispm0idle-gate", "ahb-disp", 0x8, + BIT(14), 0, 0); +static SPRD_GATE_CLK(gspm0idle_gate, "gspm0idle-gate", "ahb-disp", 0x8, + BIT(15), 0, 0); + +static struct sprd_clk_common *sc9860_disp_gate[] = { + /* address base is 0x63100000 */ + &dispc0_eb.common, + &dispc1_eb.common, + &dispc_mmu_eb.common, + &gsp0_eb.common, + &gsp1_eb.common, + &gsp0_mmu_eb.common, + &gsp1_mmu_eb.common, + &dsi0_eb.common, + &dsi1_eb.common, + &disp_ckg_eb.common, + &disp_gpu_eb.common, + &gpu_mtx_eb.common, + &gsp_mtx_eb.common, + &tmc_mtx_eb.common, + &dispc_mtx_eb.common, + &dphy0_gate.common, + &dphy1_gate.common, + &gsp0_a_gate.common, + &gsp1_a_gate.common, + &gsp0_f_gate.common, + &gsp1_f_gate.common, + &d_mtx_f_gate.common, + &d_mtx_a_gate.common, + &d_noc_f_gate.common, + &d_noc_a_gate.common, + &gsp_mtx_f_gate.common, + &gsp_mtx_a_gate.common, + &gsp_noc_f_gate.common, + &gsp_noc_a_gate.common, + &dispm0idle_gate.common, + &gspm0idle_gate.common, +}; + +static struct clk_hw_onecell_data sc9860_disp_gate_hws = { + .hws = { + [CLK_DISPC0_EB] = &dispc0_eb.common.hw, + [CLK_DISPC1_EB] = &dispc1_eb.common.hw, + [CLK_DISPC_MMU_EB] = &dispc_mmu_eb.common.hw, + [CLK_GSP0_EB] = &gsp0_eb.common.hw, + [CLK_GSP1_EB] = &gsp1_eb.common.hw, + [CLK_GSP0_MMU_EB] = &gsp0_mmu_eb.common.hw, + [CLK_GSP1_MMU_EB] = &gsp1_mmu_eb.common.hw, + [CLK_DSI0_EB] = &dsi0_eb.common.hw, + [CLK_DSI1_EB] = &dsi1_eb.common.hw, + [CLK_DISP_CKG_EB] = &disp_ckg_eb.common.hw, + [CLK_DISP_GPU_EB] = &disp_gpu_eb.common.hw, + [CLK_GPU_MTX_EB] = &gpu_mtx_eb.common.hw, + [CLK_GSP_MTX_EB] = &gsp_mtx_eb.common.hw, + [CLK_TMC_MTX_EB] = &tmc_mtx_eb.common.hw, + [CLK_DISPC_MTX_EB] = &dispc_mtx_eb.common.hw, + [CLK_DPHY0_GATE] = &dphy0_gate.common.hw, + [CLK_DPHY1_GATE] = &dphy1_gate.common.hw, + [CLK_GSP0_A_GATE] = &gsp0_a_gate.common.hw, + [CLK_GSP1_A_GATE] = &gsp1_a_gate.common.hw, + [CLK_GSP0_F_GATE] = &gsp0_f_gate.common.hw, + [CLK_GSP1_F_GATE] = &gsp1_f_gate.common.hw, + [CLK_D_MTX_F_GATE] = &d_mtx_f_gate.common.hw, + [CLK_D_MTX_A_GATE] = &d_mtx_a_gate.common.hw, + [CLK_D_NOC_F_GATE] = &d_noc_f_gate.common.hw, + [CLK_D_NOC_A_GATE] = &d_noc_a_gate.common.hw, + [CLK_GSP_MTX_F_GATE] = &gsp_mtx_f_gate.common.hw, + [CLK_GSP_MTX_A_GATE] = &gsp_mtx_a_gate.common.hw, + [CLK_GSP_NOC_F_GATE] = &gsp_noc_f_gate.common.hw, + [CLK_GSP_NOC_A_GATE] = &gsp_noc_a_gate.common.hw, + [CLK_DISPM0IDLE_GATE] = &dispm0idle_gate.common.hw, + [CLK_GSPM0IDLE_GATE] = &gspm0idle_gate.common.hw, + }, + .num = CLK_DISP_GATE_NUM, +}; + +static const struct sprd_clk_desc sc9860_disp_gate_desc = { + .clk_clks = sc9860_disp_gate, + .num_clk_clks = ARRAY_SIZE(sc9860_disp_gate), + .hw_clks = &sc9860_disp_gate_hws, +}; + +static SPRD_SC_GATE_CLK(sim0_eb, "sim0-eb", "ap-apb", 0x0, + 0x1000, BIT(0), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK(iis0_eb, "iis0-eb", "ap-apb", 0x0, + 0x1000, BIT(1), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK(iis1_eb, "iis1-eb", "ap-apb", 0x0, + 0x1000, BIT(2), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK(iis2_eb, "iis2-eb", "ap-apb", 0x0, + 0x1000, BIT(3), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK(iis3_eb, "iis3-eb", "ap-apb", 0x0, + 0x1000, BIT(4), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK(spi0_eb, "spi0-eb", "ap-apb", 0x0, + 0x1000, BIT(5), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK(spi1_eb, "spi1-eb", "ap-apb", 0x0, + 0x1000, BIT(6), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK(spi2_eb, "spi2-eb", "ap-apb", 0x0, + 0x1000, BIT(7), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK(i2c0_eb, "i2c0-eb", "ap-apb", 0x0, + 0x1000, BIT(8), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK(i2c1_eb, "i2c1-eb", "ap-apb", 0x0, + 0x1000, BIT(9), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK(i2c2_eb, "i2c2-eb", "ap-apb", 0x0, + 0x1000, BIT(10), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK(i2c3_eb, "i2c3-eb", "ap-apb", 0x0, + 0x1000, BIT(11), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK(i2c4_eb, "i2c4-eb", "ap-apb", 0x0, + 0x1000, BIT(12), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK(i2c5_eb, "i2c5-eb", "ap-apb", 0x0, + 0x1000, BIT(13), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK(uart0_eb, "uart0-eb", "ap-apb", 0x0, + 0x1000, BIT(14), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK(uart1_eb, "uart1-eb", "ap-apb", 0x0, + 0x1000, BIT(15), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK(uart2_eb, "uart2-eb", "ap-apb", 0x0, + 0x1000, BIT(16), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK(uart3_eb, "uart3-eb", "ap-apb", 0x0, + 0x1000, BIT(17), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK(uart4_eb, "uart4-eb", "ap-apb", 0x0, + 0x1000, BIT(18), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK(ap_ckg_eb, "ap-ckg-eb", "ap-apb", 0x0, + 0x1000, BIT(19), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK(spi3_eb, "spi3-eb", "ap-apb", 0x0, + 0x1000, BIT(20), CLK_IGNORE_UNUSED, 0); + +static struct sprd_clk_common *sc9860_apapb_gate[] = { + /* address base is 0x70b00000 */ + &sim0_eb.common, + &iis0_eb.common, + &iis1_eb.common, + &iis2_eb.common, + &iis3_eb.common, + &spi0_eb.common, + &spi1_eb.common, + &spi2_eb.common, + &i2c0_eb.common, + &i2c1_eb.common, + &i2c2_eb.common, + &i2c3_eb.common, + &i2c4_eb.common, + &i2c5_eb.common, + &uart0_eb.common, + &uart1_eb.common, + &uart2_eb.common, + &uart3_eb.common, + &uart4_eb.common, + &ap_ckg_eb.common, + &spi3_eb.common, +}; + +static struct clk_hw_onecell_data sc9860_apapb_gate_hws = { + .hws = { + [CLK_SIM0_EB] = &sim0_eb.common.hw, + [CLK_IIS0_EB] = &iis0_eb.common.hw, + [CLK_IIS1_EB] = &iis1_eb.common.hw, + [CLK_IIS2_EB] = &iis2_eb.common.hw, + [CLK_IIS3_EB] = &iis3_eb.common.hw, + [CLK_SPI0_EB] = &spi0_eb.common.hw, + [CLK_SPI1_EB] = &spi1_eb.common.hw, + [CLK_SPI2_EB] = &spi2_eb.common.hw, + [CLK_I2C0_EB] = &i2c0_eb.common.hw, + [CLK_I2C1_EB] = &i2c1_eb.common.hw, + [CLK_I2C2_EB] = &i2c2_eb.common.hw, + [CLK_I2C3_EB] = &i2c3_eb.common.hw, + [CLK_I2C4_EB] = &i2c4_eb.common.hw, + [CLK_I2C5_EB] = &i2c5_eb.common.hw, + [CLK_UART0_EB] = &uart0_eb.common.hw, + [CLK_UART1_EB] = &uart1_eb.common.hw, + [CLK_UART2_EB] = &uart2_eb.common.hw, + [CLK_UART3_EB] = &uart3_eb.common.hw, + [CLK_UART4_EB] = &uart4_eb.common.hw, + [CLK_AP_CKG_EB] = &ap_ckg_eb.common.hw, + [CLK_SPI3_EB] = &spi3_eb.common.hw, + }, + .num = CLK_APAPB_GATE_NUM, +}; + +static const struct sprd_clk_desc sc9860_apapb_gate_desc = { + .clk_clks = sc9860_apapb_gate, + .num_clk_clks = ARRAY_SIZE(sc9860_apapb_gate), + .hw_clks = &sc9860_apapb_gate_hws, +}; + +static const struct of_device_id sprd_sc9860_clk_ids[] = { + { .compatible = "sprd,sc9860-pmu-gate", /* 0x402b */ + .data = &sc9860_pmu_gate_desc }, + { .compatible = "sprd,sc9860-pll", /* 0x4040 */ + .data = &sc9860_pll_desc }, + { .compatible = "sprd,sc9860-ap-clk", /* 0x2000 */ + .data = &sc9860_ap_clk_desc }, + { .compatible = "sprd,sc9860-aon-prediv", /* 0x402d */ + .data = &sc9860_aon_prediv_desc }, + { .compatible = "sprd,sc9860-apahb-gate", /* 0x2021 */ + .data = &sc9860_apahb_gate_desc }, + { .compatible = "sprd,sc9860-aon-gate", /* 0x402e */ + .data = &sc9860_aon_gate_desc }, + { .compatible = "sprd,sc9860-aonsecure-clk", /* 0x4088 */ + .data = &sc9860_aonsecure_clk_desc }, + { .compatible = "sprd,sc9860-agcp-gate", /* 0x415e */ + .data = &sc9860_agcp_gate_desc }, + { .compatible = "sprd,sc9860-gpu-clk", /* 0x6020 */ + .data = &sc9860_gpu_clk_desc }, + { .compatible = "sprd,sc9860-vsp-clk", /* 0x6100 */ + .data = &sc9860_vsp_clk_desc }, + { .compatible = "sprd,sc9860-vsp-gate", /* 0x6110 */ + .data = &sc9860_vsp_gate_desc }, + { .compatible = "sprd,sc9860-cam-clk", /* 0x6200 */ + .data = &sc9860_cam_clk_desc }, + { .compatible = "sprd,sc9860-cam-gate", /* 0x6210 */ + .data = &sc9860_cam_gate_desc }, + { .compatible = "sprd,sc9860-disp-clk", /* 0x6300 */ + .data = &sc9860_disp_clk_desc }, + { .compatible = "sprd,sc9860-disp-gate", /* 0x6310 */ + .data = &sc9860_disp_gate_desc }, + { .compatible = "sprd,sc9860-apapb-gate", /* 0x70b0 */ + .data = &sc9860_apapb_gate_desc }, + { } +}; +MODULE_DEVICE_TABLE(of, sprd_sc9860_clk_ids); + +static int sc9860_clk_probe(struct platform_device *pdev) +{ + const struct sprd_clk_desc *desc; + int ret; + + desc = device_get_match_data(&pdev->dev); + if (!desc) + return -ENODEV; + + ret = sprd_clk_regmap_init(pdev, desc); + if (ret) + return ret; + + return sprd_clk_probe(&pdev->dev, desc->hw_clks); +} + +static struct platform_driver sc9860_clk_driver = { + .probe = sc9860_clk_probe, + .driver = { + .name = "sc9860-clk", + .of_match_table = sprd_sc9860_clk_ids, + }, +}; +module_platform_driver(sc9860_clk_driver); + +MODULE_DESCRIPTION("Spreadtrum SC9860 Clock Driver"); +MODULE_LICENSE("GPL v2"); +MODULE_ALIAS("platform:sc9860-clk"); diff --git a/drivers/clk/sprd/sc9863a-clk.c b/drivers/clk/sprd/sc9863a-clk.c new file mode 100644 index 000000000..ad2e0f9f8 --- /dev/null +++ b/drivers/clk/sprd/sc9863a-clk.c @@ -0,0 +1,1805 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Unisoc SC9863A clock driver + * + * Copyright (C) 2019 Unisoc, Inc. + * Author: Chunyan Zhang <chunyan.zhang@unisoc.com> + */ + +#include <linux/clk-provider.h> +#include <linux/err.h> +#include <linux/io.h> +#include <linux/module.h> +#include <linux/platform_device.h> +#include <linux/slab.h> + +#include <dt-bindings/clock/sprd,sc9863a-clk.h> + +#include "common.h" +#include "composite.h" +#include "div.h" +#include "gate.h" +#include "mux.h" +#include "pll.h" + +/* mpll*_gate clocks control cpu cores, they were enabled by default */ +static SPRD_PLL_SC_GATE_CLK_FW_NAME(mpll0_gate, "mpll0-gate", "ext-26m", 0x94, + 0x1000, BIT(0), CLK_IGNORE_UNUSED, 0, 240); +static SPRD_PLL_SC_GATE_CLK_FW_NAME(dpll0_gate, "dpll0-gate", "ext-26m", 0x98, + 0x1000, BIT(0), 0, 0, 240); +static SPRD_PLL_SC_GATE_CLK_FW_NAME(lpll_gate, "lpll-gate", "ext-26m", 0x9c, + 0x1000, BIT(0), 0, 0, 240); +static SPRD_PLL_SC_GATE_CLK_FW_NAME(gpll_gate, "gpll-gate", "ext-26m", 0xa8, + 0x1000, BIT(0), 0, 0, 240); +static SPRD_PLL_SC_GATE_CLK_FW_NAME(dpll1_gate, "dpll1-gate", "ext-26m", 0x1dc, + 0x1000, BIT(0), 0, 0, 240); +static SPRD_PLL_SC_GATE_CLK_FW_NAME(mpll1_gate, "mpll1-gate", "ext-26m", 0x1e0, + 0x1000, BIT(0), CLK_IGNORE_UNUSED, 0, 240); +static SPRD_PLL_SC_GATE_CLK_FW_NAME(mpll2_gate, "mpll2-gate", "ext-26m", 0x1e4, + 0x1000, BIT(0), CLK_IGNORE_UNUSED, 0, 240); +static SPRD_PLL_SC_GATE_CLK_FW_NAME(isppll_gate, "isppll-gate", "ext-26m", + 0x1e8, 0x1000, BIT(0), 0, 0, 240); + +static struct sprd_clk_common *sc9863a_pmu_gate_clks[] = { + /* address base is 0x402b0000 */ + &mpll0_gate.common, + &dpll0_gate.common, + &lpll_gate.common, + &gpll_gate.common, + &dpll1_gate.common, + &mpll1_gate.common, + &mpll2_gate.common, + &isppll_gate.common, +}; + +static struct clk_hw_onecell_data sc9863a_pmu_gate_hws = { + .hws = { + [CLK_MPLL0_GATE] = &mpll0_gate.common.hw, + [CLK_DPLL0_GATE] = &dpll0_gate.common.hw, + [CLK_LPLL_GATE] = &lpll_gate.common.hw, + [CLK_GPLL_GATE] = &gpll_gate.common.hw, + [CLK_DPLL1_GATE] = &dpll1_gate.common.hw, + [CLK_MPLL1_GATE] = &mpll1_gate.common.hw, + [CLK_MPLL2_GATE] = &mpll2_gate.common.hw, + [CLK_ISPPLL_GATE] = &isppll_gate.common.hw, + }, + .num = CLK_PMU_APB_NUM, +}; + +static const struct sprd_clk_desc sc9863a_pmu_gate_desc = { + .clk_clks = sc9863a_pmu_gate_clks, + .num_clk_clks = ARRAY_SIZE(sc9863a_pmu_gate_clks), + .hw_clks = &sc9863a_pmu_gate_hws, +}; + +static const u64 itable[5] = {4, 1000000000, 1200000000, + 1400000000, 1600000000}; + +static const struct clk_bit_field f_twpll[PLL_FACT_MAX] = { + { .shift = 95, .width = 1 }, /* lock_done */ + { .shift = 0, .width = 1 }, /* div_s */ + { .shift = 1, .width = 1 }, /* mod_en */ + { .shift = 2, .width = 1 }, /* sdm_en */ + { .shift = 0, .width = 0 }, /* refin */ + { .shift = 3, .width = 3 }, /* ibias */ + { .shift = 8, .width = 11 }, /* n */ + { .shift = 55, .width = 7 }, /* nint */ + { .shift = 32, .width = 23}, /* kint */ + { .shift = 0, .width = 0 }, /* prediv */ + { .shift = 0, .width = 0 }, /* postdiv */ +}; +static SPRD_PLL_FW_NAME(twpll, "twpll", "ext-26m", 0x4, 3, itable, + f_twpll, 240, 1000, 1000, 0, 0); +static CLK_FIXED_FACTOR_HW(twpll_768m, "twpll-768m", &twpll.common.hw, 2, 1, 0); +static CLK_FIXED_FACTOR_HW(twpll_384m, "twpll-384m", &twpll.common.hw, 4, 1, 0); +static CLK_FIXED_FACTOR_HW(twpll_192m, "twpll-192m", &twpll.common.hw, 8, 1, 0); +static CLK_FIXED_FACTOR_HW(twpll_96m, "twpll-96m", &twpll.common.hw, 16, 1, 0); +static CLK_FIXED_FACTOR_HW(twpll_48m, "twpll-48m", &twpll.common.hw, 32, 1, 0); +static CLK_FIXED_FACTOR_HW(twpll_24m, "twpll-24m", &twpll.common.hw, 64, 1, 0); +static CLK_FIXED_FACTOR_HW(twpll_12m, "twpll-12m", &twpll.common.hw, 128, 1, 0); +static CLK_FIXED_FACTOR_HW(twpll_512m, "twpll-512m", &twpll.common.hw, 3, 1, 0); +static CLK_FIXED_FACTOR_HW(twpll_256m, "twpll-256m", &twpll.common.hw, 6, 1, 0); +static CLK_FIXED_FACTOR_HW(twpll_128m, "twpll-128m", &twpll.common.hw, 12, 1, 0); +static CLK_FIXED_FACTOR_HW(twpll_64m, "twpll-64m", &twpll.common.hw, 24, 1, 0); +static CLK_FIXED_FACTOR_HW(twpll_307m2, "twpll-307m2", &twpll.common.hw, 5, 1, 0); +static CLK_FIXED_FACTOR_HW(twpll_219m4, "twpll-219m4", &twpll.common.hw, 7, 1, 0); +static CLK_FIXED_FACTOR_HW(twpll_170m6, "twpll-170m6", &twpll.common.hw, 9, 1, 0); +static CLK_FIXED_FACTOR_HW(twpll_153m6, "twpll-153m6", &twpll.common.hw, 10, 1, 0); +static CLK_FIXED_FACTOR_HW(twpll_76m8, "twpll-76m8", &twpll.common.hw, 20, 1, 0); +static CLK_FIXED_FACTOR_HW(twpll_51m2, "twpll-51m2", &twpll.common.hw, 30, 1, 0); +static CLK_FIXED_FACTOR_HW(twpll_38m4, "twpll-38m4", &twpll.common.hw, 40, 1, 0); +static CLK_FIXED_FACTOR_HW(twpll_19m2, "twpll-19m2", &twpll.common.hw, 80, 1, 0); + +static const struct clk_bit_field f_lpll[PLL_FACT_MAX] = { + { .shift = 95, .width = 1 }, /* lock_done */ + { .shift = 0, .width = 1 }, /* div_s */ + { .shift = 1, .width = 1 }, /* mod_en */ + { .shift = 2, .width = 1 }, /* sdm_en */ + { .shift = 0, .width = 0 }, /* refin */ + { .shift = 6, .width = 2 }, /* ibias */ + { .shift = 8, .width = 11 }, /* n */ + { .shift = 55, .width = 7 }, /* nint */ + { .shift = 32, .width = 23}, /* kint */ + { .shift = 0, .width = 0 }, /* prediv */ + { .shift = 0, .width = 0 }, /* postdiv */ +}; +static SPRD_PLL_HW(lpll, "lpll", &lpll_gate.common.hw, 0x20, 3, itable, + f_lpll, 240, 1000, 1000, 0, 0); +static CLK_FIXED_FACTOR_HW(lpll_409m6, "lpll-409m6", &lpll.common.hw, 3, 1, 0); +static CLK_FIXED_FACTOR_HW(lpll_245m76, "lpll-245m76", &lpll.common.hw, 5, 1, 0); + +static const struct clk_bit_field f_gpll[PLL_FACT_MAX] = { + { .shift = 95, .width = 1 }, /* lock_done */ + { .shift = 0, .width = 1 }, /* div_s */ + { .shift = 1, .width = 1 }, /* mod_en */ + { .shift = 2, .width = 1 }, /* sdm_en */ + { .shift = 0, .width = 0 }, /* refin */ + { .shift = 6, .width = 2 }, /* ibias */ + { .shift = 8, .width = 11 }, /* n */ + { .shift = 55, .width = 7 }, /* nint */ + { .shift = 32, .width = 23}, /* kint */ + { .shift = 0, .width = 0 }, /* prediv */ + { .shift = 80, .width = 1 }, /* postdiv */ +}; +static SPRD_PLL_HW(gpll, "gpll", &gpll_gate.common.hw, 0x38, 3, itable, + f_gpll, 240, 1000, 1000, 1, 400000000); + +static SPRD_PLL_HW(isppll, "isppll", &isppll_gate.common.hw, 0x50, 3, itable, + f_gpll, 240, 1000, 1000, 0, 0); +static CLK_FIXED_FACTOR_HW(isppll_468m, "isppll-468m", &isppll.common.hw, 2, 1, 0); + +static struct sprd_clk_common *sc9863a_pll_clks[] = { + /* address base is 0x40353000 */ + &twpll.common, + &lpll.common, + &gpll.common, + &isppll.common, +}; + +static struct clk_hw_onecell_data sc9863a_pll_hws = { + .hws = { + [CLK_TWPLL] = &twpll.common.hw, + [CLK_TWPLL_768M] = &twpll_768m.hw, + [CLK_TWPLL_384M] = &twpll_384m.hw, + [CLK_TWPLL_192M] = &twpll_192m.hw, + [CLK_TWPLL_96M] = &twpll_96m.hw, + [CLK_TWPLL_48M] = &twpll_48m.hw, + [CLK_TWPLL_24M] = &twpll_24m.hw, + [CLK_TWPLL_12M] = &twpll_12m.hw, + [CLK_TWPLL_512M] = &twpll_512m.hw, + [CLK_TWPLL_256M] = &twpll_256m.hw, + [CLK_TWPLL_128M] = &twpll_128m.hw, + [CLK_TWPLL_64M] = &twpll_64m.hw, + [CLK_TWPLL_307M2] = &twpll_307m2.hw, + [CLK_TWPLL_219M4] = &twpll_219m4.hw, + [CLK_TWPLL_170M6] = &twpll_170m6.hw, + [CLK_TWPLL_153M6] = &twpll_153m6.hw, + [CLK_TWPLL_76M8] = &twpll_76m8.hw, + [CLK_TWPLL_51M2] = &twpll_51m2.hw, + [CLK_TWPLL_38M4] = &twpll_38m4.hw, + [CLK_TWPLL_19M2] = &twpll_19m2.hw, + [CLK_LPLL] = &lpll.common.hw, + [CLK_LPLL_409M6] = &lpll_409m6.hw, + [CLK_LPLL_245M76] = &lpll_245m76.hw, + [CLK_GPLL] = &gpll.common.hw, + [CLK_ISPPLL] = &isppll.common.hw, + [CLK_ISPPLL_468M] = &isppll_468m.hw, + + }, + .num = CLK_ANLG_PHY_G1_NUM, +}; + +static const struct sprd_clk_desc sc9863a_pll_desc = { + .clk_clks = sc9863a_pll_clks, + .num_clk_clks = ARRAY_SIZE(sc9863a_pll_clks), + .hw_clks = &sc9863a_pll_hws, +}; + +static const u64 itable_mpll[6] = {5, 1000000000, 1200000000, 1400000000, + 1600000000, 1800000000}; +static SPRD_PLL_HW(mpll0, "mpll0", &mpll0_gate.common.hw, 0x0, 3, itable_mpll, + f_gpll, 240, 1000, 1000, 1, 1000000000); +static SPRD_PLL_HW(mpll1, "mpll1", &mpll1_gate.common.hw, 0x18, 3, itable_mpll, + f_gpll, 240, 1000, 1000, 1, 1000000000); +static SPRD_PLL_HW(mpll2, "mpll2", &mpll2_gate.common.hw, 0x30, 3, itable_mpll, + f_gpll, 240, 1000, 1000, 1, 1000000000); +static CLK_FIXED_FACTOR_HW(mpll2_675m, "mpll2-675m", &mpll2.common.hw, 2, 1, 0); + +static struct sprd_clk_common *sc9863a_mpll_clks[] = { + /* address base is 0x40359000 */ + &mpll0.common, + &mpll1.common, + &mpll2.common, +}; + +static struct clk_hw_onecell_data sc9863a_mpll_hws = { + .hws = { + [CLK_MPLL0] = &mpll0.common.hw, + [CLK_MPLL1] = &mpll1.common.hw, + [CLK_MPLL2] = &mpll2.common.hw, + [CLK_MPLL2_675M] = &mpll2_675m.hw, + + }, + .num = CLK_ANLG_PHY_G4_NUM, +}; + +static const struct sprd_clk_desc sc9863a_mpll_desc = { + .clk_clks = sc9863a_mpll_clks, + .num_clk_clks = ARRAY_SIZE(sc9863a_mpll_clks), + .hw_clks = &sc9863a_mpll_hws, +}; + +static SPRD_SC_GATE_CLK_FW_NAME(audio_gate, "audio-gate", "ext-26m", + 0x4, 0x1000, BIT(8), 0, 0); + +static SPRD_PLL_FW_NAME(rpll, "rpll", "ext-26m", 0x10, + 3, itable, f_lpll, 240, 1000, 1000, 0, 0); + +static CLK_FIXED_FACTOR_HW(rpll_390m, "rpll-390m", &rpll.common.hw, 2, 1, 0); +static CLK_FIXED_FACTOR_HW(rpll_260m, "rpll-260m", &rpll.common.hw, 3, 1, 0); +static CLK_FIXED_FACTOR_HW(rpll_195m, "rpll-195m", &rpll.common.hw, 4, 1, 0); +static CLK_FIXED_FACTOR_HW(rpll_26m, "rpll-26m", &rpll.common.hw, 30, 1, 0); + +static struct sprd_clk_common *sc9863a_rpll_clks[] = { + /* address base is 0x4035c000 */ + &audio_gate.common, + &rpll.common, +}; + +static struct clk_hw_onecell_data sc9863a_rpll_hws = { + .hws = { + [CLK_AUDIO_GATE] = &audio_gate.common.hw, + [CLK_RPLL] = &rpll.common.hw, + [CLK_RPLL_390M] = &rpll_390m.hw, + [CLK_RPLL_260M] = &rpll_260m.hw, + [CLK_RPLL_195M] = &rpll_195m.hw, + [CLK_RPLL_26M] = &rpll_26m.hw, + }, + .num = CLK_ANLG_PHY_G5_NUM, +}; + +static const struct sprd_clk_desc sc9863a_rpll_desc = { + .clk_clks = sc9863a_rpll_clks, + .num_clk_clks = ARRAY_SIZE(sc9863a_rpll_clks), + .hw_clks = &sc9863a_rpll_hws, +}; + +static const u64 itable_dpll[5] = {4, 1211000000, 1320000000, 1570000000, + 1866000000}; +static SPRD_PLL_HW(dpll0, "dpll0", &dpll0_gate.common.hw, 0x0, 3, itable_dpll, + f_lpll, 240, 1000, 1000, 0, 0); +static SPRD_PLL_HW(dpll1, "dpll1", &dpll1_gate.common.hw, 0x18, 3, itable_dpll, + f_lpll, 240, 1000, 1000, 0, 0); + +static CLK_FIXED_FACTOR_HW(dpll0_933m, "dpll0-933m", &dpll0.common.hw, 2, 1, 0); +static CLK_FIXED_FACTOR_HW(dpll0_622m3, "dpll0-622m3", &dpll0.common.hw, 3, 1, 0); +static CLK_FIXED_FACTOR_HW(dpll1_400m, "dpll1-400m", &dpll0.common.hw, 4, 1, 0); +static CLK_FIXED_FACTOR_HW(dpll1_266m7, "dpll1-266m7", &dpll0.common.hw, 6, 1, 0); +static CLK_FIXED_FACTOR_HW(dpll1_123m1, "dpll1-123m1", &dpll0.common.hw, 13, 1, 0); +static CLK_FIXED_FACTOR_HW(dpll1_50m, "dpll1-50m", &dpll0.common.hw, 32, 1, 0); + +static struct sprd_clk_common *sc9863a_dpll_clks[] = { + /* address base is 0x40363000 */ + &dpll0.common, + &dpll1.common, +}; + +static struct clk_hw_onecell_data sc9863a_dpll_hws = { + .hws = { + [CLK_DPLL0] = &dpll0.common.hw, + [CLK_DPLL1] = &dpll1.common.hw, + [CLK_DPLL0_933M] = &dpll0_933m.hw, + [CLK_DPLL0_622M3] = &dpll0_622m3.hw, + [CLK_DPLL0_400M] = &dpll1_400m.hw, + [CLK_DPLL0_266M7] = &dpll1_266m7.hw, + [CLK_DPLL0_123M1] = &dpll1_123m1.hw, + [CLK_DPLL0_50M] = &dpll1_50m.hw, + + }, + .num = CLK_ANLG_PHY_G7_NUM, +}; + +static const struct sprd_clk_desc sc9863a_dpll_desc = { + .clk_clks = sc9863a_dpll_clks, + .num_clk_clks = ARRAY_SIZE(sc9863a_dpll_clks), + .hw_clks = &sc9863a_dpll_hws, +}; + +static CLK_FIXED_FACTOR_FW_NAME(clk_6m5, "clk-6m5", "ext-26m", 4, 1, 0); +static CLK_FIXED_FACTOR_FW_NAME(clk_4m3, "clk-4m3", "ext-26m", 6, 1, 0); +static CLK_FIXED_FACTOR_FW_NAME(clk_2m, "clk-2m", "ext-26m", 13, 1, 0); +static CLK_FIXED_FACTOR_FW_NAME(clk_250k, "clk-250k", "ext-26m", 104, 1, 0); +static CLK_FIXED_FACTOR_FW_NAME(rco_25m, "rco-25m", "rco-100m", 4, 1, 0); +static CLK_FIXED_FACTOR_FW_NAME(rco_4m, "rco-4m", "rco-100m", 25, 1, 0); +static CLK_FIXED_FACTOR_FW_NAME(rco_2m, "rco-2m", "rco-100m", 50, 1, 0); + +#define SC9863A_MUX_FLAG \ + (CLK_GET_RATE_NOCACHE | CLK_SET_RATE_NO_REPARENT) + +static CLK_FIXED_FACTOR_FW_NAME(clk_13m, "clk-13m", "ext-26m", 2, 1, 0); +static const struct clk_parent_data emc_clk_parents[] = { + { .fw_name = "ext-26m" }, + { .hw = &twpll_384m.hw }, + { .hw = &twpll_512m.hw }, + { .hw = &twpll_768m.hw }, + { .hw = &twpll.common.hw }, +}; +static SPRD_MUX_CLK_DATA(emc_clk, "emc-clk", emc_clk_parents, 0x220, + 0, 3, SC9863A_MUX_FLAG); + +static const struct clk_parent_data aon_apb_parents[] = { + { .hw = &rco_4m.hw }, + { .hw = &rco_25m.hw }, + { .fw_name = "ext-26m" }, + { .hw = &twpll_96m.hw }, + { .fw_name = "rco-100m" }, + { .hw = &twpll_128m.hw }, +}; +static SPRD_COMP_CLK_DATA(aon_apb, "aon-apb", aon_apb_parents, 0x224, + 0, 3, 8, 2, 0); + +static const struct clk_parent_data adi_parents[] = { + { .hw = &rco_4m.hw }, + { .hw = &rco_25m.hw }, + { .fw_name = "ext-26m" }, + { .hw = &twpll_38m4.hw }, + { .hw = &twpll_51m2.hw }, +}; +static SPRD_MUX_CLK_DATA(adi_clk, "adi-clk", adi_parents, 0x228, + 0, 3, SC9863A_MUX_FLAG); + +static const struct clk_parent_data aux_parents[] = { + { .fw_name = "ext-32k" }, + { .hw = &rpll_26m.hw }, + { .fw_name = "ext-26m" }, +}; +static SPRD_COMP_CLK_DATA(aux0_clk, "aux0-clk", aux_parents, 0x22c, + 0, 5, 8, 4, 0); +static SPRD_COMP_CLK_DATA(aux1_clk, "aux1-clk", aux_parents, 0x230, + 0, 5, 8, 4, 0); +static SPRD_COMP_CLK_DATA(aux2_clk, "aux2-clk", aux_parents, 0x234, + 0, 5, 8, 4, 0); +static SPRD_COMP_CLK_DATA(probe_clk, "probe-clk", aux_parents, 0x238, + 0, 5, 8, 4, 0); + +static const struct clk_parent_data pwm_parents[] = { + { .fw_name = "ext-32k" }, + { .hw = &rpll_26m.hw }, + { .fw_name = "ext-26m" }, + { .hw = &twpll_48m.hw }, +}; +static SPRD_MUX_CLK_DATA(pwm0_clk, "pwm0-clk", pwm_parents, 0x23c, + 0, 2, SC9863A_MUX_FLAG); +static SPRD_MUX_CLK_DATA(pwm1_clk, "pwm1-clk", pwm_parents, 0x240, + 0, 2, SC9863A_MUX_FLAG); +static SPRD_MUX_CLK_DATA(pwm2_clk, "pwm2-clk", pwm_parents, 0x244, + 0, 2, SC9863A_MUX_FLAG); + +static const struct clk_parent_data aon_thm_parents[] = { + { .fw_name = "ext-32k" }, + { .hw = &clk_250k.hw }, +}; +static SPRD_MUX_CLK_DATA(aon_thm_clk, "aon-thm-clk", aon_thm_parents, 0x25c, + 0, 1, SC9863A_MUX_FLAG); + +static const struct clk_parent_data audif_parents[] = { + { .fw_name = "ext-26m" }, + { .hw = &twpll_38m4.hw }, + { .hw = &twpll_51m2.hw }, +}; +static SPRD_MUX_CLK_DATA(audif_clk, "audif-clk", audif_parents, 0x264, + 0, 2, SC9863A_MUX_FLAG); + +static const struct clk_parent_data cpu_dap_parents[] = { + { .hw = &rco_4m.hw }, + { .hw = &rco_25m.hw }, + { .fw_name = "ext-26m" }, + { .hw = &twpll_76m8.hw }, + { .fw_name = "rco-100m" }, + { .hw = &twpll_128m.hw }, + { .hw = &twpll_153m6.hw }, +}; +static SPRD_MUX_CLK_DATA(cpu_dap_clk, "cpu-dap-clk", cpu_dap_parents, 0x26c, + 0, 3, SC9863A_MUX_FLAG); + +static const struct clk_parent_data cpu_ts_parents[] = { + { .fw_name = "ext-32k" }, + { .fw_name = "ext-26m" }, + { .hw = &twpll_128m.hw }, + { .hw = &twpll_153m6.hw }, +}; +static SPRD_MUX_CLK_DATA(cpu_ts_clk, "cpu-ts-clk", cpu_ts_parents, 0x274, + 0, 2, SC9863A_MUX_FLAG); + +static const struct clk_parent_data djtag_tck_parents[] = { + { .hw = &rco_4m.hw }, + { .fw_name = "ext-26m" }, +}; +static SPRD_MUX_CLK_DATA(djtag_tck_clk, "djtag-tck-clk", djtag_tck_parents, 0x28c, + 0, 1, SC9863A_MUX_FLAG); + +static const struct clk_parent_data emc_ref_parents[] = { + { .hw = &clk_6m5.hw }, + { .hw = &clk_13m.hw }, + { .fw_name = "ext-26m" }, +}; +static SPRD_MUX_CLK_DATA(emc_ref_clk, "emc-ref-clk", emc_ref_parents, 0x29c, + 0, 2, SC9863A_MUX_FLAG); + +static const struct clk_parent_data cssys_parents[] = { + { .hw = &rco_4m.hw }, + { .fw_name = "ext-26m" }, + { .hw = &twpll_96m.hw }, + { .fw_name = "rco-100m" }, + { .hw = &twpll_128m.hw }, + { .hw = &twpll_153m6.hw }, + { .hw = &twpll_384m.hw }, + { .hw = &twpll_512m.hw }, + { .hw = &mpll2_675m.hw }, +}; +static SPRD_COMP_CLK_DATA(cssys_clk, "cssys-clk", cssys_parents, 0x2a0, + 0, 4, 8, 2, 0); + +static const struct clk_parent_data aon_pmu_parents[] = { + { .fw_name = "ext-32k" }, + { .hw = &rco_4m.hw }, + { .fw_name = "ext-4m" }, +}; +static SPRD_MUX_CLK_DATA(aon_pmu_clk, "aon-pmu-clk", aon_pmu_parents, 0x2a8, + 0, 2, SC9863A_MUX_FLAG); + +static const struct clk_parent_data pmu_26m_parents[] = { + { .hw = &rco_4m.hw }, + { .hw = &rco_25m.hw }, + { .fw_name = "ext-26m" }, +}; +static SPRD_MUX_CLK_DATA(pmu_26m_clk, "26m-pmu-clk", pmu_26m_parents, 0x2ac, + 0, 2, SC9863A_MUX_FLAG); + +static const struct clk_parent_data aon_tmr_parents[] = { + { .hw = &rco_4m.hw }, + { .fw_name = "ext-26m" }, +}; +static SPRD_MUX_CLK_DATA(aon_tmr_clk, "aon-tmr-clk", aon_tmr_parents, 0x2b0, + 0, 1, SC9863A_MUX_FLAG); + +static const struct clk_parent_data power_cpu_parents[] = { + { .fw_name = "ext-26m" }, + { .hw = &rco_25m.hw }, + { .fw_name = "rco-100m" }, + { .hw = &twpll_128m.hw }, +}; +static SPRD_MUX_CLK_DATA(power_cpu_clk, "power-cpu-clk", power_cpu_parents, 0x2c4, + 0, 2, SC9863A_MUX_FLAG); + +static const struct clk_parent_data ap_axi_parents[] = { + { .fw_name = "ext-26m" }, + { .hw = &twpll_76m8.hw }, + { .hw = &twpll_128m.hw }, + { .hw = &twpll_256m.hw }, +}; +static SPRD_MUX_CLK_DATA(ap_axi, "ap-axi", ap_axi_parents, 0x2c8, + 0, 2, SC9863A_MUX_FLAG); + +static const struct clk_parent_data sdio_parents[] = { + { .fw_name = "ext-26m" }, + { .hw = &twpll_307m2.hw }, + { .hw = &twpll_384m.hw }, + { .hw = &rpll_390m.hw }, + { .hw = &dpll1_400m.hw }, + { .hw = &lpll_409m6.hw }, +}; +static SPRD_MUX_CLK_DATA(sdio0_2x, "sdio0-2x", sdio_parents, 0x2cc, + 0, 3, SC9863A_MUX_FLAG); +static SPRD_MUX_CLK_DATA(sdio1_2x, "sdio1-2x", sdio_parents, 0x2d4, + 0, 3, SC9863A_MUX_FLAG); +static SPRD_MUX_CLK_DATA(sdio2_2x, "sdio2-2x", sdio_parents, 0x2dc, + 0, 3, SC9863A_MUX_FLAG); +static SPRD_MUX_CLK_DATA(emmc_2x, "emmc-2x", sdio_parents, 0x2e4, + 0, 3, SC9863A_MUX_FLAG); + +static const struct clk_parent_data dpu_parents[] = { + { .hw = &twpll_153m6.hw }, + { .hw = &twpll_192m.hw }, + { .hw = &twpll_256m.hw }, + { .hw = &twpll_384m.hw }, +}; +static SPRD_MUX_CLK_DATA(dpu_clk, "dpu", dpu_parents, 0x2f4, + 0, 2, SC9863A_MUX_FLAG); + +static const struct clk_parent_data dpu_dpi_parents[] = { + { .hw = &twpll_128m.hw }, + { .hw = &twpll_153m6.hw }, + { .hw = &twpll_192m.hw }, +}; +static SPRD_COMP_CLK_DATA(dpu_dpi, "dpu-dpi", dpu_dpi_parents, 0x2f8, + 0, 2, 8, 4, 0); + +static const struct clk_parent_data otg_ref_parents[] = { + { .hw = &twpll_12m.hw }, + { .fw_name = "ext-26m" }, +}; +static SPRD_MUX_CLK_DATA(otg_ref_clk, "otg-ref-clk", otg_ref_parents, 0x308, + 0, 1, SC9863A_MUX_FLAG); + +static const struct clk_parent_data sdphy_apb_parents[] = { + { .fw_name = "ext-26m" }, + { .hw = &twpll_48m.hw }, +}; +static SPRD_MUX_CLK_DATA(sdphy_apb_clk, "sdphy-apb-clk", sdphy_apb_parents, 0x330, + 0, 1, SC9863A_MUX_FLAG); + +static const struct clk_parent_data alg_io_apb_parents[] = { + { .hw = &rco_4m.hw }, + { .fw_name = "ext-26m" }, + { .hw = &twpll_48m.hw }, + { .hw = &twpll_96m.hw }, +}; +static SPRD_MUX_CLK_DATA(alg_io_apb_clk, "alg-io-apb-clk", alg_io_apb_parents, 0x33c, + 0, 1, SC9863A_MUX_FLAG); + +static const struct clk_parent_data gpu_parents[] = { + { .hw = &twpll_153m6.hw }, + { .hw = &twpll_192m.hw }, + { .hw = &twpll_256m.hw }, + { .hw = &twpll_307m2.hw }, + { .hw = &twpll_384m.hw }, + { .hw = &twpll_512m.hw }, + { .hw = &gpll.common.hw }, +}; +static SPRD_COMP_CLK_DATA(gpu_core, "gpu-core", gpu_parents, 0x344, + 0, 3, 8, 2, 0); +static SPRD_COMP_CLK_DATA(gpu_soc, "gpu-soc", gpu_parents, 0x348, + 0, 3, 8, 2, 0); + +static const struct clk_parent_data mm_emc_parents[] = { + { .fw_name = "ext-26m" }, + { .hw = &twpll_384m.hw }, + { .hw = &isppll_468m.hw }, + { .hw = &twpll_512m.hw }, +}; +static SPRD_MUX_CLK_DATA(mm_emc, "mm-emc", mm_emc_parents, 0x350, + 0, 2, SC9863A_MUX_FLAG); + +static const struct clk_parent_data mm_ahb_parents[] = { + { .fw_name = "ext-26m" }, + { .hw = &twpll_96m.hw }, + { .hw = &twpll_128m.hw }, + { .hw = &twpll_153m6.hw }, +}; +static SPRD_MUX_CLK_DATA(mm_ahb, "mm-ahb", mm_ahb_parents, 0x354, + 0, 2, SC9863A_MUX_FLAG); + +static const struct clk_parent_data bpc_clk_parents[] = { + { .hw = &twpll_192m.hw }, + { .hw = &twpll_307m2.hw }, + { .hw = &twpll_384m.hw }, + { .hw = &isppll_468m.hw }, + { .hw = &dpll0_622m3.hw }, +}; +static SPRD_MUX_CLK_DATA(bpc_clk, "bpc-clk", bpc_clk_parents, 0x358, + 0, 3, SC9863A_MUX_FLAG); + +static const struct clk_parent_data dcam_if_parents[] = { + { .hw = &twpll_192m.hw }, + { .hw = &twpll_256m.hw }, + { .hw = &twpll_307m2.hw }, + { .hw = &twpll_384m.hw }, +}; +static SPRD_MUX_CLK_DATA(dcam_if_clk, "dcam-if-clk", dcam_if_parents, 0x35c, + 0, 2, SC9863A_MUX_FLAG); + +static const struct clk_parent_data isp_parents[] = { + { .hw = &twpll_128m.hw }, + { .hw = &twpll_256m.hw }, + { .hw = &twpll_307m2.hw }, + { .hw = &twpll_384m.hw }, + { .hw = &isppll_468m.hw }, +}; +static SPRD_MUX_CLK_DATA(isp_clk, "isp-clk", isp_parents, 0x360, + 0, 3, SC9863A_MUX_FLAG); + +static const struct clk_parent_data jpg_parents[] = { + { .hw = &twpll_76m8.hw }, + { .hw = &twpll_128m.hw }, + { .hw = &twpll_256m.hw }, + { .hw = &twpll_307m2.hw }, +}; +static SPRD_MUX_CLK_DATA(jpg_clk, "jpg-clk", jpg_parents, 0x364, + 0, 2, SC9863A_MUX_FLAG); +static SPRD_MUX_CLK_DATA(cpp_clk, "cpp-clk", jpg_parents, 0x368, + 0, 2, SC9863A_MUX_FLAG); + +static const struct clk_parent_data sensor_parents[] = { + { .fw_name = "ext-26m" }, + { .hw = &twpll_48m.hw }, + { .hw = &twpll_76m8.hw }, + { .hw = &twpll_96m.hw }, +}; +static SPRD_COMP_CLK_DATA(sensor0_clk, "sensor0-clk", sensor_parents, 0x36c, + 0, 2, 8, 3, 0); +static SPRD_COMP_CLK_DATA(sensor1_clk, "sensor1-clk", sensor_parents, 0x370, + 0, 2, 8, 3, 0); +static SPRD_COMP_CLK_DATA(sensor2_clk, "sensor2-clk", sensor_parents, 0x374, + 0, 2, 8, 3, 0); + +static const struct clk_parent_data mm_vemc_parents[] = { + { .fw_name = "ext-26m" }, + { .hw = &twpll_307m2.hw }, + { .hw = &twpll_384m.hw }, + { .hw = &isppll_468m.hw }, +}; +static SPRD_MUX_CLK_DATA(mm_vemc, "mm-vemc", mm_vemc_parents, 0x378, + 0, 2, SC9863A_MUX_FLAG); + +static SPRD_MUX_CLK_DATA(mm_vahb, "mm-vahb", mm_ahb_parents, 0x37c, + 0, 2, SC9863A_MUX_FLAG); + +static const struct clk_parent_data vsp_parents[] = { + { .hw = &twpll_76m8.hw }, + { .hw = &twpll_128m.hw }, + { .hw = &twpll_256m.hw }, + { .hw = &twpll_307m2.hw }, + { .hw = &twpll_384m.hw }, +}; +static SPRD_MUX_CLK_DATA(clk_vsp, "vsp-clk", vsp_parents, 0x380, + 0, 3, SC9863A_MUX_FLAG); + +static const struct clk_parent_data core_parents[] = { + { .fw_name = "ext-26m" }, + { .hw = &twpll_512m.hw }, + { .hw = &twpll_768m.hw }, + { .hw = &lpll.common.hw }, + { .hw = &dpll0.common.hw }, + { .hw = &mpll2.common.hw }, + { .hw = &mpll0.common.hw }, + { .hw = &mpll1.common.hw }, +}; +static SPRD_COMP_CLK_DATA(core0_clk, "core0-clk", core_parents, 0xa20, + 0, 3, 8, 3, 0); +static SPRD_COMP_CLK_DATA(core1_clk, "core1-clk", core_parents, 0xa24, + 0, 3, 8, 3, 0); +static SPRD_COMP_CLK_DATA(core2_clk, "core2-clk", core_parents, 0xa28, + 0, 3, 8, 3, 0); +static SPRD_COMP_CLK_DATA(core3_clk, "core3-clk", core_parents, 0xa2c, + 0, 3, 8, 3, 0); +static SPRD_COMP_CLK_DATA(core4_clk, "core4-clk", core_parents, 0xa30, + 0, 3, 8, 3, 0); +static SPRD_COMP_CLK_DATA(core5_clk, "core5-clk", core_parents, 0xa34, + 0, 3, 8, 3, 0); +static SPRD_COMP_CLK_DATA(core6_clk, "core6-clk", core_parents, 0xa38, + 0, 3, 8, 3, 0); +static SPRD_COMP_CLK_DATA(core7_clk, "core7-clk", core_parents, 0xa3c, + 0, 3, 8, 3, 0); +static SPRD_COMP_CLK_DATA(scu_clk, "scu-clk", core_parents, 0xa40, + 0, 3, 8, 3, 0); + +static SPRD_DIV_CLK_HW(ace_clk, "ace-clk", &scu_clk.common.hw, 0xa44, + 8, 3, 0); +static SPRD_DIV_CLK_HW(axi_periph_clk, "axi-periph-clk", &scu_clk.common.hw, 0xa48, + 8, 3, 0); +static SPRD_DIV_CLK_HW(axi_acp_clk, "axi-acp-clk", &scu_clk.common.hw, 0xa4c, + 8, 3, 0); + +static const struct clk_parent_data atb_parents[] = { + { .fw_name = "ext-26m" }, + { .hw = &twpll_384m.hw }, + { .hw = &twpll_512m.hw }, + { .hw = &mpll2.common.hw }, +}; +static SPRD_COMP_CLK_DATA(atb_clk, "atb-clk", atb_parents, 0xa50, + 0, 2, 8, 3, 0); +static SPRD_DIV_CLK_HW(debug_apb_clk, "debug-apb-clk", &atb_clk.common.hw, 0xa54, + 8, 3, 0); + +static const struct clk_parent_data gic_parents[] = { + { .fw_name = "ext-26m" }, + { .hw = &twpll_153m6.hw }, + { .hw = &twpll_384m.hw }, + { .hw = &twpll_512m.hw }, +}; +static SPRD_COMP_CLK_DATA(gic_clk, "gic-clk", gic_parents, 0xa58, + 0, 2, 8, 3, 0); +static SPRD_COMP_CLK_DATA(periph_clk, "periph-clk", gic_parents, 0xa5c, + 0, 2, 8, 3, 0); + +static struct sprd_clk_common *sc9863a_aon_clks[] = { + /* address base is 0x402d0000 */ + &emc_clk.common, + &aon_apb.common, + &adi_clk.common, + &aux0_clk.common, + &aux1_clk.common, + &aux2_clk.common, + &probe_clk.common, + &pwm0_clk.common, + &pwm1_clk.common, + &pwm2_clk.common, + &aon_thm_clk.common, + &audif_clk.common, + &cpu_dap_clk.common, + &cpu_ts_clk.common, + &djtag_tck_clk.common, + &emc_ref_clk.common, + &cssys_clk.common, + &aon_pmu_clk.common, + &pmu_26m_clk.common, + &aon_tmr_clk.common, + &power_cpu_clk.common, + &ap_axi.common, + &sdio0_2x.common, + &sdio1_2x.common, + &sdio2_2x.common, + &emmc_2x.common, + &dpu_clk.common, + &dpu_dpi.common, + &otg_ref_clk.common, + &sdphy_apb_clk.common, + &alg_io_apb_clk.common, + &gpu_core.common, + &gpu_soc.common, + &mm_emc.common, + &mm_ahb.common, + &bpc_clk.common, + &dcam_if_clk.common, + &isp_clk.common, + &jpg_clk.common, + &cpp_clk.common, + &sensor0_clk.common, + &sensor1_clk.common, + &sensor2_clk.common, + &mm_vemc.common, + &mm_vahb.common, + &clk_vsp.common, + &core0_clk.common, + &core1_clk.common, + &core2_clk.common, + &core3_clk.common, + &core4_clk.common, + &core5_clk.common, + &core6_clk.common, + &core7_clk.common, + &scu_clk.common, + &ace_clk.common, + &axi_periph_clk.common, + &axi_acp_clk.common, + &atb_clk.common, + &debug_apb_clk.common, + &gic_clk.common, + &periph_clk.common, +}; + +static struct clk_hw_onecell_data sc9863a_aon_clk_hws = { + .hws = { + [CLK_13M] = &clk_13m.hw, + [CLK_6M5] = &clk_6m5.hw, + [CLK_4M3] = &clk_4m3.hw, + [CLK_2M] = &clk_2m.hw, + [CLK_250K] = &clk_250k.hw, + [CLK_RCO_25M] = &rco_25m.hw, + [CLK_RCO_4M] = &rco_4m.hw, + [CLK_RCO_2M] = &rco_2m.hw, + [CLK_EMC] = &emc_clk.common.hw, + [CLK_AON_APB] = &aon_apb.common.hw, + [CLK_ADI] = &adi_clk.common.hw, + [CLK_AUX0] = &aux0_clk.common.hw, + [CLK_AUX1] = &aux1_clk.common.hw, + [CLK_AUX2] = &aux2_clk.common.hw, + [CLK_PROBE] = &probe_clk.common.hw, + [CLK_PWM0] = &pwm0_clk.common.hw, + [CLK_PWM1] = &pwm1_clk.common.hw, + [CLK_PWM2] = &pwm2_clk.common.hw, + [CLK_AON_THM] = &aon_thm_clk.common.hw, + [CLK_AUDIF] = &audif_clk.common.hw, + [CLK_CPU_DAP] = &cpu_dap_clk.common.hw, + [CLK_CPU_TS] = &cpu_ts_clk.common.hw, + [CLK_DJTAG_TCK] = &djtag_tck_clk.common.hw, + [CLK_EMC_REF] = &emc_ref_clk.common.hw, + [CLK_CSSYS] = &cssys_clk.common.hw, + [CLK_AON_PMU] = &aon_pmu_clk.common.hw, + [CLK_PMU_26M] = &pmu_26m_clk.common.hw, + [CLK_AON_TMR] = &aon_tmr_clk.common.hw, + [CLK_POWER_CPU] = &power_cpu_clk.common.hw, + [CLK_AP_AXI] = &ap_axi.common.hw, + [CLK_SDIO0_2X] = &sdio0_2x.common.hw, + [CLK_SDIO1_2X] = &sdio1_2x.common.hw, + [CLK_SDIO2_2X] = &sdio2_2x.common.hw, + [CLK_EMMC_2X] = &emmc_2x.common.hw, + [CLK_DPU] = &dpu_clk.common.hw, + [CLK_DPU_DPI] = &dpu_dpi.common.hw, + [CLK_OTG_REF] = &otg_ref_clk.common.hw, + [CLK_SDPHY_APB] = &sdphy_apb_clk.common.hw, + [CLK_ALG_IO_APB] = &alg_io_apb_clk.common.hw, + [CLK_GPU_CORE] = &gpu_core.common.hw, + [CLK_GPU_SOC] = &gpu_soc.common.hw, + [CLK_MM_EMC] = &mm_emc.common.hw, + [CLK_MM_AHB] = &mm_ahb.common.hw, + [CLK_BPC] = &bpc_clk.common.hw, + [CLK_DCAM_IF] = &dcam_if_clk.common.hw, + [CLK_ISP] = &isp_clk.common.hw, + [CLK_JPG] = &jpg_clk.common.hw, + [CLK_CPP] = &cpp_clk.common.hw, + [CLK_SENSOR0] = &sensor0_clk.common.hw, + [CLK_SENSOR1] = &sensor1_clk.common.hw, + [CLK_SENSOR2] = &sensor2_clk.common.hw, + [CLK_MM_VEMC] = &mm_vemc.common.hw, + [CLK_MM_VAHB] = &mm_vahb.common.hw, + [CLK_VSP] = &clk_vsp.common.hw, + [CLK_CORE0] = &core0_clk.common.hw, + [CLK_CORE1] = &core1_clk.common.hw, + [CLK_CORE2] = &core2_clk.common.hw, + [CLK_CORE3] = &core3_clk.common.hw, + [CLK_CORE4] = &core4_clk.common.hw, + [CLK_CORE5] = &core5_clk.common.hw, + [CLK_CORE6] = &core6_clk.common.hw, + [CLK_CORE7] = &core7_clk.common.hw, + [CLK_SCU] = &scu_clk.common.hw, + [CLK_ACE] = &ace_clk.common.hw, + [CLK_AXI_PERIPH] = &axi_periph_clk.common.hw, + [CLK_AXI_ACP] = &axi_acp_clk.common.hw, + [CLK_ATB] = &atb_clk.common.hw, + [CLK_DEBUG_APB] = &debug_apb_clk.common.hw, + [CLK_GIC] = &gic_clk.common.hw, + [CLK_PERIPH] = &periph_clk.common.hw, + }, + .num = CLK_AON_CLK_NUM, +}; + +static const struct sprd_clk_desc sc9863a_aon_clk_desc = { + .clk_clks = sc9863a_aon_clks, + .num_clk_clks = ARRAY_SIZE(sc9863a_aon_clks), + .hw_clks = &sc9863a_aon_clk_hws, +}; + +static const struct clk_parent_data ap_apb_parents[] = { + { .fw_name = "ext-26m" }, + { .hw = &twpll_64m.hw }, + { .hw = &twpll_96m.hw }, + { .hw = &twpll_128m.hw }, +}; +static SPRD_MUX_CLK_DATA(ap_apb, "ap-apb", ap_apb_parents, 0x20, + 0, 2, SC9863A_MUX_FLAG); + +static const struct clk_parent_data ap_ce_parents[] = { + { .fw_name = "ext-26m" }, + { .hw = &twpll_256m.hw }, +}; +static SPRD_COMP_CLK_DATA(ap_ce, "ap-ce", ap_ce_parents, 0x24, + 0, 1, 8, 3, 0); + +static const struct clk_parent_data nandc_ecc_parents[] = { + { .fw_name = "ext-26m" }, + { .hw = &twpll_256m.hw }, + { .hw = &twpll_307m2.hw }, +}; +static SPRD_COMP_CLK_DATA(nandc_ecc, "nandc-ecc", nandc_ecc_parents, 0x28, + 0, 2, 8, 3, 0); + +static const struct clk_parent_data nandc_26m_parents[] = { + { .fw_name = "ext-32k" }, + { .fw_name = "ext-26m" }, +}; +static SPRD_MUX_CLK_DATA(nandc_26m, "nandc-26m", nandc_26m_parents, 0x2c, + 0, 1, SC9863A_MUX_FLAG); +static SPRD_MUX_CLK_DATA(emmc_32k, "emmc-32k", nandc_26m_parents, 0x30, + 0, 1, SC9863A_MUX_FLAG); +static SPRD_MUX_CLK_DATA(sdio0_32k, "sdio0-32k", nandc_26m_parents, 0x34, + 0, 1, SC9863A_MUX_FLAG); +static SPRD_MUX_CLK_DATA(sdio1_32k, "sdio1-32k", nandc_26m_parents, 0x38, + 0, 1, SC9863A_MUX_FLAG); +static SPRD_MUX_CLK_DATA(sdio2_32k, "sdio2-32k", nandc_26m_parents, 0x3c, + 0, 1, SC9863A_MUX_FLAG); + +static SPRD_GATE_CLK_HW(otg_utmi, "otg-utmi", &aon_apb.common.hw, 0x40, + BIT(16), 0, 0); + +static const struct clk_parent_data ap_uart_parents[] = { + { .fw_name = "ext-26m" }, + { .hw = &twpll_48m.hw }, + { .hw = &twpll_51m2.hw }, + { .hw = &twpll_96m.hw }, +}; +static SPRD_COMP_CLK_DATA(ap_uart0, "ap-uart0", ap_uart_parents, 0x44, + 0, 2, 8, 3, 0); +static SPRD_COMP_CLK_DATA(ap_uart1, "ap-uart1", ap_uart_parents, 0x48, + 0, 2, 8, 3, 0); +static SPRD_COMP_CLK_DATA(ap_uart2, "ap-uart2", ap_uart_parents, 0x4c, + 0, 2, 8, 3, 0); +static SPRD_COMP_CLK_DATA(ap_uart3, "ap-uart3", ap_uart_parents, 0x50, + 0, 2, 8, 3, 0); +static SPRD_COMP_CLK_DATA(ap_uart4, "ap-uart4", ap_uart_parents, 0x54, + 0, 2, 8, 3, 0); + +static const struct clk_parent_data i2c_parents[] = { + { .fw_name = "ext-26m" }, + { .hw = &twpll_48m.hw }, + { .hw = &twpll_51m2.hw }, + { .hw = &twpll_153m6.hw }, +}; +static SPRD_COMP_CLK_DATA(ap_i2c0, "ap-i2c0", i2c_parents, 0x58, + 0, 2, 8, 3, 0); +static SPRD_COMP_CLK_DATA(ap_i2c1, "ap-i2c1", i2c_parents, 0x5c, + 0, 2, 8, 3, 0); +static SPRD_COMP_CLK_DATA(ap_i2c2, "ap-i2c2", i2c_parents, 0x60, + 0, 2, 8, 3, 0); +static SPRD_COMP_CLK_DATA(ap_i2c3, "ap-i2c3", i2c_parents, 0x64, + 0, 2, 8, 3, 0); +static SPRD_COMP_CLK_DATA(ap_i2c4, "ap-i2c4", i2c_parents, 0x68, + 0, 2, 8, 3, 0); +static SPRD_COMP_CLK_DATA(ap_i2c5, "ap-i2c5", i2c_parents, 0x6c, + 0, 2, 8, 3, 0); +static SPRD_COMP_CLK_DATA(ap_i2c6, "ap-i2c6", i2c_parents, 0x70, + 0, 2, 8, 3, 0); + +static const struct clk_parent_data spi_parents[] = { + { .fw_name = "ext-26m" }, + { .hw = &twpll_128m.hw }, + { .hw = &twpll_153m6.hw }, + { .hw = &twpll_192m.hw }, +}; +static SPRD_COMP_CLK_DATA(ap_spi0, "ap-spi0", spi_parents, 0x74, + 0, 2, 8, 3, 0); +static SPRD_COMP_CLK_DATA(ap_spi1, "ap-spi1", spi_parents, 0x78, + 0, 2, 8, 3, 0); +static SPRD_COMP_CLK_DATA(ap_spi2, "ap-spi2", spi_parents, 0x7c, + 0, 2, 8, 3, 0); +static SPRD_COMP_CLK_DATA(ap_spi3, "ap-spi3", spi_parents, 0x80, + 0, 2, 8, 3, 0); + +static const struct clk_parent_data iis_parents[] = { + { .fw_name = "ext-26m" }, + { .hw = &twpll_128m.hw }, + { .hw = &twpll_153m6.hw }, +}; +static SPRD_COMP_CLK_DATA(ap_iis0, "ap-iis0", iis_parents, 0x84, + 0, 2, 8, 3, 0); +static SPRD_COMP_CLK_DATA(ap_iis1, "ap-iis1", iis_parents, 0x88, + 0, 2, 8, 3, 0); +static SPRD_COMP_CLK_DATA(ap_iis2, "ap-iis2", iis_parents, 0x8c, + 0, 2, 8, 3, 0); + +static const struct clk_parent_data sim0_parents[] = { + { .fw_name = "ext-26m" }, + { .hw = &twpll_51m2.hw }, + { .hw = &twpll_64m.hw }, + { .hw = &twpll_96m.hw }, + { .hw = &twpll_128m.hw }, +}; +static SPRD_COMP_CLK_DATA(sim0, "sim0", sim0_parents, 0x90, + 0, 3, 8, 3, 0); + +static const struct clk_parent_data sim0_32k_parents[] = { + { .fw_name = "ext-32k" }, + { .fw_name = "ext-26m" }, +}; +static SPRD_MUX_CLK_DATA(sim0_32k, "sim0-32k", sim0_32k_parents, 0x94, + 0, 1, SC9863A_MUX_FLAG); + +static struct sprd_clk_common *sc9863a_ap_clks[] = { + /* address base is 0x21500000 */ + &ap_apb.common, + &ap_ce.common, + &nandc_ecc.common, + &nandc_26m.common, + &emmc_32k.common, + &sdio0_32k.common, + &sdio1_32k.common, + &sdio2_32k.common, + &otg_utmi.common, + &ap_uart0.common, + &ap_uart1.common, + &ap_uart2.common, + &ap_uart3.common, + &ap_uart4.common, + &ap_i2c0.common, + &ap_i2c1.common, + &ap_i2c2.common, + &ap_i2c3.common, + &ap_i2c4.common, + &ap_i2c5.common, + &ap_i2c6.common, + &ap_spi0.common, + &ap_spi1.common, + &ap_spi2.common, + &ap_spi3.common, + &ap_iis0.common, + &ap_iis1.common, + &ap_iis2.common, + &sim0.common, + &sim0_32k.common, +}; + +static struct clk_hw_onecell_data sc9863a_ap_clk_hws = { + .hws = { + [CLK_AP_APB] = &ap_apb.common.hw, + [CLK_AP_CE] = &ap_ce.common.hw, + [CLK_NANDC_ECC] = &nandc_ecc.common.hw, + [CLK_NANDC_26M] = &nandc_26m.common.hw, + [CLK_EMMC_32K] = &emmc_32k.common.hw, + [CLK_SDIO0_32K] = &sdio0_32k.common.hw, + [CLK_SDIO1_32K] = &sdio1_32k.common.hw, + [CLK_SDIO2_32K] = &sdio2_32k.common.hw, + [CLK_OTG_UTMI] = &otg_utmi.common.hw, + [CLK_AP_UART0] = &ap_uart0.common.hw, + [CLK_AP_UART1] = &ap_uart1.common.hw, + [CLK_AP_UART2] = &ap_uart2.common.hw, + [CLK_AP_UART3] = &ap_uart3.common.hw, + [CLK_AP_UART4] = &ap_uart4.common.hw, + [CLK_AP_I2C0] = &ap_i2c0.common.hw, + [CLK_AP_I2C1] = &ap_i2c1.common.hw, + [CLK_AP_I2C2] = &ap_i2c2.common.hw, + [CLK_AP_I2C3] = &ap_i2c3.common.hw, + [CLK_AP_I2C4] = &ap_i2c4.common.hw, + [CLK_AP_I2C5] = &ap_i2c5.common.hw, + [CLK_AP_I2C6] = &ap_i2c6.common.hw, + [CLK_AP_SPI0] = &ap_spi0.common.hw, + [CLK_AP_SPI1] = &ap_spi1.common.hw, + [CLK_AP_SPI2] = &ap_spi2.common.hw, + [CLK_AP_SPI3] = &ap_spi3.common.hw, + [CLK_AP_IIS0] = &ap_iis0.common.hw, + [CLK_AP_IIS1] = &ap_iis1.common.hw, + [CLK_AP_IIS2] = &ap_iis2.common.hw, + [CLK_SIM0] = &sim0.common.hw, + [CLK_SIM0_32K] = &sim0_32k.common.hw, + }, + .num = CLK_AP_CLK_NUM, +}; + +static const struct sprd_clk_desc sc9863a_ap_clk_desc = { + .clk_clks = sc9863a_ap_clks, + .num_clk_clks = ARRAY_SIZE(sc9863a_ap_clks), + .hw_clks = &sc9863a_ap_clk_hws, +}; + +static SPRD_SC_GATE_CLK_HW(otg_eb, "otg-eb", &ap_axi.common.hw, 0x0, 0x1000, + BIT(4), 0, 0); +static SPRD_SC_GATE_CLK_HW(dma_eb, "dma-eb", &ap_axi.common.hw, 0x0, 0x1000, + BIT(5), 0, 0); +static SPRD_SC_GATE_CLK_HW(ce_eb, "ce-eb", &ap_axi.common.hw, 0x0, 0x1000, + BIT(6), 0, 0); +static SPRD_SC_GATE_CLK_HW(nandc_eb, "nandc-eb", &ap_axi.common.hw, 0x0, 0x1000, + BIT(7), 0, 0); +static SPRD_SC_GATE_CLK_HW(sdio0_eb, "sdio0-eb", &ap_axi.common.hw, 0x0, 0x1000, + BIT(8), 0, 0); +static SPRD_SC_GATE_CLK_HW(sdio1_eb, "sdio1-eb", &ap_axi.common.hw, 0x0, 0x1000, + BIT(9), 0, 0); +static SPRD_SC_GATE_CLK_HW(sdio2_eb, "sdio2-eb", &ap_axi.common.hw, 0x0, 0x1000, + BIT(10), 0, 0); +static SPRD_SC_GATE_CLK_HW(emmc_eb, "emmc-eb", &ap_axi.common.hw, 0x0, 0x1000, + BIT(11), 0, 0); +static SPRD_SC_GATE_CLK_HW(emmc_32k_eb, "emmc-32k-eb", &ap_axi.common.hw, 0x0, + 0x1000, BIT(27), 0, 0); +static SPRD_SC_GATE_CLK_HW(sdio0_32k_eb, "sdio0-32k-eb", &ap_axi.common.hw, 0x0, + 0x1000, BIT(28), 0, 0); +static SPRD_SC_GATE_CLK_HW(sdio1_32k_eb, "sdio1-32k-eb", &ap_axi.common.hw, 0x0, + 0x1000, BIT(29), 0, 0); +static SPRD_SC_GATE_CLK_HW(sdio2_32k_eb, "sdio2-32k-eb", &ap_axi.common.hw, 0x0, + 0x1000, BIT(30), 0, 0); +static SPRD_SC_GATE_CLK_HW(nandc_26m_eb, "nandc-26m-eb", &ap_axi.common.hw, 0x0, + 0x1000, BIT(31), 0, 0); +static SPRD_SC_GATE_CLK_HW(dma_eb2, "dma-eb2", &ap_axi.common.hw, 0x18, + 0x1000, BIT(0), 0, 0); +static SPRD_SC_GATE_CLK_HW(ce_eb2, "ce-eb2", &ap_axi.common.hw, 0x18, + 0x1000, BIT(1), 0, 0); + +static struct sprd_clk_common *sc9863a_apahb_gate_clks[] = { + /* address base is 0x20e00000 */ + &otg_eb.common, + &dma_eb.common, + &ce_eb.common, + &nandc_eb.common, + &sdio0_eb.common, + &sdio1_eb.common, + &sdio2_eb.common, + &emmc_eb.common, + &emmc_32k_eb.common, + &sdio0_32k_eb.common, + &sdio1_32k_eb.common, + &sdio2_32k_eb.common, + &nandc_26m_eb.common, + &dma_eb2.common, + &ce_eb2.common, +}; + +static struct clk_hw_onecell_data sc9863a_apahb_gate_hws = { + .hws = { + [CLK_OTG_EB] = &otg_eb.common.hw, + [CLK_DMA_EB] = &dma_eb.common.hw, + [CLK_CE_EB] = &ce_eb.common.hw, + [CLK_NANDC_EB] = &nandc_eb.common.hw, + [CLK_SDIO0_EB] = &sdio0_eb.common.hw, + [CLK_SDIO1_EB] = &sdio1_eb.common.hw, + [CLK_SDIO2_EB] = &sdio2_eb.common.hw, + [CLK_EMMC_EB] = &emmc_eb.common.hw, + [CLK_EMMC_32K_EB] = &emmc_32k_eb.common.hw, + [CLK_SDIO0_32K_EB] = &sdio0_32k_eb.common.hw, + [CLK_SDIO1_32K_EB] = &sdio1_32k_eb.common.hw, + [CLK_SDIO2_32K_EB] = &sdio2_32k_eb.common.hw, + [CLK_NANDC_26M_EB] = &nandc_26m_eb.common.hw, + [CLK_DMA_EB2] = &dma_eb2.common.hw, + [CLK_CE_EB2] = &ce_eb2.common.hw, + }, + .num = CLK_AP_AHB_GATE_NUM, +}; + +static const struct sprd_clk_desc sc9863a_apahb_gate_desc = { + .clk_clks = sc9863a_apahb_gate_clks, + .num_clk_clks = ARRAY_SIZE(sc9863a_apahb_gate_clks), + .hw_clks = &sc9863a_apahb_gate_hws, +}; + +/* aon gate clocks */ +static SPRD_SC_GATE_CLK_HW(gpio_eb, "gpio-eb", &aon_apb.common.hw, + 0x0, 0x1000, BIT(3), 0, 0); +static SPRD_SC_GATE_CLK_HW(pwm0_eb, "pwm0-eb", &aon_apb.common.hw, + 0x0, 0x1000, BIT(4), 0, 0); +static SPRD_SC_GATE_CLK_HW(pwm1_eb, "pwm1-eb", &aon_apb.common.hw, + 0x0, 0x1000, BIT(5), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK_HW(pwm2_eb, "pwm2-eb", &aon_apb.common.hw, 0x0, + 0x1000, BIT(6), 0, 0); +static SPRD_SC_GATE_CLK_HW(pwm3_eb, "pwm3-eb", &aon_apb.common.hw, 0x0, + 0x1000, BIT(7), 0, 0); +static SPRD_SC_GATE_CLK_HW(kpd_eb, "kpd-eb", &aon_apb.common.hw, 0x0, + 0x1000, BIT(8), 0, 0); +static SPRD_SC_GATE_CLK_HW(aon_syst_eb, "aon-syst-eb", &aon_apb.common.hw, 0x0, + 0x1000, BIT(9), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK_HW(ap_syst_eb, "ap-syst-eb", &aon_apb.common.hw, 0x0, + 0x1000, BIT(10), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK_HW(aon_tmr_eb, "aon-tmr-eb", &aon_apb.common.hw, 0x0, + 0x1000, BIT(11), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK_HW(efuse_eb, "efuse-eb", &aon_apb.common.hw, 0x0, + 0x1000, BIT(13), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK_HW(eic_eb, "eic-eb", &aon_apb.common.hw, 0x0, + 0x1000, BIT(14), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK_HW(intc_eb, "intc-eb", &aon_apb.common.hw, 0x0, + 0x1000, BIT(15), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK_HW(adi_eb, "adi-eb", &aon_apb.common.hw, 0x0, + 0x1000, BIT(16), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK_HW(audif_eb, "audif-eb", &aon_apb.common.hw, 0x0, + 0x1000, BIT(17), 0, 0); +static SPRD_SC_GATE_CLK_HW(aud_eb, "aud-eb", &aon_apb.common.hw, 0x0, + 0x1000, BIT(18), 0, 0); +static SPRD_SC_GATE_CLK_HW(vbc_eb, "vbc-eb", &aon_apb.common.hw, 0x0, + 0x1000, BIT(19), 0, 0); +static SPRD_SC_GATE_CLK_HW(pin_eb, "pin-eb", &aon_apb.common.hw, 0x0, + 0x1000, BIT(20), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK_HW(ap_wdg_eb, "ap-wdg-eb", &aon_apb.common.hw, 0x0, + 0x1000, BIT(24), 0, 0); +static SPRD_SC_GATE_CLK_HW(mm_eb, "mm-eb", &aon_apb.common.hw, 0x0, + 0x1000, BIT(25), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK_HW(aon_apb_ckg_eb, "aon-apb-ckg-eb", &aon_apb.common.hw, + 0x0, 0x1000, BIT(26), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK_HW(ca53_ts0_eb, "ca53-ts0-eb", &aon_apb.common.hw, + 0x0, 0x1000, BIT(28), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK_HW(ca53_ts1_eb, "ca53-ts1-eb", &aon_apb.common.hw, + 0x0, 0x1000, BIT(29), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK_HW(ca53_dap_eb, "ca53-dap-eb", &aon_apb.common.hw, + 0x0, 0x1000, BIT(30), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK_HW(pmu_eb, "pmu-eb", &aon_apb.common.hw, + 0x4, 0x1000, BIT(0), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK_HW(thm_eb, "thm-eb", &aon_apb.common.hw, + 0x4, 0x1000, BIT(1), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK_HW(aux0_eb, "aux0-eb", &aon_apb.common.hw, + 0x4, 0x1000, BIT(2), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK_HW(aux1_eb, "aux1-eb", &aon_apb.common.hw, + 0x4, 0x1000, BIT(3), 0, 0); +static SPRD_SC_GATE_CLK_HW(aux2_eb, "aux2-eb", &aon_apb.common.hw, + 0x4, 0x1000, BIT(4), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK_HW(probe_eb, "probe-eb", &aon_apb.common.hw, + 0x4, 0x1000, BIT(5), 0, 0); +static SPRD_SC_GATE_CLK_HW(emc_ref_eb, "emc-ref-eb", &aon_apb.common.hw, + 0x4, 0x1000, BIT(7), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK_HW(ca53_wdg_eb, "ca53-wdg-eb", &aon_apb.common.hw, + 0x4, 0x1000, BIT(8), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK_HW(ap_tmr1_eb, "ap-tmr1-eb", &aon_apb.common.hw, + 0x4, 0x1000, BIT(9), 0, 0); +static SPRD_SC_GATE_CLK_HW(ap_tmr2_eb, "ap-tmr2-eb", &aon_apb.common.hw, + 0x4, 0x1000, BIT(10), 0, 0); +static SPRD_SC_GATE_CLK_HW(disp_emc_eb, "disp-emc-eb", &aon_apb.common.hw, + 0x4, 0x1000, BIT(11), 0, 0); +static SPRD_SC_GATE_CLK_HW(zip_emc_eb, "zip-emc-eb", &aon_apb.common.hw, + 0x4, 0x1000, BIT(12), 0, 0); +static SPRD_SC_GATE_CLK_HW(gsp_emc_eb, "gsp-emc-eb", &aon_apb.common.hw, + 0x4, 0x1000, BIT(13), 0, 0); +static SPRD_SC_GATE_CLK_HW(mm_vsp_eb, "mm-vsp-eb", &aon_apb.common.hw, + 0x4, 0x1000, BIT(14), 0, 0); +static SPRD_SC_GATE_CLK_HW(mdar_eb, "mdar-eb", &aon_apb.common.hw, + 0x4, 0x1000, BIT(17), 0, 0); +static SPRD_SC_GATE_CLK_HW(rtc4m0_cal_eb, "rtc4m0-cal-eb", &aon_apb.common.hw, + 0x4, 0x1000, BIT(18), 0, 0); +static SPRD_SC_GATE_CLK_HW(rtc4m1_cal_eb, "rtc4m1-cal-eb", &aon_apb.common.hw, + 0x4, 0x1000, BIT(19), 0, 0); +static SPRD_SC_GATE_CLK_HW(djtag_eb, "djtag-eb", &aon_apb.common.hw, + 0x4, 0x1000, BIT(20), 0, 0); +static SPRD_SC_GATE_CLK_HW(mbox_eb, "mbox-eb", &aon_apb.common.hw, + 0x4, 0x1000, BIT(21), 0, 0); +static SPRD_SC_GATE_CLK_HW(aon_dma_eb, "aon-dma-eb", &aon_apb.common.hw, + 0x4, 0x1000, BIT(22), 0, 0); +static SPRD_SC_GATE_CLK_HW(aon_apb_def_eb, "aon-apb-def-eb", &aon_apb.common.hw, + 0x4, 0x1000, BIT(25), 0, 0); +static SPRD_SC_GATE_CLK_HW(ca5_ts0_eb, "ca5-ts0-eb", &aon_apb.common.hw, + 0x4, 0x1000, BIT(26), 0, 0); +static SPRD_SC_GATE_CLK_HW(dbg_eb, "dbg-eb", &aon_apb.common.hw, + 0x4, 0x1000, BIT(28), 0, 0); +static SPRD_SC_GATE_CLK_HW(dbg_emc_eb, "dbg-emc-eb", &aon_apb.common.hw, + 0x4, 0x1000, BIT(29), 0, 0); +static SPRD_SC_GATE_CLK_HW(cross_trig_eb, "cross-trig-eb", &aon_apb.common.hw, + 0x4, 0x1000, BIT(30), 0, 0); +static SPRD_SC_GATE_CLK_HW(serdes_dphy_eb, "serdes-dphy-eb", &aon_apb.common.hw, + 0x4, 0x1000, BIT(31), 0, 0); +static SPRD_SC_GATE_CLK_HW(arch_rtc_eb, "arch-rtc-eb", &aon_apb.common.hw, + 0x10, 0x1000, BIT(0), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK_HW(kpd_rtc_eb, "kpd-rtc-eb", &aon_apb.common.hw, + 0x10, 0x1000, BIT(1), 0, 0); +static SPRD_SC_GATE_CLK_HW(aon_syst_rtc_eb, "aon-syst-rtc-eb", &aon_apb.common.hw, + 0x10, 0x1000, BIT(2), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK_HW(ap_syst_rtc_eb, "ap-syst-rtc-eb", &aon_apb.common.hw, + 0x10, 0x1000, BIT(3), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK_HW(aon_tmr_rtc_eb, "aon-tmr-rtc-eb", &aon_apb.common.hw, + 0x10, 0x1000, BIT(4), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK_HW(ap_tmr0_rtc_eb, "ap-tmr0-rtc-eb", &aon_apb.common.hw, + 0x10, 0x1000, BIT(5), 0, 0); +static SPRD_SC_GATE_CLK_HW(eic_rtc_eb, "eic-rtc-eb", &aon_apb.common.hw, + 0x10, 0x1000, BIT(6), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK_HW(eic_rtcdv5_eb, "eic-rtcdv5-eb", &aon_apb.common.hw, + 0x10, 0x1000, BIT(7), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK_HW(ap_wdg_rtc_eb, "ap-wdg-rtc-eb", &aon_apb.common.hw, + 0x10, 0x1000, BIT(8), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK_HW(ca53_wdg_rtc_eb, "ca53-wdg-rtc-eb", &aon_apb.common.hw, + 0x10, 0x1000, BIT(9), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK_HW(thm_rtc_eb, "thm-rtc-eb", &aon_apb.common.hw, + 0x10, 0x1000, BIT(10), 0, 0); +static SPRD_SC_GATE_CLK_HW(athma_rtc_eb, "athma-rtc-eb", &aon_apb.common.hw, + 0x10, 0x1000, BIT(11), 0, 0); +static SPRD_SC_GATE_CLK_HW(gthma_rtc_eb, "gthma-rtc-eb", &aon_apb.common.hw, + 0x10, 0x1000, BIT(12), 0, 0); +static SPRD_SC_GATE_CLK_HW(athma_rtc_a_eb, "athma-rtc-a-eb", &aon_apb.common.hw, + 0x10, 0x1000, BIT(13), 0, 0); +static SPRD_SC_GATE_CLK_HW(gthma_rtc_a_eb, "gthma-rtc-a-eb", &aon_apb.common.hw, + 0x10, 0x1000, BIT(14), 0, 0); +static SPRD_SC_GATE_CLK_HW(ap_tmr1_rtc_eb, "ap-tmr1-rtc-eb", &aon_apb.common.hw, + 0x10, 0x1000, BIT(15), 0, 0); +static SPRD_SC_GATE_CLK_HW(ap_tmr2_rtc_eb, "ap-tmr2-rtc-eb", &aon_apb.common.hw, + 0x10, 0x1000, BIT(16), 0, 0); +static SPRD_SC_GATE_CLK_HW(dxco_lc_rtc_eb, "dxco-lc-rtc-eb", &aon_apb.common.hw, + 0x10, 0x1000, BIT(17), 0, 0); +static SPRD_SC_GATE_CLK_HW(bb_cal_rtc_eb, "bb-cal-rtc-eb", &aon_apb.common.hw, + 0x10, 0x1000, BIT(18), 0, 0); +static SPRD_SC_GATE_CLK_HW(gpu_eb, "gpu-eb", &aon_apb.common.hw, 0x50, + 0x1000, BIT(0), 0, 0); +static SPRD_SC_GATE_CLK_HW(disp_eb, "disp-eb", &aon_apb.common.hw, 0x50, + 0x1000, BIT(2), 0, 0); +static SPRD_SC_GATE_CLK_HW(mm_emc_eb, "mm-emc-eb", &aon_apb.common.hw, 0x50, + 0x1000, BIT(3), 0, 0); +static SPRD_SC_GATE_CLK_HW(power_cpu_eb, "power-cpu-eb", &aon_apb.common.hw, 0x50, + 0x1000, BIT(10), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK_HW(hw_i2c_eb, "hw-i2c-eb", &aon_apb.common.hw, 0x50, + 0x1000, BIT(11), 0, 0); +static SPRD_SC_GATE_CLK_HW(mm_vsp_emc_eb, "mm-vsp-emc-eb", &aon_apb.common.hw, 0x50, + 0x1000, BIT(14), 0, 0); +static SPRD_SC_GATE_CLK_HW(vsp_eb, "vsp-eb", &aon_apb.common.hw, 0x50, + 0x1000, BIT(16), 0, 0); +static SPRD_SC_GATE_CLK_HW(cssys_eb, "cssys-eb", &aon_apb.common.hw, 0xb0, + 0x1000, BIT(4), 0, 0); +static SPRD_SC_GATE_CLK_HW(dmc_eb, "dmc-eb", &aon_apb.common.hw, 0xb0, + 0x1000, BIT(5), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK_HW(rosc_eb, "rosc-eb", &aon_apb.common.hw, 0xb0, + 0x1000, BIT(7), 0, 0); +static SPRD_SC_GATE_CLK_HW(s_d_cfg_eb, "s-d-cfg-eb", &aon_apb.common.hw, 0xb0, + 0x1000, BIT(8), 0, 0); +static SPRD_SC_GATE_CLK_HW(s_d_ref_eb, "s-d-ref-eb", &aon_apb.common.hw, 0xb0, + 0x1000, BIT(9), 0, 0); +static SPRD_SC_GATE_CLK_HW(b_dma_eb, "b-dma-eb", &aon_apb.common.hw, 0xb0, + 0x1000, BIT(10), 0, 0); +static SPRD_SC_GATE_CLK_HW(anlg_eb, "anlg-eb", &aon_apb.common.hw, 0xb0, + 0x1000, BIT(11), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK_HW(anlg_apb_eb, "anlg-apb-eb", &aon_apb.common.hw, 0xb0, + 0x1000, BIT(13), 0, 0); +static SPRD_SC_GATE_CLK_HW(bsmtmr_eb, "bsmtmr-eb", &aon_apb.common.hw, 0xb0, + 0x1000, BIT(14), 0, 0); +static SPRD_SC_GATE_CLK_HW(ap_axi_eb, "ap-axi-eb", &aon_apb.common.hw, 0xb0, + 0x1000, BIT(15), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK_HW(ap_intc0_eb, "ap-intc0-eb", &aon_apb.common.hw, 0xb0, + 0x1000, BIT(16), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK_HW(ap_intc1_eb, "ap-intc1-eb", &aon_apb.common.hw, 0xb0, + 0x1000, BIT(17), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK_HW(ap_intc2_eb, "ap-intc2-eb", &aon_apb.common.hw, 0xb0, + 0x1000, BIT(18), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK_HW(ap_intc3_eb, "ap-intc3-eb", &aon_apb.common.hw, 0xb0, + 0x1000, BIT(19), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK_HW(ap_intc4_eb, "ap-intc4-eb", &aon_apb.common.hw, 0xb0, + 0x1000, BIT(20), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK_HW(ap_intc5_eb, "ap-intc5-eb", &aon_apb.common.hw, 0xb0, + 0x1000, BIT(21), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK_HW(scc_eb, "scc-eb", &aon_apb.common.hw, 0xb0, + 0x1000, BIT(22), 0, 0); +static SPRD_SC_GATE_CLK_HW(dphy_cfg_eb, "dphy-cfg-eb", &aon_apb.common.hw, 0xb0, + 0x1000, BIT(23), 0, 0); +static SPRD_SC_GATE_CLK_HW(dphy_ref_eb, "dphy-ref-eb", &aon_apb.common.hw, 0xb0, + 0x1000, BIT(24), 0, 0); +static SPRD_SC_GATE_CLK_HW(cphy_cfg_eb, "cphy-cfg-eb", &aon_apb.common.hw, 0xb0, + 0x1000, BIT(25), 0, 0); +static SPRD_SC_GATE_CLK_HW(otg_ref_eb, "otg-ref-eb", &aon_apb.common.hw, 0xb0, + 0x1000, BIT(26), 0, 0); +static SPRD_SC_GATE_CLK_HW(serdes_eb, "serdes-eb", &aon_apb.common.hw, 0xb0, + 0x1000, BIT(27), 0, 0); +static SPRD_SC_GATE_CLK_HW(aon_ap_emc_eb, "aon-ap-emc-eb", &aon_apb.common.hw, 0xb0, + 0x1000, BIT(28), 0, 0); +static struct sprd_clk_common *sc9863a_aonapb_gate_clks[] = { + /* address base is 0x402e0000 */ + &gpio_eb.common, + &pwm0_eb.common, + &pwm1_eb.common, + &pwm2_eb.common, + &pwm3_eb.common, + &kpd_eb.common, + &aon_syst_eb.common, + &ap_syst_eb.common, + &aon_tmr_eb.common, + &efuse_eb.common, + &eic_eb.common, + &intc_eb.common, + &adi_eb.common, + &audif_eb.common, + &aud_eb.common, + &vbc_eb.common, + &pin_eb.common, + &ap_wdg_eb.common, + &mm_eb.common, + &aon_apb_ckg_eb.common, + &ca53_ts0_eb.common, + &ca53_ts1_eb.common, + &ca53_dap_eb.common, + &pmu_eb.common, + &thm_eb.common, + &aux0_eb.common, + &aux1_eb.common, + &aux2_eb.common, + &probe_eb.common, + &emc_ref_eb.common, + &ca53_wdg_eb.common, + &ap_tmr1_eb.common, + &ap_tmr2_eb.common, + &disp_emc_eb.common, + &zip_emc_eb.common, + &gsp_emc_eb.common, + &mm_vsp_eb.common, + &mdar_eb.common, + &rtc4m0_cal_eb.common, + &rtc4m1_cal_eb.common, + &djtag_eb.common, + &mbox_eb.common, + &aon_dma_eb.common, + &aon_apb_def_eb.common, + &ca5_ts0_eb.common, + &dbg_eb.common, + &dbg_emc_eb.common, + &cross_trig_eb.common, + &serdes_dphy_eb.common, + &arch_rtc_eb.common, + &kpd_rtc_eb.common, + &aon_syst_rtc_eb.common, + &ap_syst_rtc_eb.common, + &aon_tmr_rtc_eb.common, + &ap_tmr0_rtc_eb.common, + &eic_rtc_eb.common, + &eic_rtcdv5_eb.common, + &ap_wdg_rtc_eb.common, + &ca53_wdg_rtc_eb.common, + &thm_rtc_eb.common, + &athma_rtc_eb.common, + >hma_rtc_eb.common, + &athma_rtc_a_eb.common, + >hma_rtc_a_eb.common, + &ap_tmr1_rtc_eb.common, + &ap_tmr2_rtc_eb.common, + &dxco_lc_rtc_eb.common, + &bb_cal_rtc_eb.common, + &gpu_eb.common, + &disp_eb.common, + &mm_emc_eb.common, + &power_cpu_eb.common, + &hw_i2c_eb.common, + &mm_vsp_emc_eb.common, + &vsp_eb.common, + &cssys_eb.common, + &dmc_eb.common, + &rosc_eb.common, + &s_d_cfg_eb.common, + &s_d_ref_eb.common, + &b_dma_eb.common, + &anlg_eb.common, + &anlg_apb_eb.common, + &bsmtmr_eb.common, + &ap_axi_eb.common, + &ap_intc0_eb.common, + &ap_intc1_eb.common, + &ap_intc2_eb.common, + &ap_intc3_eb.common, + &ap_intc4_eb.common, + &ap_intc5_eb.common, + &scc_eb.common, + &dphy_cfg_eb.common, + &dphy_ref_eb.common, + &cphy_cfg_eb.common, + &otg_ref_eb.common, + &serdes_eb.common, + &aon_ap_emc_eb.common, +}; + +static struct clk_hw_onecell_data sc9863a_aonapb_gate_hws = { + .hws = { + [CLK_GPIO_EB] = &gpio_eb.common.hw, + [CLK_PWM0_EB] = &pwm0_eb.common.hw, + [CLK_PWM1_EB] = &pwm1_eb.common.hw, + [CLK_PWM2_EB] = &pwm2_eb.common.hw, + [CLK_PWM3_EB] = &pwm3_eb.common.hw, + [CLK_KPD_EB] = &kpd_eb.common.hw, + [CLK_AON_SYST_EB] = &aon_syst_eb.common.hw, + [CLK_AP_SYST_EB] = &ap_syst_eb.common.hw, + [CLK_AON_TMR_EB] = &aon_tmr_eb.common.hw, + [CLK_EFUSE_EB] = &efuse_eb.common.hw, + [CLK_EIC_EB] = &eic_eb.common.hw, + [CLK_INTC_EB] = &intc_eb.common.hw, + [CLK_ADI_EB] = &adi_eb.common.hw, + [CLK_AUDIF_EB] = &audif_eb.common.hw, + [CLK_AUD_EB] = &aud_eb.common.hw, + [CLK_VBC_EB] = &vbc_eb.common.hw, + [CLK_PIN_EB] = &pin_eb.common.hw, + [CLK_AP_WDG_EB] = &ap_wdg_eb.common.hw, + [CLK_MM_EB] = &mm_eb.common.hw, + [CLK_AON_APB_CKG_EB] = &aon_apb_ckg_eb.common.hw, + [CLK_CA53_TS0_EB] = &ca53_ts0_eb.common.hw, + [CLK_CA53_TS1_EB] = &ca53_ts1_eb.common.hw, + [CLK_CS53_DAP_EB] = &ca53_dap_eb.common.hw, + [CLK_PMU_EB] = &pmu_eb.common.hw, + [CLK_THM_EB] = &thm_eb.common.hw, + [CLK_AUX0_EB] = &aux0_eb.common.hw, + [CLK_AUX1_EB] = &aux1_eb.common.hw, + [CLK_AUX2_EB] = &aux2_eb.common.hw, + [CLK_PROBE_EB] = &probe_eb.common.hw, + [CLK_EMC_REF_EB] = &emc_ref_eb.common.hw, + [CLK_CA53_WDG_EB] = &ca53_wdg_eb.common.hw, + [CLK_AP_TMR1_EB] = &ap_tmr1_eb.common.hw, + [CLK_AP_TMR2_EB] = &ap_tmr2_eb.common.hw, + [CLK_DISP_EMC_EB] = &disp_emc_eb.common.hw, + [CLK_ZIP_EMC_EB] = &zip_emc_eb.common.hw, + [CLK_GSP_EMC_EB] = &gsp_emc_eb.common.hw, + [CLK_MM_VSP_EB] = &mm_vsp_eb.common.hw, + [CLK_MDAR_EB] = &mdar_eb.common.hw, + [CLK_RTC4M0_CAL_EB] = &rtc4m0_cal_eb.common.hw, + [CLK_RTC4M1_CAL_EB] = &rtc4m1_cal_eb.common.hw, + [CLK_DJTAG_EB] = &djtag_eb.common.hw, + [CLK_MBOX_EB] = &mbox_eb.common.hw, + [CLK_AON_DMA_EB] = &aon_dma_eb.common.hw, + [CLK_AON_APB_DEF_EB] = &aon_apb_def_eb.common.hw, + [CLK_CA5_TS0_EB] = &ca5_ts0_eb.common.hw, + [CLK_DBG_EB] = &dbg_eb.common.hw, + [CLK_DBG_EMC_EB] = &dbg_emc_eb.common.hw, + [CLK_CROSS_TRIG_EB] = &cross_trig_eb.common.hw, + [CLK_SERDES_DPHY_EB] = &serdes_dphy_eb.common.hw, + [CLK_ARCH_RTC_EB] = &arch_rtc_eb.common.hw, + [CLK_KPD_RTC_EB] = &kpd_rtc_eb.common.hw, + [CLK_AON_SYST_RTC_EB] = &aon_syst_rtc_eb.common.hw, + [CLK_AP_SYST_RTC_EB] = &ap_syst_rtc_eb.common.hw, + [CLK_AON_TMR_RTC_EB] = &aon_tmr_rtc_eb.common.hw, + [CLK_AP_TMR0_RTC_EB] = &ap_tmr0_rtc_eb.common.hw, + [CLK_EIC_RTC_EB] = &eic_rtc_eb.common.hw, + [CLK_EIC_RTCDV5_EB] = &eic_rtcdv5_eb.common.hw, + [CLK_AP_WDG_RTC_EB] = &ap_wdg_rtc_eb.common.hw, + [CLK_CA53_WDG_RTC_EB] = &ca53_wdg_rtc_eb.common.hw, + [CLK_THM_RTC_EB] = &thm_rtc_eb.common.hw, + [CLK_ATHMA_RTC_EB] = &athma_rtc_eb.common.hw, + [CLK_GTHMA_RTC_EB] = >hma_rtc_eb.common.hw, + [CLK_ATHMA_RTC_A_EB] = &athma_rtc_a_eb.common.hw, + [CLK_GTHMA_RTC_A_EB] = >hma_rtc_a_eb.common.hw, + [CLK_AP_TMR1_RTC_EB] = &ap_tmr1_rtc_eb.common.hw, + [CLK_AP_TMR2_RTC_EB] = &ap_tmr2_rtc_eb.common.hw, + [CLK_DXCO_LC_RTC_EB] = &dxco_lc_rtc_eb.common.hw, + [CLK_BB_CAL_RTC_EB] = &bb_cal_rtc_eb.common.hw, + [CLK_GNU_EB] = &gpu_eb.common.hw, + [CLK_DISP_EB] = &disp_eb.common.hw, + [CLK_MM_EMC_EB] = &mm_emc_eb.common.hw, + [CLK_POWER_CPU_EB] = &power_cpu_eb.common.hw, + [CLK_HW_I2C_EB] = &hw_i2c_eb.common.hw, + [CLK_MM_VSP_EMC_EB] = &mm_vsp_emc_eb.common.hw, + [CLK_VSP_EB] = &vsp_eb.common.hw, + [CLK_CSSYS_EB] = &cssys_eb.common.hw, + [CLK_DMC_EB] = &dmc_eb.common.hw, + [CLK_ROSC_EB] = &rosc_eb.common.hw, + [CLK_S_D_CFG_EB] = &s_d_cfg_eb.common.hw, + [CLK_S_D_REF_EB] = &s_d_ref_eb.common.hw, + [CLK_B_DMA_EB] = &b_dma_eb.common.hw, + [CLK_ANLG_EB] = &anlg_eb.common.hw, + [CLK_ANLG_APB_EB] = &anlg_apb_eb.common.hw, + [CLK_BSMTMR_EB] = &bsmtmr_eb.common.hw, + [CLK_AP_AXI_EB] = &ap_axi_eb.common.hw, + [CLK_AP_INTC0_EB] = &ap_intc0_eb.common.hw, + [CLK_AP_INTC1_EB] = &ap_intc1_eb.common.hw, + [CLK_AP_INTC2_EB] = &ap_intc2_eb.common.hw, + [CLK_AP_INTC3_EB] = &ap_intc3_eb.common.hw, + [CLK_AP_INTC4_EB] = &ap_intc4_eb.common.hw, + [CLK_AP_INTC5_EB] = &ap_intc5_eb.common.hw, + [CLK_SCC_EB] = &scc_eb.common.hw, + [CLK_DPHY_CFG_EB] = &dphy_cfg_eb.common.hw, + [CLK_DPHY_REF_EB] = &dphy_ref_eb.common.hw, + [CLK_CPHY_CFG_EB] = &cphy_cfg_eb.common.hw, + [CLK_OTG_REF_EB] = &otg_ref_eb.common.hw, + [CLK_SERDES_EB] = &serdes_eb.common.hw, + [CLK_AON_AP_EMC_EB] = &aon_ap_emc_eb.common.hw, + }, + .num = CLK_AON_APB_GATE_NUM, +}; + +static const struct sprd_clk_desc sc9863a_aonapb_gate_desc = { + .clk_clks = sc9863a_aonapb_gate_clks, + .num_clk_clks = ARRAY_SIZE(sc9863a_aonapb_gate_clks), + .hw_clks = &sc9863a_aonapb_gate_hws, +}; + +/* mm gate clocks */ +static SPRD_SC_GATE_CLK_HW(mahb_ckg_eb, "mahb-ckg-eb", &mm_ahb.common.hw, 0x0, 0x1000, + BIT(0), 0, 0); +static SPRD_SC_GATE_CLK_HW(mdcam_eb, "mdcam-eb", &mm_ahb.common.hw, 0x0, 0x1000, + BIT(1), 0, 0); +static SPRD_SC_GATE_CLK_HW(misp_eb, "misp-eb", &mm_ahb.common.hw, 0x0, 0x1000, + BIT(2), 0, 0); +static SPRD_SC_GATE_CLK_HW(mahbcsi_eb, "mahbcsi-eb", &mm_ahb.common.hw, 0x0, 0x1000, + BIT(3), 0, 0); +static SPRD_SC_GATE_CLK_HW(mcsi_s_eb, "mcsi-s-eb", &mm_ahb.common.hw, 0x0, 0x1000, + BIT(4), 0, 0); +static SPRD_SC_GATE_CLK_HW(mcsi_t_eb, "mcsi-t-eb", &mm_ahb.common.hw, 0x0, 0x1000, + BIT(5), 0, 0); +static SPRD_GATE_CLK_HW(dcam_axi_eb, "dcam-axi-eb", &mm_ahb.common.hw, 0x8, + BIT(0), 0, 0); +static SPRD_GATE_CLK_HW(isp_axi_eb, "isp-axi-eb", &mm_ahb.common.hw, 0x8, + BIT(1), 0, 0); +static SPRD_GATE_CLK_HW(mcsi_eb, "mcsi-eb", &mm_ahb.common.hw, 0x8, + BIT(2), 0, 0); +static SPRD_GATE_CLK_HW(mcsi_s_ckg_eb, "mcsi-s-ckg-eb", &mm_ahb.common.hw, 0x8, + BIT(3), 0, 0); +static SPRD_GATE_CLK_HW(mcsi_t_ckg_eb, "mcsi-t-ckg-eb", &mm_ahb.common.hw, 0x8, + BIT(4), 0, 0); +static SPRD_GATE_CLK_HW(sensor0_eb, "sensor0-eb", &mm_ahb.common.hw, 0x8, + BIT(5), 0, 0); +static SPRD_GATE_CLK_HW(sensor1_eb, "sensor1-eb", &mm_ahb.common.hw, 0x8, + BIT(6), 0, 0); +static SPRD_GATE_CLK_HW(sensor2_eb, "sensor2-eb", &mm_ahb.common.hw, 0x8, + BIT(7), 0, 0); +static SPRD_GATE_CLK_HW(mcphy_cfg_eb, "mcphy-cfg-eb", &mm_ahb.common.hw, 0x8, + BIT(8), 0, 0); + +static struct sprd_clk_common *sc9863a_mm_gate_clks[] = { + /* address base is 0x60800000 */ + &mahb_ckg_eb.common, + &mdcam_eb.common, + &misp_eb.common, + &mahbcsi_eb.common, + &mcsi_s_eb.common, + &mcsi_t_eb.common, + &dcam_axi_eb.common, + &isp_axi_eb.common, + &mcsi_eb.common, + &mcsi_s_ckg_eb.common, + &mcsi_t_ckg_eb.common, + &sensor0_eb.common, + &sensor1_eb.common, + &sensor2_eb.common, + &mcphy_cfg_eb.common, +}; + +static struct clk_hw_onecell_data sc9863a_mm_gate_hws = { + .hws = { + [CLK_MAHB_CKG_EB] = &mahb_ckg_eb.common.hw, + [CLK_MDCAM_EB] = &mdcam_eb.common.hw, + [CLK_MISP_EB] = &misp_eb.common.hw, + [CLK_MAHBCSI_EB] = &mahbcsi_eb.common.hw, + [CLK_MCSI_S_EB] = &mcsi_s_eb.common.hw, + [CLK_MCSI_T_EB] = &mcsi_t_eb.common.hw, + [CLK_DCAM_AXI_EB] = &dcam_axi_eb.common.hw, + [CLK_ISP_AXI_EB] = &isp_axi_eb.common.hw, + [CLK_MCSI_EB] = &mcsi_eb.common.hw, + [CLK_MCSI_S_CKG_EB] = &mcsi_s_ckg_eb.common.hw, + [CLK_MCSI_T_CKG_EB] = &mcsi_t_ckg_eb.common.hw, + [CLK_SENSOR0_EB] = &sensor0_eb.common.hw, + [CLK_SENSOR1_EB] = &sensor1_eb.common.hw, + [CLK_SENSOR2_EB] = &sensor2_eb.common.hw, + [CLK_MCPHY_CFG_EB] = &mcphy_cfg_eb.common.hw, + }, + .num = CLK_MM_GATE_NUM, +}; + +static const struct sprd_clk_desc sc9863a_mm_gate_desc = { + .clk_clks = sc9863a_mm_gate_clks, + .num_clk_clks = ARRAY_SIZE(sc9863a_mm_gate_clks), + .hw_clks = &sc9863a_mm_gate_hws, +}; + +/* camera sensor clocks */ +static SPRD_GATE_CLK_HW(mipi_csi_clk, "mipi-csi-clk", &mahb_ckg_eb.common.hw, + 0x20, BIT(16), 0, SPRD_GATE_NON_AON); +static SPRD_GATE_CLK_HW(mipi_csi_s_clk, "mipi-csi-s-clk", &mahb_ckg_eb.common.hw, + 0x24, BIT(16), 0, SPRD_GATE_NON_AON); +static SPRD_GATE_CLK_HW(mipi_csi_m_clk, "mipi-csi-m-clk", &mahb_ckg_eb.common.hw, + 0x28, BIT(16), 0, SPRD_GATE_NON_AON); + +static struct sprd_clk_common *sc9863a_mm_clk_clks[] = { + /* address base is 0x60900000 */ + &mipi_csi_clk.common, + &mipi_csi_s_clk.common, + &mipi_csi_m_clk.common, +}; + +static struct clk_hw_onecell_data sc9863a_mm_clk_hws = { + .hws = { + [CLK_MIPI_CSI] = &mipi_csi_clk.common.hw, + [CLK_MIPI_CSI_S] = &mipi_csi_s_clk.common.hw, + [CLK_MIPI_CSI_M] = &mipi_csi_m_clk.common.hw, + }, + .num = CLK_MM_CLK_NUM, +}; + +static const struct sprd_clk_desc sc9863a_mm_clk_desc = { + .clk_clks = sc9863a_mm_clk_clks, + .num_clk_clks = ARRAY_SIZE(sc9863a_mm_clk_clks), + .hw_clks = &sc9863a_mm_clk_hws, +}; + +static SPRD_SC_GATE_CLK_FW_NAME(sim0_eb, "sim0-eb", "ext-26m", 0x0, + 0x1000, BIT(0), 0, 0); +static SPRD_SC_GATE_CLK_FW_NAME(iis0_eb, "iis0-eb", "ext-26m", 0x0, + 0x1000, BIT(1), 0, 0); +static SPRD_SC_GATE_CLK_FW_NAME(iis1_eb, "iis1-eb", "ext-26m", 0x0, + 0x1000, BIT(2), 0, 0); +static SPRD_SC_GATE_CLK_FW_NAME(iis2_eb, "iis2-eb", "ext-26m", 0x0, + 0x1000, BIT(3), 0, 0); +static SPRD_SC_GATE_CLK_FW_NAME(spi0_eb, "spi0-eb", "ext-26m", 0x0, + 0x1000, BIT(5), 0, 0); +static SPRD_SC_GATE_CLK_FW_NAME(spi1_eb, "spi1-eb", "ext-26m", 0x0, + 0x1000, BIT(6), 0, 0); +static SPRD_SC_GATE_CLK_FW_NAME(spi2_eb, "spi2-eb", "ext-26m", 0x0, + 0x1000, BIT(7), 0, 0); +static SPRD_SC_GATE_CLK_FW_NAME(i2c0_eb, "i2c0-eb", "ext-26m", 0x0, + 0x1000, BIT(8), 0, 0); +static SPRD_SC_GATE_CLK_FW_NAME(i2c1_eb, "i2c1-eb", "ext-26m", 0x0, + 0x1000, BIT(9), 0, 0); +static SPRD_SC_GATE_CLK_FW_NAME(i2c2_eb, "i2c2-eb", "ext-26m", 0x0, + 0x1000, BIT(10), 0, 0); +static SPRD_SC_GATE_CLK_FW_NAME(i2c3_eb, "i2c3-eb", "ext-26m", 0x0, + 0x1000, BIT(11), 0, 0); +static SPRD_SC_GATE_CLK_FW_NAME(i2c4_eb, "i2c4-eb", "ext-26m", 0x0, + 0x1000, BIT(12), 0, 0); +static SPRD_SC_GATE_CLK_FW_NAME(uart0_eb, "uart0-eb", "ext-26m", 0x0, + 0x1000, BIT(13), 0, 0); +/* uart1_eb is for console, don't gate even if unused */ +static SPRD_SC_GATE_CLK_FW_NAME(uart1_eb, "uart1-eb", "ext-26m", 0x0, + 0x1000, BIT(14), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK_FW_NAME(uart2_eb, "uart2-eb", "ext-26m", 0x0, + 0x1000, BIT(15), 0, 0); +static SPRD_SC_GATE_CLK_FW_NAME(uart3_eb, "uart3-eb", "ext-26m", 0x0, + 0x1000, BIT(16), 0, 0); +static SPRD_SC_GATE_CLK_FW_NAME(uart4_eb, "uart4-eb", "ext-26m", 0x0, + 0x1000, BIT(17), 0, 0); +static SPRD_SC_GATE_CLK_FW_NAME(sim0_32k_eb, "sim0_32k-eb", "ext-26m", 0x0, + 0x1000, BIT(18), 0, 0); +static SPRD_SC_GATE_CLK_FW_NAME(spi3_eb, "spi3-eb", "ext-26m", 0x0, + 0x1000, BIT(19), 0, 0); +static SPRD_SC_GATE_CLK_FW_NAME(i2c5_eb, "i2c5-eb", "ext-26m", 0x0, + 0x1000, BIT(20), 0, 0); +static SPRD_SC_GATE_CLK_FW_NAME(i2c6_eb, "i2c6-eb", "ext-26m", 0x0, + 0x1000, BIT(21), 0, 0); + +static struct sprd_clk_common *sc9863a_apapb_gate[] = { + /* address base is 0x71300000 */ + &sim0_eb.common, + &iis0_eb.common, + &iis1_eb.common, + &iis2_eb.common, + &spi0_eb.common, + &spi1_eb.common, + &spi2_eb.common, + &i2c0_eb.common, + &i2c1_eb.common, + &i2c2_eb.common, + &i2c3_eb.common, + &i2c4_eb.common, + &uart0_eb.common, + &uart1_eb.common, + &uart2_eb.common, + &uart3_eb.common, + &uart4_eb.common, + &sim0_32k_eb.common, + &spi3_eb.common, + &i2c5_eb.common, + &i2c6_eb.common, +}; + +static struct clk_hw_onecell_data sc9863a_apapb_gate_hws = { + .hws = { + [CLK_SIM0_EB] = &sim0_eb.common.hw, + [CLK_IIS0_EB] = &iis0_eb.common.hw, + [CLK_IIS1_EB] = &iis1_eb.common.hw, + [CLK_IIS2_EB] = &iis2_eb.common.hw, + [CLK_SPI0_EB] = &spi0_eb.common.hw, + [CLK_SPI1_EB] = &spi1_eb.common.hw, + [CLK_SPI2_EB] = &spi2_eb.common.hw, + [CLK_I2C0_EB] = &i2c0_eb.common.hw, + [CLK_I2C1_EB] = &i2c1_eb.common.hw, + [CLK_I2C2_EB] = &i2c2_eb.common.hw, + [CLK_I2C3_EB] = &i2c3_eb.common.hw, + [CLK_I2C4_EB] = &i2c4_eb.common.hw, + [CLK_UART0_EB] = &uart0_eb.common.hw, + [CLK_UART1_EB] = &uart1_eb.common.hw, + [CLK_UART2_EB] = &uart2_eb.common.hw, + [CLK_UART3_EB] = &uart3_eb.common.hw, + [CLK_UART4_EB] = &uart4_eb.common.hw, + [CLK_SIM0_32K_EB] = &sim0_32k_eb.common.hw, + [CLK_SPI3_EB] = &spi3_eb.common.hw, + [CLK_I2C5_EB] = &i2c5_eb.common.hw, + [CLK_I2C6_EB] = &i2c6_eb.common.hw, + }, + .num = CLK_AP_APB_GATE_NUM, +}; + +static const struct sprd_clk_desc sc9863a_apapb_gate_desc = { + .clk_clks = sc9863a_apapb_gate, + .num_clk_clks = ARRAY_SIZE(sc9863a_apapb_gate), + .hw_clks = &sc9863a_apapb_gate_hws, +}; + +static const struct of_device_id sprd_sc9863a_clk_ids[] = { + { .compatible = "sprd,sc9863a-ap-clk", /* 0x21500000 */ + .data = &sc9863a_ap_clk_desc }, + { .compatible = "sprd,sc9863a-pmu-gate", /* 0x402b0000 */ + .data = &sc9863a_pmu_gate_desc }, + { .compatible = "sprd,sc9863a-pll", /* 0x40353000 */ + .data = &sc9863a_pll_desc }, + { .compatible = "sprd,sc9863a-mpll", /* 0x40359000 */ + .data = &sc9863a_mpll_desc }, + { .compatible = "sprd,sc9863a-rpll", /* 0x4035c000 */ + .data = &sc9863a_rpll_desc }, + { .compatible = "sprd,sc9863a-dpll", /* 0x40363000 */ + .data = &sc9863a_dpll_desc }, + { .compatible = "sprd,sc9863a-aon-clk", /* 0x402d0000 */ + .data = &sc9863a_aon_clk_desc }, + { .compatible = "sprd,sc9863a-apahb-gate", /* 0x20e00000 */ + .data = &sc9863a_apahb_gate_desc }, + { .compatible = "sprd,sc9863a-aonapb-gate", /* 0x402e0000 */ + .data = &sc9863a_aonapb_gate_desc }, + { .compatible = "sprd,sc9863a-mm-gate", /* 0x60800000 */ + .data = &sc9863a_mm_gate_desc }, + { .compatible = "sprd,sc9863a-mm-clk", /* 0x60900000 */ + .data = &sc9863a_mm_clk_desc }, + { .compatible = "sprd,sc9863a-apapb-gate", /* 0x71300000 */ + .data = &sc9863a_apapb_gate_desc }, + { } +}; +MODULE_DEVICE_TABLE(of, sprd_sc9863a_clk_ids); + +static int sc9863a_clk_probe(struct platform_device *pdev) +{ + const struct sprd_clk_desc *desc; + int ret; + + desc = device_get_match_data(&pdev->dev); + if (!desc) + return -ENODEV; + + ret = sprd_clk_regmap_init(pdev, desc); + if (ret) + return ret; + + return sprd_clk_probe(&pdev->dev, desc->hw_clks); +} + +static struct platform_driver sc9863a_clk_driver = { + .probe = sc9863a_clk_probe, + .driver = { + .name = "sc9863a-clk", + .of_match_table = sprd_sc9863a_clk_ids, + }, +}; +module_platform_driver(sc9863a_clk_driver); + +MODULE_DESCRIPTION("Spreadtrum SC9863A Clock Driver"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/clk/sprd/ums512-clk.c b/drivers/clk/sprd/ums512-clk.c new file mode 100644 index 000000000..fc17b74b8 --- /dev/null +++ b/drivers/clk/sprd/ums512-clk.c @@ -0,0 +1,2201 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Unisoc UMS512 clock driver + * + * Copyright (C) 2022 Unisoc, Inc. + * Author: Xiaolong Zhang <xiaolong.zhang@unisoc.com> + */ + +#include <linux/clk-provider.h> +#include <linux/err.h> +#include <linux/io.h> +#include <linux/module.h> +#include <linux/platform_device.h> +#include <linux/slab.h> + +#include <dt-bindings/clock/sprd,ums512-clk.h> + +#include "common.h" +#include "composite.h" +#include "div.h" +#include "gate.h" +#include "mux.h" +#include "pll.h" + +#define UMS512_MUX_FLAG \ + (CLK_GET_RATE_NOCACHE | CLK_SET_RATE_NO_REPARENT) + +/* pll gate clock */ +/* some pll clocks configure CLK_IGNORE_UNUSED because hw dvfs does not call + * clock interface. hw dvfs can not gate the pll clock. + */ +static CLK_FIXED_FACTOR_FW_NAME(clk_26m_aud, "clk-26m-aud", "ext-26m", 1, 1, 0); +static CLK_FIXED_FACTOR_FW_NAME(clk_13m, "clk-13m", "ext-26m", 2, 1, 0); +static CLK_FIXED_FACTOR_FW_NAME(clk_6m5, "clk-6m5", "ext-26m", 4, 1, 0); +static CLK_FIXED_FACTOR_FW_NAME(clk_4m3, "clk-4m3", "ext-26m", 6, 1, 0); +static CLK_FIXED_FACTOR_FW_NAME(clk_2m, "clk-2m", "ext-26m", 13, 1, 0); +static CLK_FIXED_FACTOR_FW_NAME(clk_1m, "clk-1m", "ext-26m", 26, 1, 0); +static CLK_FIXED_FACTOR_FW_NAME(clk_250k, "clk-250k", "ext-26m", 104, 1, 0); +static CLK_FIXED_FACTOR_FW_NAME(rco_25m, "rco-25m", "rco-100m", 4, 1, 0); +static CLK_FIXED_FACTOR_FW_NAME(rco_4m, "rco-4m", "rco-100m", 25, 1, 0); +static CLK_FIXED_FACTOR_FW_NAME(rco_2m, "rco-2m", "rco-100m", 50, 1, 0); +static SPRD_PLL_SC_GATE_CLK_FW_NAME(isppll_gate, "isppll-gate", "ext-26m", 0x8c, + 0x1000, BIT(0), CLK_IGNORE_UNUSED, 0, 240); +static SPRD_PLL_SC_GATE_CLK_FW_NAME(dpll0_gate, "dpll0-gate", "ext-26m", 0x98, + 0x1000, BIT(0), 0, 0, 240); +static SPRD_PLL_SC_GATE_CLK_FW_NAME(dpll1_gate, "dpll1-gate", "ext-26m", 0x9c, + 0x1000, BIT(0), 0, 0, 240); +static SPRD_PLL_SC_GATE_CLK_FW_NAME(lpll_gate, "lpll-gate", "ext-26m", 0xa0, + 0x1000, BIT(0), CLK_IGNORE_UNUSED, 0, 240); +static SPRD_PLL_SC_GATE_CLK_FW_NAME(twpll_gate, "twpll-gate", "ext-26m", 0xa4, + 0x1000, BIT(0), CLK_IGNORE_UNUSED, 0, 240); +static SPRD_PLL_SC_GATE_CLK_FW_NAME(gpll_gate, "gpll-gate", "ext-26m", 0xa8, + 0x1000, BIT(0), CLK_IGNORE_UNUSED, 0, 240); +static SPRD_PLL_SC_GATE_CLK_FW_NAME(rpll_gate, "rpll-gate", "ext-26m", 0xac, + 0x1000, BIT(0), CLK_IGNORE_UNUSED, 0, 240); +static SPRD_PLL_SC_GATE_CLK_FW_NAME(cppll_gate, "cppll-gate", "ext-26m", 0xe4, + 0x1000, BIT(0), CLK_IGNORE_UNUSED, 0, 240); +static SPRD_PLL_SC_GATE_CLK_FW_NAME(mpll0_gate, "mpll0-gate", "ext-26m", 0x190, + 0x1000, BIT(0), CLK_IGNORE_UNUSED, 0, 240); +static SPRD_PLL_SC_GATE_CLK_FW_NAME(mpll1_gate, "mpll1-gate", "ext-26m", 0x194, + 0x1000, BIT(0), CLK_IGNORE_UNUSED, 0, 240); +static SPRD_PLL_SC_GATE_CLK_FW_NAME(mpll2_gate, "mpll2-gate", "ext-26m", 0x198, + 0x1000, BIT(0), CLK_IGNORE_UNUSED, 0, 240); + +static struct sprd_clk_common *ums512_pmu_gate_clks[] = { + /* address base is 0x327e0000 */ + &isppll_gate.common, + &dpll0_gate.common, + &dpll1_gate.common, + &lpll_gate.common, + &twpll_gate.common, + &gpll_gate.common, + &rpll_gate.common, + &cppll_gate.common, + &mpll0_gate.common, + &mpll1_gate.common, + &mpll2_gate.common, +}; + +static struct clk_hw_onecell_data ums512_pmu_gate_hws = { + .hws = { + [CLK_26M_AUD] = &clk_26m_aud.hw, + [CLK_13M] = &clk_13m.hw, + [CLK_6M5] = &clk_6m5.hw, + [CLK_4M3] = &clk_4m3.hw, + [CLK_2M] = &clk_2m.hw, + [CLK_1M] = &clk_1m.hw, + [CLK_250K] = &clk_250k.hw, + [CLK_RCO_25M] = &rco_25m.hw, + [CLK_RCO_4M] = &rco_4m.hw, + [CLK_RCO_2M] = &rco_2m.hw, + [CLK_ISPPLL_GATE] = &isppll_gate.common.hw, + [CLK_DPLL0_GATE] = &dpll0_gate.common.hw, + [CLK_DPLL1_GATE] = &dpll1_gate.common.hw, + [CLK_LPLL_GATE] = &lpll_gate.common.hw, + [CLK_TWPLL_GATE] = &twpll_gate.common.hw, + [CLK_GPLL_GATE] = &gpll_gate.common.hw, + [CLK_RPLL_GATE] = &rpll_gate.common.hw, + [CLK_CPPLL_GATE] = &cppll_gate.common.hw, + [CLK_MPLL0_GATE] = &mpll0_gate.common.hw, + [CLK_MPLL1_GATE] = &mpll1_gate.common.hw, + [CLK_MPLL2_GATE] = &mpll2_gate.common.hw, + }, + .num = CLK_PMU_GATE_NUM, +}; + +static struct sprd_clk_desc ums512_pmu_gate_desc = { + .clk_clks = ums512_pmu_gate_clks, + .num_clk_clks = ARRAY_SIZE(ums512_pmu_gate_clks), + .hw_clks = &ums512_pmu_gate_hws, +}; + +/* pll clock at g0 */ +static const u64 itable_dpll0[7] = { 6, 0, 0, + 1173000000ULL, 1475000000ULL, + 1855000000ULL, 1866000000ULL }; + +static struct clk_bit_field f_dpll0[PLL_FACT_MAX] = { + { .shift = 18, .width = 1 }, /* lock_done */ + { .shift = 0, .width = 1 }, /* div_s */ + { .shift = 67, .width = 1 }, /* mod_en */ + { .shift = 1, .width = 1 }, /* sdm_en */ + { .shift = 0, .width = 0 }, /* refin */ + { .shift = 4, .width = 3 }, /* icp */ + { .shift = 7, .width = 11 }, /* n */ + { .shift = 55, .width = 7 }, /* nint */ + { .shift = 32, .width = 23}, /* kint */ + { .shift = 0, .width = 0 }, /* prediv */ + { .shift = 0, .width = 0 }, /* postdiv */ +}; +static SPRD_PLL_HW(dpll0, "dpll0", &dpll0_gate.common.hw, 0x4, 3, + itable_dpll0, f_dpll0, 240, 1000, 1000, 0, 0); +static CLK_FIXED_FACTOR_HW(dpll0_58m31, "dpll0-58m31", &dpll0.common.hw, + 32, 1, 0); + +static struct sprd_clk_common *ums512_g0_pll_clks[] = { + /* address base is 0x32390000 */ + &dpll0.common, +}; + +static struct clk_hw_onecell_data ums512_g0_pll_hws = { + .hws = { + [CLK_DPLL0] = &dpll0.common.hw, + [CLK_DPLL0_58M31] = &dpll0_58m31.hw, + }, + .num = CLK_ANLG_PHY_G0_NUM, +}; + +static struct sprd_clk_desc ums512_g0_pll_desc = { + .clk_clks = ums512_g0_pll_clks, + .num_clk_clks = ARRAY_SIZE(ums512_g0_pll_clks), + .hw_clks = &ums512_g0_pll_hws, +}; + +/* pll clock at g2 */ +static const u64 itable_mpll[8] = { 7, 0, + 1400000000ULL, 1600000000ULL, + 1800000000ULL, 2000000000ULL, + 2200000000ULL, 2500000000ULL }; + +static struct clk_bit_field f_mpll[PLL_FACT_MAX] = { + { .shift = 17, .width = 1 }, /* lock_done */ + { .shift = 0, .width = 1 }, /* div_s */ + { .shift = 67, .width = 1 }, /* mod_en */ + { .shift = 1, .width = 1 }, /* sdm_en */ + { .shift = 0, .width = 0 }, /* refin */ + { .shift = 2, .width = 3 }, /* icp */ + { .shift = 5, .width = 11 }, /* n */ + { .shift = 55, .width = 7 }, /* nint */ + { .shift = 32, .width = 23}, /* kint */ + { .shift = 0, .width = 0 }, /* prediv */ + { .shift = 77, .width = 1 }, /* postdiv */ +}; +static SPRD_PLL_HW(mpll1, "mpll1", &mpll1_gate.common.hw, 0x0, 3, + itable_mpll, f_mpll, 240, 1000, 1000, 1, 1200000000); +static CLK_FIXED_FACTOR_HW(mpll1_63m38, "mpll1-63m38", &mpll1.common.hw, + 32, 1, 0); + +static struct sprd_clk_common *ums512_g2_pll_clks[] = { + /* address base is 0x323B0000 */ + &mpll1.common, +}; + +static struct clk_hw_onecell_data ums512_g2_pll_hws = { + .hws = { + [CLK_MPLL1] = &mpll1.common.hw, + [CLK_MPLL1_63M38] = &mpll1_63m38.hw, + }, + .num = CLK_ANLG_PHY_G2_NUM, +}; + +static struct sprd_clk_desc ums512_g2_pll_desc = { + .clk_clks = ums512_g2_pll_clks, + .num_clk_clks = ARRAY_SIZE(ums512_g2_pll_clks), + .hw_clks = &ums512_g2_pll_hws, +}; + +/* pll at g3 */ +static const u64 itable[8] = { 7, 0, 0, + 900000000ULL, 1100000000ULL, + 1300000000ULL, 1500000000ULL, + 1600000000ULL }; + +static struct clk_bit_field f_pll[PLL_FACT_MAX] = { + { .shift = 18, .width = 1 }, /* lock_done */ + { .shift = 0, .width = 1 }, /* div_s */ + { .shift = 67, .width = 1 }, /* mod_en */ + { .shift = 1, .width = 1 }, /* sdm_en */ + { .shift = 0, .width = 0 }, /* refin */ + { .shift = 2, .width = 3 }, /* icp */ + { .shift = 5, .width = 11 }, /* n */ + { .shift = 55, .width = 7 }, /* nint */ + { .shift = 32, .width = 23}, /* kint */ + { .shift = 0, .width = 0 }, /* prediv */ + { .shift = 77, .width = 1 }, /* postdiv */ +}; + +static SPRD_PLL_FW_NAME(rpll, "rpll", "ext-26m", 0x0, 3, + itable, f_pll, 240, 1000, 1000, 1, 750000000); + +static SPRD_SC_GATE_CLK_FW_NAME(audio_gate, "audio-gate", "ext-26m", 0x24, + 0x1000, BIT(1), CLK_IGNORE_UNUSED, 0); + +static struct clk_bit_field f_mpll2[PLL_FACT_MAX] = { + { .shift = 16, .width = 1 }, /* lock_done */ + { .shift = 0, .width = 1 }, /* div_s */ + { .shift = 67, .width = 1 }, /* mod_en */ + { .shift = 1, .width = 1 }, /* sdm_en */ + { .shift = 0, .width = 0 }, /* refin */ + { .shift = 2, .width = 3 }, /* icp */ + { .shift = 5, .width = 11 }, /* n */ + { .shift = 55, .width = 7 }, /* nint */ + { .shift = 32, .width = 23}, /* kint */ + { .shift = 0, .width = 0 }, /* prediv */ + { .shift = 77, .width = 1 }, /* postdiv */ +}; +static SPRD_PLL_HW(mpll0, "mpll0", &mpll0_gate.common.hw, 0x54, 3, + itable_mpll, f_mpll, 240, 1000, 1000, 1, 1200000000); +static CLK_FIXED_FACTOR_HW(mpll0_56m88, "mpll0-56m88", &mpll0.common.hw, + 32, 1, 0); + +static const u64 itable_mpll2[6] = { 5, + 1200000000ULL, 1400000000ULL, + 1600000000ULL, 1800000000ULL, + 2000000000ULL }; + +static SPRD_PLL_HW(mpll2, "mpll2", &mpll2_gate.common.hw, 0x9c, 3, + itable_mpll2, f_mpll2, 240, 1000, 1000, 1, 1000000000); +static CLK_FIXED_FACTOR_HW(mpll2_47m13, "mpll2-47m13", &mpll2.common.hw, + 32, 1, 0); + +static struct sprd_clk_common *ums512_g3_pll_clks[] = { + /* address base is 0x323c0000 */ + &rpll.common, + &audio_gate.common, + &mpll0.common, + &mpll2.common, +}; + +static struct clk_hw_onecell_data ums512_g3_pll_hws = { + .hws = { + [CLK_RPLL] = &rpll.common.hw, + [CLK_AUDIO_GATE] = &audio_gate.common.hw, + [CLK_MPLL0] = &mpll0.common.hw, + [CLK_MPLL0_56M88] = &mpll0_56m88.hw, + [CLK_MPLL2] = &mpll2.common.hw, + [CLK_MPLL2_47M13] = &mpll2_47m13.hw, + }, + .num = CLK_ANLG_PHY_G3_NUM, +}; + +static struct sprd_clk_desc ums512_g3_pll_desc = { + .clk_clks = ums512_g3_pll_clks, + .num_clk_clks = ARRAY_SIZE(ums512_g3_pll_clks), + .hw_clks = &ums512_g3_pll_hws, +}; + +/* pll clock at gc */ +static SPRD_PLL_FW_NAME(twpll, "twpll", "ext-26m", 0x0, 3, + itable, f_pll, 240, 1000, 1000, 1, 750000000); +static CLK_FIXED_FACTOR_HW(twpll_768m, "twpll-768m", &twpll.common.hw, + 2, 1, 0); +static CLK_FIXED_FACTOR_HW(twpll_384m, "twpll-384m", &twpll.common.hw, + 4, 1, 0); +static CLK_FIXED_FACTOR_HW(twpll_192m, "twpll-192m", &twpll.common.hw, + 8, 1, 0); +static CLK_FIXED_FACTOR_HW(twpll_96m, "twpll-96m", &twpll.common.hw, + 16, 1, 0); +static CLK_FIXED_FACTOR_HW(twpll_48m, "twpll-48m", &twpll.common.hw, + 32, 1, 0); +static CLK_FIXED_FACTOR_HW(twpll_24m, "twpll-24m", &twpll.common.hw, + 64, 1, 0); +static CLK_FIXED_FACTOR_HW(twpll_12m, "twpll-12m", &twpll.common.hw, + 128, 1, 0); +static CLK_FIXED_FACTOR_HW(twpll_512m, "twpll-512m", &twpll.common.hw, + 3, 1, 0); +static CLK_FIXED_FACTOR_HW(twpll_256m, "twpll-256m", &twpll.common.hw, + 6, 1, 0); +static CLK_FIXED_FACTOR_HW(twpll_128m, "twpll-128m", &twpll.common.hw, + 12, 1, 0); +static CLK_FIXED_FACTOR_HW(twpll_64m, "twpll-64m", &twpll.common.hw, + 24, 1, 0); +static CLK_FIXED_FACTOR_HW(twpll_307m2, "twpll-307m2", &twpll.common.hw, + 5, 1, 0); +static CLK_FIXED_FACTOR_HW(twpll_219m4, "twpll-219m4", &twpll.common.hw, + 7, 1, 0); +static CLK_FIXED_FACTOR_HW(twpll_170m6, "twpll-170m6", &twpll.common.hw, + 9, 1, 0); +static CLK_FIXED_FACTOR_HW(twpll_153m6, "twpll-153m6", &twpll.common.hw, + 10, 1, 0); +static CLK_FIXED_FACTOR_HW(twpll_76m8, "twpll-76m8", &twpll.common.hw, + 20, 1, 0); +static CLK_FIXED_FACTOR_HW(twpll_51m2, "twpll-51m2", &twpll.common.hw, + 30, 1, 0); +static CLK_FIXED_FACTOR_HW(twpll_38m4, "twpll-38m4", &twpll.common.hw, + 40, 1, 0); +static CLK_FIXED_FACTOR_HW(twpll_19m2, "twpll-19m2", &twpll.common.hw, + 80, 1, 0); +static CLK_FIXED_FACTOR_HW(twpll_12m29, "twpll-12m29", &twpll.common.hw, + 125, 1, 0); + +static SPRD_PLL_FW_NAME(lpll, "lpll", "ext-26m", 0x18, 3, + itable, f_pll, 240, 1000, 1000, 1, 750000000); +static CLK_FIXED_FACTOR_HW(lpll_614m4, "lpll-614m4", &lpll.common.hw, + 2, 1, 0); +static CLK_FIXED_FACTOR_HW(lpll_409m6, "lpll-409m6", &lpll.common.hw, + 3, 1, 0); +static CLK_FIXED_FACTOR_HW(lpll_245m76, "lpll-245m76", &lpll.common.hw, + 5, 1, 0); +static CLK_FIXED_FACTOR_HW(lpll_30m72, "lpll-30m72", &lpll.common.hw, + 40, 1, 0); + +static SPRD_PLL_FW_NAME(isppll, "isppll", "ext-26m", 0x30, 3, + itable, f_pll, 240, 1000, 1000, 1, 750000000); +static CLK_FIXED_FACTOR_HW(isppll_468m, "isppll-468m", &isppll.common.hw, + 2, 1, 0); +static CLK_FIXED_FACTOR_HW(isppll_78m, "isppll-78m", &isppll.common.hw, + 12, 1, 0); + +static SPRD_PLL_HW(gpll, "gpll", &gpll_gate.common.hw, 0x48, 3, + itable, f_pll, 240, 1000, 1000, 1, 750000000); +static CLK_FIXED_FACTOR_HW(gpll_40m, "gpll-40m", &gpll.common.hw, + 20, 1, 0); + +static SPRD_PLL_HW(cppll, "cppll", &cppll_gate.common.hw, 0x60, 3, + itable, f_pll, 240, 1000, 1000, 1, 750000000); +static CLK_FIXED_FACTOR_HW(cppll_39m32, "cppll-39m32", &cppll.common.hw, + 26, 1, 0); + +static struct sprd_clk_common *ums512_gc_pll_clks[] = { + /* address base is 0x323e0000 */ + &twpll.common, + &lpll.common, + &isppll.common, + &gpll.common, + &cppll.common, +}; + +static struct clk_hw_onecell_data ums512_gc_pll_hws = { + .hws = { + [CLK_TWPLL] = &twpll.common.hw, + [CLK_TWPLL_768M] = &twpll_768m.hw, + [CLK_TWPLL_384M] = &twpll_384m.hw, + [CLK_TWPLL_192M] = &twpll_192m.hw, + [CLK_TWPLL_96M] = &twpll_96m.hw, + [CLK_TWPLL_48M] = &twpll_48m.hw, + [CLK_TWPLL_24M] = &twpll_24m.hw, + [CLK_TWPLL_12M] = &twpll_12m.hw, + [CLK_TWPLL_512M] = &twpll_512m.hw, + [CLK_TWPLL_256M] = &twpll_256m.hw, + [CLK_TWPLL_128M] = &twpll_128m.hw, + [CLK_TWPLL_64M] = &twpll_64m.hw, + [CLK_TWPLL_307M2] = &twpll_307m2.hw, + [CLK_TWPLL_219M4] = &twpll_219m4.hw, + [CLK_TWPLL_170M6] = &twpll_170m6.hw, + [CLK_TWPLL_153M6] = &twpll_153m6.hw, + [CLK_TWPLL_76M8] = &twpll_76m8.hw, + [CLK_TWPLL_51M2] = &twpll_51m2.hw, + [CLK_TWPLL_38M4] = &twpll_38m4.hw, + [CLK_TWPLL_19M2] = &twpll_19m2.hw, + [CLK_TWPLL_12M29] = &twpll_12m29.hw, + [CLK_LPLL] = &lpll.common.hw, + [CLK_LPLL_614M4] = &lpll_614m4.hw, + [CLK_LPLL_409M6] = &lpll_409m6.hw, + [CLK_LPLL_245M76] = &lpll_245m76.hw, + [CLK_LPLL_30M72] = &lpll_30m72.hw, + [CLK_ISPPLL] = &isppll.common.hw, + [CLK_ISPPLL_468M] = &isppll_468m.hw, + [CLK_ISPPLL_78M] = &isppll_78m.hw, + [CLK_GPLL] = &gpll.common.hw, + [CLK_GPLL_40M] = &gpll_40m.hw, + [CLK_CPPLL] = &cppll.common.hw, + [CLK_CPPLL_39M32] = &cppll_39m32.hw, + }, + .num = CLK_ANLG_PHY_GC_NUM, +}; + +static struct sprd_clk_desc ums512_gc_pll_desc = { + .clk_clks = ums512_gc_pll_clks, + .num_clk_clks = ARRAY_SIZE(ums512_gc_pll_clks), + .hw_clks = &ums512_gc_pll_hws, +}; + +/* ap ahb gates */ +static SPRD_SC_GATE_CLK_FW_NAME(dsi_eb, "dsi-eb", "ext-26m", + 0x0, 0x1000, BIT(0), 0, 0); +static SPRD_SC_GATE_CLK_FW_NAME(dispc_eb, "dispc-eb", "ext-26m", + 0x0, 0x1000, BIT(1), 0, 0); +static SPRD_SC_GATE_CLK_FW_NAME(vsp_eb, "vsp-eb", "ext-26m", + 0x0, 0x1000, BIT(2), 0, 0); +static SPRD_SC_GATE_CLK_FW_NAME(vdma_eb, "vdma-eb", "ext-26m", + 0x0, 0x1000, BIT(3), 0, 0); +static SPRD_SC_GATE_CLK_FW_NAME(dma_pub_eb, "dma-pub-eb", "ext-26m", + 0x0, 0x1000, BIT(4), 0, 0); +static SPRD_SC_GATE_CLK_FW_NAME(dma_sec_eb, "dma-sec-eb", "ext-26m", + 0x0, 0x1000, BIT(5), 0, 0); +static SPRD_SC_GATE_CLK_FW_NAME(ipi_eb, "ipi-eb", "ext-26m", + 0x0, 0x1000, BIT(6), 0, 0); +static SPRD_SC_GATE_CLK_FW_NAME(ahb_ckg_eb, "ahb-ckg-eb", "ext-26m", + 0x0, 0x1000, BIT(7), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK_FW_NAME(bm_clk_eb, "bm-clk-eb", "ext-26m", + 0x0, 0x1000, BIT(8), CLK_IGNORE_UNUSED, 0); + +static struct sprd_clk_common *ums512_apahb_gate[] = { + /* address base is 0x20100000 */ + &dsi_eb.common, + &dispc_eb.common, + &vsp_eb.common, + &vdma_eb.common, + &dma_pub_eb.common, + &dma_sec_eb.common, + &ipi_eb.common, + &ahb_ckg_eb.common, + &bm_clk_eb.common, +}; + +static struct clk_hw_onecell_data ums512_apahb_gate_hws = { + .hws = { + [CLK_DSI_EB] = &dsi_eb.common.hw, + [CLK_DISPC_EB] = &dispc_eb.common.hw, + [CLK_VSP_EB] = &vsp_eb.common.hw, + [CLK_VDMA_EB] = &vdma_eb.common.hw, + [CLK_DMA_PUB_EB] = &dma_pub_eb.common.hw, + [CLK_DMA_SEC_EB] = &dma_sec_eb.common.hw, + [CLK_IPI_EB] = &ipi_eb.common.hw, + [CLK_AHB_CKG_EB] = &ahb_ckg_eb.common.hw, + [CLK_BM_CLK_EB] = &bm_clk_eb.common.hw, + }, + .num = CLK_AP_AHB_GATE_NUM, +}; + +static struct sprd_clk_desc ums512_apahb_gate_desc = { + .clk_clks = ums512_apahb_gate, + .num_clk_clks = ARRAY_SIZE(ums512_apahb_gate), + .hw_clks = &ums512_apahb_gate_hws, +}; + +/* ap clks */ +static const struct clk_parent_data ap_apb_parents[] = { + { .fw_name = "ext-26m" }, + { .hw = &twpll_64m.hw }, + { .hw = &twpll_96m.hw }, + { .hw = &twpll_128m.hw }, +}; +static SPRD_MUX_CLK_DATA(ap_apb_clk, "ap-apb-clk", ap_apb_parents, + 0x20, 0, 2, UMS512_MUX_FLAG); + +static const struct clk_parent_data ipi_parents[] = { + { .fw_name = "ext-26m" }, + { .hw = &twpll_64m.hw }, + { .hw = &twpll_96m.hw }, + { .hw = &twpll_128m.hw }, +}; +static SPRD_MUX_CLK_DATA(ipi_clk, "ipi-clk", ipi_parents, + 0x24, 0, 2, UMS512_MUX_FLAG); + +static const struct clk_parent_data ap_uart_parents[] = { + { .fw_name = "ext-26m" }, + { .hw = &twpll_48m.hw }, + { .hw = &twpll_51m2.hw }, + { .hw = &twpll_96m.hw }, +}; +static SPRD_COMP_CLK_DATA(ap_uart0_clk, "ap-uart0-clk", ap_uart_parents, + 0x28, 0, 2, 8, 3, 0); +static SPRD_COMP_CLK_DATA(ap_uart1_clk, "ap-uart1-clk", ap_uart_parents, + 0x2c, 0, 2, 8, 3, 0); +static SPRD_COMP_CLK_DATA(ap_uart2_clk, "ap-uart2-clk", ap_uart_parents, + 0x30, 0, 2, 8, 3, 0); + +static const struct clk_parent_data i2c_parents[] = { + { .fw_name = "ext-26m" }, + { .hw = &twpll_48m.hw }, + { .hw = &twpll_51m2.hw }, + { .hw = &twpll_153m6.hw }, +}; +static SPRD_COMP_CLK_DATA(ap_i2c0_clk, "ap-i2c0-clk", i2c_parents, + 0x34, 0, 2, 8, 3, 0); +static SPRD_COMP_CLK_DATA(ap_i2c1_clk, "ap-i2c1-clk", i2c_parents, + 0x38, 0, 2, 8, 3, 0); +static SPRD_COMP_CLK_DATA(ap_i2c2_clk, "ap-i2c2-clk", i2c_parents, + 0x3c, 0, 2, 8, 3, 0); +static SPRD_COMP_CLK_DATA(ap_i2c3_clk, "ap-i2c3-clk", i2c_parents, + 0x40, 0, 2, 8, 3, 0); +static SPRD_COMP_CLK_DATA(ap_i2c4_clk, "ap-i2c4-clk", i2c_parents, + 0x44, 0, 2, 8, 3, 0); + +static const struct clk_parent_data spi_parents[] = { + { .fw_name = "ext-26m" }, + { .hw = &twpll_128m.hw }, + { .hw = &twpll_153m6.hw }, + { .hw = &twpll_192m.hw }, +}; +static SPRD_COMP_CLK_DATA(ap_spi0_clk, "ap-spi0-clk", spi_parents, + 0x48, 0, 2, 8, 3, 0); +static SPRD_COMP_CLK_DATA(ap_spi1_clk, "ap-spi1-clk", spi_parents, + 0x4c, 0, 2, 8, 3, 0); +static SPRD_COMP_CLK_DATA(ap_spi2_clk, "ap-spi2-clk", spi_parents, + 0x50, 0, 2, 8, 3, 0); +static SPRD_COMP_CLK_DATA(ap_spi3_clk, "ap-spi3-clk", spi_parents, + 0x54, 0, 2, 8, 3, 0); + +static const struct clk_parent_data iis_parents[] = { + { .fw_name = "ext-26m" }, + { .hw = &twpll_128m.hw }, + { .hw = &twpll_153m6.hw }, +}; +static SPRD_COMP_CLK_DATA(ap_iis0_clk, "ap-iis0-clk", iis_parents, + 0x58, 0, 2, 8, 3, 0); +static SPRD_COMP_CLK_DATA(ap_iis1_clk, "ap-iis1-clk", iis_parents, + 0x5c, 0, 2, 8, 3, 0); +static SPRD_COMP_CLK_DATA(ap_iis2_clk, "ap-iis2-clk", iis_parents, + 0x60, 0, 2, 8, 3, 0); + +static const struct clk_parent_data sim_parents[] = { + { .fw_name = "ext-26m" }, + { .hw = &twpll_51m2.hw }, + { .hw = &twpll_64m.hw }, + { .hw = &twpll_96m.hw }, + { .hw = &twpll_128m.hw }, +}; +static SPRD_COMP_CLK_DATA(ap_sim_clk, "ap-sim-clk", sim_parents, + 0x64, 0, 3, 8, 3, 0); + +static const struct clk_parent_data ap_ce_parents[] = { + { .fw_name = "ext-26m" }, + { .hw = &twpll_96m.hw }, + { .hw = &twpll_192m.hw }, + { .hw = &twpll_256m.hw }, +}; +static SPRD_MUX_CLK_DATA(ap_ce_clk, "ap-ce-clk", ap_ce_parents, + 0x68, 0, 2, UMS512_MUX_FLAG); + +static const struct clk_parent_data sdio_parents[] = { + { .hw = &clk_1m.hw }, + { .fw_name = "ext-26m" }, + { .hw = &twpll_307m2.hw }, + { .hw = &twpll_384m.hw }, + { .hw = &rpll.common.hw }, + { .hw = &lpll_409m6.hw }, +}; +static SPRD_MUX_CLK_DATA(sdio0_2x_clk, "sdio0-2x", sdio_parents, + 0x80, 0, 3, UMS512_MUX_FLAG); +static SPRD_MUX_CLK_DATA(sdio1_2x_clk, "sdio1-2x", sdio_parents, + 0x88, 0, 3, UMS512_MUX_FLAG); +static SPRD_MUX_CLK_DATA(emmc_2x_clk, "emmc-2x", sdio_parents, + 0x90, 0, 3, UMS512_MUX_FLAG); + +static const struct clk_parent_data vsp_parents[] = { + { .hw = &twpll_256m.hw }, + { .hw = &twpll_307m2.hw }, + { .hw = &twpll_384m.hw }, +}; +static SPRD_MUX_CLK_DATA(vsp_clk, "vsp-clk", vsp_parents, + 0x98, 0, 2, UMS512_MUX_FLAG); + +static const struct clk_parent_data dispc0_parents[] = { + { .hw = &twpll_153m6.hw }, + { .hw = &twpll_192m.hw }, + { .hw = &twpll_256m.hw }, + { .hw = &twpll_307m2.hw }, + { .hw = &twpll_384m.hw }, +}; +static SPRD_MUX_CLK_DATA(dispc0_clk, "dispc0-clk", dispc0_parents, + 0x9c, 0, 3, UMS512_MUX_FLAG); + +static const struct clk_parent_data dispc0_dpi_parents[] = { + { .hw = &twpll_96m.hw }, + { .hw = &twpll_128m.hw }, + { .hw = &twpll_153m6.hw }, + { .hw = &twpll_192m.hw }, +}; +static SPRD_COMP_CLK_DATA(dispc0_dpi_clk, "dispc0-dpi-clk", dispc0_dpi_parents, + 0xa0, 0, 3, 8, 4, 0); + +static const struct clk_parent_data dsi_apb_parents[] = { + { .hw = &twpll_96m.hw }, + { .hw = &twpll_128m.hw }, + { .hw = &twpll_153m6.hw }, + { .hw = &twpll_192m.hw }, +}; +static SPRD_MUX_CLK_DATA(dsi_apb_clk, "dsi-apb-clk", dsi_apb_parents, + 0xa4, 0, 2, UMS512_MUX_FLAG); + +static SPRD_GATE_CLK_FW_NAME(dsi_rxesc, "dsi-rxesc", "ext-26m", + 0xa8, BIT(16), 0, 0); + +static SPRD_GATE_CLK_FW_NAME(dsi_lanebyte, "dsi-lanebyte", "ext-26m", + 0xac, BIT(16), 0, 0); + +static const struct clk_parent_data vdsp_parents[] = { + { .hw = &twpll_256m.hw }, + { .hw = &twpll_384m.hw }, + { .hw = &twpll_512m.hw }, + { .hw = &lpll_614m4.hw }, + { .hw = &twpll_768m.hw }, + { .hw = &isppll.common.hw }, +}; +static SPRD_MUX_CLK_DATA(vdsp_clk, "vdsp-clk", vdsp_parents, + 0xb0, 0, 3, UMS512_MUX_FLAG); +static SPRD_DIV_CLK_HW(vdsp_m_clk, "vdsp-m-clk", &vdsp_clk.common.hw, + 0xb4, 8, 2, 0); + +static struct sprd_clk_common *ums512_ap_clks[] = { + /* address base is 0x20200000 */ + &ap_apb_clk.common, + &ipi_clk.common, + &ap_uart0_clk.common, + &ap_uart1_clk.common, + &ap_uart2_clk.common, + &ap_i2c0_clk.common, + &ap_i2c1_clk.common, + &ap_i2c2_clk.common, + &ap_i2c3_clk.common, + &ap_i2c4_clk.common, + &ap_spi0_clk.common, + &ap_spi1_clk.common, + &ap_spi2_clk.common, + &ap_spi3_clk.common, + &ap_iis0_clk.common, + &ap_iis1_clk.common, + &ap_iis2_clk.common, + &ap_sim_clk.common, + &ap_ce_clk.common, + &sdio0_2x_clk.common, + &sdio1_2x_clk.common, + &emmc_2x_clk.common, + &vsp_clk.common, + &dispc0_clk.common, + &dispc0_dpi_clk.common, + &dsi_apb_clk.common, + &dsi_rxesc.common, + &dsi_lanebyte.common, + &vdsp_clk.common, + &vdsp_m_clk.common, + +}; + +static struct clk_hw_onecell_data ums512_ap_clk_hws = { + .hws = { + [CLK_AP_APB] = &ap_apb_clk.common.hw, + [CLK_IPI] = &ipi_clk.common.hw, + [CLK_AP_UART0] = &ap_uart0_clk.common.hw, + [CLK_AP_UART1] = &ap_uart1_clk.common.hw, + [CLK_AP_UART2] = &ap_uart2_clk.common.hw, + [CLK_AP_I2C0] = &ap_i2c0_clk.common.hw, + [CLK_AP_I2C1] = &ap_i2c1_clk.common.hw, + [CLK_AP_I2C2] = &ap_i2c2_clk.common.hw, + [CLK_AP_I2C3] = &ap_i2c3_clk.common.hw, + [CLK_AP_I2C4] = &ap_i2c4_clk.common.hw, + [CLK_AP_SPI0] = &ap_spi0_clk.common.hw, + [CLK_AP_SPI1] = &ap_spi1_clk.common.hw, + [CLK_AP_SPI2] = &ap_spi2_clk.common.hw, + [CLK_AP_SPI3] = &ap_spi3_clk.common.hw, + [CLK_AP_IIS0] = &ap_iis0_clk.common.hw, + [CLK_AP_IIS1] = &ap_iis1_clk.common.hw, + [CLK_AP_IIS2] = &ap_iis2_clk.common.hw, + [CLK_AP_SIM] = &ap_sim_clk.common.hw, + [CLK_AP_CE] = &ap_ce_clk.common.hw, + [CLK_SDIO0_2X] = &sdio0_2x_clk.common.hw, + [CLK_SDIO1_2X] = &sdio1_2x_clk.common.hw, + [CLK_EMMC_2X] = &emmc_2x_clk.common.hw, + [CLK_VSP] = &vsp_clk.common.hw, + [CLK_DISPC0] = &dispc0_clk.common.hw, + [CLK_DISPC0_DPI] = &dispc0_dpi_clk.common.hw, + [CLK_DSI_APB] = &dsi_apb_clk.common.hw, + [CLK_DSI_RXESC] = &dsi_rxesc.common.hw, + [CLK_DSI_LANEBYTE] = &dsi_lanebyte.common.hw, + [CLK_VDSP] = &vdsp_clk.common.hw, + [CLK_VDSP_M] = &vdsp_m_clk.common.hw, + }, + .num = CLK_AP_CLK_NUM, +}; + +static struct sprd_clk_desc ums512_ap_clk_desc = { + .clk_clks = ums512_ap_clks, + .num_clk_clks = ARRAY_SIZE(ums512_ap_clks), + .hw_clks = &ums512_ap_clk_hws, +}; + +/* aon apb clks */ +static const struct clk_parent_data aon_apb_parents[] = { + { .hw = &rco_4m.hw }, + { .fw_name = "ext-4m" }, + { .hw = &clk_13m.hw }, + { .hw = &rco_25m.hw }, + { .fw_name = "ext-26m" }, + { .hw = &twpll_96m.hw }, + { .fw_name = "rco-100m" }, + { .hw = &twpll_128m.hw }, +}; +static SPRD_COMP_CLK_DATA(aon_apb_clk, "aon-apb-clk", aon_apb_parents, + 0x220, 0, 3, 8, 2, 0); + + +static const struct clk_parent_data adi_parents[] = { + { .hw = &rco_4m.hw }, + { .fw_name = "ext-26m" }, + { .hw = &rco_25m.hw }, + { .hw = &twpll_38m4.hw }, + { .hw = &twpll_51m2.hw }, +}; +static SPRD_MUX_CLK_DATA(adi_clk, "adi-clk", adi_parents, + 0x224, 0, 3, UMS512_MUX_FLAG); + +static const struct clk_parent_data aux_parents[] = { + { .fw_name = "ext-32k" }, + { .fw_name = "ext-26m" }, + { .hw = &clk_26m_aud.hw }, + { .hw = &rco_25m.hw }, + { .hw = &cppll_39m32.hw }, + { .hw = &mpll0_56m88.hw }, + { .hw = &mpll1_63m38.hw }, + { .hw = &mpll2_47m13.hw }, + { .hw = &dpll0_58m31.hw }, + { .hw = &gpll_40m.hw }, + { .hw = &twpll_48m.hw }, +}; +static const struct clk_parent_data aux1_parents[] = { + { .fw_name = "ext-32k" }, + { .fw_name = "ext-26m" }, + { .hw = &clk_26m_aud.hw }, + { .hw = &rco_25m.hw }, + { .hw = &cppll_39m32.hw }, + { .hw = &mpll0_56m88.hw }, + { .hw = &mpll1_63m38.hw }, + { .hw = &mpll2_47m13.hw }, + { .hw = &dpll0_58m31.hw }, + { .hw = &gpll_40m.hw }, + { .hw = &twpll_19m2.hw }, + { .hw = &lpll_30m72.hw }, + { .hw = &rpll.common.hw }, + { .hw = &twpll_12m29.hw }, + +}; +static SPRD_COMP_CLK_DATA(aux0_clk, "aux0-clk", aux_parents, + 0x228, 0, 5, 8, 4, 0); +static SPRD_COMP_CLK_DATA(aux1_clk, "aux1-clk", aux1_parents, + 0x22c, 0, 5, 8, 4, 0); +static SPRD_COMP_CLK_DATA(aux2_clk, "aux2-clk", aux_parents, + 0x230, 0, 5, 8, 4, 0); +static SPRD_COMP_CLK_DATA(probe_clk, "probe-clk", aux_parents, + 0x234, 0, 5, 8, 4, 0); + +static const struct clk_parent_data pwm_parents[] = { + { .fw_name = "ext-32k" }, + { .fw_name = "ext-26m" }, + { .hw = &rco_4m.hw }, + { .hw = &rco_25m.hw }, + { .hw = &twpll_48m.hw }, +}; +static SPRD_MUX_CLK_DATA(pwm0_clk, "pwm0-clk", pwm_parents, + 0x238, 0, 3, UMS512_MUX_FLAG); +static SPRD_MUX_CLK_DATA(pwm1_clk, "pwm1-clk", pwm_parents, + 0x23c, 0, 3, UMS512_MUX_FLAG); +static SPRD_MUX_CLK_DATA(pwm2_clk, "pwm2-clk", pwm_parents, + 0x240, 0, 3, UMS512_MUX_FLAG); +static SPRD_MUX_CLK_DATA(pwm3_clk, "pwm3-clk", pwm_parents, + 0x244, 0, 3, UMS512_MUX_FLAG); + +static const struct clk_parent_data efuse_parents[] = { + { .hw = &rco_25m.hw }, + { .fw_name = "ext-26m" }, +}; +static SPRD_MUX_CLK_DATA(efuse_clk, "efuse-clk", efuse_parents, + 0x248, 0, 1, UMS512_MUX_FLAG); + +static const struct clk_parent_data uart_parents[] = { + { .hw = &rco_4m.hw }, + { .fw_name = "ext-26m" }, + { .hw = &twpll_48m.hw }, + { .hw = &twpll_51m2.hw }, + { .hw = &twpll_96m.hw }, + { .fw_name = "rco-100m" }, + { .hw = &twpll_128m.hw }, +}; +static SPRD_MUX_CLK_DATA(uart0_clk, "uart0-clk", uart_parents, + 0x24c, 0, 3, UMS512_MUX_FLAG); +static SPRD_MUX_CLK_DATA(uart1_clk, "uart1-clk", uart_parents, + 0x250, 0, 3, UMS512_MUX_FLAG); + +static const struct clk_parent_data thm_parents[] = { + { .fw_name = "ext-32k" }, + { .hw = &clk_250k.hw }, +}; +static SPRD_MUX_CLK_DATA(thm0_clk, "thm0-clk", thm_parents, + 0x260, 0, 1, UMS512_MUX_FLAG); +static SPRD_MUX_CLK_DATA(thm1_clk, "thm1-clk", thm_parents, + 0x264, 0, 1, UMS512_MUX_FLAG); +static SPRD_MUX_CLK_DATA(thm2_clk, "thm2-clk", thm_parents, + 0x268, 0, 1, UMS512_MUX_FLAG); +static SPRD_MUX_CLK_DATA(thm3_clk, "thm3-clk", thm_parents, + 0x26c, 0, 1, UMS512_MUX_FLAG); + +static const struct clk_parent_data aon_i2c_parents[] = { + { .hw = &rco_4m.hw }, + { .fw_name = "ext-26m" }, + { .hw = &twpll_48m.hw }, + { .hw = &twpll_51m2.hw }, + { .fw_name = "rco-100m" }, + { .hw = &twpll_153m6.hw }, +}; +static SPRD_MUX_CLK_DATA(aon_i2c_clk, "aon-i2c-clk", aon_i2c_parents, + 0x27c, 0, 3, UMS512_MUX_FLAG); + +static const struct clk_parent_data aon_iis_parents[] = { + { .fw_name = "ext-26m" }, + { .hw = &twpll_128m.hw }, + { .hw = &twpll_153m6.hw }, +}; +static SPRD_MUX_CLK_DATA(aon_iis_clk, "aon-iis-clk", aon_iis_parents, + 0x280, 0, 2, UMS512_MUX_FLAG); + +static const struct clk_parent_data scc_parents[] = { + { .fw_name = "ext-26m" }, + { .hw = &twpll_48m.hw }, + { .hw = &twpll_51m2.hw }, + { .hw = &twpll_96m.hw }, +}; +static SPRD_MUX_CLK_DATA(scc_clk, "scc-clk", scc_parents, + 0x284, 0, 2, UMS512_MUX_FLAG); + +static const struct clk_parent_data apcpu_dap_parents[] = { + { .fw_name = "ext-26m" }, + { .hw = &rco_4m.hw }, + { .hw = &twpll_76m8.hw }, + { .fw_name = "rco-100m" }, + { .hw = &twpll_128m.hw }, + { .hw = &twpll_153m6.hw }, +}; +static SPRD_MUX_CLK_DATA(apcpu_dap_clk, "apcpu-dap-clk", apcpu_dap_parents, + 0x288, 0, 3, UMS512_MUX_FLAG); + +static SPRD_GATE_CLK_FW_NAME(apcpu_dap_mtck, "apcpu-dap-mtck", "ext-26m", + 0x28c, BIT(16), 0, 0); + +static const struct clk_parent_data apcpu_ts_parents[] = { + { .fw_name = "ext-32m" }, + { .fw_name = "ext-26m" }, + { .hw = &twpll_128m.hw }, + { .hw = &twpll_153m6.hw }, +}; +static SPRD_MUX_CLK_DATA(apcpu_ts_clk, "apcpu-ts-clk", apcpu_ts_parents, + 0x290, 0, 2, UMS512_MUX_FLAG); + +static const struct clk_parent_data debug_ts_parents[] = { + { .fw_name = "ext-26m" }, + { .hw = &twpll_76m8.hw }, + { .hw = &twpll_128m.hw }, + { .hw = &twpll_192m.hw }, +}; +static SPRD_MUX_CLK_DATA(debug_ts_clk, "debug-ts-clk", debug_ts_parents, + 0x294, 0, 2, UMS512_MUX_FLAG); + +static SPRD_GATE_CLK_FW_NAME(dsi_test_s, "dsi-test-s", "ext-26m", + 0x298, BIT(16), 0, 0); + +static const struct clk_parent_data djtag_tck_parents[] = { + { .hw = &rco_4m.hw }, + { .fw_name = "ext-26m" }, +}; +static SPRD_MUX_CLK_DATA(djtag_tck_clk, "djtag-tck-clk", djtag_tck_parents, + 0x2b4, 0, 1, UMS512_MUX_FLAG); + +static SPRD_GATE_CLK_FW_NAME(djtag_tck_hw, "djtag-tck-hw", "ext-26m", + 0x2b8, BIT(16), 0, 0); + +static const struct clk_parent_data aon_tmr_parents[] = { + { .hw = &rco_4m.hw }, + { .hw = &rco_25m.hw }, + { .fw_name = "ext-26m" }, +}; +static SPRD_MUX_CLK_DATA(aon_tmr_clk, "aon-tmr-clk", aon_tmr_parents, + 0x2c0, 0, 2, UMS512_MUX_FLAG); + +static const struct clk_parent_data aon_pmu_parents[] = { + { .fw_name = "ext-32k" }, + { .hw = &rco_4m.hw }, + { .fw_name = "ext-4m" }, +}; +static SPRD_MUX_CLK_DATA(aon_pmu_clk, "aon-pmu-clk", aon_pmu_parents, + 0x2c8, 0, 2, UMS512_MUX_FLAG); + +static const struct clk_parent_data debounce_parents[] = { + { .fw_name = "ext-32k" }, + { .hw = &rco_4m.hw }, + { .hw = &rco_25m.hw }, + { .fw_name = "ext-26m" }, +}; +static SPRD_MUX_CLK_DATA(debounce_clk, "debounce-clk", debounce_parents, + 0x2cc, 0, 2, UMS512_MUX_FLAG); + +static const struct clk_parent_data apcpu_pmu_parents[] = { + { .fw_name = "ext-26m" }, + { .hw = &twpll_76m8.hw }, + { .fw_name = "rco-100m" }, + { .hw = &twpll_128m.hw }, +}; +static SPRD_MUX_CLK_DATA(apcpu_pmu_clk, "apcpu-pmu-clk", apcpu_pmu_parents, + 0x2d0, 0, 2, UMS512_MUX_FLAG); + +static const struct clk_parent_data top_dvfs_parents[] = { + { .fw_name = "ext-26m" }, + { .hw = &twpll_96m.hw }, + { .fw_name = "rco-100m" }, + { .hw = &twpll_128m.hw }, +}; +static SPRD_MUX_CLK_DATA(top_dvfs_clk, "top-dvfs-clk", top_dvfs_parents, + 0x2d8, 0, 2, UMS512_MUX_FLAG); + +static SPRD_GATE_CLK_FW_NAME(otg_utmi, "otg-utmi", "ext-26m", 0x2dc, + BIT(16), 0, 0); + +static const struct clk_parent_data otg_ref_parents[] = { + { .hw = &twpll_12m.hw }, + { .fw_name = "ext-26m" }, +}; +static SPRD_MUX_CLK_DATA(otg_ref_clk, "otg-ref-clk", otg_ref_parents, + 0x2e0, 0, 1, UMS512_MUX_FLAG); + +static const struct clk_parent_data cssys_parents[] = { + { .hw = &rco_25m.hw }, + { .fw_name = "ext-26m" }, + { .fw_name = "rco-100m" }, + { .hw = &twpll_153m6.hw }, + { .hw = &twpll_384m.hw }, + { .hw = &twpll_512m.hw }, +}; +static SPRD_COMP_CLK_DATA(cssys_clk, "cssys-clk", cssys_parents, + 0x2e4, 0, 3, 8, 2, 0); +static SPRD_DIV_CLK_HW(cssys_pub_clk, "cssys-pub-clk", &cssys_clk.common.hw, + 0x2e8, 8, 2, 0); +static SPRD_DIV_CLK_HW(cssys_apb_clk, "cssys-apb-clk", &cssys_clk.common.hw, + 0x2ec, 8, 3, 0); + +static const struct clk_parent_data ap_axi_parents[] = { + { .fw_name = "ext-26m" }, + { .hw = &twpll_76m8.hw }, + { .hw = &twpll_128m.hw }, + { .hw = &twpll_256m.hw }, +}; +static SPRD_MUX_CLK_DATA(ap_axi_clk, "ap-axi-clk", ap_axi_parents, + 0x2f0, 0, 2, UMS512_MUX_FLAG); + +static const struct clk_parent_data ap_mm_parents[] = { + { .fw_name = "ext-26m" }, + { .hw = &twpll_96m.hw }, + { .hw = &twpll_128m.hw }, + { .hw = &twpll_153m6.hw }, +}; +static SPRD_MUX_CLK_DATA(ap_mm_clk, "ap-mm-clk", ap_mm_parents, + 0x2f4, 0, 2, UMS512_MUX_FLAG); + +static const struct clk_parent_data sdio2_2x_parents[] = { + { .hw = &clk_1m.hw }, + { .fw_name = "ext-26m" }, + { .hw = &twpll_307m2.hw }, + { .hw = &twpll_384m.hw }, + { .hw = &rpll.common.hw }, + { .hw = &lpll_409m6.hw }, +}; +static SPRD_MUX_CLK_DATA(sdio2_2x_clk, "sdio2-2x-clk", sdio2_2x_parents, + 0x2f8, 0, 3, UMS512_MUX_FLAG); + +static const struct clk_parent_data analog_io_apb_parents[] = { + { .fw_name = "ext-26m" }, + { .hw = &twpll_48m.hw }, +}; +static SPRD_COMP_CLK_DATA(analog_io_apb, "analog-io-apb", analog_io_apb_parents, + 0x300, 0, 1, 8, 2, 0); + +static const struct clk_parent_data dmc_ref_parents[] = { + { .hw = &clk_6m5.hw }, + { .hw = &clk_13m.hw }, + { .fw_name = "ext-26m" }, +}; +static SPRD_MUX_CLK_DATA(dmc_ref_clk, "dmc-ref-clk", dmc_ref_parents, + 0x304, 0, 2, UMS512_MUX_FLAG); + +static const struct clk_parent_data emc_parents[] = { + { .fw_name = "ext-26m" }, + { .hw = &twpll_384m.hw }, + { .hw = &twpll_512m.hw }, + { .hw = &twpll_768m.hw }, +}; +static SPRD_MUX_CLK_DATA(emc_clk, "emc-clk", emc_parents, + 0x30c, 0, 2, UMS512_MUX_FLAG); + +static const struct clk_parent_data usb_parents[] = { + { .hw = &rco_25m.hw }, + { .fw_name = "ext-26m" }, + { .hw = &twpll_192m.hw }, + { .hw = &twpll_96m.hw }, + { .fw_name = "rco-100m" }, + { .hw = &twpll_128m.hw }, +}; +static SPRD_COMP_CLK_DATA(usb_clk, "usb-clk", usb_parents, + 0x310, 0, 3, 8, 2, 0); + +static const struct clk_parent_data pmu_26m_parents[] = { + { .hw = &rco_25m.hw }, + { .fw_name = "ext-26m" }, +}; +static SPRD_MUX_CLK_DATA(pmu_26m_clk, "26m-pmu-clk", pmu_26m_parents, + 0x318, 0, 1, UMS512_MUX_FLAG); + +static struct sprd_clk_common *ums512_aon_apb[] = { + /* address base is 0x32080200 */ + &aon_apb_clk.common, + &adi_clk.common, + &aux0_clk.common, + &aux1_clk.common, + &aux2_clk.common, + &probe_clk.common, + &pwm0_clk.common, + &pwm1_clk.common, + &pwm2_clk.common, + &pwm3_clk.common, + &efuse_clk.common, + &uart0_clk.common, + &uart1_clk.common, + &thm0_clk.common, + &thm1_clk.common, + &thm2_clk.common, + &thm3_clk.common, + &aon_i2c_clk.common, + &aon_iis_clk.common, + &scc_clk.common, + &apcpu_dap_clk.common, + &apcpu_dap_mtck.common, + &apcpu_ts_clk.common, + &debug_ts_clk.common, + &dsi_test_s.common, + &djtag_tck_clk.common, + &djtag_tck_hw.common, + &aon_tmr_clk.common, + &aon_pmu_clk.common, + &debounce_clk.common, + &apcpu_pmu_clk.common, + &top_dvfs_clk.common, + &otg_utmi.common, + &otg_ref_clk.common, + &cssys_clk.common, + &cssys_pub_clk.common, + &cssys_apb_clk.common, + &ap_axi_clk.common, + &ap_mm_clk.common, + &sdio2_2x_clk.common, + &analog_io_apb.common, + &dmc_ref_clk.common, + &emc_clk.common, + &usb_clk.common, + &pmu_26m_clk.common, +}; + +static struct clk_hw_onecell_data ums512_aon_apb_hws = { + .hws = { + [CLK_AON_APB] = &aon_apb_clk.common.hw, + [CLK_ADI] = &adi_clk.common.hw, + [CLK_AUX0] = &aux0_clk.common.hw, + [CLK_AUX1] = &aux1_clk.common.hw, + [CLK_AUX2] = &aux2_clk.common.hw, + [CLK_PROBE] = &probe_clk.common.hw, + [CLK_PWM0] = &pwm0_clk.common.hw, + [CLK_PWM1] = &pwm1_clk.common.hw, + [CLK_PWM2] = &pwm2_clk.common.hw, + [CLK_PWM3] = &pwm3_clk.common.hw, + [CLK_EFUSE] = &efuse_clk.common.hw, + [CLK_UART0] = &uart0_clk.common.hw, + [CLK_UART1] = &uart1_clk.common.hw, + [CLK_THM0] = &thm0_clk.common.hw, + [CLK_THM1] = &thm1_clk.common.hw, + [CLK_THM2] = &thm2_clk.common.hw, + [CLK_THM3] = &thm3_clk.common.hw, + [CLK_AON_I2C] = &aon_i2c_clk.common.hw, + [CLK_AON_IIS] = &aon_iis_clk.common.hw, + [CLK_SCC] = &scc_clk.common.hw, + [CLK_APCPU_DAP] = &apcpu_dap_clk.common.hw, + [CLK_APCPU_DAP_MTCK] = &apcpu_dap_mtck.common.hw, + [CLK_APCPU_TS] = &apcpu_ts_clk.common.hw, + [CLK_DEBUG_TS] = &debug_ts_clk.common.hw, + [CLK_DSI_TEST_S] = &dsi_test_s.common.hw, + [CLK_DJTAG_TCK] = &djtag_tck_clk.common.hw, + [CLK_DJTAG_TCK_HW] = &djtag_tck_hw.common.hw, + [CLK_AON_TMR] = &aon_tmr_clk.common.hw, + [CLK_AON_PMU] = &aon_pmu_clk.common.hw, + [CLK_DEBOUNCE] = &debounce_clk.common.hw, + [CLK_APCPU_PMU] = &apcpu_pmu_clk.common.hw, + [CLK_TOP_DVFS] = &top_dvfs_clk.common.hw, + [CLK_OTG_UTMI] = &otg_utmi.common.hw, + [CLK_OTG_REF] = &otg_ref_clk.common.hw, + [CLK_CSSYS] = &cssys_clk.common.hw, + [CLK_CSSYS_PUB] = &cssys_pub_clk.common.hw, + [CLK_CSSYS_APB] = &cssys_apb_clk.common.hw, + [CLK_AP_AXI] = &ap_axi_clk.common.hw, + [CLK_AP_MM] = &ap_mm_clk.common.hw, + [CLK_SDIO2_2X] = &sdio2_2x_clk.common.hw, + [CLK_ANALOG_IO_APB] = &analog_io_apb.common.hw, + [CLK_DMC_REF_CLK] = &dmc_ref_clk.common.hw, + [CLK_EMC] = &emc_clk.common.hw, + [CLK_USB] = &usb_clk.common.hw, + [CLK_26M_PMU] = &pmu_26m_clk.common.hw, + }, + .num = CLK_AON_APB_NUM, +}; + +static struct sprd_clk_desc ums512_aon_apb_desc = { + .clk_clks = ums512_aon_apb, + .num_clk_clks = ARRAY_SIZE(ums512_aon_apb), + .hw_clks = &ums512_aon_apb_hws, +}; + +/* aon apb gates */ +static SPRD_SC_GATE_CLK_FW_NAME(rc100m_cal_eb, "rc100m-cal-eb", "ext-26m", + 0x0, 0x1000, BIT(0), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK_FW_NAME(djtag_tck_eb, "djtag-tck-eb", "ext-26m", + 0x0, 0x1000, BIT(2), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK_FW_NAME(djtag_eb, "djtag-eb", "ext-26m", + 0x0, 0x1000, BIT(3), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK_FW_NAME(aux0_eb, "aux0-eb", "ext-26m", + 0x0, 0x1000, BIT(4), 0, 0); +static SPRD_SC_GATE_CLK_FW_NAME(aux1_eb, "aux1-eb", "ext-26m", + 0x0, 0x1000, BIT(5), 0, 0); +static SPRD_SC_GATE_CLK_FW_NAME(aux2_eb, "aux2-eb", "ext-26m", + 0x0, 0x1000, BIT(6), 0, 0); +static SPRD_SC_GATE_CLK_FW_NAME(probe_eb, "probe-eb", "ext-26m", + 0x0, 0x1000, BIT(7), 0, 0); +static SPRD_SC_GATE_CLK_FW_NAME(mm_eb, "mm-eb", "ext-26m", + 0x0, 0x1000, BIT(9), 0, 0); +static SPRD_SC_GATE_CLK_FW_NAME(gpu_eb, "gpu-eb", "ext-26m", + 0x0, 0x1000, BIT(11), 0, 0); +static SPRD_SC_GATE_CLK_FW_NAME(mspi_eb, "mspi-eb", "ext-26m", + 0x0, 0x1000, BIT(12), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK_FW_NAME(apcpu_dap_eb, "apcpu-dap-eb", "ext-26m", + 0x0, 0x1000, BIT(14), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK_FW_NAME(aon_cssys_eb, "aon-cssys-eb", "ext-26m", + 0x0, 0x1000, BIT(15), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK_FW_NAME(cssys_apb_eb, "cssys-apb-eb", "ext-26m", + 0x0, 0x1000, BIT(16), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK_FW_NAME(cssys_pub_eb, "cssys-pub-eb", "ext-26m", + 0x0, 0x1000, BIT(17), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK_FW_NAME(sdphy_cfg_eb, "sdphy-cfg-eb", "ext-26m", + 0x0, 0x1000, BIT(19), 0, 0); +static SPRD_SC_GATE_CLK_FW_NAME(sdphy_ref_eb, "sdphy-ref-eb", "ext-26m", + 0x0, 0x1000, BIT(20), 0, 0); +static SPRD_SC_GATE_CLK_FW_NAME(efuse_eb, "efuse-eb", "ext-26m", + 0x4, 0x1000, BIT(0), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK_FW_NAME(gpio_eb, "gpio-eb", "ext-26m", + 0x4, 0x1000, BIT(1), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK_FW_NAME(mbox_eb, "mbox-eb", "ext-26m", + 0x4, 0x1000, BIT(2), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK_FW_NAME(kpd_eb, "kpd-eb", "ext-26m", + 0x4, 0x1000, BIT(3), 0, 0); +static SPRD_SC_GATE_CLK_FW_NAME(aon_syst_eb, "aon-syst-eb", "ext-26m", + 0x4, 0x1000, BIT(4), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK_FW_NAME(ap_syst_eb, "ap-syst-eb", "ext-26m", + 0x4, 0x1000, BIT(5), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK_FW_NAME(aon_tmr_eb, "aon-tmr-eb", "ext-26m", + 0x4, 0x1000, BIT(6), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK_FW_NAME(otg_utmi_eb, "otg-utmi-eb", "ext-26m", + 0x4, 0x1000, BIT(8), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK_FW_NAME(otg_phy_eb, "otg-phy-eb", "ext-26m", + 0x4, 0x1000, BIT(9), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK_FW_NAME(splk_eb, "splk-eb", "ext-26m", + 0x4, 0x1000, BIT(10), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK_FW_NAME(pin_eb, "pin-eb", "ext-26m", + 0x4, 0x1000, BIT(11), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK_FW_NAME(ana_eb, "ana-eb", "ext-26m", + 0x4, 0x1000, BIT(12), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK_FW_NAME(apcpu_ts0_eb, "apcpu-ts0-eb", "ext-26m", + 0x4, 0x1000, BIT(17), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK_FW_NAME(apb_busmon_eb, "apb-busmon-eb", "ext-26m", + 0x4, 0x1000, BIT(18), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK_FW_NAME(aon_iis_eb, "aon-iis-eb", "ext-26m", + 0x4, 0x1000, BIT(19), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK_FW_NAME(scc_eb, "scc-eb", "ext-26m", + 0x4, 0x1000, BIT(20), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK_FW_NAME(thm0_eb, "thm0-eb", "ext-26m", + 0x8, 0x1000, BIT(0), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK_FW_NAME(thm1_eb, "thm1-eb", "ext-26m", + 0x8, 0x1000, BIT(1), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK_FW_NAME(thm2_eb, "thm2-eb", "ext-26m", + 0x8, 0x1000, BIT(2), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK_FW_NAME(asim_top_eb, "asim-top", "ext-26m", + 0x8, 0x1000, BIT(3), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK_FW_NAME(i2c_eb, "i2c-eb", "ext-26m", + 0x8, 0x1000, BIT(7), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK_FW_NAME(pmu_eb, "pmu-eb", "ext-26m", + 0x8, 0x1000, BIT(8), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK_FW_NAME(adi_eb, "adi-eb", "ext-26m", + 0x8, 0x1000, BIT(9), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK_FW_NAME(eic_eb, "eic-eb", "ext-26m", + 0x8, 0x1000, BIT(10), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK_FW_NAME(ap_intc0_eb, "ap-intc0-eb", "ext-26m", + 0x8, 0x1000, BIT(11), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK_FW_NAME(ap_intc1_eb, "ap-intc1-eb", "ext-26m", + 0x8, 0x1000, BIT(12), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK_FW_NAME(ap_intc2_eb, "ap-intc2-eb", "ext-26m", + 0x8, 0x1000, BIT(13), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK_FW_NAME(ap_intc3_eb, "ap-intc3-eb", "ext-26m", + 0x8, 0x1000, BIT(14), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK_FW_NAME(ap_intc4_eb, "ap-intc4-eb", "ext-26m", + 0x8, 0x1000, BIT(15), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK_FW_NAME(ap_intc5_eb, "ap-intc5-eb", "ext-26m", + 0x8, 0x1000, BIT(16), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK_FW_NAME(audcp_intc_eb, "audcp-intc-eb", "ext-26m", + 0x8, 0x1000, BIT(17), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK_FW_NAME(ap_tmr0_eb, "ap-tmr0-eb", "ext-26m", + 0x8, 0x1000, BIT(22), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK_FW_NAME(ap_tmr1_eb, "ap-tmr1-eb", "ext-26m", + 0x8, 0x1000, BIT(23), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK_FW_NAME(ap_tmr2_eb, "ap-tmr2-eb", "ext-26m", + 0x8, 0x1000, BIT(24), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK_FW_NAME(pwm0_eb, "pwm0-eb", "ext-26m", + 0x8, 0x1000, BIT(25), 0, 0); +static SPRD_SC_GATE_CLK_FW_NAME(pwm1_eb, "pwm1-eb", "ext-26m", + 0x8, 0x1000, BIT(26), 0, 0); +static SPRD_SC_GATE_CLK_FW_NAME(pwm2_eb, "pwm2-eb", "ext-26m", + 0x8, 0x1000, BIT(27), 0, 0); +static SPRD_SC_GATE_CLK_FW_NAME(pwm3_eb, "pwm3-eb", "ext-26m", + 0x8, 0x1000, BIT(28), 0, 0); +static SPRD_SC_GATE_CLK_FW_NAME(ap_wdg_eb, "ap-wdg-eb", "ext-26m", + 0x8, 0x1000, BIT(29), 0, 0); +static SPRD_SC_GATE_CLK_FW_NAME(apcpu_wdg_eb, "apcpu-wdg-eb", "ext-26m", + 0x8, 0x1000, BIT(30), 0, 0); +static SPRD_SC_GATE_CLK_FW_NAME(serdes_eb, "serdes-eb", "ext-26m", + 0x8, 0x1000, BIT(31), 0, 0); +static SPRD_SC_GATE_CLK_FW_NAME(arch_rtc_eb, "arch-rtc-eb", "ext-26m", + 0x18, 0x1000, BIT(0), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK_FW_NAME(kpd_rtc_eb, "kpd-rtc-eb", "ext-26m", + 0x18, 0x1000, BIT(1), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK_FW_NAME(aon_syst_rtc_eb, "aon-syst-rtc-eb", "ext-26m", + 0x18, 0x1000, BIT(2), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK_FW_NAME(ap_syst_rtc_eb, "ap-syst-rtc-eb", "ext-26m", + 0x18, 0x1000, BIT(3), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK_FW_NAME(aon_tmr_rtc_eb, "aon-tmr-rtc-eb", "ext-26m", + 0x18, 0x1000, BIT(4), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK_FW_NAME(eic_rtc_eb, "eic-rtc-eb", "ext-26m", + 0x18, 0x1000, BIT(5), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK_FW_NAME(eic_rtcdv5_eb, "eic-rtcdv5-eb", "ext-26m", + 0x18, 0x1000, BIT(6), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK_FW_NAME(ap_wdg_rtc_eb, "ap-wdg-rtc-eb", "ext-26m", + 0x18, 0x1000, BIT(7), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK_FW_NAME(ac_wdg_rtc_eb, "ac-wdg-rtc-eb", "ext-26m", + 0x18, 0x1000, BIT(8), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK_FW_NAME(ap_tmr0_rtc_eb, "ap-tmr0-rtc-eb", "ext-26m", + 0x18, 0x1000, BIT(9), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK_FW_NAME(ap_tmr1_rtc_eb, "ap-tmr1-rtc-eb", "ext-26m", + 0x18, 0x1000, BIT(10), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK_FW_NAME(ap_tmr2_rtc_eb, "ap-tmr2-rtc-eb", "ext-26m", + 0x18, 0x1000, BIT(11), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK_FW_NAME(dcxo_lc_rtc_eb, "dcxo-lc-rtc-eb", "ext-26m", + 0x18, 0x1000, BIT(12), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK_FW_NAME(bb_cal_rtc_eb, "bb-cal-rtc-eb", "ext-26m", + 0x18, 0x1000, BIT(13), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK_FW_NAME(ap_emmc_rtc_eb, "ap-emmc-rtc-eb", "ext-26m", + 0x18, 0x1000, BIT(14), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK_FW_NAME(ap_sdio0_rtc_eb, "ap-sdio0-rtc-eb", "ext-26m", + 0x18, 0x1000, BIT(15), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK_FW_NAME(ap_sdio1_rtc_eb, "ap-sdio1-rtc-eb", "ext-26m", + 0x18, 0x1000, BIT(16), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK_FW_NAME(ap_sdio2_rtc_eb, "ap-sdio2-rtc-eb", "ext-26m", + 0x18, 0x1000, BIT(17), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK_FW_NAME(dsi_csi_test_eb, "dsi-csi-test-eb", "ext-26m", + 0x138, 0x1000, BIT(8), 0, 0); +static SPRD_SC_GATE_CLK_FW_NAME(djtag_tck_en, "djtag-tck-en", "ext-26m", + 0x138, 0x1000, BIT(9), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK_FW_NAME(dphy_ref_eb, "dphy-ref-eb", "ext-26m", + 0x138, 0x1000, BIT(10), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK_FW_NAME(dmc_ref_eb, "dmc-ref-eb", "ext-26m", + 0x138, 0x1000, BIT(11), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK_FW_NAME(otg_ref_eb, "otg-ref-eb", "ext-26m", + 0x138, 0x1000, BIT(12), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK_FW_NAME(tsen_eb, "tsen-eb", "ext-26m", + 0x138, 0x1000, BIT(13), 0, 0); +static SPRD_SC_GATE_CLK_FW_NAME(tmr_eb, "tmr-eb", "ext-26m", + 0x138, 0x1000, BIT(14), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK_FW_NAME(rc100m_ref_eb, "rc100m-ref-eb", "ext-26m", + 0x138, 0x1000, BIT(15), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK_FW_NAME(rc100m_fdk_eb, "rc100m-fdk-eb", "ext-26m", + 0x138, 0x1000, BIT(16), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK_FW_NAME(debounce_eb, "debounce-eb", "ext-26m", + 0x138, 0x1000, BIT(17), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK_FW_NAME(det_32k_eb, "det-32k-eb", "ext-26m", + 0x138, 0x1000, BIT(18), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK_FW_NAME(top_cssys_en, "top-cssys-en", "ext-26m", + 0x13c, 0x1000, BIT(0), 0, 0); +static SPRD_SC_GATE_CLK_FW_NAME(ap_axi_en, "ap-axi-en", "ext-26m", + 0x13c, 0x1000, BIT(1), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK_FW_NAME(sdio0_2x_en, "sdio0-2x-en", "ext-26m", + 0x13c, 0x1000, BIT(2), 0, 0); +static SPRD_SC_GATE_CLK_FW_NAME(sdio0_1x_en, "sdio0-1x-en", "ext-26m", + 0x13c, 0x1000, BIT(3), 0, 0); +static SPRD_SC_GATE_CLK_FW_NAME(sdio1_2x_en, "sdio1-2x-en", "ext-26m", + 0x13c, 0x1000, BIT(4), 0, 0); +static SPRD_SC_GATE_CLK_FW_NAME(sdio1_1x_en, "sdio1-1x-en", "ext-26m", + 0x13c, 0x1000, BIT(5), 0, 0); +static SPRD_SC_GATE_CLK_FW_NAME(sdio2_2x_en, "sdio2-2x-en", "ext-26m", + 0x13c, 0x1000, BIT(6), 0, 0); +static SPRD_SC_GATE_CLK_FW_NAME(sdio2_1x_en, "sdio2-1x-en", "ext-26m", + 0x13c, 0x1000, BIT(7), 0, 0); +static SPRD_SC_GATE_CLK_FW_NAME(emmc_2x_en, "emmc-2x-en", "ext-26m", + 0x13c, 0x1000, BIT(8), 0, 0); +static SPRD_SC_GATE_CLK_FW_NAME(emmc_1x_en, "emmc-1x-en", "ext-26m", + 0x13c, 0x1000, BIT(9), 0, 0); +static SPRD_SC_GATE_CLK_FW_NAME(pll_test_en, "pll-test-en", "ext-26m", + 0x13c, 0x1000, BIT(14), 0, 0); +static SPRD_SC_GATE_CLK_FW_NAME(cphy_cfg_en, "cphy-cfg-en", "ext-26m", + 0x13c, 0x1000, BIT(15), 0, 0); +static SPRD_SC_GATE_CLK_FW_NAME(debug_ts_en, "debug-ts-en", "ext-26m", + 0x13c, 0x1000, BIT(18), 0, 0); +static SPRD_SC_GATE_CLK_FW_NAME(access_aud_en, "access-aud-en", + "ext-26m", 0x14c, 0x1000, BIT(0), 0, 0); + +static struct sprd_clk_common *ums512_aon_gate[] = { + /* address base is 0x327d0000 */ + &rc100m_cal_eb.common, + &djtag_tck_eb.common, + &djtag_eb.common, + &aux0_eb.common, + &aux1_eb.common, + &aux2_eb.common, + &probe_eb.common, + &mm_eb.common, + &gpu_eb.common, + &mspi_eb.common, + &apcpu_dap_eb.common, + &aon_cssys_eb.common, + &cssys_apb_eb.common, + &cssys_pub_eb.common, + &sdphy_cfg_eb.common, + &sdphy_ref_eb.common, + &efuse_eb.common, + &gpio_eb.common, + &mbox_eb.common, + &kpd_eb.common, + &aon_syst_eb.common, + &ap_syst_eb.common, + &aon_tmr_eb.common, + &otg_utmi_eb.common, + &otg_phy_eb.common, + &splk_eb.common, + &pin_eb.common, + &ana_eb.common, + &apcpu_ts0_eb.common, + &apb_busmon_eb.common, + &aon_iis_eb.common, + &scc_eb.common, + &thm0_eb.common, + &thm1_eb.common, + &thm2_eb.common, + &asim_top_eb.common, + &i2c_eb.common, + &pmu_eb.common, + &adi_eb.common, + &eic_eb.common, + &ap_intc0_eb.common, + &ap_intc1_eb.common, + &ap_intc2_eb.common, + &ap_intc3_eb.common, + &ap_intc4_eb.common, + &ap_intc5_eb.common, + &audcp_intc_eb.common, + &ap_tmr0_eb.common, + &ap_tmr1_eb.common, + &ap_tmr2_eb.common, + &pwm0_eb.common, + &pwm1_eb.common, + &pwm2_eb.common, + &pwm3_eb.common, + &ap_wdg_eb.common, + &apcpu_wdg_eb.common, + &serdes_eb.common, + &arch_rtc_eb.common, + &kpd_rtc_eb.common, + &aon_syst_rtc_eb.common, + &ap_syst_rtc_eb.common, + &aon_tmr_rtc_eb.common, + &eic_rtc_eb.common, + &eic_rtcdv5_eb.common, + &ap_wdg_rtc_eb.common, + &ac_wdg_rtc_eb.common, + &ap_tmr0_rtc_eb.common, + &ap_tmr1_rtc_eb.common, + &ap_tmr2_rtc_eb.common, + &dcxo_lc_rtc_eb.common, + &bb_cal_rtc_eb.common, + &ap_emmc_rtc_eb.common, + &ap_sdio0_rtc_eb.common, + &ap_sdio1_rtc_eb.common, + &ap_sdio2_rtc_eb.common, + &dsi_csi_test_eb.common, + &djtag_tck_en.common, + &dphy_ref_eb.common, + &dmc_ref_eb.common, + &otg_ref_eb.common, + &tsen_eb.common, + &tmr_eb.common, + &rc100m_ref_eb.common, + &rc100m_fdk_eb.common, + &debounce_eb.common, + &det_32k_eb.common, + &top_cssys_en.common, + &ap_axi_en.common, + &sdio0_2x_en.common, + &sdio0_1x_en.common, + &sdio1_2x_en.common, + &sdio1_1x_en.common, + &sdio2_2x_en.common, + &sdio2_1x_en.common, + &emmc_2x_en.common, + &emmc_1x_en.common, + &pll_test_en.common, + &cphy_cfg_en.common, + &debug_ts_en.common, + &access_aud_en.common, +}; + +static struct clk_hw_onecell_data ums512_aon_gate_hws = { + .hws = { + [CLK_RC100M_CAL_EB] = &rc100m_cal_eb.common.hw, + [CLK_DJTAG_TCK_EB] = &djtag_tck_eb.common.hw, + [CLK_DJTAG_EB] = &djtag_eb.common.hw, + [CLK_AUX0_EB] = &aux0_eb.common.hw, + [CLK_AUX1_EB] = &aux1_eb.common.hw, + [CLK_AUX2_EB] = &aux2_eb.common.hw, + [CLK_PROBE_EB] = &probe_eb.common.hw, + [CLK_MM_EB] = &mm_eb.common.hw, + [CLK_GPU_EB] = &gpu_eb.common.hw, + [CLK_MSPI_EB] = &mspi_eb.common.hw, + [CLK_APCPU_DAP_EB] = &apcpu_dap_eb.common.hw, + [CLK_AON_CSSYS_EB] = &aon_cssys_eb.common.hw, + [CLK_CSSYS_APB_EB] = &cssys_apb_eb.common.hw, + [CLK_CSSYS_PUB_EB] = &cssys_pub_eb.common.hw, + [CLK_SDPHY_CFG_EB] = &sdphy_cfg_eb.common.hw, + [CLK_SDPHY_REF_EB] = &sdphy_ref_eb.common.hw, + [CLK_EFUSE_EB] = &efuse_eb.common.hw, + [CLK_GPIO_EB] = &gpio_eb.common.hw, + [CLK_MBOX_EB] = &mbox_eb.common.hw, + [CLK_KPD_EB] = &kpd_eb.common.hw, + [CLK_AON_SYST_EB] = &aon_syst_eb.common.hw, + [CLK_AP_SYST_EB] = &ap_syst_eb.common.hw, + [CLK_AON_TMR_EB] = &aon_tmr_eb.common.hw, + [CLK_OTG_UTMI_EB] = &otg_utmi_eb.common.hw, + [CLK_OTG_PHY_EB] = &otg_phy_eb.common.hw, + [CLK_SPLK_EB] = &splk_eb.common.hw, + [CLK_PIN_EB] = &pin_eb.common.hw, + [CLK_ANA_EB] = &ana_eb.common.hw, + [CLK_APCPU_TS0_EB] = &apcpu_ts0_eb.common.hw, + [CLK_APB_BUSMON_EB] = &apb_busmon_eb.common.hw, + [CLK_AON_IIS_EB] = &aon_iis_eb.common.hw, + [CLK_SCC_EB] = &scc_eb.common.hw, + [CLK_THM0_EB] = &thm0_eb.common.hw, + [CLK_THM1_EB] = &thm1_eb.common.hw, + [CLK_THM2_EB] = &thm2_eb.common.hw, + [CLK_ASIM_TOP_EB] = &asim_top_eb.common.hw, + [CLK_I2C_EB] = &i2c_eb.common.hw, + [CLK_PMU_EB] = &pmu_eb.common.hw, + [CLK_ADI_EB] = &adi_eb.common.hw, + [CLK_EIC_EB] = &eic_eb.common.hw, + [CLK_AP_INTC0_EB] = &ap_intc0_eb.common.hw, + [CLK_AP_INTC1_EB] = &ap_intc1_eb.common.hw, + [CLK_AP_INTC2_EB] = &ap_intc2_eb.common.hw, + [CLK_AP_INTC3_EB] = &ap_intc3_eb.common.hw, + [CLK_AP_INTC4_EB] = &ap_intc4_eb.common.hw, + [CLK_AP_INTC5_EB] = &ap_intc5_eb.common.hw, + [CLK_AUDCP_INTC_EB] = &audcp_intc_eb.common.hw, + [CLK_AP_TMR0_EB] = &ap_tmr0_eb.common.hw, + [CLK_AP_TMR1_EB] = &ap_tmr1_eb.common.hw, + [CLK_AP_TMR2_EB] = &ap_tmr2_eb.common.hw, + [CLK_PWM0_EB] = &pwm0_eb.common.hw, + [CLK_PWM1_EB] = &pwm1_eb.common.hw, + [CLK_PWM2_EB] = &pwm2_eb.common.hw, + [CLK_PWM3_EB] = &pwm3_eb.common.hw, + [CLK_AP_WDG_EB] = &ap_wdg_eb.common.hw, + [CLK_APCPU_WDG_EB] = &apcpu_wdg_eb.common.hw, + [CLK_SERDES_EB] = &serdes_eb.common.hw, + [CLK_ARCH_RTC_EB] = &arch_rtc_eb.common.hw, + [CLK_KPD_RTC_EB] = &kpd_rtc_eb.common.hw, + [CLK_AON_SYST_RTC_EB] = &aon_syst_rtc_eb.common.hw, + [CLK_AP_SYST_RTC_EB] = &ap_syst_rtc_eb.common.hw, + [CLK_AON_TMR_RTC_EB] = &aon_tmr_rtc_eb.common.hw, + [CLK_EIC_RTC_EB] = &eic_rtc_eb.common.hw, + [CLK_EIC_RTCDV5_EB] = &eic_rtcdv5_eb.common.hw, + [CLK_AP_WDG_RTC_EB] = &ap_wdg_rtc_eb.common.hw, + [CLK_AC_WDG_RTC_EB] = &ac_wdg_rtc_eb.common.hw, + [CLK_AP_TMR0_RTC_EB] = &ap_tmr0_rtc_eb.common.hw, + [CLK_AP_TMR1_RTC_EB] = &ap_tmr1_rtc_eb.common.hw, + [CLK_AP_TMR2_RTC_EB] = &ap_tmr2_rtc_eb.common.hw, + [CLK_DCXO_LC_RTC_EB] = &dcxo_lc_rtc_eb.common.hw, + [CLK_BB_CAL_RTC_EB] = &bb_cal_rtc_eb.common.hw, + [CLK_AP_EMMC_RTC_EB] = &ap_emmc_rtc_eb.common.hw, + [CLK_AP_SDIO0_RTC_EB] = &ap_sdio0_rtc_eb.common.hw, + [CLK_AP_SDIO1_RTC_EB] = &ap_sdio1_rtc_eb.common.hw, + [CLK_AP_SDIO2_RTC_EB] = &ap_sdio2_rtc_eb.common.hw, + [CLK_DSI_CSI_TEST_EB] = &dsi_csi_test_eb.common.hw, + [CLK_DJTAG_TCK_EN] = &djtag_tck_en.common.hw, + [CLK_DPHY_REF_EB] = &dphy_ref_eb.common.hw, + [CLK_DMC_REF_EB] = &dmc_ref_eb.common.hw, + [CLK_OTG_REF_EB] = &otg_ref_eb.common.hw, + [CLK_TSEN_EB] = &tsen_eb.common.hw, + [CLK_TMR_EB] = &tmr_eb.common.hw, + [CLK_RC100M_REF_EB] = &rc100m_ref_eb.common.hw, + [CLK_RC100M_FDK_EB] = &rc100m_fdk_eb.common.hw, + [CLK_DEBOUNCE_EB] = &debounce_eb.common.hw, + [CLK_DET_32K_EB] = &det_32k_eb.common.hw, + [CLK_TOP_CSSYS_EB] = &top_cssys_en.common.hw, + [CLK_AP_AXI_EN] = &ap_axi_en.common.hw, + [CLK_SDIO0_2X_EN] = &sdio0_2x_en.common.hw, + [CLK_SDIO0_1X_EN] = &sdio0_1x_en.common.hw, + [CLK_SDIO1_2X_EN] = &sdio1_2x_en.common.hw, + [CLK_SDIO1_1X_EN] = &sdio1_1x_en.common.hw, + [CLK_SDIO2_2X_EN] = &sdio2_2x_en.common.hw, + [CLK_SDIO2_1X_EN] = &sdio2_1x_en.common.hw, + [CLK_EMMC_2X_EN] = &emmc_2x_en.common.hw, + [CLK_EMMC_1X_EN] = &emmc_1x_en.common.hw, + [CLK_PLL_TEST_EN] = &pll_test_en.common.hw, + [CLK_CPHY_CFG_EN] = &cphy_cfg_en.common.hw, + [CLK_DEBUG_TS_EN] = &debug_ts_en.common.hw, + [CLK_ACCESS_AUD_EN] = &access_aud_en.common.hw, + }, + .num = CLK_AON_APB_GATE_NUM, +}; + +static struct sprd_clk_desc ums512_aon_gate_desc = { + .clk_clks = ums512_aon_gate, + .num_clk_clks = ARRAY_SIZE(ums512_aon_gate), + .hw_clks = &ums512_aon_gate_hws, +}; + +/* audcp apb gates */ +/* Audcp apb clocks configure CLK_IGNORE_UNUSED because these clocks may be + * controlled by audcp sys at the same time. It may cause an exception if + * kernel gates these clock. + */ +static SPRD_SC_GATE_CLK_HW(audcp_wdg_eb, "audcp-wdg-eb", + &access_aud_en.common.hw, 0x0, 0x100, BIT(1), + CLK_IGNORE_UNUSED, SPRD_GATE_NON_AON); +static SPRD_SC_GATE_CLK_HW(audcp_rtc_wdg_eb, "audcp-rtc-wdg-eb", + &access_aud_en.common.hw, 0x0, 0x100, BIT(2), + CLK_IGNORE_UNUSED, SPRD_GATE_NON_AON); +static SPRD_SC_GATE_CLK_HW(audcp_tmr0_eb, "audcp-tmr0-eb", + &access_aud_en.common.hw, 0x0, 0x100, BIT(5), + CLK_IGNORE_UNUSED, SPRD_GATE_NON_AON); +static SPRD_SC_GATE_CLK_HW(audcp_tmr1_eb, "audcp-tmr1-eb", + &access_aud_en.common.hw, 0x0, 0x100, BIT(6), + CLK_IGNORE_UNUSED, SPRD_GATE_NON_AON); + +static struct sprd_clk_common *ums512_audcpapb_gate[] = { + /* address base is 0x3350d000 */ + &audcp_wdg_eb.common, + &audcp_rtc_wdg_eb.common, + &audcp_tmr0_eb.common, + &audcp_tmr1_eb.common, +}; + +static struct clk_hw_onecell_data ums512_audcpapb_gate_hws = { + .hws = { + [CLK_AUDCP_WDG_EB] = &audcp_wdg_eb.common.hw, + [CLK_AUDCP_RTC_WDG_EB] = &audcp_rtc_wdg_eb.common.hw, + [CLK_AUDCP_TMR0_EB] = &audcp_tmr0_eb.common.hw, + [CLK_AUDCP_TMR1_EB] = &audcp_tmr1_eb.common.hw, + }, + .num = CLK_AUDCP_APB_GATE_NUM, +}; + +static const struct sprd_clk_desc ums512_audcpapb_gate_desc = { + .clk_clks = ums512_audcpapb_gate, + .num_clk_clks = ARRAY_SIZE(ums512_audcpapb_gate), + .hw_clks = &ums512_audcpapb_gate_hws, +}; + +/* audcp ahb gates */ +/* Audcp aphb clocks configure CLK_IGNORE_UNUSED because these clocks may be + * controlled by audcp sys at the same time. It may cause an exception if + * kernel gates these clock. + */ +static SPRD_SC_GATE_CLK_HW(audcp_iis0_eb, "audcp-iis0-eb", + &access_aud_en.common.hw, 0x0, 0x100, BIT(0), + CLK_IGNORE_UNUSED, SPRD_GATE_NON_AON); +static SPRD_SC_GATE_CLK_HW(audcp_iis1_eb, "audcp-iis1-eb", + &access_aud_en.common.hw, 0x0, 0x100, BIT(1), + CLK_IGNORE_UNUSED, SPRD_GATE_NON_AON); +static SPRD_SC_GATE_CLK_HW(audcp_iis2_eb, "audcp-iis2-eb", + &access_aud_en.common.hw, 0x0, 0x100, BIT(2), + CLK_IGNORE_UNUSED, SPRD_GATE_NON_AON); +static SPRD_SC_GATE_CLK_HW(audcp_uart_eb, "audcp-uart-eb", + &access_aud_en.common.hw, 0x0, 0x100, BIT(4), + CLK_IGNORE_UNUSED, SPRD_GATE_NON_AON); +static SPRD_SC_GATE_CLK_HW(audcp_dma_cp_eb, "audcp-dma-cp-eb", + &access_aud_en.common.hw, 0x0, 0x100, BIT(5), + CLK_IGNORE_UNUSED, SPRD_GATE_NON_AON); +static SPRD_SC_GATE_CLK_HW(audcp_dma_ap_eb, "audcp-dma-ap-eb", + &access_aud_en.common.hw, 0x0, 0x100, BIT(6), + CLK_IGNORE_UNUSED, SPRD_GATE_NON_AON); +static SPRD_SC_GATE_CLK_HW(audcp_src48k_eb, "audcp-src48k-eb", + &access_aud_en.common.hw, 0x0, 0x100, BIT(10), + CLK_IGNORE_UNUSED, SPRD_GATE_NON_AON); +static SPRD_SC_GATE_CLK_HW(audcp_mcdt_eb, "audcp-mcdt-eb", + &access_aud_en.common.hw, 0x0, 0x100, BIT(12), + CLK_IGNORE_UNUSED, SPRD_GATE_NON_AON); +static SPRD_SC_GATE_CLK_HW(audcp_vbcifd_eb, "audcp-vbcifd-eb", + &access_aud_en.common.hw, 0x0, 0x100, BIT(13), + CLK_IGNORE_UNUSED, SPRD_GATE_NON_AON); +static SPRD_SC_GATE_CLK_HW(audcp_vbc_eb, "audcp-vbc-eb", + &access_aud_en.common.hw, 0x0, 0x100, BIT(14), + CLK_IGNORE_UNUSED, SPRD_GATE_NON_AON); +static SPRD_SC_GATE_CLK_HW(audcp_splk_eb, "audcp-splk-eb", + &access_aud_en.common.hw, 0x0, 0x100, BIT(15), + CLK_IGNORE_UNUSED, SPRD_GATE_NON_AON); +static SPRD_SC_GATE_CLK_HW(audcp_icu_eb, "audcp-icu-eb", + &access_aud_en.common.hw, 0x0, 0x100, BIT(16), + CLK_IGNORE_UNUSED, SPRD_GATE_NON_AON); +static SPRD_SC_GATE_CLK_HW(dma_ap_ashb_eb, "dma-ap-ashb-eb", + &access_aud_en.common.hw, 0x0, 0x100, BIT(17), + CLK_IGNORE_UNUSED, SPRD_GATE_NON_AON); +static SPRD_SC_GATE_CLK_HW(dma_cp_ashb_eb, "dma-cp-ashb-eb", + &access_aud_en.common.hw, 0x0, 0x100, BIT(18), + CLK_IGNORE_UNUSED, SPRD_GATE_NON_AON); +static SPRD_SC_GATE_CLK_HW(audcp_aud_eb, "audcp-aud-eb", + &access_aud_en.common.hw, 0x0, 0x100, BIT(19), + CLK_IGNORE_UNUSED, SPRD_GATE_NON_AON); +static SPRD_SC_GATE_CLK_HW(audcp_vbc_24m_eb, "audcp-vbc-24m-eb", + &access_aud_en.common.hw, 0x0, 0x100, BIT(21), + CLK_IGNORE_UNUSED, SPRD_GATE_NON_AON); +static SPRD_SC_GATE_CLK_HW(audcp_tmr_26m_eb, "audcp-tmr-26m-eb", + &access_aud_en.common.hw, 0x0, 0x100, BIT(22), + CLK_IGNORE_UNUSED, SPRD_GATE_NON_AON); +static SPRD_SC_GATE_CLK_HW(audcp_dvfs_ashb_eb, "audcp-dvfs-ashb-eb", + &access_aud_en.common.hw, 0x0, 0x100, BIT(23), + CLK_IGNORE_UNUSED, SPRD_GATE_NON_AON); + +static struct sprd_clk_common *ums512_audcpahb_gate[] = { + /* address base is 0x335e0000 */ + &audcp_iis0_eb.common, + &audcp_iis1_eb.common, + &audcp_iis2_eb.common, + &audcp_uart_eb.common, + &audcp_dma_cp_eb.common, + &audcp_dma_ap_eb.common, + &audcp_src48k_eb.common, + &audcp_mcdt_eb.common, + &audcp_vbcifd_eb.common, + &audcp_vbc_eb.common, + &audcp_splk_eb.common, + &audcp_icu_eb.common, + &dma_ap_ashb_eb.common, + &dma_cp_ashb_eb.common, + &audcp_aud_eb.common, + &audcp_vbc_24m_eb.common, + &audcp_tmr_26m_eb.common, + &audcp_dvfs_ashb_eb.common, +}; + +static struct clk_hw_onecell_data ums512_audcpahb_gate_hws = { + .hws = { + [CLK_AUDCP_IIS0_EB] = &audcp_iis0_eb.common.hw, + [CLK_AUDCP_IIS1_EB] = &audcp_iis1_eb.common.hw, + [CLK_AUDCP_IIS2_EB] = &audcp_iis2_eb.common.hw, + [CLK_AUDCP_UART_EB] = &audcp_uart_eb.common.hw, + [CLK_AUDCP_DMA_CP_EB] = &audcp_dma_cp_eb.common.hw, + [CLK_AUDCP_DMA_AP_EB] = &audcp_dma_ap_eb.common.hw, + [CLK_AUDCP_SRC48K_EB] = &audcp_src48k_eb.common.hw, + [CLK_AUDCP_MCDT_EB] = &audcp_mcdt_eb.common.hw, + [CLK_AUDCP_VBCIFD_EB] = &audcp_vbcifd_eb.common.hw, + [CLK_AUDCP_VBC_EB] = &audcp_vbc_eb.common.hw, + [CLK_AUDCP_SPLK_EB] = &audcp_splk_eb.common.hw, + [CLK_AUDCP_ICU_EB] = &audcp_icu_eb.common.hw, + [CLK_AUDCP_DMA_AP_ASHB_EB] = &dma_ap_ashb_eb.common.hw, + [CLK_AUDCP_DMA_CP_ASHB_EB] = &dma_cp_ashb_eb.common.hw, + [CLK_AUDCP_AUD_EB] = &audcp_aud_eb.common.hw, + [CLK_AUDCP_VBC_24M_EB] = &audcp_vbc_24m_eb.common.hw, + [CLK_AUDCP_TMR_26M_EB] = &audcp_tmr_26m_eb.common.hw, + [CLK_AUDCP_DVFS_ASHB_EB] = &audcp_dvfs_ashb_eb.common.hw, + }, + .num = CLK_AUDCP_AHB_GATE_NUM, +}; + +static const struct sprd_clk_desc ums512_audcpahb_gate_desc = { + .clk_clks = ums512_audcpahb_gate, + .num_clk_clks = ARRAY_SIZE(ums512_audcpahb_gate), + .hw_clks = &ums512_audcpahb_gate_hws, +}; + +/* gpu clocks */ +static SPRD_GATE_CLK_HW(gpu_core_gate, "gpu-core-gate", &gpu_eb.common.hw, + 0x4, BIT(0), 0, 0); + +static const struct clk_parent_data gpu_parents[] = { + { .fw_name = "ext-26m" }, + { .hw = &twpll_384m.hw }, + { .hw = &twpll_512m.hw }, + { .hw = &lpll_614m4.hw }, + { .hw = &twpll_768m.hw }, + { .hw = &gpll.common.hw }, +}; + +static SPRD_COMP_CLK_DATA(gpu_core_clk, "gpu-core-clk", gpu_parents, + 0x4, 4, 3, 8, 3, 0); + +static SPRD_GATE_CLK_HW(gpu_mem_gate, "gpu-mem-gate", &gpu_eb.common.hw, + 0x8, BIT(0), 0, 0); + +static SPRD_COMP_CLK_DATA(gpu_mem_clk, "gpu-mem-clk", gpu_parents, + 0x8, 4, 3, 8, 3, 0); + +static SPRD_GATE_CLK_HW(gpu_sys_gate, "gpu-sys-gate", &gpu_eb.common.hw, + 0xc, BIT(0), 0, 0); + +static SPRD_DIV_CLK_HW(gpu_sys_clk, "gpu-sys-clk", &gpu_eb.common.hw, + 0xc, 4, 3, 0); + +static struct sprd_clk_common *ums512_gpu_clk[] = { + /* address base is 0x60100000 */ + &gpu_core_gate.common, + &gpu_core_clk.common, + &gpu_mem_gate.common, + &gpu_mem_clk.common, + &gpu_sys_gate.common, + &gpu_sys_clk.common, +}; + +static struct clk_hw_onecell_data ums512_gpu_clk_hws = { + .hws = { + [CLK_GPU_CORE_EB] = &gpu_core_gate.common.hw, + [CLK_GPU_CORE] = &gpu_core_clk.common.hw, + [CLK_GPU_MEM_EB] = &gpu_mem_gate.common.hw, + [CLK_GPU_MEM] = &gpu_mem_clk.common.hw, + [CLK_GPU_SYS_EB] = &gpu_sys_gate.common.hw, + [CLK_GPU_SYS] = &gpu_sys_clk.common.hw, + }, + .num = CLK_GPU_CLK_NUM, +}; + +static struct sprd_clk_desc ums512_gpu_clk_desc = { + .clk_clks = ums512_gpu_clk, + .num_clk_clks = ARRAY_SIZE(ums512_gpu_clk), + .hw_clks = &ums512_gpu_clk_hws, +}; + +/* mm clocks */ +static const struct clk_parent_data mm_ahb_parents[] = { + { .fw_name = "ext-26m" }, + { .hw = &twpll_96m.hw }, + { .hw = &twpll_128m.hw }, + { .hw = &twpll_153m6.hw }, +}; +static SPRD_MUX_CLK_DATA(mm_ahb_clk, "mm-ahb-clk", mm_ahb_parents, + 0x20, 0, 2, UMS512_MUX_FLAG); + +static const struct clk_parent_data mm_mtx_parents[] = { + { .hw = &twpll_76m8.hw }, + { .hw = &twpll_128m.hw }, + { .hw = &twpll_256m.hw }, + { .hw = &twpll_307m2.hw }, + { .hw = &twpll_384m.hw }, + { .hw = &isppll_468m.hw }, + { .hw = &twpll_512m.hw }, +}; +static SPRD_MUX_CLK_DATA(mm_mtx_clk, "mm-mtx-clk", mm_mtx_parents, + 0x24, 0, 3, UMS512_MUX_FLAG); + +static const struct clk_parent_data sensor_parents[] = { + { .fw_name = "ext-26m" }, + { .hw = &twpll_48m.hw }, + { .hw = &twpll_76m8.hw }, + { .hw = &twpll_96m.hw }, +}; +static SPRD_COMP_CLK_DATA(sensor0_clk, "sensor0-clk", sensor_parents, + 0x28, 0, 2, 8, 3, 0); +static SPRD_COMP_CLK_DATA(sensor1_clk, "sensor1-clk", sensor_parents, + 0x2c, 0, 2, 8, 3, 0); +static SPRD_COMP_CLK_DATA(sensor2_clk, "sensor2-clk", sensor_parents, + 0x30, 0, 2, 8, 3, 0); + +static const struct clk_parent_data cpp_parents[] = { + { .hw = &twpll_76m8.hw }, + { .hw = &twpll_128m.hw }, + { .hw = &twpll_256m.hw }, + { .hw = &twpll_384m.hw }, +}; +static SPRD_MUX_CLK_DATA(cpp_clk, "cpp-clk", cpp_parents, + 0x34, 0, 2, UMS512_MUX_FLAG); + +static const struct clk_parent_data jpg_parents[] = { + { .hw = &twpll_76m8.hw }, + { .hw = &twpll_128m.hw }, + { .hw = &twpll_256m.hw }, + { .hw = &twpll_384m.hw }, +}; +static SPRD_MUX_CLK_DATA(jpg_clk, "jpg-clk", jpg_parents, + 0x38, 0, 2, UMS512_MUX_FLAG); + +static const struct clk_parent_data fd_parents[] = { + { .hw = &twpll_76m8.hw }, + { .hw = &twpll_192m.hw }, + { .hw = &twpll_307m2.hw }, + { .hw = &twpll_384m.hw }, +}; +static SPRD_MUX_CLK_DATA(fd_clk, "fd-clk", fd_parents, + 0x3c, 0, 2, UMS512_MUX_FLAG); + +static const struct clk_parent_data dcam_if_parents[] = { + { .hw = &twpll_192m.hw }, + { .hw = &twpll_256m.hw }, + { .hw = &twpll_307m2.hw }, + { .hw = &twpll_384m.hw }, + { .hw = &isppll_468m.hw }, +}; +static SPRD_MUX_CLK_DATA(dcam_if_clk, "dcam-if-clk", dcam_if_parents, + 0x40, 0, 3, UMS512_MUX_FLAG); + +static const struct clk_parent_data dcam_axi_parents[] = { + { .hw = &twpll_256m.hw }, + { .hw = &twpll_307m2.hw }, + { .hw = &twpll_384m.hw }, + { .hw = &isppll_468m.hw }, +}; +static SPRD_MUX_CLK_DATA(dcam_axi_clk, "dcam-axi-clk", dcam_axi_parents, + 0x44, 0, 2, UMS512_MUX_FLAG); + +static const struct clk_parent_data isp_parents[] = { + { .hw = &twpll_256m.hw }, + { .hw = &twpll_307m2.hw }, + { .hw = &twpll_384m.hw }, + { .hw = &isppll_468m.hw }, + { .hw = &twpll_512m.hw }, +}; +static SPRD_MUX_CLK_DATA(isp_clk, "isp-clk", isp_parents, + 0x48, 0, 3, UMS512_MUX_FLAG); + +static SPRD_GATE_CLK_HW(mipi_csi0, "mipi-csi0", &mm_eb.common.hw, + 0x4c, BIT(16), CLK_IGNORE_UNUSED, 0); + +static SPRD_GATE_CLK_HW(mipi_csi1, "mipi-csi1", &mm_eb.common.hw, + 0x50, BIT(16), CLK_IGNORE_UNUSED, 0); + +static SPRD_GATE_CLK_HW(mipi_csi2, "mipi-csi2", &mm_eb.common.hw, + 0x54, BIT(16), CLK_IGNORE_UNUSED, 0); + +static struct sprd_clk_common *ums512_mm_clk[] = { + /* address base is 0x62100000 */ + &mm_ahb_clk.common, + &mm_mtx_clk.common, + &sensor0_clk.common, + &sensor1_clk.common, + &sensor2_clk.common, + &cpp_clk.common, + &jpg_clk.common, + &fd_clk.common, + &dcam_if_clk.common, + &dcam_axi_clk.common, + &isp_clk.common, + &mipi_csi0.common, + &mipi_csi1.common, + &mipi_csi2.common, +}; + +static struct clk_hw_onecell_data ums512_mm_clk_hws = { + .hws = { + [CLK_MM_AHB] = &mm_ahb_clk.common.hw, + [CLK_MM_MTX] = &mm_mtx_clk.common.hw, + [CLK_SENSOR0] = &sensor0_clk.common.hw, + [CLK_SENSOR1] = &sensor1_clk.common.hw, + [CLK_SENSOR2] = &sensor2_clk.common.hw, + [CLK_CPP] = &cpp_clk.common.hw, + [CLK_JPG] = &jpg_clk.common.hw, + [CLK_FD] = &fd_clk.common.hw, + [CLK_DCAM_IF] = &dcam_if_clk.common.hw, + [CLK_DCAM_AXI] = &dcam_axi_clk.common.hw, + [CLK_ISP] = &isp_clk.common.hw, + [CLK_MIPI_CSI0] = &mipi_csi0.common.hw, + [CLK_MIPI_CSI1] = &mipi_csi1.common.hw, + [CLK_MIPI_CSI2] = &mipi_csi2.common.hw, + }, + .num = CLK_MM_CLK_NUM, +}; + +static struct sprd_clk_desc ums512_mm_clk_desc = { + .clk_clks = ums512_mm_clk, + .num_clk_clks = ARRAY_SIZE(ums512_mm_clk), + .hw_clks = &ums512_mm_clk_hws, +}; + +/* mm gate clocks */ +static SPRD_SC_GATE_CLK_HW(mm_cpp_eb, "mm-cpp-eb", &mm_eb.common.hw, + 0x0, 0x1000, BIT(0), 0, 0); +static SPRD_SC_GATE_CLK_HW(mm_jpg_eb, "mm-jpg-eb", &mm_eb.common.hw, + 0x0, 0x1000, BIT(1), 0, 0); +static SPRD_SC_GATE_CLK_HW(mm_dcam_eb, "mm-dcam-eb", &mm_eb.common.hw, + 0x0, 0x1000, BIT(2), 0, 0); +static SPRD_SC_GATE_CLK_HW(mm_isp_eb, "mm-isp-eb", &mm_eb.common.hw, + 0x0, 0x1000, BIT(3), 0, 0); +static SPRD_SC_GATE_CLK_HW(mm_csi2_eb, "mm-csi2-eb", &mm_eb.common.hw, + 0x0, 0x1000, BIT(4), 0, 0); +static SPRD_SC_GATE_CLK_HW(mm_csi1_eb, "mm-csi1-eb", &mm_eb.common.hw, + 0x0, 0x1000, BIT(5), 0, 0); +static SPRD_SC_GATE_CLK_HW(mm_csi0_eb, "mm-csi0-eb", &mm_eb.common.hw, + 0x0, 0x1000, BIT(6), 0, 0); +static SPRD_SC_GATE_CLK_HW(mm_ckg_eb, "mm-ckg-eb", &mm_eb.common.hw, + 0x0, 0x1000, BIT(7), 0, 0); +static SPRD_SC_GATE_CLK_HW(mm_isp_ahb_eb, "mm-isp-ahb-eb", &mm_eb.common.hw, + 0x0, 0x1000, BIT(8), 0, 0); +static SPRD_SC_GATE_CLK_HW(mm_dvfs_eb, "mm-dvfs-eb", &mm_eb.common.hw, + 0x0, 0x1000, BIT(9), 0, 0); +static SPRD_SC_GATE_CLK_HW(mm_fd_eb, "mm-fd-eb", &mm_eb.common.hw, + 0x0, 0x1000, BIT(10), 0, 0); +static SPRD_SC_GATE_CLK_HW(mm_sensor2_en, "mm-sensor2-en", &mm_eb.common.hw, + 0x8, 0x1000, BIT(0), 0, 0); +static SPRD_SC_GATE_CLK_HW(mm_sensor1_en, "mm-sensor1-en", &mm_eb.common.hw, + 0x8, 0x1000, BIT(1), 0, 0); +static SPRD_SC_GATE_CLK_HW(mm_sensor0_en, "mm-sensor0-en", &mm_eb.common.hw, + 0x8, 0x1000, BIT(2), 0, 0); +static SPRD_SC_GATE_CLK_HW(mm_mipi_csi2_en, "mm-mipi-csi2-en", &mm_eb.common.hw, + 0x8, 0x1000, BIT(3), 0, 0); +static SPRD_SC_GATE_CLK_HW(mm_mipi_csi1_en, "mm-mipi-csi1-en", &mm_eb.common.hw, + 0x8, 0x1000, BIT(4), 0, 0); +static SPRD_SC_GATE_CLK_HW(mm_mipi_csi0_en, "mm-mipi-csi0-en", &mm_eb.common.hw, + 0x8, 0x1000, BIT(5), 0, 0); +static SPRD_SC_GATE_CLK_HW(mm_dcam_axi_en, "mm-dcam-axi-en", &mm_eb.common.hw, + 0x8, 0x1000, BIT(6), 0, 0); +static SPRD_SC_GATE_CLK_HW(mm_isp_axi_en, "mm-isp-axi-en", &mm_eb.common.hw, + 0x8, 0x1000, BIT(7), 0, 0); +static SPRD_SC_GATE_CLK_HW(mm_cphy_en, "mm-cphy-en", &mm_eb.common.hw, + 0x8, 0x1000, BIT(8), 0, 0); + +static struct sprd_clk_common *ums512_mm_gate_clk[] = { + /* address base is 0x62200000 */ + &mm_cpp_eb.common, + &mm_jpg_eb.common, + &mm_dcam_eb.common, + &mm_isp_eb.common, + &mm_csi2_eb.common, + &mm_csi1_eb.common, + &mm_csi0_eb.common, + &mm_ckg_eb.common, + &mm_isp_ahb_eb.common, + &mm_dvfs_eb.common, + &mm_fd_eb.common, + &mm_sensor2_en.common, + &mm_sensor1_en.common, + &mm_sensor0_en.common, + &mm_mipi_csi2_en.common, + &mm_mipi_csi1_en.common, + &mm_mipi_csi0_en.common, + &mm_dcam_axi_en.common, + &mm_isp_axi_en.common, + &mm_cphy_en.common, +}; + +static struct clk_hw_onecell_data ums512_mm_gate_clk_hws = { + .hws = { + [CLK_MM_CPP_EB] = &mm_cpp_eb.common.hw, + [CLK_MM_JPG_EB] = &mm_jpg_eb.common.hw, + [CLK_MM_DCAM_EB] = &mm_dcam_eb.common.hw, + [CLK_MM_ISP_EB] = &mm_isp_eb.common.hw, + [CLK_MM_CSI2_EB] = &mm_csi2_eb.common.hw, + [CLK_MM_CSI1_EB] = &mm_csi1_eb.common.hw, + [CLK_MM_CSI0_EB] = &mm_csi0_eb.common.hw, + [CLK_MM_CKG_EB] = &mm_ckg_eb.common.hw, + [CLK_ISP_AHB_EB] = &mm_isp_ahb_eb.common.hw, + [CLK_MM_DVFS_EB] = &mm_dvfs_eb.common.hw, + [CLK_MM_FD_EB] = &mm_fd_eb.common.hw, + [CLK_MM_SENSOR2_EB] = &mm_sensor2_en.common.hw, + [CLK_MM_SENSOR1_EB] = &mm_sensor1_en.common.hw, + [CLK_MM_SENSOR0_EB] = &mm_sensor0_en.common.hw, + [CLK_MM_MIPI_CSI2_EB] = &mm_mipi_csi2_en.common.hw, + [CLK_MM_MIPI_CSI1_EB] = &mm_mipi_csi1_en.common.hw, + [CLK_MM_MIPI_CSI0_EB] = &mm_mipi_csi0_en.common.hw, + [CLK_DCAM_AXI_EB] = &mm_dcam_axi_en.common.hw, + [CLK_ISP_AXI_EB] = &mm_isp_axi_en.common.hw, + [CLK_MM_CPHY_EB] = &mm_cphy_en.common.hw, + }, + .num = CLK_MM_GATE_CLK_NUM, +}; + +static struct sprd_clk_desc ums512_mm_gate_clk_desc = { + .clk_clks = ums512_mm_gate_clk, + .num_clk_clks = ARRAY_SIZE(ums512_mm_gate_clk), + .hw_clks = &ums512_mm_gate_clk_hws, +}; + +/* ap apb gates */ +static SPRD_SC_GATE_CLK_FW_NAME(sim0_eb, "sim0-eb", "ext-26m", + 0x0, 0x1000, BIT(0), 0, 0); +static SPRD_SC_GATE_CLK_FW_NAME(iis0_eb, "iis0-eb", "ext-26m", + 0x0, 0x1000, BIT(1), 0, 0); +static SPRD_SC_GATE_CLK_FW_NAME(iis1_eb, "iis1-eb", "ext-26m", + 0x0, 0x1000, BIT(2), 0, 0); +static SPRD_SC_GATE_CLK_FW_NAME(iis2_eb, "iis2-eb", "ext-26m", + 0x0, 0x1000, BIT(3), 0, 0); +static SPRD_SC_GATE_CLK_FW_NAME(apb_reg_eb, "apb-reg-eb", "ext-26m", + 0x0, 0x1000, BIT(4), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK_FW_NAME(spi0_eb, "spi0-eb", "ext-26m", + 0x0, 0x1000, BIT(5), 0, 0); +static SPRD_SC_GATE_CLK_FW_NAME(spi1_eb, "spi1-eb", "ext-26m", + 0x0, 0x1000, BIT(6), 0, 0); +static SPRD_SC_GATE_CLK_FW_NAME(spi2_eb, "spi2-eb", "ext-26m", + 0x0, 0x1000, BIT(7), 0, 0); +static SPRD_SC_GATE_CLK_FW_NAME(spi3_eb, "spi3-eb", "ext-26m", + 0x0, 0x1000, BIT(8), 0, 0); +static SPRD_SC_GATE_CLK_FW_NAME(i2c0_eb, "i2c0-eb", "ext-26m", + 0x0, 0x1000, BIT(9), 0, 0); +static SPRD_SC_GATE_CLK_FW_NAME(i2c1_eb, "i2c1-eb", "ext-26m", + 0x0, 0x1000, BIT(10), 0, 0); +static SPRD_SC_GATE_CLK_FW_NAME(i2c2_eb, "i2c2-eb", "ext-26m", + 0x0, 0x1000, BIT(11), 0, 0); +static SPRD_SC_GATE_CLK_FW_NAME(i2c3_eb, "i2c3-eb", "ext-26m", + 0x0, 0x1000, BIT(12), 0, 0); +static SPRD_SC_GATE_CLK_FW_NAME(i2c4_eb, "i2c4-eb", "ext-26m", + 0x0, 0x1000, BIT(13), 0, 0); +static SPRD_SC_GATE_CLK_FW_NAME(uart0_eb, "uart0-eb", "ext-26m", + 0x0, 0x1000, BIT(14), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK_FW_NAME(uart1_eb, "uart1-eb", "ext-26m", + 0x0, 0x1000, BIT(15), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK_FW_NAME(uart2_eb, "uart2-eb", "ext-26m", + 0x0, 0x1000, BIT(16), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK_FW_NAME(sim0_32k_eb, "sim0-32k-eb", "ext-26m", + 0x0, 0x1000, BIT(17), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK_FW_NAME(spi0_lfin_eb, "spi0-lfin-eb", "ext-26m", + 0x0, 0x1000, BIT(18), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK_FW_NAME(spi1_lfin_eb, "spi1-lfin-eb", "ext-26m", + 0x0, 0x1000, BIT(19), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK_FW_NAME(spi2_lfin_eb, "spi2-lfin-eb", "ext-26m", + 0x0, 0x1000, BIT(20), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK_FW_NAME(spi3_lfin_eb, "spi3-lfin-eb", "ext-26m", + 0x0, 0x1000, BIT(21), CLK_IGNORE_UNUSED, 0); +static SPRD_SC_GATE_CLK_FW_NAME(sdio0_eb, "sdio0-eb", "ext-26m", + 0x0, 0x1000, BIT(22), 0, 0); +static SPRD_SC_GATE_CLK_FW_NAME(sdio1_eb, "sdio1-eb", "ext-26m", + 0x0, 0x1000, BIT(23), 0, 0); +static SPRD_SC_GATE_CLK_FW_NAME(sdio2_eb, "sdio2-eb", "ext-26m", + 0x0, 0x1000, BIT(24), 0, 0); +static SPRD_SC_GATE_CLK_FW_NAME(emmc_eb, "emmc-eb", "ext-26m", + 0x0, 0x1000, BIT(25), 0, 0); +static SPRD_SC_GATE_CLK_FW_NAME(sdio0_32k_eb, "sdio0-32k-eb", "ext-26m", + 0x0, 0x1000, BIT(26), 0, 0); +static SPRD_SC_GATE_CLK_FW_NAME(sdio1_32k_eb, "sdio1-32k-eb", "ext-26m", + 0x0, 0x1000, BIT(27), 0, 0); +static SPRD_SC_GATE_CLK_FW_NAME(sdio2_32k_eb, "sdio2-32k-eb", "ext-26m", + 0x0, 0x1000, BIT(28), 0, 0); +static SPRD_SC_GATE_CLK_FW_NAME(emmc_32k_eb, "emmc-32k-eb", "ext-26m", + 0x0, 0x1000, BIT(29), 0, 0); + +static struct sprd_clk_common *ums512_apapb_gate[] = { + /* address base is 0x71000000 */ + &sim0_eb.common, + &iis0_eb.common, + &iis1_eb.common, + &iis2_eb.common, + &apb_reg_eb.common, + &spi0_eb.common, + &spi1_eb.common, + &spi2_eb.common, + &spi3_eb.common, + &i2c0_eb.common, + &i2c1_eb.common, + &i2c2_eb.common, + &i2c3_eb.common, + &i2c4_eb.common, + &uart0_eb.common, + &uart1_eb.common, + &uart2_eb.common, + &sim0_32k_eb.common, + &spi0_lfin_eb.common, + &spi1_lfin_eb.common, + &spi2_lfin_eb.common, + &spi3_lfin_eb.common, + &sdio0_eb.common, + &sdio1_eb.common, + &sdio2_eb.common, + &emmc_eb.common, + &sdio0_32k_eb.common, + &sdio1_32k_eb.common, + &sdio2_32k_eb.common, + &emmc_32k_eb.common, +}; + +static struct clk_hw_onecell_data ums512_apapb_gate_hws = { + .hws = { + [CLK_SIM0_EB] = &sim0_eb.common.hw, + [CLK_IIS0_EB] = &iis0_eb.common.hw, + [CLK_IIS1_EB] = &iis1_eb.common.hw, + [CLK_IIS2_EB] = &iis2_eb.common.hw, + [CLK_APB_REG_EB] = &apb_reg_eb.common.hw, + [CLK_SPI0_EB] = &spi0_eb.common.hw, + [CLK_SPI1_EB] = &spi1_eb.common.hw, + [CLK_SPI2_EB] = &spi2_eb.common.hw, + [CLK_SPI3_EB] = &spi3_eb.common.hw, + [CLK_I2C0_EB] = &i2c0_eb.common.hw, + [CLK_I2C1_EB] = &i2c1_eb.common.hw, + [CLK_I2C2_EB] = &i2c2_eb.common.hw, + [CLK_I2C3_EB] = &i2c3_eb.common.hw, + [CLK_I2C4_EB] = &i2c4_eb.common.hw, + [CLK_UART0_EB] = &uart0_eb.common.hw, + [CLK_UART1_EB] = &uart1_eb.common.hw, + [CLK_UART2_EB] = &uart2_eb.common.hw, + [CLK_SIM0_32K_EB] = &sim0_32k_eb.common.hw, + [CLK_SPI0_LFIN_EB] = &spi0_lfin_eb.common.hw, + [CLK_SPI1_LFIN_EB] = &spi1_lfin_eb.common.hw, + [CLK_SPI2_LFIN_EB] = &spi2_lfin_eb.common.hw, + [CLK_SPI3_LFIN_EB] = &spi3_lfin_eb.common.hw, + [CLK_SDIO0_EB] = &sdio0_eb.common.hw, + [CLK_SDIO1_EB] = &sdio1_eb.common.hw, + [CLK_SDIO2_EB] = &sdio2_eb.common.hw, + [CLK_EMMC_EB] = &emmc_eb.common.hw, + [CLK_SDIO0_32K_EB] = &sdio0_32k_eb.common.hw, + [CLK_SDIO1_32K_EB] = &sdio1_32k_eb.common.hw, + [CLK_SDIO2_32K_EB] = &sdio2_32k_eb.common.hw, + [CLK_EMMC_32K_EB] = &emmc_32k_eb.common.hw, + }, + .num = CLK_AP_APB_GATE_NUM, +}; + +static struct sprd_clk_desc ums512_apapb_gate_desc = { + .clk_clks = ums512_apapb_gate, + .num_clk_clks = ARRAY_SIZE(ums512_apapb_gate), + .hw_clks = &ums512_apapb_gate_hws, +}; + +static const struct of_device_id sprd_ums512_clk_ids[] = { + { .compatible = "sprd,ums512-pmu-gate", /* 0x327e0000 */ + .data = &ums512_pmu_gate_desc }, + { .compatible = "sprd,ums512-g0-pll", /* 0x32390000 */ + .data = &ums512_g0_pll_desc }, + { .compatible = "sprd,ums512-g2-pll", /* 0x323b0000 */ + .data = &ums512_g2_pll_desc }, + { .compatible = "sprd,ums512-g3-pll", /* 0x323c0000 */ + .data = &ums512_g3_pll_desc }, + { .compatible = "sprd,ums512-gc-pll", /* 0x323e0000 */ + .data = &ums512_gc_pll_desc }, + { .compatible = "sprd,ums512-apahb-gate", /* 0x20100000 */ + .data = &ums512_apahb_gate_desc }, + { .compatible = "sprd,ums512-ap-clk", /* 0x20200000 */ + .data = &ums512_ap_clk_desc }, + { .compatible = "sprd,ums512-aonapb-clk", /* 0x32080200 */ + .data = &ums512_aon_apb_desc }, + { .compatible = "sprd,ums512-aon-gate", /* 0x327d0000 */ + .data = &ums512_aon_gate_desc }, + { .compatible = "sprd,ums512-audcpapb-gate", /* 0x3350d000 */ + .data = &ums512_audcpapb_gate_desc }, + { .compatible = "sprd,ums512-audcpahb-gate", /* 0x335e0000 */ + .data = &ums512_audcpahb_gate_desc }, + { .compatible = "sprd,ums512-gpu-clk", /* 0x60100000 */ + .data = &ums512_gpu_clk_desc }, + { .compatible = "sprd,ums512-mm-clk", /* 0x62100000 */ + .data = &ums512_mm_clk_desc }, + { .compatible = "sprd,ums512-mm-gate-clk", /* 0x62200000 */ + .data = &ums512_mm_gate_clk_desc }, + { .compatible = "sprd,ums512-apapb-gate", /* 0x71000000 */ + .data = &ums512_apapb_gate_desc }, + { } +}; +MODULE_DEVICE_TABLE(of, sprd_ums512_clk_ids); + +static int ums512_clk_probe(struct platform_device *pdev) +{ + const struct sprd_clk_desc *desc; + int ret; + + desc = device_get_match_data(&pdev->dev); + if (!desc) + return -ENODEV; + + ret = sprd_clk_regmap_init(pdev, desc); + if (ret) + return ret; + + return sprd_clk_probe(&pdev->dev, desc->hw_clks); +} + +static struct platform_driver ums512_clk_driver = { + .probe = ums512_clk_probe, + .driver = { + .name = "ums512-clk", + .of_match_table = sprd_ums512_clk_ids, + }, +}; +module_platform_driver(ums512_clk_driver); + +MODULE_DESCRIPTION("Unisoc UMS512 Clock Driver"); +MODULE_LICENSE("GPL"); |
