diff options
Diffstat (limited to 'drivers')
476 files changed, 34431 insertions, 9892 deletions
diff --git a/drivers/Makefile b/drivers/Makefile index a104163b1353..8e1ffa4358d5 100644 --- a/drivers/Makefile +++ b/drivers/Makefile @@ -161,7 +161,7 @@ obj-$(CONFIG_SOUNDWIRE) += soundwire/ # Virtualization drivers obj-$(CONFIG_VIRT_DRIVERS) += virt/ -obj-$(subst m,y,$(CONFIG_HYPERV)) += hv/ +obj-$(CONFIG_HYPERV) += hv/ obj-$(CONFIG_PM_DEVFREQ) += devfreq/ obj-$(CONFIG_EXTCON) += extcon/ diff --git a/drivers/acpi/apei/ghes.c b/drivers/acpi/apei/ghes.c index a0d54993edb3..97ee19f2cae0 100644 --- a/drivers/acpi/apei/ghes.c +++ b/drivers/acpi/apei/ghes.c @@ -1207,12 +1207,10 @@ static int ghes_notify_hed(struct notifier_block *this, unsigned long event, int ret = NOTIFY_DONE; spin_lock_irqsave(&ghes_notify_lock_irq, flags); - rcu_read_lock(); list_for_each_entry_rcu(ghes, &ghes_hed, list) { if (!ghes_proc(ghes)) ret = NOTIFY_OK; } - rcu_read_unlock(); spin_unlock_irqrestore(&ghes_notify_lock_irq, flags); return ret; diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c index 6905b56bf3e4..67b76492c839 100644 --- a/drivers/acpi/battery.c +++ b/drivers/acpi/battery.c @@ -92,7 +92,7 @@ enum { struct acpi_battery { struct mutex lock; - struct mutex sysfs_lock; + struct mutex update_lock; struct power_supply *bat; struct power_supply_desc bat_desc; struct acpi_device *device; @@ -904,15 +904,12 @@ static int sysfs_add_battery(struct acpi_battery *battery) static void sysfs_remove_battery(struct acpi_battery *battery) { - mutex_lock(&battery->sysfs_lock); - if (!battery->bat) { - mutex_unlock(&battery->sysfs_lock); + if (!battery->bat) return; - } + battery_hook_remove_battery(battery); power_supply_unregister(battery->bat); battery->bat = NULL; - mutex_unlock(&battery->sysfs_lock); } static void find_battery(const struct dmi_header *dm, void *private) @@ -1072,6 +1069,9 @@ static void acpi_battery_notify(acpi_handle handle, u32 event, void *data) if (!battery) return; + + guard(mutex)(&battery->update_lock); + old = battery->bat; /* * On Acer Aspire V5-573G notifications are sometimes triggered too @@ -1094,21 +1094,22 @@ static void acpi_battery_notify(acpi_handle handle, u32 event, void *data) } static int battery_notify(struct notifier_block *nb, - unsigned long mode, void *_unused) + unsigned long mode, void *_unused) { struct acpi_battery *battery = container_of(nb, struct acpi_battery, pm_nb); - int result; - switch (mode) { - case PM_POST_HIBERNATION: - case PM_POST_SUSPEND: + if (mode == PM_POST_SUSPEND || mode == PM_POST_HIBERNATION) { + guard(mutex)(&battery->update_lock); + if (!acpi_battery_present(battery)) return 0; if (battery->bat) { acpi_battery_refresh(battery); } else { + int result; + result = acpi_battery_get_info(battery); if (result) return result; @@ -1120,7 +1121,6 @@ static int battery_notify(struct notifier_block *nb, acpi_battery_init_alarm(battery); acpi_battery_get_state(battery); - break; } return 0; @@ -1198,6 +1198,8 @@ static int acpi_battery_update_retry(struct acpi_battery *battery) { int retry, ret; + guard(mutex)(&battery->update_lock); + for (retry = 5; retry; retry--) { ret = acpi_battery_update(battery, false); if (!ret) @@ -1208,6 +1210,13 @@ static int acpi_battery_update_retry(struct acpi_battery *battery) return ret; } +static void sysfs_battery_cleanup(struct acpi_battery *battery) +{ + guard(mutex)(&battery->update_lock); + + sysfs_remove_battery(battery); +} + static int acpi_battery_add(struct acpi_device *device) { int result = 0; @@ -1230,7 +1239,7 @@ static int acpi_battery_add(struct acpi_device *device) if (result) return result; - result = devm_mutex_init(&device->dev, &battery->sysfs_lock); + result = devm_mutex_init(&device->dev, &battery->update_lock); if (result) return result; @@ -1262,7 +1271,7 @@ fail_pm: device_init_wakeup(&device->dev, 0); unregister_pm_notifier(&battery->pm_nb); fail: - sysfs_remove_battery(battery); + sysfs_battery_cleanup(battery); return result; } @@ -1281,6 +1290,9 @@ static void acpi_battery_remove(struct acpi_device *device) device_init_wakeup(&device->dev, 0); unregister_pm_notifier(&battery->pm_nb); + + guard(mutex)(&battery->update_lock); + sysfs_remove_battery(battery); } @@ -1297,6 +1309,9 @@ static int acpi_battery_resume(struct device *dev) return -EINVAL; battery->update_time = 0; + + guard(mutex)(&battery->update_lock); + acpi_battery_update(battery, true); return 0; } diff --git a/drivers/acpi/cppc_acpi.c b/drivers/acpi/cppc_acpi.c index 6b649031808f..ab4651205e8a 100644 --- a/drivers/acpi/cppc_acpi.c +++ b/drivers/acpi/cppc_acpi.c @@ -1876,7 +1876,7 @@ EXPORT_SYMBOL_GPL(cppc_set_perf); * If desired_reg is in the SystemMemory or SystemIo ACPI address space, * then assume there is no latency. */ -unsigned int cppc_get_transition_latency(int cpu_num) +int cppc_get_transition_latency(int cpu_num) { /* * Expected transition latency is based on the PCCT timing values @@ -1889,31 +1889,29 @@ unsigned int cppc_get_transition_latency(int cpu_num) * completion of a command before issuing the next command, * in microseconds. */ - unsigned int latency_ns = 0; struct cpc_desc *cpc_desc; struct cpc_register_resource *desired_reg; int pcc_ss_id = per_cpu(cpu_pcc_subspace_idx, cpu_num); struct cppc_pcc_data *pcc_ss_data; + int latency_ns = 0; cpc_desc = per_cpu(cpc_desc_ptr, cpu_num); if (!cpc_desc) - return CPUFREQ_ETERNAL; + return -ENODATA; desired_reg = &cpc_desc->cpc_regs[DESIRED_PERF]; if (CPC_IN_SYSTEM_MEMORY(desired_reg) || CPC_IN_SYSTEM_IO(desired_reg)) return 0; - else if (!CPC_IN_PCC(desired_reg)) - return CPUFREQ_ETERNAL; - if (pcc_ss_id < 0) - return CPUFREQ_ETERNAL; + if (!CPC_IN_PCC(desired_reg) || pcc_ss_id < 0) + return -ENODATA; pcc_ss_data = pcc_data[pcc_ss_id]; if (pcc_ss_data->pcc_mpar) latency_ns = 60 * (1000 * 1000 * 1000 / pcc_ss_data->pcc_mpar); - latency_ns = max(latency_ns, pcc_ss_data->pcc_nominal * 1000); - latency_ns = max(latency_ns, pcc_ss_data->pcc_mrtt * 1000); + latency_ns = max_t(int, latency_ns, pcc_ss_data->pcc_nominal * 1000); + latency_ns = max_t(int, latency_ns, pcc_ss_data->pcc_mrtt * 1000); return latency_ns; } diff --git a/drivers/acpi/nfit/core.c b/drivers/acpi/nfit/core.c index ae035b93da08..3eb56b77cb6d 100644 --- a/drivers/acpi/nfit/core.c +++ b/drivers/acpi/nfit/core.c @@ -2637,7 +2637,7 @@ static int acpi_nfit_register_region(struct acpi_nfit_desc *acpi_desc, if (ndr_desc->target_node == NUMA_NO_NODE) { ndr_desc->target_node = phys_to_target_node(spa->address); dev_info(acpi_desc->dev, "changing target node from %d to %d for nfit region [%pa-%pa]", - NUMA_NO_NODE, ndr_desc->numa_node, &res.start, &res.end); + NUMA_NO_NODE, ndr_desc->target_node, &res.start, &res.end); } /* diff --git a/drivers/acpi/property.c b/drivers/acpi/property.c index b261dbb16230..1b997a5497e7 100644 --- a/drivers/acpi/property.c +++ b/drivers/acpi/property.c @@ -1388,6 +1388,28 @@ struct fwnode_handle *acpi_get_next_subnode(const struct fwnode_handle *fwnode, return NULL; } +/* + * acpi_get_next_present_subnode - Return the next present child node handle + * @fwnode: Firmware node to find the next child node for. + * @child: Handle to one of the device's child nodes or a null handle. + * + * Like acpi_get_next_subnode(), but the device nodes returned by + * acpi_get_next_present_subnode() are guaranteed to be present. + * + * Returns: The fwnode handle of the next present sub-node. + */ +static struct fwnode_handle * +acpi_get_next_present_subnode(const struct fwnode_handle *fwnode, + struct fwnode_handle *child) +{ + do { + child = acpi_get_next_subnode(fwnode, child); + } while (is_acpi_device_node(child) && + !acpi_device_is_present(to_acpi_device_node(child))); + + return child; +} + /** * acpi_node_get_parent - Return parent fwnode of this fwnode * @fwnode: Firmware node whose parent to get @@ -1722,7 +1744,7 @@ static int acpi_fwnode_irq_get(const struct fwnode_handle *fwnode, .property_read_string_array = \ acpi_fwnode_property_read_string_array, \ .get_parent = acpi_node_get_parent, \ - .get_next_child_node = acpi_get_next_subnode, \ + .get_next_child_node = acpi_get_next_present_subnode, \ .get_named_child_node = acpi_fwnode_get_named_child_node, \ .get_name = acpi_fwnode_get_name, \ .get_name_prefix = acpi_fwnode_get_name_prefix, \ diff --git a/drivers/base/Kconfig b/drivers/base/Kconfig index 064eb52ff7e2..1786d87b29e2 100644 --- a/drivers/base/Kconfig +++ b/drivers/base/Kconfig @@ -167,6 +167,12 @@ config PM_QOS_KUNIT_TEST depends on KUNIT=y default KUNIT_ALL_TESTS +config PM_RUNTIME_KUNIT_TEST + tristate "KUnit Tests for runtime PM" if !KUNIT_ALL_TESTS + depends on KUNIT + depends on PM + default KUNIT_ALL_TESTS + config HMEM_REPORTING bool default n diff --git a/drivers/base/base.h b/drivers/base/base.h index 700aecd22fd3..86fa7fbb3548 100644 --- a/drivers/base/base.h +++ b/drivers/base/base.h @@ -248,6 +248,7 @@ void device_links_driver_cleanup(struct device *dev); void device_links_no_driver(struct device *dev); bool device_links_busy(struct device *dev); void device_links_unbind_consumers(struct device *dev); +bool device_link_flag_is_sync_state_only(u32 flags); void fw_devlink_drivers_done(void); void fw_devlink_probing_done(void); diff --git a/drivers/base/core.c b/drivers/base/core.c index fa8093119602..3c533dab8fa5 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c @@ -287,7 +287,7 @@ static bool device_is_ancestor(struct device *dev, struct device *target) #define DL_MARKER_FLAGS (DL_FLAG_INFERRED | \ DL_FLAG_CYCLE | \ DL_FLAG_MANAGED) -static inline bool device_link_flag_is_sync_state_only(u32 flags) +bool device_link_flag_is_sync_state_only(u32 flags) { return (flags & ~DL_MARKER_FLAGS) == DL_FLAG_SYNC_STATE_ONLY; } diff --git a/drivers/base/power/Makefile b/drivers/base/power/Makefile index 01f11629d241..2989e42d0161 100644 --- a/drivers/base/power/Makefile +++ b/drivers/base/power/Makefile @@ -4,5 +4,6 @@ obj-$(CONFIG_PM_SLEEP) += main.o wakeup.o wakeup_stats.o obj-$(CONFIG_PM_TRACE_RTC) += trace.o obj-$(CONFIG_HAVE_CLK) += clock_ops.o obj-$(CONFIG_PM_QOS_KUNIT_TEST) += qos-test.o +obj-$(CONFIG_PM_RUNTIME_KUNIT_TEST) += runtime-test.o ccflags-$(CONFIG_DEBUG_DRIVER) := -DDEBUG diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c index b9a34c3425ec..e83503bdc1fd 100644 --- a/drivers/base/power/main.c +++ b/drivers/base/power/main.c @@ -278,7 +278,8 @@ static void dpm_wait_for_suppliers(struct device *dev, bool async) * walking. */ dev_for_each_link_to_supplier(link, dev) - if (READ_ONCE(link->status) != DL_STATE_DORMANT) + if (READ_ONCE(link->status) != DL_STATE_DORMANT && + !device_link_flag_is_sync_state_only(link->flags)) dpm_wait(link->supplier, async); device_links_read_unlock(idx); @@ -335,7 +336,8 @@ static void dpm_wait_for_consumers(struct device *dev, bool async) * unregistration). */ dev_for_each_link_to_consumer(link, dev) - if (READ_ONCE(link->status) != DL_STATE_DORMANT) + if (READ_ONCE(link->status) != DL_STATE_DORMANT && + !device_link_flag_is_sync_state_only(link->flags)) dpm_wait(link->consumer, async); device_links_read_unlock(idx); diff --git a/drivers/base/power/runtime-test.c b/drivers/base/power/runtime-test.c new file mode 100644 index 000000000000..477feca804c7 --- /dev/null +++ b/drivers/base/power/runtime-test.c @@ -0,0 +1,253 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright 2025 Google, Inc. + */ + +#include <linux/cleanup.h> +#include <linux/pm_runtime.h> +#include <kunit/device.h> +#include <kunit/test.h> + +#define DEVICE_NAME "pm_runtime_test_device" + +static void pm_runtime_depth_test(struct kunit *test) +{ + struct device *dev = kunit_device_register(test, DEVICE_NAME); + + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dev); + + pm_runtime_enable(dev); + + KUNIT_EXPECT_TRUE(test, pm_runtime_suspended(dev)); + KUNIT_EXPECT_EQ(test, 0, pm_runtime_get_sync(dev)); + KUNIT_EXPECT_TRUE(test, pm_runtime_active(dev)); + KUNIT_EXPECT_EQ(test, 1, pm_runtime_get_sync(dev)); /* "already active" */ + KUNIT_EXPECT_EQ(test, 0, pm_runtime_put_sync(dev)); + KUNIT_EXPECT_EQ(test, 0, pm_runtime_put_sync(dev)); + KUNIT_EXPECT_TRUE(test, pm_runtime_suspended(dev)); +} + +/* Test pm_runtime_put() and friends when already suspended. */ +static void pm_runtime_already_suspended_test(struct kunit *test) +{ + struct device *dev = kunit_device_register(test, DEVICE_NAME); + + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dev); + + pm_runtime_enable(dev); + KUNIT_EXPECT_TRUE(test, pm_runtime_suspended(dev)); + + pm_runtime_get_noresume(dev); + KUNIT_EXPECT_EQ(test, 0, pm_runtime_barrier(dev)); /* no wakeup needed */ + pm_runtime_put(dev); + + pm_runtime_get_noresume(dev); + KUNIT_EXPECT_EQ(test, 1, pm_runtime_put_sync(dev)); + + KUNIT_EXPECT_EQ(test, 1, pm_runtime_suspend(dev)); + KUNIT_EXPECT_EQ(test, 1, pm_runtime_autosuspend(dev)); + KUNIT_EXPECT_EQ(test, 1, pm_request_autosuspend(dev)); + + pm_runtime_get_noresume(dev); + KUNIT_EXPECT_EQ(test, 1, pm_runtime_put_sync_autosuspend(dev)); + + pm_runtime_get_noresume(dev); + pm_runtime_put_autosuspend(dev); + + /* Grab 2 refcounts */ + pm_runtime_get_noresume(dev); + pm_runtime_get_noresume(dev); + /* The first put() sees usage_count 1 */ + KUNIT_EXPECT_EQ(test, 0, pm_runtime_put_sync_autosuspend(dev)); + /* The second put() sees usage_count 0 but tells us "already suspended". */ + KUNIT_EXPECT_EQ(test, 1, pm_runtime_put_sync_autosuspend(dev)); + + /* Should have remained suspended the whole time. */ + KUNIT_EXPECT_TRUE(test, pm_runtime_suspended(dev)); +} + +static void pm_runtime_idle_test(struct kunit *test) +{ + struct device *dev = kunit_device_register(test, DEVICE_NAME); + + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dev); + + pm_runtime_enable(dev); + + KUNIT_EXPECT_TRUE(test, pm_runtime_suspended(dev)); + KUNIT_EXPECT_EQ(test, 0, pm_runtime_get_sync(dev)); + KUNIT_EXPECT_TRUE(test, pm_runtime_active(dev)); + KUNIT_EXPECT_EQ(test, -EAGAIN, pm_runtime_idle(dev)); + KUNIT_EXPECT_TRUE(test, pm_runtime_active(dev)); + pm_runtime_put_noidle(dev); + KUNIT_EXPECT_TRUE(test, pm_runtime_active(dev)); + KUNIT_EXPECT_EQ(test, 0, pm_runtime_idle(dev)); + KUNIT_EXPECT_TRUE(test, pm_runtime_suspended(dev)); + KUNIT_EXPECT_EQ(test, -EAGAIN, pm_runtime_idle(dev)); + KUNIT_EXPECT_EQ(test, -EAGAIN, pm_request_idle(dev)); +} + +static void pm_runtime_disabled_test(struct kunit *test) +{ + struct device *dev = kunit_device_register(test, DEVICE_NAME); + + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dev); + + /* Never called pm_runtime_enable() */ + KUNIT_EXPECT_FALSE(test, pm_runtime_enabled(dev)); + + /* "disabled" is treated as "active" */ + KUNIT_EXPECT_TRUE(test, pm_runtime_active(dev)); + KUNIT_EXPECT_FALSE(test, pm_runtime_suspended(dev)); + + /* + * Note: these "fail", but they still acquire/release refcounts, so + * keep them balanced. + */ + KUNIT_EXPECT_EQ(test, -EACCES, pm_runtime_get(dev)); + pm_runtime_put(dev); + + KUNIT_EXPECT_EQ(test, -EACCES, pm_runtime_get_sync(dev)); + KUNIT_EXPECT_EQ(test, -EACCES, pm_runtime_put_sync(dev)); + + KUNIT_EXPECT_EQ(test, -EACCES, pm_runtime_get(dev)); + pm_runtime_put_autosuspend(dev); + + KUNIT_EXPECT_EQ(test, -EACCES, pm_runtime_resume_and_get(dev)); + KUNIT_EXPECT_EQ(test, -EACCES, pm_runtime_idle(dev)); + KUNIT_EXPECT_EQ(test, -EACCES, pm_request_idle(dev)); + KUNIT_EXPECT_EQ(test, -EACCES, pm_request_resume(dev)); + KUNIT_EXPECT_EQ(test, -EACCES, pm_request_autosuspend(dev)); + KUNIT_EXPECT_EQ(test, -EACCES, pm_runtime_suspend(dev)); + KUNIT_EXPECT_EQ(test, -EACCES, pm_runtime_resume(dev)); + KUNIT_EXPECT_EQ(test, -EACCES, pm_runtime_autosuspend(dev)); + + /* Still disabled */ + KUNIT_EXPECT_TRUE(test, pm_runtime_active(dev)); + KUNIT_EXPECT_FALSE(test, pm_runtime_enabled(dev)); +} + +static void pm_runtime_error_test(struct kunit *test) +{ + struct device *dev = kunit_device_register(test, DEVICE_NAME); + + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dev); + + pm_runtime_enable(dev); + KUNIT_EXPECT_TRUE(test, pm_runtime_suspended(dev)); + + /* Fake a .runtime_resume() error */ + dev->power.runtime_error = -EIO; + + /* + * Note: these "fail", but they still acquire/release refcounts, so + * keep them balanced. + */ + KUNIT_EXPECT_EQ(test, -EINVAL, pm_runtime_get(dev)); + pm_runtime_put(dev); + + KUNIT_EXPECT_EQ(test, -EINVAL, pm_runtime_get_sync(dev)); + KUNIT_EXPECT_EQ(test, -EINVAL, pm_runtime_put_sync(dev)); + + KUNIT_EXPECT_EQ(test, -EINVAL, pm_runtime_get(dev)); + pm_runtime_put_autosuspend(dev); + + KUNIT_EXPECT_EQ(test, -EINVAL, pm_runtime_get(dev)); + KUNIT_EXPECT_EQ(test, -EINVAL, pm_runtime_put_sync_autosuspend(dev)); + + KUNIT_EXPECT_EQ(test, -EINVAL, pm_runtime_resume_and_get(dev)); + KUNIT_EXPECT_EQ(test, -EINVAL, pm_runtime_idle(dev)); + KUNIT_EXPECT_EQ(test, -EINVAL, pm_request_idle(dev)); + KUNIT_EXPECT_EQ(test, -EINVAL, pm_request_resume(dev)); + KUNIT_EXPECT_EQ(test, -EINVAL, pm_request_autosuspend(dev)); + KUNIT_EXPECT_EQ(test, -EINVAL, pm_runtime_suspend(dev)); + KUNIT_EXPECT_EQ(test, -EINVAL, pm_runtime_resume(dev)); + KUNIT_EXPECT_EQ(test, -EINVAL, pm_runtime_autosuspend(dev)); + + /* Error is still pending */ + KUNIT_EXPECT_TRUE(test, pm_runtime_suspended(dev)); + KUNIT_EXPECT_EQ(test, -EIO, dev->power.runtime_error); + /* Clear error */ + KUNIT_EXPECT_EQ(test, 0, pm_runtime_set_suspended(dev)); + KUNIT_EXPECT_EQ(test, 0, dev->power.runtime_error); + /* Still suspended */ + KUNIT_EXPECT_TRUE(test, pm_runtime_suspended(dev)); + + KUNIT_EXPECT_EQ(test, 0, pm_runtime_get(dev)); + KUNIT_EXPECT_EQ(test, 1, pm_runtime_barrier(dev)); /* resume was pending */ + pm_runtime_put(dev); + pm_runtime_suspend(dev); /* flush the put(), to suspend */ + KUNIT_EXPECT_TRUE(test, pm_runtime_suspended(dev)); + + KUNIT_EXPECT_EQ(test, 0, pm_runtime_get_sync(dev)); + KUNIT_EXPECT_EQ(test, 0, pm_runtime_put_sync(dev)); + + KUNIT_EXPECT_EQ(test, 0, pm_runtime_get_sync(dev)); + pm_runtime_put_autosuspend(dev); + + KUNIT_EXPECT_EQ(test, 0, pm_runtime_resume_and_get(dev)); + + /* + * The following should all return -EAGAIN (usage is non-zero) or 1 + * (already resumed). + */ + KUNIT_EXPECT_EQ(test, -EAGAIN, pm_runtime_idle(dev)); + KUNIT_EXPECT_EQ(test, -EAGAIN, pm_request_idle(dev)); + KUNIT_EXPECT_EQ(test, 1, pm_request_resume(dev)); + KUNIT_EXPECT_EQ(test, -EAGAIN, pm_request_autosuspend(dev)); + KUNIT_EXPECT_EQ(test, -EAGAIN, pm_runtime_suspend(dev)); + KUNIT_EXPECT_EQ(test, 1, pm_runtime_resume(dev)); + KUNIT_EXPECT_EQ(test, -EAGAIN, pm_runtime_autosuspend(dev)); + + KUNIT_EXPECT_EQ(test, 0, pm_runtime_put_sync(dev)); + + /* Suspended again */ + KUNIT_EXPECT_TRUE(test, pm_runtime_suspended(dev)); +} + +/* + * Explore a typical probe() sequence in which a device marks itself powered, + * but doesn't hold any runtime PM reference, so it suspends as soon as it goes + * idle. + */ +static void pm_runtime_probe_active_test(struct kunit *test) +{ + struct device *dev = kunit_device_register(test, DEVICE_NAME); + + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dev); + + KUNIT_EXPECT_TRUE(test, pm_runtime_status_suspended(dev)); + + KUNIT_EXPECT_EQ(test, 0, pm_runtime_set_active(dev)); + KUNIT_EXPECT_TRUE(test, pm_runtime_active(dev)); + + pm_runtime_enable(dev); + KUNIT_EXPECT_TRUE(test, pm_runtime_active(dev)); + + /* Nothing to flush. We stay active. */ + KUNIT_EXPECT_EQ(test, 0, pm_runtime_barrier(dev)); + KUNIT_EXPECT_TRUE(test, pm_runtime_active(dev)); + + /* Ask for idle? Now we suspend. */ + KUNIT_EXPECT_EQ(test, 0, pm_runtime_idle(dev)); + KUNIT_EXPECT_TRUE(test, pm_runtime_suspended(dev)); +} + +static struct kunit_case pm_runtime_test_cases[] = { + KUNIT_CASE(pm_runtime_depth_test), + KUNIT_CASE(pm_runtime_already_suspended_test), + KUNIT_CASE(pm_runtime_idle_test), + KUNIT_CASE(pm_runtime_disabled_test), + KUNIT_CASE(pm_runtime_error_test), + KUNIT_CASE(pm_runtime_probe_active_test), + {} +}; + +static struct kunit_suite pm_runtime_test_suite = { + .name = "pm_runtime_test_cases", + .test_cases = pm_runtime_test_cases, +}; + +kunit_test_suite(pm_runtime_test_suite); +MODULE_DESCRIPTION("Runtime power management unit test suite"); +MODULE_LICENSE("GPL"); diff --git a/drivers/base/power/runtime.c b/drivers/base/power/runtime.c index 7420b9851fe0..1b11a3cd4acc 100644 --- a/drivers/base/power/runtime.c +++ b/drivers/base/power/runtime.c @@ -498,6 +498,9 @@ static int rpm_idle(struct device *dev, int rpmflags) if (retval < 0) ; /* Conditions are wrong. */ + else if ((rpmflags & RPM_GET_PUT) && retval == 1) + ; /* put() is allowed in RPM_SUSPENDED */ + /* Idle notifications are allowed only in the RPM_ACTIVE state. */ else if (dev->power.runtime_status != RPM_ACTIVE) retval = -EAGAIN; @@ -796,6 +799,8 @@ static int rpm_resume(struct device *dev, int rpmflags) if (dev->power.runtime_status == RPM_ACTIVE && dev->power.last_status == RPM_ACTIVE) retval = 1; + else if (rpmflags & RPM_TRANSPARENT) + goto out; else retval = -EACCES; } diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig index 6fc5ae76b483..3a1611008e48 100644 --- a/drivers/clk/Kconfig +++ b/drivers/clk/Kconfig @@ -364,6 +364,7 @@ config COMMON_CLK_LOCHNAGAR config COMMON_CLK_NPCM8XX tristate "Clock driver for the NPCM8XX SoC Family" depends on ARCH_NPCM || COMPILE_TEST + select AUXILIARY_BUS help This driver supports the clocks on the Nuvoton BMC NPCM8XX SoC Family, all the clocks are initialized by the bootloader, so this driver @@ -520,6 +521,7 @@ source "drivers/clk/imx/Kconfig" source "drivers/clk/ingenic/Kconfig" source "drivers/clk/keystone/Kconfig" source "drivers/clk/mediatek/Kconfig" +source "drivers/clk/mmp/Kconfig" source "drivers/clk/meson/Kconfig" source "drivers/clk/mstar/Kconfig" source "drivers/clk/microchip/Kconfig" diff --git a/drivers/clk/actions/owl-common.c b/drivers/clk/actions/owl-common.c index c62024b7c737..b3dded204dc5 100644 --- a/drivers/clk/actions/owl-common.c +++ b/drivers/clk/actions/owl-common.c @@ -18,7 +18,6 @@ static const struct regmap_config owl_regmap_config = { .reg_stride = 4, .val_bits = 32, .max_register = 0x00cc, - .fast_io = true, }; static void owl_clk_set_regmap(const struct owl_clk_desc *desc, diff --git a/drivers/clk/actions/owl-composite.c b/drivers/clk/actions/owl-composite.c index 48f177f6ce9c..00b74f8bc437 100644 --- a/drivers/clk/actions/owl-composite.c +++ b/drivers/clk/actions/owl-composite.c @@ -122,13 +122,13 @@ static int owl_comp_fact_set_rate(struct clk_hw *hw, unsigned long rate, rate, parent_rate); } -static long owl_comp_fix_fact_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *parent_rate) +static int owl_comp_fix_fact_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { struct owl_composite *comp = hw_to_owl_comp(hw); struct clk_fixed_factor *fix_fact_hw = &comp->rate.fix_fact_hw; - return comp->fix_fact_ops->round_rate(&fix_fact_hw->hw, rate, parent_rate); + return comp->fix_fact_ops->determine_rate(&fix_fact_hw->hw, req); } static unsigned long owl_comp_fix_fact_recalc_rate(struct clk_hw *hw, @@ -193,7 +193,7 @@ const struct clk_ops owl_comp_fix_fact_ops = { .is_enabled = owl_comp_is_enabled, /* fix_fact_ops */ - .round_rate = owl_comp_fix_fact_round_rate, + .determine_rate = owl_comp_fix_fact_determine_rate, .recalc_rate = owl_comp_fix_fact_recalc_rate, .set_rate = owl_comp_fix_fact_set_rate, }; diff --git a/drivers/clk/actions/owl-divider.c b/drivers/clk/actions/owl-divider.c index cddac00fe324..118f1393c678 100644 --- a/drivers/clk/actions/owl-divider.c +++ b/drivers/clk/actions/owl-divider.c @@ -23,13 +23,16 @@ long owl_divider_helper_round_rate(struct owl_clk_common *common, div_hw->div_flags); } -static long owl_divider_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *parent_rate) +static int owl_divider_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { struct owl_divider *div = hw_to_owl_divider(hw); - return owl_divider_helper_round_rate(&div->common, &div->div_hw, - rate, parent_rate); + req->rate = owl_divider_helper_round_rate(&div->common, &div->div_hw, + req->rate, + &req->best_parent_rate); + + return 0; } unsigned long owl_divider_helper_recalc_rate(struct owl_clk_common *common, @@ -89,6 +92,6 @@ static int owl_divider_set_rate(struct clk_hw *hw, unsigned long rate, const struct clk_ops owl_divider_ops = { .recalc_rate = owl_divider_recalc_rate, - .round_rate = owl_divider_round_rate, + .determine_rate = owl_divider_determine_rate, .set_rate = owl_divider_set_rate, }; diff --git a/drivers/clk/actions/owl-factor.c b/drivers/clk/actions/owl-factor.c index 64f316cf7cfc..12f41f6bacd6 100644 --- a/drivers/clk/actions/owl-factor.c +++ b/drivers/clk/actions/owl-factor.c @@ -130,14 +130,16 @@ long owl_factor_helper_round_rate(struct owl_clk_common *common, return *parent_rate * mul / div; } -static long owl_factor_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *parent_rate) +static int owl_factor_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { struct owl_factor *factor = hw_to_owl_factor(hw); struct owl_factor_hw *factor_hw = &factor->factor_hw; - return owl_factor_helper_round_rate(&factor->common, factor_hw, - rate, parent_rate); + req->rate = owl_factor_helper_round_rate(&factor->common, factor_hw, + req->rate, &req->best_parent_rate); + + return 0; } unsigned long owl_factor_helper_recalc_rate(struct owl_clk_common *common, @@ -214,7 +216,7 @@ static int owl_factor_set_rate(struct clk_hw *hw, unsigned long rate, } const struct clk_ops owl_factor_ops = { - .round_rate = owl_factor_round_rate, + .determine_rate = owl_factor_determine_rate, .recalc_rate = owl_factor_recalc_rate, .set_rate = owl_factor_set_rate, }; diff --git a/drivers/clk/actions/owl-pll.c b/drivers/clk/actions/owl-pll.c index 155f313986b4..869690b79cc1 100644 --- a/drivers/clk/actions/owl-pll.c +++ b/drivers/clk/actions/owl-pll.c @@ -56,8 +56,8 @@ static const struct clk_pll_table *_get_pll_table( return table; } -static long owl_pll_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *parent_rate) +static int owl_pll_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { struct owl_pll *pll = hw_to_owl_pll(hw); struct owl_pll_hw *pll_hw = &pll->pll_hw; @@ -65,17 +65,24 @@ static long owl_pll_round_rate(struct clk_hw *hw, unsigned long rate, u32 mul; if (pll_hw->table) { - clkt = _get_pll_table(pll_hw->table, rate); - return clkt->rate; + clkt = _get_pll_table(pll_hw->table, req->rate); + req->rate = clkt->rate; + + return 0; } /* fixed frequency */ - if (pll_hw->width == 0) - return pll_hw->bfreq; + if (pll_hw->width == 0) { + req->rate = pll_hw->bfreq; - mul = owl_pll_calculate_mul(pll_hw, rate); + return 0; + } + + mul = owl_pll_calculate_mul(pll_hw, req->rate); - return pll_hw->bfreq * mul; + req->rate = pll_hw->bfreq * mul; + + return 0; } static unsigned long owl_pll_recalc_rate(struct clk_hw *hw, @@ -188,7 +195,7 @@ const struct clk_ops owl_pll_ops = { .enable = owl_pll_enable, .disable = owl_pll_disable, .is_enabled = owl_pll_is_enabled, - .round_rate = owl_pll_round_rate, + .determine_rate = owl_pll_determine_rate, .recalc_rate = owl_pll_recalc_rate, .set_rate = owl_pll_set_rate, }; diff --git a/drivers/clk/at91/clk-audio-pll.c b/drivers/clk/at91/clk-audio-pll.c index a92da64c12e1..bf9b635ac9d6 100644 --- a/drivers/clk/at91/clk-audio-pll.c +++ b/drivers/clk/at91/clk-audio-pll.c @@ -270,8 +270,8 @@ static int clk_audio_pll_frac_determine_rate(struct clk_hw *hw, return 0; } -static long clk_audio_pll_pad_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *parent_rate) +static int clk_audio_pll_pad_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { struct clk_hw *pclk = clk_hw_get_parent(hw); long best_rate = -EINVAL; @@ -283,7 +283,7 @@ static long clk_audio_pll_pad_round_rate(struct clk_hw *hw, unsigned long rate, int best_diff = -1; pr_debug("A PLL/PAD: %s, rate = %lu (parent_rate = %lu)\n", __func__, - rate, *parent_rate); + req->rate, req->best_parent_rate); /* * Rate divisor is actually made of two different divisors, multiplied @@ -304,12 +304,12 @@ static long clk_audio_pll_pad_round_rate(struct clk_hw *hw, unsigned long rate, continue; best_parent_rate = clk_hw_round_rate(pclk, - rate * tmp_qd * div); + req->rate * tmp_qd * div); tmp_rate = best_parent_rate / (div * tmp_qd); - tmp_diff = abs(rate - tmp_rate); + tmp_diff = abs(req->rate - tmp_rate); if (best_diff < 0 || best_diff > tmp_diff) { - *parent_rate = best_parent_rate; + req->best_parent_rate = best_parent_rate; best_rate = tmp_rate; best_diff = tmp_diff; } @@ -318,11 +318,13 @@ static long clk_audio_pll_pad_round_rate(struct clk_hw *hw, unsigned long rate, pr_debug("A PLL/PAD: %s, best_rate = %ld, best_parent_rate = %lu\n", __func__, best_rate, best_parent_rate); - return best_rate; + req->rate = best_rate; + + return 0; } -static long clk_audio_pll_pmc_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *parent_rate) +static int clk_audio_pll_pmc_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { struct clk_hw *pclk = clk_hw_get_parent(hw); long best_rate = -EINVAL; @@ -333,20 +335,20 @@ static long clk_audio_pll_pmc_round_rate(struct clk_hw *hw, unsigned long rate, int best_diff = -1; pr_debug("A PLL/PMC: %s, rate = %lu (parent_rate = %lu)\n", __func__, - rate, *parent_rate); + req->rate, req->best_parent_rate); - if (!rate) + if (!req->rate) return 0; best_parent_rate = clk_round_rate(pclk->clk, 1); - div = max(best_parent_rate / rate, 1UL); + div = max(best_parent_rate / req->rate, 1UL); for (; div <= AUDIO_PLL_QDPMC_MAX; div++) { - best_parent_rate = clk_round_rate(pclk->clk, rate * div); + best_parent_rate = clk_round_rate(pclk->clk, req->rate * div); tmp_rate = best_parent_rate / div; - tmp_diff = abs(rate - tmp_rate); + tmp_diff = abs(req->rate - tmp_rate); if (best_diff < 0 || best_diff > tmp_diff) { - *parent_rate = best_parent_rate; + req->best_parent_rate = best_parent_rate; best_rate = tmp_rate; best_diff = tmp_diff; tmp_qd = div; @@ -356,9 +358,11 @@ static long clk_audio_pll_pmc_round_rate(struct clk_hw *hw, unsigned long rate, } pr_debug("A PLL/PMC: %s, best_rate = %ld, best_parent_rate = %lu (qd = %d)\n", - __func__, best_rate, *parent_rate, tmp_qd - 1); + __func__, best_rate, req->best_parent_rate, tmp_qd - 1); + + req->rate = best_rate; - return best_rate; + return 0; } static int clk_audio_pll_frac_set_rate(struct clk_hw *hw, unsigned long rate, @@ -436,7 +440,7 @@ static const struct clk_ops audio_pll_pad_ops = { .enable = clk_audio_pll_pad_enable, .disable = clk_audio_pll_pad_disable, .recalc_rate = clk_audio_pll_pad_recalc_rate, - .round_rate = clk_audio_pll_pad_round_rate, + .determine_rate = clk_audio_pll_pad_determine_rate, .set_rate = clk_audio_pll_pad_set_rate, }; @@ -444,7 +448,7 @@ static const struct clk_ops audio_pll_pmc_ops = { .enable = clk_audio_pll_pmc_enable, .disable = clk_audio_pll_pmc_disable, .recalc_rate = clk_audio_pll_pmc_recalc_rate, - .round_rate = clk_audio_pll_pmc_round_rate, + .determine_rate = clk_audio_pll_pmc_determine_rate, .set_rate = clk_audio_pll_pmc_set_rate, }; diff --git a/drivers/clk/at91/clk-h32mx.c b/drivers/clk/at91/clk-h32mx.c index 1e6c12eeda10..a9aa93b5a870 100644 --- a/drivers/clk/at91/clk-h32mx.c +++ b/drivers/clk/at91/clk-h32mx.c @@ -40,21 +40,32 @@ static unsigned long clk_sama5d4_h32mx_recalc_rate(struct clk_hw *hw, return parent_rate; } -static long clk_sama5d4_h32mx_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *parent_rate) +static int clk_sama5d4_h32mx_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { unsigned long div; - if (rate > *parent_rate) - return *parent_rate; - div = *parent_rate / 2; - if (rate < div) - return div; + if (req->rate > req->best_parent_rate) { + req->rate = req->best_parent_rate; - if (rate - div < *parent_rate - rate) - return div; + return 0; + } + div = req->best_parent_rate / 2; + if (req->rate < div) { + req->rate = div; + + return 0; + } + + if (req->rate - div < req->best_parent_rate - req->rate) { + req->rate = div; - return *parent_rate; + return 0; + } + + req->rate = req->best_parent_rate; + + return 0; } static int clk_sama5d4_h32mx_set_rate(struct clk_hw *hw, unsigned long rate, @@ -77,7 +88,7 @@ static int clk_sama5d4_h32mx_set_rate(struct clk_hw *hw, unsigned long rate, static const struct clk_ops h32mx_ops = { .recalc_rate = clk_sama5d4_h32mx_recalc_rate, - .round_rate = clk_sama5d4_h32mx_round_rate, + .determine_rate = clk_sama5d4_h32mx_determine_rate, .set_rate = clk_sama5d4_h32mx_set_rate, }; diff --git a/drivers/clk/at91/clk-master.c b/drivers/clk/at91/clk-master.c index 7a544e429d34..d5ea2069ec83 100644 --- a/drivers/clk/at91/clk-master.c +++ b/drivers/clk/at91/clk-master.c @@ -580,6 +580,9 @@ clk_sama7g5_master_recalc_rate(struct clk_hw *hw, { struct clk_master *master = to_clk_master(hw); + if (master->div == MASTER_PRES_MAX) + return DIV_ROUND_CLOSEST_ULL(parent_rate, 3); + return DIV_ROUND_CLOSEST_ULL(parent_rate, (1 << master->div)); } diff --git a/drivers/clk/at91/clk-peripheral.c b/drivers/clk/at91/clk-peripheral.c index c173a44c800a..e700f40fd87f 100644 --- a/drivers/clk/at91/clk-peripheral.c +++ b/drivers/clk/at91/clk-peripheral.c @@ -279,8 +279,11 @@ static int clk_sam9x5_peripheral_determine_rate(struct clk_hw *hw, long best_diff = LONG_MIN; u32 shift; - if (periph->id < PERIPHERAL_ID_MIN || !periph->range.max) - return parent_rate; + if (periph->id < PERIPHERAL_ID_MIN || !periph->range.max) { + req->rate = parent_rate; + + return 0; + } /* Fist step: check the available dividers. */ for (shift = 0; shift <= PERIPHERAL_MAX_SHIFT; shift++) { @@ -332,50 +335,57 @@ end: return 0; } -static long clk_sam9x5_peripheral_round_rate(struct clk_hw *hw, - unsigned long rate, - unsigned long *parent_rate) +static int clk_sam9x5_peripheral_no_parent_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { int shift = 0; unsigned long best_rate; unsigned long best_diff; - unsigned long cur_rate = *parent_rate; + unsigned long cur_rate = req->best_parent_rate; unsigned long cur_diff; struct clk_sam9x5_peripheral *periph = to_clk_sam9x5_peripheral(hw); - if (periph->id < PERIPHERAL_ID_MIN || !periph->range.max) - return *parent_rate; + if (periph->id < PERIPHERAL_ID_MIN || !periph->range.max) { + req->rate = req->best_parent_rate; + + return 0; + } if (periph->range.max) { for (; shift <= PERIPHERAL_MAX_SHIFT; shift++) { - cur_rate = *parent_rate >> shift; + cur_rate = req->best_parent_rate >> shift; if (cur_rate <= periph->range.max) break; } } - if (rate >= cur_rate) - return cur_rate; + if (req->rate >= cur_rate) { + req->rate = cur_rate; + + return 0; + } - best_diff = cur_rate - rate; + best_diff = cur_rate - req->rate; best_rate = cur_rate; for (; shift <= PERIPHERAL_MAX_SHIFT; shift++) { - cur_rate = *parent_rate >> shift; - if (cur_rate < rate) - cur_diff = rate - cur_rate; + cur_rate = req->best_parent_rate >> shift; + if (cur_rate < req->rate) + cur_diff = req->rate - cur_rate; else - cur_diff = cur_rate - rate; + cur_diff = cur_rate - req->rate; if (cur_diff < best_diff) { best_diff = cur_diff; best_rate = cur_rate; } - if (!best_diff || cur_rate < rate) + if (!best_diff || cur_rate < req->rate) break; } - return best_rate; + req->rate = best_rate; + + return 0; } static int clk_sam9x5_peripheral_set_rate(struct clk_hw *hw, @@ -427,7 +437,7 @@ static const struct clk_ops sam9x5_peripheral_ops = { .disable = clk_sam9x5_peripheral_disable, .is_enabled = clk_sam9x5_peripheral_is_enabled, .recalc_rate = clk_sam9x5_peripheral_recalc_rate, - .round_rate = clk_sam9x5_peripheral_round_rate, + .determine_rate = clk_sam9x5_peripheral_no_parent_determine_rate, .set_rate = clk_sam9x5_peripheral_set_rate, .save_context = clk_sam9x5_peripheral_save_context, .restore_context = clk_sam9x5_peripheral_restore_context, diff --git a/drivers/clk/at91/clk-pll.c b/drivers/clk/at91/clk-pll.c index 249d6a53cedf..5c5f7398effe 100644 --- a/drivers/clk/at91/clk-pll.c +++ b/drivers/clk/at91/clk-pll.c @@ -231,13 +231,15 @@ static long clk_pll_get_best_div_mul(struct clk_pll *pll, unsigned long rate, return bestrate; } -static long clk_pll_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *parent_rate) +static int clk_pll_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { struct clk_pll *pll = to_clk_pll(hw); - return clk_pll_get_best_div_mul(pll, rate, *parent_rate, - NULL, NULL, NULL); + req->rate = clk_pll_get_best_div_mul(pll, req->rate, req->best_parent_rate, + NULL, NULL, NULL); + + return 0; } static int clk_pll_set_rate(struct clk_hw *hw, unsigned long rate, @@ -302,7 +304,7 @@ static const struct clk_ops pll_ops = { .unprepare = clk_pll_unprepare, .is_prepared = clk_pll_is_prepared, .recalc_rate = clk_pll_recalc_rate, - .round_rate = clk_pll_round_rate, + .determine_rate = clk_pll_determine_rate, .set_rate = clk_pll_set_rate, .save_context = clk_pll_save_context, .restore_context = clk_pll_restore_context, diff --git a/drivers/clk/at91/clk-plldiv.c b/drivers/clk/at91/clk-plldiv.c index ba3a1839a96d..3ac09fecc54e 100644 --- a/drivers/clk/at91/clk-plldiv.c +++ b/drivers/clk/at91/clk-plldiv.c @@ -33,21 +33,33 @@ static unsigned long clk_plldiv_recalc_rate(struct clk_hw *hw, return parent_rate; } -static long clk_plldiv_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *parent_rate) +static int clk_plldiv_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { unsigned long div; - if (rate > *parent_rate) - return *parent_rate; - div = *parent_rate / 2; - if (rate < div) - return div; + if (req->rate > req->best_parent_rate) { + req->rate = req->best_parent_rate; - if (rate - div < *parent_rate - rate) - return div; + return 0; + } + + div = req->best_parent_rate / 2; + if (req->rate < div) { + req->rate = div; + + return 0; + } + + if (req->rate - div < req->best_parent_rate - req->rate) { + req->rate = div; - return *parent_rate; + return 0; + } + + req->rate = req->best_parent_rate; + + return 0; } static int clk_plldiv_set_rate(struct clk_hw *hw, unsigned long rate, @@ -66,7 +78,7 @@ static int clk_plldiv_set_rate(struct clk_hw *hw, unsigned long rate, static const struct clk_ops plldiv_ops = { .recalc_rate = clk_plldiv_recalc_rate, - .round_rate = clk_plldiv_round_rate, + .determine_rate = clk_plldiv_determine_rate, .set_rate = clk_plldiv_set_rate, }; diff --git a/drivers/clk/at91/clk-sam9x60-pll.c b/drivers/clk/at91/clk-sam9x60-pll.c index cefd9948e103..3b965057ba0d 100644 --- a/drivers/clk/at91/clk-sam9x60-pll.c +++ b/drivers/clk/at91/clk-sam9x60-pll.c @@ -93,8 +93,8 @@ static int sam9x60_frac_pll_set(struct sam9x60_pll_core *core) spin_lock_irqsave(core->lock, flags); - regmap_update_bits(regmap, AT91_PMC_PLL_UPDT, - AT91_PMC_PLL_UPDT_ID_MSK, core->id); + regmap_write_bits(regmap, AT91_PMC_PLL_UPDT, + AT91_PMC_PLL_UPDT_ID_MSK, core->id); regmap_read(regmap, AT91_PMC_PLL_CTRL1, &val); cmul = (val & core->layout->mul_mask) >> core->layout->mul_shift; cfrac = (val & core->layout->frac_mask) >> core->layout->frac_shift; @@ -103,11 +103,8 @@ static int sam9x60_frac_pll_set(struct sam9x60_pll_core *core) (cmul == frac->mul && cfrac == frac->frac)) goto unlock; - /* Recommended value for PMC_PLL_ACR */ - if (core->characteristics->upll) - val = AT91_PMC_PLL_ACR_DEFAULT_UPLL; - else - val = AT91_PMC_PLL_ACR_DEFAULT_PLLA; + /* Load recommended value for PMC_PLL_ACR */ + val = core->characteristics->acr; regmap_write(regmap, AT91_PMC_PLL_ACR, val); regmap_write(regmap, AT91_PMC_PLL_CTRL1, @@ -128,17 +125,17 @@ static int sam9x60_frac_pll_set(struct sam9x60_pll_core *core) udelay(10); } - regmap_update_bits(regmap, AT91_PMC_PLL_UPDT, - AT91_PMC_PLL_UPDT_UPDATE | AT91_PMC_PLL_UPDT_ID_MSK, - AT91_PMC_PLL_UPDT_UPDATE | core->id); + regmap_write_bits(regmap, AT91_PMC_PLL_UPDT, + AT91_PMC_PLL_UPDT_UPDATE | AT91_PMC_PLL_UPDT_ID_MSK, + AT91_PMC_PLL_UPDT_UPDATE | core->id); regmap_update_bits(regmap, AT91_PMC_PLL_CTRL0, AT91_PMC_PLL_CTRL0_ENLOCK | AT91_PMC_PLL_CTRL0_ENPLL, AT91_PMC_PLL_CTRL0_ENLOCK | AT91_PMC_PLL_CTRL0_ENPLL); - regmap_update_bits(regmap, AT91_PMC_PLL_UPDT, - AT91_PMC_PLL_UPDT_UPDATE | AT91_PMC_PLL_UPDT_ID_MSK, - AT91_PMC_PLL_UPDT_UPDATE | core->id); + regmap_write_bits(regmap, AT91_PMC_PLL_UPDT, + AT91_PMC_PLL_UPDT_UPDATE | AT91_PMC_PLL_UPDT_ID_MSK, + AT91_PMC_PLL_UPDT_UPDATE | core->id); while (!sam9x60_pll_ready(regmap, core->id)) cpu_relax(); @@ -164,8 +161,8 @@ static void sam9x60_frac_pll_unprepare(struct clk_hw *hw) spin_lock_irqsave(core->lock, flags); - regmap_update_bits(regmap, AT91_PMC_PLL_UPDT, - AT91_PMC_PLL_UPDT_ID_MSK, core->id); + regmap_write_bits(regmap, AT91_PMC_PLL_UPDT, + AT91_PMC_PLL_UPDT_ID_MSK, core->id); regmap_update_bits(regmap, AT91_PMC_PLL_CTRL0, AT91_PMC_PLL_CTRL0_ENPLL, 0); @@ -173,9 +170,9 @@ static void sam9x60_frac_pll_unprepare(struct clk_hw *hw) regmap_update_bits(regmap, AT91_PMC_PLL_ACR, AT91_PMC_PLL_ACR_UTMIBG | AT91_PMC_PLL_ACR_UTMIVR, 0); - regmap_update_bits(regmap, AT91_PMC_PLL_UPDT, - AT91_PMC_PLL_UPDT_UPDATE | AT91_PMC_PLL_UPDT_ID_MSK, - AT91_PMC_PLL_UPDT_UPDATE | core->id); + regmap_write_bits(regmap, AT91_PMC_PLL_UPDT, + AT91_PMC_PLL_UPDT_UPDATE | AT91_PMC_PLL_UPDT_ID_MSK, + AT91_PMC_PLL_UPDT_UPDATE | core->id); spin_unlock_irqrestore(core->lock, flags); } @@ -230,12 +227,16 @@ static long sam9x60_frac_pll_compute_mul_frac(struct sam9x60_pll_core *core, return tmprate; } -static long sam9x60_frac_pll_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *parent_rate) +static int sam9x60_frac_pll_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { struct sam9x60_pll_core *core = to_sam9x60_pll_core(hw); - return sam9x60_frac_pll_compute_mul_frac(core, rate, *parent_rate, false); + req->rate = sam9x60_frac_pll_compute_mul_frac(core, req->rate, + req->best_parent_rate, + false); + + return 0; } static int sam9x60_frac_pll_set_rate(struct clk_hw *hw, unsigned long rate, @@ -262,8 +263,8 @@ static int sam9x60_frac_pll_set_rate_chg(struct clk_hw *hw, unsigned long rate, spin_lock_irqsave(core->lock, irqflags); - regmap_update_bits(regmap, AT91_PMC_PLL_UPDT, AT91_PMC_PLL_UPDT_ID_MSK, - core->id); + regmap_write_bits(regmap, AT91_PMC_PLL_UPDT, AT91_PMC_PLL_UPDT_ID_MSK, + core->id); regmap_read(regmap, AT91_PMC_PLL_CTRL1, &val); cmul = (val & core->layout->mul_mask) >> core->layout->mul_shift; cfrac = (val & core->layout->frac_mask) >> core->layout->frac_shift; @@ -275,18 +276,18 @@ static int sam9x60_frac_pll_set_rate_chg(struct clk_hw *hw, unsigned long rate, (frac->mul << core->layout->mul_shift) | (frac->frac << core->layout->frac_shift)); - regmap_update_bits(regmap, AT91_PMC_PLL_UPDT, - AT91_PMC_PLL_UPDT_UPDATE | AT91_PMC_PLL_UPDT_ID_MSK, - AT91_PMC_PLL_UPDT_UPDATE | core->id); + regmap_write_bits(regmap, AT91_PMC_PLL_UPDT, + AT91_PMC_PLL_UPDT_UPDATE | AT91_PMC_PLL_UPDT_ID_MSK, + AT91_PMC_PLL_UPDT_UPDATE | core->id); regmap_update_bits(regmap, AT91_PMC_PLL_CTRL0, AT91_PMC_PLL_CTRL0_ENLOCK | AT91_PMC_PLL_CTRL0_ENPLL, AT91_PMC_PLL_CTRL0_ENLOCK | AT91_PMC_PLL_CTRL0_ENPLL); - regmap_update_bits(regmap, AT91_PMC_PLL_UPDT, - AT91_PMC_PLL_UPDT_UPDATE | AT91_PMC_PLL_UPDT_ID_MSK, - AT91_PMC_PLL_UPDT_UPDATE | core->id); + regmap_write_bits(regmap, AT91_PMC_PLL_UPDT, + AT91_PMC_PLL_UPDT_UPDATE | AT91_PMC_PLL_UPDT_ID_MSK, + AT91_PMC_PLL_UPDT_UPDATE | core->id); while (!sam9x60_pll_ready(regmap, core->id)) cpu_relax(); @@ -321,7 +322,7 @@ static const struct clk_ops sam9x60_frac_pll_ops = { .unprepare = sam9x60_frac_pll_unprepare, .is_prepared = sam9x60_frac_pll_is_prepared, .recalc_rate = sam9x60_frac_pll_recalc_rate, - .round_rate = sam9x60_frac_pll_round_rate, + .determine_rate = sam9x60_frac_pll_determine_rate, .set_rate = sam9x60_frac_pll_set_rate, .save_context = sam9x60_frac_pll_save_context, .restore_context = sam9x60_frac_pll_restore_context, @@ -332,13 +333,16 @@ static const struct clk_ops sam9x60_frac_pll_ops_chg = { .unprepare = sam9x60_frac_pll_unprepare, .is_prepared = sam9x60_frac_pll_is_prepared, .recalc_rate = sam9x60_frac_pll_recalc_rate, - .round_rate = sam9x60_frac_pll_round_rate, + .determine_rate = sam9x60_frac_pll_determine_rate, .set_rate = sam9x60_frac_pll_set_rate_chg, .save_context = sam9x60_frac_pll_save_context, .restore_context = sam9x60_frac_pll_restore_context, }; -/* This function should be called with spinlock acquired. */ +/* This function should be called with spinlock acquired. + * Warning: this function must be called only if the same PLL ID was set in + * PLL_UPDT register previously. + */ static void sam9x60_div_pll_set_div(struct sam9x60_pll_core *core, u32 div, bool enable) { @@ -350,9 +354,9 @@ static void sam9x60_div_pll_set_div(struct sam9x60_pll_core *core, u32 div, core->layout->div_mask | ena_msk, (div << core->layout->div_shift) | ena_val); - regmap_update_bits(regmap, AT91_PMC_PLL_UPDT, - AT91_PMC_PLL_UPDT_UPDATE | AT91_PMC_PLL_UPDT_ID_MSK, - AT91_PMC_PLL_UPDT_UPDATE | core->id); + regmap_write_bits(regmap, AT91_PMC_PLL_UPDT, + AT91_PMC_PLL_UPDT_UPDATE | AT91_PMC_PLL_UPDT_ID_MSK, + AT91_PMC_PLL_UPDT_UPDATE | core->id); while (!sam9x60_pll_ready(regmap, core->id)) cpu_relax(); @@ -366,8 +370,8 @@ static int sam9x60_div_pll_set(struct sam9x60_pll_core *core) unsigned int val, cdiv; spin_lock_irqsave(core->lock, flags); - regmap_update_bits(regmap, AT91_PMC_PLL_UPDT, - AT91_PMC_PLL_UPDT_ID_MSK, core->id); + regmap_write_bits(regmap, AT91_PMC_PLL_UPDT, + AT91_PMC_PLL_UPDT_ID_MSK, core->id); regmap_read(regmap, AT91_PMC_PLL_CTRL0, &val); cdiv = (val & core->layout->div_mask) >> core->layout->div_shift; @@ -398,15 +402,15 @@ static void sam9x60_div_pll_unprepare(struct clk_hw *hw) spin_lock_irqsave(core->lock, flags); - regmap_update_bits(regmap, AT91_PMC_PLL_UPDT, - AT91_PMC_PLL_UPDT_ID_MSK, core->id); + regmap_write_bits(regmap, AT91_PMC_PLL_UPDT, + AT91_PMC_PLL_UPDT_ID_MSK, core->id); regmap_update_bits(regmap, AT91_PMC_PLL_CTRL0, core->layout->endiv_mask, 0); - regmap_update_bits(regmap, AT91_PMC_PLL_UPDT, - AT91_PMC_PLL_UPDT_UPDATE | AT91_PMC_PLL_UPDT_ID_MSK, - AT91_PMC_PLL_UPDT_UPDATE | core->id); + regmap_write_bits(regmap, AT91_PMC_PLL_UPDT, + AT91_PMC_PLL_UPDT_UPDATE | AT91_PMC_PLL_UPDT_ID_MSK, + AT91_PMC_PLL_UPDT_UPDATE | core->id); spin_unlock_irqrestore(core->lock, flags); } @@ -487,12 +491,15 @@ static long sam9x60_div_pll_compute_div(struct sam9x60_pll_core *core, return best_rate; } -static long sam9x60_div_pll_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *parent_rate) +static int sam9x60_div_pll_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { struct sam9x60_pll_core *core = to_sam9x60_pll_core(hw); - return sam9x60_div_pll_compute_div(core, parent_rate, rate); + req->rate = sam9x60_div_pll_compute_div(core, &req->best_parent_rate, + req->rate); + + return 0; } static int sam9x60_div_pll_set_rate(struct clk_hw *hw, unsigned long rate, @@ -518,8 +525,8 @@ static int sam9x60_div_pll_set_rate_chg(struct clk_hw *hw, unsigned long rate, div->div = DIV_ROUND_CLOSEST(parent_rate, rate) - 1; spin_lock_irqsave(core->lock, irqflags); - regmap_update_bits(regmap, AT91_PMC_PLL_UPDT, AT91_PMC_PLL_UPDT_ID_MSK, - core->id); + regmap_write_bits(regmap, AT91_PMC_PLL_UPDT, AT91_PMC_PLL_UPDT_ID_MSK, + core->id); regmap_read(regmap, AT91_PMC_PLL_CTRL0, &val); cdiv = (val & core->layout->div_mask) >> core->layout->div_shift; @@ -574,8 +581,8 @@ static int sam9x60_div_pll_notifier_fn(struct notifier_block *notifier, div->div = div->safe_div; spin_lock_irqsave(core.lock, irqflags); - regmap_update_bits(regmap, AT91_PMC_PLL_UPDT, AT91_PMC_PLL_UPDT_ID_MSK, - core.id); + regmap_write_bits(regmap, AT91_PMC_PLL_UPDT, AT91_PMC_PLL_UPDT_ID_MSK, + core.id); regmap_read(regmap, AT91_PMC_PLL_CTRL0, &val); cdiv = (val & core.layout->div_mask) >> core.layout->div_shift; @@ -601,7 +608,7 @@ static const struct clk_ops sam9x60_div_pll_ops = { .unprepare = sam9x60_div_pll_unprepare, .is_prepared = sam9x60_div_pll_is_prepared, .recalc_rate = sam9x60_div_pll_recalc_rate, - .round_rate = sam9x60_div_pll_round_rate, + .determine_rate = sam9x60_div_pll_determine_rate, .set_rate = sam9x60_div_pll_set_rate, .save_context = sam9x60_div_pll_save_context, .restore_context = sam9x60_div_pll_restore_context, @@ -612,7 +619,7 @@ static const struct clk_ops sam9x60_div_pll_ops_chg = { .unprepare = sam9x60_div_pll_unprepare, .is_prepared = sam9x60_div_pll_is_prepared, .recalc_rate = sam9x60_div_pll_recalc_rate, - .round_rate = sam9x60_div_pll_round_rate, + .determine_rate = sam9x60_div_pll_determine_rate, .set_rate = sam9x60_div_pll_set_rate_chg, .save_context = sam9x60_div_pll_save_context, .restore_context = sam9x60_div_pll_restore_context, @@ -623,7 +630,7 @@ static const struct clk_ops sam9x60_fixed_div_pll_ops = { .unprepare = sam9x60_div_pll_unprepare, .is_prepared = sam9x60_div_pll_is_prepared, .recalc_rate = sam9x60_fixed_div_pll_recalc_rate, - .round_rate = sam9x60_div_pll_round_rate, + .determine_rate = sam9x60_div_pll_determine_rate, .save_context = sam9x60_div_pll_save_context, .restore_context = sam9x60_div_pll_restore_context, }; diff --git a/drivers/clk/at91/clk-usb.c b/drivers/clk/at91/clk-usb.c index b0696a928aa9..e906928cfbf0 100644 --- a/drivers/clk/at91/clk-usb.c +++ b/drivers/clk/at91/clk-usb.c @@ -319,8 +319,8 @@ static unsigned long at91rm9200_clk_usb_recalc_rate(struct clk_hw *hw, return 0; } -static long at91rm9200_clk_usb_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *parent_rate) +static int at91rm9200_clk_usb_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { struct at91rm9200_clk_usb *usb = to_at91rm9200_clk_usb(hw); struct clk_hw *parent = clk_hw_get_parent(hw); @@ -336,25 +336,27 @@ static long at91rm9200_clk_usb_round_rate(struct clk_hw *hw, unsigned long rate, if (!usb->divisors[i]) continue; - tmp_parent_rate = rate * usb->divisors[i]; + tmp_parent_rate = req->rate * usb->divisors[i]; tmp_parent_rate = clk_hw_round_rate(parent, tmp_parent_rate); tmprate = DIV_ROUND_CLOSEST(tmp_parent_rate, usb->divisors[i]); - if (tmprate < rate) - tmpdiff = rate - tmprate; + if (tmprate < req->rate) + tmpdiff = req->rate - tmprate; else - tmpdiff = tmprate - rate; + tmpdiff = tmprate - req->rate; if (bestdiff < 0 || bestdiff > tmpdiff) { bestrate = tmprate; bestdiff = tmpdiff; - *parent_rate = tmp_parent_rate; + req->best_parent_rate = tmp_parent_rate; } if (!bestdiff) break; } - return bestrate; + req->rate = bestrate; + + return 0; } static int at91rm9200_clk_usb_set_rate(struct clk_hw *hw, unsigned long rate, @@ -384,7 +386,7 @@ static int at91rm9200_clk_usb_set_rate(struct clk_hw *hw, unsigned long rate, static const struct clk_ops at91rm9200_usb_ops = { .recalc_rate = at91rm9200_clk_usb_recalc_rate, - .round_rate = at91rm9200_clk_usb_round_rate, + .determine_rate = at91rm9200_clk_usb_determine_rate, .set_rate = at91rm9200_clk_usb_set_rate, }; diff --git a/drivers/clk/at91/pmc.h b/drivers/clk/at91/pmc.h index 4fb29ca111f7..5daa32c4cf25 100644 --- a/drivers/clk/at91/pmc.h +++ b/drivers/clk/at91/pmc.h @@ -80,6 +80,7 @@ struct clk_pll_characteristics { u16 *icpll; u8 *out; u8 upll : 1; + u32 acr; }; struct clk_programmable_layout { diff --git a/drivers/clk/at91/sam9x60.c b/drivers/clk/at91/sam9x60.c index db6db9e2073e..18baf4a256f4 100644 --- a/drivers/clk/at91/sam9x60.c +++ b/drivers/clk/at91/sam9x60.c @@ -36,6 +36,7 @@ static const struct clk_pll_characteristics plla_characteristics = { .num_output = ARRAY_SIZE(plla_outputs), .output = plla_outputs, .core_output = core_outputs, + .acr = UL(0x00020010), }; static const struct clk_range upll_outputs[] = { @@ -48,6 +49,7 @@ static const struct clk_pll_characteristics upll_characteristics = { .output = upll_outputs, .core_output = core_outputs, .upll = true, + .acr = UL(0x12023010), /* fIN = [18 MHz, 32 MHz]*/ }; static const struct clk_pll_layout pll_frac_layout = { diff --git a/drivers/clk/at91/sam9x7.c b/drivers/clk/at91/sam9x7.c index ffab32b047a0..89868a0aeaba 100644 --- a/drivers/clk/at91/sam9x7.c +++ b/drivers/clk/at91/sam9x7.c @@ -107,6 +107,7 @@ static const struct clk_pll_characteristics plla_characteristics = { .num_output = ARRAY_SIZE(plla_outputs), .output = plla_outputs, .core_output = plla_core_outputs, + .acr = UL(0x00020010), /* Old ACR_DEFAULT_PLLA value */ }; static const struct clk_pll_characteristics upll_characteristics = { @@ -115,6 +116,7 @@ static const struct clk_pll_characteristics upll_characteristics = { .output = upll_outputs, .core_output = upll_core_outputs, .upll = true, + .acr = UL(0x12023010), /* fIN=[20 MHz, 32 MHz] */ }; static const struct clk_pll_characteristics lvdspll_characteristics = { @@ -122,6 +124,7 @@ static const struct clk_pll_characteristics lvdspll_characteristics = { .num_output = ARRAY_SIZE(lvdspll_outputs), .output = lvdspll_outputs, .core_output = lvdspll_core_outputs, + .acr = UL(0x12023010), /* fIN=[20 MHz, 32 MHz] */ }; static const struct clk_pll_characteristics audiopll_characteristics = { @@ -129,6 +132,7 @@ static const struct clk_pll_characteristics audiopll_characteristics = { .num_output = ARRAY_SIZE(audiopll_outputs), .output = audiopll_outputs, .core_output = audiopll_core_outputs, + .acr = UL(0x12023010), /* fIN=[20 MHz, 32 MHz] */ }; static const struct clk_pll_characteristics plladiv2_characteristics = { @@ -136,6 +140,7 @@ static const struct clk_pll_characteristics plladiv2_characteristics = { .num_output = ARRAY_SIZE(plladiv2_outputs), .output = plladiv2_outputs, .core_output = plladiv2_core_outputs, + .acr = UL(0x00020010), /* Old ACR_DEFAULT_PLLA value */ }; /* Layout for fractional PLL ID PLLA. */ @@ -403,6 +408,7 @@ static const struct { { .n = "pioD_clk", .id = 44, }, { .n = "tcb1_clk", .id = 45, }, { .n = "dbgu_clk", .id = 47, }, + { .n = "pmecc_clk", .id = 48, }, /* * mpddr_clk feeds DDR controller and is enabled by bootloader thus we * need to keep it enabled in case there is no Linux consumer for it. diff --git a/drivers/clk/at91/sama7d65.c b/drivers/clk/at91/sama7d65.c index a5d40df8b2f2..7dee2b160ffb 100644 --- a/drivers/clk/at91/sama7d65.c +++ b/drivers/clk/at91/sama7d65.c @@ -138,6 +138,7 @@ static const struct clk_pll_characteristics cpu_pll_characteristics = { .num_output = ARRAY_SIZE(cpu_pll_outputs), .output = cpu_pll_outputs, .core_output = core_outputs, + .acr = UL(0x00070010), }; /* PLL characteristics. */ @@ -146,6 +147,7 @@ static const struct clk_pll_characteristics pll_characteristics = { .num_output = ARRAY_SIZE(pll_outputs), .output = pll_outputs, .core_output = core_outputs, + .acr = UL(0x00070010), }; static const struct clk_pll_characteristics lvdspll_characteristics = { @@ -153,6 +155,7 @@ static const struct clk_pll_characteristics lvdspll_characteristics = { .num_output = ARRAY_SIZE(lvdspll_outputs), .output = lvdspll_outputs, .core_output = lvdspll_core_outputs, + .acr = UL(0x00070010), }; static const struct clk_pll_characteristics upll_characteristics = { @@ -160,6 +163,7 @@ static const struct clk_pll_characteristics upll_characteristics = { .num_output = ARRAY_SIZE(upll_outputs), .output = upll_outputs, .core_output = upll_core_outputs, + .acr = UL(0x12020010), .upll = true, }; diff --git a/drivers/clk/at91/sama7g5.c b/drivers/clk/at91/sama7g5.c index 8385badc1c70..1340c2b00619 100644 --- a/drivers/clk/at91/sama7g5.c +++ b/drivers/clk/at91/sama7g5.c @@ -113,6 +113,7 @@ static const struct clk_pll_characteristics cpu_pll_characteristics = { .num_output = ARRAY_SIZE(cpu_pll_outputs), .output = cpu_pll_outputs, .core_output = core_outputs, + .acr = UL(0x00070010), }; /* PLL characteristics. */ @@ -121,6 +122,7 @@ static const struct clk_pll_characteristics pll_characteristics = { .num_output = ARRAY_SIZE(pll_outputs), .output = pll_outputs, .core_output = core_outputs, + .acr = UL(0x00070010), }; /* diff --git a/drivers/clk/axs10x/i2s_pll_clock.c b/drivers/clk/axs10x/i2s_pll_clock.c index 9667ce898428..6f3e1151b354 100644 --- a/drivers/clk/axs10x/i2s_pll_clock.c +++ b/drivers/clk/axs10x/i2s_pll_clock.c @@ -108,21 +108,21 @@ static unsigned long i2s_pll_recalc_rate(struct clk_hw *hw, return ((parent_rate / idiv) * fbdiv) / odiv; } -static long i2s_pll_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *prate) +static int i2s_pll_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { struct i2s_pll_clk *clk = to_i2s_pll_clk(hw); - const struct i2s_pll_cfg *pll_cfg = i2s_pll_get_cfg(*prate); + const struct i2s_pll_cfg *pll_cfg = i2s_pll_get_cfg(req->best_parent_rate); int i; if (!pll_cfg) { - dev_err(clk->dev, "invalid parent rate=%ld\n", *prate); + dev_err(clk->dev, "invalid parent rate=%ld\n", req->best_parent_rate); return -EINVAL; } for (i = 0; pll_cfg[i].rate != 0; i++) - if (pll_cfg[i].rate == rate) - return rate; + if (pll_cfg[i].rate == req->rate) + return 0; return -EINVAL; } @@ -156,7 +156,7 @@ static int i2s_pll_set_rate(struct clk_hw *hw, unsigned long rate, static const struct clk_ops i2s_pll_ops = { .recalc_rate = i2s_pll_recalc_rate, - .round_rate = i2s_pll_round_rate, + .determine_rate = i2s_pll_determine_rate, .set_rate = i2s_pll_set_rate, }; diff --git a/drivers/clk/axs10x/pll_clock.c b/drivers/clk/axs10x/pll_clock.c index 6c7a2b62b406..c7ca473ee76c 100644 --- a/drivers/clk/axs10x/pll_clock.c +++ b/drivers/clk/axs10x/pll_clock.c @@ -149,8 +149,8 @@ static unsigned long axs10x_pll_recalc_rate(struct clk_hw *hw, return rate; } -static long axs10x_pll_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *prate) +static int axs10x_pll_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { int i; long best_rate; @@ -163,11 +163,13 @@ static long axs10x_pll_round_rate(struct clk_hw *hw, unsigned long rate, best_rate = pll_cfg[0].rate; for (i = 1; pll_cfg[i].rate != 0; i++) { - if (abs(rate - pll_cfg[i].rate) < abs(rate - best_rate)) + if (abs(req->rate - pll_cfg[i].rate) < abs(req->rate - best_rate)) best_rate = pll_cfg[i].rate; } - return best_rate; + req->rate = best_rate; + + return 0; } static int axs10x_pll_set_rate(struct clk_hw *hw, unsigned long rate, @@ -208,7 +210,7 @@ static int axs10x_pll_set_rate(struct clk_hw *hw, unsigned long rate, static const struct clk_ops axs10x_pll_ops = { .recalc_rate = axs10x_pll_recalc_rate, - .round_rate = axs10x_pll_round_rate, + .determine_rate = axs10x_pll_determine_rate, .set_rate = axs10x_pll_set_rate, }; diff --git a/drivers/clk/baikal-t1/ccu-div.c b/drivers/clk/baikal-t1/ccu-div.c index 8d5fc7158f33..849d1f55765f 100644 --- a/drivers/clk/baikal-t1/ccu-div.c +++ b/drivers/clk/baikal-t1/ccu-div.c @@ -228,15 +228,18 @@ static inline unsigned long ccu_div_var_calc_divider(unsigned long rate, CCU_DIV_CLKDIV_MAX(mask)); } -static long ccu_div_var_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *parent_rate) +static int ccu_div_var_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { struct ccu_div *div = to_ccu_div(hw); unsigned long divider; - divider = ccu_div_var_calc_divider(rate, *parent_rate, div->mask); + divider = ccu_div_var_calc_divider(req->rate, req->best_parent_rate, + div->mask); - return ccu_div_calc_freq(*parent_rate, divider); + req->rate = ccu_div_calc_freq(req->best_parent_rate, divider); + + return 0; } /* @@ -308,12 +311,14 @@ static unsigned long ccu_div_fixed_recalc_rate(struct clk_hw *hw, return ccu_div_calc_freq(parent_rate, div->divider); } -static long ccu_div_fixed_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *parent_rate) +static int ccu_div_fixed_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { struct ccu_div *div = to_ccu_div(hw); - return ccu_div_calc_freq(*parent_rate, div->divider); + req->rate = ccu_div_calc_freq(req->best_parent_rate, div->divider); + + return 0; } static int ccu_div_fixed_set_rate(struct clk_hw *hw, unsigned long rate, @@ -534,14 +539,14 @@ static const struct clk_ops ccu_div_var_gate_to_set_ops = { .disable = ccu_div_gate_disable, .is_enabled = ccu_div_gate_is_enabled, .recalc_rate = ccu_div_var_recalc_rate, - .round_rate = ccu_div_var_round_rate, + .determine_rate = ccu_div_var_determine_rate, .set_rate = ccu_div_var_set_rate_fast, .debug_init = ccu_div_var_debug_init }; static const struct clk_ops ccu_div_var_nogate_ops = { .recalc_rate = ccu_div_var_recalc_rate, - .round_rate = ccu_div_var_round_rate, + .determine_rate = ccu_div_var_determine_rate, .set_rate = ccu_div_var_set_rate_slow, .debug_init = ccu_div_var_debug_init }; @@ -551,7 +556,7 @@ static const struct clk_ops ccu_div_gate_ops = { .disable = ccu_div_gate_disable, .is_enabled = ccu_div_gate_is_enabled, .recalc_rate = ccu_div_fixed_recalc_rate, - .round_rate = ccu_div_fixed_round_rate, + .determine_rate = ccu_div_fixed_determine_rate, .set_rate = ccu_div_fixed_set_rate, .debug_init = ccu_div_gate_debug_init }; @@ -565,7 +570,7 @@ static const struct clk_ops ccu_div_buf_ops = { static const struct clk_ops ccu_div_fixed_ops = { .recalc_rate = ccu_div_fixed_recalc_rate, - .round_rate = ccu_div_fixed_round_rate, + .determine_rate = ccu_div_fixed_determine_rate, .set_rate = ccu_div_fixed_set_rate, .debug_init = ccu_div_fixed_debug_init }; diff --git a/drivers/clk/baikal-t1/ccu-pll.c b/drivers/clk/baikal-t1/ccu-pll.c index 13ef28001439..357269f41cdc 100644 --- a/drivers/clk/baikal-t1/ccu-pll.c +++ b/drivers/clk/baikal-t1/ccu-pll.c @@ -228,14 +228,16 @@ static void ccu_pll_calc_factors(unsigned long rate, unsigned long parent_rate, } } -static long ccu_pll_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *parent_rate) +static int ccu_pll_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { unsigned long nr = 1, nf = 1, od = 1; - ccu_pll_calc_factors(rate, *parent_rate, &nr, &nf, &od); + ccu_pll_calc_factors(req->rate, req->best_parent_rate, &nr, &nf, &od); - return ccu_pll_calc_freq(*parent_rate, nr, nf, od); + req->rate = ccu_pll_calc_freq(req->best_parent_rate, nr, nf, od); + + return 0; } /* @@ -481,7 +483,7 @@ static const struct clk_ops ccu_pll_gate_to_set_ops = { .disable = ccu_pll_disable, .is_enabled = ccu_pll_is_enabled, .recalc_rate = ccu_pll_recalc_rate, - .round_rate = ccu_pll_round_rate, + .determine_rate = ccu_pll_determine_rate, .set_rate = ccu_pll_set_rate_norst, .debug_init = ccu_pll_debug_init }; @@ -491,7 +493,7 @@ static const struct clk_ops ccu_pll_straight_set_ops = { .disable = ccu_pll_disable, .is_enabled = ccu_pll_is_enabled, .recalc_rate = ccu_pll_recalc_rate, - .round_rate = ccu_pll_round_rate, + .determine_rate = ccu_pll_determine_rate, .set_rate = ccu_pll_set_rate_reset, .debug_init = ccu_pll_debug_init }; diff --git a/drivers/clk/bcm/clk-iproc-asiu.c b/drivers/clk/bcm/clk-iproc-asiu.c index dcacf55c55ae..83ec13da9b2e 100644 --- a/drivers/clk/bcm/clk-iproc-asiu.c +++ b/drivers/clk/bcm/clk-iproc-asiu.c @@ -98,22 +98,27 @@ static unsigned long iproc_asiu_clk_recalc_rate(struct clk_hw *hw, return clk->rate; } -static long iproc_asiu_clk_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *parent_rate) +static int iproc_asiu_clk_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { unsigned int div; - if (rate == 0 || *parent_rate == 0) + if (req->rate == 0 || req->best_parent_rate == 0) return -EINVAL; - if (rate == *parent_rate) - return *parent_rate; + if (req->rate == req->best_parent_rate) + return 0; - div = DIV_ROUND_CLOSEST(*parent_rate, rate); - if (div < 2) - return *parent_rate; + div = DIV_ROUND_CLOSEST(req->best_parent_rate, req->rate); + if (div < 2) { + req->rate = req->best_parent_rate; - return *parent_rate / div; + return 0; + } + + req->rate = req->best_parent_rate / div; + + return 0; } static int iproc_asiu_clk_set_rate(struct clk_hw *hw, unsigned long rate, @@ -168,7 +173,7 @@ static const struct clk_ops iproc_asiu_ops = { .enable = iproc_asiu_clk_enable, .disable = iproc_asiu_clk_disable, .recalc_rate = iproc_asiu_clk_recalc_rate, - .round_rate = iproc_asiu_clk_round_rate, + .determine_rate = iproc_asiu_clk_determine_rate, .set_rate = iproc_asiu_clk_set_rate, }; diff --git a/drivers/clk/bcm/clk-raspberrypi.c b/drivers/clk/bcm/clk-raspberrypi.c index 8e4fde03ed23..1a9162f0ae31 100644 --- a/drivers/clk/bcm/clk-raspberrypi.c +++ b/drivers/clk/bcm/clk-raspberrypi.c @@ -68,6 +68,8 @@ struct raspberrypi_clk_variant { char *clkdev; unsigned long min_rate; bool minimize; + bool maximize; + u32 flags; }; static struct raspberrypi_clk_variant @@ -75,6 +77,7 @@ raspberrypi_clk_variants[RPI_FIRMWARE_NUM_CLK_ID] = { [RPI_FIRMWARE_ARM_CLK_ID] = { .export = true, .clkdev = "cpu0", + .flags = CLK_IS_CRITICAL, }, [RPI_FIRMWARE_CORE_CLK_ID] = { .export = true, @@ -90,6 +93,12 @@ raspberrypi_clk_variants[RPI_FIRMWARE_NUM_CLK_ID] = { * always use the minimum the drivers will let us. */ .minimize = true, + + /* + * It should never be disabled as it drives the bus for + * everything else. + */ + .flags = CLK_IS_CRITICAL, }, [RPI_FIRMWARE_M2MC_CLK_ID] = { .export = true, @@ -115,18 +124,29 @@ raspberrypi_clk_variants[RPI_FIRMWARE_NUM_CLK_ID] = { * drivers will let us. */ .minimize = true, + + /* + * As mentioned above, this clock is disabled during boot, + * the firmware will skip the HSM initialization, resulting + * in a bus lockup. Therefore, make sure it's enabled + * during boot, but after it, it can be enabled/disabled + * by the driver. + */ + .flags = CLK_IGNORE_UNUSED, }, [RPI_FIRMWARE_V3D_CLK_ID] = { .export = true, - .minimize = true, + .maximize = true, }, [RPI_FIRMWARE_PIXEL_CLK_ID] = { .export = true, .minimize = true, + .flags = CLK_IS_CRITICAL, }, [RPI_FIRMWARE_HEVC_CLK_ID] = { .export = true, .minimize = true, + .flags = CLK_IS_CRITICAL, }, [RPI_FIRMWARE_ISP_CLK_ID] = { .export = true, @@ -135,6 +155,7 @@ raspberrypi_clk_variants[RPI_FIRMWARE_NUM_CLK_ID] = { [RPI_FIRMWARE_PIXEL_BVB_CLK_ID] = { .export = true, .minimize = true, + .flags = CLK_IS_CRITICAL, }, [RPI_FIRMWARE_VEC_CLK_ID] = { .export = true, @@ -194,8 +215,11 @@ static int raspberrypi_fw_is_prepared(struct clk_hw *hw) ret = raspberrypi_clock_property(rpi->firmware, data, RPI_FIRMWARE_GET_CLOCK_STATE, &val); - if (ret) + if (ret) { + dev_err_ratelimited(rpi->dev, "Failed to get %s state: %d\n", + clk_hw_get_name(hw), ret); return 0; + } return !!(val & RPI_FIRMWARE_STATE_ENABLE_BIT); } @@ -211,8 +235,11 @@ static unsigned long raspberrypi_fw_get_rate(struct clk_hw *hw, ret = raspberrypi_clock_property(rpi->firmware, data, RPI_FIRMWARE_GET_CLOCK_RATE, &val); - if (ret) + if (ret) { + dev_err_ratelimited(rpi->dev, "Failed to get %s frequency: %d\n", + clk_hw_get_name(hw), ret); return 0; + } return val; } @@ -259,7 +286,41 @@ static int raspberrypi_fw_dumb_determine_rate(struct clk_hw *hw, return 0; } +static int raspberrypi_fw_prepare(struct clk_hw *hw) +{ + const struct raspberrypi_clk_data *data = clk_hw_to_data(hw); + struct raspberrypi_clk *rpi = data->rpi; + u32 state = RPI_FIRMWARE_STATE_ENABLE_BIT; + int ret; + + ret = raspberrypi_clock_property(rpi->firmware, data, + RPI_FIRMWARE_SET_CLOCK_STATE, &state); + if (ret) + dev_err_ratelimited(rpi->dev, + "Failed to set clock %s state to on: %d\n", + clk_hw_get_name(hw), ret); + + return ret; +} + +static void raspberrypi_fw_unprepare(struct clk_hw *hw) +{ + const struct raspberrypi_clk_data *data = clk_hw_to_data(hw); + struct raspberrypi_clk *rpi = data->rpi; + u32 state = 0; + int ret; + + ret = raspberrypi_clock_property(rpi->firmware, data, + RPI_FIRMWARE_SET_CLOCK_STATE, &state); + if (ret) + dev_err_ratelimited(rpi->dev, + "Failed to set clock %s state to off: %d\n", + clk_hw_get_name(hw), ret); +} + static const struct clk_ops raspberrypi_firmware_clk_ops = { + .prepare = raspberrypi_fw_prepare, + .unprepare = raspberrypi_fw_unprepare, .is_prepared = raspberrypi_fw_is_prepared, .recalc_rate = raspberrypi_fw_get_rate, .determine_rate = raspberrypi_fw_dumb_determine_rate, @@ -289,7 +350,7 @@ static struct clk_hw *raspberrypi_clk_register(struct raspberrypi_clk *rpi, if (!init.name) return ERR_PTR(-ENOMEM); init.ops = &raspberrypi_firmware_clk_ops; - init.flags = CLK_GET_RATE_NOCACHE; + init.flags = variant->flags | CLK_GET_RATE_NOCACHE; data->hw.init = &init; @@ -326,6 +387,9 @@ static struct clk_hw *raspberrypi_clk_register(struct raspberrypi_clk *rpi, } } + if (variant->maximize) + variant->min_rate = max_rate; + if (variant->min_rate) { unsigned long rate; diff --git a/drivers/clk/clk-apple-nco.c b/drivers/clk/clk-apple-nco.c index 457a48d48941..d3ced4a0f029 100644 --- a/drivers/clk/clk-apple-nco.c +++ b/drivers/clk/clk-apple-nco.c @@ -212,13 +212,15 @@ static unsigned long applnco_recalc_rate(struct clk_hw *hw, ((u64) div) * incbase + inc1); } -static long applnco_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *parent_rate) +static int applnco_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { - unsigned long lo = *parent_rate / (COARSE_DIV_OFFSET + LFSR_TBLSIZE) + 1; - unsigned long hi = *parent_rate / COARSE_DIV_OFFSET; + unsigned long lo = req->best_parent_rate / (COARSE_DIV_OFFSET + LFSR_TBLSIZE) + 1; + unsigned long hi = req->best_parent_rate / COARSE_DIV_OFFSET; - return clamp(rate, lo, hi); + req->rate = clamp(req->rate, lo, hi); + + return 0; } static int applnco_enable(struct clk_hw *hw) @@ -246,7 +248,7 @@ static void applnco_disable(struct clk_hw *hw) static const struct clk_ops applnco_ops = { .set_rate = applnco_set_rate, .recalc_rate = applnco_recalc_rate, - .round_rate = applnco_round_rate, + .determine_rate = applnco_determine_rate, .enable = applnco_enable, .disable = applnco_disable, .is_enabled = applnco_is_enabled, diff --git a/drivers/clk/clk-axi-clkgen.c b/drivers/clk/clk-axi-clkgen.c index aec62301fa06..fa5ccef73e60 100644 --- a/drivers/clk/clk-axi-clkgen.c +++ b/drivers/clk/clk-axi-clkgen.c @@ -540,7 +540,7 @@ static int axi_clkgen_setup_limits(struct axi_clkgen *axi_clkgen, default: return dev_err_probe(dev, -ENODEV, "Unknown speed grade %d\n", speed_grade); - }; + } /* Overwrite vco limits for ultrascale+ */ if (tech == ADI_AXI_FPGA_TECH_ULTRASCALE_PLUS) { diff --git a/drivers/clk/clk-axm5516.c b/drivers/clk/clk-axm5516.c index 4a3462ee8f3e..3823383f3fa6 100644 --- a/drivers/clk/clk-axm5516.c +++ b/drivers/clk/clk-axm5516.c @@ -529,7 +529,6 @@ static const struct regmap_config axmclk_regmap_config = { .reg_stride = 4, .val_bits = 32, .max_register = 0x1fffc, - .fast_io = true, }; static const struct of_device_id axmclk_match_table[] = { diff --git a/drivers/clk/clk-bm1880.c b/drivers/clk/clk-bm1880.c index 002f7360b1c6..dac190bc6e19 100644 --- a/drivers/clk/clk-bm1880.c +++ b/drivers/clk/clk-bm1880.c @@ -608,8 +608,8 @@ static unsigned long bm1880_clk_div_recalc_rate(struct clk_hw *hw, return rate; } -static long bm1880_clk_div_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *prate) +static int bm1880_clk_div_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { struct bm1880_div_hw_clock *div_hw = to_bm1880_div_clk(hw); struct bm1880_div_clock *div = &div_hw->div; @@ -621,13 +621,18 @@ static long bm1880_clk_div_round_rate(struct clk_hw *hw, unsigned long rate, val = readl(reg_addr) >> div->shift; val &= clk_div_mask(div->width); - return divider_ro_round_rate(hw, rate, prate, div->table, - div->width, div->flags, - val); + req->rate = divider_ro_round_rate(hw, req->rate, + &req->best_parent_rate, + div->table, + div->width, div->flags, val); + + return 0; } - return divider_round_rate(hw, rate, prate, div->table, - div->width, div->flags); + req->rate = divider_round_rate(hw, req->rate, &req->best_parent_rate, + div->table, div->width, div->flags); + + return 0; } static int bm1880_clk_div_set_rate(struct clk_hw *hw, unsigned long rate, @@ -665,7 +670,7 @@ static int bm1880_clk_div_set_rate(struct clk_hw *hw, unsigned long rate, static const struct clk_ops bm1880_clk_div_ops = { .recalc_rate = bm1880_clk_div_recalc_rate, - .round_rate = bm1880_clk_div_round_rate, + .determine_rate = bm1880_clk_div_determine_rate, .set_rate = bm1880_clk_div_set_rate, }; diff --git a/drivers/clk/clk-cdce706.c b/drivers/clk/clk-cdce706.c index d0705bb03a2a..a495d313b02f 100644 --- a/drivers/clk/clk-cdce706.c +++ b/drivers/clk/clk-cdce706.c @@ -183,8 +183,8 @@ static unsigned long cdce706_pll_recalc_rate(struct clk_hw *hw, return 0; } -static long cdce706_pll_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *parent_rate) +static int cdce706_pll_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { struct cdce706_hw_data *hwd = to_hw_data(hw); unsigned long mul, div; @@ -192,9 +192,9 @@ static long cdce706_pll_round_rate(struct clk_hw *hw, unsigned long rate, dev_dbg(&hwd->dev_data->client->dev, "%s, rate: %lu, parent_rate: %lu\n", - __func__, rate, *parent_rate); + __func__, req->rate, req->best_parent_rate); - rational_best_approximation(rate, *parent_rate, + rational_best_approximation(req->rate, req->best_parent_rate, CDCE706_PLL_N_MAX, CDCE706_PLL_M_MAX, &mul, &div); hwd->mul = mul; @@ -204,9 +204,11 @@ static long cdce706_pll_round_rate(struct clk_hw *hw, unsigned long rate, "%s, pll: %d, mul: %lu, div: %lu\n", __func__, hwd->idx, mul, div); - res = (u64)*parent_rate * hwd->mul; + res = (u64)req->best_parent_rate * hwd->mul; do_div(res, hwd->div); - return res; + req->rate = res; + + return 0; } static int cdce706_pll_set_rate(struct clk_hw *hw, unsigned long rate, @@ -251,7 +253,7 @@ static int cdce706_pll_set_rate(struct clk_hw *hw, unsigned long rate, static const struct clk_ops cdce706_pll_ops = { .recalc_rate = cdce706_pll_recalc_rate, - .round_rate = cdce706_pll_round_rate, + .determine_rate = cdce706_pll_determine_rate, .set_rate = cdce706_pll_set_rate, }; diff --git a/drivers/clk/clk-cdce925.c b/drivers/clk/clk-cdce925.c index c51818c1af98..0b2ad21e6e4d 100644 --- a/drivers/clk/clk-cdce925.c +++ b/drivers/clk/clk-cdce925.c @@ -128,13 +128,15 @@ static void cdce925_pll_find_rate(unsigned long rate, } } -static long cdce925_pll_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *parent_rate) +static int cdce925_pll_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { u16 n, m; - cdce925_pll_find_rate(rate, *parent_rate, &n, &m); - return (long)cdce925_pll_calculate_rate(*parent_rate, n, m); + cdce925_pll_find_rate(req->rate, req->best_parent_rate, &n, &m); + req->rate = (long)cdce925_pll_calculate_rate(req->best_parent_rate, n, m); + + return 0; } static int cdce925_pll_set_rate(struct clk_hw *hw, unsigned long rate, @@ -266,7 +268,7 @@ static const struct clk_ops cdce925_pll_ops = { .prepare = cdce925_pll_prepare, .unprepare = cdce925_pll_unprepare, .recalc_rate = cdce925_pll_recalc_rate, - .round_rate = cdce925_pll_round_rate, + .determine_rate = cdce925_pll_determine_rate, .set_rate = cdce925_pll_set_rate, }; @@ -420,20 +422,23 @@ static unsigned long cdce925_clk_best_parent_rate( return rate * pdiv_best; } -static long cdce925_clk_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *parent_rate) +static int cdce925_clk_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { - unsigned long l_parent_rate = *parent_rate; - u16 divider = cdce925_calc_divider(rate, l_parent_rate); + unsigned long l_parent_rate = req->best_parent_rate; + u16 divider = cdce925_calc_divider(req->rate, l_parent_rate); - if (l_parent_rate / divider != rate) { - l_parent_rate = cdce925_clk_best_parent_rate(hw, rate); - divider = cdce925_calc_divider(rate, l_parent_rate); - *parent_rate = l_parent_rate; + if (l_parent_rate / divider != req->rate) { + l_parent_rate = cdce925_clk_best_parent_rate(hw, req->rate); + divider = cdce925_calc_divider(req->rate, l_parent_rate); + req->best_parent_rate = l_parent_rate; } if (divider) - return (long)(l_parent_rate / divider); + req->rate = (long)(l_parent_rate / divider); + else + req->rate = 0; + return 0; } @@ -451,7 +456,7 @@ static const struct clk_ops cdce925_clk_ops = { .prepare = cdce925_clk_prepare, .unprepare = cdce925_clk_unprepare, .recalc_rate = cdce925_clk_recalc_rate, - .round_rate = cdce925_clk_round_rate, + .determine_rate = cdce925_clk_determine_rate, .set_rate = cdce925_clk_set_rate, }; @@ -473,14 +478,17 @@ static u16 cdce925_y1_calc_divider(unsigned long rate, return (u16)divider; } -static long cdce925_clk_y1_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *parent_rate) +static int cdce925_clk_y1_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { - unsigned long l_parent_rate = *parent_rate; - u16 divider = cdce925_y1_calc_divider(rate, l_parent_rate); + unsigned long l_parent_rate = req->best_parent_rate; + u16 divider = cdce925_y1_calc_divider(req->rate, l_parent_rate); if (divider) - return (long)(l_parent_rate / divider); + req->rate = (long)(l_parent_rate / divider); + else + req->rate = 0; + return 0; } @@ -498,7 +506,7 @@ static const struct clk_ops cdce925_clk_y1_ops = { .prepare = cdce925_clk_prepare, .unprepare = cdce925_clk_unprepare, .recalc_rate = cdce925_clk_recalc_rate, - .round_rate = cdce925_clk_y1_round_rate, + .determine_rate = cdce925_clk_y1_determine_rate, .set_rate = cdce925_clk_y1_set_rate, }; diff --git a/drivers/clk/clk-cs2000-cp.c b/drivers/clk/clk-cs2000-cp.c index 35cb93ad298a..8800472ba63f 100644 --- a/drivers/clk/clk-cs2000-cp.c +++ b/drivers/clk/clk-cs2000-cp.c @@ -305,15 +305,19 @@ static unsigned long cs2000_recalc_rate(struct clk_hw *hw, return cs2000_ratio_to_rate(ratio, parent_rate, priv->lf_ratio); } -static long cs2000_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *parent_rate) +static int cs2000_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { struct cs2000_priv *priv = hw_to_priv(hw); u32 ratio; - ratio = cs2000_rate_to_ratio(*parent_rate, rate, priv->lf_ratio); + ratio = cs2000_rate_to_ratio(req->best_parent_rate, req->rate, + priv->lf_ratio); - return cs2000_ratio_to_rate(ratio, *parent_rate, priv->lf_ratio); + req->rate = cs2000_ratio_to_rate(ratio, req->best_parent_rate, + priv->lf_ratio); + + return 0; } static int cs2000_select_ratio_mode(struct cs2000_priv *priv, @@ -430,7 +434,7 @@ static u8 cs2000_get_parent(struct clk_hw *hw) static const struct clk_ops cs2000_ops = { .get_parent = cs2000_get_parent, .recalc_rate = cs2000_recalc_rate, - .round_rate = cs2000_round_rate, + .determine_rate = cs2000_determine_rate, .set_rate = cs2000_set_rate, .prepare = cs2000_enable, .unprepare = cs2000_disable, diff --git a/drivers/clk/clk-divider.c b/drivers/clk/clk-divider.c index c1f426b8a504..2601b6155afb 100644 --- a/drivers/clk/clk-divider.c +++ b/drivers/clk/clk-divider.c @@ -431,27 +431,6 @@ long divider_ro_round_rate_parent(struct clk_hw *hw, struct clk_hw *parent, } EXPORT_SYMBOL_GPL(divider_ro_round_rate_parent); -static long clk_divider_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *prate) -{ - struct clk_divider *divider = to_clk_divider(hw); - - /* if read only, just return current value */ - if (divider->flags & CLK_DIVIDER_READ_ONLY) { - u32 val; - - val = clk_div_readl(divider) >> divider->shift; - val &= clk_div_mask(divider->width); - - return divider_ro_round_rate(hw, rate, prate, divider->table, - divider->width, divider->flags, - val); - } - - return divider_round_rate(hw, rate, prate, divider->table, - divider->width, divider->flags); -} - static int clk_divider_determine_rate(struct clk_hw *hw, struct clk_rate_request *req) { @@ -527,7 +506,6 @@ static int clk_divider_set_rate(struct clk_hw *hw, unsigned long rate, const struct clk_ops clk_divider_ops = { .recalc_rate = clk_divider_recalc_rate, - .round_rate = clk_divider_round_rate, .determine_rate = clk_divider_determine_rate, .set_rate = clk_divider_set_rate, }; @@ -535,7 +513,6 @@ EXPORT_SYMBOL_GPL(clk_divider_ops); const struct clk_ops clk_divider_ro_ops = { .recalc_rate = clk_divider_recalc_rate, - .round_rate = clk_divider_round_rate, .determine_rate = clk_divider_determine_rate, }; EXPORT_SYMBOL_GPL(clk_divider_ro_ops); diff --git a/drivers/clk/clk-ep93xx.c b/drivers/clk/clk-ep93xx.c index 4bd8d6ecf6a2..972aadd11493 100644 --- a/drivers/clk/clk-ep93xx.c +++ b/drivers/clk/clk-ep93xx.c @@ -389,23 +389,25 @@ static unsigned long ep93xx_div_recalc_rate(struct clk_hw *hw, return DIV_ROUND_CLOSEST(parent_rate, clk->div[index]); } -static long ep93xx_div_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *parent_rate) +static int ep93xx_div_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { struct ep93xx_clk *clk = ep93xx_clk_from(hw); unsigned long best = 0, now; unsigned int i; for (i = 0; i < clk->num_div; i++) { - if ((rate * clk->div[i]) == *parent_rate) - return rate; + if (req->rate * clk->div[i] == req->best_parent_rate) + return 0; - now = DIV_ROUND_CLOSEST(*parent_rate, clk->div[i]); - if (!best || is_best(rate, now, best)) + now = DIV_ROUND_CLOSEST(req->best_parent_rate, clk->div[i]); + if (!best || is_best(req->rate, now, best)) best = now; } - return best; + req->rate = best; + + return 0; } static int ep93xx_div_set_rate(struct clk_hw *hw, unsigned long rate, @@ -437,7 +439,7 @@ static const struct clk_ops ep93xx_div_ops = { .disable = ep93xx_clk_disable, .is_enabled = ep93xx_clk_is_enabled, .recalc_rate = ep93xx_div_recalc_rate, - .round_rate = ep93xx_div_round_rate, + .determine_rate = ep93xx_div_determine_rate, .set_rate = ep93xx_div_set_rate, }; @@ -486,9 +488,10 @@ static const struct ep93xx_gate ep93xx_uarts[] = { static int ep93xx_uart_clock_init(struct ep93xx_clk_priv *priv) { struct clk_parent_data parent_data = { }; - unsigned int i, idx, ret, clk_uart_div; + unsigned int i, idx, clk_uart_div; struct ep93xx_clk *clk; u32 val; + int ret; regmap_read(priv->map, EP93XX_SYSCON_PWRCNT, &val); if (val & EP93XX_SYSCON_PWRCNT_UARTBAUD) diff --git a/drivers/clk/clk-fixed-factor.c b/drivers/clk/clk-fixed-factor.c index e62ae8794d44..de658c9e4c53 100644 --- a/drivers/clk/clk-fixed-factor.c +++ b/drivers/clk/clk-fixed-factor.c @@ -30,19 +30,21 @@ static unsigned long clk_factor_recalc_rate(struct clk_hw *hw, return (unsigned long)rate; } -static long clk_factor_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *prate) +static int clk_factor_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { struct clk_fixed_factor *fix = to_clk_fixed_factor(hw); if (clk_hw_get_flags(hw) & CLK_SET_RATE_PARENT) { unsigned long best_parent; - best_parent = (rate / fix->mult) * fix->div; - *prate = clk_hw_round_rate(clk_hw_get_parent(hw), best_parent); + best_parent = (req->rate / fix->mult) * fix->div; + req->best_parent_rate = clk_hw_round_rate(clk_hw_get_parent(hw), best_parent); } - return (*prate / fix->div) * fix->mult; + req->rate = (req->best_parent_rate / fix->div) * fix->mult; + + return 0; } static int clk_factor_set_rate(struct clk_hw *hw, unsigned long rate, @@ -50,7 +52,7 @@ static int clk_factor_set_rate(struct clk_hw *hw, unsigned long rate, { /* * We must report success but we can do so unconditionally because - * clk_factor_round_rate returns values that ensure this call is a + * clk_factor_determine_rate returns values that ensure this call is a * nop. */ @@ -69,7 +71,7 @@ static unsigned long clk_factor_recalc_accuracy(struct clk_hw *hw, } const struct clk_ops clk_fixed_factor_ops = { - .round_rate = clk_factor_round_rate, + .determine_rate = clk_factor_determine_rate, .set_rate = clk_factor_set_rate, .recalc_rate = clk_factor_recalc_rate, .recalc_accuracy = clk_factor_recalc_accuracy, diff --git a/drivers/clk/clk-fractional-divider.c b/drivers/clk/clk-fractional-divider.c index da057172cc90..cd36a6e27f25 100644 --- a/drivers/clk/clk-fractional-divider.c +++ b/drivers/clk/clk-fractional-divider.c @@ -151,25 +151,32 @@ void clk_fractional_divider_general_approximation(struct clk_hw *hw, } EXPORT_SYMBOL_GPL(clk_fractional_divider_general_approximation); -static long clk_fd_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *parent_rate) +static int clk_fd_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { struct clk_fractional_divider *fd = to_clk_fd(hw); unsigned long m, n; u64 ret; - if (!rate || (!clk_hw_can_set_rate_parent(hw) && rate >= *parent_rate)) - return *parent_rate; + if (!req->rate || (!clk_hw_can_set_rate_parent(hw) && req->rate >= req->best_parent_rate)) { + req->rate = req->best_parent_rate; + + return 0; + } if (fd->approximation) - fd->approximation(hw, rate, parent_rate, &m, &n); + fd->approximation(hw, req->rate, &req->best_parent_rate, &m, &n); else - clk_fractional_divider_general_approximation(hw, rate, parent_rate, &m, &n); + clk_fractional_divider_general_approximation(hw, req->rate, + &req->best_parent_rate, + &m, &n); - ret = (u64)*parent_rate * m; + ret = (u64)req->best_parent_rate * m; do_div(ret, n); - return ret; + req->rate = ret; + + return 0; } static int clk_fd_set_rate(struct clk_hw *hw, unsigned long rate, @@ -250,7 +257,7 @@ static void clk_fd_debug_init(struct clk_hw *hw, struct dentry *dentry) const struct clk_ops clk_fractional_divider_ops = { .recalc_rate = clk_fd_recalc_rate, - .round_rate = clk_fd_round_rate, + .determine_rate = clk_fd_determine_rate, .set_rate = clk_fd_set_rate, #ifdef CONFIG_DEBUG_FS .debug_init = clk_fd_debug_init, diff --git a/drivers/clk/clk-gemini.c b/drivers/clk/clk-gemini.c index 856b008e07c6..e94589c38568 100644 --- a/drivers/clk/clk-gemini.c +++ b/drivers/clk/clk-gemini.c @@ -126,13 +126,16 @@ static unsigned long gemini_pci_recalc_rate(struct clk_hw *hw, return 33000000; } -static long gemini_pci_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *prate) +static int gemini_pci_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { /* We support 33 and 66 MHz */ - if (rate < 48000000) - return 33000000; - return 66000000; + if (req->rate < 48000000) + req->rate = 33000000; + else + req->rate = 66000000; + + return 0; } static int gemini_pci_set_rate(struct clk_hw *hw, unsigned long rate, @@ -179,7 +182,7 @@ static int gemini_pci_is_enabled(struct clk_hw *hw) static const struct clk_ops gemini_pci_clk_ops = { .recalc_rate = gemini_pci_recalc_rate, - .round_rate = gemini_pci_round_rate, + .determine_rate = gemini_pci_determine_rate, .set_rate = gemini_pci_set_rate, .enable = gemini_pci_enable, .disable = gemini_pci_disable, diff --git a/drivers/clk/clk-highbank.c b/drivers/clk/clk-highbank.c index 6e68a41a70a1..cc583934ecf2 100644 --- a/drivers/clk/clk-highbank.c +++ b/drivers/clk/clk-highbank.c @@ -130,15 +130,17 @@ static void clk_pll_calc(unsigned long rate, unsigned long ref_freq, *pdivf = divf; } -static long clk_pll_round_rate(struct clk_hw *hwclk, unsigned long rate, - unsigned long *parent_rate) +static int clk_pll_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { u32 divq, divf; - unsigned long ref_freq = *parent_rate; + unsigned long ref_freq = req->best_parent_rate; - clk_pll_calc(rate, ref_freq, &divq, &divf); + clk_pll_calc(req->rate, ref_freq, &divq, &divf); - return (ref_freq * (divf + 1)) / (1 << divq); + req->rate = (ref_freq * (divf + 1)) / (1 << divq); + + return 0; } static int clk_pll_set_rate(struct clk_hw *hwclk, unsigned long rate, @@ -185,7 +187,7 @@ static const struct clk_ops clk_pll_ops = { .enable = clk_pll_enable, .disable = clk_pll_disable, .recalc_rate = clk_pll_recalc_rate, - .round_rate = clk_pll_round_rate, + .determine_rate = clk_pll_determine_rate, .set_rate = clk_pll_set_rate, }; @@ -227,16 +229,18 @@ static unsigned long clk_periclk_recalc_rate(struct clk_hw *hwclk, return parent_rate / div; } -static long clk_periclk_round_rate(struct clk_hw *hwclk, unsigned long rate, - unsigned long *parent_rate) +static int clk_periclk_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { u32 div; - div = *parent_rate / rate; + div = req->best_parent_rate / req->rate; div++; div &= ~0x1; - return *parent_rate / div; + req->rate = req->best_parent_rate / div; + + return 0; } static int clk_periclk_set_rate(struct clk_hw *hwclk, unsigned long rate, @@ -255,7 +259,7 @@ static int clk_periclk_set_rate(struct clk_hw *hwclk, unsigned long rate, static const struct clk_ops periclk_ops = { .recalc_rate = clk_periclk_recalc_rate, - .round_rate = clk_periclk_round_rate, + .determine_rate = clk_periclk_determine_rate, .set_rate = clk_periclk_set_rate, }; diff --git a/drivers/clk/clk-hsdk-pll.c b/drivers/clk/clk-hsdk-pll.c index 921523fc26f2..7d56a47c2aa7 100644 --- a/drivers/clk/clk-hsdk-pll.c +++ b/drivers/clk/clk-hsdk-pll.c @@ -197,8 +197,8 @@ static unsigned long hsdk_pll_recalc_rate(struct clk_hw *hw, return rate; } -static long hsdk_pll_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *prate) +static int hsdk_pll_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { int i; unsigned long best_rate; @@ -211,13 +211,15 @@ static long hsdk_pll_round_rate(struct clk_hw *hw, unsigned long rate, best_rate = pll_cfg[0].rate; for (i = 1; pll_cfg[i].rate != 0; i++) { - if (abs(rate - pll_cfg[i].rate) < abs(rate - best_rate)) + if (abs(req->rate - pll_cfg[i].rate) < abs(req->rate - best_rate)) best_rate = pll_cfg[i].rate; } dev_dbg(clk->dev, "chosen best rate: %lu\n", best_rate); - return best_rate; + req->rate = best_rate; + + return 0; } static int hsdk_pll_comm_update_rate(struct hsdk_pll_clk *clk, @@ -296,7 +298,7 @@ static int hsdk_pll_set_rate(struct clk_hw *hw, unsigned long rate, static const struct clk_ops hsdk_pll_ops = { .recalc_rate = hsdk_pll_recalc_rate, - .round_rate = hsdk_pll_round_rate, + .determine_rate = hsdk_pll_determine_rate, .set_rate = hsdk_pll_set_rate, }; diff --git a/drivers/clk/clk-lmk04832.c b/drivers/clk/clk-lmk04832.c index 2bcf422f0b04..b2107b31efa2 100644 --- a/drivers/clk/clk-lmk04832.c +++ b/drivers/clk/clk-lmk04832.c @@ -491,28 +491,33 @@ static long lmk04832_calc_pll2_params(unsigned long prate, unsigned long rate, return DIV_ROUND_CLOSEST(prate * 2 * pll2_p * pll2_n, pll2_r); } -static long lmk04832_vco_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *prate) +static int lmk04832_vco_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { struct lmk04832 *lmk = container_of(hw, struct lmk04832, vco); unsigned int n, p, r; long vco_rate; int ret; - ret = lmk04832_check_vco_ranges(lmk, rate); + ret = lmk04832_check_vco_ranges(lmk, req->rate); if (ret < 0) return ret; - vco_rate = lmk04832_calc_pll2_params(*prate, rate, &n, &p, &r); + vco_rate = lmk04832_calc_pll2_params(req->best_parent_rate, req->rate, + &n, &p, &r); if (vco_rate < 0) { dev_err(lmk->dev, "PLL2 parameters out of range\n"); - return vco_rate; + req->rate = vco_rate; + + return 0; } - if (rate != vco_rate) + if (req->rate != vco_rate) return -EINVAL; - return vco_rate; + req->rate = vco_rate; + + return 0; } static int lmk04832_vco_set_rate(struct clk_hw *hw, unsigned long rate, @@ -579,7 +584,7 @@ static const struct clk_ops lmk04832_vco_ops = { .prepare = lmk04832_vco_prepare, .unprepare = lmk04832_vco_unprepare, .recalc_rate = lmk04832_vco_recalc_rate, - .round_rate = lmk04832_vco_round_rate, + .determine_rate = lmk04832_vco_determine_rate, .set_rate = lmk04832_vco_set_rate, }; @@ -888,25 +893,27 @@ static unsigned long lmk04832_sclk_recalc_rate(struct clk_hw *hw, return DIV_ROUND_CLOSEST(prate, sysref_div); } -static long lmk04832_sclk_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *prate) +static int lmk04832_sclk_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { struct lmk04832 *lmk = container_of(hw, struct lmk04832, sclk); unsigned long sclk_rate; unsigned int sysref_div; - sysref_div = DIV_ROUND_CLOSEST(*prate, rate); - sclk_rate = DIV_ROUND_CLOSEST(*prate, sysref_div); + sysref_div = DIV_ROUND_CLOSEST(req->best_parent_rate, req->rate); + sclk_rate = DIV_ROUND_CLOSEST(req->best_parent_rate, sysref_div); if (sysref_div < 0x07 || sysref_div > 0x1fff) { dev_err(lmk->dev, "SYSREF divider out of range\n"); return -EINVAL; } - if (rate != sclk_rate) + if (req->rate != sclk_rate) return -EINVAL; - return sclk_rate; + req->rate = sclk_rate; + + return 0; } static int lmk04832_sclk_set_rate(struct clk_hw *hw, unsigned long rate, @@ -945,7 +952,7 @@ static const struct clk_ops lmk04832_sclk_ops = { .prepare = lmk04832_sclk_prepare, .unprepare = lmk04832_sclk_unprepare, .recalc_rate = lmk04832_sclk_recalc_rate, - .round_rate = lmk04832_sclk_round_rate, + .determine_rate = lmk04832_sclk_determine_rate, .set_rate = lmk04832_sclk_set_rate, }; @@ -1069,26 +1076,28 @@ static unsigned long lmk04832_dclk_recalc_rate(struct clk_hw *hw, return rate; } -static long lmk04832_dclk_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *prate) +static int lmk04832_dclk_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { struct lmk_dclk *dclk = container_of(hw, struct lmk_dclk, hw); struct lmk04832 *lmk = dclk->lmk; unsigned long dclk_rate; unsigned int dclk_div; - dclk_div = DIV_ROUND_CLOSEST(*prate, rate); - dclk_rate = DIV_ROUND_CLOSEST(*prate, dclk_div); + dclk_div = DIV_ROUND_CLOSEST(req->best_parent_rate, req->rate); + dclk_rate = DIV_ROUND_CLOSEST(req->best_parent_rate, dclk_div); if (dclk_div < 1 || dclk_div > 0x3ff) { dev_err(lmk->dev, "%s_div out of range\n", clk_hw_get_name(hw)); return -EINVAL; } - if (rate != dclk_rate) + if (req->rate != dclk_rate) return -EINVAL; - return dclk_rate; + req->rate = dclk_rate; + + return 0; } static int lmk04832_dclk_set_rate(struct clk_hw *hw, unsigned long rate, @@ -1158,7 +1167,7 @@ static const struct clk_ops lmk04832_dclk_ops = { .prepare = lmk04832_dclk_prepare, .unprepare = lmk04832_dclk_unprepare, .recalc_rate = lmk04832_dclk_recalc_rate, - .round_rate = lmk04832_dclk_round_rate, + .determine_rate = lmk04832_dclk_determine_rate, .set_rate = lmk04832_dclk_set_rate, }; diff --git a/drivers/clk/clk-loongson1.c b/drivers/clk/clk-loongson1.c index a3467aa6790f..f9f060d08a5f 100644 --- a/drivers/clk/clk-loongson1.c +++ b/drivers/clk/clk-loongson1.c @@ -93,14 +93,16 @@ static unsigned long ls1x_divider_recalc_rate(struct clk_hw *hw, d->flags, d->width); } -static long ls1x_divider_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *prate) +static int ls1x_divider_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { struct ls1x_clk *ls1x_clk = to_ls1x_clk(hw); const struct ls1x_clk_div_data *d = ls1x_clk->data; - return divider_round_rate(hw, rate, prate, d->table, - d->width, d->flags); + req->rate = divider_round_rate(hw, req->rate, &req->best_parent_rate, + d->table, d->width, d->flags); + + return 0; } static int ls1x_divider_set_rate(struct clk_hw *hw, unsigned long rate, @@ -146,7 +148,7 @@ static int ls1x_divider_set_rate(struct clk_hw *hw, unsigned long rate, static const struct clk_ops ls1x_clk_divider_ops = { .recalc_rate = ls1x_divider_recalc_rate, - .round_rate = ls1x_divider_round_rate, + .determine_rate = ls1x_divider_determine_rate, .set_rate = ls1x_divider_set_rate, }; diff --git a/drivers/clk/clk-loongson2.c b/drivers/clk/clk-loongson2.c index 27e632edd484..9c4c6c99db3e 100644 --- a/drivers/clk/clk-loongson2.c +++ b/drivers/clk/clk-loongson2.c @@ -13,10 +13,6 @@ #include <linux/io-64-nonatomic-lo-hi.h> #include <dt-bindings/clock/loongson,ls2k-clk.h> -static const struct clk_parent_data pdata[] = { - { .fw_name = "ref_100m", }, -}; - enum loongson2_clk_type { CLK_TYPE_PLL, CLK_TYPE_SCALE, @@ -42,6 +38,7 @@ struct loongson2_clk_data { u8 div_width; u8 mult_shift; u8 mult_width; + u8 bit_idx; }; struct loongson2_clk_board_info { @@ -50,6 +47,7 @@ struct loongson2_clk_board_info { const char *name; const char *parent_name; unsigned long fixed_rate; + unsigned long flags; u8 reg_offset; u8 div_shift; u8 div_width; @@ -95,6 +93,19 @@ struct loongson2_clk_board_info { .div_width = _dwidth, \ } +#define CLK_SCALE_MODE(_id, _name, _pname, _offset, \ + _dshift, _dwidth, _midx) \ + { \ + .id = _id, \ + .type = CLK_TYPE_SCALE, \ + .name = _name, \ + .parent_name = _pname, \ + .reg_offset = _offset, \ + .div_shift = _dshift, \ + .div_width = _dwidth, \ + .bit_idx = _midx + 1, \ + } + #define CLK_GATE(_id, _name, _pname, _offset, _bidx) \ { \ .id = _id, \ @@ -105,6 +116,18 @@ struct loongson2_clk_board_info { .bit_idx = _bidx, \ } +#define CLK_GATE_FLAGS(_id, _name, _pname, _offset, _bidx, \ + _flags) \ + { \ + .id = _id, \ + .type = CLK_TYPE_GATE, \ + .name = _name, \ + .parent_name = _pname, \ + .reg_offset = _offset, \ + .bit_idx = _bidx, \ + .flags = _flags \ + } + #define CLK_FIXED(_id, _name, _pname, _rate) \ { \ .id = _id, \ @@ -114,6 +137,51 @@ struct loongson2_clk_board_info { .fixed_rate = _rate, \ } +static const struct loongson2_clk_board_info ls2k0300_clks[] = { + /* Reference Clock */ + CLK_PLL(LS2K0300_NODE_PLL, "pll_node", 0x00, 15, 9, 8, 7), + CLK_PLL(LS2K0300_DDR_PLL, "pll_ddr", 0x08, 15, 9, 8, 7), + CLK_PLL(LS2K0300_PIX_PLL, "pll_pix", 0x10, 15, 9, 8, 7), + CLK_FIXED(LS2K0300_CLK_STABLE, "clk_stable", NULL, 100000000), + CLK_FIXED(LS2K0300_CLK_THSENS, "clk_thsens", NULL, 10000000), + /* Node PLL */ + CLK_DIV(LS2K0300_CLK_NODE_DIV, "clk_node_div", "pll_node", 0x00, 24, 7), + CLK_DIV(LS2K0300_CLK_GMAC_DIV, "clk_gmac_div", "pll_node", 0x04, 0, 7), + CLK_DIV(LS2K0300_CLK_I2S_DIV, "clk_i2s_div", "pll_node", 0x04, 8, 7), + CLK_GATE(LS2K0300_CLK_NODE_PLL_GATE, "clk_node_pll_gate", "clk_node_div", 0x00, 0), + CLK_GATE(LS2K0300_CLK_GMAC_GATE, "clk_gmac_gate", "clk_gmac_div", 0x00, 1), + CLK_GATE(LS2K0300_CLK_I2S_GATE, "clk_i2s_gate", "clk_i2s_div", 0x00, 2), + CLK_GATE_FLAGS(LS2K0300_CLK_NODE_GATE, "clk_node_gate", "clk_node_scale", 0x24, 0, + CLK_IS_CRITICAL), + CLK_SCALE_MODE(LS2K0300_CLK_NODE_SCALE, "clk_node_scale", "clk_node_pll_gate", 0x20, 0, 3, + 3), + /* DDR PLL */ + CLK_DIV(LS2K0300_CLK_DDR_DIV, "clk_ddr_div", "pll_ddr", 0x08, 24, 7), + CLK_DIV(LS2K0300_CLK_NET_DIV, "clk_net_div", "pll_ddr", 0x0c, 0, 7), + CLK_DIV(LS2K0300_CLK_DEV_DIV, "clk_dev_div", "pll_ddr", 0x0c, 8, 7), + CLK_GATE(LS2K0300_CLK_NET_GATE, "clk_net_gate", "clk_net_div", 0x08, 1), + CLK_GATE(LS2K0300_CLK_DEV_GATE, "clk_dev_gate", "clk_dev_div", 0x08, 2), + CLK_GATE_FLAGS(LS2K0300_CLK_DDR_GATE, "clk_ddr_gate", "clk_ddr_div", 0x08, 0, + CLK_IS_CRITICAL), + /* PIX PLL */ + CLK_DIV(LS2K0300_CLK_PIX_DIV, "clk_pix_div", "pll_pix", 0x10, 24, 7), + CLK_DIV(LS2K0300_CLK_GMACBP_DIV, "clk_gmacbp_div", "pll_pix", 0x14, 0, 7), + CLK_GATE(LS2K0300_CLK_PIX_PLL_GATE, "clk_pix_pll_gate", "clk_pix_div", 0x10, 0), + CLK_GATE(LS2K0300_CLK_PIX_GATE, "clk_pix_gate", "clk_pix_scale", 0x24, 6), + CLK_GATE(LS2K0300_CLK_GMACBP_GATE, "clk_gmacbp_gate", "clk_gmacbp_div", 0x10, 1), + CLK_SCALE_MODE(LS2K0300_CLK_PIX_SCALE, "clk_pix_scale", "clk_pix_pll_gate", 0x20, 4, 3, 7), + /* clk_dev_gate */ + CLK_DIV(LS2K0300_CLK_SDIO_SCALE, "clk_sdio_scale", "clk_dev_gate", 0x20, 24, 4), + CLK_GATE(LS2K0300_CLK_USB_GATE, "clk_usb_gate", "clk_usb_scale", 0x24, 2), + CLK_GATE(LS2K0300_CLK_SDIO_GATE, "clk_sdio_gate", "clk_sdio_scale", 0x24, 4), + CLK_GATE(LS2K0300_CLK_APB_GATE, "clk_apb_gate", "clk_apb_scale", 0x24, 3), + CLK_GATE_FLAGS(LS2K0300_CLK_BOOT_GATE, "clk_boot_gate", "clk_boot_scale", 0x24, 1, + CLK_IS_CRITICAL), + CLK_SCALE_MODE(LS2K0300_CLK_USB_SCALE, "clk_usb_scale", "clk_dev_gate", 0x20, 12, 3, 15), + CLK_SCALE_MODE(LS2K0300_CLK_APB_SCALE, "clk_apb_scale", "clk_dev_gate", 0x20, 16, 3, 19), + CLK_SCALE_MODE(LS2K0300_CLK_BOOT_SCALE, "clk_boot_scale", "clk_dev_gate", 0x20, 8, 3, 11), +}; + static const struct loongson2_clk_board_info ls2k0500_clks[] = { CLK_PLL(LOONGSON2_NODE_PLL, "pll_node", 0, 16, 8, 8, 6), CLK_PLL(LOONGSON2_DDR_PLL, "pll_ddr", 0x8, 16, 8, 8, 6), @@ -230,20 +298,26 @@ static const struct clk_ops loongson2_pll_recalc_ops = { static unsigned long loongson2_freqscale_recalc_rate(struct clk_hw *hw, unsigned long parent_rate) { - u64 val, mult; + u64 val, scale; + u32 mode = 0; struct loongson2_clk_data *clk = to_loongson2_clk(hw); val = readq(clk->reg); - mult = loongson2_rate_part(val, clk->div_shift, clk->div_width) + 1; + scale = loongson2_rate_part(val, clk->div_shift, clk->div_width) + 1; + + if (clk->bit_idx) + mode = val & BIT(clk->bit_idx - 1); - return div_u64((u64)parent_rate * mult, 8); + return mode == 0 ? div_u64((u64)parent_rate * scale, 8) : + div_u64((u64)parent_rate, scale); } static const struct clk_ops loongson2_freqscale_recalc_ops = { .recalc_rate = loongson2_freqscale_recalc_rate, }; -static struct clk_hw *loongson2_clk_register(struct loongson2_clk_provider *clp, +static struct clk_hw *loongson2_clk_register(const char *parent, + struct loongson2_clk_provider *clp, const struct loongson2_clk_board_info *cld, const struct clk_ops *ops) { @@ -260,17 +334,14 @@ static struct clk_hw *loongson2_clk_register(struct loongson2_clk_provider *clp, init.ops = ops; init.flags = 0; init.num_parents = 1; - - if (!cld->parent_name) - init.parent_data = pdata; - else - init.parent_names = &cld->parent_name; + init.parent_names = &parent; clk->reg = clp->base + cld->reg_offset; clk->div_shift = cld->div_shift; clk->div_width = cld->div_width; clk->mult_shift = cld->mult_shift; clk->mult_width = cld->mult_width; + clk->bit_idx = cld->bit_idx; clk->hw.init = &init; hw = &clk->hw; @@ -288,11 +359,17 @@ static int loongson2_clk_probe(struct platform_device *pdev) struct device *dev = &pdev->dev; struct loongson2_clk_provider *clp; const struct loongson2_clk_board_info *p, *data; + const char *refclk_name, *parent_name; data = device_get_match_data(dev); if (!data) return -EINVAL; + refclk_name = of_clk_get_parent_name(dev->of_node, 0); + if (IS_ERR(refclk_name)) + return dev_err_probe(dev, PTR_ERR(refclk_name), + "failed to get refclk name\n"); + for (p = data; p->name; p++) clks_num = max(clks_num, p->id + 1); @@ -314,32 +391,36 @@ static int loongson2_clk_probe(struct platform_device *pdev) for (i = 0; i < clks_num; i++) { p = &data[i]; + parent_name = p->parent_name ? p->parent_name : refclk_name; + switch (p->type) { case CLK_TYPE_PLL: - hw = loongson2_clk_register(clp, p, + hw = loongson2_clk_register(parent_name, clp, p, &loongson2_pll_recalc_ops); break; case CLK_TYPE_SCALE: - hw = loongson2_clk_register(clp, p, + hw = loongson2_clk_register(parent_name, clp, p, &loongson2_freqscale_recalc_ops); break; case CLK_TYPE_DIVIDER: hw = devm_clk_hw_register_divider(dev, p->name, - p->parent_name, 0, + parent_name, 0, clp->base + p->reg_offset, p->div_shift, p->div_width, - CLK_DIVIDER_ONE_BASED, + CLK_DIVIDER_ONE_BASED | + CLK_DIVIDER_ALLOW_ZERO, &clp->clk_lock); break; case CLK_TYPE_GATE: - hw = devm_clk_hw_register_gate(dev, p->name, p->parent_name, 0, + hw = devm_clk_hw_register_gate(dev, p->name, parent_name, + p->flags, clp->base + p->reg_offset, p->bit_idx, 0, &clp->clk_lock); break; case CLK_TYPE_FIXED: - hw = devm_clk_hw_register_fixed_rate_parent_data(dev, p->name, pdata, - 0, p->fixed_rate); + hw = devm_clk_hw_register_fixed_rate(dev, p->name, parent_name, + 0, p->fixed_rate); break; default: return dev_err_probe(dev, -EINVAL, "Invalid clk type\n"); @@ -357,6 +438,7 @@ static int loongson2_clk_probe(struct platform_device *pdev) } static const struct of_device_id loongson2_clk_match_table[] = { + { .compatible = "loongson,ls2k0300-clk", .data = &ls2k0300_clks }, { .compatible = "loongson,ls2k0500-clk", .data = &ls2k0500_clks }, { .compatible = "loongson,ls2k-clk", .data = &ls2k1000_clks }, { .compatible = "loongson,ls2k2000-clk", .data = &ls2k2000_clks }, diff --git a/drivers/clk/clk-max9485.c b/drivers/clk/clk-max9485.c index be9020b6c789..0515e3e41162 100644 --- a/drivers/clk/clk-max9485.c +++ b/drivers/clk/clk-max9485.c @@ -159,29 +159,32 @@ static unsigned long max9485_clkout_recalc_rate(struct clk_hw *hw, return 0; } -static long max9485_clkout_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *parent_rate) +static int max9485_clkout_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { const struct max9485_rate *curr, *prev = NULL; for (curr = max9485_rates; curr->out != 0; curr++) { /* Exact matches */ - if (curr->out == rate) - return rate; + if (curr->out == req->rate) + return 0; /* * Find the first entry that has a frequency higher than the * requested one. */ - if (curr->out > rate) { + if (curr->out > req->rate) { unsigned int mid; /* * If this is the first entry, clamp the value to the * lowest possible frequency. */ - if (!prev) - return curr->out; + if (!prev) { + req->rate = curr->out; + + return 0; + } /* * Otherwise, determine whether the previous entry or @@ -189,14 +192,18 @@ static long max9485_clkout_round_rate(struct clk_hw *hw, unsigned long rate, */ mid = prev->out + ((curr->out - prev->out) / 2); - return (mid > rate) ? prev->out : curr->out; + req->rate = mid > req->rate ? prev->out : curr->out; + + return 0; } prev = curr; } /* If the last entry was still too high, clamp the value */ - return prev->out; + req->rate = prev->out; + + return 0; } struct max9485_clk { @@ -221,7 +228,7 @@ static const struct max9485_clk max9485_clks[MAX9485_NUM_CLKS] = { .parent_index = -1, .ops = { .set_rate = max9485_clkout_set_rate, - .round_rate = max9485_clkout_round_rate, + .determine_rate = max9485_clkout_determine_rate, .recalc_rate = max9485_clkout_recalc_rate, }, }, diff --git a/drivers/clk/clk-milbeaut.c b/drivers/clk/clk-milbeaut.c index 18c20aff45f7..b4f9b7143eaa 100644 --- a/drivers/clk/clk-milbeaut.c +++ b/drivers/clk/clk-milbeaut.c @@ -386,8 +386,8 @@ static unsigned long m10v_clk_divider_recalc_rate(struct clk_hw *hw, divider->flags, divider->width); } -static long m10v_clk_divider_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *prate) +static int m10v_clk_divider_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { struct m10v_clk_divider *divider = to_m10v_div(hw); @@ -398,13 +398,19 @@ static long m10v_clk_divider_round_rate(struct clk_hw *hw, unsigned long rate, val = readl(divider->reg) >> divider->shift; val &= clk_div_mask(divider->width); - return divider_ro_round_rate(hw, rate, prate, divider->table, - divider->width, divider->flags, - val); + req->rate = divider_ro_round_rate(hw, req->rate, + &req->best_parent_rate, + divider->table, + divider->width, + divider->flags, val); + + return 0; } - return divider_round_rate(hw, rate, prate, divider->table, - divider->width, divider->flags); + req->rate = divider_round_rate(hw, req->rate, &req->best_parent_rate, + divider->table, divider->width, divider->flags); + + return 0; } static int m10v_clk_divider_set_rate(struct clk_hw *hw, unsigned long rate, @@ -450,7 +456,7 @@ static int m10v_clk_divider_set_rate(struct clk_hw *hw, unsigned long rate, static const struct clk_ops m10v_clk_divider_ops = { .recalc_rate = m10v_clk_divider_recalc_rate, - .round_rate = m10v_clk_divider_round_rate, + .determine_rate = m10v_clk_divider_determine_rate, .set_rate = m10v_clk_divider_set_rate, }; diff --git a/drivers/clk/clk-multiplier.c b/drivers/clk/clk-multiplier.c index e507aa958da9..6f2955d408b6 100644 --- a/drivers/clk/clk-multiplier.c +++ b/drivers/clk/clk-multiplier.c @@ -112,14 +112,16 @@ static unsigned long __bestmult(struct clk_hw *hw, unsigned long rate, return bestmult; } -static long clk_multiplier_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *parent_rate) +static int clk_multiplier_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { struct clk_multiplier *mult = to_clk_multiplier(hw); - unsigned long factor = __bestmult(hw, rate, parent_rate, + unsigned long factor = __bestmult(hw, req->rate, &req->best_parent_rate, mult->width, mult->flags); - return *parent_rate * factor; + req->rate = req->best_parent_rate * factor; + + return 0; } static int clk_multiplier_set_rate(struct clk_hw *hw, unsigned long rate, @@ -150,7 +152,7 @@ static int clk_multiplier_set_rate(struct clk_hw *hw, unsigned long rate, const struct clk_ops clk_multiplier_ops = { .recalc_rate = clk_multiplier_recalc_rate, - .round_rate = clk_multiplier_round_rate, + .determine_rate = clk_multiplier_determine_rate, .set_rate = clk_multiplier_set_rate, }; EXPORT_SYMBOL_GPL(clk_multiplier_ops); diff --git a/drivers/clk/clk-s2mps11.c b/drivers/clk/clk-s2mps11.c index d4e9c3577b35..ff7ce12a5da6 100644 --- a/drivers/clk/clk-s2mps11.c +++ b/drivers/clk/clk-s2mps11.c @@ -11,6 +11,7 @@ #include <linux/regmap.h> #include <linux/clk-provider.h> #include <linux/platform_device.h> +#include <linux/mfd/samsung/s2mpg10.h> #include <linux/mfd/samsung/s2mps11.h> #include <linux/mfd/samsung/s2mps13.h> #include <linux/mfd/samsung/s2mps14.h> @@ -140,6 +141,9 @@ static int s2mps11_clk_probe(struct platform_device *pdev) clk_data->num = S2MPS11_CLKS_NUM; switch (hwid) { + case S2MPG10: + s2mps11_reg = S2MPG10_PMIC_RTCBUF; + break; case S2MPS11X: s2mps11_reg = S2MPS11_REG_RTC_CTRL; break; @@ -221,6 +225,7 @@ static void s2mps11_clk_remove(struct platform_device *pdev) } static const struct platform_device_id s2mps11_clk_id[] = { + { "s2mpg10-clk", S2MPG10}, { "s2mps11-clk", S2MPS11X}, { "s2mps13-clk", S2MPS13X}, { "s2mps14-clk", S2MPS14X}, @@ -241,6 +246,9 @@ MODULE_DEVICE_TABLE(platform, s2mps11_clk_id); */ static const struct of_device_id s2mps11_dt_match[] __used = { { + .compatible = "samsung,s2mpg10-clk", + .data = (void *)S2MPG10, + }, { .compatible = "samsung,s2mps11-clk", .data = (void *)S2MPS11X, }, { diff --git a/drivers/clk/clk-scmi.c b/drivers/clk/clk-scmi.c index d2408403283f..6b286ea6f121 100644 --- a/drivers/clk/clk-scmi.c +++ b/drivers/clk/clk-scmi.c @@ -54,8 +54,8 @@ static unsigned long scmi_clk_recalc_rate(struct clk_hw *hw, return rate; } -static long scmi_clk_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *parent_rate) +static int scmi_clk_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { u64 fmin, fmax, ftmp; struct scmi_clk *clk = to_scmi_clk(hw); @@ -67,20 +67,27 @@ static long scmi_clk_round_rate(struct clk_hw *hw, unsigned long rate, * running at then. */ if (clk->info->rate_discrete) - return rate; + return 0; fmin = clk->info->range.min_rate; fmax = clk->info->range.max_rate; - if (rate <= fmin) - return fmin; - else if (rate >= fmax) - return fmax; + if (req->rate <= fmin) { + req->rate = fmin; + + return 0; + } else if (req->rate >= fmax) { + req->rate = fmax; + + return 0; + } - ftmp = rate - fmin; + ftmp = req->rate - fmin; ftmp += clk->info->range.step_size - 1; /* to round up */ do_div(ftmp, clk->info->range.step_size); - return ftmp * clk->info->range.step_size + fmin; + req->rate = ftmp * clk->info->range.step_size + fmin; + + return 0; } static int scmi_clk_set_rate(struct clk_hw *hw, unsigned long rate, @@ -119,15 +126,6 @@ static u8 scmi_clk_get_parent(struct clk_hw *hw) return p_idx; } -static int scmi_clk_determine_rate(struct clk_hw *hw, struct clk_rate_request *req) -{ - /* - * Suppose all the requested rates are supported, and let firmware - * to handle the left work. - */ - return 0; -} - static int scmi_clk_enable(struct clk_hw *hw) { struct scmi_clk *clk = to_scmi_clk(hw); @@ -300,7 +298,6 @@ scmi_clk_ops_alloc(struct device *dev, unsigned long feats_key) /* Rate ops */ ops->recalc_rate = scmi_clk_recalc_rate; - ops->round_rate = scmi_clk_round_rate; ops->determine_rate = scmi_clk_determine_rate; if (feats_key & BIT(SCMI_CLK_RATE_CTRL_SUPPORTED)) ops->set_rate = scmi_clk_set_rate; @@ -349,6 +346,8 @@ scmi_clk_ops_select(struct scmi_clk *sclk, bool atomic_capable, unsigned int atomic_threshold_us, const struct clk_ops **clk_ops_db, size_t db_size) { + int ret; + u32 val; const struct scmi_clock_info *ci = sclk->info; unsigned int feats_key = 0; const struct clk_ops *ops; @@ -370,8 +369,13 @@ scmi_clk_ops_select(struct scmi_clk *sclk, bool atomic_capable, if (!ci->parent_ctrl_forbidden) feats_key |= BIT(SCMI_CLK_PARENT_CTRL_SUPPORTED); - if (ci->extended_config) - feats_key |= BIT(SCMI_CLK_DUTY_CYCLE_SUPPORTED); + if (ci->extended_config) { + ret = scmi_proto_clk_ops->config_oem_get(sclk->ph, sclk->id, + SCMI_CLOCK_CFG_DUTY_CYCLE, + &val, NULL, false); + if (!ret) + feats_key |= BIT(SCMI_CLK_DUTY_CYCLE_SUPPORTED); + } if (WARN_ON(feats_key >= db_size)) return NULL; diff --git a/drivers/clk/clk-scpi.c b/drivers/clk/clk-scpi.c index 19d530d52e64..0b592de7bdb2 100644 --- a/drivers/clk/clk-scpi.c +++ b/drivers/clk/clk-scpi.c @@ -32,8 +32,8 @@ static unsigned long scpi_clk_recalc_rate(struct clk_hw *hw, return clk->scpi_ops->clk_get_val(clk->id); } -static long scpi_clk_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *parent_rate) +static int scpi_clk_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { /* * We can't figure out what rate it will be, so just return the @@ -41,7 +41,7 @@ static long scpi_clk_round_rate(struct clk_hw *hw, unsigned long rate, * after the rate is set and we'll know what rate the clock is * running at then. */ - return rate; + return 0; } static int scpi_clk_set_rate(struct clk_hw *hw, unsigned long rate, @@ -54,7 +54,7 @@ static int scpi_clk_set_rate(struct clk_hw *hw, unsigned long rate, static const struct clk_ops scpi_clk_ops = { .recalc_rate = scpi_clk_recalc_rate, - .round_rate = scpi_clk_round_rate, + .determine_rate = scpi_clk_determine_rate, .set_rate = scpi_clk_set_rate, }; @@ -92,12 +92,14 @@ static unsigned long scpi_dvfs_recalc_rate(struct clk_hw *hw, return opp->freq; } -static long scpi_dvfs_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *parent_rate) +static int scpi_dvfs_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { struct scpi_clk *clk = to_scpi_clk(hw); - return __scpi_dvfs_round_rate(clk, rate); + req->rate = __scpi_dvfs_round_rate(clk, req->rate); + + return 0; } static int __scpi_find_dvfs_index(struct scpi_clk *clk, unsigned long rate) @@ -124,7 +126,7 @@ static int scpi_dvfs_set_rate(struct clk_hw *hw, unsigned long rate, static const struct clk_ops scpi_dvfs_ops = { .recalc_rate = scpi_dvfs_recalc_rate, - .round_rate = scpi_dvfs_round_rate, + .determine_rate = scpi_dvfs_determine_rate, .set_rate = scpi_dvfs_set_rate, }; diff --git a/drivers/clk/clk-si514.c b/drivers/clk/clk-si514.c index 1127c35ce57d..f61590d70575 100644 --- a/drivers/clk/clk-si514.c +++ b/drivers/clk/clk-si514.c @@ -227,20 +227,28 @@ static unsigned long si514_recalc_rate(struct clk_hw *hw, return si514_calc_rate(&settings); } -static long si514_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *parent_rate) +static int si514_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { struct clk_si514_muldiv settings; int err; - if (!rate) + if (!req->rate) { + req->rate = 0; + return 0; + } - err = si514_calc_muldiv(&settings, rate); - if (err) - return err; + err = si514_calc_muldiv(&settings, req->rate); + if (err) { + req->rate = err; - return si514_calc_rate(&settings); + return 0; + } + + req->rate = si514_calc_rate(&settings); + + return 0; } /* @@ -289,7 +297,7 @@ static const struct clk_ops si514_clk_ops = { .unprepare = si514_unprepare, .is_prepared = si514_is_prepared, .recalc_rate = si514_recalc_rate, - .round_rate = si514_round_rate, + .determine_rate = si514_determine_rate, .set_rate = si514_set_rate, }; diff --git a/drivers/clk/clk-si521xx.c b/drivers/clk/clk-si521xx.c index 4f7b74f889f1..4ed4e1a5f4f2 100644 --- a/drivers/clk/clk-si521xx.c +++ b/drivers/clk/clk-si521xx.c @@ -164,15 +164,17 @@ static unsigned long si521xx_diff_recalc_rate(struct clk_hw *hw, return (unsigned long)rate; } -static long si521xx_diff_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *prate) +static int si521xx_diff_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { unsigned long best_parent; - best_parent = (rate / SI521XX_DIFF_MULT) * SI521XX_DIFF_DIV; - *prate = clk_hw_round_rate(clk_hw_get_parent(hw), best_parent); + best_parent = (req->rate / SI521XX_DIFF_MULT) * SI521XX_DIFF_DIV; + req->best_parent_rate = clk_hw_round_rate(clk_hw_get_parent(hw), best_parent); - return (*prate / SI521XX_DIFF_DIV) * SI521XX_DIFF_MULT; + req->rate = (req->best_parent_rate / SI521XX_DIFF_DIV) * SI521XX_DIFF_MULT; + + return 0; } static int si521xx_diff_set_rate(struct clk_hw *hw, unsigned long rate, @@ -208,7 +210,7 @@ static void si521xx_diff_unprepare(struct clk_hw *hw) } static const struct clk_ops si521xx_diff_clk_ops = { - .round_rate = si521xx_diff_round_rate, + .determine_rate = si521xx_diff_determine_rate, .set_rate = si521xx_diff_set_rate, .recalc_rate = si521xx_diff_recalc_rate, .prepare = si521xx_diff_prepare, diff --git a/drivers/clk/clk-si5341.c b/drivers/clk/clk-si5341.c index 5004888c7eca..2499b771cd83 100644 --- a/drivers/clk/clk-si5341.c +++ b/drivers/clk/clk-si5341.c @@ -663,8 +663,8 @@ static unsigned long si5341_synth_clk_recalc_rate(struct clk_hw *hw, return f; } -static long si5341_synth_clk_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *parent_rate) +static int si5341_synth_clk_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { struct clk_si5341_synth *synth = to_clk_si5341_synth(hw); u64 f; @@ -672,15 +672,21 @@ static long si5341_synth_clk_round_rate(struct clk_hw *hw, unsigned long rate, /* The synthesizer accuracy is such that anything in range will work */ f = synth->data->freq_vco; do_div(f, SI5341_SYNTH_N_MAX); - if (rate < f) - return f; + if (req->rate < f) { + req->rate = f; + + return 0; + } f = synth->data->freq_vco; do_div(f, SI5341_SYNTH_N_MIN); - if (rate > f) - return f; + if (req->rate > f) { + req->rate = f; - return rate; + return 0; + } + + return 0; } static int si5341_synth_program(struct clk_si5341_synth *synth, @@ -741,7 +747,7 @@ static const struct clk_ops si5341_synth_clk_ops = { .prepare = si5341_synth_clk_prepare, .unprepare = si5341_synth_clk_unprepare, .recalc_rate = si5341_synth_clk_recalc_rate, - .round_rate = si5341_synth_clk_round_rate, + .determine_rate = si5341_synth_clk_determine_rate, .set_rate = si5341_synth_clk_set_rate, }; diff --git a/drivers/clk/clk-si544.c b/drivers/clk/clk-si544.c index ca3473efa314..09c06ecec1a5 100644 --- a/drivers/clk/clk-si544.c +++ b/drivers/clk/clk-si544.c @@ -307,16 +307,16 @@ static unsigned long si544_recalc_rate(struct clk_hw *hw, return si544_calc_rate(&settings); } -static long si544_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *parent_rate) +static int si544_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { struct clk_si544 *data = to_clk_si544(hw); - if (!is_valid_frequency(data, rate)) + if (!is_valid_frequency(data, req->rate)) return -EINVAL; /* The accuracy is less than 1 Hz, so any rate is possible */ - return rate; + return 0; } /* Calculates the maximum "small" change, 950 * rate / 1000000 */ @@ -408,7 +408,7 @@ static const struct clk_ops si544_clk_ops = { .unprepare = si544_unprepare, .is_prepared = si544_is_prepared, .recalc_rate = si544_recalc_rate, - .round_rate = si544_round_rate, + .determine_rate = si544_determine_rate, .set_rate = si544_set_rate, }; diff --git a/drivers/clk/clk-si570.c b/drivers/clk/clk-si570.c index e97fe90443a6..b0b1830dd430 100644 --- a/drivers/clk/clk-si570.c +++ b/drivers/clk/clk-si570.c @@ -246,34 +246,40 @@ static unsigned long si570_recalc_rate(struct clk_hw *hw, return rate; } -static long si570_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *parent_rate) +static int si570_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { int err; u64 rfreq; unsigned int n1, hs_div; struct clk_si570 *data = to_clk_si570(hw); - if (!rate) + if (!req->rate) { + req->rate = 0; + return 0; + } - if (div64_u64(abs(rate - data->frequency) * 10000LL, + if (div64_u64(abs(req->rate - data->frequency) * 10000LL, data->frequency) < 35) { - rfreq = div64_u64((data->rfreq * rate) + - div64_u64(data->frequency, 2), data->frequency); + rfreq = div64_u64((data->rfreq * req->rate) + + div64_u64(data->frequency, 2), + data->frequency); n1 = data->n1; hs_div = data->hs_div; } else { - err = si570_calc_divs(rate, data, &rfreq, &n1, &hs_div); + err = si570_calc_divs(req->rate, data, &rfreq, &n1, &hs_div); if (err) { dev_err(&data->i2c_client->dev, "unable to round rate\n"); + req->rate = 0; + return 0; } } - return rate; + return 0; } /** @@ -368,7 +374,7 @@ static int si570_set_rate(struct clk_hw *hw, unsigned long rate, static const struct clk_ops si570_clk_ops = { .recalc_rate = si570_recalc_rate, - .round_rate = si570_round_rate, + .determine_rate = si570_determine_rate, .set_rate = si570_set_rate, }; diff --git a/drivers/clk/clk-sp7021.c b/drivers/clk/clk-sp7021.c index e902ba75e006..36528a71a2e6 100644 --- a/drivers/clk/clk-sp7021.c +++ b/drivers/clk/clk-sp7021.c @@ -406,25 +406,27 @@ static long sp_pll_calc_div(struct sp_pll *clk, unsigned long rate) return fbdiv; } -static long sp_pll_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *prate) +static int sp_pll_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { struct sp_pll *clk = to_sp_pll(hw); long ret; - if (rate == *prate) { - ret = *prate; /* bypass */ + if (req->rate == req->best_parent_rate) { + ret = req->best_parent_rate; /* bypass */ } else if (clk->div_width == DIV_A) { - ret = plla_round_rate(clk, rate); + ret = plla_round_rate(clk, req->rate); } else if (clk->div_width == DIV_TV) { - ret = plltv_div(clk, rate); + ret = plltv_div(clk, req->rate); if (ret < 0) - ret = *prate; + ret = req->best_parent_rate; } else { - ret = sp_pll_calc_div(clk, rate) * clk->brate; + ret = sp_pll_calc_div(clk, req->rate) * clk->brate; } - return ret; + req->rate = ret; + + return 0; } static unsigned long sp_pll_recalc_rate(struct clk_hw *hw, @@ -529,7 +531,7 @@ static const struct clk_ops sp_pll_ops = { .enable = sp_pll_enable, .disable = sp_pll_disable, .is_enabled = sp_pll_is_enabled, - .round_rate = sp_pll_round_rate, + .determine_rate = sp_pll_determine_rate, .recalc_rate = sp_pll_recalc_rate, .set_rate = sp_pll_set_rate }; diff --git a/drivers/clk/clk-sparx5.c b/drivers/clk/clk-sparx5.c index 0fad0c1a0186..b2facc9c95d4 100644 --- a/drivers/clk/clk-sparx5.c +++ b/drivers/clk/clk-sparx5.c @@ -213,19 +213,21 @@ static unsigned long s5_pll_recalc_rate(struct clk_hw *hw, return conf.freq; } -static long s5_pll_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *parent_rate) +static int s5_pll_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { struct s5_pll_conf conf; - return s5_calc_params(rate, *parent_rate, &conf); + req->rate = s5_calc_params(req->rate, req->best_parent_rate, &conf); + + return 0; } static const struct clk_ops s5_pll_ops = { .enable = s5_pll_enable, .disable = s5_pll_disable, .set_rate = s5_pll_set_rate, - .round_rate = s5_pll_round_rate, + .determine_rate = s5_pll_determine_rate, .recalc_rate = s5_pll_recalc_rate, }; diff --git a/drivers/clk/clk-stm32f4.c b/drivers/clk/clk-stm32f4.c index 719cddc82ae6..b5d4d48432a0 100644 --- a/drivers/clk/clk-stm32f4.c +++ b/drivers/clk/clk-stm32f4.c @@ -443,8 +443,8 @@ static unsigned long clk_apb_mul_recalc_rate(struct clk_hw *hw, return parent_rate; } -static long clk_apb_mul_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *prate) +static int clk_apb_mul_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { struct clk_apb_mul *am = to_clk_apb_mul(hw); unsigned long mult = 1; @@ -453,12 +453,14 @@ static long clk_apb_mul_round_rate(struct clk_hw *hw, unsigned long rate, mult = 2; if (clk_hw_get_flags(hw) & CLK_SET_RATE_PARENT) { - unsigned long best_parent = rate / mult; + unsigned long best_parent = req->rate / mult; - *prate = clk_hw_round_rate(clk_hw_get_parent(hw), best_parent); + req->best_parent_rate = clk_hw_round_rate(clk_hw_get_parent(hw), best_parent); } - return *prate * mult; + req->rate = req->best_parent_rate * mult; + + return 0; } static int clk_apb_mul_set_rate(struct clk_hw *hw, unsigned long rate, @@ -474,7 +476,7 @@ static int clk_apb_mul_set_rate(struct clk_hw *hw, unsigned long rate, } static const struct clk_ops clk_apb_mul_factor_ops = { - .round_rate = clk_apb_mul_round_rate, + .determine_rate = clk_apb_mul_determine_rate, .set_rate = clk_apb_mul_set_rate, .recalc_rate = clk_apb_mul_recalc_rate, }; @@ -670,21 +672,23 @@ static unsigned long stm32f4_pll_recalc(struct clk_hw *hw, return parent_rate * n; } -static long stm32f4_pll_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *prate) +static int stm32f4_pll_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { struct clk_gate *gate = to_clk_gate(hw); struct stm32f4_pll *pll = to_stm32f4_pll(gate); unsigned long n; - n = rate / *prate; + n = req->rate / req->best_parent_rate; if (n < pll->n_start) n = pll->n_start; else if (n > 432) n = 432; - return *prate * n; + req->rate = req->best_parent_rate * n; + + return 0; } static void stm32f4_pll_set_ssc(struct clk_hw *hw, unsigned long parent_rate, @@ -749,7 +753,7 @@ static const struct clk_ops stm32f4_pll_gate_ops = { .disable = stm32f4_pll_disable, .is_enabled = stm32f4_pll_is_enabled, .recalc_rate = stm32f4_pll_recalc, - .round_rate = stm32f4_pll_round_rate, + .determine_rate = stm32f4_pll_determine_rate, .set_rate = stm32f4_pll_set_rate, }; diff --git a/drivers/clk/clk-tps68470.c b/drivers/clk/clk-tps68470.c index 38f44b5b9b1b..9511248c6bc9 100644 --- a/drivers/clk/clk-tps68470.c +++ b/drivers/clk/clk-tps68470.c @@ -146,12 +146,14 @@ static unsigned int tps68470_clk_cfg_lookup(unsigned long rate) return best_idx; } -static long tps68470_clk_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *parent_rate) +static int tps68470_clk_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { - unsigned int idx = tps68470_clk_cfg_lookup(rate); + unsigned int idx = tps68470_clk_cfg_lookup(req->rate); + + req->rate = clk_freqs[idx].freq; - return clk_freqs[idx].freq; + return 0; } static int tps68470_clk_set_rate(struct clk_hw *hw, unsigned long rate, @@ -186,7 +188,7 @@ static const struct clk_ops tps68470_clk_ops = { .prepare = tps68470_clk_prepare, .unprepare = tps68470_clk_unprepare, .recalc_rate = tps68470_clk_recalc_rate, - .round_rate = tps68470_clk_round_rate, + .determine_rate = tps68470_clk_determine_rate, .set_rate = tps68470_clk_set_rate, }; diff --git a/drivers/clk/clk-versaclock3.c b/drivers/clk/clk-versaclock3.c index 9fe27dace111..1849863dbd67 100644 --- a/drivers/clk/clk-versaclock3.c +++ b/drivers/clk/clk-versaclock3.c @@ -289,22 +289,25 @@ static unsigned long vc3_pfd_recalc_rate(struct clk_hw *hw, return rate; } -static long vc3_pfd_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *parent_rate) +static int vc3_pfd_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { struct vc3_hw_data *vc3 = container_of(hw, struct vc3_hw_data, hw); const struct vc3_pfd_data *pfd = vc3->data; unsigned long idiv; /* PLL cannot operate with input clock above 50 MHz. */ - if (rate > 50000000) + if (req->rate > 50000000) return -EINVAL; /* CLKIN within range of PLL input, feed directly to PLL. */ - if (*parent_rate <= 50000000) - return *parent_rate; + if (req->best_parent_rate <= 50000000) { + req->rate = req->best_parent_rate; - idiv = DIV_ROUND_UP(*parent_rate, rate); + return 0; + } + + idiv = DIV_ROUND_UP(req->best_parent_rate, req->rate); if (pfd->num == VC3_PFD1 || pfd->num == VC3_PFD3) { if (idiv > 63) return -EINVAL; @@ -313,7 +316,9 @@ static long vc3_pfd_round_rate(struct clk_hw *hw, unsigned long rate, return -EINVAL; } - return *parent_rate / idiv; + req->rate = req->best_parent_rate / idiv; + + return 0; } static int vc3_pfd_set_rate(struct clk_hw *hw, unsigned long rate, @@ -354,7 +359,7 @@ static int vc3_pfd_set_rate(struct clk_hw *hw, unsigned long rate, static const struct clk_ops vc3_pfd_ops = { .recalc_rate = vc3_pfd_recalc_rate, - .round_rate = vc3_pfd_round_rate, + .determine_rate = vc3_pfd_determine_rate, .set_rate = vc3_pfd_set_rate, }; @@ -385,36 +390,38 @@ static unsigned long vc3_pll_recalc_rate(struct clk_hw *hw, return rate; } -static long vc3_pll_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *parent_rate) +static int vc3_pll_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { struct vc3_hw_data *vc3 = container_of(hw, struct vc3_hw_data, hw); const struct vc3_pll_data *pll = vc3->data; u64 div_frc; - if (rate < pll->vco.min) - rate = pll->vco.min; - if (rate > pll->vco.max) - rate = pll->vco.max; + if (req->rate < pll->vco.min) + req->rate = pll->vco.min; + if (req->rate > pll->vco.max) + req->rate = pll->vco.max; - vc3->div_int = rate / *parent_rate; + vc3->div_int = req->rate / req->best_parent_rate; if (pll->num == VC3_PLL2) { if (vc3->div_int > 0x7ff) - rate = *parent_rate * 0x7ff; + req->rate = req->best_parent_rate * 0x7ff; /* Determine best fractional part, which is 16 bit wide */ - div_frc = rate % *parent_rate; + div_frc = req->rate % req->best_parent_rate; div_frc *= BIT(16) - 1; - vc3->div_frc = min_t(u64, div64_ul(div_frc, *parent_rate), U16_MAX); - rate = (*parent_rate * - (vc3->div_int * VC3_2_POW_16 + vc3->div_frc) / VC3_2_POW_16); + vc3->div_frc = min_t(u64, + div64_ul(div_frc, req->best_parent_rate), + U16_MAX); + req->rate = (req->best_parent_rate * + (vc3->div_int * VC3_2_POW_16 + vc3->div_frc) / VC3_2_POW_16); } else { - rate = *parent_rate * vc3->div_int; + req->rate = req->best_parent_rate * vc3->div_int; } - return rate; + return 0; } static int vc3_pll_set_rate(struct clk_hw *hw, unsigned long rate, @@ -441,7 +448,7 @@ static int vc3_pll_set_rate(struct clk_hw *hw, unsigned long rate, static const struct clk_ops vc3_pll_ops = { .recalc_rate = vc3_pll_recalc_rate, - .round_rate = vc3_pll_round_rate, + .determine_rate = vc3_pll_determine_rate, .set_rate = vc3_pll_set_rate, }; @@ -498,8 +505,8 @@ static unsigned long vc3_div_recalc_rate(struct clk_hw *hw, div_data->flags, div_data->width); } -static long vc3_div_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *parent_rate) +static int vc3_div_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { struct vc3_hw_data *vc3 = container_of(hw, struct vc3_hw_data, hw); const struct vc3_div_data *div_data = vc3->data; @@ -511,11 +518,16 @@ static long vc3_div_round_rate(struct clk_hw *hw, unsigned long rate, bestdiv >>= div_data->shift; bestdiv &= VC3_DIV_MASK(div_data->width); bestdiv = vc3_get_div(div_data->table, bestdiv, div_data->flags); - return DIV_ROUND_UP(*parent_rate, bestdiv); + req->rate = DIV_ROUND_UP(req->best_parent_rate, bestdiv); + + return 0; } - return divider_round_rate(hw, rate, parent_rate, div_data->table, - div_data->width, div_data->flags); + req->rate = divider_round_rate(hw, req->rate, &req->best_parent_rate, + div_data->table, + div_data->width, div_data->flags); + + return 0; } static int vc3_div_set_rate(struct clk_hw *hw, unsigned long rate, @@ -534,7 +546,7 @@ static int vc3_div_set_rate(struct clk_hw *hw, unsigned long rate, static const struct clk_ops vc3_div_ops = { .recalc_rate = vc3_div_recalc_rate, - .round_rate = vc3_div_round_rate, + .determine_rate = vc3_div_determine_rate, .set_rate = vc3_div_set_rate, }; diff --git a/drivers/clk/clk-versaclock5.c b/drivers/clk/clk-versaclock5.c index 4200022d2084..57228e88e81d 100644 --- a/drivers/clk/clk-versaclock5.c +++ b/drivers/clk/clk-versaclock5.c @@ -304,11 +304,11 @@ static unsigned long vc5_dbl_recalc_rate(struct clk_hw *hw, return parent_rate; } -static long vc5_dbl_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *parent_rate) +static int vc5_dbl_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { - if ((*parent_rate == rate) || ((*parent_rate * 2) == rate)) - return rate; + if ((req->best_parent_rate == req->rate) || ((req->best_parent_rate * 2) == req->rate)) + return 0; else return -EINVAL; } @@ -332,7 +332,7 @@ static int vc5_dbl_set_rate(struct clk_hw *hw, unsigned long rate, static const struct clk_ops vc5_dbl_ops = { .recalc_rate = vc5_dbl_recalc_rate, - .round_rate = vc5_dbl_round_rate, + .determine_rate = vc5_dbl_determine_rate, .set_rate = vc5_dbl_set_rate, }; @@ -363,24 +363,29 @@ static unsigned long vc5_pfd_recalc_rate(struct clk_hw *hw, return parent_rate / VC5_REF_DIVIDER_REF_DIV(div); } -static long vc5_pfd_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *parent_rate) +static int vc5_pfd_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { unsigned long idiv; /* PLL cannot operate with input clock above 50 MHz. */ - if (rate > 50000000) + if (req->rate > 50000000) return -EINVAL; /* CLKIN within range of PLL input, feed directly to PLL. */ - if (*parent_rate <= 50000000) - return *parent_rate; + if (req->best_parent_rate <= 50000000) { + req->rate = req->best_parent_rate; + + return 0; + } - idiv = DIV_ROUND_UP(*parent_rate, rate); + idiv = DIV_ROUND_UP(req->best_parent_rate, req->rate); if (idiv > 127) return -EINVAL; - return *parent_rate / idiv; + req->rate = req->best_parent_rate / idiv; + + return 0; } static int vc5_pfd_set_rate(struct clk_hw *hw, unsigned long rate, @@ -420,7 +425,7 @@ static int vc5_pfd_set_rate(struct clk_hw *hw, unsigned long rate, static const struct clk_ops vc5_pfd_ops = { .recalc_rate = vc5_pfd_recalc_rate, - .round_rate = vc5_pfd_round_rate, + .determine_rate = vc5_pfd_determine_rate, .set_rate = vc5_pfd_set_rate, }; @@ -444,30 +449,32 @@ static unsigned long vc5_pll_recalc_rate(struct clk_hw *hw, return (parent_rate * div_int) + ((parent_rate * div_frc) >> 24); } -static long vc5_pll_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *parent_rate) +static int vc5_pll_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { struct vc5_hw_data *hwdata = container_of(hw, struct vc5_hw_data, hw); struct vc5_driver_data *vc5 = hwdata->vc5; u32 div_int; u64 div_frc; - rate = clamp(rate, VC5_PLL_VCO_MIN, vc5->chip_info->vco_max); + req->rate = clamp(req->rate, VC5_PLL_VCO_MIN, vc5->chip_info->vco_max); /* Determine integer part, which is 12 bit wide */ - div_int = rate / *parent_rate; + div_int = req->rate / req->best_parent_rate; if (div_int > 0xfff) - rate = *parent_rate * 0xfff; + req->rate = req->best_parent_rate * 0xfff; /* Determine best fractional part, which is 24 bit wide */ - div_frc = rate % *parent_rate; + div_frc = req->rate % req->best_parent_rate; div_frc *= BIT(24) - 1; - do_div(div_frc, *parent_rate); + do_div(div_frc, req->best_parent_rate); hwdata->div_int = div_int; hwdata->div_frc = (u32)div_frc; - return (*parent_rate * div_int) + ((*parent_rate * div_frc) >> 24); + req->rate = (req->best_parent_rate * div_int) + ((req->best_parent_rate * div_frc) >> 24); + + return 0; } static int vc5_pll_set_rate(struct clk_hw *hw, unsigned long rate, @@ -488,7 +495,7 @@ static int vc5_pll_set_rate(struct clk_hw *hw, unsigned long rate, static const struct clk_ops vc5_pll_ops = { .recalc_rate = vc5_pll_recalc_rate, - .round_rate = vc5_pll_round_rate, + .determine_rate = vc5_pll_determine_rate, .set_rate = vc5_pll_set_rate, }; @@ -520,17 +527,17 @@ static unsigned long vc5_fod_recalc_rate(struct clk_hw *hw, return div64_u64((u64)f_in << 24ULL, ((u64)div_int << 24ULL) + div_frc); } -static long vc5_fod_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *parent_rate) +static int vc5_fod_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { struct vc5_hw_data *hwdata = container_of(hw, struct vc5_hw_data, hw); /* VCO frequency is divided by two before entering FOD */ - u32 f_in = *parent_rate / 2; + u32 f_in = req->best_parent_rate / 2; u32 div_int; u64 div_frc; /* Determine integer part, which is 12 bit wide */ - div_int = f_in / rate; + div_int = f_in / req->rate; /* * WARNING: The clock chip does not output signal if the integer part * of the divider is 0xfff and fractional part is non-zero. @@ -538,18 +545,20 @@ static long vc5_fod_round_rate(struct clk_hw *hw, unsigned long rate, */ if (div_int > 0xffe) { div_int = 0xffe; - rate = f_in / div_int; + req->rate = f_in / div_int; } /* Determine best fractional part, which is 30 bit wide */ - div_frc = f_in % rate; + div_frc = f_in % req->rate; div_frc <<= 24; - do_div(div_frc, rate); + do_div(div_frc, req->rate); hwdata->div_int = div_int; hwdata->div_frc = (u32)div_frc; - return div64_u64((u64)f_in << 24ULL, ((u64)div_int << 24ULL) + div_frc); + req->rate = div64_u64((u64)f_in << 24ULL, ((u64)div_int << 24ULL) + div_frc); + + return 0; } static int vc5_fod_set_rate(struct clk_hw *hw, unsigned long rate, @@ -589,7 +598,7 @@ static int vc5_fod_set_rate(struct clk_hw *hw, unsigned long rate, static const struct clk_ops vc5_fod_ops = { .recalc_rate = vc5_fod_recalc_rate, - .round_rate = vc5_fod_round_rate, + .determine_rate = vc5_fod_determine_rate, .set_rate = vc5_fod_set_rate, }; diff --git a/drivers/clk/clk-versaclock7.c b/drivers/clk/clk-versaclock7.c index 483285b30c13..adcc603e3259 100644 --- a/drivers/clk/clk-versaclock7.c +++ b/drivers/clk/clk-versaclock7.c @@ -900,17 +900,18 @@ static unsigned long vc7_fod_recalc_rate(struct clk_hw *hw, unsigned long parent return fod_rate; } -static long vc7_fod_round_rate(struct clk_hw *hw, unsigned long rate, unsigned long *parent_rate) +static int vc7_fod_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { struct vc7_fod_data *fod = container_of(hw, struct vc7_fod_data, hw); unsigned long fod_rate; pr_debug("%s - %s: requested rate: %lu, parent_rate: %lu\n", - __func__, clk_hw_get_name(hw), rate, *parent_rate); + __func__, clk_hw_get_name(hw), req->rate, req->best_parent_rate); - vc7_calc_fod_divider(rate, *parent_rate, + vc7_calc_fod_divider(req->rate, req->best_parent_rate, &fod->fod_1st_int, &fod->fod_2nd_int, &fod->fod_frac); - fod_rate = vc7_calc_fod_2nd_stage_rate(*parent_rate, fod->fod_1st_int, + fod_rate = vc7_calc_fod_2nd_stage_rate(req->best_parent_rate, fod->fod_1st_int, fod->fod_2nd_int, fod->fod_frac); pr_debug("%s - %s: fod_1st_int: %u, fod_2nd_int: %u, fod_frac: %llu\n", @@ -918,7 +919,9 @@ static long vc7_fod_round_rate(struct clk_hw *hw, unsigned long rate, unsigned l fod->fod_1st_int, fod->fod_2nd_int, fod->fod_frac); pr_debug("%s - %s rate: %lu\n", __func__, clk_hw_get_name(hw), fod_rate); - return fod_rate; + req->rate = fod_rate; + + return 0; } static int vc7_fod_set_rate(struct clk_hw *hw, unsigned long rate, unsigned long parent_rate) @@ -952,7 +955,7 @@ static int vc7_fod_set_rate(struct clk_hw *hw, unsigned long rate, unsigned long static const struct clk_ops vc7_fod_ops = { .recalc_rate = vc7_fod_recalc_rate, - .round_rate = vc7_fod_round_rate, + .determine_rate = vc7_fod_determine_rate, .set_rate = vc7_fod_set_rate, }; @@ -978,21 +981,24 @@ static unsigned long vc7_iod_recalc_rate(struct clk_hw *hw, unsigned long parent return iod_rate; } -static long vc7_iod_round_rate(struct clk_hw *hw, unsigned long rate, unsigned long *parent_rate) +static int vc7_iod_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { struct vc7_iod_data *iod = container_of(hw, struct vc7_iod_data, hw); unsigned long iod_rate; pr_debug("%s - %s: requested rate: %lu, parent_rate: %lu\n", - __func__, clk_hw_get_name(hw), rate, *parent_rate); + __func__, clk_hw_get_name(hw), req->rate, req->best_parent_rate); - vc7_calc_iod_divider(rate, *parent_rate, &iod->iod_int); - iod_rate = div64_u64(*parent_rate, iod->iod_int); + vc7_calc_iod_divider(req->rate, req->best_parent_rate, &iod->iod_int); + iod_rate = div64_u64(req->best_parent_rate, iod->iod_int); pr_debug("%s - %s: iod_int: %u\n", __func__, clk_hw_get_name(hw), iod->iod_int); pr_debug("%s - %s rate: %ld\n", __func__, clk_hw_get_name(hw), iod_rate); - return iod_rate; + req->rate = iod_rate; + + return 0; } static int vc7_iod_set_rate(struct clk_hw *hw, unsigned long rate, unsigned long parent_rate) @@ -1023,7 +1029,7 @@ static int vc7_iod_set_rate(struct clk_hw *hw, unsigned long rate, unsigned long static const struct clk_ops vc7_iod_ops = { .recalc_rate = vc7_iod_recalc_rate, - .round_rate = vc7_iod_round_rate, + .determine_rate = vc7_iod_determine_rate, .set_rate = vc7_iod_set_rate, }; diff --git a/drivers/clk/clk-vt8500.c b/drivers/clk/clk-vt8500.c index 2a74a713ad59..eae5b3fbfb82 100644 --- a/drivers/clk/clk-vt8500.c +++ b/drivers/clk/clk-vt8500.c @@ -128,30 +128,31 @@ static unsigned long vt8500_dclk_recalc_rate(struct clk_hw *hw, return parent_rate / div; } -static long vt8500_dclk_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *prate) +static int vt8500_dclk_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { struct clk_device *cdev = to_clk_device(hw); u32 divisor; - if (rate == 0) + if (req->rate == 0) return 0; - divisor = *prate / rate; + divisor = req->best_parent_rate / req->rate; /* If prate / rate would be decimal, incr the divisor */ - if (rate * divisor < *prate) + if (req->rate * divisor < req->best_parent_rate) divisor++; /* * If this is a request for SDMMC we have to adjust the divisor * when >31 to use the fixed predivisor */ - if ((cdev->div_mask == 0x3F) && (divisor > 31)) { + if ((cdev->div_mask == 0x3F) && (divisor > 31)) divisor = 64 * ((divisor / 64) + 1); - } - return *prate / divisor; + req->rate = req->best_parent_rate / divisor; + + return 0; } static int vt8500_dclk_set_rate(struct clk_hw *hw, unsigned long rate, @@ -202,7 +203,7 @@ static const struct clk_ops vt8500_gated_clk_ops = { }; static const struct clk_ops vt8500_divisor_clk_ops = { - .round_rate = vt8500_dclk_round_rate, + .determine_rate = vt8500_dclk_determine_rate, .set_rate = vt8500_dclk_set_rate, .recalc_rate = vt8500_dclk_recalc_rate, }; @@ -211,7 +212,7 @@ static const struct clk_ops vt8500_gated_divisor_clk_ops = { .enable = vt8500_dclk_enable, .disable = vt8500_dclk_disable, .is_enabled = vt8500_dclk_is_enabled, - .round_rate = vt8500_dclk_round_rate, + .determine_rate = vt8500_dclk_determine_rate, .set_rate = vt8500_dclk_set_rate, .recalc_rate = vt8500_dclk_recalc_rate, }; @@ -594,8 +595,8 @@ static int vtwm_pll_set_rate(struct clk_hw *hw, unsigned long rate, return 0; } -static long vtwm_pll_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *prate) +static int vtwm_pll_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { struct clk_pll *pll = to_clk_pll(hw); u32 filter, mul, div1, div2; @@ -604,33 +605,43 @@ static long vtwm_pll_round_rate(struct clk_hw *hw, unsigned long rate, switch (pll->type) { case PLL_TYPE_VT8500: - ret = vt8500_find_pll_bits(rate, *prate, &mul, &div1); + ret = vt8500_find_pll_bits(req->rate, req->best_parent_rate, + &mul, &div1); if (!ret) - round_rate = VT8500_BITS_TO_FREQ(*prate, mul, div1); + round_rate = VT8500_BITS_TO_FREQ(req->best_parent_rate, + mul, div1); break; case PLL_TYPE_WM8650: - ret = wm8650_find_pll_bits(rate, *prate, &mul, &div1, &div2); + ret = wm8650_find_pll_bits(req->rate, req->best_parent_rate, + &mul, &div1, &div2); if (!ret) - round_rate = WM8650_BITS_TO_FREQ(*prate, mul, div1, div2); + round_rate = WM8650_BITS_TO_FREQ(req->best_parent_rate, + mul, div1, div2); break; case PLL_TYPE_WM8750: - ret = wm8750_find_pll_bits(rate, *prate, &filter, &mul, &div1, &div2); + ret = wm8750_find_pll_bits(req->rate, req->best_parent_rate, + &filter, &mul, &div1, &div2); if (!ret) - round_rate = WM8750_BITS_TO_FREQ(*prate, mul, div1, div2); + round_rate = WM8750_BITS_TO_FREQ(req->best_parent_rate, + mul, div1, div2); break; case PLL_TYPE_WM8850: - ret = wm8850_find_pll_bits(rate, *prate, &mul, &div1, &div2); + ret = wm8850_find_pll_bits(req->rate, req->best_parent_rate, + &mul, &div1, &div2); if (!ret) - round_rate = WM8850_BITS_TO_FREQ(*prate, mul, div1, div2); + round_rate = WM8850_BITS_TO_FREQ(req->best_parent_rate, + mul, div1, div2); break; default: - ret = -EINVAL; + return -EINVAL; } if (ret) - return ret; + req->rate = ret; + else + req->rate = round_rate; - return round_rate; + return 0; } static unsigned long vtwm_pll_recalc_rate(struct clk_hw *hw, @@ -665,7 +676,7 @@ static unsigned long vtwm_pll_recalc_rate(struct clk_hw *hw, } static const struct clk_ops vtwm_pll_ops = { - .round_rate = vtwm_pll_round_rate, + .determine_rate = vtwm_pll_determine_rate, .set_rate = vtwm_pll_set_rate, .recalc_rate = vtwm_pll_recalc_rate, }; diff --git a/drivers/clk/clk-wm831x.c b/drivers/clk/clk-wm831x.c index 34e9d4d541e2..263e927138c2 100644 --- a/drivers/clk/clk-wm831x.c +++ b/drivers/clk/clk-wm831x.c @@ -133,18 +133,20 @@ static unsigned long wm831x_fll_recalc_rate(struct clk_hw *hw, return 0; } -static long wm831x_fll_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *unused) +static int wm831x_fll_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { int best = 0; int i; for (i = 0; i < ARRAY_SIZE(wm831x_fll_auto_rates); i++) - if (abs(wm831x_fll_auto_rates[i] - rate) < - abs(wm831x_fll_auto_rates[best] - rate)) + if (abs(wm831x_fll_auto_rates[i] - req->rate) < + abs(wm831x_fll_auto_rates[best] - req->rate)) best = i; - return wm831x_fll_auto_rates[best]; + req->rate = wm831x_fll_auto_rates[best]; + + return 0; } static int wm831x_fll_set_rate(struct clk_hw *hw, unsigned long rate, @@ -214,7 +216,7 @@ static const struct clk_ops wm831x_fll_ops = { .is_prepared = wm831x_fll_is_prepared, .prepare = wm831x_fll_prepare, .unprepare = wm831x_fll_unprepare, - .round_rate = wm831x_fll_round_rate, + .determine_rate = wm831x_fll_determine_rate, .recalc_rate = wm831x_fll_recalc_rate, .set_rate = wm831x_fll_set_rate, .get_parent = wm831x_fll_get_parent, diff --git a/drivers/clk/clk-xgene.c b/drivers/clk/clk-xgene.c index 96946a8e2854..92e39f3237c2 100644 --- a/drivers/clk/clk-xgene.c +++ b/drivers/clk/clk-xgene.c @@ -271,23 +271,28 @@ static unsigned long xgene_clk_pmd_recalc_rate(struct clk_hw *hw, return ret; } -static long xgene_clk_pmd_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *parent_rate) +static int xgene_clk_pmd_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { struct xgene_clk_pmd *fd = to_xgene_clk_pmd(hw); u64 ret, scale; - if (!rate || rate >= *parent_rate) - return *parent_rate; + if (!req->rate || req->rate >= req->best_parent_rate) { + req->rate = req->best_parent_rate; + + return 0; + } /* freq = parent_rate * scaler / denom */ - ret = rate * fd->denom; - scale = DIV_ROUND_UP_ULL(ret, *parent_rate); + ret = req->rate * fd->denom; + scale = DIV_ROUND_UP_ULL(ret, req->best_parent_rate); - ret = (u64)*parent_rate * scale; + ret = (u64)req->best_parent_rate * scale; do_div(ret, fd->denom); - return ret; + req->rate = ret; + + return 0; } static int xgene_clk_pmd_set_rate(struct clk_hw *hw, unsigned long rate, @@ -333,7 +338,7 @@ static int xgene_clk_pmd_set_rate(struct clk_hw *hw, unsigned long rate, static const struct clk_ops xgene_clk_pmd_ops = { .recalc_rate = xgene_clk_pmd_recalc_rate, - .round_rate = xgene_clk_pmd_round_rate, + .determine_rate = xgene_clk_pmd_determine_rate, .set_rate = xgene_clk_pmd_set_rate, }; @@ -593,23 +598,25 @@ static int xgene_clk_set_rate(struct clk_hw *hw, unsigned long rate, return parent_rate / divider_save; } -static long xgene_clk_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *prate) +static int xgene_clk_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { struct xgene_clk *pclk = to_xgene_clk(hw); - unsigned long parent_rate = *prate; + unsigned long parent_rate = req->best_parent_rate; u32 divider; if (pclk->param.divider_reg) { /* Let's compute the divider */ - if (rate > parent_rate) - rate = parent_rate; - divider = parent_rate / rate; /* Rounded down */ + if (req->rate > parent_rate) + req->rate = parent_rate; + divider = parent_rate / req->rate; /* Rounded down */ } else { divider = 1; } - return parent_rate / divider; + req->rate = parent_rate / divider; + + return 0; } static const struct clk_ops xgene_clk_ops = { @@ -618,7 +625,7 @@ static const struct clk_ops xgene_clk_ops = { .is_enabled = xgene_clk_is_enabled, .recalc_rate = xgene_clk_recalc_rate, .set_rate = xgene_clk_set_rate, - .round_rate = xgene_clk_round_rate, + .determine_rate = xgene_clk_determine_rate, }; static struct clk *xgene_register_clk(struct device *dev, diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c index b821b2cdb155..85d2f2481acf 100644 --- a/drivers/clk/clk.c +++ b/drivers/clk/clk.c @@ -6,21 +6,24 @@ * Standard functionality for the common clock API. See Documentation/driver-api/clk.rst */ +#include <linux/clk/clk-conf.h> +#include <linux/clkdev.h> #include <linux/clk.h> #include <linux/clk-provider.h> -#include <linux/clk/clk-conf.h> -#include <linux/module.h> -#include <linux/mutex.h> -#include <linux/spinlock.h> +#include <linux/device.h> #include <linux/err.h> +#include <linux/hashtable.h> +#include <linux/init.h> #include <linux/list.h> -#include <linux/slab.h> +#include <linux/module.h> +#include <linux/mutex.h> #include <linux/of.h> -#include <linux/device.h> -#include <linux/init.h> #include <linux/pm_runtime.h> #include <linux/sched.h> -#include <linux/clkdev.h> +#include <linux/slab.h> +#include <linux/spinlock.h> +#include <linux/string.h> +#include <linux/stringhash.h> #include "clk.h" @@ -33,6 +36,9 @@ static struct task_struct *enable_owner; static int prepare_refcnt; static int enable_refcnt; +#define CLK_HASH_BITS 9 +static DEFINE_HASHTABLE(clk_hashtable, CLK_HASH_BITS); + static HLIST_HEAD(clk_root_list); static HLIST_HEAD(clk_orphan_list); static LIST_HEAD(clk_notifier_list); @@ -87,6 +93,7 @@ struct clk_core { struct clk_duty duty; struct hlist_head children; struct hlist_node child_node; + struct hlist_node hashtable_node; struct hlist_head clks; unsigned int notifier_count; #ifdef CONFIG_DEBUG_FS @@ -395,45 +402,20 @@ struct clk_hw *clk_hw_get_parent(const struct clk_hw *hw) } EXPORT_SYMBOL_GPL(clk_hw_get_parent); -static struct clk_core *__clk_lookup_subtree(const char *name, - struct clk_core *core) -{ - struct clk_core *child; - struct clk_core *ret; - - if (!strcmp(core->name, name)) - return core; - - hlist_for_each_entry(child, &core->children, child_node) { - ret = __clk_lookup_subtree(name, child); - if (ret) - return ret; - } - - return NULL; -} - static struct clk_core *clk_core_lookup(const char *name) { - struct clk_core *root_clk; - struct clk_core *ret; + struct clk_core *core; + u32 hash; if (!name) return NULL; - /* search the 'proper' clk tree first */ - hlist_for_each_entry(root_clk, &clk_root_list, child_node) { - ret = __clk_lookup_subtree(name, root_clk); - if (ret) - return ret; - } + hash = full_name_hash(NULL, name, strlen(name)); - /* if not found, then search the orphan tree */ - hlist_for_each_entry(root_clk, &clk_orphan_list, child_node) { - ret = __clk_lookup_subtree(name, root_clk); - if (ret) - return ret; - } + /* search the hashtable */ + hash_for_each_possible(clk_hashtable, core, hashtable_node, hash) + if (!strcmp(core->name, name)) + return core; return NULL; } @@ -4013,6 +3995,8 @@ static int __clk_core_init(struct clk_core *core) hlist_add_head(&core->child_node, &clk_orphan_list); core->orphan = true; } + hash_add(clk_hashtable, &core->hashtable_node, + full_name_hash(NULL, core->name, strlen(core->name))); /* * Set clk's accuracy. The preferred method is to use @@ -4089,6 +4073,7 @@ out: clk_pm_runtime_put(core); unlock: if (ret) { + hash_del(&core->hashtable_node); hlist_del_init(&core->child_node); core->hw->core = NULL; } @@ -4610,6 +4595,7 @@ void clk_unregister(struct clk *clk) clk_core_evict_parent_cache(clk->core); + hash_del(&clk->core->hashtable_node); hlist_del_init(&clk->core->child_node); if (clk->core->prepare_count) diff --git a/drivers/clk/hisilicon/clk-hi3660-stub.c b/drivers/clk/hisilicon/clk-hi3660-stub.c index 3a653d54bee0..7c8b00ee6019 100644 --- a/drivers/clk/hisilicon/clk-hi3660-stub.c +++ b/drivers/clk/hisilicon/clk-hi3660-stub.c @@ -34,7 +34,7 @@ .num_parents = 0, \ .flags = CLK_GET_RATE_NOCACHE, \ }, \ - }, + } #define to_stub_clk(_hw) container_of(_hw, struct hi3660_stub_clk, hw) @@ -67,14 +67,14 @@ static unsigned long hi3660_stub_clk_recalc_rate(struct clk_hw *hw, return stub_clk->rate; } -static long hi3660_stub_clk_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *prate) +static int hi3660_stub_clk_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { /* * LPM3 handles rate rounding so just return whatever * rate is requested. */ - return rate; + return 0; } static int hi3660_stub_clk_set_rate(struct clk_hw *hw, unsigned long rate, @@ -97,15 +97,15 @@ static int hi3660_stub_clk_set_rate(struct clk_hw *hw, unsigned long rate, static const struct clk_ops hi3660_stub_clk_ops = { .recalc_rate = hi3660_stub_clk_recalc_rate, - .round_rate = hi3660_stub_clk_round_rate, + .determine_rate = hi3660_stub_clk_determine_rate, .set_rate = hi3660_stub_clk_set_rate, }; static struct hi3660_stub_clk hi3660_stub_clks[HI3660_CLK_STUB_NUM] = { - DEFINE_CLK_STUB(HI3660_CLK_STUB_CLUSTER0, 0x0001030A, "cpu-cluster.0") - DEFINE_CLK_STUB(HI3660_CLK_STUB_CLUSTER1, 0x0002030A, "cpu-cluster.1") - DEFINE_CLK_STUB(HI3660_CLK_STUB_GPU, 0x0003030A, "clk-g3d") - DEFINE_CLK_STUB(HI3660_CLK_STUB_DDR, 0x00040309, "clk-ddrc") + DEFINE_CLK_STUB(HI3660_CLK_STUB_CLUSTER0, 0x0001030A, "cpu-cluster.0"), + DEFINE_CLK_STUB(HI3660_CLK_STUB_CLUSTER1, 0x0002030A, "cpu-cluster.1"), + DEFINE_CLK_STUB(HI3660_CLK_STUB_GPU, 0x0003030A, "clk-g3d"), + DEFINE_CLK_STUB(HI3660_CLK_STUB_DDR, 0x00040309, "clk-ddrc"), }; static struct clk_hw *hi3660_stub_clk_hw_get(struct of_phandle_args *clkspec, diff --git a/drivers/clk/hisilicon/clk-hi6220-stub.c b/drivers/clk/hisilicon/clk-hi6220-stub.c index a8319795ed1c..bf99cfafafa0 100644 --- a/drivers/clk/hisilicon/clk-hi6220-stub.c +++ b/drivers/clk/hisilicon/clk-hi6220-stub.c @@ -161,11 +161,11 @@ static int hi6220_stub_clk_set_rate(struct clk_hw *hw, unsigned long rate, return ret; } -static long hi6220_stub_clk_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *parent_rate) +static int hi6220_stub_clk_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { struct hi6220_stub_clk *stub_clk = to_stub_clk(hw); - unsigned long new_rate = rate / 1000; /* kHz */ + unsigned long new_rate = req->rate / 1000; /* kHz */ switch (stub_clk->id) { case HI6220_STUB_ACPU0: @@ -181,12 +181,14 @@ static long hi6220_stub_clk_round_rate(struct clk_hw *hw, unsigned long rate, break; } - return new_rate; + req->rate = new_rate; + + return 0; } static const struct clk_ops hi6220_stub_clk_ops = { .recalc_rate = hi6220_stub_clk_recalc_rate, - .round_rate = hi6220_stub_clk_round_rate, + .determine_rate = hi6220_stub_clk_determine_rate, .set_rate = hi6220_stub_clk_set_rate, }; diff --git a/drivers/clk/hisilicon/clkdivider-hi6220.c b/drivers/clk/hisilicon/clkdivider-hi6220.c index 5348bafe694f..6bae18a84cb6 100644 --- a/drivers/clk/hisilicon/clkdivider-hi6220.c +++ b/drivers/clk/hisilicon/clkdivider-hi6220.c @@ -55,13 +55,15 @@ static unsigned long hi6220_clkdiv_recalc_rate(struct clk_hw *hw, CLK_DIVIDER_ROUND_CLOSEST, dclk->width); } -static long hi6220_clkdiv_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *prate) +static int hi6220_clkdiv_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { struct hi6220_clk_divider *dclk = to_hi6220_clk_divider(hw); - return divider_round_rate(hw, rate, prate, dclk->table, - dclk->width, CLK_DIVIDER_ROUND_CLOSEST); + req->rate = divider_round_rate(hw, req->rate, &req->best_parent_rate, dclk->table, + dclk->width, CLK_DIVIDER_ROUND_CLOSEST); + + return 0; } static int hi6220_clkdiv_set_rate(struct clk_hw *hw, unsigned long rate, @@ -93,7 +95,7 @@ static int hi6220_clkdiv_set_rate(struct clk_hw *hw, unsigned long rate, static const struct clk_ops hi6220_clkdiv_ops = { .recalc_rate = hi6220_clkdiv_recalc_rate, - .round_rate = hi6220_clkdiv_round_rate, + .determine_rate = hi6220_clkdiv_determine_rate, .set_rate = hi6220_clkdiv_set_rate, }; diff --git a/drivers/clk/imx/clk-imx95-blk-ctl.c b/drivers/clk/imx/clk-imx95-blk-ctl.c index 7e88877a6245..56bed4471995 100644 --- a/drivers/clk/imx/clk-imx95-blk-ctl.c +++ b/drivers/clk/imx/clk-imx95-blk-ctl.c @@ -36,6 +36,7 @@ struct imx95_blk_ctl { void __iomem *base; /* clock gate register */ u32 clk_reg_restore; + const struct imx95_blk_ctl_dev_data *pdata; }; struct imx95_blk_ctl_clk_dev_data { @@ -349,7 +350,6 @@ static const struct imx95_blk_ctl_dev_data imx94_dispmix_csr_dev_data = { static int imx95_bc_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; - const struct imx95_blk_ctl_dev_data *bc_data; struct imx95_blk_ctl *bc; struct clk_hw_onecell_data *clk_hw_data; struct clk_hw **hws; @@ -379,25 +379,25 @@ static int imx95_bc_probe(struct platform_device *pdev) return ret; } - bc_data = of_device_get_match_data(dev); - if (!bc_data) + bc->pdata = of_device_get_match_data(dev); + if (!bc->pdata) return devm_of_platform_populate(dev); - clk_hw_data = devm_kzalloc(dev, struct_size(clk_hw_data, hws, bc_data->num_clks), + clk_hw_data = devm_kzalloc(dev, struct_size(clk_hw_data, hws, bc->pdata->num_clks), GFP_KERNEL); if (!clk_hw_data) return -ENOMEM; - if (bc_data->rpm_enabled) { + if (bc->pdata->rpm_enabled) { devm_pm_runtime_enable(&pdev->dev); pm_runtime_resume_and_get(&pdev->dev); } - clk_hw_data->num = bc_data->num_clks; + clk_hw_data->num = bc->pdata->num_clks; hws = clk_hw_data->hws; - for (i = 0; i < bc_data->num_clks; i++) { - const struct imx95_blk_ctl_clk_dev_data *data = &bc_data->clk_dev_data[i]; + for (i = 0; i < bc->pdata->num_clks; i++) { + const struct imx95_blk_ctl_clk_dev_data *data = &bc->pdata->clk_dev_data[i]; void __iomem *reg = base + data->reg; if (data->type == CLK_MUX) { @@ -439,7 +439,7 @@ static int imx95_bc_probe(struct platform_device *pdev) return 0; cleanup: - for (i = 0; i < bc_data->num_clks; i++) { + for (i = 0; i < bc->pdata->num_clks; i++) { if (IS_ERR_OR_NULL(hws[i])) continue; clk_hw_unregister(hws[i]); @@ -453,15 +453,24 @@ static int imx95_bc_runtime_suspend(struct device *dev) { struct imx95_blk_ctl *bc = dev_get_drvdata(dev); + bc->clk_reg_restore = readl(bc->base + bc->pdata->clk_reg_offset); clk_disable_unprepare(bc->clk_apb); + return 0; } static int imx95_bc_runtime_resume(struct device *dev) { struct imx95_blk_ctl *bc = dev_get_drvdata(dev); + int ret; - return clk_prepare_enable(bc->clk_apb); + ret = clk_prepare_enable(bc->clk_apb); + if (ret) + return ret; + + writel(bc->clk_reg_restore, bc->base + bc->pdata->clk_reg_offset); + + return 0; } #endif @@ -469,22 +478,12 @@ static int imx95_bc_runtime_resume(struct device *dev) static int imx95_bc_suspend(struct device *dev) { struct imx95_blk_ctl *bc = dev_get_drvdata(dev); - const struct imx95_blk_ctl_dev_data *bc_data; - int ret; - bc_data = of_device_get_match_data(dev); - if (!bc_data) + if (pm_runtime_suspended(dev)) return 0; - if (bc_data->rpm_enabled) { - ret = pm_runtime_get_sync(bc->dev); - if (ret < 0) { - pm_runtime_put_noidle(bc->dev); - return ret; - } - } - - bc->clk_reg_restore = readl(bc->base + bc_data->clk_reg_offset); + bc->clk_reg_restore = readl(bc->base + bc->pdata->clk_reg_offset); + clk_disable_unprepare(bc->clk_apb); return 0; } @@ -492,16 +491,16 @@ static int imx95_bc_suspend(struct device *dev) static int imx95_bc_resume(struct device *dev) { struct imx95_blk_ctl *bc = dev_get_drvdata(dev); - const struct imx95_blk_ctl_dev_data *bc_data; + int ret; - bc_data = of_device_get_match_data(dev); - if (!bc_data) + if (pm_runtime_suspended(dev)) return 0; - writel(bc->clk_reg_restore, bc->base + bc_data->clk_reg_offset); + ret = clk_prepare_enable(bc->clk_apb); + if (ret) + return ret; - if (bc_data->rpm_enabled) - pm_runtime_put(bc->dev); + writel(bc->clk_reg_restore, bc->base + bc->pdata->clk_reg_offset); return 0; } diff --git a/drivers/clk/ingenic/cgu.c b/drivers/clk/ingenic/cgu.c index 0c9c8344ad11..91e7ac0cc334 100644 --- a/drivers/clk/ingenic/cgu.c +++ b/drivers/clk/ingenic/cgu.c @@ -174,14 +174,16 @@ ingenic_pll_calc(const struct ingenic_cgu_clk_info *clk_info, n * od); } -static long -ingenic_pll_round_rate(struct clk_hw *hw, unsigned long req_rate, - unsigned long *prate) +static int ingenic_pll_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { struct ingenic_clk *ingenic_clk = to_ingenic_clk(hw); const struct ingenic_cgu_clk_info *clk_info = to_clk_info(ingenic_clk); - return ingenic_pll_calc(clk_info, req_rate, *prate, NULL, NULL, NULL); + req->rate = ingenic_pll_calc(clk_info, req->rate, req->best_parent_rate, + NULL, NULL, NULL); + + return 0; } static inline int ingenic_pll_check_stable(struct ingenic_cgu *cgu, @@ -317,7 +319,7 @@ static int ingenic_pll_is_enabled(struct clk_hw *hw) static const struct clk_ops ingenic_pll_ops = { .recalc_rate = ingenic_pll_recalc_rate, - .round_rate = ingenic_pll_round_rate, + .determine_rate = ingenic_pll_determine_rate, .set_rate = ingenic_pll_set_rate, .enable = ingenic_pll_enable, diff --git a/drivers/clk/ingenic/jz4780-cgu.c b/drivers/clk/ingenic/jz4780-cgu.c index b1dadc0a5e75..07e2f3c5c454 100644 --- a/drivers/clk/ingenic/jz4780-cgu.c +++ b/drivers/clk/ingenic/jz4780-cgu.c @@ -128,19 +128,19 @@ static unsigned long jz4780_otg_phy_recalc_rate(struct clk_hw *hw, return parent_rate; } -static long jz4780_otg_phy_round_rate(struct clk_hw *hw, unsigned long req_rate, - unsigned long *parent_rate) +static int jz4780_otg_phy_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { - if (req_rate < 15600000) - return 12000000; - - if (req_rate < 21600000) - return 19200000; + if (req->rate < 15600000) + req->rate = 12000000; + else if (req->rate < 21600000) + req->rate = 19200000; + else if (req->rate < 36000000) + req->rate = 24000000; + else + req->rate = 48000000; - if (req_rate < 36000000) - return 24000000; - - return 48000000; + return 0; } static int jz4780_otg_phy_set_rate(struct clk_hw *hw, unsigned long req_rate, @@ -212,7 +212,7 @@ static int jz4780_otg_phy_is_enabled(struct clk_hw *hw) static const struct clk_ops jz4780_otg_phy_ops = { .recalc_rate = jz4780_otg_phy_recalc_rate, - .round_rate = jz4780_otg_phy_round_rate, + .determine_rate = jz4780_otg_phy_determine_rate, .set_rate = jz4780_otg_phy_set_rate, .enable = jz4780_otg_phy_enable, diff --git a/drivers/clk/ingenic/x1000-cgu.c b/drivers/clk/ingenic/x1000-cgu.c index feb03eed4fe8..d80886caf393 100644 --- a/drivers/clk/ingenic/x1000-cgu.c +++ b/drivers/clk/ingenic/x1000-cgu.c @@ -84,16 +84,17 @@ static unsigned long x1000_otg_phy_recalc_rate(struct clk_hw *hw, return parent_rate; } -static long x1000_otg_phy_round_rate(struct clk_hw *hw, unsigned long req_rate, - unsigned long *parent_rate) +static int x1000_otg_phy_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { - if (req_rate < 18000000) - return 12000000; - - if (req_rate < 36000000) - return 24000000; + if (req->rate < 18000000) + req->rate = 12000000; + else if (req->rate < 36000000) + req->rate = 24000000; + else + req->rate = 48000000; - return 48000000; + return 0; } static int x1000_otg_phy_set_rate(struct clk_hw *hw, unsigned long req_rate, @@ -161,7 +162,7 @@ static int x1000_usb_phy_is_enabled(struct clk_hw *hw) static const struct clk_ops x1000_otg_phy_ops = { .recalc_rate = x1000_otg_phy_recalc_rate, - .round_rate = x1000_otg_phy_round_rate, + .determine_rate = x1000_otg_phy_determine_rate, .set_rate = x1000_otg_phy_set_rate, .enable = x1000_usb_phy_enable, diff --git a/drivers/clk/keystone/sci-clk.c b/drivers/clk/keystone/sci-clk.c index c5894fc9395e..a4b42811de55 100644 --- a/drivers/clk/keystone/sci-clk.c +++ b/drivers/clk/keystone/sci-clk.c @@ -480,13 +480,10 @@ static int ti_sci_scan_clocks_from_fw(struct sci_clk_provider *provider) num_clks++; } - provider->clocks = devm_kmalloc_array(dev, num_clks, sizeof(sci_clk), - GFP_KERNEL); + provider->clocks = devm_kmemdup_array(dev, clks, num_clks, sizeof(sci_clk), GFP_KERNEL); if (!provider->clocks) return -ENOMEM; - memcpy(provider->clocks, clks, num_clks * sizeof(sci_clk)); - provider->num_clocks = num_clks; devm_kfree(dev, clks); diff --git a/drivers/clk/mediatek/Kconfig b/drivers/clk/mediatek/Kconfig index 5f8e6d68fa14..0e8dd82aa84e 100644 --- a/drivers/clk/mediatek/Kconfig +++ b/drivers/clk/mediatek/Kconfig @@ -1002,6 +1002,77 @@ config COMMON_CLK_MT8195_VENCSYS help This driver supports MediaTek MT8195 vencsys clocks. +config COMMON_CLK_MT8196 + tristate "Clock driver for MediaTek MT8196" + depends on ARM64 || COMPILE_TEST + select COMMON_CLK_MEDIATEK + default ARCH_MEDIATEK + help + This driver supports MediaTek MT8196 basic clocks. + +config COMMON_CLK_MT8196_IMP_IIC_WRAP + tristate "Clock driver for MediaTek MT8196 imp_iic_wrap" + depends on COMMON_CLK_MT8196 + default COMMON_CLK_MT8196 + help + This driver supports MediaTek MT8196 i2c clocks. + +config COMMON_CLK_MT8196_MCUSYS + tristate "Clock driver for MediaTek MT8196 mcusys" + depends on COMMON_CLK_MT8196 + default COMMON_CLK_MT8196 + help + This driver supports MediaTek MT8196 mcusys clocks. + +config COMMON_CLK_MT8196_MDPSYS + tristate "Clock driver for MediaTek MT8196 mdpsys" + depends on COMMON_CLK_MT8196 + default COMMON_CLK_MT8196 + help + This driver supports MediaTek MT8196 mdpsys clocks. + +config COMMON_CLK_MT8196_MFGCFG + tristate "Clock driver for MediaTek MT8196 mfgcfg" + depends on COMMON_CLK_MT8196 + default m + help + This driver supports MediaTek MT8196 mfgcfg clocks. + +config COMMON_CLK_MT8196_MMSYS + tristate "Clock driver for MediaTek MT8196 mmsys" + depends on COMMON_CLK_MT8196 + default m + help + This driver supports MediaTek MT8196 mmsys clocks. + +config COMMON_CLK_MT8196_PEXTPSYS + tristate "Clock driver for MediaTek MT8196 pextpsys" + depends on COMMON_CLK_MT8196 + default COMMON_CLK_MT8196 + help + This driver supports MediaTek MT8196 pextpsys clocks. + +config COMMON_CLK_MT8196_UFSSYS + tristate "Clock driver for MediaTek MT8196 ufssys" + depends on COMMON_CLK_MT8196 + default COMMON_CLK_MT8196 + help + This driver supports MediaTek MT8196 ufssys clocks. + +config COMMON_CLK_MT8196_VDECSYS + tristate "Clock driver for MediaTek MT8196 vdecsys" + depends on COMMON_CLK_MT8196 + default m + help + This driver supports MediaTek MT8196 vdecsys clocks. + +config COMMON_CLK_MT8196_VENCSYS + tristate "Clock driver for MediaTek MT8196 vencsys" + depends on COMMON_CLK_MT8196 + default m + help + This driver supports MediaTek MT8196 vencsys clocks. + config COMMON_CLK_MT8365 tristate "Clock driver for MediaTek MT8365" depends on ARCH_MEDIATEK || COMPILE_TEST diff --git a/drivers/clk/mediatek/Makefile b/drivers/clk/mediatek/Makefile index 6efec95406bd..d8736a060dbd 100644 --- a/drivers/clk/mediatek/Makefile +++ b/drivers/clk/mediatek/Makefile @@ -150,6 +150,19 @@ obj-$(CONFIG_COMMON_CLK_MT8195_VDOSYS) += clk-mt8195-vdo0.o clk-mt8195-vdo1.o obj-$(CONFIG_COMMON_CLK_MT8195_VENCSYS) += clk-mt8195-venc.o obj-$(CONFIG_COMMON_CLK_MT8195_VPPSYS) += clk-mt8195-vpp0.o clk-mt8195-vpp1.o obj-$(CONFIG_COMMON_CLK_MT8195_WPESYS) += clk-mt8195-wpe.o +obj-$(CONFIG_COMMON_CLK_MT8196) += clk-mt8196-apmixedsys.o clk-mt8196-topckgen.o \ + clk-mt8196-topckgen2.o clk-mt8196-vlpckgen.o \ + clk-mt8196-peri_ao.o +obj-$(CONFIG_COMMON_CLK_MT8196_IMP_IIC_WRAP) += clk-mt8196-imp_iic_wrap.o +obj-$(CONFIG_COMMON_CLK_MT8196_MCUSYS) += clk-mt8196-mcu.o +obj-$(CONFIG_COMMON_CLK_MT8196_MDPSYS) += clk-mt8196-mdpsys.o +obj-$(CONFIG_COMMON_CLK_MT8196_MFGCFG) += clk-mt8196-mfg.o +obj-$(CONFIG_COMMON_CLK_MT8196_MMSYS) += clk-mt8196-disp0.o clk-mt8196-disp1.o clk-mt8196-vdisp_ao.o \ + clk-mt8196-ovl0.o clk-mt8196-ovl1.o +obj-$(CONFIG_COMMON_CLK_MT8196_PEXTPSYS) += clk-mt8196-pextp.o +obj-$(CONFIG_COMMON_CLK_MT8196_UFSSYS) += clk-mt8196-ufs_ao.o +obj-$(CONFIG_COMMON_CLK_MT8196_VDECSYS) += clk-mt8196-vdec.o +obj-$(CONFIG_COMMON_CLK_MT8196_VENCSYS) += clk-mt8196-venc.o obj-$(CONFIG_COMMON_CLK_MT8365) += clk-mt8365-apmixedsys.o clk-mt8365.o obj-$(CONFIG_COMMON_CLK_MT8365_APU) += clk-mt8365-apu.o obj-$(CONFIG_COMMON_CLK_MT8365_CAM) += clk-mt8365-cam.o diff --git a/drivers/clk/mediatek/clk-gate.c b/drivers/clk/mediatek/clk-gate.c index 67d9e741c5e7..f6b1429ff757 100644 --- a/drivers/clk/mediatek/clk-gate.c +++ b/drivers/clk/mediatek/clk-gate.c @@ -5,6 +5,7 @@ */ #include <linux/clk-provider.h> +#include <linux/dev_printk.h> #include <linux/mfd/syscon.h> #include <linux/module.h> #include <linux/printk.h> @@ -12,15 +13,14 @@ #include <linux/slab.h> #include <linux/types.h> +#include "clk-mtk.h" #include "clk-gate.h" struct mtk_clk_gate { struct clk_hw hw; struct regmap *regmap; - int set_ofs; - int clr_ofs; - int sta_ofs; - u8 bit; + struct regmap *regmap_hwv; + const struct mtk_gate *gate; }; static inline struct mtk_clk_gate *to_mtk_clk_gate(struct clk_hw *hw) @@ -33,9 +33,9 @@ static u32 mtk_get_clockgating(struct clk_hw *hw) struct mtk_clk_gate *cg = to_mtk_clk_gate(hw); u32 val; - regmap_read(cg->regmap, cg->sta_ofs, &val); + regmap_read(cg->regmap, cg->gate->regs->sta_ofs, &val); - return val & BIT(cg->bit); + return val & BIT(cg->gate->shift); } static int mtk_cg_bit_is_cleared(struct clk_hw *hw) @@ -52,28 +52,30 @@ static void mtk_cg_set_bit(struct clk_hw *hw) { struct mtk_clk_gate *cg = to_mtk_clk_gate(hw); - regmap_write(cg->regmap, cg->set_ofs, BIT(cg->bit)); + regmap_write(cg->regmap, cg->gate->regs->set_ofs, BIT(cg->gate->shift)); } static void mtk_cg_clr_bit(struct clk_hw *hw) { struct mtk_clk_gate *cg = to_mtk_clk_gate(hw); - regmap_write(cg->regmap, cg->clr_ofs, BIT(cg->bit)); + regmap_write(cg->regmap, cg->gate->regs->clr_ofs, BIT(cg->gate->shift)); } static void mtk_cg_set_bit_no_setclr(struct clk_hw *hw) { struct mtk_clk_gate *cg = to_mtk_clk_gate(hw); - regmap_set_bits(cg->regmap, cg->sta_ofs, BIT(cg->bit)); + regmap_set_bits(cg->regmap, cg->gate->regs->sta_ofs, + BIT(cg->gate->shift)); } static void mtk_cg_clr_bit_no_setclr(struct clk_hw *hw) { struct mtk_clk_gate *cg = to_mtk_clk_gate(hw); - regmap_clear_bits(cg->regmap, cg->sta_ofs, BIT(cg->bit)); + regmap_clear_bits(cg->regmap, cg->gate->regs->sta_ofs, + BIT(cg->gate->shift)); } static int mtk_cg_enable(struct clk_hw *hw) @@ -100,6 +102,32 @@ static void mtk_cg_disable_inv(struct clk_hw *hw) mtk_cg_clr_bit(hw); } +static int mtk_cg_hwv_set_en(struct clk_hw *hw, bool enable) +{ + struct mtk_clk_gate *cg = to_mtk_clk_gate(hw); + u32 val; + + regmap_write(cg->regmap_hwv, + enable ? cg->gate->hwv_regs->set_ofs : + cg->gate->hwv_regs->clr_ofs, + BIT(cg->gate->shift)); + + return regmap_read_poll_timeout_atomic(cg->regmap_hwv, + cg->gate->hwv_regs->sta_ofs, val, + val & BIT(cg->gate->shift), 0, + MTK_WAIT_HWV_DONE_US); +} + +static int mtk_cg_hwv_enable(struct clk_hw *hw) +{ + return mtk_cg_hwv_set_en(hw, true); +} + +static void mtk_cg_hwv_disable(struct clk_hw *hw) +{ + mtk_cg_hwv_set_en(hw, false); +} + static int mtk_cg_enable_no_setclr(struct clk_hw *hw) { mtk_cg_clr_bit_no_setclr(hw); @@ -124,6 +152,15 @@ static void mtk_cg_disable_inv_no_setclr(struct clk_hw *hw) mtk_cg_clr_bit_no_setclr(hw); } +static bool mtk_cg_uses_hwv(const struct clk_ops *ops) +{ + if (ops == &mtk_clk_gate_hwv_ops_setclr || + ops == &mtk_clk_gate_hwv_ops_setclr_inv) + return true; + + return false; +} + const struct clk_ops mtk_clk_gate_ops_setclr = { .is_enabled = mtk_cg_bit_is_cleared, .enable = mtk_cg_enable, @@ -138,6 +175,20 @@ const struct clk_ops mtk_clk_gate_ops_setclr_inv = { }; EXPORT_SYMBOL_GPL(mtk_clk_gate_ops_setclr_inv); +const struct clk_ops mtk_clk_gate_hwv_ops_setclr = { + .is_enabled = mtk_cg_bit_is_cleared, + .enable = mtk_cg_hwv_enable, + .disable = mtk_cg_hwv_disable, +}; +EXPORT_SYMBOL_GPL(mtk_clk_gate_hwv_ops_setclr); + +const struct clk_ops mtk_clk_gate_hwv_ops_setclr_inv = { + .is_enabled = mtk_cg_bit_is_set, + .enable = mtk_cg_hwv_enable, + .disable = mtk_cg_hwv_disable, +}; +EXPORT_SYMBOL_GPL(mtk_clk_gate_hwv_ops_setclr_inv); + const struct clk_ops mtk_clk_gate_ops_no_setclr = { .is_enabled = mtk_cg_bit_is_cleared, .enable = mtk_cg_enable_no_setclr, @@ -152,12 +203,10 @@ const struct clk_ops mtk_clk_gate_ops_no_setclr_inv = { }; EXPORT_SYMBOL_GPL(mtk_clk_gate_ops_no_setclr_inv); -static struct clk_hw *mtk_clk_register_gate(struct device *dev, const char *name, - const char *parent_name, - struct regmap *regmap, int set_ofs, - int clr_ofs, int sta_ofs, u8 bit, - const struct clk_ops *ops, - unsigned long flags) +static struct clk_hw *mtk_clk_register_gate(struct device *dev, + const struct mtk_gate *gate, + struct regmap *regmap, + struct regmap *regmap_hwv) { struct mtk_clk_gate *cg; int ret; @@ -167,18 +216,19 @@ static struct clk_hw *mtk_clk_register_gate(struct device *dev, const char *name if (!cg) return ERR_PTR(-ENOMEM); - init.name = name; - init.flags = flags | CLK_SET_RATE_PARENT; - init.parent_names = parent_name ? &parent_name : NULL; - init.num_parents = parent_name ? 1 : 0; - init.ops = ops; + init.name = gate->name; + init.flags = gate->flags | CLK_SET_RATE_PARENT; + init.parent_names = gate->parent_name ? &gate->parent_name : NULL; + init.num_parents = gate->parent_name ? 1 : 0; + init.ops = gate->ops; + if (mtk_cg_uses_hwv(init.ops) && !regmap_hwv) + return dev_err_ptr_probe( + dev, -ENXIO, + "regmap not found for hardware voter clocks\n"); cg->regmap = regmap; - cg->set_ofs = set_ofs; - cg->clr_ofs = clr_ofs; - cg->sta_ofs = sta_ofs; - cg->bit = bit; - + cg->regmap_hwv = regmap_hwv; + cg->gate = gate; cg->hw.init = &init; ret = clk_hw_register(dev, &cg->hw); @@ -209,6 +259,7 @@ int mtk_clk_register_gates(struct device *dev, struct device_node *node, int i; struct clk_hw *hw; struct regmap *regmap; + struct regmap *regmap_hwv; if (!clk_data) return -ENOMEM; @@ -219,6 +270,12 @@ int mtk_clk_register_gates(struct device *dev, struct device_node *node, return PTR_ERR(regmap); } + regmap_hwv = mtk_clk_get_hwv_regmap(node); + if (IS_ERR(regmap_hwv)) + return dev_err_probe( + dev, PTR_ERR(regmap_hwv), + "Cannot find hardware voter regmap for %pOF\n", node); + for (i = 0; i < num; i++) { const struct mtk_gate *gate = &clks[i]; @@ -228,13 +285,7 @@ int mtk_clk_register_gates(struct device *dev, struct device_node *node, continue; } - hw = mtk_clk_register_gate(dev, gate->name, gate->parent_name, - regmap, - gate->regs->set_ofs, - gate->regs->clr_ofs, - gate->regs->sta_ofs, - gate->shift, gate->ops, - gate->flags); + hw = mtk_clk_register_gate(dev, gate, regmap, regmap_hwv); if (IS_ERR(hw)) { pr_err("Failed to register clk %s: %pe\n", gate->name, diff --git a/drivers/clk/mediatek/clk-gate.h b/drivers/clk/mediatek/clk-gate.h index 1a46b4c56fc5..4f05b9855dae 100644 --- a/drivers/clk/mediatek/clk-gate.h +++ b/drivers/clk/mediatek/clk-gate.h @@ -19,6 +19,8 @@ extern const struct clk_ops mtk_clk_gate_ops_setclr; extern const struct clk_ops mtk_clk_gate_ops_setclr_inv; extern const struct clk_ops mtk_clk_gate_ops_no_setclr; extern const struct clk_ops mtk_clk_gate_ops_no_setclr_inv; +extern const struct clk_ops mtk_clk_gate_hwv_ops_setclr; +extern const struct clk_ops mtk_clk_gate_hwv_ops_setclr_inv; struct mtk_gate_regs { u32 sta_ofs; @@ -31,6 +33,7 @@ struct mtk_gate { const char *name; const char *parent_name; const struct mtk_gate_regs *regs; + const struct mtk_gate_regs *hwv_regs; int shift; const struct clk_ops *ops; unsigned long flags; diff --git a/drivers/clk/mediatek/clk-mt7622-aud.c b/drivers/clk/mediatek/clk-mt7622-aud.c index 931a0598e598..a4ea5e20efa2 100644 --- a/drivers/clk/mediatek/clk-mt7622-aud.c +++ b/drivers/clk/mediatek/clk-mt7622-aud.c @@ -75,6 +75,7 @@ static const struct mtk_gate audio_clks[] = { GATE_AUDIO1(CLK_AUDIO_A1SYS, "audio_a1sys", "a1sys_hp_sel", 21), GATE_AUDIO1(CLK_AUDIO_A2SYS, "audio_a2sys", "a2sys_hp_sel", 22), GATE_AUDIO1(CLK_AUDIO_AFE_CONN, "audio_afe_conn", "a1sys_hp_sel", 23), + GATE_AUDIO1(CLK_AUDIO_AFE_MRGIF, "audio_afe_mrgif", "aud_mux1_sel", 25), /* AUDIO2 */ GATE_AUDIO2(CLK_AUDIO_UL1, "audio_ul1", "a1sys_hp_sel", 0), GATE_AUDIO2(CLK_AUDIO_UL2, "audio_ul2", "a1sys_hp_sel", 1), diff --git a/drivers/clk/mediatek/clk-mt8195-infra_ao.c b/drivers/clk/mediatek/clk-mt8195-infra_ao.c index bb648a88e43a..ad47fdb23460 100644 --- a/drivers/clk/mediatek/clk-mt8195-infra_ao.c +++ b/drivers/clk/mediatek/clk-mt8195-infra_ao.c @@ -103,7 +103,7 @@ static const struct mtk_gate infra_ao_clks[] = { GATE_INFRA_AO0(CLK_INFRA_AO_CQ_DMA_FPC, "infra_ao_cq_dma_fpc", "fpc", 28), GATE_INFRA_AO0(CLK_INFRA_AO_UART5, "infra_ao_uart5", "top_uart", 29), /* INFRA_AO1 */ - GATE_INFRA_AO1(CLK_INFRA_AO_HDMI_26M, "infra_ao_hdmi_26m", "clk26m", 0), + GATE_INFRA_AO1(CLK_INFRA_AO_HDMI_26M, "infra_ao_hdmi_26m", "top_hdmi_xtal", 0), GATE_INFRA_AO1(CLK_INFRA_AO_SPI0, "infra_ao_spi0", "top_spi", 1), GATE_INFRA_AO1(CLK_INFRA_AO_MSDC0, "infra_ao_msdc0", "top_msdc50_0_hclk", 2), GATE_INFRA_AO1(CLK_INFRA_AO_MSDC1, "infra_ao_msdc1", "top_axi", 4), diff --git a/drivers/clk/mediatek/clk-mt8196-apmixedsys.c b/drivers/clk/mediatek/clk-mt8196-apmixedsys.c new file mode 100644 index 000000000000..617f5449b88b --- /dev/null +++ b/drivers/clk/mediatek/clk-mt8196-apmixedsys.c @@ -0,0 +1,204 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2025 MediaTek Inc. + * Guangjie Song <guangjie.song@mediatek.com> + * Copyright (c) 2025 Collabora Ltd. + * Laura Nao <laura.nao@collabora.com> + */ +#include <dt-bindings/clock/mediatek,mt8196-clock.h> + +#include <linux/clk.h> +#include <linux/module.h> +#include <linux/of.h> +#include <linux/of_address.h> +#include <linux/of_device.h> +#include <linux/platform_device.h> + +#include "clk-mtk.h" +#include "clk-pll.h" + +/* APMIXEDSYS PLL control register offsets */ +#define MAINPLL_CON0 0x250 +#define MAINPLL_CON1 0x254 +#define UNIVPLL_CON0 0x264 +#define UNIVPLL_CON1 0x268 +#define MSDCPLL_CON0 0x278 +#define MSDCPLL_CON1 0x27c +#define ADSPPLL_CON0 0x28c +#define ADSPPLL_CON1 0x290 +#define EMIPLL_CON0 0x2a0 +#define EMIPLL_CON1 0x2a4 +#define EMIPLL2_CON0 0x2b4 +#define EMIPLL2_CON1 0x2b8 +#define NET1PLL_CON0 0x2c8 +#define NET1PLL_CON1 0x2cc +#define SGMIIPLL_CON0 0x2dc +#define SGMIIPLL_CON1 0x2e0 + +/* APMIXEDSYS_GP2 PLL control register offsets*/ +#define MAINPLL2_CON0 0x250 +#define MAINPLL2_CON1 0x254 +#define UNIVPLL2_CON0 0x264 +#define UNIVPLL2_CON1 0x268 +#define MMPLL2_CON0 0x278 +#define MMPLL2_CON1 0x27c +#define IMGPLL_CON0 0x28c +#define IMGPLL_CON1 0x290 +#define TVDPLL1_CON0 0x2a0 +#define TVDPLL1_CON1 0x2a4 +#define TVDPLL2_CON0 0x2b4 +#define TVDPLL2_CON1 0x2b8 +#define TVDPLL3_CON0 0x2c8 +#define TVDPLL3_CON1 0x2cc + +#define PLLEN_ALL 0x080 +#define PLLEN_ALL_SET 0x084 +#define PLLEN_ALL_CLR 0x088 + +#define FENC_STATUS_CON0 0x03c + +#define MT8196_PLL_FMAX (3800UL * MHZ) +#define MT8196_PLL_FMIN (1500UL * MHZ) +#define MT8196_INTEGER_BITS 8 + +#define PLL_FENC(_id, _name, _reg, _fenc_sta_ofs, _fenc_sta_bit,\ + _flags, _pd_reg, _pd_shift, \ + _pcw_reg, _pcw_shift, _pcwbits, \ + _pll_en_bit) { \ + .id = _id, \ + .name = _name, \ + .reg = _reg, \ + .fenc_sta_ofs = _fenc_sta_ofs, \ + .fenc_sta_bit = _fenc_sta_bit, \ + .flags = _flags, \ + .fmax = MT8196_PLL_FMAX, \ + .fmin = MT8196_PLL_FMIN, \ + .pd_reg = _pd_reg, \ + .pd_shift = _pd_shift, \ + .pcw_reg = _pcw_reg, \ + .pcw_shift = _pcw_shift, \ + .pcwbits = _pcwbits, \ + .pcwibits = MT8196_INTEGER_BITS, \ + .en_reg = PLLEN_ALL, \ + .en_set_reg = PLLEN_ALL_SET, \ + .en_clr_reg = PLLEN_ALL_CLR, \ + .pll_en_bit = _pll_en_bit, \ + .ops = &mtk_pll_fenc_clr_set_ops, \ +} + +struct mtk_pll_desc { + const struct mtk_pll_data *clks; + size_t num_clks; +}; + +static const struct mtk_pll_data apmixed_plls[] = { + PLL_FENC(CLK_APMIXED_MAINPLL, "mainpll", MAINPLL_CON0, FENC_STATUS_CON0, + 7, PLL_AO, MAINPLL_CON1, 24, MAINPLL_CON1, 0, 22, 0), + PLL_FENC(CLK_APMIXED_UNIVPLL, "univpll", UNIVPLL_CON0, FENC_STATUS_CON0, + 6, 0, UNIVPLL_CON1, 24, UNIVPLL_CON1, 0, 22, 1), + PLL_FENC(CLK_APMIXED_MSDCPLL, "msdcpll", MSDCPLL_CON0, FENC_STATUS_CON0, + 5, 0, MSDCPLL_CON1, 24, MSDCPLL_CON1, 0, 22, 2), + PLL_FENC(CLK_APMIXED_ADSPPLL, "adsppll", ADSPPLL_CON0, FENC_STATUS_CON0, + 4, 0, ADSPPLL_CON1, 24, ADSPPLL_CON1, 0, 22, 3), + PLL_FENC(CLK_APMIXED_EMIPLL, "emipll", EMIPLL_CON0, FENC_STATUS_CON0, 3, + PLL_AO, EMIPLL_CON1, 24, EMIPLL_CON1, 0, 22, 4), + PLL_FENC(CLK_APMIXED_EMIPLL2, "emipll2", EMIPLL2_CON0, FENC_STATUS_CON0, + 2, PLL_AO, EMIPLL2_CON1, 24, EMIPLL2_CON1, 0, 22, 5), + PLL_FENC(CLK_APMIXED_NET1PLL, "net1pll", NET1PLL_CON0, FENC_STATUS_CON0, + 1, 0, NET1PLL_CON1, 24, NET1PLL_CON1, 0, 22, 6), + PLL_FENC(CLK_APMIXED_SGMIIPLL, "sgmiipll", SGMIIPLL_CON0, FENC_STATUS_CON0, + 0, 0, SGMIIPLL_CON1, 24, SGMIIPLL_CON1, 0, 22, 7), +}; + +static const struct mtk_pll_desc apmixed_desc = { + .clks = apmixed_plls, + .num_clks = ARRAY_SIZE(apmixed_plls), +}; + +static const struct mtk_pll_data apmixed2_plls[] = { + PLL_FENC(CLK_APMIXED2_MAINPLL2, "mainpll2", MAINPLL2_CON0, FENC_STATUS_CON0, + 6, 0, MAINPLL2_CON1, 24, MAINPLL2_CON1, 0, 22, 0), + PLL_FENC(CLK_APMIXED2_UNIVPLL2, "univpll2", UNIVPLL2_CON0, FENC_STATUS_CON0, + 5, 0, UNIVPLL2_CON1, 24, UNIVPLL2_CON1, 0, 22, 1), + PLL_FENC(CLK_APMIXED2_MMPLL2, "mmpll2", MMPLL2_CON0, FENC_STATUS_CON0, + 4, 0, MMPLL2_CON1, 24, MMPLL2_CON1, 0, 22, 2), + PLL_FENC(CLK_APMIXED2_IMGPLL, "imgpll", IMGPLL_CON0, FENC_STATUS_CON0, + 3, 0, IMGPLL_CON1, 24, IMGPLL_CON1, 0, 22, 3), + PLL_FENC(CLK_APMIXED2_TVDPLL1, "tvdpll1", TVDPLL1_CON0, FENC_STATUS_CON0, + 2, 0, TVDPLL1_CON1, 24, TVDPLL1_CON1, 0, 22, 4), + PLL_FENC(CLK_APMIXED2_TVDPLL2, "tvdpll2", TVDPLL2_CON0, FENC_STATUS_CON0, + 1, 0, TVDPLL2_CON1, 24, TVDPLL2_CON1, 0, 22, 5), + PLL_FENC(CLK_APMIXED2_TVDPLL3, "tvdpll3", TVDPLL3_CON0, FENC_STATUS_CON0, + 0, 0, TVDPLL3_CON1, 24, TVDPLL3_CON1, 0, 22, 6), +}; + +static const struct mtk_pll_desc apmixed2_desc = { + .clks = apmixed2_plls, + .num_clks = ARRAY_SIZE(apmixed2_plls), +}; + +static int clk_mt8196_apmixed_probe(struct platform_device *pdev) +{ + struct clk_hw_onecell_data *clk_data; + struct device_node *node = pdev->dev.of_node; + const struct mtk_pll_desc *mcd; + int r; + + mcd = device_get_match_data(&pdev->dev); + if (!mcd) + return -EINVAL; + + clk_data = mtk_alloc_clk_data(mcd->num_clks); + if (!clk_data) + return -ENOMEM; + + r = mtk_clk_register_plls(node, mcd->clks, mcd->num_clks, clk_data); + if (r) + goto free_apmixed_data; + + r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data); + if (r) + goto unregister_plls; + + platform_set_drvdata(pdev, clk_data); + + return r; + +unregister_plls: + mtk_clk_unregister_plls(mcd->clks, mcd->num_clks, clk_data); +free_apmixed_data: + mtk_free_clk_data(clk_data); + return r; +} + +static void clk_mt8196_apmixed_remove(struct platform_device *pdev) +{ + const struct mtk_pll_desc *mcd = device_get_match_data(&pdev->dev); + struct clk_hw_onecell_data *clk_data = platform_get_drvdata(pdev); + struct device_node *node = pdev->dev.of_node; + + of_clk_del_provider(node); + mtk_clk_unregister_plls(mcd->clks, mcd->num_clks, clk_data); + mtk_free_clk_data(clk_data); +} + +static const struct of_device_id of_match_clk_mt8196_apmixed[] = { + { .compatible = "mediatek,mt8196-apmixedsys", .data = &apmixed_desc }, + { .compatible = "mediatek,mt8196-apmixedsys-gp2", + .data = &apmixed2_desc }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(of, of_match_clk_mt8196_apmixed); + +static struct platform_driver clk_mt8196_apmixed_drv = { + .probe = clk_mt8196_apmixed_probe, + .remove = clk_mt8196_apmixed_remove, + .driver = { + .name = "clk-mt8196-apmixed", + .of_match_table = of_match_clk_mt8196_apmixed, + }, +}; +module_platform_driver(clk_mt8196_apmixed_drv); + +MODULE_DESCRIPTION("MediaTek MT8196 apmixedsys clocks driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/clk/mediatek/clk-mt8196-disp0.c b/drivers/clk/mediatek/clk-mt8196-disp0.c new file mode 100644 index 000000000000..9474aad26e92 --- /dev/null +++ b/drivers/clk/mediatek/clk-mt8196-disp0.c @@ -0,0 +1,170 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2025 MediaTek Inc. + * Guangjie Song <guangjie.song@mediatek.com> + * Copyright (c) 2025 Collabora Ltd. + * Laura Nao <laura.nao@collabora.com> + */ +#include <dt-bindings/clock/mediatek,mt8196-clock.h> + +#include <linux/clk-provider.h> +#include <linux/module.h> +#include <linux/of_device.h> +#include <linux/platform_device.h> + +#include "clk-gate.h" +#include "clk-mtk.h" + +static const struct mtk_gate_regs mm0_cg_regs = { + .set_ofs = 0x104, + .clr_ofs = 0x108, + .sta_ofs = 0x100, +}; + +static const struct mtk_gate_regs mm0_hwv_regs = { + .set_ofs = 0x0020, + .clr_ofs = 0x0024, + .sta_ofs = 0x2c10, +}; + +static const struct mtk_gate_regs mm1_cg_regs = { + .set_ofs = 0x114, + .clr_ofs = 0x118, + .sta_ofs = 0x110, +}; + +static const struct mtk_gate_regs mm1_hwv_regs = { + .set_ofs = 0x0028, + .clr_ofs = 0x002c, + .sta_ofs = 0x2c14, +}; + +#define GATE_MM0(_id, _name, _parent, _shift) { \ + .id = _id, \ + .name = _name, \ + .parent_name = _parent, \ + .regs = &mm0_cg_regs, \ + .shift = _shift, \ + .flags = CLK_OPS_PARENT_ENABLE, \ + .ops = &mtk_clk_gate_ops_setclr,\ + } + +#define GATE_HWV_MM0(_id, _name, _parent, _shift) { \ + .id = _id, \ + .name = _name, \ + .parent_name = _parent, \ + .regs = &mm0_cg_regs, \ + .hwv_regs = &mm0_hwv_regs, \ + .shift = _shift, \ + .ops = &mtk_clk_gate_hwv_ops_setclr, \ + .flags = CLK_OPS_PARENT_ENABLE \ + } + +#define GATE_MM1(_id, _name, _parent, _shift) { \ + .id = _id, \ + .name = _name, \ + .parent_name = _parent, \ + .regs = &mm1_cg_regs, \ + .shift = _shift, \ + .flags = CLK_OPS_PARENT_ENABLE, \ + .ops = &mtk_clk_gate_ops_setclr,\ + } + +#define GATE_HWV_MM1(_id, _name, _parent, _shift) { \ + .id = _id, \ + .name = _name, \ + .parent_name = _parent, \ + .regs = &mm1_cg_regs, \ + .hwv_regs = &mm1_hwv_regs, \ + .shift = _shift, \ + .ops = &mtk_clk_gate_hwv_ops_setclr, \ + .flags = CLK_OPS_PARENT_ENABLE, \ + } + +static const struct mtk_gate mm_clks[] = { + /* MM0 */ + GATE_HWV_MM0(CLK_MM_CONFIG, "mm_config", "disp", 0), + GATE_HWV_MM0(CLK_MM_DISP_MUTEX0, "mm_disp_mutex0", "disp", 1), + GATE_HWV_MM0(CLK_MM_DISP_AAL0, "mm_disp_aal0", "disp", 2), + GATE_HWV_MM0(CLK_MM_DISP_AAL1, "mm_disp_aal1", "disp", 3), + GATE_MM0(CLK_MM_DISP_C3D0, "mm_disp_c3d0", "disp", 4), + GATE_MM0(CLK_MM_DISP_C3D1, "mm_disp_c3d1", "disp", 5), + GATE_MM0(CLK_MM_DISP_C3D2, "mm_disp_c3d2", "disp", 6), + GATE_MM0(CLK_MM_DISP_C3D3, "mm_disp_c3d3", "disp", 7), + GATE_MM0(CLK_MM_DISP_CCORR0, "mm_disp_ccorr0", "disp", 8), + GATE_MM0(CLK_MM_DISP_CCORR1, "mm_disp_ccorr1", "disp", 9), + GATE_MM0(CLK_MM_DISP_CCORR2, "mm_disp_ccorr2", "disp", 10), + GATE_MM0(CLK_MM_DISP_CCORR3, "mm_disp_ccorr3", "disp", 11), + GATE_MM0(CLK_MM_DISP_CHIST0, "mm_disp_chist0", "disp", 12), + GATE_MM0(CLK_MM_DISP_CHIST1, "mm_disp_chist1", "disp", 13), + GATE_MM0(CLK_MM_DISP_COLOR0, "mm_disp_color0", "disp", 14), + GATE_MM0(CLK_MM_DISP_COLOR1, "mm_disp_color1", "disp", 15), + GATE_MM0(CLK_MM_DISP_DITHER0, "mm_disp_dither0", "disp", 16), + GATE_MM0(CLK_MM_DISP_DITHER1, "mm_disp_dither1", "disp", 17), + GATE_HWV_MM0(CLK_MM_DISP_DLI_ASYNC0, "mm_disp_dli_async0", "disp", 18), + GATE_HWV_MM0(CLK_MM_DISP_DLI_ASYNC1, "mm_disp_dli_async1", "disp", 19), + GATE_HWV_MM0(CLK_MM_DISP_DLI_ASYNC2, "mm_disp_dli_async2", "disp", 20), + GATE_HWV_MM0(CLK_MM_DISP_DLI_ASYNC3, "mm_disp_dli_async3", "disp", 21), + GATE_HWV_MM0(CLK_MM_DISP_DLI_ASYNC4, "mm_disp_dli_async4", "disp", 22), + GATE_HWV_MM0(CLK_MM_DISP_DLI_ASYNC5, "mm_disp_dli_async5", "disp", 23), + GATE_HWV_MM0(CLK_MM_DISP_DLI_ASYNC6, "mm_disp_dli_async6", "disp", 24), + GATE_HWV_MM0(CLK_MM_DISP_DLI_ASYNC7, "mm_disp_dli_async7", "disp", 25), + GATE_HWV_MM0(CLK_MM_DISP_DLI_ASYNC8, "mm_disp_dli_async8", "disp", 26), + GATE_HWV_MM0(CLK_MM_DISP_DLI_ASYNC9, "mm_disp_dli_async9", "disp", 27), + GATE_HWV_MM0(CLK_MM_DISP_DLI_ASYNC10, "mm_disp_dli_async10", "disp", 28), + GATE_HWV_MM0(CLK_MM_DISP_DLI_ASYNC11, "mm_disp_dli_async11", "disp", 29), + GATE_HWV_MM0(CLK_MM_DISP_DLI_ASYNC12, "mm_disp_dli_async12", "disp", 30), + GATE_HWV_MM0(CLK_MM_DISP_DLI_ASYNC13, "mm_disp_dli_async13", "disp", 31), + /* MM1 */ + GATE_HWV_MM1(CLK_MM_DISP_DLI_ASYNC14, "mm_disp_dli_async14", "disp", 0), + GATE_HWV_MM1(CLK_MM_DISP_DLI_ASYNC15, "mm_disp_dli_async15", "disp", 1), + GATE_HWV_MM1(CLK_MM_DISP_DLO_ASYNC0, "mm_disp_dlo_async0", "disp", 2), + GATE_HWV_MM1(CLK_MM_DISP_DLO_ASYNC1, "mm_disp_dlo_async1", "disp", 3), + GATE_HWV_MM1(CLK_MM_DISP_DLO_ASYNC2, "mm_disp_dlo_async2", "disp", 4), + GATE_HWV_MM1(CLK_MM_DISP_DLO_ASYNC3, "mm_disp_dlo_async3", "disp", 5), + GATE_HWV_MM1(CLK_MM_DISP_DLO_ASYNC4, "mm_disp_dlo_async4", "disp", 6), + GATE_HWV_MM1(CLK_MM_DISP_DLO_ASYNC5, "mm_disp_dlo_async5", "disp", 7), + GATE_HWV_MM1(CLK_MM_DISP_DLO_ASYNC6, "mm_disp_dlo_async6", "disp", 8), + GATE_HWV_MM1(CLK_MM_DISP_DLO_ASYNC7, "mm_disp_dlo_async7", "disp", 9), + GATE_HWV_MM1(CLK_MM_DISP_DLO_ASYNC8, "mm_disp_dlo_async8", "disp", 10), + GATE_MM1(CLK_MM_DISP_GAMMA0, "mm_disp_gamma0", "disp", 11), + GATE_MM1(CLK_MM_DISP_GAMMA1, "mm_disp_gamma1", "disp", 12), + GATE_MM1(CLK_MM_MDP_AAL0, "mm_mdp_aal0", "disp", 13), + GATE_MM1(CLK_MM_MDP_AAL1, "mm_mdp_aal1", "disp", 14), + GATE_HWV_MM1(CLK_MM_MDP_RDMA0, "mm_mdp_rdma0", "disp", 15), + GATE_HWV_MM1(CLK_MM_DISP_POSTMASK0, "mm_disp_postmask0", "disp", 16), + GATE_HWV_MM1(CLK_MM_DISP_POSTMASK1, "mm_disp_postmask1", "disp", 17), + GATE_HWV_MM1(CLK_MM_MDP_RSZ0, "mm_mdp_rsz0", "disp", 18), + GATE_HWV_MM1(CLK_MM_MDP_RSZ1, "mm_mdp_rsz1", "disp", 19), + GATE_HWV_MM1(CLK_MM_DISP_SPR0, "mm_disp_spr0", "disp", 20), + GATE_MM1(CLK_MM_DISP_TDSHP0, "mm_disp_tdshp0", "disp", 21), + GATE_MM1(CLK_MM_DISP_TDSHP1, "mm_disp_tdshp1", "disp", 22), + GATE_HWV_MM1(CLK_MM_DISP_WDMA0, "mm_disp_wdma0", "disp", 23), + GATE_HWV_MM1(CLK_MM_DISP_Y2R0, "mm_disp_y2r0", "disp", 24), + GATE_HWV_MM1(CLK_MM_SMI_SUB_COMM0, "mm_ssc", "disp", 25), + GATE_HWV_MM1(CLK_MM_DISP_FAKE_ENG0, "mm_disp_fake_eng0", "disp", 26), +}; + +static const struct mtk_clk_desc mm_mcd = { + .clks = mm_clks, + .num_clks = ARRAY_SIZE(mm_clks), +}; + +static const struct platform_device_id clk_mt8196_disp0_id_table[] = { + { .name = "clk-mt8196-disp0", .driver_data = (kernel_ulong_t)&mm_mcd }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(platform, clk_mt8196_disp0_id_table); + +static struct platform_driver clk_mt8196_disp0_drv = { + .probe = mtk_clk_pdev_probe, + .remove = mtk_clk_pdev_remove, + .driver = { + .name = "clk-mt8196-disp0", + }, + .id_table = clk_mt8196_disp0_id_table, +}; +module_platform_driver(clk_mt8196_disp0_drv); + +MODULE_DESCRIPTION("MediaTek MT8196 disp0 clocks driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/clk/mediatek/clk-mt8196-disp1.c b/drivers/clk/mediatek/clk-mt8196-disp1.c new file mode 100644 index 000000000000..3bbec79a7010 --- /dev/null +++ b/drivers/clk/mediatek/clk-mt8196-disp1.c @@ -0,0 +1,170 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2025 MediaTek Inc. + * Guangjie Song <guangjie.song@mediatek.com> + * Copyright (c) 2025 Collabora Ltd. + * Laura Nao <laura.nao@collabora.com> + */ +#include <dt-bindings/clock/mediatek,mt8196-clock.h> + +#include <linux/clk-provider.h> +#include <linux/module.h> +#include <linux/of_device.h> +#include <linux/platform_device.h> + +#include "clk-gate.h" +#include "clk-mtk.h" + +static const struct mtk_gate_regs mm10_cg_regs = { + .set_ofs = 0x104, + .clr_ofs = 0x108, + .sta_ofs = 0x100, +}; + +static const struct mtk_gate_regs mm10_hwv_regs = { + .set_ofs = 0x0010, + .clr_ofs = 0x0014, + .sta_ofs = 0x2c08, +}; + +static const struct mtk_gate_regs mm11_cg_regs = { + .set_ofs = 0x114, + .clr_ofs = 0x118, + .sta_ofs = 0x110, +}; + +static const struct mtk_gate_regs mm11_hwv_regs = { + .set_ofs = 0x0018, + .clr_ofs = 0x001c, + .sta_ofs = 0x2c0c, +}; + +#define GATE_MM10(_id, _name, _parent, _shift) {\ + .id = _id, \ + .name = _name, \ + .parent_name = _parent, \ + .regs = &mm10_cg_regs, \ + .shift = _shift, \ + .flags = CLK_OPS_PARENT_ENABLE, \ + .ops = &mtk_clk_gate_ops_setclr,\ + } + +#define GATE_HWV_MM10(_id, _name, _parent, _shift) { \ + .id = _id, \ + .name = _name, \ + .parent_name = _parent, \ + .regs = &mm10_cg_regs, \ + .hwv_regs = &mm10_hwv_regs, \ + .shift = _shift, \ + .ops = &mtk_clk_gate_hwv_ops_setclr, \ + .flags = CLK_OPS_PARENT_ENABLE, \ + } + +#define GATE_MM11(_id, _name, _parent, _shift) {\ + .id = _id, \ + .name = _name, \ + .parent_name = _parent, \ + .regs = &mm11_cg_regs, \ + .shift = _shift, \ + .flags = CLK_OPS_PARENT_ENABLE, \ + .ops = &mtk_clk_gate_ops_setclr,\ + } + +#define GATE_HWV_MM11(_id, _name, _parent, _shift) { \ + .id = _id, \ + .name = _name, \ + .parent_name = _parent, \ + .regs = &mm11_cg_regs, \ + .hwv_regs = &mm11_hwv_regs, \ + .shift = _shift, \ + .ops = &mtk_clk_gate_hwv_ops_setclr, \ + } + +static const struct mtk_gate mm1_clks[] = { + /* MM10 */ + GATE_HWV_MM10(CLK_MM1_DISPSYS1_CONFIG, "mm1_dispsys1_config", "disp", 0), + GATE_HWV_MM10(CLK_MM1_DISPSYS1_S_CONFIG, "mm1_dispsys1_s_config", "disp", 1), + GATE_HWV_MM10(CLK_MM1_DISP_MUTEX0, "mm1_disp_mutex0", "disp", 2), + GATE_HWV_MM10(CLK_MM1_DISP_DLI_ASYNC20, "mm1_disp_dli_async20", "disp", 3), + GATE_HWV_MM10(CLK_MM1_DISP_DLI_ASYNC21, "mm1_disp_dli_async21", "disp", 4), + GATE_HWV_MM10(CLK_MM1_DISP_DLI_ASYNC22, "mm1_disp_dli_async22", "disp", 5), + GATE_HWV_MM10(CLK_MM1_DISP_DLI_ASYNC23, "mm1_disp_dli_async23", "disp", 6), + GATE_HWV_MM10(CLK_MM1_DISP_DLI_ASYNC24, "mm1_disp_dli_async24", "disp", 7), + GATE_HWV_MM10(CLK_MM1_DISP_DLI_ASYNC25, "mm1_disp_dli_async25", "disp", 8), + GATE_HWV_MM10(CLK_MM1_DISP_DLI_ASYNC26, "mm1_disp_dli_async26", "disp", 9), + GATE_HWV_MM10(CLK_MM1_DISP_DLI_ASYNC27, "mm1_disp_dli_async27", "disp", 10), + GATE_HWV_MM10(CLK_MM1_DISP_DLI_ASYNC28, "mm1_disp_dli_async28", "disp", 11), + GATE_HWV_MM10(CLK_MM1_DISP_RELAY0, "mm1_disp_relay0", "disp", 12), + GATE_HWV_MM10(CLK_MM1_DISP_RELAY1, "mm1_disp_relay1", "disp", 13), + GATE_HWV_MM10(CLK_MM1_DISP_RELAY2, "mm1_disp_relay2", "disp", 14), + GATE_HWV_MM10(CLK_MM1_DISP_RELAY3, "mm1_disp_relay3", "disp", 15), + GATE_HWV_MM10(CLK_MM1_DISP_DP_INTF0, "mm1_DP_CLK", "disp", 16), + GATE_HWV_MM10(CLK_MM1_DISP_DP_INTF1, "mm1_disp_dp_intf1", "disp", 17), + GATE_HWV_MM10(CLK_MM1_DISP_DSC_WRAP0, "mm1_disp_dsc_wrap0", "disp", 18), + GATE_HWV_MM10(CLK_MM1_DISP_DSC_WRAP1, "mm1_disp_dsc_wrap1", "disp", 19), + GATE_HWV_MM10(CLK_MM1_DISP_DSC_WRAP2, "mm1_disp_dsc_wrap2", "disp", 20), + GATE_HWV_MM10(CLK_MM1_DISP_DSC_WRAP3, "mm1_disp_dsc_wrap3", "disp", 21), + GATE_HWV_MM10(CLK_MM1_DISP_DSI0, "mm1_CLK0", "disp", 22), + GATE_HWV_MM10(CLK_MM1_DISP_DSI1, "mm1_CLK1", "disp", 23), + GATE_HWV_MM10(CLK_MM1_DISP_DSI2, "mm1_CLK2", "disp", 24), + GATE_HWV_MM10(CLK_MM1_DISP_DVO0, "mm1_disp_dvo0", "disp", 25), + GATE_HWV_MM10(CLK_MM1_DISP_GDMA0, "mm1_disp_gdma0", "disp", 26), + GATE_HWV_MM10(CLK_MM1_DISP_MERGE0, "mm1_disp_merge0", "disp", 27), + GATE_HWV_MM10(CLK_MM1_DISP_MERGE1, "mm1_disp_merge1", "disp", 28), + GATE_HWV_MM10(CLK_MM1_DISP_MERGE2, "mm1_disp_merge2", "disp", 29), + GATE_HWV_MM10(CLK_MM1_DISP_ODDMR0, "mm1_disp_oddmr0", "disp", 30), + GATE_HWV_MM10(CLK_MM1_DISP_POSTALIGN0, "mm1_disp_postalign0", "disp", 31), + /* MM11 */ + GATE_HWV_MM11(CLK_MM1_DISP_DITHER2, "mm1_disp_dither2", "disp", 0), + GATE_HWV_MM11(CLK_MM1_DISP_R2Y0, "mm1_disp_r2y0", "disp", 1), + GATE_HWV_MM11(CLK_MM1_DISP_SPLITTER0, "mm1_disp_splitter0", "disp", 2), + GATE_HWV_MM11(CLK_MM1_DISP_SPLITTER1, "mm1_disp_splitter1", "disp", 3), + GATE_HWV_MM11(CLK_MM1_DISP_SPLITTER2, "mm1_disp_splitter2", "disp", 4), + GATE_HWV_MM11(CLK_MM1_DISP_SPLITTER3, "mm1_disp_splitter3", "disp", 5), + GATE_HWV_MM11(CLK_MM1_DISP_VDCM0, "mm1_disp_vdcm0", "disp", 6), + GATE_HWV_MM11(CLK_MM1_DISP_WDMA1, "mm1_disp_wdma1", "disp", 7), + GATE_HWV_MM11(CLK_MM1_DISP_WDMA2, "mm1_disp_wdma2", "disp", 8), + GATE_HWV_MM11(CLK_MM1_DISP_WDMA3, "mm1_disp_wdma3", "disp", 9), + GATE_HWV_MM11(CLK_MM1_DISP_WDMA4, "mm1_disp_wdma4", "disp", 10), + GATE_HWV_MM11(CLK_MM1_MDP_RDMA1, "mm1_mdp_rdma1", "disp", 11), + GATE_HWV_MM11(CLK_MM1_SMI_LARB0, "mm1_smi_larb0", "disp", 12), + GATE_HWV_MM11(CLK_MM1_MOD1, "mm1_mod1", "clk26m", 13), + GATE_HWV_MM11(CLK_MM1_MOD2, "mm1_mod2", "clk26m", 14), + GATE_HWV_MM11(CLK_MM1_MOD3, "mm1_mod3", "clk26m", 15), + GATE_HWV_MM11(CLK_MM1_MOD4, "mm1_mod4", "dp0", 16), + GATE_HWV_MM11(CLK_MM1_MOD5, "mm1_mod5", "dp1", 17), + GATE_HWV_MM11(CLK_MM1_MOD6, "mm1_mod6", "dp1", 18), + GATE_HWV_MM11(CLK_MM1_CG0, "mm1_cg0", "disp", 20), + GATE_HWV_MM11(CLK_MM1_CG1, "mm1_cg1", "disp", 21), + GATE_HWV_MM11(CLK_MM1_CG2, "mm1_cg2", "disp", 22), + GATE_HWV_MM11(CLK_MM1_CG3, "mm1_cg3", "disp", 23), + GATE_HWV_MM11(CLK_MM1_CG4, "mm1_cg4", "disp", 24), + GATE_HWV_MM11(CLK_MM1_CG5, "mm1_cg5", "disp", 25), + GATE_HWV_MM11(CLK_MM1_CG6, "mm1_cg6", "disp", 26), + GATE_HWV_MM11(CLK_MM1_CG7, "mm1_cg7", "disp", 27), + GATE_HWV_MM11(CLK_MM1_F26M, "mm1_f26m_ck", "clk26m", 28), +}; + +static const struct mtk_clk_desc mm1_mcd = { + .clks = mm1_clks, + .num_clks = ARRAY_SIZE(mm1_clks), +}; + +static const struct platform_device_id clk_mt8196_disp1_id_table[] = { + { .name = "clk-mt8196-disp1", .driver_data = (kernel_ulong_t)&mm1_mcd }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(platform, clk_mt8196_disp1_id_table); + +static struct platform_driver clk_mt8196_disp1_drv = { + .probe = mtk_clk_pdev_probe, + .remove = mtk_clk_pdev_remove, + .driver = { + .name = "clk-mt8196-disp1", + }, + .id_table = clk_mt8196_disp1_id_table, +}; +module_platform_driver(clk_mt8196_disp1_drv); + +MODULE_DESCRIPTION("MediaTek MT8196 disp1 clocks driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/clk/mediatek/clk-mt8196-imp_iic_wrap.c b/drivers/clk/mediatek/clk-mt8196-imp_iic_wrap.c new file mode 100644 index 000000000000..a63241671650 --- /dev/null +++ b/drivers/clk/mediatek/clk-mt8196-imp_iic_wrap.c @@ -0,0 +1,118 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2025 MediaTek Inc. + * Guangjie Song <guangjie.song@mediatek.com> + * Copyright (c) 2025 Collabora Ltd. + * Laura Nao <laura.nao@collabora.com> + */ +#include <dt-bindings/clock/mediatek,mt8196-clock.h> + +#include <linux/clk-provider.h> +#include <linux/module.h> +#include <linux/of_device.h> +#include <linux/platform_device.h> + +#include "clk-gate.h" +#include "clk-mtk.h" + +static const struct mtk_gate_regs imp_cg_regs = { + .set_ofs = 0xe08, + .clr_ofs = 0xe04, + .sta_ofs = 0xe00, +}; + +#define GATE_IMP(_id, _name, _parent, _shift) { \ + .id = _id, \ + .name = _name, \ + .parent_name = _parent, \ + .regs = &imp_cg_regs, \ + .shift = _shift, \ + .flags = CLK_OPS_PARENT_ENABLE, \ + .ops = &mtk_clk_gate_ops_setclr, \ + } + +static const struct mtk_gate impc_clks[] = { + GATE_IMP(CLK_IMPC_I2C11, "impc_i2c11", "i2c_p", 0), + GATE_IMP(CLK_IMPC_I2C12, "impc_i2c12", "i2c_p", 1), + GATE_IMP(CLK_IMPC_I2C13, "impc_i2c13", "i2c_p", 2), + GATE_IMP(CLK_IMPC_I2C14, "impc_i2c14", "i2c_p", 3), +}; + +static const struct mtk_clk_desc impc_mcd = { + .clks = impc_clks, + .num_clks = ARRAY_SIZE(impc_clks), +}; + +static const struct mtk_gate impe_clks[] = { + GATE_IMP(CLK_IMPE_I2C5, "impe_i2c5", "i2c_east", 0), +}; + +static const struct mtk_clk_desc impe_mcd = { + .clks = impe_clks, + .num_clks = ARRAY_SIZE(impe_clks), +}; + +static const struct mtk_gate_regs impn_hwv_regs = { + .set_ofs = 0x0000, + .clr_ofs = 0x0004, + .sta_ofs = 0x2c00, +}; + +#define GATE_HWV_IMPN(_id, _name, _parent, _shift) { \ + .id = _id, \ + .name = _name, \ + .parent_name = _parent, \ + .regs = &imp_cg_regs, \ + .hwv_regs = &impn_hwv_regs, \ + .shift = _shift, \ + .ops = &mtk_clk_gate_hwv_ops_setclr, \ + .flags = CLK_OPS_PARENT_ENABLE, \ + } + +static const struct mtk_gate impn_clks[] = { + GATE_IMP(CLK_IMPN_I2C1, "impn_i2c1", "i2c_north", 0), + GATE_IMP(CLK_IMPN_I2C2, "impn_i2c2", "i2c_north", 1), + GATE_IMP(CLK_IMPN_I2C4, "impn_i2c4", "i2c_north", 2), + GATE_HWV_IMPN(CLK_IMPN_I2C7, "impn_i2c7", "i2c_north", 3), + GATE_IMP(CLK_IMPN_I2C8, "impn_i2c8", "i2c_north", 4), + GATE_IMP(CLK_IMPN_I2C9, "impn_i2c9", "i2c_north", 5), +}; + +static const struct mtk_clk_desc impn_mcd = { + .clks = impn_clks, + .num_clks = ARRAY_SIZE(impn_clks), +}; + +static const struct mtk_gate impw_clks[] = { + GATE_IMP(CLK_IMPW_I2C0, "impw_i2c0", "i2c_west", 0), + GATE_IMP(CLK_IMPW_I2C3, "impw_i2c3", "i2c_west", 1), + GATE_IMP(CLK_IMPW_I2C6, "impw_i2c6", "i2c_west", 2), + GATE_IMP(CLK_IMPW_I2C10, "impw_i2c10", "i2c_west", 3), +}; + +static const struct mtk_clk_desc impw_mcd = { + .clks = impw_clks, + .num_clks = ARRAY_SIZE(impw_clks), +}; + +static const struct of_device_id of_match_clk_mt8196_imp_iic_wrap[] = { + { .compatible = "mediatek,mt8196-imp-iic-wrap-c", .data = &impc_mcd }, + { .compatible = "mediatek,mt8196-imp-iic-wrap-e", .data = &impe_mcd }, + { .compatible = "mediatek,mt8196-imp-iic-wrap-n", .data = &impn_mcd }, + { .compatible = "mediatek,mt8196-imp-iic-wrap-w", .data = &impw_mcd }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(of, of_match_clk_mt8196_imp_iic_wrap); + +static struct platform_driver clk_mt8196_imp_iic_wrap_drv = { + .probe = mtk_clk_simple_probe, + .remove = mtk_clk_simple_remove, + .driver = { + .name = "clk-mt8196-imp_iic_wrap", + .of_match_table = of_match_clk_mt8196_imp_iic_wrap, + }, +}; +module_platform_driver(clk_mt8196_imp_iic_wrap_drv); + +MODULE_DESCRIPTION("MediaTek MT8196 I2C Wrapper clocks driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/clk/mediatek/clk-mt8196-mcu.c b/drivers/clk/mediatek/clk-mt8196-mcu.c new file mode 100644 index 000000000000..5cbcc411ae73 --- /dev/null +++ b/drivers/clk/mediatek/clk-mt8196-mcu.c @@ -0,0 +1,167 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2025 MediaTek Inc. + * Guangjie Song <guangjie.song@mediatek.com> + * Copyright (c) 2025 Collabora Ltd. + * Laura Nao <laura.nao@collabora.com> + */ +#include <dt-bindings/clock/mediatek,mt8196-clock.h> + +#include <linux/clk.h> +#include <linux/module.h> +#include <linux/of.h> +#include <linux/of_address.h> +#include <linux/of_device.h> +#include <linux/platform_device.h> + +#include "clk-mtk.h" +#include "clk-pll.h" + +#define ARMPLL_LL_CON0 0x008 +#define ARMPLL_LL_CON1 0x00c +#define ARMPLL_LL_CON2 0x010 +#define ARMPLL_LL_CON3 0x014 +#define ARMPLL_BL_CON0 0x008 +#define ARMPLL_BL_CON1 0x00c +#define ARMPLL_BL_CON2 0x010 +#define ARMPLL_BL_CON3 0x014 +#define ARMPLL_B_CON0 0x008 +#define ARMPLL_B_CON1 0x00c +#define ARMPLL_B_CON2 0x010 +#define ARMPLL_B_CON3 0x014 +#define CCIPLL_CON0 0x008 +#define CCIPLL_CON1 0x00c +#define CCIPLL_CON2 0x010 +#define CCIPLL_CON3 0x014 +#define PTPPLL_CON0 0x008 +#define PTPPLL_CON1 0x00c +#define PTPPLL_CON2 0x010 +#define PTPPLL_CON3 0x014 + +#define MT8196_PLL_FMAX (3800UL * MHZ) +#define MT8196_PLL_FMIN (1500UL * MHZ) +#define MT8196_INTEGER_BITS 8 + +#define PLL(_id, _name, _reg, _en_reg, _en_mask, _pll_en_bit, \ + _flags, _rst_bar_mask, \ + _pd_reg, _pd_shift, _tuner_reg, \ + _tuner_en_reg, _tuner_en_bit, \ + _pcw_reg, _pcw_shift, _pcwbits) { \ + .id = _id, \ + .name = _name, \ + .reg = _reg, \ + .en_reg = _en_reg, \ + .en_mask = _en_mask, \ + .pll_en_bit = _pll_en_bit, \ + .flags = _flags, \ + .rst_bar_mask = _rst_bar_mask, \ + .fmax = MT8196_PLL_FMAX, \ + .fmin = MT8196_PLL_FMIN, \ + .pd_reg = _pd_reg, \ + .pd_shift = _pd_shift, \ + .tuner_reg = _tuner_reg, \ + .tuner_en_reg = _tuner_en_reg, \ + .tuner_en_bit = _tuner_en_bit, \ + .pcw_reg = _pcw_reg, \ + .pcw_shift = _pcw_shift, \ + .pcwbits = _pcwbits, \ + .pcwibits = MT8196_INTEGER_BITS, \ + } + +static const struct mtk_pll_data cpu_bl_plls[] = { + PLL(CLK_CPBL_ARMPLL_BL, "armpll-bl", ARMPLL_BL_CON0, ARMPLL_BL_CON0, 0, + 0, PLL_AO, BIT(0), ARMPLL_BL_CON1, 24, 0, 0, 0, ARMPLL_BL_CON1, 0, 22), +}; + +static const struct mtk_pll_data cpu_b_plls[] = { + PLL(CLK_CPB_ARMPLL_B, "armpll-b", ARMPLL_B_CON0, ARMPLL_B_CON0, 0, 0, + PLL_AO, BIT(0), ARMPLL_B_CON1, 24, 0, 0, 0, ARMPLL_B_CON1, 0, 22), +}; + +static const struct mtk_pll_data cpu_ll_plls[] = { + PLL(CLK_CPLL_ARMPLL_LL, "armpll-ll", ARMPLL_LL_CON0, ARMPLL_LL_CON0, 0, + 0, PLL_AO, BIT(0), ARMPLL_LL_CON1, 24, 0, 0, 0, ARMPLL_LL_CON1, 0, 22), +}; + +static const struct mtk_pll_data cci_plls[] = { + PLL(CLK_CCIPLL, "ccipll", CCIPLL_CON0, CCIPLL_CON0, 0, 0, PLL_AO, + BIT(0), CCIPLL_CON1, 24, 0, 0, 0, CCIPLL_CON1, 0, 22), +}; + +static const struct mtk_pll_data ptp_plls[] = { + PLL(CLK_PTPPLL, "ptppll", PTPPLL_CON0, PTPPLL_CON0, 0, 0, PLL_AO, + BIT(0), PTPPLL_CON1, 24, 0, 0, 0, PTPPLL_CON1, 0, 22), +}; + +static const struct of_device_id of_match_clk_mt8196_mcu[] = { + { .compatible = "mediatek,mt8196-armpll-bl-pll-ctrl", + .data = &cpu_bl_plls }, + { .compatible = "mediatek,mt8196-armpll-b-pll-ctrl", + .data = &cpu_b_plls }, + { .compatible = "mediatek,mt8196-armpll-ll-pll-ctrl", + .data = &cpu_ll_plls }, + { .compatible = "mediatek,mt8196-ccipll-pll-ctrl", .data = &cci_plls }, + { .compatible = "mediatek,mt8196-ptppll-pll-ctrl", .data = &ptp_plls }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(of, of_match_clk_mt8196_mcu); + +static int clk_mt8196_mcu_probe(struct platform_device *pdev) +{ + const struct mtk_pll_data *plls; + struct clk_hw_onecell_data *clk_data; + struct device_node *node = pdev->dev.of_node; + const int num_plls = 1; + int r; + + plls = of_device_get_match_data(&pdev->dev); + if (!plls) + return -EINVAL; + + clk_data = mtk_alloc_clk_data(num_plls); + if (!clk_data) + return -ENOMEM; + + r = mtk_clk_register_plls(node, plls, num_plls, clk_data); + if (r) + goto free_clk_data; + + r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data); + if (r) + goto unregister_plls; + + platform_set_drvdata(pdev, clk_data); + + return r; + +unregister_plls: + mtk_clk_unregister_plls(plls, num_plls, clk_data); +free_clk_data: + mtk_free_clk_data(clk_data); + + return r; +} + +static void clk_mt8196_mcu_remove(struct platform_device *pdev) +{ + const struct mtk_pll_data *plls = of_device_get_match_data(&pdev->dev); + struct clk_hw_onecell_data *clk_data = platform_get_drvdata(pdev); + struct device_node *node = pdev->dev.of_node; + + of_clk_del_provider(node); + mtk_clk_unregister_plls(plls, 1, clk_data); + mtk_free_clk_data(clk_data); +} + +static struct platform_driver clk_mt8196_mcu_drv = { + .probe = clk_mt8196_mcu_probe, + .remove = clk_mt8196_mcu_remove, + .driver = { + .name = "clk-mt8196-mcu", + .of_match_table = of_match_clk_mt8196_mcu, + }, +}; +module_platform_driver(clk_mt8196_mcu_drv); + +MODULE_DESCRIPTION("MediaTek MT8196 mcusys clocks driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/clk/mediatek/clk-mt8196-mdpsys.c b/drivers/clk/mediatek/clk-mt8196-mdpsys.c new file mode 100644 index 000000000000..7667d88f0eb0 --- /dev/null +++ b/drivers/clk/mediatek/clk-mt8196-mdpsys.c @@ -0,0 +1,186 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2025 MediaTek Inc. + * Guangjie Song <guangjie.song@mediatek.com> + * Copyright (c) 2025 Collabora Ltd. + * Laura Nao <laura.nao@collabora.com> + */ +#include <dt-bindings/clock/mediatek,mt8196-clock.h> + +#include <linux/clk-provider.h> +#include <linux/module.h> +#include <linux/of_device.h> +#include <linux/platform_device.h> + +#include "clk-gate.h" +#include "clk-mtk.h" + +static const struct mtk_gate_regs mdp0_cg_regs = { + .set_ofs = 0x104, + .clr_ofs = 0x108, + .sta_ofs = 0x100, +}; + +static const struct mtk_gate_regs mdp1_cg_regs = { + .set_ofs = 0x114, + .clr_ofs = 0x118, + .sta_ofs = 0x110, +}; + +static const struct mtk_gate_regs mdp2_cg_regs = { + .set_ofs = 0x124, + .clr_ofs = 0x128, + .sta_ofs = 0x120, +}; + +#define GATE_MDP0(_id, _name, _parent, _shift) { \ + .id = _id, \ + .name = _name, \ + .parent_name = _parent, \ + .regs = &mdp0_cg_regs, \ + .shift = _shift, \ + .flags = CLK_OPS_PARENT_ENABLE, \ + .ops = &mtk_clk_gate_ops_setclr, \ + } + +#define GATE_MDP1(_id, _name, _parent, _shift) { \ + .id = _id, \ + .name = _name, \ + .parent_name = _parent, \ + .regs = &mdp1_cg_regs, \ + .shift = _shift, \ + .ops = &mtk_clk_gate_ops_setclr, \ + } + +#define GATE_MDP2(_id, _name, _parent, _shift) { \ + .id = _id, \ + .name = _name, \ + .parent_name = _parent, \ + .regs = &mdp2_cg_regs, \ + .shift = _shift, \ + .flags = CLK_OPS_PARENT_ENABLE, \ + .ops = &mtk_clk_gate_ops_setclr, \ + } + +static const struct mtk_gate mdp1_clks[] = { + /* MDP1-0 */ + GATE_MDP0(CLK_MDP1_MDP_MUTEX0, "mdp1_mdp_mutex0", "mdp", 0), + GATE_MDP0(CLK_MDP1_SMI0, "mdp1_smi0", "mdp", 1), + GATE_MDP0(CLK_MDP1_APB_BUS, "mdp1_apb_bus", "mdp", 2), + GATE_MDP0(CLK_MDP1_MDP_RDMA0, "mdp1_mdp_rdma0", "mdp", 3), + GATE_MDP0(CLK_MDP1_MDP_RDMA1, "mdp1_mdp_rdma1", "mdp", 4), + GATE_MDP0(CLK_MDP1_MDP_RDMA2, "mdp1_mdp_rdma2", "mdp", 5), + GATE_MDP0(CLK_MDP1_MDP_BIRSZ0, "mdp1_mdp_birsz0", "mdp", 6), + GATE_MDP0(CLK_MDP1_MDP_HDR0, "mdp1_mdp_hdr0", "mdp", 7), + GATE_MDP0(CLK_MDP1_MDP_AAL0, "mdp1_mdp_aal0", "mdp", 8), + GATE_MDP0(CLK_MDP1_MDP_RSZ0, "mdp1_mdp_rsz0", "mdp", 9), + GATE_MDP0(CLK_MDP1_MDP_RSZ2, "mdp1_mdp_rsz2", "mdp", 10), + GATE_MDP0(CLK_MDP1_MDP_TDSHP0, "mdp1_mdp_tdshp0", "mdp", 11), + GATE_MDP0(CLK_MDP1_MDP_COLOR0, "mdp1_mdp_color0", "mdp", 12), + GATE_MDP0(CLK_MDP1_MDP_WROT0, "mdp1_mdp_wrot0", "mdp", 13), + GATE_MDP0(CLK_MDP1_MDP_WROT1, "mdp1_mdp_wrot1", "mdp", 14), + GATE_MDP0(CLK_MDP1_MDP_WROT2, "mdp1_mdp_wrot2", "mdp", 15), + GATE_MDP0(CLK_MDP1_MDP_FAKE_ENG0, "mdp1_mdp_fake_eng0", "mdp", 16), + GATE_MDP0(CLK_MDP1_APB_DB, "mdp1_apb_db", "mdp", 17), + GATE_MDP0(CLK_MDP1_MDP_DLI_ASYNC0, "mdp1_mdp_dli_async0", "mdp", 18), + GATE_MDP0(CLK_MDP1_MDP_DLI_ASYNC1, "mdp1_mdp_dli_async1", "mdp", 19), + GATE_MDP0(CLK_MDP1_MDP_DLO_ASYNC0, "mdp1_mdp_dlo_async0", "mdp", 20), + GATE_MDP0(CLK_MDP1_MDP_DLO_ASYNC1, "mdp1_mdp_dlo_async1", "mdp", 21), + GATE_MDP0(CLK_MDP1_MDP_DLI_ASYNC2, "mdp1_mdp_dli_async2", "mdp", 22), + GATE_MDP0(CLK_MDP1_MDP_DLO_ASYNC2, "mdp1_mdp_dlo_async2", "mdp", 23), + GATE_MDP0(CLK_MDP1_MDP_DLO_ASYNC3, "mdp1_mdp_dlo_async3", "mdp", 24), + GATE_MDP0(CLK_MDP1_IMG_DL_ASYNC0, "mdp1_img_dl_async0", "mdp", 25), + GATE_MDP0(CLK_MDP1_MDP_RROT0, "mdp1_mdp_rrot0", "mdp", 26), + GATE_MDP0(CLK_MDP1_MDP_MERGE0, "mdp1_mdp_merge0", "mdp", 27), + GATE_MDP0(CLK_MDP1_MDP_C3D0, "mdp1_mdp_c3d0", "mdp", 28), + GATE_MDP0(CLK_MDP1_MDP_FG0, "mdp1_mdp_fg0", "mdp", 29), + GATE_MDP0(CLK_MDP1_MDP_CLA2, "mdp1_mdp_cla2", "mdp", 30), + GATE_MDP0(CLK_MDP1_MDP_DLO_ASYNC4, "mdp1_mdp_dlo_async4", "mdp", 31), + /* MDP1-1 */ + GATE_MDP1(CLK_MDP1_VPP_RSZ0, "mdp1_vpp_rsz0", "mdp", 0), + GATE_MDP1(CLK_MDP1_VPP_RSZ1, "mdp1_vpp_rsz1", "mdp", 1), + GATE_MDP1(CLK_MDP1_MDP_DLO_ASYNC5, "mdp1_mdp_dlo_async5", "mdp", 2), + GATE_MDP1(CLK_MDP1_IMG0, "mdp1_img0", "mdp", 3), + GATE_MDP1(CLK_MDP1_F26M, "mdp1_f26m", "clk26m", 27), + /* MDP1-2 */ + GATE_MDP2(CLK_MDP1_IMG_DL_RELAY0, "mdp1_img_dl_relay0", "mdp", 0), + GATE_MDP2(CLK_MDP1_IMG_DL_RELAY1, "mdp1_img_dl_relay1", "mdp", 8), +}; + +static const struct mtk_clk_desc mdp1_mcd = { + .clks = mdp1_clks, + .num_clks = ARRAY_SIZE(mdp1_clks), + .need_runtime_pm = true, +}; + + +static const struct mtk_gate mdp_clks[] = { + /* MDP0 */ + GATE_MDP0(CLK_MDP_MDP_MUTEX0, "mdp_mdp_mutex0", "mdp", 0), + GATE_MDP0(CLK_MDP_SMI0, "mdp_smi0", "mdp", 1), + GATE_MDP0(CLK_MDP_APB_BUS, "mdp_apb_bus", "mdp", 2), + GATE_MDP0(CLK_MDP_MDP_RDMA0, "mdp_mdp_rdma0", "mdp", 3), + GATE_MDP0(CLK_MDP_MDP_RDMA1, "mdp_mdp_rdma1", "mdp", 4), + GATE_MDP0(CLK_MDP_MDP_RDMA2, "mdp_mdp_rdma2", "mdp", 5), + GATE_MDP0(CLK_MDP_MDP_BIRSZ0, "mdp_mdp_birsz0", "mdp", 6), + GATE_MDP0(CLK_MDP_MDP_HDR0, "mdp_mdp_hdr0", "mdp", 7), + GATE_MDP0(CLK_MDP_MDP_AAL0, "mdp_mdp_aal0", "mdp", 8), + GATE_MDP0(CLK_MDP_MDP_RSZ0, "mdp_mdp_rsz0", "mdp", 9), + GATE_MDP0(CLK_MDP_MDP_RSZ2, "mdp_mdp_rsz2", "mdp", 10), + GATE_MDP0(CLK_MDP_MDP_TDSHP0, "mdp_mdp_tdshp0", "mdp", 11), + GATE_MDP0(CLK_MDP_MDP_COLOR0, "mdp_mdp_color0", "mdp", 12), + GATE_MDP0(CLK_MDP_MDP_WROT0, "mdp_mdp_wrot0", "mdp", 13), + GATE_MDP0(CLK_MDP_MDP_WROT1, "mdp_mdp_wrot1", "mdp", 14), + GATE_MDP0(CLK_MDP_MDP_WROT2, "mdp_mdp_wrot2", "mdp", 15), + GATE_MDP0(CLK_MDP_MDP_FAKE_ENG0, "mdp_mdp_fake_eng0", "mdp", 16), + GATE_MDP0(CLK_MDP_APB_DB, "mdp_apb_db", "mdp", 17), + GATE_MDP0(CLK_MDP_MDP_DLI_ASYNC0, "mdp_mdp_dli_async0", "mdp", 18), + GATE_MDP0(CLK_MDP_MDP_DLI_ASYNC1, "mdp_mdp_dli_async1", "mdp", 19), + GATE_MDP0(CLK_MDP_MDP_DLO_ASYNC0, "mdp_mdp_dlo_async0", "mdp", 20), + GATE_MDP0(CLK_MDP_MDP_DLO_ASYNC1, "mdp_mdp_dlo_async1", "mdp", 21), + GATE_MDP0(CLK_MDP_MDP_DLI_ASYNC2, "mdp_mdp_dli_async2", "mdp", 22), + GATE_MDP0(CLK_MDP_MDP_DLO_ASYNC2, "mdp_mdp_dlo_async2", "mdp", 23), + GATE_MDP0(CLK_MDP_MDP_DLO_ASYNC3, "mdp_mdp_dlo_async3", "mdp", 24), + GATE_MDP0(CLK_MDP_IMG_DL_ASYNC0, "mdp_img_dl_async0", "mdp", 25), + GATE_MDP0(CLK_MDP_MDP_RROT0, "mdp_mdp_rrot0", "mdp", 26), + GATE_MDP0(CLK_MDP_MDP_MERGE0, "mdp_mdp_merge0", "mdp", 27), + GATE_MDP0(CLK_MDP_MDP_C3D0, "mdp_mdp_c3d0", "mdp", 28), + GATE_MDP0(CLK_MDP_MDP_FG0, "mdp_mdp_fg0", "mdp", 29), + GATE_MDP0(CLK_MDP_MDP_CLA2, "mdp_mdp_cla2", "mdp", 30), + GATE_MDP0(CLK_MDP_MDP_DLO_ASYNC4, "mdp_mdp_dlo_async4", "mdp", 31), + /* MDP1 */ + GATE_MDP1(CLK_MDP_VPP_RSZ0, "mdp_vpp_rsz0", "mdp", 0), + GATE_MDP1(CLK_MDP_VPP_RSZ1, "mdp_vpp_rsz1", "mdp", 1), + GATE_MDP1(CLK_MDP_MDP_DLO_ASYNC5, "mdp_mdp_dlo_async5", "mdp", 2), + GATE_MDP1(CLK_MDP_IMG0, "mdp_img0", "mdp", 3), + GATE_MDP1(CLK_MDP_F26M, "mdp_f26m", "clk26m", 27), + /* MDP2 */ + GATE_MDP2(CLK_MDP_IMG_DL_RELAY0, "mdp_img_dl_relay0", "mdp", 0), + GATE_MDP2(CLK_MDP_IMG_DL_RELAY1, "mdp_img_dl_relay1", "mdp", 8), +}; + +static const struct mtk_clk_desc mdp_mcd = { + .clks = mdp_clks, + .num_clks = ARRAY_SIZE(mdp_clks), + .need_runtime_pm = true, +}; + +static const struct of_device_id of_match_clk_mt8196_mdpsys[] = { + { .compatible = "mediatek,mt8196-mdpsys0", .data = &mdp_mcd }, + { .compatible = "mediatek,mt8196-mdpsys1", .data = &mdp1_mcd }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(of, of_match_clk_mt8196_mdpsys); + +static struct platform_driver clk_mt8196_mdpsys_drv = { + .probe = mtk_clk_simple_probe, + .remove = mtk_clk_simple_remove, + .driver = { + .name = "clk-mt8196-mdpsys", + .of_match_table = of_match_clk_mt8196_mdpsys, + }, +}; +module_platform_driver(clk_mt8196_mdpsys_drv); + +MODULE_DESCRIPTION("MediaTek MT8196 Multimedia Data Path clocks driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/clk/mediatek/clk-mt8196-mfg.c b/drivers/clk/mediatek/clk-mt8196-mfg.c new file mode 100644 index 000000000000..ae1eb9de79ae --- /dev/null +++ b/drivers/clk/mediatek/clk-mt8196-mfg.c @@ -0,0 +1,150 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2025 MediaTek Inc. + * Guangjie Song <guangjie.song@mediatek.com> + * Copyright (c) 2025 Collabora Ltd. + * Laura Nao <laura.nao@collabora.com> + */ +#include <dt-bindings/clock/mediatek,mt8196-clock.h> + +#include <linux/clk.h> +#include <linux/module.h> +#include <linux/of.h> +#include <linux/of_address.h> +#include <linux/of_device.h> +#include <linux/platform_device.h> + +#include "clk-mtk.h" +#include "clk-pll.h" + +#define MFGPLL_CON0 0x008 +#define MFGPLL_CON1 0x00c +#define MFGPLL_CON2 0x010 +#define MFGPLL_CON3 0x014 +#define MFGPLL_SC0_CON0 0x008 +#define MFGPLL_SC0_CON1 0x00c +#define MFGPLL_SC0_CON2 0x010 +#define MFGPLL_SC0_CON3 0x014 +#define MFGPLL_SC1_CON0 0x008 +#define MFGPLL_SC1_CON1 0x00c +#define MFGPLL_SC1_CON2 0x010 +#define MFGPLL_SC1_CON3 0x014 + +#define MT8196_PLL_FMAX (3800UL * MHZ) +#define MT8196_PLL_FMIN (1500UL * MHZ) +#define MT8196_INTEGER_BITS 8 + +#define PLL(_id, _name, _reg, _en_reg, _en_mask, _pll_en_bit, \ + _flags, _rst_bar_mask, \ + _pd_reg, _pd_shift, _tuner_reg, \ + _tuner_en_reg, _tuner_en_bit, \ + _pcw_reg, _pcw_shift, _pcwbits) { \ + .id = _id, \ + .name = _name, \ + .reg = _reg, \ + .en_reg = _en_reg, \ + .en_mask = _en_mask, \ + .pll_en_bit = _pll_en_bit, \ + .flags = _flags, \ + .rst_bar_mask = _rst_bar_mask, \ + .fmax = MT8196_PLL_FMAX, \ + .fmin = MT8196_PLL_FMIN, \ + .pd_reg = _pd_reg, \ + .pd_shift = _pd_shift, \ + .tuner_reg = _tuner_reg, \ + .tuner_en_reg = _tuner_en_reg, \ + .tuner_en_bit = _tuner_en_bit, \ + .pcw_reg = _pcw_reg, \ + .pcw_shift = _pcw_shift, \ + .pcwbits = _pcwbits, \ + .pcwibits = MT8196_INTEGER_BITS, \ + } + +static const struct mtk_pll_data mfg_ao_plls[] = { + PLL(CLK_MFG_AO_MFGPLL, "mfgpll", MFGPLL_CON0, MFGPLL_CON0, 0, 0, 0, + BIT(0), MFGPLL_CON1, 24, 0, 0, 0, + MFGPLL_CON1, 0, 22), +}; + +static const struct mtk_pll_data mfgsc0_ao_plls[] = { + PLL(CLK_MFGSC0_AO_MFGPLL_SC0, "mfgpll-sc0", MFGPLL_SC0_CON0, + MFGPLL_SC0_CON0, 0, 0, 0, BIT(0), MFGPLL_SC0_CON1, 24, 0, 0, 0, + MFGPLL_SC0_CON1, 0, 22), +}; + +static const struct mtk_pll_data mfgsc1_ao_plls[] = { + PLL(CLK_MFGSC1_AO_MFGPLL_SC1, "mfgpll-sc1", MFGPLL_SC1_CON0, + MFGPLL_SC1_CON0, 0, 0, 0, BIT(0), MFGPLL_SC1_CON1, 24, 0, 0, 0, + MFGPLL_SC1_CON1, 0, 22), +}; + +static const struct of_device_id of_match_clk_mt8196_mfg[] = { + { .compatible = "mediatek,mt8196-mfgpll-pll-ctrl", + .data = &mfg_ao_plls }, + { .compatible = "mediatek,mt8196-mfgpll-sc0-pll-ctrl", + .data = &mfgsc0_ao_plls }, + { .compatible = "mediatek,mt8196-mfgpll-sc1-pll-ctrl", + .data = &mfgsc1_ao_plls }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(of, of_match_clk_mt8196_mfg); + +static int clk_mt8196_mfg_probe(struct platform_device *pdev) +{ + const struct mtk_pll_data *plls; + struct clk_hw_onecell_data *clk_data; + struct device_node *node = pdev->dev.of_node; + const int num_plls = 1; + int r; + + plls = of_device_get_match_data(&pdev->dev); + if (!plls) + return -EINVAL; + + clk_data = mtk_alloc_clk_data(num_plls); + if (!clk_data) + return -ENOMEM; + + r = mtk_clk_register_plls(node, plls, num_plls, clk_data); + if (r) + goto free_clk_data; + + r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data); + if (r) + goto unregister_plls; + + platform_set_drvdata(pdev, clk_data); + + return r; + +unregister_plls: + mtk_clk_unregister_plls(plls, num_plls, clk_data); +free_clk_data: + mtk_free_clk_data(clk_data); + + return r; +} + +static void clk_mt8196_mfg_remove(struct platform_device *pdev) +{ + const struct mtk_pll_data *plls = of_device_get_match_data(&pdev->dev); + struct clk_hw_onecell_data *clk_data = platform_get_drvdata(pdev); + struct device_node *node = pdev->dev.of_node; + + of_clk_del_provider(node); + mtk_clk_unregister_plls(plls, 1, clk_data); + mtk_free_clk_data(clk_data); +} + +static struct platform_driver clk_mt8196_mfg_drv = { + .probe = clk_mt8196_mfg_probe, + .remove = clk_mt8196_mfg_remove, + .driver = { + .name = "clk-mt8196-mfg", + .of_match_table = of_match_clk_mt8196_mfg, + }, +}; +module_platform_driver(clk_mt8196_mfg_drv); + +MODULE_DESCRIPTION("MediaTek MT8196 GPU mfg clocks driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/clk/mediatek/clk-mt8196-ovl0.c b/drivers/clk/mediatek/clk-mt8196-ovl0.c new file mode 100644 index 000000000000..d4affd14d2c4 --- /dev/null +++ b/drivers/clk/mediatek/clk-mt8196-ovl0.c @@ -0,0 +1,154 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2025 MediaTek Inc. + * Guangjie Song <guangjie.song@mediatek.com> + * Copyright (c) 2025 Collabora Ltd. + * Laura Nao <laura.nao@collabora.com> + */ +#include <dt-bindings/clock/mediatek,mt8196-clock.h> + +#include <linux/clk-provider.h> +#include <linux/module.h> +#include <linux/of_device.h> +#include <linux/platform_device.h> + +#include "clk-gate.h" +#include "clk-mtk.h" + +static const struct mtk_gate_regs ovl0_cg_regs = { + .set_ofs = 0x104, + .clr_ofs = 0x108, + .sta_ofs = 0x100, +}; + +static const struct mtk_gate_regs ovl0_hwv_regs = { + .set_ofs = 0x0060, + .clr_ofs = 0x0064, + .sta_ofs = 0x2c30, +}; + +static const struct mtk_gate_regs ovl1_cg_regs = { + .set_ofs = 0x114, + .clr_ofs = 0x118, + .sta_ofs = 0x110, +}; + +static const struct mtk_gate_regs ovl1_hwv_regs = { + .set_ofs = 0x0068, + .clr_ofs = 0x006c, + .sta_ofs = 0x2c34, +}; + +#define GATE_HWV_OVL0(_id, _name, _parent, _shift) { \ + .id = _id, \ + .name = _name, \ + .parent_name = _parent, \ + .regs = &ovl0_cg_regs, \ + .hwv_regs = &ovl0_hwv_regs, \ + .shift = _shift, \ + .ops = &mtk_clk_gate_hwv_ops_setclr, \ + .flags = CLK_OPS_PARENT_ENABLE, \ + } + +#define GATE_HWV_OVL1(_id, _name, _parent, _shift) { \ + .id = _id, \ + .name = _name, \ + .parent_name = _parent, \ + .regs = &ovl1_cg_regs, \ + .hwv_regs = &ovl1_hwv_regs, \ + .shift = _shift, \ + .ops = &mtk_clk_gate_hwv_ops_setclr, \ + .flags = CLK_OPS_PARENT_ENABLE, \ + } + +static const struct mtk_gate ovl_clks[] = { + /* OVL0 */ + GATE_HWV_OVL0(CLK_OVLSYS_CONFIG, "ovlsys_config", "disp", 0), + GATE_HWV_OVL0(CLK_OVL_FAKE_ENG0, "ovl_fake_eng0", "disp", 1), + GATE_HWV_OVL0(CLK_OVL_FAKE_ENG1, "ovl_fake_eng1", "disp", 2), + GATE_HWV_OVL0(CLK_OVL_MUTEX0, "ovl_mutex0", "disp", 3), + GATE_HWV_OVL0(CLK_OVL_EXDMA0, "ovl_exdma0", "disp", 4), + GATE_HWV_OVL0(CLK_OVL_EXDMA1, "ovl_exdma1", "disp", 5), + GATE_HWV_OVL0(CLK_OVL_EXDMA2, "ovl_exdma2", "disp", 6), + GATE_HWV_OVL0(CLK_OVL_EXDMA3, "ovl_exdma3", "disp", 7), + GATE_HWV_OVL0(CLK_OVL_EXDMA4, "ovl_exdma4", "disp", 8), + GATE_HWV_OVL0(CLK_OVL_EXDMA5, "ovl_exdma5", "disp", 9), + GATE_HWV_OVL0(CLK_OVL_EXDMA6, "ovl_exdma6", "disp", 10), + GATE_HWV_OVL0(CLK_OVL_EXDMA7, "ovl_exdma7", "disp", 11), + GATE_HWV_OVL0(CLK_OVL_EXDMA8, "ovl_exdma8", "disp", 12), + GATE_HWV_OVL0(CLK_OVL_EXDMA9, "ovl_exdma9", "disp", 13), + GATE_HWV_OVL0(CLK_OVL_BLENDER0, "ovl_blender0", "disp", 14), + GATE_HWV_OVL0(CLK_OVL_BLENDER1, "ovl_blender1", "disp", 15), + GATE_HWV_OVL0(CLK_OVL_BLENDER2, "ovl_blender2", "disp", 16), + GATE_HWV_OVL0(CLK_OVL_BLENDER3, "ovl_blender3", "disp", 17), + GATE_HWV_OVL0(CLK_OVL_BLENDER4, "ovl_blender4", "disp", 18), + GATE_HWV_OVL0(CLK_OVL_BLENDER5, "ovl_blender5", "disp", 19), + GATE_HWV_OVL0(CLK_OVL_BLENDER6, "ovl_blender6", "disp", 20), + GATE_HWV_OVL0(CLK_OVL_BLENDER7, "ovl_blender7", "disp", 21), + GATE_HWV_OVL0(CLK_OVL_BLENDER8, "ovl_blender8", "disp", 22), + GATE_HWV_OVL0(CLK_OVL_BLENDER9, "ovl_blender9", "disp", 23), + GATE_HWV_OVL0(CLK_OVL_OUTPROC0, "ovl_outproc0", "disp", 24), + GATE_HWV_OVL0(CLK_OVL_OUTPROC1, "ovl_outproc1", "disp", 25), + GATE_HWV_OVL0(CLK_OVL_OUTPROC2, "ovl_outproc2", "disp", 26), + GATE_HWV_OVL0(CLK_OVL_OUTPROC3, "ovl_outproc3", "disp", 27), + GATE_HWV_OVL0(CLK_OVL_OUTPROC4, "ovl_outproc4", "disp", 28), + GATE_HWV_OVL0(CLK_OVL_OUTPROC5, "ovl_outproc5", "disp", 29), + GATE_HWV_OVL0(CLK_OVL_MDP_RSZ0, "ovl_mdp_rsz0", "disp", 30), + GATE_HWV_OVL0(CLK_OVL_MDP_RSZ1, "ovl_mdp_rsz1", "disp", 31), + /* OVL1 */ + GATE_HWV_OVL1(CLK_OVL_DISP_WDMA0, "ovl_disp_wdma0", "disp", 0), + GATE_HWV_OVL1(CLK_OVL_DISP_WDMA1, "ovl_disp_wdma1", "disp", 1), + GATE_HWV_OVL1(CLK_OVL_UFBC_WDMA0, "ovl_ufbc_wdma0", "disp", 2), + GATE_HWV_OVL1(CLK_OVL_MDP_RDMA0, "ovl_mdp_rdma0", "disp", 3), + GATE_HWV_OVL1(CLK_OVL_MDP_RDMA1, "ovl_mdp_rdma1", "disp", 4), + GATE_HWV_OVL1(CLK_OVL_BWM0, "ovl_bwm0", "disp", 5), + GATE_HWV_OVL1(CLK_OVL_DLI0, "ovl_dli0", "disp", 6), + GATE_HWV_OVL1(CLK_OVL_DLI1, "ovl_dli1", "disp", 7), + GATE_HWV_OVL1(CLK_OVL_DLI2, "ovl_dli2", "disp", 8), + GATE_HWV_OVL1(CLK_OVL_DLI3, "ovl_dli3", "disp", 9), + GATE_HWV_OVL1(CLK_OVL_DLI4, "ovl_dli4", "disp", 10), + GATE_HWV_OVL1(CLK_OVL_DLI5, "ovl_dli5", "disp", 11), + GATE_HWV_OVL1(CLK_OVL_DLI6, "ovl_dli6", "disp", 12), + GATE_HWV_OVL1(CLK_OVL_DLI7, "ovl_dli7", "disp", 13), + GATE_HWV_OVL1(CLK_OVL_DLI8, "ovl_dli8", "disp", 14), + GATE_HWV_OVL1(CLK_OVL_DLO0, "ovl_dlo0", "disp", 15), + GATE_HWV_OVL1(CLK_OVL_DLO1, "ovl_dlo1", "disp", 16), + GATE_HWV_OVL1(CLK_OVL_DLO2, "ovl_dlo2", "disp", 17), + GATE_HWV_OVL1(CLK_OVL_DLO3, "ovl_dlo3", "disp", 18), + GATE_HWV_OVL1(CLK_OVL_DLO4, "ovl_dlo4", "disp", 19), + GATE_HWV_OVL1(CLK_OVL_DLO5, "ovl_dlo5", "disp", 20), + GATE_HWV_OVL1(CLK_OVL_DLO6, "ovl_dlo6", "disp", 21), + GATE_HWV_OVL1(CLK_OVL_DLO7, "ovl_dlo7", "disp", 22), + GATE_HWV_OVL1(CLK_OVL_DLO8, "ovl_dlo8", "disp", 23), + GATE_HWV_OVL1(CLK_OVL_DLO9, "ovl_dlo9", "disp", 24), + GATE_HWV_OVL1(CLK_OVL_DLO10, "ovl_dlo10", "disp", 25), + GATE_HWV_OVL1(CLK_OVL_DLO11, "ovl_dlo11", "disp", 26), + GATE_HWV_OVL1(CLK_OVL_DLO12, "ovl_dlo12", "disp", 27), + GATE_HWV_OVL1(CLK_OVLSYS_RELAY0, "ovlsys_relay0", "disp", 28), + GATE_HWV_OVL1(CLK_OVL_INLINEROT0, "ovl_inlinerot0", "disp", 29), + GATE_HWV_OVL1(CLK_OVL_SMI, "ovl_smi", "disp", 30), +}; + +static const struct mtk_clk_desc ovl_mcd = { + .clks = ovl_clks, + .num_clks = ARRAY_SIZE(ovl_clks), +}; + +static const struct platform_device_id clk_mt8196_ovl0_id_table[] = { + { .name = "clk-mt8196-ovl0", .driver_data = (kernel_ulong_t)&ovl_mcd }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(platform, clk_mt8196_ovl0_id_table); + +static struct platform_driver clk_mt8196_ovl0_drv = { + .probe = mtk_clk_pdev_probe, + .remove = mtk_clk_pdev_remove, + .driver = { + .name = "clk-mt8196-ovl0", + }, + .id_table = clk_mt8196_ovl0_id_table, +}; +module_platform_driver(clk_mt8196_ovl0_drv); + +MODULE_DESCRIPTION("MediaTek MT8196 ovl0 clocks driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/clk/mediatek/clk-mt8196-ovl1.c b/drivers/clk/mediatek/clk-mt8196-ovl1.c new file mode 100644 index 000000000000..c8843d0d3ede --- /dev/null +++ b/drivers/clk/mediatek/clk-mt8196-ovl1.c @@ -0,0 +1,154 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2025 MediaTek Inc. + * Guangjie Song <guangjie.song@mediatek.com> + * Copyright (c) 2025 Collabora Ltd. + * Laura Nao <laura.nao@collabora.com> + */ +#include <dt-bindings/clock/mediatek,mt8196-clock.h> + +#include <linux/clk-provider.h> +#include <linux/module.h> +#include <linux/of_device.h> +#include <linux/platform_device.h> + +#include "clk-gate.h" +#include "clk-mtk.h" + +static const struct mtk_gate_regs ovl10_cg_regs = { + .set_ofs = 0x104, + .clr_ofs = 0x108, + .sta_ofs = 0x100, +}; + +static const struct mtk_gate_regs ovl10_hwv_regs = { + .set_ofs = 0x0050, + .clr_ofs = 0x0054, + .sta_ofs = 0x2c28, +}; + +static const struct mtk_gate_regs ovl11_cg_regs = { + .set_ofs = 0x114, + .clr_ofs = 0x118, + .sta_ofs = 0x110, +}; + +static const struct mtk_gate_regs ovl11_hwv_regs = { + .set_ofs = 0x0058, + .clr_ofs = 0x005c, + .sta_ofs = 0x2c2c, +}; + +#define GATE_HWV_OVL10(_id, _name, _parent, _shift) { \ + .id = _id, \ + .name = _name, \ + .parent_name = _parent, \ + .regs = &ovl10_cg_regs, \ + .hwv_regs = &ovl10_hwv_regs, \ + .shift = _shift, \ + .ops = &mtk_clk_gate_hwv_ops_setclr, \ + .flags = CLK_OPS_PARENT_ENABLE, \ + } + +#define GATE_HWV_OVL11(_id, _name, _parent, _shift) { \ + .id = _id, \ + .name = _name, \ + .parent_name = _parent, \ + .regs = &ovl11_cg_regs, \ + .hwv_regs = &ovl11_hwv_regs, \ + .shift = _shift, \ + .ops = &mtk_clk_gate_hwv_ops_setclr, \ + .flags = CLK_OPS_PARENT_ENABLE, \ + } + +static const struct mtk_gate ovl1_clks[] = { + /* OVL10 */ + GATE_HWV_OVL10(CLK_OVL1_OVLSYS_CONFIG, "ovl1_ovlsys_config", "disp", 0), + GATE_HWV_OVL10(CLK_OVL1_OVL_FAKE_ENG0, "ovl1_ovl_fake_eng0", "disp", 1), + GATE_HWV_OVL10(CLK_OVL1_OVL_FAKE_ENG1, "ovl1_ovl_fake_eng1", "disp", 2), + GATE_HWV_OVL10(CLK_OVL1_OVL_MUTEX0, "ovl1_ovl_mutex0", "disp", 3), + GATE_HWV_OVL10(CLK_OVL1_OVL_EXDMA0, "ovl1_ovl_exdma0", "disp", 4), + GATE_HWV_OVL10(CLK_OVL1_OVL_EXDMA1, "ovl1_ovl_exdma1", "disp", 5), + GATE_HWV_OVL10(CLK_OVL1_OVL_EXDMA2, "ovl1_ovl_exdma2", "disp", 6), + GATE_HWV_OVL10(CLK_OVL1_OVL_EXDMA3, "ovl1_ovl_exdma3", "disp", 7), + GATE_HWV_OVL10(CLK_OVL1_OVL_EXDMA4, "ovl1_ovl_exdma4", "disp", 8), + GATE_HWV_OVL10(CLK_OVL1_OVL_EXDMA5, "ovl1_ovl_exdma5", "disp", 9), + GATE_HWV_OVL10(CLK_OVL1_OVL_EXDMA6, "ovl1_ovl_exdma6", "disp", 10), + GATE_HWV_OVL10(CLK_OVL1_OVL_EXDMA7, "ovl1_ovl_exdma7", "disp", 11), + GATE_HWV_OVL10(CLK_OVL1_OVL_EXDMA8, "ovl1_ovl_exdma8", "disp", 12), + GATE_HWV_OVL10(CLK_OVL1_OVL_EXDMA9, "ovl1_ovl_exdma9", "disp", 13), + GATE_HWV_OVL10(CLK_OVL1_OVL_BLENDER0, "ovl1_ovl_blender0", "disp", 14), + GATE_HWV_OVL10(CLK_OVL1_OVL_BLENDER1, "ovl1_ovl_blender1", "disp", 15), + GATE_HWV_OVL10(CLK_OVL1_OVL_BLENDER2, "ovl1_ovl_blender2", "disp", 16), + GATE_HWV_OVL10(CLK_OVL1_OVL_BLENDER3, "ovl1_ovl_blender3", "disp", 17), + GATE_HWV_OVL10(CLK_OVL1_OVL_BLENDER4, "ovl1_ovl_blender4", "disp", 18), + GATE_HWV_OVL10(CLK_OVL1_OVL_BLENDER5, "ovl1_ovl_blender5", "disp", 19), + GATE_HWV_OVL10(CLK_OVL1_OVL_BLENDER6, "ovl1_ovl_blender6", "disp", 20), + GATE_HWV_OVL10(CLK_OVL1_OVL_BLENDER7, "ovl1_ovl_blender7", "disp", 21), + GATE_HWV_OVL10(CLK_OVL1_OVL_BLENDER8, "ovl1_ovl_blender8", "disp", 22), + GATE_HWV_OVL10(CLK_OVL1_OVL_BLENDER9, "ovl1_ovl_blender9", "disp", 23), + GATE_HWV_OVL10(CLK_OVL1_OVL_OUTPROC0, "ovl1_ovl_outproc0", "disp", 24), + GATE_HWV_OVL10(CLK_OVL1_OVL_OUTPROC1, "ovl1_ovl_outproc1", "disp", 25), + GATE_HWV_OVL10(CLK_OVL1_OVL_OUTPROC2, "ovl1_ovl_outproc2", "disp", 26), + GATE_HWV_OVL10(CLK_OVL1_OVL_OUTPROC3, "ovl1_ovl_outproc3", "disp", 27), + GATE_HWV_OVL10(CLK_OVL1_OVL_OUTPROC4, "ovl1_ovl_outproc4", "disp", 28), + GATE_HWV_OVL10(CLK_OVL1_OVL_OUTPROC5, "ovl1_ovl_outproc5", "disp", 29), + GATE_HWV_OVL10(CLK_OVL1_OVL_MDP_RSZ0, "ovl1_ovl_mdp_rsz0", "disp", 30), + GATE_HWV_OVL10(CLK_OVL1_OVL_MDP_RSZ1, "ovl1_ovl_mdp_rsz1", "disp", 31), + /* OVL11 */ + GATE_HWV_OVL11(CLK_OVL1_OVL_DISP_WDMA0, "ovl1_ovl_disp_wdma0", "disp", 0), + GATE_HWV_OVL11(CLK_OVL1_OVL_DISP_WDMA1, "ovl1_ovl_disp_wdma1", "disp", 1), + GATE_HWV_OVL11(CLK_OVL1_OVL_UFBC_WDMA0, "ovl1_ovl_ufbc_wdma0", "disp", 2), + GATE_HWV_OVL11(CLK_OVL1_OVL_MDP_RDMA0, "ovl1_ovl_mdp_rdma0", "disp", 3), + GATE_HWV_OVL11(CLK_OVL1_OVL_MDP_RDMA1, "ovl1_ovl_mdp_rdma1", "disp", 4), + GATE_HWV_OVL11(CLK_OVL1_OVL_BWM0, "ovl1_ovl_bwm0", "disp", 5), + GATE_HWV_OVL11(CLK_OVL1_DLI0, "ovl1_dli0", "disp", 6), + GATE_HWV_OVL11(CLK_OVL1_DLI1, "ovl1_dli1", "disp", 7), + GATE_HWV_OVL11(CLK_OVL1_DLI2, "ovl1_dli2", "disp", 8), + GATE_HWV_OVL11(CLK_OVL1_DLI3, "ovl1_dli3", "disp", 9), + GATE_HWV_OVL11(CLK_OVL1_DLI4, "ovl1_dli4", "disp", 10), + GATE_HWV_OVL11(CLK_OVL1_DLI5, "ovl1_dli5", "disp", 11), + GATE_HWV_OVL11(CLK_OVL1_DLI6, "ovl1_dli6", "disp", 12), + GATE_HWV_OVL11(CLK_OVL1_DLI7, "ovl1_dli7", "disp", 13), + GATE_HWV_OVL11(CLK_OVL1_DLI8, "ovl1_dli8", "disp", 14), + GATE_HWV_OVL11(CLK_OVL1_DLO0, "ovl1_dlo0", "disp", 15), + GATE_HWV_OVL11(CLK_OVL1_DLO1, "ovl1_dlo1", "disp", 16), + GATE_HWV_OVL11(CLK_OVL1_DLO2, "ovl1_dlo2", "disp", 17), + GATE_HWV_OVL11(CLK_OVL1_DLO3, "ovl1_dlo3", "disp", 18), + GATE_HWV_OVL11(CLK_OVL1_DLO4, "ovl1_dlo4", "disp", 19), + GATE_HWV_OVL11(CLK_OVL1_DLO5, "ovl1_dlo5", "disp", 20), + GATE_HWV_OVL11(CLK_OVL1_DLO6, "ovl1_dlo6", "disp", 21), + GATE_HWV_OVL11(CLK_OVL1_DLO7, "ovl1_dlo7", "disp", 22), + GATE_HWV_OVL11(CLK_OVL1_DLO8, "ovl1_dlo8", "disp", 23), + GATE_HWV_OVL11(CLK_OVL1_DLO9, "ovl1_dlo9", "disp", 24), + GATE_HWV_OVL11(CLK_OVL1_DLO10, "ovl1_dlo10", "disp", 25), + GATE_HWV_OVL11(CLK_OVL1_DLO11, "ovl1_dlo11", "disp", 26), + GATE_HWV_OVL11(CLK_OVL1_DLO12, "ovl1_dlo12", "disp", 27), + GATE_HWV_OVL11(CLK_OVL1_OVLSYS_RELAY0, "ovl1_ovlsys_relay0", "disp", 28), + GATE_HWV_OVL11(CLK_OVL1_OVL_INLINEROT0, "ovl1_ovl_inlinerot0", "disp", 29), + GATE_HWV_OVL11(CLK_OVL1_SMI, "ovl1_smi", "disp", 30), +}; + +static const struct mtk_clk_desc ovl1_mcd = { + .clks = ovl1_clks, + .num_clks = ARRAY_SIZE(ovl1_clks), +}; + +static const struct platform_device_id clk_mt8196_ovl1_id_table[] = { + { .name = "clk-mt8196-ovl1", .driver_data = (kernel_ulong_t)&ovl1_mcd }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(platform, clk_mt8196_ovl1_id_table); + +static struct platform_driver clk_mt8196_ovl1_drv = { + .probe = mtk_clk_pdev_probe, + .remove = mtk_clk_pdev_remove, + .driver = { + .name = "clk-mt8196-ovl1", + }, + .id_table = clk_mt8196_ovl1_id_table, +}; +module_platform_driver(clk_mt8196_ovl1_drv); + +MODULE_DESCRIPTION("MediaTek MT8196 ovl1 clocks driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/clk/mediatek/clk-mt8196-peri_ao.c b/drivers/clk/mediatek/clk-mt8196-peri_ao.c new file mode 100644 index 000000000000..f227a86c5d60 --- /dev/null +++ b/drivers/clk/mediatek/clk-mt8196-peri_ao.c @@ -0,0 +1,142 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2025 MediaTek Inc. + * Guangjie Song <guangjie.song@mediatek.com> + * Copyright (c) 2025 Collabora Ltd. + * Laura Nao <laura.nao@collabora.com> + */ +#include <dt-bindings/clock/mediatek,mt8196-clock.h> + +#include <linux/clk-provider.h> +#include <linux/module.h> +#include <linux/of_device.h> +#include <linux/platform_device.h> + +#include "clk-gate.h" +#include "clk-mtk.h" + +static const struct mtk_gate_regs peri_ao0_cg_regs = { + .set_ofs = 0x24, + .clr_ofs = 0x28, + .sta_ofs = 0x10, +}; + +static const struct mtk_gate_regs peri_ao1_cg_regs = { + .set_ofs = 0x2c, + .clr_ofs = 0x30, + .sta_ofs = 0x14, +}; + +static const struct mtk_gate_regs peri_ao1_hwv_regs = { + .set_ofs = 0x0008, + .clr_ofs = 0x000c, + .sta_ofs = 0x2c04, +}; + +static const struct mtk_gate_regs peri_ao2_cg_regs = { + .set_ofs = 0x34, + .clr_ofs = 0x38, + .sta_ofs = 0x18, +}; + +#define GATE_PERI_AO0(_id, _name, _parent, _shift) { \ + .id = _id, \ + .name = _name, \ + .parent_name = _parent, \ + .regs = &peri_ao0_cg_regs, \ + .shift = _shift, \ + .ops = &mtk_clk_gate_ops_setclr, \ + } + +#define GATE_PERI_AO1(_id, _name, _parent, _shift) { \ + .id = _id, \ + .name = _name, \ + .parent_name = _parent, \ + .regs = &peri_ao1_cg_regs, \ + .shift = _shift, \ + .ops = &mtk_clk_gate_ops_setclr, \ + } + +#define GATE_HWV_PERI_AO1(_id, _name, _parent, _shift) {\ + .id = _id, \ + .name = _name, \ + .parent_name = _parent, \ + .regs = &peri_ao1_cg_regs, \ + .hwv_regs = &peri_ao1_hwv_regs, \ + .shift = _shift, \ + .ops = &mtk_clk_gate_hwv_ops_setclr, \ + } + +#define GATE_PERI_AO2(_id, _name, _parent, _shift) { \ + .id = _id, \ + .name = _name, \ + .parent_name = _parent, \ + .regs = &peri_ao2_cg_regs, \ + .shift = _shift, \ + .ops = &mtk_clk_gate_ops_setclr, \ + } + +static const struct mtk_gate peri_ao_clks[] = { + /* PERI_AO0 */ + GATE_PERI_AO0(CLK_PERI_AO_UART0_BCLK, "peri_ao_uart0_bclk", "uart", 0), + GATE_PERI_AO0(CLK_PERI_AO_UART1_BCLK, "peri_ao_uart1_bclk", "uart", 1), + GATE_PERI_AO0(CLK_PERI_AO_UART2_BCLK, "peri_ao_uart2_bclk", "uart", 2), + GATE_PERI_AO0(CLK_PERI_AO_UART3_BCLK, "peri_ao_uart3_bclk", "uart", 3), + GATE_PERI_AO0(CLK_PERI_AO_UART4_BCLK, "peri_ao_uart4_bclk", "uart", 4), + GATE_PERI_AO0(CLK_PERI_AO_UART5_BCLK, "peri_ao_uart5_bclk", "uart", 5), + GATE_PERI_AO0(CLK_PERI_AO_PWM_X16W_HCLK, "peri_ao_pwm_x16w", "p_axi", 12), + GATE_PERI_AO0(CLK_PERI_AO_PWM_X16W_BCLK, "peri_ao_pwm_x16w_bclk", "pwm", 13), + GATE_PERI_AO0(CLK_PERI_AO_PWM_PWM_BCLK0, "peri_ao_pwm_pwm_bclk0", "pwm", 14), + GATE_PERI_AO0(CLK_PERI_AO_PWM_PWM_BCLK1, "peri_ao_pwm_pwm_bclk1", "pwm", 15), + GATE_PERI_AO0(CLK_PERI_AO_PWM_PWM_BCLK2, "peri_ao_pwm_pwm_bclk2", "pwm", 16), + GATE_PERI_AO0(CLK_PERI_AO_PWM_PWM_BCLK3, "peri_ao_pwm_pwm_bclk3", "pwm", 17), + /* PERI_AO1 */ + GATE_HWV_PERI_AO1(CLK_PERI_AO_SPI0_BCLK, "peri_ao_spi0_bclk", "spi0_b", 0), + GATE_HWV_PERI_AO1(CLK_PERI_AO_SPI1_BCLK, "peri_ao_spi1_bclk", "spi1_b", 2), + GATE_HWV_PERI_AO1(CLK_PERI_AO_SPI2_BCLK, "peri_ao_spi2_bclk", "spi2_b", 3), + GATE_HWV_PERI_AO1(CLK_PERI_AO_SPI3_BCLK, "peri_ao_spi3_bclk", "spi3_b", 4), + GATE_HWV_PERI_AO1(CLK_PERI_AO_SPI4_BCLK, "peri_ao_spi4_bclk", "spi4_b", 5), + GATE_HWV_PERI_AO1(CLK_PERI_AO_SPI5_BCLK, "peri_ao_spi5_bclk", "spi5_b", 6), + GATE_HWV_PERI_AO1(CLK_PERI_AO_SPI6_BCLK, "peri_ao_spi6_bclk", "spi6_b", 7), + GATE_HWV_PERI_AO1(CLK_PERI_AO_SPI7_BCLK, "peri_ao_spi7_bclk", "spi7_b", 8), + GATE_PERI_AO1(CLK_PERI_AO_FLASHIF_FLASH, "peri_ao_flashif_flash", "peri_ao_flashif_27m", + 18), + GATE_PERI_AO1(CLK_PERI_AO_FLASHIF_27M, "peri_ao_flashif_27m", "sflash", 19), + GATE_PERI_AO1(CLK_PERI_AO_FLASHIF_DRAM, "peri_ao_flashif_dram", "p_axi", 20), + GATE_PERI_AO1(CLK_PERI_AO_FLASHIF_AXI, "peri_ao_flashif_axi", "peri_ao_flashif_dram", 21), + GATE_PERI_AO1(CLK_PERI_AO_FLASHIF_BCLK, "peri_ao_flashif_bclk", "p_axi", 22), + GATE_PERI_AO1(CLK_PERI_AO_AP_DMA_X32W_BCLK, "peri_ao_ap_dma_x32w_bclk", "p_axi", 26), + /* PERI_AO2 */ + GATE_PERI_AO2(CLK_PERI_AO_MSDC1_MSDC_SRC, "peri_ao_msdc1_msdc_src", "msdc30_1", 1), + GATE_PERI_AO2(CLK_PERI_AO_MSDC1_HCLK, "peri_ao_msdc1", "peri_ao_msdc1_axi", 2), + GATE_PERI_AO2(CLK_PERI_AO_MSDC1_AXI, "peri_ao_msdc1_axi", "p_axi", 3), + GATE_PERI_AO2(CLK_PERI_AO_MSDC1_HCLK_WRAP, "peri_ao_msdc1_h_wrap", "peri_ao_msdc1", 4), + GATE_PERI_AO2(CLK_PERI_AO_MSDC2_MSDC_SRC, "peri_ao_msdc2_msdc_src", "msdc30_2", 10), + GATE_PERI_AO2(CLK_PERI_AO_MSDC2_HCLK, "peri_ao_msdc2", "peri_ao_msdc2_axi", 11), + GATE_PERI_AO2(CLK_PERI_AO_MSDC2_AXI, "peri_ao_msdc2_axi", "p_axi", 12), + GATE_PERI_AO2(CLK_PERI_AO_MSDC2_HCLK_WRAP, "peri_ao_msdc2_h_wrap", "peri_ao_msdc2", 13), +}; + +static const struct mtk_clk_desc peri_ao_mcd = { + .clks = peri_ao_clks, + .num_clks = ARRAY_SIZE(peri_ao_clks), +}; + +static const struct of_device_id of_match_clk_mt8196_peri_ao[] = { + { .compatible = "mediatek,mt8196-pericfg-ao", .data = &peri_ao_mcd }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(of, of_match_clk_mt8196_peri_ao); + +static struct platform_driver clk_mt8196_peri_ao_drv = { + .probe = mtk_clk_simple_probe, + .remove = mtk_clk_simple_remove, + .driver = { + .name = "clk-mt8196-peri-ao", + .of_match_table = of_match_clk_mt8196_peri_ao, + }, +}; + +MODULE_DESCRIPTION("MediaTek MT8196 pericfg_ao clock controller driver"); +module_platform_driver(clk_mt8196_peri_ao_drv); +MODULE_LICENSE("GPL"); diff --git a/drivers/clk/mediatek/clk-mt8196-pextp.c b/drivers/clk/mediatek/clk-mt8196-pextp.c new file mode 100644 index 000000000000..3e505ecc4b6e --- /dev/null +++ b/drivers/clk/mediatek/clk-mt8196-pextp.c @@ -0,0 +1,131 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2025 MediaTek Inc. + * Guangjie Song <guangjie.song@mediatek.com> + * Copyright (c) 2025 Collabora Ltd. + * Laura Nao <laura.nao@collabora.com> + */ +#include <dt-bindings/clock/mediatek,mt8196-clock.h> +#include <dt-bindings/reset/mediatek,mt8196-resets.h> + +#include <linux/clk-provider.h> +#include <linux/module.h> +#include <linux/of_device.h> +#include <linux/platform_device.h> + +#include "clk-gate.h" +#include "clk-mtk.h" +#include "reset.h" + +#define MT8196_PEXTP_RST0_SET_OFFSET 0x8 + +static const struct mtk_gate_regs pext_cg_regs = { + .set_ofs = 0x18, + .clr_ofs = 0x1c, + .sta_ofs = 0x14, +}; + +#define GATE_PEXT(_id, _name, _parent, _shift) {\ + .id = _id, \ + .name = _name, \ + .parent_name = _parent, \ + .regs = &pext_cg_regs, \ + .shift = _shift, \ + .ops = &mtk_clk_gate_ops_setclr,\ + } + +static const struct mtk_gate pext_clks[] = { + GATE_PEXT(CLK_PEXT_PEXTP_MAC_P0_TL, "pext_pm0_tl", "tl", 0), + GATE_PEXT(CLK_PEXT_PEXTP_MAC_P0_REF, "pext_pm0_ref", "clk26m", 1), + GATE_PEXT(CLK_PEXT_PEXTP_PHY_P0_MCU_BUS, "pext_pp0_mcu_bus", "clk26m", 6), + GATE_PEXT(CLK_PEXT_PEXTP_PHY_P0_PEXTP_REF, "pext_pp0_pextp_ref", "clk26m", 7), + GATE_PEXT(CLK_PEXT_PEXTP_MAC_P0_AXI_250, "pext_pm0_axi_250", "ufs_pexpt0_mem_sub", 12), + GATE_PEXT(CLK_PEXT_PEXTP_MAC_P0_AHB_APB, "pext_pm0_ahb_apb", "ufs_pextp0_axi", 13), + GATE_PEXT(CLK_PEXT_PEXTP_MAC_P0_PL_P, "pext_pm0_pl_p", "clk26m", 14), + GATE_PEXT(CLK_PEXT_PEXTP_VLP_AO_P0_LP, "pext_pextp_vlp_ao_p0_lp", "clk26m", 19), +}; + +static u16 pext_rst_ofs[] = { MT8196_PEXTP_RST0_SET_OFFSET }; + +static u16 pext_rst_idx_map[] = { + [MT8196_PEXTP0_RST0_PCIE0_MAC] = 0, + [MT8196_PEXTP0_RST0_PCIE0_PHY] = 1, +}; + +static const struct mtk_clk_rst_desc pext_rst_desc = { + .version = MTK_RST_SET_CLR, + .rst_bank_ofs = pext_rst_ofs, + .rst_bank_nr = ARRAY_SIZE(pext_rst_ofs), + .rst_idx_map = pext_rst_idx_map, + .rst_idx_map_nr = ARRAY_SIZE(pext_rst_idx_map), +}; + +static const struct mtk_clk_desc pext_mcd = { + .clks = pext_clks, + .num_clks = ARRAY_SIZE(pext_clks), + .rst_desc = &pext_rst_desc, +}; + +static const struct mtk_gate pext1_clks[] = { + GATE_PEXT(CLK_PEXT1_PEXTP_MAC_P1_TL, "pext1_pm1_tl", "tl_p1", 0), + GATE_PEXT(CLK_PEXT1_PEXTP_MAC_P1_REF, "pext1_pm1_ref", "clk26m", 1), + GATE_PEXT(CLK_PEXT1_PEXTP_MAC_P2_TL, "pext1_pm2_tl", "tl_p2", 2), + GATE_PEXT(CLK_PEXT1_PEXTP_MAC_P2_REF, "pext1_pm2_ref", "clk26m", 3), + GATE_PEXT(CLK_PEXT1_PEXTP_PHY_P1_MCU_BUS, "pext1_pp1_mcu_bus", "clk26m", 8), + GATE_PEXT(CLK_PEXT1_PEXTP_PHY_P1_PEXTP_REF, "pext1_pp1_pextp_ref", "clk26m", 9), + GATE_PEXT(CLK_PEXT1_PEXTP_PHY_P2_MCU_BUS, "pext1_pp2_mcu_bus", "clk26m", 10), + GATE_PEXT(CLK_PEXT1_PEXTP_PHY_P2_PEXTP_REF, "pext1_pp2_pextp_ref", "clk26m", 11), + GATE_PEXT(CLK_PEXT1_PEXTP_MAC_P1_AXI_250, "pext1_pm1_axi_250", + "pextp1_usb_axi", 16), + GATE_PEXT(CLK_PEXT1_PEXTP_MAC_P1_AHB_APB, "pext1_pm1_ahb_apb", + "pextp1_usb_mem_sub", 17), + GATE_PEXT(CLK_PEXT1_PEXTP_MAC_P1_PL_P, "pext1_pm1_pl_p", "clk26m", 18), + GATE_PEXT(CLK_PEXT1_PEXTP_MAC_P2_AXI_250, "pext1_pm2_axi_250", + "pextp1_usb_axi", 19), + GATE_PEXT(CLK_PEXT1_PEXTP_MAC_P2_AHB_APB, "pext1_pm2_ahb_apb", + "pextp1_usb_mem_sub", 20), + GATE_PEXT(CLK_PEXT1_PEXTP_MAC_P2_PL_P, "pext1_pm2_pl_p", "clk26m", 21), + GATE_PEXT(CLK_PEXT1_PEXTP_VLP_AO_P1_LP, "pext1_pextp_vlp_ao_p1_lp", "clk26m", 26), + GATE_PEXT(CLK_PEXT1_PEXTP_VLP_AO_P2_LP, "pext1_pextp_vlp_ao_p2_lp", "clk26m", 27), +}; + +static u16 pext1_rst_idx_map[] = { + [MT8196_PEXTP1_RST0_PCIE1_MAC] = 0, + [MT8196_PEXTP1_RST0_PCIE1_PHY] = 1, + [MT8196_PEXTP1_RST0_PCIE2_MAC] = 8, + [MT8196_PEXTP1_RST0_PCIE2_PHY] = 9, +}; + +static const struct mtk_clk_rst_desc pext1_rst_desc = { + .version = MTK_RST_SET_CLR, + .rst_bank_ofs = pext_rst_ofs, + .rst_bank_nr = ARRAY_SIZE(pext_rst_ofs), + .rst_idx_map = pext1_rst_idx_map, + .rst_idx_map_nr = ARRAY_SIZE(pext1_rst_idx_map), +}; + +static const struct mtk_clk_desc pext1_mcd = { + .clks = pext1_clks, + .num_clks = ARRAY_SIZE(pext1_clks), + .rst_desc = &pext1_rst_desc, +}; + +static const struct of_device_id of_match_clk_mt8196_pextp[] = { + { .compatible = "mediatek,mt8196-pextp0cfg-ao", .data = &pext_mcd }, + { .compatible = "mediatek,mt8196-pextp1cfg-ao", .data = &pext1_mcd }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(of, of_match_clk_mt8196_pextp); + +static struct platform_driver clk_mt8196_pextp_drv = { + .probe = mtk_clk_simple_probe, + .remove = mtk_clk_simple_remove, + .driver = { + .name = "clk-mt8196-pextp", + .of_match_table = of_match_clk_mt8196_pextp, + }, +}; + +module_platform_driver(clk_mt8196_pextp_drv); +MODULE_DESCRIPTION("MediaTek MT8196 PCIe transmit phy clocks driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/clk/mediatek/clk-mt8196-topckgen.c b/drivers/clk/mediatek/clk-mt8196-topckgen.c new file mode 100644 index 000000000000..6ace11ef6b69 --- /dev/null +++ b/drivers/clk/mediatek/clk-mt8196-topckgen.c @@ -0,0 +1,985 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2025 MediaTek Inc. + * Guangjie Song <guangjie.song@mediatek.com> + * Copyright (c) 2025 Collabora Ltd. + * Laura Nao <laura.nao@collabora.com> + */ +#include <dt-bindings/clock/mediatek,mt8196-clock.h> + +#include <linux/clk.h> +#include <linux/module.h> +#include <linux/of.h> +#include <linux/of_address.h> +#include <linux/of_device.h> +#include <linux/platform_device.h> + +#include "clk-mtk.h" +#include "clk-mux.h" + +/* MUX SEL REG */ +#define CLK_CFG_UPDATE 0x0004 +#define CLK_CFG_UPDATE1 0x0008 +#define CLK_CFG_UPDATE2 0x000c +#define CLK_CFG_0 0x0010 +#define CLK_CFG_0_SET 0x0014 +#define CLK_CFG_0_CLR 0x0018 +#define CLK_CFG_1 0x0020 +#define CLK_CFG_1_SET 0x0024 +#define CLK_CFG_1_CLR 0x0028 +#define CLK_CFG_2 0x0030 +#define CLK_CFG_2_SET 0x0034 +#define CLK_CFG_2_CLR 0x0038 +#define CLK_CFG_3 0x0040 +#define CLK_CFG_3_SET 0x0044 +#define CLK_CFG_3_CLR 0x0048 +#define CLK_CFG_4 0x0050 +#define CLK_CFG_4_SET 0x0054 +#define CLK_CFG_4_CLR 0x0058 +#define CLK_CFG_5 0x0060 +#define CLK_CFG_5_SET 0x0064 +#define CLK_CFG_5_CLR 0x0068 +#define CLK_CFG_6 0x0070 +#define CLK_CFG_6_SET 0x0074 +#define CLK_CFG_6_CLR 0x0078 +#define CLK_CFG_7 0x0080 +#define CLK_CFG_7_SET 0x0084 +#define CLK_CFG_7_CLR 0x0088 +#define CLK_CFG_8 0x0090 +#define CLK_CFG_8_SET 0x0094 +#define CLK_CFG_8_CLR 0x0098 +#define CLK_CFG_9 0x00a0 +#define CLK_CFG_9_SET 0x00a4 +#define CLK_CFG_9_CLR 0x00a8 +#define CLK_CFG_10 0x00b0 +#define CLK_CFG_10_SET 0x00b4 +#define CLK_CFG_10_CLR 0x00b8 +#define CLK_CFG_11 0x00c0 +#define CLK_CFG_11_SET 0x00c4 +#define CLK_CFG_11_CLR 0x00c8 +#define CLK_CFG_12 0x00d0 +#define CLK_CFG_12_SET 0x00d4 +#define CLK_CFG_12_CLR 0x00d8 +#define CLK_CFG_13 0x00e0 +#define CLK_CFG_13_SET 0x00e4 +#define CLK_CFG_13_CLR 0x00e8 +#define CLK_CFG_14 0x00f0 +#define CLK_CFG_14_SET 0x00f4 +#define CLK_CFG_14_CLR 0x00f8 +#define CLK_CFG_15 0x0100 +#define CLK_CFG_15_SET 0x0104 +#define CLK_CFG_15_CLR 0x0108 +#define CLK_CFG_16 0x0110 +#define CLK_CFG_16_SET 0x0114 +#define CLK_CFG_16_CLR 0x0118 +#define CLK_CFG_17 0x0120 +#define CLK_CFG_17_SET 0x0124 +#define CLK_CFG_17_CLR 0x0128 +#define CLK_CFG_18 0x0130 +#define CLK_CFG_18_SET 0x0134 +#define CLK_CFG_18_CLR 0x0138 +#define CLK_CFG_19 0x0140 +#define CLK_CFG_19_SET 0x0144 +#define CLK_CFG_19_CLR 0x0148 +#define CLK_AUDDIV_0 0x020c +#define CLK_FENC_STATUS_MON_0 0x0270 +#define CLK_FENC_STATUS_MON_1 0x0274 +#define CLK_FENC_STATUS_MON_2 0x0278 + +/* MUX SHIFT */ +#define TOP_MUX_AXI_SHIFT 0 +#define TOP_MUX_MEM_SUB_SHIFT 1 +#define TOP_MUX_IO_NOC_SHIFT 2 +#define TOP_MUX_PERI_AXI_SHIFT 3 +#define TOP_MUX_UFS_PEXTP0_AXI_SHIFT 4 +#define TOP_MUX_PEXTP1_USB_AXI_SHIFT 5 +#define TOP_MUX_PERI_FMEM_SUB_SHIFT 6 +#define TOP_MUX_UFS_PEXPT0_MEM_SUB_SHIFT 7 +#define TOP_MUX_PEXTP1_USB_MEM_SUB_SHIFT 8 +#define TOP_MUX_PERI_NOC_SHIFT 9 +#define TOP_MUX_EMI_N_SHIFT 10 +#define TOP_MUX_EMI_S_SHIFT 11 +#define TOP_MUX_AP2CONN_HOST_SHIFT 14 +#define TOP_MUX_ATB_SHIFT 15 +#define TOP_MUX_CIRQ_SHIFT 16 +#define TOP_MUX_PBUS_156M_SHIFT 17 +#define TOP_MUX_EFUSE_SHIFT 20 +#define TOP_MUX_MCU_L3GIC_SHIFT 21 +#define TOP_MUX_MCU_INFRA_SHIFT 22 +#define TOP_MUX_DSP_SHIFT 23 +#define TOP_MUX_MFG_REF_SHIFT 24 +#define TOP_MUX_MFG_EB_SHIFT 26 +#define TOP_MUX_UART_SHIFT 27 +#define TOP_MUX_SPI0_BCLK_SHIFT 28 +#define TOP_MUX_SPI1_BCLK_SHIFT 29 +#define TOP_MUX_SPI2_BCLK_SHIFT 30 +#define TOP_MUX_SPI3_BCLK_SHIFT 0 +#define TOP_MUX_SPI4_BCLK_SHIFT 1 +#define TOP_MUX_SPI5_BCLK_SHIFT 2 +#define TOP_MUX_SPI6_BCLK_SHIFT 3 +#define TOP_MUX_SPI7_BCLK_SHIFT 4 +#define TOP_MUX_MSDC30_1_SHIFT 7 +#define TOP_MUX_MSDC30_2_SHIFT 8 +#define TOP_MUX_DISP_PWM_SHIFT 9 +#define TOP_MUX_USB_TOP_1P_SHIFT 10 +#define TOP_MUX_SSUSB_XHCI_1P_SHIFT 11 +#define TOP_MUX_SSUSB_FMCNT_P1_SHIFT 12 +#define TOP_MUX_I2C_PERI_SHIFT 13 +#define TOP_MUX_I2C_EAST_SHIFT 14 +#define TOP_MUX_I2C_WEST_SHIFT 15 +#define TOP_MUX_I2C_NORTH_SHIFT 16 +#define TOP_MUX_AES_UFSFDE_SHIFT 17 +#define TOP_MUX_UFS_SHIFT 18 +#define TOP_MUX_AUD_1_SHIFT 21 +#define TOP_MUX_AUD_2_SHIFT 22 +#define TOP_MUX_ADSP_SHIFT 23 +#define TOP_MUX_ADSP_UARTHUB_B_SHIFT 24 +#define TOP_MUX_DPMAIF_MAIN_SHIFT 25 +#define TOP_MUX_PWM_SHIFT 26 +#define TOP_MUX_MCUPM_SHIFT 27 +#define TOP_MUX_SFLASH_SHIFT 28 +#define TOP_MUX_IPSEAST_SHIFT 29 +#define TOP_MUX_TL_SHIFT 0 +#define TOP_MUX_TL_P1_SHIFT 1 +#define TOP_MUX_TL_P2_SHIFT 2 +#define TOP_MUX_EMI_INTERFACE_546_SHIFT 3 +#define TOP_MUX_SDF_SHIFT 4 +#define TOP_MUX_UARTHUB_BCLK_SHIFT 5 +#define TOP_MUX_DPSW_CMP_26M_SHIFT 6 +#define TOP_MUX_SMAPCK_SHIFT 7 +#define TOP_MUX_SSR_PKA_SHIFT 8 +#define TOP_MUX_SSR_DMA_SHIFT 9 +#define TOP_MUX_SSR_KDF_SHIFT 10 +#define TOP_MUX_SSR_RNG_SHIFT 11 +#define TOP_MUX_SPU0_SHIFT 12 +#define TOP_MUX_SPU1_SHIFT 13 +#define TOP_MUX_DXCC_SHIFT 14 + +/* CKSTA REG */ +#define CKSTA_REG 0x01c8 +#define CKSTA_REG1 0x01cc +#define CKSTA_REG2 0x01d0 + +/* DIVIDER REG */ +#define CLK_AUDDIV_2 0x0214 +#define CLK_AUDDIV_3 0x0220 +#define CLK_AUDDIV_4 0x0224 +#define CLK_AUDDIV_5 0x0228 + +/* HW Voter REG */ +#define HWV_CG_0_SET 0x0000 +#define HWV_CG_0_CLR 0x0004 +#define HWV_CG_0_DONE 0x2c00 +#define HWV_CG_1_SET 0x0008 +#define HWV_CG_1_CLR 0x000c +#define HWV_CG_1_DONE 0x2c04 +#define HWV_CG_2_SET 0x0010 +#define HWV_CG_2_CLR 0x0014 +#define HWV_CG_2_DONE 0x2c08 +#define HWV_CG_3_SET 0x0018 +#define HWV_CG_3_CLR 0x001c +#define HWV_CG_3_DONE 0x2c0c +#define HWV_CG_4_SET 0x0020 +#define HWV_CG_4_CLR 0x0024 +#define HWV_CG_4_DONE 0x2c10 +#define HWV_CG_5_SET 0x0028 +#define HWV_CG_5_CLR 0x002c +#define HWV_CG_5_DONE 0x2c14 +#define HWV_CG_6_SET 0x0030 +#define HWV_CG_6_CLR 0x0034 +#define HWV_CG_6_DONE 0x2c18 +#define HWV_CG_7_SET 0x0038 +#define HWV_CG_7_CLR 0x003c +#define HWV_CG_7_DONE 0x2c1c +#define HWV_CG_8_SET 0x0040 +#define HWV_CG_8_CLR 0x0044 +#define HWV_CG_8_DONE 0x2c20 + +static const struct mtk_fixed_factor top_divs[] = { + FACTOR(CLK_TOP_MAINPLL_D3, "mainpll_d3", "mainpll", 1, 3), + FACTOR(CLK_TOP_MAINPLL_D4, "mainpll_d4", "mainpll", 1, 4), + FACTOR(CLK_TOP_MAINPLL_D4_D2, "mainpll_d4_d2", "mainpll", 1, 8), + FACTOR(CLK_TOP_MAINPLL_D4_D4, "mainpll_d4_d4", "mainpll", 1, 16), + FACTOR(CLK_TOP_MAINPLL_D4_D8, "mainpll_d4_d8", "mainpll", 1, 32), + FACTOR(CLK_TOP_MAINPLL_D5, "mainpll_d5", "mainpll", 1, 5), + FACTOR(CLK_TOP_MAINPLL_D5_D2, "mainpll_d5_d2", "mainpll", 1, 10), + FACTOR(CLK_TOP_MAINPLL_D5_D4, "mainpll_d5_d4", "mainpll", 1, 20), + FACTOR(CLK_TOP_MAINPLL_D5_D8, "mainpll_d5_d8", "mainpll", 1, 40), + FACTOR(CLK_TOP_MAINPLL_D6, "mainpll_d6", "mainpll", 1, 6), + FACTOR(CLK_TOP_MAINPLL_D6_D2, "mainpll_d6_d2", "mainpll", 1, 12), + FACTOR(CLK_TOP_MAINPLL_D7, "mainpll_d7", "mainpll", 1, 7), + FACTOR(CLK_TOP_MAINPLL_D7_D2, "mainpll_d7_d2", "mainpll", 1, 14), + FACTOR(CLK_TOP_MAINPLL_D7_D4, "mainpll_d7_d4", "mainpll", 1, 28), + FACTOR(CLK_TOP_MAINPLL_D7_D8, "mainpll_d7_d8", "mainpll", 1, 56), + FACTOR(CLK_TOP_MAINPLL_D9, "mainpll_d9", "mainpll", 1, 9), + FACTOR(CLK_TOP_UNIVPLL_D4, "univpll_d4", "univpll", 1, 4), + FACTOR(CLK_TOP_UNIVPLL_D4_D2, "univpll_d4_d2", "univpll", 1, 8), + FACTOR(CLK_TOP_UNIVPLL_D4_D4, "univpll_d4_d4", "univpll", 1, 16), + FACTOR(CLK_TOP_UNIVPLL_D4_D8, "univpll_d4_d8", "univpll", 1, 32), + FACTOR(CLK_TOP_UNIVPLL_D5, "univpll_d5", "univpll", 1, 5), + FACTOR(CLK_TOP_UNIVPLL_D5_D2, "univpll_d5_d2", "univpll", 1, 10), + FACTOR(CLK_TOP_UNIVPLL_D5_D4, "univpll_d5_d4", "univpll", 1, 20), + FACTOR(CLK_TOP_UNIVPLL_D6, "univpll_d6", "univpll", 1, 6), + FACTOR(CLK_TOP_UNIVPLL_D6_D2, "univpll_d6_d2", "univpll", 1, 12), + FACTOR(CLK_TOP_UNIVPLL_D6_D4, "univpll_d6_d4", "univpll", 1, 24), + FACTOR(CLK_TOP_UNIVPLL_D6_D8, "univpll_d6_d8", "univpll", 1, 48), + FACTOR(CLK_TOP_UNIVPLL_D6_D16, "univpll_d6_d16", "univpll", 1, 96), + FACTOR(CLK_TOP_UNIVPLL_192M, "univpll_192m", "univpll", 1, 13), + FACTOR(CLK_TOP_UNIVPLL_192M_D4, "univpll_192m_d4", "univpll", 1, 52), + FACTOR(CLK_TOP_UNIVPLL_192M_D8, "univpll_192m_d8", "univpll", 1, 104), + FACTOR(CLK_TOP_UNIVPLL_192M_D16, "univpll_192m_d16", "univpll", 1, 208), + FACTOR(CLK_TOP_UNIVPLL_192M_D32, "univpll_192m_d32", "univpll", 1, 416), + FACTOR(CLK_TOP_UNIVPLL_192M_D10, "univpll_192m_d10", "univpll", 1, 130), + FACTOR(CLK_TOP_TVDPLL1_D2, "tvdpll1_d2", "tvdpll1", 1, 2), + FACTOR(CLK_TOP_MSDCPLL_D2, "msdcpll_d2", "msdcpll", 1, 2), + FACTOR(CLK_TOP_OSC_D2, "osc_d2", "ulposc", 1, 2), + FACTOR(CLK_TOP_OSC_D3, "osc_d3", "ulposc", 1, 3), + FACTOR(CLK_TOP_OSC_D4, "osc_d4", "ulposc", 1, 4), + FACTOR(CLK_TOP_OSC_D5, "osc_d5", "ulposc", 1, 5), + FACTOR(CLK_TOP_OSC_D7, "osc_d7", "ulposc", 1, 7), + FACTOR(CLK_TOP_OSC_D8, "osc_d8", "ulposc", 1, 8), + FACTOR(CLK_TOP_OSC_D10, "osc_d10", "ulposc", 1, 10), + FACTOR(CLK_TOP_OSC_D14, "osc_d14", "ulposc", 1, 14), + FACTOR(CLK_TOP_OSC_D20, "osc_d20", "ulposc", 1, 20), + FACTOR(CLK_TOP_OSC_D32, "osc_d32", "ulposc", 1, 32), + FACTOR(CLK_TOP_OSC_D40, "osc_d40", "ulposc", 1, 40), +}; + +static const char * const axi_parents[] = { + "clk26m", + "osc_d20", + "osc_d8", + "osc_d4", + "mainpll_d4_d4", + "mainpll_d7_d2" +}; + +static const char * const mem_sub_parents[] = { + "clk26m", + "osc_d20", + "osc_d4", + "univpll_d4_d4", + "osc_d3", + "mainpll_d5_d2", + "mainpll_d4_d2", + "mainpll_d6", + "mainpll_d5", + "univpll_d5", + "mainpll_d4", + "mainpll_d3" +}; + +static const char * const io_noc_parents[] = { + "clk26m", + "osc_d20", + "osc_d8", + "osc_d4", + "mainpll_d6_d2", + "mainpll_d9" +}; + +static const char * const shared_axi_parents[] = { + "clk26m", + "mainpll_d7_d8", + "mainpll_d5_d8", + "osc_d8", + "mainpll_d7_d4", + "mainpll_d5_d4", + "mainpll_d4_d4", + "mainpll_d7_d2" +}; + +static const char * const shared_sub_parents[] = { + "clk26m", + "mainpll_d5_d8", + "mainpll_d5_d4", + "osc_d4", + "univpll_d4_d4", + "mainpll_d5_d2", + "mainpll_d4_d2", + "mainpll_d6", + "mainpll_d5", + "univpll_d5", + "mainpll_d4" +}; + +static const char * const p_noc_parents[] = { + "clk26m", + "mainpll_d5_d8", + "mainpll_d5_d4", + "osc_d4", + "univpll_d4_d4", + "mainpll_d5_d2", + "mainpll_d4_d2", + "mainpll_d6", + "mainpll_d5", + "univpll_d5", + "mainpll_d4", + "mainpll_d3" +}; + +static const char * const emi_parents[] = { + "clk26m", + "osc_d4", + "mainpll_d5_d8", + "mainpll_d5_d4", + "mainpll_d4_d4", + "emipll1_ck" +}; + +static const char * const ap2conn_host_parents[] = { + "clk26m", + "mainpll_d7_d4" +}; + +static const char * const atb_parents[] = { + "clk26m", + "mainpll_d5_d2", + "mainpll_d4_d2", + "mainpll_d6" +}; + +static const char * const cirq_parents[] = { + "clk26m", + "osc_d20", + "mainpll_d7_d4" +}; + +static const char * const pbus_156m_parents[] = { + "clk26m", + "mainpll_d7_d2", + "osc_d2", + "mainpll_d7" +}; + +static const char * const efuse_parents[] = { + "clk26m", + "osc_d20" +}; + +static const char * const mcu_l3gic_parents[] = { + "clk26m", + "osc_d8", + "mainpll_d4_d4", + "mainpll_d7_d2" +}; + +static const char * const mcu_infra_parents[] = { + "clk26m", + "osc_d20", + "mainpll_d7_d2", + "mainpll_d5_d2", + "mainpll_d4_d2", + "mainpll_d9", + "mainpll_d6" +}; + +static const char * const dsp_parents[] = { + "clk26m", + "osc_d5", + "osc_d4", + "osc_d3", + "univpll_d6_d2", + "osc_d2", + "univpll_d5", + "osc" +}; + +static const char * const mfg_ref_parents[] = { + "clk26m", + "mainpll_d7_d2" +}; + +static const char * const mfg_eb_parents[] = { + "clk26m", + "mainpll_d7_d2", + "mainpll_d6_d2", + "mainpll_d5_d2" +}; + +static const char * const uart_parents[] = { + "clk26m", + "univpll_d6_d8", + "univpll_d6_d4", + "univpll_d6_d2" +}; + +static const char * const spi_b_parents[] = { + "clk26m", + "univpll_d6_d4", + "univpll_d5_d4", + "mainpll_d4_d4", + "univpll_d4_d4", + "mainpll_d6_d2", + "univpll_192m", + "univpll_d6_d2" +}; + +static const char * const msdc30_parents[] = { + "clk26m", + "univpll_d6_d4", + "mainpll_d6_d2", + "univpll_d6_d2", + "msdcpll_d2" +}; + +static const char * const disp_pwm_parents[] = { + "clk26m", + "osc_d32", + "osc_d8", + "univpll_d6_d4", + "univpll_d5_d4", + "osc_d4", + "mainpll_d4_d4" +}; + +static const char * const usb_1p_parents[] = { + "clk26m", + "univpll_d5_d4" +}; + +static const char * const usb_fmcnt_p1_parents[] = { + "clk26m", + "univpll_192m_d4" +}; + +static const char * const i2c_parents[] = { + "clk26m", + "mainpll_d4_d8", + "univpll_d5_d4", + "mainpll_d4_d4", + "univpll_d5_d2" +}; + +static const char * const aes_ufsfde_parents[] = { + "clk26m", + "mainpll_d4_d4", + "univpll_d6_d2", + "mainpll_d4_d2", + "univpll_d6", + "mainpll_d4" +}; + +static const char * const ufs_parents[] = { + "clk26m", + "mainpll_d4_d4", + "univpll_d6_d2", + "mainpll_d4_d2", + "univpll_d6", + "mainpll_d5", + "univpll_d5" +}; + +static const char * const aud_1_parents[] = { + "clk26m", + "vlp_apll1" +}; + +static const char * const aud_2_parents[] = { + "clk26m", + "vlp_apll2" +}; + +static const char * const adsp_parents[] = { + "clk26m", + "adsppll" +}; + +static const char * const adsp_uarthub_b_parents[] = { + "clk26m", + "univpll_d6_d4", + "univpll_d6_d2" +}; + +static const char * const dpmaif_main_parents[] = { + "clk26m", + "univpll_d4_d4", + "univpll_d5_d2", + "mainpll_d4_d2", + "univpll_d4_d2", + "mainpll_d6", + "univpll_d6", + "mainpll_d5", + "univpll_d5" +}; + +static const char * const pwm_parents[] = { + "clk26m", + "mainpll_d7_d4", + "univpll_d4_d8" +}; + +static const char * const mcupm_parents[] = { + "clk26m", + "mainpll_d7_d2", + "mainpll_d6_d2", + "univpll_d6_d2", + "mainpll_d5_d2" +}; + +static const char * const ipseast_parents[] = { + "clk26m", + "mainpll_d6", + "mainpll_d5", + "mainpll_d4", + "mainpll_d3" +}; + +static const char * const tl_parents[] = { + "clk26m", + "mainpll_d7_d4", + "mainpll_d4_d4", + "mainpll_d5_d2" +}; + +static const char * const md_emi_parents[] = { + "clk26m", + "mainpll_d4" +}; + +static const char * const sdf_parents[] = { + "clk26m", + "mainpll_d5_d2", + "mainpll_d4_d2", + "mainpll_d6", + "mainpll_d4", + "univpll_d4" +}; + +static const char * const uarthub_b_parents[] = { + "clk26m", + "univpll_d6_d4", + "univpll_d6_d2" +}; + +static const char * const dpsw_cmp_26m_parents[] = { + "clk26m", + "osc_d20" +}; + +static const char * const smapparents[] = { + "clk26m", + "mainpll_d4_d8" +}; + +static const char * const ssr_parents[] = { + "clk26m", + "mainpll_d4_d4", + "mainpll_d4_d2", + "mainpll_d7", + "mainpll_d6", + "mainpll_d5" +}; + +static const char * const ssr_kdf_parents[] = { + "clk26m", + "mainpll_d4_d4", + "mainpll_d4_d2", + "mainpll_d7" +}; + +static const char * const ssr_rng_parents[] = { + "clk26m", + "mainpll_d4_d4", + "mainpll_d5_d2", + "mainpll_d4_d2" +}; + +static const char * const spu_parents[] = { + "clk26m", + "mainpll_d4_d4", + "mainpll_d4_d2", + "mainpll_d7", + "mainpll_d6", + "mainpll_d5" +}; + +static const char * const dxcc_parents[] = { + "clk26m", + "mainpll_d4_d8", + "mainpll_d4_d4", + "mainpll_d4_d2" +}; + +static const char * const apll_m_parents[] = { + "aud_1", + "aud_2" +}; + +static const char * const sflash_parents[] = { + "clk26m", + "mainpll_d7_d8", + "univpll_d6_d8" +}; + +static const struct mtk_mux top_muxes[] = { + /* CLK_CFG_0 */ + MUX_CLR_SET_UPD(CLK_TOP_AXI, "axi", + axi_parents, CLK_CFG_0, CLK_CFG_0_SET, + CLK_CFG_0_CLR, 0, 3, + CLK_CFG_UPDATE, TOP_MUX_AXI_SHIFT), + MUX_CLR_SET_UPD(CLK_TOP_MEM_SUB, "mem_sub", + mem_sub_parents, CLK_CFG_0, CLK_CFG_0_SET, + CLK_CFG_0_CLR, 8, 4, + CLK_CFG_UPDATE, TOP_MUX_MEM_SUB_SHIFT), + MUX_CLR_SET_UPD(CLK_TOP_IO_NOC, "io_noc", + io_noc_parents, CLK_CFG_0, CLK_CFG_0_SET, + CLK_CFG_0_CLR, 16, 3, + CLK_CFG_UPDATE, TOP_MUX_IO_NOC_SHIFT), + MUX_CLR_SET_UPD(CLK_TOP_P_AXI, "p_axi", + shared_axi_parents, CLK_CFG_0, CLK_CFG_0_SET, + CLK_CFG_0_CLR, 24, 3, + CLK_CFG_UPDATE, TOP_MUX_PERI_AXI_SHIFT), + /* CLK_CFG_1 */ + MUX_CLR_SET_UPD(CLK_TOP_UFS_PEXTP0_AXI, "ufs_pextp0_axi", + shared_axi_parents, CLK_CFG_1, CLK_CFG_1_SET, + CLK_CFG_1_CLR, 0, 3, + CLK_CFG_UPDATE, TOP_MUX_UFS_PEXTP0_AXI_SHIFT), + MUX_CLR_SET_UPD(CLK_TOP_PEXTP1_USB_AXI, "pextp1_usb_axi", + shared_axi_parents, CLK_CFG_1, CLK_CFG_1_SET, + CLK_CFG_1_CLR, 8, 3, + CLK_CFG_UPDATE, TOP_MUX_PEXTP1_USB_AXI_SHIFT), + MUX_CLR_SET_UPD(CLK_TOP_P_FMEM_SUB, "p_fmem_sub", + shared_sub_parents, CLK_CFG_1, CLK_CFG_1_SET, + CLK_CFG_1_CLR, 16, 4, + CLK_CFG_UPDATE, TOP_MUX_PERI_FMEM_SUB_SHIFT), + MUX_CLR_SET_UPD(CLK_TOP_PEXPT0_MEM_SUB, "ufs_pexpt0_mem_sub", + shared_sub_parents, CLK_CFG_1, CLK_CFG_1_SET, + CLK_CFG_1_CLR, 24, 4, + CLK_CFG_UPDATE, TOP_MUX_UFS_PEXPT0_MEM_SUB_SHIFT), + /* CLK_CFG_2 */ + MUX_CLR_SET_UPD(CLK_TOP_PEXTP1_USB_MEM_SUB, "pextp1_usb_mem_sub", + shared_sub_parents, CLK_CFG_2, CLK_CFG_2_SET, + CLK_CFG_2_CLR, 0, 4, + CLK_CFG_UPDATE, TOP_MUX_PEXTP1_USB_MEM_SUB_SHIFT), + MUX_CLR_SET_UPD(CLK_TOP_P_NOC, "p_noc", + p_noc_parents, CLK_CFG_2, CLK_CFG_2_SET, + CLK_CFG_2_CLR, 8, 4, + CLK_CFG_UPDATE, TOP_MUX_PERI_NOC_SHIFT), + MUX_CLR_SET_UPD(CLK_TOP_EMI_N, "emi_n", + emi_parents, CLK_CFG_2, CLK_CFG_2_SET, + CLK_CFG_2_CLR, 16, 3, + CLK_CFG_UPDATE, TOP_MUX_EMI_N_SHIFT), + MUX_CLR_SET_UPD(CLK_TOP_EMI_S, "emi_s", + emi_parents, CLK_CFG_2, CLK_CFG_2_SET, + CLK_CFG_2_CLR, 24, 3, + CLK_CFG_UPDATE, TOP_MUX_EMI_S_SHIFT), + /* CLK_CFG_3 */ + MUX_CLR_SET_UPD(CLK_TOP_AP2CONN_HOST, "ap2conn_host", + ap2conn_host_parents, CLK_CFG_3, CLK_CFG_3_SET, + CLK_CFG_3_CLR, 16, 1, + CLK_CFG_UPDATE, TOP_MUX_AP2CONN_HOST_SHIFT), + MUX_CLR_SET_UPD(CLK_TOP_ATB, "atb", + atb_parents, CLK_CFG_3, CLK_CFG_3_SET, + CLK_CFG_3_CLR, 24, 2, + CLK_CFG_UPDATE, TOP_MUX_ATB_SHIFT), + /* CLK_CFG_4 */ + MUX_CLR_SET_UPD(CLK_TOP_CIRQ, "cirq", + cirq_parents, CLK_CFG_4, CLK_CFG_4_SET, + CLK_CFG_4_CLR, 0, 2, + CLK_CFG_UPDATE, TOP_MUX_CIRQ_SHIFT), + MUX_CLR_SET_UPD(CLK_TOP_PBUS_156M, "pbus_156m", + pbus_156m_parents, CLK_CFG_4, CLK_CFG_4_SET, + CLK_CFG_4_CLR, 8, 2, + CLK_CFG_UPDATE, TOP_MUX_PBUS_156M_SHIFT), + /* CLK_CFG_5 */ + MUX_CLR_SET_UPD(CLK_TOP_EFUSE, "efuse", + efuse_parents, CLK_CFG_5, CLK_CFG_5_SET, + CLK_CFG_5_CLR, 0, 1, + CLK_CFG_UPDATE, TOP_MUX_EFUSE_SHIFT), + MUX_CLR_SET_UPD(CLK_TOP_MCL3GIC, "mcu_l3gic", + mcu_l3gic_parents, CLK_CFG_5, CLK_CFG_5_SET, + CLK_CFG_5_CLR, 8, 2, + CLK_CFG_UPDATE, TOP_MUX_MCU_L3GIC_SHIFT), + MUX_CLR_SET_UPD(CLK_TOP_MCINFRA, "mcu_infra", + mcu_infra_parents, CLK_CFG_5, CLK_CFG_5_SET, + CLK_CFG_5_CLR, 16, 3, + CLK_CFG_UPDATE, TOP_MUX_MCU_INFRA_SHIFT), + MUX_CLR_SET_UPD(CLK_TOP_DSP, "dsp", + dsp_parents, CLK_CFG_5, CLK_CFG_5_SET, + CLK_CFG_5_CLR, 24, 3, + CLK_CFG_UPDATE, TOP_MUX_DSP_SHIFT), + /* CLK_CFG_6 */ + MUX_GATE_FENC_CLR_SET_UPD_FLAGS(CLK_TOP_MFG_REF, "mfg_ref", mfg_ref_parents, + NULL, ARRAY_SIZE(mfg_ref_parents), + CLK_CFG_6, CLK_CFG_6_SET, CLK_CFG_6_CLR, + 0, 1, 7, CLK_CFG_UPDATE, TOP_MUX_MFG_REF_SHIFT, + CLK_FENC_STATUS_MON_0, 7, CLK_IGNORE_UNUSED), + MUX_GATE_CLR_SET_UPD(CLK_TOP_MFG_EB, "mfg_eb", + mfg_eb_parents, CLK_CFG_6, CLK_CFG_6_SET, + CLK_CFG_6_CLR, 16, 2, + 23, CLK_CFG_UPDATE, TOP_MUX_MFG_EB_SHIFT), + MUX_GATE_HWV_FENC_CLR_SET_UPD(CLK_TOP_UART, "uart", uart_parents, + CLK_CFG_6, CLK_CFG_6_SET, CLK_CFG_6_CLR, + HWV_CG_3_DONE, HWV_CG_3_SET, HWV_CG_3_CLR, + 24, 2, 31, CLK_CFG_UPDATE, TOP_MUX_UART_SHIFT, + CLK_FENC_STATUS_MON_0, 4), + /* CLK_CFG_7 */ + MUX_GATE_HWV_FENC_CLR_SET_UPD(CLK_TOP_SPI0_BCLK, "spi0_b", spi_b_parents, + CLK_CFG_7, CLK_CFG_7_SET, CLK_CFG_7_CLR, + HWV_CG_4_DONE, HWV_CG_4_SET, HWV_CG_4_CLR, + 0, 3, 7, CLK_CFG_UPDATE, TOP_MUX_SPI0_BCLK_SHIFT, + CLK_FENC_STATUS_MON_0, 3), + MUX_GATE_HWV_FENC_CLR_SET_UPD(CLK_TOP_SPI1_BCLK, "spi1_b", spi_b_parents, + CLK_CFG_7, CLK_CFG_7_SET, CLK_CFG_7_CLR, + HWV_CG_4_DONE, HWV_CG_4_SET, HWV_CG_4_CLR, + 8, 3, 15, CLK_CFG_UPDATE, TOP_MUX_SPI1_BCLK_SHIFT, + CLK_FENC_STATUS_MON_0, 2), + MUX_GATE_HWV_FENC_CLR_SET_UPD(CLK_TOP_SPI2_BCLK, "spi2_b", spi_b_parents, + CLK_CFG_7, CLK_CFG_7_SET, CLK_CFG_7_CLR, + HWV_CG_4_DONE, HWV_CG_4_SET, HWV_CG_4_CLR, + 16, 3, 23, CLK_CFG_UPDATE, TOP_MUX_SPI2_BCLK_SHIFT, + CLK_FENC_STATUS_MON_0, 1), + MUX_GATE_HWV_FENC_CLR_SET_UPD(CLK_TOP_SPI3_BCLK, "spi3_b", spi_b_parents, + CLK_CFG_7, CLK_CFG_7_SET, CLK_CFG_7_CLR, + HWV_CG_4_DONE, HWV_CG_4_SET, HWV_CG_4_CLR, + 24, 3, 31, CLK_CFG_UPDATE1, TOP_MUX_SPI3_BCLK_SHIFT, + CLK_FENC_STATUS_MON_0, 0), + /* CLK_CFG_8 */ + MUX_GATE_HWV_FENC_CLR_SET_UPD(CLK_TOP_SPI4_BCLK, "spi4_b", spi_b_parents, + CLK_CFG_8, CLK_CFG_8_SET, CLK_CFG_8_CLR, + HWV_CG_5_DONE, HWV_CG_5_SET, HWV_CG_5_CLR, + 0, 3, 7, CLK_CFG_UPDATE1, TOP_MUX_SPI4_BCLK_SHIFT, + CLK_FENC_STATUS_MON_1, 31), + MUX_GATE_HWV_FENC_CLR_SET_UPD(CLK_TOP_SPI5_BCLK, "spi5_b", spi_b_parents, + CLK_CFG_8, CLK_CFG_8_SET, CLK_CFG_8_CLR, + HWV_CG_5_DONE, HWV_CG_5_SET, HWV_CG_5_CLR, + 8, 3, 15, CLK_CFG_UPDATE1, TOP_MUX_SPI5_BCLK_SHIFT, + CLK_FENC_STATUS_MON_1, 30), + MUX_GATE_HWV_FENC_CLR_SET_UPD(CLK_TOP_SPI6_BCLK, "spi6_b", spi_b_parents, + CLK_CFG_8, CLK_CFG_8_SET, CLK_CFG_8_CLR, + HWV_CG_5_DONE, HWV_CG_5_SET, HWV_CG_5_CLR, + 16, 3, 23, CLK_CFG_UPDATE1, TOP_MUX_SPI6_BCLK_SHIFT, + CLK_FENC_STATUS_MON_1, 29), + MUX_GATE_HWV_FENC_CLR_SET_UPD(CLK_TOP_SPI7_BCLK, "spi7_b", spi_b_parents, + CLK_CFG_8, CLK_CFG_8_SET, CLK_CFG_8_CLR, + HWV_CG_5_DONE, HWV_CG_5_SET, HWV_CG_5_CLR, + 24, 3, 31, CLK_CFG_UPDATE1, TOP_MUX_SPI7_BCLK_SHIFT, + CLK_FENC_STATUS_MON_1, 28), + /* CLK_CFG_9 */ + MUX_GATE_FENC_CLR_SET_UPD(CLK_TOP_MSDC30_1, "msdc30_1", msdc30_parents, + CLK_CFG_9, CLK_CFG_9_SET, CLK_CFG_9_CLR, + 16, 3, 23, CLK_CFG_UPDATE1, TOP_MUX_MSDC30_1_SHIFT, + CLK_FENC_STATUS_MON_1, 25), + MUX_GATE_FENC_CLR_SET_UPD(CLK_TOP_MSDC30_2, "msdc30_2", msdc30_parents, + CLK_CFG_9, CLK_CFG_9_SET, CLK_CFG_9_CLR, + 24, 3, 31, CLK_CFG_UPDATE1, TOP_MUX_MSDC30_2_SHIFT, + CLK_FENC_STATUS_MON_1, 24), + /* CLK_CFG_10 */ + MUX_GATE_FENC_CLR_SET_UPD(CLK_TOP_DISP_PWM, "disp_pwm", disp_pwm_parents, + CLK_CFG_10, CLK_CFG_10_SET, CLK_CFG_10_CLR, + 0, 3, 7, CLK_CFG_UPDATE1, TOP_MUX_DISP_PWM_SHIFT, + CLK_FENC_STATUS_MON_1, 23), + MUX_GATE_FENC_CLR_SET_UPD(CLK_TOP_USB_TOP_1P, "usb_1p", usb_1p_parents, + CLK_CFG_10, CLK_CFG_10_SET, CLK_CFG_10_CLR, + 8, 1, 15, CLK_CFG_UPDATE1, TOP_MUX_USB_TOP_1P_SHIFT, + CLK_FENC_STATUS_MON_1, 22), + MUX_GATE_FENC_CLR_SET_UPD(CLK_TOP_USB_XHCI_1P, "usb_xhci_1p", usb_1p_parents, + CLK_CFG_10, CLK_CFG_10_SET, CLK_CFG_10_CLR, + 16, 1, 23, CLK_CFG_UPDATE1, TOP_MUX_SSUSB_XHCI_1P_SHIFT, + CLK_FENC_STATUS_MON_1, 21), + MUX_GATE_FENC_CLR_SET_UPD(CLK_TOP_USB_FMCNT_P1, "usb_fmcnt_p1", usb_fmcnt_p1_parents, + CLK_CFG_10, CLK_CFG_10_SET, CLK_CFG_10_CLR, + 24, 1, 31, CLK_CFG_UPDATE1, TOP_MUX_SSUSB_FMCNT_P1_SHIFT, + CLK_FENC_STATUS_MON_1, 20), + /* CLK_CFG_11 */ + MUX_GATE_FENC_CLR_SET_UPD(CLK_TOP_I2C_P, "i2c_p", i2c_parents, + CLK_CFG_11, CLK_CFG_11_SET, CLK_CFG_11_CLR, + 0, 3, 7, CLK_CFG_UPDATE1, TOP_MUX_I2C_PERI_SHIFT, + CLK_FENC_STATUS_MON_1, 19), + MUX_GATE_FENC_CLR_SET_UPD(CLK_TOP_I2C_EAST, "i2c_east", i2c_parents, + CLK_CFG_11, CLK_CFG_11_SET, CLK_CFG_11_CLR, + 8, 3, 15, CLK_CFG_UPDATE1, TOP_MUX_I2C_EAST_SHIFT, + CLK_FENC_STATUS_MON_1, 18), + MUX_GATE_FENC_CLR_SET_UPD(CLK_TOP_I2C_WEST, "i2c_west", i2c_parents, + CLK_CFG_11, CLK_CFG_11_SET, CLK_CFG_11_CLR, + 16, 3, 23, CLK_CFG_UPDATE1, TOP_MUX_I2C_WEST_SHIFT, + CLK_FENC_STATUS_MON_1, 17), + MUX_GATE_HWV_FENC_CLR_SET_UPD(CLK_TOP_I2C_NORTH, "i2c_north", i2c_parents, + CLK_CFG_11, CLK_CFG_11_SET, CLK_CFG_11_CLR, + HWV_CG_6_DONE, HWV_CG_6_SET, HWV_CG_6_CLR, + 24, 3, 31, CLK_CFG_UPDATE1, TOP_MUX_I2C_NORTH_SHIFT, + CLK_FENC_STATUS_MON_1, 16), + /* CLK_CFG_12 */ + MUX_GATE_FENC_CLR_SET_UPD(CLK_TOP_AES_UFSFDE, "aes_ufsfde", aes_ufsfde_parents, + CLK_CFG_12, CLK_CFG_12_SET, CLK_CFG_12_CLR, + 0, 3, 7, CLK_CFG_UPDATE1, TOP_MUX_AES_UFSFDE_SHIFT, + CLK_FENC_STATUS_MON_1, 15), + MUX_GATE_FENC_CLR_SET_UPD(CLK_TOP_UFS, "ufs", ufs_parents, + CLK_CFG_12, CLK_CFG_12_SET, CLK_CFG_12_CLR, + 8, 3, 15, CLK_CFG_UPDATE1, TOP_MUX_UFS_SHIFT, + CLK_FENC_STATUS_MON_1, 14), + /* CLK_CFG_13 */ + MUX_GATE_FENC_CLR_SET_UPD(CLK_TOP_AUD_1, "aud_1", aud_1_parents, + CLK_CFG_13, CLK_CFG_13_SET, CLK_CFG_13_CLR, + 0, 1, 7, CLK_CFG_UPDATE1, TOP_MUX_AUD_1_SHIFT, + CLK_FENC_STATUS_MON_1, 11), + MUX_GATE_FENC_CLR_SET_UPD(CLK_TOP_AUD_2, "aud_2", aud_2_parents, + CLK_CFG_13, CLK_CFG_13_SET, CLK_CFG_13_CLR, + 8, 1, 15, CLK_CFG_UPDATE1, TOP_MUX_AUD_2_SHIFT, + CLK_FENC_STATUS_MON_1, 10), + MUX_GATE_FENC_CLR_SET_UPD(CLK_TOP_ADSP, "adsp", adsp_parents, + CLK_CFG_13, CLK_CFG_13_SET, CLK_CFG_13_CLR, + 16, 1, 23, CLK_CFG_UPDATE1, TOP_MUX_ADSP_SHIFT, + CLK_FENC_STATUS_MON_1, 9), + MUX_GATE_CLR_SET_UPD(CLK_TOP_ADSP_UARTHUB_B, "adsp_uarthub_b", + adsp_uarthub_b_parents, CLK_CFG_13, CLK_CFG_13_SET, + CLK_CFG_13_CLR, 24, 2, 31, + CLK_CFG_UPDATE1, TOP_MUX_ADSP_UARTHUB_B_SHIFT), + /* CLK_CFG_14 */ + MUX_GATE_FENC_CLR_SET_UPD(CLK_TOP_DPMAIF_MAIN, "dpmaif_main", dpmaif_main_parents, + CLK_CFG_14, CLK_CFG_14_SET, CLK_CFG_14_CLR, + 0, 4, 7, CLK_CFG_UPDATE1, TOP_MUX_DPMAIF_MAIN_SHIFT, + CLK_FENC_STATUS_MON_1, 7), + MUX_GATE_FENC_CLR_SET_UPD(CLK_TOP_PWM, "pwm", pwm_parents, + CLK_CFG_14, CLK_CFG_14_SET, CLK_CFG_14_CLR, + 8, 2, 15, CLK_CFG_UPDATE1, TOP_MUX_PWM_SHIFT, + CLK_FENC_STATUS_MON_1, 6), + MUX_CLR_SET_UPD(CLK_TOP_MCUPM, "mcupm", + mcupm_parents, CLK_CFG_14, CLK_CFG_14_SET, + CLK_CFG_14_CLR, 16, 3, + CLK_CFG_UPDATE1, TOP_MUX_MCUPM_SHIFT), + MUX_GATE_FENC_CLR_SET_UPD(CLK_TOP_SFLASH, "sflash", sflash_parents, + CLK_CFG_14, CLK_CFG_14_SET, CLK_CFG_14_CLR, + 24, 2, 31, CLK_CFG_UPDATE1, TOP_MUX_SFLASH_SHIFT, + CLK_FENC_STATUS_MON_1, 4), + /* CLK_CFG_15 */ + MUX_GATE_FENC_CLR_SET_UPD(CLK_TOP_IPSEAST, "ipseast", ipseast_parents, + CLK_CFG_15, CLK_CFG_15_SET, CLK_CFG_15_CLR, + 0, 3, 7, CLK_CFG_UPDATE1, TOP_MUX_IPSEAST_SHIFT, + CLK_FENC_STATUS_MON_1, 3), + MUX_GATE_FENC_CLR_SET_UPD(CLK_TOP_TL, "tl", tl_parents, + CLK_CFG_15, CLK_CFG_15_SET, CLK_CFG_15_CLR, + 16, 2, 23, CLK_CFG_UPDATE2, TOP_MUX_TL_SHIFT, + CLK_FENC_STATUS_MON_1, 1), + MUX_GATE_FENC_CLR_SET_UPD(CLK_TOP_TL_P1, "tl_p1", tl_parents, + CLK_CFG_15, CLK_CFG_15_SET, CLK_CFG_15_CLR, + 24, 2, 31, CLK_CFG_UPDATE2, TOP_MUX_TL_P1_SHIFT, + CLK_FENC_STATUS_MON_1, 0), + /* CLK_CFG_16 */ + MUX_GATE_FENC_CLR_SET_UPD(CLK_TOP_TL_P2, "tl_p2", tl_parents, + CLK_CFG_16, CLK_CFG_16_SET, CLK_CFG_16_CLR, + 0, 2, 7, CLK_CFG_UPDATE2, TOP_MUX_TL_P2_SHIFT, + CLK_FENC_STATUS_MON_2, 31), + MUX_CLR_SET_UPD(CLK_TOP_EMI_INTERFACE_546, "emi_interface_546", + md_emi_parents, CLK_CFG_16, CLK_CFG_16_SET, + CLK_CFG_16_CLR, 8, 1, + CLK_CFG_UPDATE2, TOP_MUX_EMI_INTERFACE_546_SHIFT), + MUX_CLR_SET_UPD(CLK_TOP_SDF, "sdf", + sdf_parents, CLK_CFG_16, CLK_CFG_16_SET, + CLK_CFG_16_CLR, 16, 3, + CLK_CFG_UPDATE2, TOP_MUX_SDF_SHIFT), + MUX_GATE_HWV_FENC_CLR_SET_UPD(CLK_TOP_UARTHUB_BCLK, "uarthub_b", uarthub_b_parents, + CLK_CFG_16, CLK_CFG_16_SET, CLK_CFG_16_CLR, + HWV_CG_7_DONE, HWV_CG_7_SET, HWV_CG_7_CLR, + 24, 2, 31, CLK_CFG_UPDATE2, TOP_MUX_UARTHUB_BCLK_SHIFT, + CLK_FENC_STATUS_MON_2, 28), + /* CLK_CFG_17 */ + MUX_CLR_SET_UPD(CLK_TOP_DPSW_CMP_26M, "dpsw_cmp_26m", + dpsw_cmp_26m_parents, CLK_CFG_17, CLK_CFG_17_SET, + CLK_CFG_17_CLR, 0, 1, + CLK_CFG_UPDATE2, TOP_MUX_DPSW_CMP_26M_SHIFT), + MUX_CLR_SET_UPD(CLK_TOP_SMAP, "smap", + smapparents, CLK_CFG_17, CLK_CFG_17_SET, + CLK_CFG_17_CLR, 8, 1, + CLK_CFG_UPDATE2, TOP_MUX_SMAPCK_SHIFT), + MUX_CLR_SET_UPD(CLK_TOP_SSR_PKA, "ssr_pka", + ssr_parents, CLK_CFG_17, CLK_CFG_17_SET, + CLK_CFG_17_CLR, 16, 3, + CLK_CFG_UPDATE2, TOP_MUX_SSR_PKA_SHIFT), + MUX_CLR_SET_UPD(CLK_TOP_SSR_DMA, "ssr_dma", + ssr_parents, CLK_CFG_17, CLK_CFG_17_SET, + CLK_CFG_17_CLR, 24, 3, + CLK_CFG_UPDATE2, TOP_MUX_SSR_DMA_SHIFT), + /* CLK_CFG_18 */ + MUX_CLR_SET_UPD(CLK_TOP_SSR_KDF, "ssr_kdf", + ssr_kdf_parents, CLK_CFG_18, CLK_CFG_18_SET, + CLK_CFG_18_CLR, 0, 2, + CLK_CFG_UPDATE2, TOP_MUX_SSR_KDF_SHIFT), + MUX_CLR_SET_UPD(CLK_TOP_SSR_RNG, "ssr_rng", + ssr_rng_parents, CLK_CFG_18, CLK_CFG_18_SET, + CLK_CFG_18_CLR, 8, 2, + CLK_CFG_UPDATE2, TOP_MUX_SSR_RNG_SHIFT), + MUX_CLR_SET_UPD(CLK_TOP_SPU0, "spu0", + spu_parents, CLK_CFG_18, CLK_CFG_18_SET, + CLK_CFG_18_CLR, 16, 3, + CLK_CFG_UPDATE2, TOP_MUX_SPU0_SHIFT), + MUX_CLR_SET_UPD(CLK_TOP_SPU1, "spu1", + spu_parents, CLK_CFG_18, CLK_CFG_18_SET, + CLK_CFG_18_CLR, 24, 3, + CLK_CFG_UPDATE2, TOP_MUX_SPU1_SHIFT), + /* CLK_CFG_19 */ + MUX_CLR_SET_UPD(CLK_TOP_DXCC, "dxcc", + dxcc_parents, CLK_CFG_19, CLK_CFG_19_SET, + CLK_CFG_19_CLR, 0, 2, + CLK_CFG_UPDATE2, TOP_MUX_DXCC_SHIFT), +}; + +static const struct mtk_composite top_aud_divs[] = { + /* CLK_AUDDIV_2 */ + MUX_DIV_GATE(CLK_TOP_APLL_I2SIN0, "apll_i2sin0_m", apll_m_parents, + CLK_AUDDIV_0, 16, 1, CLK_AUDDIV_2, 0, 8, CLK_AUDDIV_0, 0), + MUX_DIV_GATE(CLK_TOP_APLL_I2SIN1, "apll_i2sin1_m", apll_m_parents, + CLK_AUDDIV_0, 17, 1, CLK_AUDDIV_2, 8, 8, CLK_AUDDIV_0, 1), + MUX_DIV_GATE(CLK_TOP_APLL_I2SIN2, "apll_i2sin2_m", apll_m_parents, + CLK_AUDDIV_0, 18, 1, CLK_AUDDIV_2, 16, 8, CLK_AUDDIV_0, 2), + MUX_DIV_GATE(CLK_TOP_APLL_I2SIN3, "apll_i2sin3_m", apll_m_parents, + CLK_AUDDIV_0, 19, 1, CLK_AUDDIV_2, 24, 8, CLK_AUDDIV_0, 3), + /* CLK_AUDDIV_3 */ + MUX_DIV_GATE(CLK_TOP_APLL_I2SIN4, "apll_i2sin4_m", apll_m_parents, + CLK_AUDDIV_0, 20, 1, CLK_AUDDIV_3, 0, 8, CLK_AUDDIV_0, 4), + MUX_DIV_GATE(CLK_TOP_APLL_I2SIN6, "apll_i2sin6_m", apll_m_parents, + CLK_AUDDIV_0, 21, 1, CLK_AUDDIV_3, 8, 8, CLK_AUDDIV_0, 5), + MUX_DIV_GATE(CLK_TOP_APLL_I2SOUT0, "apll_i2sout0_m", apll_m_parents, + CLK_AUDDIV_0, 22, 1, CLK_AUDDIV_3, 16, 8, CLK_AUDDIV_0, 6), + MUX_DIV_GATE(CLK_TOP_APLL_I2SOUT1, "apll_i2sout1_m", apll_m_parents, + CLK_AUDDIV_0, 23, 1, CLK_AUDDIV_3, 24, 8, CLK_AUDDIV_0, 7), + /* CLK_AUDDIV_4 */ + MUX_DIV_GATE(CLK_TOP_APLL_I2SOUT2, "apll_i2sout2_m", apll_m_parents, + CLK_AUDDIV_0, 24, 1, CLK_AUDDIV_4, 0, 8, CLK_AUDDIV_0, 8), + MUX_DIV_GATE(CLK_TOP_APLL_I2SOUT3, "apll_i2sout3_m", apll_m_parents, + CLK_AUDDIV_0, 25, 1, CLK_AUDDIV_4, 8, 8, CLK_AUDDIV_0, 9), + MUX_DIV_GATE(CLK_TOP_APLL_I2SOUT4, "apll_i2sout4_m", apll_m_parents, + CLK_AUDDIV_0, 26, 1, CLK_AUDDIV_4, 16, 8, CLK_AUDDIV_0, 10), + MUX_DIV_GATE(CLK_TOP_APLL_I2SOUT6, "apll_i2sout6_m", apll_m_parents, + CLK_AUDDIV_0, 27, 1, CLK_AUDDIV_4, 24, 8, CLK_AUDDIV_0, 11), + /* CLK_AUDDIV_5 */ + MUX_DIV_GATE(CLK_TOP_APLL_FMI2S, "apll_fmi2s_m", apll_m_parents, + CLK_AUDDIV_0, 28, 1, CLK_AUDDIV_5, 0, 8, CLK_AUDDIV_0, 12), + MUX(CLK_TOP_APLL_TDMOUT, "apll_tdmout_m", + apll_m_parents, CLK_AUDDIV_0, 29, 1), + DIV_GATE(CLK_TOP_APLL12_DIV_TDMOUT_M, "apll12_div_tdmout_m", + "apll_tdmout_m", CLK_AUDDIV_0, + 13, CLK_AUDDIV_5, 8, 8), + DIV_GATE(CLK_TOP_APLL12_DIV_TDMOUT_B, "apll12_div_tdmout_b", + "apll_tdmout_m", CLK_AUDDIV_0, + 14, CLK_AUDDIV_5, 8, 16), +}; + +static const struct mtk_clk_desc topck_desc = { + .factor_clks = top_divs, + .num_factor_clks = ARRAY_SIZE(top_divs), + .mux_clks = top_muxes, + .num_mux_clks = ARRAY_SIZE(top_muxes), + .composite_clks = top_aud_divs, + .num_composite_clks = ARRAY_SIZE(top_aud_divs) +}; + +static const struct of_device_id of_match_clk_mt8196_ck[] = { + { .compatible = "mediatek,mt8196-topckgen", .data = &topck_desc }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(of, of_match_clk_mt8196_ck); + +static struct platform_driver clk_mt8196_topck_drv = { + .probe = mtk_clk_simple_probe, + .remove = mtk_clk_simple_remove, + .driver = { + .name = "clk-mt8196-topck", + .of_match_table = of_match_clk_mt8196_ck, + }, +}; + +MODULE_DESCRIPTION("MediaTek MT8196 top clock generators driver"); +module_platform_driver(clk_mt8196_topck_drv); +MODULE_LICENSE("GPL"); diff --git a/drivers/clk/mediatek/clk-mt8196-topckgen2.c b/drivers/clk/mediatek/clk-mt8196-topckgen2.c new file mode 100644 index 000000000000..6df93d7fbf91 --- /dev/null +++ b/drivers/clk/mediatek/clk-mt8196-topckgen2.c @@ -0,0 +1,568 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2025 MediaTek Inc. + * Guangjie Song <guangjie.song@mediatek.com> + * Copyright (c) 2025 Collabora Ltd. + * Laura Nao <laura.nao@collabora.com> + */ +#include <dt-bindings/clock/mediatek,mt8196-clock.h> + +#include <linux/clk.h> +#include <linux/module.h> +#include <linux/of.h> +#include <linux/of_address.h> +#include <linux/of_device.h> +#include <linux/platform_device.h> + +#include "clk-mtk.h" +#include "clk-mux.h" + +/* MUX SEL REG */ +#define CKSYS2_CLK_CFG_UPDATE 0x0004 +#define CKSYS2_CLK_CFG_0 0x0010 +#define CKSYS2_CLK_CFG_0_SET 0x0014 +#define CKSYS2_CLK_CFG_0_CLR 0x0018 +#define CKSYS2_CLK_CFG_1 0x0020 +#define CKSYS2_CLK_CFG_1_SET 0x0024 +#define CKSYS2_CLK_CFG_1_CLR 0x0028 +#define CKSYS2_CLK_CFG_2 0x0030 +#define CKSYS2_CLK_CFG_2_SET 0x0034 +#define CKSYS2_CLK_CFG_2_CLR 0x0038 +#define CKSYS2_CLK_CFG_3 0x0040 +#define CKSYS2_CLK_CFG_3_SET 0x0044 +#define CKSYS2_CLK_CFG_3_CLR 0x0048 +#define CKSYS2_CLK_CFG_4 0x0050 +#define CKSYS2_CLK_CFG_4_SET 0x0054 +#define CKSYS2_CLK_CFG_4_CLR 0x0058 +#define CKSYS2_CLK_CFG_5 0x0060 +#define CKSYS2_CLK_CFG_5_SET 0x0064 +#define CKSYS2_CLK_CFG_5_CLR 0x0068 +#define CKSYS2_CLK_CFG_6 0x0070 +#define CKSYS2_CLK_CFG_6_SET 0x0074 +#define CKSYS2_CLK_CFG_6_CLR 0x0078 +#define CKSYS2_CLK_FENC_STATUS_MON_0 0x0174 + +/* MUX SHIFT */ +#define TOP_MUX_SENINF0_SHIFT 0 +#define TOP_MUX_SENINF1_SHIFT 1 +#define TOP_MUX_SENINF2_SHIFT 2 +#define TOP_MUX_SENINF3_SHIFT 3 +#define TOP_MUX_SENINF4_SHIFT 4 +#define TOP_MUX_SENINF5_SHIFT 5 +#define TOP_MUX_IMG1_SHIFT 6 +#define TOP_MUX_IPE_SHIFT 7 +#define TOP_MUX_CAM_SHIFT 8 +#define TOP_MUX_CAMTM_SHIFT 9 +#define TOP_MUX_DPE_SHIFT 10 +#define TOP_MUX_VDEC_SHIFT 11 +#define TOP_MUX_CCUSYS_SHIFT 12 +#define TOP_MUX_CCUTM_SHIFT 13 +#define TOP_MUX_VENC_SHIFT 14 +#define TOP_MUX_DVO_SHIFT 15 +#define TOP_MUX_DVO_FAVT_SHIFT 16 +#define TOP_MUX_DP1_SHIFT 17 +#define TOP_MUX_DP0_SHIFT 18 +#define TOP_MUX_DISP_SHIFT 19 +#define TOP_MUX_MDP_SHIFT 20 +#define TOP_MUX_MMINFRA_SHIFT 21 +#define TOP_MUX_MMINFRA_SNOC_SHIFT 22 +#define TOP_MUX_MMUP_SHIFT 23 +#define TOP_MUX_MMINFRA_AO_SHIFT 26 + +/* HW Voter REG */ +#define HWV_CG_30_SET 0x0058 +#define HWV_CG_30_CLR 0x005c +#define HWV_CG_30_DONE 0x2c2c + +#define MM_HWV_CG_30_SET 0x00f0 +#define MM_HWV_CG_30_CLR 0x00f4 +#define MM_HWV_CG_30_DONE 0x2c78 +#define MM_HWV_CG_31_SET 0x00f8 +#define MM_HWV_CG_31_CLR 0x00fc +#define MM_HWV_CG_31_DONE 0x2c7c +#define MM_HWV_CG_32_SET 0x0100 +#define MM_HWV_CG_32_CLR 0x0104 +#define MM_HWV_CG_32_DONE 0x2c80 +#define MM_HWV_CG_33_SET 0x0108 +#define MM_HWV_CG_33_CLR 0x010c +#define MM_HWV_CG_33_DONE 0x2c84 +#define MM_HWV_CG_34_SET 0x0110 +#define MM_HWV_CG_34_CLR 0x0114 +#define MM_HWV_CG_34_DONE 0x2c88 +#define MM_HWV_CG_35_SET 0x0118 +#define MM_HWV_CG_35_CLR 0x011c +#define MM_HWV_CG_35_DONE 0x2c8c +#define MM_HWV_CG_36_SET 0x0120 +#define MM_HWV_CG_36_CLR 0x0124 +#define MM_HWV_CG_36_DONE 0x2c90 +#define MM_HWV_MUX_UPDATE_31_0 0x0240 + +static const struct mtk_fixed_factor top_divs[] = { + FACTOR(CLK_TOP2_MAINPLL2_D2, "mainpll2_d2", "mainpll2", 1, 2), + FACTOR(CLK_TOP2_MAINPLL2_D3, "mainpll2_d3", "mainpll2", 1, 3), + FACTOR(CLK_TOP2_MAINPLL2_D4, "mainpll2_d4", "mainpll2", 1, 4), + FACTOR(CLK_TOP2_MAINPLL2_D4_D2, "mainpll2_d4_d2", "mainpll2", 1, 8), + FACTOR(CLK_TOP2_MAINPLL2_D4_D4, "mainpll2_d4_d4", "mainpll2", 1, 16), + FACTOR(CLK_TOP2_MAINPLL2_D5, "mainpll2_d5", "mainpll2", 1, 5), + FACTOR(CLK_TOP2_MAINPLL2_D5_D2, "mainpll2_d5_d2", "mainpll2", 1, 10), + FACTOR(CLK_TOP2_MAINPLL2_D6, "mainpll2_d6", "mainpll2", 1, 6), + FACTOR(CLK_TOP2_MAINPLL2_D6_D2, "mainpll2_d6_d2", "mainpll2", 1, 12), + FACTOR(CLK_TOP2_MAINPLL2_D7, "mainpll2_d7", "mainpll2", 1, 7), + FACTOR(CLK_TOP2_MAINPLL2_D7_D2, "mainpll2_d7_d2", "mainpll2", 1, 14), + FACTOR(CLK_TOP2_MAINPLL2_D9, "mainpll2_d9", "mainpll2", 1, 9), + FACTOR(CLK_TOP2_UNIVPLL2_D3, "univpll2_d3", "univpll2", 1, 3), + FACTOR(CLK_TOP2_UNIVPLL2_D4, "univpll2_d4", "univpll2", 1, 4), + FACTOR(CLK_TOP2_UNIVPLL2_D4_D2, "univpll2_d4_d2", "univpll2", 1, 8), + FACTOR(CLK_TOP2_UNIVPLL2_D5, "univpll2_d5", "univpll2", 1, 5), + FACTOR(CLK_TOP2_UNIVPLL2_D5_D2, "univpll2_d5_d2", "univpll2", 1, 10), + FACTOR(CLK_TOP2_UNIVPLL2_D6, "univpll2_d6", "univpll2", 1, 6), + FACTOR(CLK_TOP2_UNIVPLL2_D6_D2, "univpll2_d6_d2", "univpll2", 1, 12), + FACTOR(CLK_TOP2_UNIVPLL2_D6_D4, "univpll2_d6_d4", "univpll2", 1, 24), + FACTOR(CLK_TOP2_UNIVPLL2_D7, "univpll2_d7", "univpll2", 1, 7), + FACTOR(CLK_TOP2_IMGPLL_D2, "imgpll_d2", "imgpll", 1, 2), + FACTOR(CLK_TOP2_IMGPLL_D4, "imgpll_d4", "imgpll", 1, 4), + FACTOR(CLK_TOP2_IMGPLL_D5, "imgpll_d5", "imgpll", 1, 5), + FACTOR(CLK_TOP2_IMGPLL_D5_D2, "imgpll_d5_d2", "imgpll", 1, 10), + FACTOR(CLK_TOP2_MMPLL2_D3, "mmpll2_d3", "mmpll2", 1, 3), + FACTOR(CLK_TOP2_MMPLL2_D4, "mmpll2_d4", "mmpll2", 1, 4), + FACTOR(CLK_TOP2_MMPLL2_D4_D2, "mmpll2_d4_d2", "mmpll2", 1, 8), + FACTOR(CLK_TOP2_MMPLL2_D5, "mmpll2_d5", "mmpll2", 1, 5), + FACTOR(CLK_TOP2_MMPLL2_D5_D2, "mmpll2_d5_d2", "mmpll2", 1, 10), + FACTOR(CLK_TOP2_MMPLL2_D6, "mmpll2_d6", "mmpll2", 1, 6), + FACTOR(CLK_TOP2_MMPLL2_D6_D2, "mmpll2_d6_d2", "mmpll2", 1, 12), + FACTOR(CLK_TOP2_MMPLL2_D7, "mmpll2_d7", "mmpll2", 1, 7), + FACTOR(CLK_TOP2_MMPLL2_D9, "mmpll2_d9", "mmpll2", 1, 9), + FACTOR(CLK_TOP2_TVDPLL1_D4, "tvdpll1_d4", "tvdpll1", 1, 4), + FACTOR(CLK_TOP2_TVDPLL1_D8, "tvdpll1_d8", "tvdpll1", 1, 8), + FACTOR(CLK_TOP2_TVDPLL1_D16, "tvdpll1_d16", "tvdpll1", 1, 16), + FACTOR(CLK_TOP2_TVDPLL2_D2, "tvdpll2_d2", "tvdpll2", 1, 2), + FACTOR(CLK_TOP2_TVDPLL2_D4, "tvdpll2_d4", "tvdpll2", 1, 4), + FACTOR(CLK_TOP2_TVDPLL2_D8, "tvdpll2_d8", "tvdpll2", 1, 8), + FACTOR(CLK_TOP2_TVDPLL2_D16, "tvdpll2_d16", "tvdpll2", 92, 1473), + FACTOR(CLK_TOP2_TVDPLL3_D2, "tvdpll3_d2", "tvdpll3", 1, 2), + FACTOR(CLK_TOP2_TVDPLL3_D4, "tvdpll3_d4", "tvdpll3", 1, 4), + FACTOR(CLK_TOP2_TVDPLL3_D8, "tvdpll3_d8", "tvdpll3", 1, 8), + FACTOR(CLK_TOP2_TVDPLL3_D16, "tvdpll3_d16", "tvdpll3", 92, 1473), +}; + +static const char * const seninf_parents[] = { + "clk26m", + "ck_osc_d10", + "ck_osc_d8", + "ck_osc_d5", + "ck_osc_d4", + "univpll2_d6_d2", + "mainpll2_d9", + "ck_osc_d2", + "mainpll2_d4_d2", + "univpll2_d4_d2", + "mmpll2_d4_d2", + "univpll2_d7", + "mainpll2_d6", + "mmpll2_d7", + "univpll2_d6", + "univpll2_d5" +}; + +static const char * const img1_parents[] = { + "clk26m", + "ck_osc_d4", + "ck_osc_d3", + "mmpll2_d6_d2", + "ck_osc_d2", + "imgpll_d5_d2", + "mmpll2_d5_d2", + "univpll2_d4_d2", + "mmpll2_d4_d2", + "mmpll2_d7", + "univpll2_d6", + "mmpll2_d6", + "univpll2_d5", + "mmpll2_d5", + "univpll2_d4", + "imgpll_d4" +}; + +static const char * const ipe_parents[] = { + "clk26m", + "ck_osc_d4", + "ck_osc_d3", + "ck_osc_d2", + "univpll2_d6", + "mmpll2_d6", + "univpll2_d5", + "imgpll_d5", + "ck_mainpll_d4", + "mmpll2_d5", + "imgpll_d4" +}; + +static const char * const cam_parents[] = { + "clk26m", + "ck_osc_d10", + "ck_osc_d4", + "ck_osc_d3", + "ck_osc_d2", + "mmpll2_d5_d2", + "univpll2_d4_d2", + "univpll2_d7", + "mmpll2_d7", + "univpll2_d6", + "mmpll2_d6", + "univpll2_d5", + "mmpll2_d5", + "univpll2_d4", + "imgpll_d4", + "mmpll2_d4" +}; + +static const char * const camtm_parents[] = { + "clk26m", + "univpll2_d6_d4", + "ck_osc_d4", + "ck_osc_d3", + "univpll2_d6_d2" +}; + +static const char * const dpe_parents[] = { + "clk26m", + "mmpll2_d5_d2", + "univpll2_d4_d2", + "mmpll2_d7", + "univpll2_d6", + "mmpll2_d6", + "univpll2_d5", + "mmpll2_d5", + "imgpll_d4", + "mmpll2_d4" +}; + +static const char * const vdec_parents[] = { + "clk26m", + "ck_mainpll_d5_d2", + "mainpll2_d4_d4", + "mainpll2_d7_d2", + "mainpll2_d6_d2", + "mainpll2_d5_d2", + "mainpll2_d9", + "mainpll2_d4_d2", + "mainpll2_d7", + "mainpll2_d6", + "univpll2_d6", + "mainpll2_d5", + "mainpll2_d4", + "imgpll_d2" +}; + +static const char * const ccusys_parents[] = { + "clk26m", + "ck_osc_d4", + "ck_osc_d3", + "ck_osc_d2", + "mmpll2_d5_d2", + "univpll2_d4_d2", + "mmpll2_d7", + "univpll2_d6", + "mmpll2_d6", + "univpll2_d5", + "mainpll2_d4", + "mainpll2_d3", + "univpll2_d3" +}; + +static const char * const ccutm_parents[] = { + "clk26m", + "univpll2_d6_d4", + "ck_osc_d4", + "ck_osc_d3", + "univpll2_d6_d2" +}; + +static const char * const venc_parents[] = { + "clk26m", + "mainpll2_d5_d2", + "univpll2_d5_d2", + "mainpll2_d4_d2", + "mmpll2_d9", + "univpll2_d4_d2", + "mmpll2_d4_d2", + "mainpll2_d6", + "univpll2_d6", + "mainpll2_d5", + "mmpll2_d6", + "univpll2_d5", + "mainpll2_d4", + "univpll2_d4", + "univpll2_d3" +}; + +static const char * const dp1_parents[] = { + "clk26m", + "tvdpll2_d16", + "tvdpll2_d8", + "tvdpll2_d4", + "tvdpll2_d2" +}; + +static const char * const dp0_parents[] = { + "clk26m", + "tvdpll1_d16", + "tvdpll1_d8", + "tvdpll1_d4", + "ck_tvdpll1_d2" +}; + +static const char * const disp_parents[] = { + "clk26m", + "ck_mainpll_d5_d2", + "ck_mainpll_d4_d2", + "ck_mainpll_d6", + "mainpll2_d5", + "mmpll2_d6", + "mainpll2_d4", + "univpll2_d4", + "mainpll2_d3" +}; + +static const char * const mdp_parents[] = { + "clk26m", + "ck_mainpll_d5_d2", + "mainpll2_d5_d2", + "mmpll2_d6_d2", + "mainpll2_d9", + "mainpll2_d4_d2", + "mainpll2_d7", + "mainpll2_d6", + "mainpll2_d5", + "mmpll2_d6", + "mainpll2_d4", + "univpll2_d4", + "mainpll2_d3" +}; + +static const char * const mminfra_parents[] = { + "clk26m", + "ck_osc_d4", + "ck_mainpll_d7_d2", + "ck_mainpll_d5_d2", + "ck_mainpll_d9", + "mmpll2_d6_d2", + "mainpll2_d4_d2", + "ck_mainpll_d6", + "univpll2_d6", + "mainpll2_d5", + "mmpll2_d6", + "univpll2_d5", + "mainpll2_d4", + "univpll2_d4", + "mainpll2_d3", + "univpll2_d3" +}; + +static const char * const mminfra_snoc_parents[] = { + "clk26m", + "ck_osc_d4", + "ck_mainpll_d7_d2", + "ck_mainpll_d9", + "ck_mainpll_d7", + "ck_mainpll_d6", + "mmpll2_d4_d2", + "ck_mainpll_d5", + "ck_mainpll_d4", + "univpll2_d4", + "mmpll2_d4", + "mainpll2_d3", + "univpll2_d3", + "mmpll2_d3", + "mainpll2_d2" +}; + +static const char * const mmup_parents[] = { + "clk26m", + "mainpll2_d6", + "mainpll2_d5", + "ck_osc_d2", + "ck_osc", + "ck_mainpll_d4", + "univpll2_d4", + "mainpll2_d3" +}; + +static const char * const mminfra_ao_parents[] = { + "clk26m", + "ck_osc_d4", + "ck_mainpll_d3" +}; + +static const char * const dvo_parents[] = { + "clk26m", + "tvdpll3_d16", + "tvdpll3_d8", + "tvdpll3_d4", + "tvdpll3_d2" +}; + +static const char * const dvo_favt_parents[] = { + "clk26m", + "tvdpll3_d16", + "tvdpll3_d8", + "tvdpll3_d4", + "vlp_apll1", + "vlp_apll2", + "tvdpll3_d2" +}; + +static const struct mtk_mux top_muxes[] = { + /* CKSYS2_CLK_CFG_0 */ + MUX_GATE_HWV_FENC_CLR_SET_UPD(CLK_TOP2_SENINF0, "seninf0", seninf_parents, + CKSYS2_CLK_CFG_0, CKSYS2_CLK_CFG_0_SET, CKSYS2_CLK_CFG_0_CLR, + MM_HWV_CG_30_DONE, MM_HWV_CG_30_SET, MM_HWV_CG_30_CLR, + 0, 4, 7, CKSYS2_CLK_CFG_UPDATE, TOP_MUX_SENINF0_SHIFT, + CKSYS2_CLK_FENC_STATUS_MON_0, 31), + MUX_GATE_HWV_FENC_CLR_SET_UPD(CLK_TOP2_SENINF1, "seninf1", seninf_parents, + CKSYS2_CLK_CFG_0, CKSYS2_CLK_CFG_0_SET, CKSYS2_CLK_CFG_0_CLR, + MM_HWV_CG_30_DONE, MM_HWV_CG_30_SET, MM_HWV_CG_30_CLR, + 8, 4, 15, CKSYS2_CLK_CFG_UPDATE, TOP_MUX_SENINF1_SHIFT, + CKSYS2_CLK_FENC_STATUS_MON_0, 30), + MUX_GATE_HWV_FENC_CLR_SET_UPD(CLK_TOP2_SENINF2, "seninf2", seninf_parents, + CKSYS2_CLK_CFG_0, CKSYS2_CLK_CFG_0_SET, CKSYS2_CLK_CFG_0_CLR, + MM_HWV_CG_30_DONE, MM_HWV_CG_30_SET, MM_HWV_CG_30_CLR, + 16, 4, 23, CKSYS2_CLK_CFG_UPDATE, TOP_MUX_SENINF2_SHIFT, + CKSYS2_CLK_FENC_STATUS_MON_0, 29), + MUX_GATE_HWV_FENC_CLR_SET_UPD(CLK_TOP2_SENINF3, "seninf3", seninf_parents, + CKSYS2_CLK_CFG_0, CKSYS2_CLK_CFG_0_SET, CKSYS2_CLK_CFG_0_CLR, + MM_HWV_CG_30_DONE, MM_HWV_CG_30_SET, MM_HWV_CG_30_CLR, + 24, 4, 31, CKSYS2_CLK_CFG_UPDATE, TOP_MUX_SENINF3_SHIFT, + CKSYS2_CLK_FENC_STATUS_MON_0, 28), + /* CKSYS2_CLK_CFG_1 */ + MUX_GATE_HWV_FENC_CLR_SET_UPD(CLK_TOP2_SENINF4, "seninf4", seninf_parents, + CKSYS2_CLK_CFG_1, CKSYS2_CLK_CFG_1_SET, CKSYS2_CLK_CFG_1_CLR, + MM_HWV_CG_31_DONE, MM_HWV_CG_31_SET, MM_HWV_CG_31_CLR, + 0, 4, 7, CKSYS2_CLK_CFG_UPDATE, TOP_MUX_SENINF4_SHIFT, + CKSYS2_CLK_FENC_STATUS_MON_0, 27), + MUX_GATE_HWV_FENC_CLR_SET_UPD(CLK_TOP2_SENINF5, "seninf5", seninf_parents, + CKSYS2_CLK_CFG_1, CKSYS2_CLK_CFG_1_SET, CKSYS2_CLK_CFG_1_CLR, + MM_HWV_CG_31_DONE, MM_HWV_CG_31_SET, MM_HWV_CG_31_CLR, + 8, 4, 15, CKSYS2_CLK_CFG_UPDATE, TOP_MUX_SENINF5_SHIFT, + CKSYS2_CLK_FENC_STATUS_MON_0, 26), + MUX_GATE_HWV_FENC_CLR_SET_UPD(CLK_TOP2_IMG1, "img1", img1_parents, + CKSYS2_CLK_CFG_1, CKSYS2_CLK_CFG_1_SET, CKSYS2_CLK_CFG_1_CLR, + MM_HWV_CG_31_DONE, MM_HWV_CG_31_SET, MM_HWV_CG_31_CLR, + 16, 4, 23, CKSYS2_CLK_CFG_UPDATE, TOP_MUX_IMG1_SHIFT, + CKSYS2_CLK_FENC_STATUS_MON_0, 25), + MUX_GATE_HWV_FENC_CLR_SET_UPD(CLK_TOP2_IPE, "ipe", ipe_parents, + CKSYS2_CLK_CFG_1, CKSYS2_CLK_CFG_1_SET, CKSYS2_CLK_CFG_1_CLR, + MM_HWV_CG_31_DONE, MM_HWV_CG_31_SET, MM_HWV_CG_31_CLR, + 24, 4, 31, CKSYS2_CLK_CFG_UPDATE, TOP_MUX_IPE_SHIFT, + CKSYS2_CLK_FENC_STATUS_MON_0, 24), + /* CKSYS2_CLK_CFG_2 */ + MUX_GATE_HWV_FENC_CLR_SET_UPD(CLK_TOP2_CAM, "cam", cam_parents, + CKSYS2_CLK_CFG_2, CKSYS2_CLK_CFG_2_SET, CKSYS2_CLK_CFG_2_CLR, + MM_HWV_CG_32_DONE, MM_HWV_CG_32_SET, MM_HWV_CG_32_CLR, + 0, 4, 7, CKSYS2_CLK_CFG_UPDATE, TOP_MUX_CAM_SHIFT, + CKSYS2_CLK_FENC_STATUS_MON_0, 23), + MUX_GATE_HWV_FENC_CLR_SET_UPD(CLK_TOP2_CAMTM, "camtm", camtm_parents, + CKSYS2_CLK_CFG_2, CKSYS2_CLK_CFG_2_SET, CKSYS2_CLK_CFG_2_CLR, + MM_HWV_CG_32_DONE, MM_HWV_CG_32_SET, MM_HWV_CG_32_CLR, + 8, 3, 15, CKSYS2_CLK_CFG_UPDATE, TOP_MUX_CAMTM_SHIFT, + CKSYS2_CLK_FENC_STATUS_MON_0, 22), + MUX_GATE_HWV_FENC_CLR_SET_UPD(CLK_TOP2_DPE, "dpe", dpe_parents, + CKSYS2_CLK_CFG_2, CKSYS2_CLK_CFG_2_SET, CKSYS2_CLK_CFG_2_CLR, + MM_HWV_CG_32_DONE, MM_HWV_CG_32_SET, MM_HWV_CG_32_CLR, + 16, 4, 23, CKSYS2_CLK_CFG_UPDATE, TOP_MUX_DPE_SHIFT, + CKSYS2_CLK_FENC_STATUS_MON_0, 21), + MUX_GATE_HWV_FENC_CLR_SET_UPD(CLK_TOP2_VDEC, "vdec", vdec_parents, + CKSYS2_CLK_CFG_2, CKSYS2_CLK_CFG_2_SET, CKSYS2_CLK_CFG_2_CLR, + MM_HWV_CG_32_DONE, MM_HWV_CG_32_SET, MM_HWV_CG_32_CLR, + 24, 4, 31, CKSYS2_CLK_CFG_UPDATE, TOP_MUX_VDEC_SHIFT, + CKSYS2_CLK_FENC_STATUS_MON_0, 20), + /* CKSYS2_CLK_CFG_3 */ + MUX_GATE_HWV_FENC_CLR_SET_UPD(CLK_TOP2_CCUSYS, "ccusys", ccusys_parents, + CKSYS2_CLK_CFG_3, CKSYS2_CLK_CFG_3_SET, CKSYS2_CLK_CFG_3_CLR, + MM_HWV_CG_33_DONE, MM_HWV_CG_33_SET, MM_HWV_CG_33_CLR, + 0, 4, 7, CKSYS2_CLK_CFG_UPDATE, TOP_MUX_CCUSYS_SHIFT, + CKSYS2_CLK_FENC_STATUS_MON_0, 19), + MUX_GATE_HWV_FENC_CLR_SET_UPD(CLK_TOP2_CCUTM, "ccutm", ccutm_parents, + CKSYS2_CLK_CFG_3, CKSYS2_CLK_CFG_3_SET, CKSYS2_CLK_CFG_3_CLR, + MM_HWV_CG_33_DONE, MM_HWV_CG_33_SET, MM_HWV_CG_33_CLR, + 8, 3, 15, CKSYS2_CLK_CFG_UPDATE, TOP_MUX_CCUTM_SHIFT, + CKSYS2_CLK_FENC_STATUS_MON_0, 18), + MUX_GATE_HWV_FENC_CLR_SET_UPD(CLK_TOP2_VENC, "venc", venc_parents, + CKSYS2_CLK_CFG_3, CKSYS2_CLK_CFG_3_SET, CKSYS2_CLK_CFG_3_CLR, + MM_HWV_CG_33_DONE, MM_HWV_CG_33_SET, MM_HWV_CG_33_CLR, + 16, 4, 23, CKSYS2_CLK_CFG_UPDATE, TOP_MUX_VENC_SHIFT, + CKSYS2_CLK_FENC_STATUS_MON_0, 17), + MUX_GATE_FENC_CLR_SET_UPD(CLK_TOP2_DVO, "dvo", dvo_parents, + CKSYS2_CLK_CFG_3, CKSYS2_CLK_CFG_3_SET, CKSYS2_CLK_CFG_3_CLR, + 24, 3, 31, CKSYS2_CLK_CFG_UPDATE, TOP_MUX_DVO_SHIFT, + CKSYS2_CLK_FENC_STATUS_MON_0, 16), + MUX_GATE_FENC_CLR_SET_UPD(CLK_TOP2_DVO_FAVT, "dvo_favt", dvo_favt_parents, + CKSYS2_CLK_CFG_4, CKSYS2_CLK_CFG_4_SET, CKSYS2_CLK_CFG_4_CLR, + 0, 3, 7, CKSYS2_CLK_CFG_UPDATE, TOP_MUX_DVO_FAVT_SHIFT, + CKSYS2_CLK_FENC_STATUS_MON_0, 15), + MUX_GATE_FENC_CLR_SET_UPD(CLK_TOP2_DP1, "dp1", dp1_parents, + CKSYS2_CLK_CFG_4, CKSYS2_CLK_CFG_4_SET, CKSYS2_CLK_CFG_4_CLR, + 8, 3, 15, CKSYS2_CLK_CFG_UPDATE, TOP_MUX_DP1_SHIFT, + CKSYS2_CLK_FENC_STATUS_MON_0, 14), + MUX_GATE_FENC_CLR_SET_UPD(CLK_TOP2_DP0, "dp0", dp0_parents, + CKSYS2_CLK_CFG_4, CKSYS2_CLK_CFG_4_SET, CKSYS2_CLK_CFG_4_CLR, + 16, 3, 23, CKSYS2_CLK_CFG_UPDATE, TOP_MUX_DP0_SHIFT, + CKSYS2_CLK_FENC_STATUS_MON_0, 13), + MUX_GATE_HWV_FENC_CLR_SET_UPD(CLK_TOP2_DISP, "disp", disp_parents, + CKSYS2_CLK_CFG_4, CKSYS2_CLK_CFG_4_SET, CKSYS2_CLK_CFG_4_CLR, + MM_HWV_CG_34_DONE, MM_HWV_CG_34_SET, MM_HWV_CG_34_CLR, + 24, 4, 31, CKSYS2_CLK_CFG_UPDATE, TOP_MUX_DISP_SHIFT, + CKSYS2_CLK_FENC_STATUS_MON_0, 12), + /* CKSYS2_CLK_CFG_5 */ + MUX_GATE_HWV_FENC_CLR_SET_UPD(CLK_TOP2_MDP, "mdp", mdp_parents, + CKSYS2_CLK_CFG_5, CKSYS2_CLK_CFG_5_SET, CKSYS2_CLK_CFG_5_CLR, + MM_HWV_CG_35_DONE, MM_HWV_CG_35_SET, MM_HWV_CG_35_CLR, + 0, 4, 7, CKSYS2_CLK_CFG_UPDATE, TOP_MUX_MDP_SHIFT, + CKSYS2_CLK_FENC_STATUS_MON_0, 11), + MUX_GATE_HWV_FENC_CLR_SET_UPD(CLK_TOP2_MMINFRA, "mminfra", mminfra_parents, + CKSYS2_CLK_CFG_5, CKSYS2_CLK_CFG_5_SET, CKSYS2_CLK_CFG_5_CLR, + MM_HWV_CG_35_DONE, MM_HWV_CG_35_SET, MM_HWV_CG_35_CLR, + 8, 4, 15, CKSYS2_CLK_CFG_UPDATE, TOP_MUX_MMINFRA_SHIFT, + CKSYS2_CLK_FENC_STATUS_MON_0, 10), + MUX_GATE_HWV_FENC_CLR_SET_UPD(CLK_TOP2_MMINFRA_SNOC, "mminfra_snoc", mminfra_snoc_parents, + CKSYS2_CLK_CFG_5, CKSYS2_CLK_CFG_5_SET, CKSYS2_CLK_CFG_5_CLR, + MM_HWV_CG_35_DONE, MM_HWV_CG_35_SET, MM_HWV_CG_35_CLR, + 16, 4, 23, CKSYS2_CLK_CFG_UPDATE, TOP_MUX_MMINFRA_SNOC_SHIFT, + CKSYS2_CLK_FENC_STATUS_MON_0, 9), + MUX_GATE_FENC_CLR_SET_UPD(CLK_TOP2_MMUP, "mmup", mmup_parents, + CKSYS2_CLK_CFG_5, CKSYS2_CLK_CFG_5_SET, CKSYS2_CLK_CFG_5_CLR, + 24, 3, 31, CKSYS2_CLK_CFG_UPDATE, TOP_MUX_MMUP_SHIFT, + CKSYS2_CLK_FENC_STATUS_MON_0, 8), + /* CKSYS2_CLK_CFG_6 */ + MUX_GATE_HWV_FENC_CLR_SET_UPD(CLK_TOP2_MMINFRA_AO, "mminfra_ao", mminfra_ao_parents, + CKSYS2_CLK_CFG_6, CKSYS2_CLK_CFG_6_SET, CKSYS2_CLK_CFG_6_CLR, + MM_HWV_CG_36_DONE, MM_HWV_CG_36_SET, MM_HWV_CG_36_CLR, + 16, 2, 7, CKSYS2_CLK_CFG_UPDATE, TOP_MUX_MMINFRA_AO_SHIFT, + CKSYS2_CLK_FENC_STATUS_MON_0, 5), +}; + +static const struct mtk_clk_desc topck_desc = { + .factor_clks = top_divs, + .num_factor_clks = ARRAY_SIZE(top_divs), + .mux_clks = top_muxes, + .num_mux_clks = ARRAY_SIZE(top_muxes), +}; + +static const struct of_device_id of_match_clk_mt8196_ck[] = { + { .compatible = "mediatek,mt8196-topckgen-gp2", .data = &topck_desc }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(of, of_match_clk_mt8196_ck); + +static struct platform_driver clk_mt8196_topck_drv = { + .probe = mtk_clk_simple_probe, + .remove = mtk_clk_simple_remove, + .driver = { + .name = "clk-mt8196-topck2", + .of_match_table = of_match_clk_mt8196_ck, + }, +}; + +MODULE_DESCRIPTION("MediaTek MT8196 GP2 top clock generators driver"); +module_platform_driver(clk_mt8196_topck_drv); +MODULE_LICENSE("GPL"); diff --git a/drivers/clk/mediatek/clk-mt8196-ufs_ao.c b/drivers/clk/mediatek/clk-mt8196-ufs_ao.c new file mode 100644 index 000000000000..0c04717b7b4b --- /dev/null +++ b/drivers/clk/mediatek/clk-mt8196-ufs_ao.c @@ -0,0 +1,108 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2025 MediaTek Inc. + * Guangjie Song <guangjie.song@mediatek.com> + * Copyright (c) 2025 Collabora Ltd. + * Laura Nao <laura.nao@collabora.com> + */ +#include <dt-bindings/clock/mediatek,mt8196-clock.h> +#include <dt-bindings/reset/mediatek,mt8196-resets.h> + +#include <linux/clk-provider.h> +#include <linux/module.h> +#include <linux/of_device.h> +#include <linux/platform_device.h> + +#include "clk-gate.h" +#include "clk-mtk.h" + +#define MT8196_UFSAO_RST0_SET_OFFSET 0x48 +#define MT8196_UFSAO_RST1_SET_OFFSET 0x148 + +static const struct mtk_gate_regs ufsao0_cg_regs = { + .set_ofs = 0x108, + .clr_ofs = 0x10c, + .sta_ofs = 0x104, +}; + +static const struct mtk_gate_regs ufsao1_cg_regs = { + .set_ofs = 0x8, + .clr_ofs = 0xc, + .sta_ofs = 0x4, +}; + +#define GATE_UFSAO0(_id, _name, _parent, _shift) { \ + .id = _id, \ + .name = _name, \ + .parent_name = _parent, \ + .regs = &ufsao0_cg_regs, \ + .shift = _shift, \ + .ops = &mtk_clk_gate_ops_setclr, \ + } + +#define GATE_UFSAO1(_id, _name, _parent, _shift) { \ + .id = _id, \ + .name = _name, \ + .parent_name = _parent, \ + .regs = &ufsao1_cg_regs, \ + .shift = _shift, \ + .ops = &mtk_clk_gate_ops_setclr, \ + } + +static const struct mtk_gate ufsao_clks[] = { + /* UFSAO0 */ + GATE_UFSAO0(CLK_UFSAO_UFSHCI_UFS, "ufsao_ufshci_ufs", "ufs", 0), + GATE_UFSAO0(CLK_UFSAO_UFSHCI_AES, "ufsao_ufshci_aes", "aes_ufsfde", 1), + /* UFSAO1 */ + GATE_UFSAO1(CLK_UFSAO_UNIPRO_TX_SYM, "ufsao_unipro_tx_sym", "clk26m", 0), + GATE_UFSAO1(CLK_UFSAO_UNIPRO_RX_SYM0, "ufsao_unipro_rx_sym0", "clk26m", 1), + GATE_UFSAO1(CLK_UFSAO_UNIPRO_RX_SYM1, "ufsao_unipro_rx_sym1", "clk26m", 2), + GATE_UFSAO1(CLK_UFSAO_UNIPRO_SYS, "ufsao_unipro_sys", "ufs", 3), + GATE_UFSAO1(CLK_UFSAO_UNIPRO_SAP, "ufsao_unipro_sap", "clk26m", 4), + GATE_UFSAO1(CLK_UFSAO_PHY_SAP, "ufsao_phy_sap", "clk26m", 8), +}; + +static u16 ufsao_rst_ofs[] = { + MT8196_UFSAO_RST0_SET_OFFSET, + MT8196_UFSAO_RST1_SET_OFFSET +}; + +static u16 ufsao_rst_idx_map[] = { + [MT8196_UFSAO_RST0_UFS_MPHY] = 8, + [MT8196_UFSAO_RST1_UFS_UNIPRO] = 1 * RST_NR_PER_BANK + 0, + [MT8196_UFSAO_RST1_UFS_CRYPTO] = 1 * RST_NR_PER_BANK + 1, + [MT8196_UFSAO_RST1_UFSHCI] = 1 * RST_NR_PER_BANK + 2, +}; + +static const struct mtk_clk_rst_desc ufsao_rst_desc = { + .version = MTK_RST_SET_CLR, + .rst_bank_ofs = ufsao_rst_ofs, + .rst_bank_nr = ARRAY_SIZE(ufsao_rst_ofs), + .rst_idx_map = ufsao_rst_idx_map, + .rst_idx_map_nr = ARRAY_SIZE(ufsao_rst_idx_map), +}; + +static const struct mtk_clk_desc ufsao_mcd = { + .clks = ufsao_clks, + .num_clks = ARRAY_SIZE(ufsao_clks), + .rst_desc = &ufsao_rst_desc, +}; + +static const struct of_device_id of_match_clk_mt8196_ufs_ao[] = { + { .compatible = "mediatek,mt8196-ufscfg-ao", .data = &ufsao_mcd }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(of, of_match_clk_mt8196_ufs_ao); + +static struct platform_driver clk_mt8196_ufs_ao_drv = { + .probe = mtk_clk_simple_probe, + .remove = mtk_clk_simple_remove, + .driver = { + .name = "clk-mt8196-ufs-ao", + .of_match_table = of_match_clk_mt8196_ufs_ao, + }, +}; + +module_platform_driver(clk_mt8196_ufs_ao_drv); +MODULE_DESCRIPTION("MediaTek MT8196 ufs_ao clocks driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/clk/mediatek/clk-mt8196-vdec.c b/drivers/clk/mediatek/clk-mt8196-vdec.c new file mode 100644 index 000000000000..f8dcd84a2b58 --- /dev/null +++ b/drivers/clk/mediatek/clk-mt8196-vdec.c @@ -0,0 +1,253 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2025 MediaTek Inc. + * Guangjie Song <guangjie.song@mediatek.com> + * Copyright (c) 2025 Collabora Ltd. + * Laura Nao <laura.nao@collabora.com> + */ +#include <dt-bindings/clock/mediatek,mt8196-clock.h> + +#include <linux/clk-provider.h> +#include <linux/module.h> +#include <linux/of_device.h> +#include <linux/platform_device.h> + +#include "clk-gate.h" +#include "clk-mtk.h" + +static const struct mtk_gate_regs vde20_cg_regs = { + .set_ofs = 0x0, + .clr_ofs = 0x4, + .sta_ofs = 0x0, +}; + +static const struct mtk_gate_regs vde20_hwv_regs = { + .set_ofs = 0x0088, + .clr_ofs = 0x008c, + .sta_ofs = 0x2c44, +}; + +static const struct mtk_gate_regs vde21_cg_regs = { + .set_ofs = 0x200, + .clr_ofs = 0x204, + .sta_ofs = 0x200, +}; + +static const struct mtk_gate_regs vde21_hwv_regs = { + .set_ofs = 0x0080, + .clr_ofs = 0x0084, + .sta_ofs = 0x2c40, +}; + +static const struct mtk_gate_regs vde22_cg_regs = { + .set_ofs = 0x8, + .clr_ofs = 0xc, + .sta_ofs = 0x8, +}; + +static const struct mtk_gate_regs vde22_hwv_regs = { + .set_ofs = 0x0078, + .clr_ofs = 0x007c, + .sta_ofs = 0x2c3c, +}; + +#define GATE_HWV_VDE20(_id, _name, _parent, _shift) { \ + .id = _id, \ + .name = _name, \ + .parent_name = _parent, \ + .regs = &vde20_cg_regs, \ + .hwv_regs = &vde20_hwv_regs, \ + .shift = _shift, \ + .ops = &mtk_clk_gate_hwv_ops_setclr_inv,\ + .flags = CLK_OPS_PARENT_ENABLE, \ + } + +#define GATE_HWV_VDE21(_id, _name, _parent, _shift) { \ + .id = _id, \ + .name = _name, \ + .parent_name = _parent, \ + .regs = &vde21_cg_regs, \ + .hwv_regs = &vde21_hwv_regs, \ + .shift = _shift, \ + .ops = &mtk_clk_gate_hwv_ops_setclr_inv,\ + .flags = CLK_OPS_PARENT_ENABLE, \ + } + +#define GATE_HWV_VDE22(_id, _name, _parent, _shift) { \ + .id = _id, \ + .name = _name, \ + .parent_name = _parent, \ + .regs = &vde22_cg_regs, \ + .hwv_regs = &vde22_hwv_regs, \ + .shift = _shift, \ + .ops = &mtk_clk_gate_hwv_ops_setclr_inv,\ + .flags = CLK_OPS_PARENT_ENABLE | \ + CLK_IGNORE_UNUSED, \ + } + +static const struct mtk_gate vde2_clks[] = { + /* VDE20 */ + GATE_HWV_VDE20(CLK_VDE2_VDEC_CKEN, "vde2_vdec_cken", "vdec", 0), + GATE_HWV_VDE20(CLK_VDE2_VDEC_ACTIVE, "vde2_vdec_active", "vdec", 4), + GATE_HWV_VDE20(CLK_VDE2_VDEC_CKEN_ENG, "vde2_vdec_cken_eng", "vdec", 8), + /* VDE21 */ + GATE_HWV_VDE21(CLK_VDE2_LAT_CKEN, "vde2_lat_cken", "vdec", 0), + GATE_HWV_VDE21(CLK_VDE2_LAT_ACTIVE, "vde2_lat_active", "vdec", 4), + GATE_HWV_VDE21(CLK_VDE2_LAT_CKEN_ENG, "vde2_lat_cken_eng", "vdec", 8), + /* VDE22 */ + GATE_HWV_VDE22(CLK_VDE2_LARB1_CKEN, "vde2_larb1_cken", "vdec", 0), +}; + +static const struct mtk_clk_desc vde2_mcd = { + .clks = vde2_clks, + .num_clks = ARRAY_SIZE(vde2_clks), + .need_runtime_pm = true, +}; + +static const struct mtk_gate_regs vde10_hwv_regs = { + .set_ofs = 0x00a0, + .clr_ofs = 0x00a4, + .sta_ofs = 0x2c50, +}; + +static const struct mtk_gate_regs vde11_cg_regs = { + .set_ofs = 0x1e0, + .clr_ofs = 0x1e0, + .sta_ofs = 0x1e0, +}; + +static const struct mtk_gate_regs vde11_hwv_regs = { + .set_ofs = 0x00b0, + .clr_ofs = 0x00b4, + .sta_ofs = 0x2c58, +}; + +static const struct mtk_gate_regs vde12_cg_regs = { + .set_ofs = 0x1ec, + .clr_ofs = 0x1ec, + .sta_ofs = 0x1ec, +}; + +static const struct mtk_gate_regs vde12_hwv_regs = { + .set_ofs = 0x00a8, + .clr_ofs = 0x00ac, + .sta_ofs = 0x2c54, +}; + +static const struct mtk_gate_regs vde13_cg_regs = { + .set_ofs = 0x200, + .clr_ofs = 0x204, + .sta_ofs = 0x200, +}; + +static const struct mtk_gate_regs vde13_hwv_regs = { + .set_ofs = 0x0098, + .clr_ofs = 0x009c, + .sta_ofs = 0x2c4c, +}; + +static const struct mtk_gate_regs vde14_hwv_regs = { + .set_ofs = 0x0090, + .clr_ofs = 0x0094, + .sta_ofs = 0x2c48, +}; + +#define GATE_HWV_VDE10(_id, _name, _parent, _shift) { \ + .id = _id, \ + .name = _name, \ + .parent_name = _parent, \ + .regs = &vde20_cg_regs, \ + .hwv_regs = &vde10_hwv_regs, \ + .shift = _shift, \ + .ops = &mtk_clk_gate_hwv_ops_setclr_inv,\ + .flags = CLK_OPS_PARENT_ENABLE, \ + } + +#define GATE_HWV_VDE11(_id, _name, _parent, _shift) { \ + .id = _id, \ + .name = _name, \ + .parent_name = _parent, \ + .regs = &vde11_cg_regs, \ + .hwv_regs = &vde11_hwv_regs, \ + .shift = _shift, \ + .ops = &mtk_clk_gate_hwv_ops_setclr_inv, \ + .flags = CLK_OPS_PARENT_ENABLE, \ + } + +#define GATE_HWV_VDE12(_id, _name, _parent, _shift) { \ + .id = _id, \ + .name = _name, \ + .parent_name = _parent, \ + .regs = &vde12_cg_regs, \ + .hwv_regs = &vde12_hwv_regs, \ + .shift = _shift, \ + .ops = &mtk_clk_gate_hwv_ops_setclr_inv, \ + .flags = CLK_OPS_PARENT_ENABLE \ + } + +#define GATE_HWV_VDE13(_id, _name, _parent, _shift) { \ + .id = _id, \ + .name = _name, \ + .parent_name = _parent, \ + .regs = &vde13_cg_regs, \ + .hwv_regs = &vde13_hwv_regs, \ + .shift = _shift, \ + .ops = &mtk_clk_gate_hwv_ops_setclr_inv,\ + .flags = CLK_OPS_PARENT_ENABLE, \ + } + +#define GATE_HWV_VDE14(_id, _name, _parent, _shift) { \ + .id = _id, \ + .name = _name, \ + .parent_name = _parent, \ + .regs = &vde22_cg_regs, \ + .hwv_regs = &vde14_hwv_regs, \ + .shift = _shift, \ + .ops = &mtk_clk_gate_hwv_ops_setclr_inv,\ + .flags = CLK_OPS_PARENT_ENABLE | \ + CLK_IGNORE_UNUSED, \ + } + +static const struct mtk_gate vde1_clks[] = { + /* VDE10 */ + GATE_HWV_VDE10(CLK_VDE1_VDEC_CKEN, "vde1_vdec_cken", "vdec", 0), + GATE_HWV_VDE10(CLK_VDE1_VDEC_ACTIVE, "vde1_vdec_active", "vdec", 4), + GATE_HWV_VDE10(CLK_VDE1_VDEC_CKEN_ENG, "vde1_vdec_cken_eng", "vdec", 8), + /* VDE11 */ + GATE_HWV_VDE11(CLK_VDE1_VDEC_SOC_IPS_EN, "vde1_vdec_soc_ips_en", "vdec", 0), + /* VDE12 */ + GATE_HWV_VDE12(CLK_VDE1_VDEC_SOC_APTV_EN, "vde1_aptv_en", "ck_tck_26m_mx9_ck", 0), + GATE_HWV_VDE12(CLK_VDE1_VDEC_SOC_APTV_TOP_EN, "vde1_aptv_topen", "ck_tck_26m_mx9_ck", 1), + /* VDE13 */ + GATE_HWV_VDE13(CLK_VDE1_LAT_CKEN, "vde1_lat_cken", "vdec", 0), + GATE_HWV_VDE13(CLK_VDE1_LAT_ACTIVE, "vde1_lat_active", "vdec", 4), + GATE_HWV_VDE13(CLK_VDE1_LAT_CKEN_ENG, "vde1_lat_cken_eng", "vdec", 8), + /* VDE14 */ + GATE_HWV_VDE14(CLK_VDE1_LARB1_CKEN, "vde1_larb1_cken", "vdec", 0), +}; + +static const struct mtk_clk_desc vde1_mcd = { + .clks = vde1_clks, + .num_clks = ARRAY_SIZE(vde1_clks), + .need_runtime_pm = true, +}; + +static const struct of_device_id of_match_clk_mt8196_vdec[] = { + { .compatible = "mediatek,mt8196-vdecsys", .data = &vde2_mcd }, + { .compatible = "mediatek,mt8196-vdecsys-soc", .data = &vde1_mcd }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(of, of_match_clk_mt8196_vdec); + +static struct platform_driver clk_mt8196_vdec_drv = { + .probe = mtk_clk_simple_probe, + .remove = mtk_clk_simple_remove, + .driver = { + .name = "clk-mt8196-vdec", + .of_match_table = of_match_clk_mt8196_vdec, + }, +}; +module_platform_driver(clk_mt8196_vdec_drv); + +MODULE_DESCRIPTION("MediaTek MT8196 Video Decoders clocks driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/clk/mediatek/clk-mt8196-vdisp_ao.c b/drivers/clk/mediatek/clk-mt8196-vdisp_ao.c new file mode 100644 index 000000000000..fddb69d1c3eb --- /dev/null +++ b/drivers/clk/mediatek/clk-mt8196-vdisp_ao.c @@ -0,0 +1,80 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2025 MediaTek Inc. + * Guangjie Song <guangjie.song@mediatek.com> + * Copyright (c) 2025 Collabora Ltd. + * Laura Nao <laura.nao@collabora.com> + */ +#include <dt-bindings/clock/mediatek,mt8196-clock.h> + +#include <linux/clk-provider.h> +#include <linux/module.h> +#include <linux/of_device.h> +#include <linux/platform_device.h> + +#include "clk-gate.h" +#include "clk-mtk.h" + +static const struct mtk_gate_regs mm_v_cg_regs = { + .set_ofs = 0x104, + .clr_ofs = 0x108, + .sta_ofs = 0x100, +}; + +static const struct mtk_gate_regs mm_v_hwv_regs = { + .set_ofs = 0x0030, + .clr_ofs = 0x0034, + .sta_ofs = 0x2c18, +}; + +#define GATE_MM_AO_V(_id, _name, _parent, _shift) { \ + .id = _id, \ + .name = _name, \ + .parent_name = _parent, \ + .regs = &mm_v_cg_regs, \ + .shift = _shift, \ + .ops = &mtk_clk_gate_ops_setclr, \ + .flags = CLK_OPS_PARENT_ENABLE | \ + CLK_IS_CRITICAL, \ + } + +#define GATE_HWV_MM_V(_id, _name, _parent, _shift) { \ + .id = _id, \ + .name = _name, \ + .parent_name = _parent, \ + .regs = &mm_v_cg_regs, \ + .hwv_regs = &mm_v_hwv_regs, \ + .shift = _shift, \ + .ops = &mtk_clk_gate_hwv_ops_setclr, \ + .flags = CLK_OPS_PARENT_ENABLE, \ + } + +static const struct mtk_gate mm_v_clks[] = { + GATE_HWV_MM_V(CLK_MM_V_DISP_VDISP_AO_CONFIG, "mm_v_disp_vdisp_ao_config", "disp", 0), + GATE_HWV_MM_V(CLK_MM_V_DISP_DPC, "mm_v_disp_dpc", "disp", 16), + GATE_MM_AO_V(CLK_MM_V_SMI_SUB_SOMM0, "mm_v_smi_sub_somm0", "disp", 2), +}; + +static const struct mtk_clk_desc mm_v_mcd = { + .clks = mm_v_clks, + .num_clks = ARRAY_SIZE(mm_v_clks), +}; + +static const struct of_device_id of_match_clk_mt8196_vdisp_ao[] = { + { .compatible = "mediatek,mt8196-vdisp-ao", .data = &mm_v_mcd }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(of, of_match_clk_mt8196_vdisp_ao); + +static struct platform_driver clk_mt8196_vdisp_ao_drv = { + .probe = mtk_clk_pdev_probe, + .remove = mtk_clk_pdev_remove, + .driver = { + .name = "clk-mt8196-vdisp-ao", + .of_match_table = of_match_clk_mt8196_vdisp_ao, + }, +}; +module_platform_driver(clk_mt8196_vdisp_ao_drv); + +MODULE_DESCRIPTION("MediaTek MT8196 vdisp_ao clocks driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/clk/mediatek/clk-mt8196-venc.c b/drivers/clk/mediatek/clk-mt8196-venc.c new file mode 100644 index 000000000000..13e2e36e945f --- /dev/null +++ b/drivers/clk/mediatek/clk-mt8196-venc.c @@ -0,0 +1,236 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2025 MediaTek Inc. + * Guangjie Song <guangjie.song@mediatek.com> + * Copyright (c) 2025 Collabora Ltd. + * Laura Nao <laura.nao@collabora.com> + */ +#include <dt-bindings/clock/mediatek,mt8196-clock.h> + +#include <linux/clk-provider.h> +#include <linux/module.h> +#include <linux/of_device.h> +#include <linux/platform_device.h> + +#include "clk-gate.h" +#include "clk-mtk.h" + +static const struct mtk_gate_regs ven10_cg_regs = { + .set_ofs = 0x4, + .clr_ofs = 0x8, + .sta_ofs = 0x0, +}; + +static const struct mtk_gate_regs ven10_hwv_regs = { + .set_ofs = 0x00b8, + .clr_ofs = 0x00bc, + .sta_ofs = 0x2c5c, +}; + +static const struct mtk_gate_regs ven11_cg_regs = { + .set_ofs = 0x10, + .clr_ofs = 0x14, + .sta_ofs = 0x10, +}; + +static const struct mtk_gate_regs ven11_hwv_regs = { + .set_ofs = 0x00c0, + .clr_ofs = 0x00c4, + .sta_ofs = 0x2c60, +}; + +#define GATE_VEN10(_id, _name, _parent, _shift) { \ + .id = _id, \ + .name = _name, \ + .parent_name = _parent, \ + .regs = &ven10_cg_regs, \ + .shift = _shift, \ + .flags = CLK_OPS_PARENT_ENABLE, \ + .ops = &mtk_clk_gate_ops_setclr_inv, \ + } + +#define GATE_HWV_VEN10_FLAGS(_id, _name, _parent, _shift, _flags) { \ + .id = _id, \ + .name = _name, \ + .parent_name = _parent, \ + .regs = &ven10_cg_regs, \ + .hwv_regs = &ven10_hwv_regs, \ + .shift = _shift, \ + .ops = &mtk_clk_gate_hwv_ops_setclr_inv, \ + .flags = (_flags) | \ + CLK_OPS_PARENT_ENABLE, \ + } + +#define GATE_HWV_VEN10(_id, _name, _parent, _shift) \ + GATE_HWV_VEN10_FLAGS(_id, _name, _parent, _shift, 0) + +#define GATE_HWV_VEN11(_id, _name, _parent, _shift) { \ + .id = _id, \ + .name = _name, \ + .parent_name = _parent, \ + .regs = &ven11_cg_regs, \ + .hwv_regs = &ven11_hwv_regs, \ + .shift = _shift, \ + .ops = &mtk_clk_gate_hwv_ops_setclr_inv,\ + .flags = CLK_OPS_PARENT_ENABLE \ + } + +static const struct mtk_gate ven1_clks[] = { + /* VEN10 */ + GATE_HWV_VEN10(CLK_VEN1_CKE0_LARB, "ven1_larb", "venc", 0), + GATE_HWV_VEN10(CLK_VEN1_CKE1_VENC, "ven1_venc", "venc", 4), + GATE_VEN10(CLK_VEN1_CKE2_JPGENC, "ven1_jpgenc", "venc", 8), + GATE_VEN10(CLK_VEN1_CKE3_JPGDEC, "ven1_jpgdec", "venc", 12), + GATE_VEN10(CLK_VEN1_CKE4_JPGDEC_C1, "ven1_jpgdec_c1", "venc", 16), + GATE_HWV_VEN10(CLK_VEN1_CKE5_GALS, "ven1_gals", "venc", 28), + GATE_HWV_VEN10(CLK_VEN1_CKE29_VENC_ADAB_CTRL, "ven1_venc_adab_ctrl", + "venc", 29), + GATE_HWV_VEN10_FLAGS(CLK_VEN1_CKE29_VENC_XPC_CTRL, + "ven1_venc_xpc_ctrl", "venc", 30, + CLK_IGNORE_UNUSED), + GATE_HWV_VEN10(CLK_VEN1_CKE6_GALS_SRAM, "ven1_gals_sram", "venc", 31), + /* VEN11 */ + GATE_HWV_VEN11(CLK_VEN1_RES_FLAT, "ven1_res_flat", "venc", 0), +}; + +static const struct mtk_clk_desc ven1_mcd = { + .clks = ven1_clks, + .num_clks = ARRAY_SIZE(ven1_clks), + .need_runtime_pm = true, +}; + +static const struct mtk_gate_regs ven20_hwv_regs = { + .set_ofs = 0x00c8, + .clr_ofs = 0x00cc, + .sta_ofs = 0x2c64, +}; + +static const struct mtk_gate_regs ven21_hwv_regs = { + .set_ofs = 0x00d0, + .clr_ofs = 0x00d4, + .sta_ofs = 0x2c68, +}; + +#define GATE_VEN20(_id, _name, _parent, _shift) { \ + .id = _id, \ + .name = _name, \ + .parent_name = _parent, \ + .regs = &ven10_cg_regs, \ + .shift = _shift, \ + .flags = CLK_OPS_PARENT_ENABLE, \ + .ops = &mtk_clk_gate_ops_setclr_inv, \ + } + +#define GATE_HWV_VEN20(_id, _name, _parent, _shift) { \ + .id = _id, \ + .name = _name, \ + .parent_name = _parent, \ + .regs = &ven10_cg_regs, \ + .hwv_regs = &ven20_hwv_regs, \ + .shift = _shift, \ + .ops = &mtk_clk_gate_hwv_ops_setclr_inv,\ + .flags = CLK_OPS_PARENT_ENABLE, \ + } + +#define GATE_HWV_VEN21(_id, _name, _parent, _shift) { \ + .id = _id, \ + .name = _name, \ + .parent_name = _parent, \ + .regs = &ven11_cg_regs, \ + .hwv_regs = &ven21_hwv_regs, \ + .shift = _shift, \ + .ops = &mtk_clk_gate_hwv_ops_setclr, \ + .flags = CLK_OPS_PARENT_ENABLE \ + } + +static const struct mtk_gate ven2_clks[] = { + /* VEN20 */ + GATE_HWV_VEN20(CLK_VEN2_CKE0_LARB, "ven2_larb", "venc", 0), + GATE_HWV_VEN20(CLK_VEN2_CKE1_VENC, "ven2_venc", "venc", 4), + GATE_VEN20(CLK_VEN2_CKE2_JPGENC, "ven2_jpgenc", "venc", 8), + GATE_VEN20(CLK_VEN2_CKE3_JPGDEC, "ven2_jpgdec", "venc", 12), + GATE_HWV_VEN20(CLK_VEN2_CKE5_GALS, "ven2_gals", "venc", 28), + GATE_HWV_VEN20(CLK_VEN2_CKE29_VENC_XPC_CTRL, "ven2_venc_xpc_ctrl", "venc", 30), + GATE_HWV_VEN20(CLK_VEN2_CKE6_GALS_SRAM, "ven2_gals_sram", "venc", 31), + /* VEN21 */ + GATE_HWV_VEN21(CLK_VEN2_RES_FLAT, "ven2_res_flat", "venc", 0), +}; + +static const struct mtk_clk_desc ven2_mcd = { + .clks = ven2_clks, + .num_clks = ARRAY_SIZE(ven2_clks), + .need_runtime_pm = true, +}; + +static const struct mtk_gate_regs ven_c20_hwv_regs = { + .set_ofs = 0x00d8, + .clr_ofs = 0x00dc, + .sta_ofs = 0x2c6c, +}; + +static const struct mtk_gate_regs ven_c21_hwv_regs = { + .set_ofs = 0x00e0, + .clr_ofs = 0x00e4, + .sta_ofs = 0x2c70, +}; + +#define GATE_HWV_VEN_C20(_id, _name, _parent, _shift) {\ + .id = _id, \ + .name = _name, \ + .parent_name = _parent, \ + .regs = &ven10_cg_regs, \ + .hwv_regs = &ven_c20_hwv_regs, \ + .shift = _shift, \ + .ops = &mtk_clk_gate_hwv_ops_setclr_inv,\ + .flags = CLK_OPS_PARENT_ENABLE, \ + } + +#define GATE_HWV_VEN_C21(_id, _name, _parent, _shift) {\ + .id = _id, \ + .name = _name, \ + .parent_name = _parent, \ + .regs = &ven11_cg_regs, \ + .hwv_regs = &ven_c21_hwv_regs, \ + .shift = _shift, \ + .ops = &mtk_clk_gate_hwv_ops_setclr, \ + .flags = CLK_OPS_PARENT_ENABLE, \ + } + +static const struct mtk_gate ven_c2_clks[] = { + /* VEN_C20 */ + GATE_HWV_VEN_C20(CLK_VEN_C2_CKE0_LARB, "ven_c2_larb", "venc", 0), + GATE_HWV_VEN_C20(CLK_VEN_C2_CKE1_VENC, "ven_c2_venc", "venc", 4), + GATE_HWV_VEN_C20(CLK_VEN_C2_CKE5_GALS, "ven_c2_gals", "venc", 28), + GATE_HWV_VEN_C20(CLK_VEN_C2_CKE29_VENC_XPC_CTRL, "ven_c2_venc_xpc_ctrl", + "venc", 30), + GATE_HWV_VEN_C20(CLK_VEN_C2_CKE6_GALS_SRAM, "ven_c2_gals_sram", "venc", 31), + /* VEN_C21 */ + GATE_HWV_VEN_C21(CLK_VEN_C2_RES_FLAT, "ven_c2_res_flat", "venc", 0), +}; + +static const struct mtk_clk_desc ven_c2_mcd = { + .clks = ven_c2_clks, + .num_clks = ARRAY_SIZE(ven_c2_clks), + .need_runtime_pm = true, +}; + +static const struct of_device_id of_match_clk_mt8196_venc[] = { + { .compatible = "mediatek,mt8196-vencsys", .data = &ven1_mcd }, + { .compatible = "mediatek,mt8196-vencsys-c1", .data = &ven2_mcd }, + { .compatible = "mediatek,mt8196-vencsys-c2", .data = &ven_c2_mcd }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(of, of_match_clk_mt8196_venc); + +static struct platform_driver clk_mt8196_venc_drv = { + .probe = mtk_clk_simple_probe, + .remove = mtk_clk_simple_remove, + .driver = { + .name = "clk-mt8196-venc", + .of_match_table = of_match_clk_mt8196_venc, + }, +}; +module_platform_driver(clk_mt8196_venc_drv); + +MODULE_DESCRIPTION("MediaTek MT8196 Video Encoders clocks driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/clk/mediatek/clk-mt8196-vlpckgen.c b/drivers/clk/mediatek/clk-mt8196-vlpckgen.c new file mode 100644 index 000000000000..d59a8a9d9855 --- /dev/null +++ b/drivers/clk/mediatek/clk-mt8196-vlpckgen.c @@ -0,0 +1,725 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2025 MediaTek Inc. + * Guangjie Song <guangjie.song@mediatek.com> + * Copyright (c) 2025 Collabora Ltd. + * Laura Nao <laura.nao@collabora.com> + */ +#include <dt-bindings/clock/mediatek,mt8196-clock.h> + +#include <linux/clk.h> +#include <linux/module.h> +#include <linux/of.h> +#include <linux/of_address.h> +#include <linux/of_device.h> +#include <linux/platform_device.h> +#include <linux/regmap.h> + +#include "clk-mtk.h" +#include "clk-mux.h" +#include "clk-pll.h" + +/* MUX SEL REG */ +#define VLP_CLK_CFG_UPDATE 0x0004 +#define VLP_CLK_CFG_UPDATE1 0x0008 +#define VLP_CLK_CFG_0 0x0010 +#define VLP_CLK_CFG_0_SET 0x0014 +#define VLP_CLK_CFG_0_CLR 0x0018 +#define VLP_CLK_CFG_1 0x0020 +#define VLP_CLK_CFG_1_SET 0x0024 +#define VLP_CLK_CFG_1_CLR 0x0028 +#define VLP_CLK_CFG_2 0x0030 +#define VLP_CLK_CFG_2_SET 0x0034 +#define VLP_CLK_CFG_2_CLR 0x0038 +#define VLP_CLK_CFG_3 0x0040 +#define VLP_CLK_CFG_3_SET 0x0044 +#define VLP_CLK_CFG_3_CLR 0x0048 +#define VLP_CLK_CFG_4 0x0050 +#define VLP_CLK_CFG_4_SET 0x0054 +#define VLP_CLK_CFG_4_CLR 0x0058 +#define VLP_CLK_CFG_5 0x0060 +#define VLP_CLK_CFG_5_SET 0x0064 +#define VLP_CLK_CFG_5_CLR 0x0068 +#define VLP_CLK_CFG_6 0x0070 +#define VLP_CLK_CFG_6_SET 0x0074 +#define VLP_CLK_CFG_6_CLR 0x0078 +#define VLP_CLK_CFG_7 0x0080 +#define VLP_CLK_CFG_7_SET 0x0084 +#define VLP_CLK_CFG_7_CLR 0x0088 +#define VLP_CLK_CFG_8 0x0090 +#define VLP_CLK_CFG_8_SET 0x0094 +#define VLP_CLK_CFG_8_CLR 0x0098 +#define VLP_CLK_CFG_9 0x00a0 +#define VLP_CLK_CFG_9_SET 0x00a4 +#define VLP_CLK_CFG_9_CLR 0x00a8 +#define VLP_CLK_CFG_10 0x00b0 +#define VLP_CLK_CFG_10_SET 0x00b4 +#define VLP_CLK_CFG_10_CLR 0x00b8 +#define VLP_OCIC_FENC_STATUS_MON_0 0x039c +#define VLP_OCIC_FENC_STATUS_MON_1 0x03a0 + +/* MUX SHIFT */ +#define TOP_MUX_SCP_SHIFT 0 +#define TOP_MUX_SCP_SPI_SHIFT 1 +#define TOP_MUX_SCP_IIC_SHIFT 2 +#define TOP_MUX_SCP_IIC_HS_SHIFT 3 +#define TOP_MUX_PWRAP_ULPOSC_SHIFT 4 +#define TOP_MUX_SPMI_M_TIA_32K_SHIFT 5 +#define TOP_MUX_APXGPT_26M_B_SHIFT 6 +#define TOP_MUX_DPSW_SHIFT 7 +#define TOP_MUX_DPSW_CENTRAL_SHIFT 8 +#define TOP_MUX_SPMI_M_MST_SHIFT 9 +#define TOP_MUX_DVFSRC_SHIFT 10 +#define TOP_MUX_PWM_VLP_SHIFT 11 +#define TOP_MUX_AXI_VLP_SHIFT 12 +#define TOP_MUX_SYSTIMER_26M_SHIFT 13 +#define TOP_MUX_SSPM_SHIFT 14 +#define TOP_MUX_SRCK_SHIFT 15 +#define TOP_MUX_CAMTG0_SHIFT 16 +#define TOP_MUX_CAMTG1_SHIFT 17 +#define TOP_MUX_CAMTG2_SHIFT 18 +#define TOP_MUX_CAMTG3_SHIFT 19 +#define TOP_MUX_CAMTG4_SHIFT 20 +#define TOP_MUX_CAMTG5_SHIFT 21 +#define TOP_MUX_CAMTG6_SHIFT 22 +#define TOP_MUX_CAMTG7_SHIFT 23 +#define TOP_MUX_SSPM_26M_SHIFT 25 +#define TOP_MUX_ULPOSC_SSPM_SHIFT 26 +#define TOP_MUX_VLP_PBUS_26M_SHIFT 27 +#define TOP_MUX_DEBUG_ERR_FLAG_VLP_26M_SHIFT 28 +#define TOP_MUX_DPMSRDMA_SHIFT 29 +#define TOP_MUX_VLP_PBUS_156M_SHIFT 30 +#define TOP_MUX_SPM_SHIFT 0 +#define TOP_MUX_MMINFRA_VLP_SHIFT 1 +#define TOP_MUX_USB_TOP_SHIFT 2 +#define TOP_MUX_SSUSB_XHCI_SHIFT 3 +#define TOP_MUX_NOC_VLP_SHIFT 4 +#define TOP_MUX_AUDIO_H_SHIFT 5 +#define TOP_MUX_AUD_ENGEN1_SHIFT 6 +#define TOP_MUX_AUD_ENGEN2_SHIFT 7 +#define TOP_MUX_AUD_INTBUS_SHIFT 8 +#define TOP_MUX_SPU_VLP_26M_SHIFT 9 +#define TOP_MUX_SPU0_VLP_SHIFT 10 +#define TOP_MUX_SPU1_VLP_SHIFT 11 + +/* CKSTA REG */ +#define VLP_CKSTA_REG0 0x0250 +#define VLP_CKSTA_REG1 0x0254 + +/* HW Voter REG */ +#define HWV_CG_9_SET 0x0048 +#define HWV_CG_9_CLR 0x004c +#define HWV_CG_9_DONE 0x2c24 +#define HWV_CG_10_SET 0x0050 +#define HWV_CG_10_CLR 0x0054 +#define HWV_CG_10_DONE 0x2c28 + +/* PLL REG */ +#define VLP_AP_PLL_CON3 0x264 +#define VLP_APLL1_TUNER_CON0 0x2a4 +#define VLP_APLL2_TUNER_CON0 0x2a8 +#define VLP_APLL1_CON0 0x274 +#define VLP_APLL1_CON1 0x278 +#define VLP_APLL1_CON2 0x27c +#define VLP_APLL1_CON3 0x280 +#define VLP_APLL2_CON0 0x28c +#define VLP_APLL2_CON1 0x290 +#define VLP_APLL2_CON2 0x294 +#define VLP_APLL2_CON3 0x298 + +/* vlp apll1 tuner default value*/ +#define VLP_APLL1_TUNER_CON0_VALUE 0x6f28bd4d +/* vlp apll2 tuner default value + 1*/ +#define VLP_APLL2_TUNER_CON0_VALUE 0x78fd5265 + +#define VLP_PLLEN_ALL 0x080 +#define VLP_PLLEN_ALL_SET 0x084 +#define VLP_PLLEN_ALL_CLR 0x088 + +#define MT8196_PLL_FMAX (3800UL * MHZ) +#define MT8196_PLL_FMIN (1500UL * MHZ) +#define MT8196_INTEGER_BITS 8 + +#define PLL_FENC(_id, _name, _reg, _fenc_sta_ofs, _fenc_sta_bit,\ + _flags, _pd_reg, _pd_shift, \ + _pcw_reg, _pcw_shift, _pcwbits, \ + _pll_en_bit) { \ + .id = _id, \ + .name = _name, \ + .reg = _reg, \ + .fenc_sta_ofs = _fenc_sta_ofs, \ + .fenc_sta_bit = _fenc_sta_bit, \ + .flags = _flags, \ + .fmax = MT8196_PLL_FMAX, \ + .fmin = MT8196_PLL_FMIN, \ + .pd_reg = _pd_reg, \ + .pd_shift = _pd_shift, \ + .pcw_reg = _pcw_reg, \ + .pcw_shift = _pcw_shift, \ + .pcwbits = _pcwbits, \ + .pcwibits = MT8196_INTEGER_BITS, \ + .en_reg = VLP_PLLEN_ALL, \ + .en_set_reg = VLP_PLLEN_ALL_SET, \ + .en_clr_reg = VLP_PLLEN_ALL_CLR, \ + .pll_en_bit = _pll_en_bit, \ + .ops = &mtk_pll_fenc_clr_set_ops, \ +} + +static DEFINE_SPINLOCK(mt8196_clk_vlp_lock); + +static const struct mtk_fixed_factor vlp_divs[] = { + FACTOR(CLK_VLP_CLK26M, "vlp_clk26m", "clk26m", 1, 1), + FACTOR(CLK_VLP_APLL1_D4, "apll1_d4", "vlp_apll1", 1, 4), + FACTOR(CLK_VLP_APLL1_D8, "apll1_d8", "vlp_apll1", 1, 8), + FACTOR(CLK_VLP_APLL2_D4, "apll2_d4", "vlp_apll2", 1, 4), + FACTOR(CLK_VLP_APLL2_D8, "apll2_d8", "vlp_apll2", 1, 8), +}; + +static const char * const vlp_scp_parents[] = { + "clk26m", + "osc_d20", + "mainpll_d6", + "mainpll_d4", + "mainpll_d3", + "vlp_apll1" +}; + +static const char * const vlp_scp_spi_parents[] = { + "clk26m", + "osc_d20", + "mainpll_d7_d2", + "mainpll_d5_d2" +}; + +static const char * const vlp_scp_iic_parents[] = { + "clk26m", + "osc_d20", + "mainpll_d5_d4", + "mainpll_d7_d2" +}; + +static const char * const vlp_scp_iic_hs_parents[] = { + "clk26m", + "osc_d20", + "mainpll_d5_d4", + "mainpll_d7_d2", + "mainpll_d7" +}; + +static const char * const vlp_pwrap_ulposc_parents[] = { + "clk26m", + "osc_d20", + "osc_d14", + "osc_d10" +}; + +static const char * const vlp_spmi_32k_parents[] = { + "clk26m", + "clk32k", + "osc_d20", + "osc_d14", + "osc_d10" +}; + +static const char * const vlp_apxgpt_26m_b_parents[] = { + "clk26m", + "osc_d20" +}; + +static const char * const vlp_dpsw_parents[] = { + "clk26m", + "osc_d10", + "osc_d7", + "mainpll_d7_d4" +}; + +static const char * const vlp_dpsw_central_parents[] = { + "clk26m", + "osc_d10", + "osc_d7", + "mainpll_d7_d4" +}; + +static const char * const vlp_spmi_m_parents[] = { + "clk26m", + "osc_d20", + "osc_d14", + "osc_d10" +}; + +static const char * const vlp_dvfsrc_parents[] = { + "clk26m", + "osc_d20" +}; + +static const char * const vlp_pwm_vlp_parents[] = { + "clk26m", + "clk32k", + "osc_d20", + "osc_d8", + "mainpll_d4_d8" +}; + +static const char * const vlp_axi_vlp_parents[] = { + "clk26m", + "osc_d20", + "mainpll_d7_d4", + "osc_d4", + "mainpll_d7_d2" +}; + +static const char * const vlp_systimer_26m_parents[] = { + "clk26m", + "osc_d20" +}; + +static const char * const vlp_sspm_parents[] = { + "clk26m", + "osc_d20", + "mainpll_d5_d2", + "osc_d2", + "mainpll_d6" +}; + +static const char * const vlp_srck_parents[] = { + "clk26m", + "osc_d20" +}; + +static const char * const vlp_camtg0_1_parents[] = { + "clk26m", + "univpll_192m_d32", + "univpll_192m_d16", + "clk13m", + "osc_d40", + "osc_d32", + "univpll_192m_d10", + "univpll_192m_d8", + "univpll_d6_d16", + "ulposc3", + "osc_d20", + "ck2_tvdpll1_d16", + "univpll_d6_d8" +}; + +static const char * const vlp_camtg2_7_parents[] = { + "clk26m", + "univpll_192m_d32", + "univpll_192m_d16", + "clk13m", + "osc_d40", + "osc_d32", + "univpll_192m_d10", + "univpll_192m_d8", + "univpll_d6_d16", + "osc_d20", + "ck2_tvdpll1_d16", + "univpll_d6_d8" +}; + +static const char * const vlp_sspm_26m_parents[] = { + "clk26m", + "osc_d20" +}; + +static const char * const vlp_ulposc_sspm_parents[] = { + "clk26m", + "osc_d2", + "mainpll_d4_d2" +}; + +static const char * const vlp_vlp_pbus_26m_parents[] = { + "clk26m", + "osc_d20" +}; + +static const char * const vlp_debug_err_flag_parents[] = { + "clk26m", + "osc_d20" +}; + +static const char * const vlp_dpmsrdma_parents[] = { + "clk26m", + "mainpll_d7_d2" +}; + +static const char * const vlp_vlp_pbus_156m_parents[] = { + "clk26m", + "osc_d2", + "mainpll_d7_d2", + "mainpll_d7" +}; + +static const char * const vlp_spm_parents[] = { + "clk26m", + "mainpll_d7_d4" +}; + +static const char * const vlp_mminfra_parents[] = { + "clk26m", + "osc_d4", + "mainpll_d3" +}; + +static const char * const vlp_usb_parents[] = { + "clk26m", + "mainpll_d9" +}; + +static const char * const vlp_noc_vlp_parents[] = { + "clk26m", + "osc_d20", + "mainpll_d9" +}; + +static const char * const vlp_audio_h_parents[] = { + "vlp_clk26m", + "vlp_apll1", + "vlp_apll2" +}; + +static const char * const vlp_aud_engen1_parents[] = { + "vlp_clk26m", + "apll1_d8", + "apll1_d4" +}; + +static const char * const vlp_aud_engen2_parents[] = { + "vlp_clk26m", + "apll2_d8", + "apll2_d4" +}; + +static const char * const vlp_aud_intbus_parents[] = { + "vlp_clk26m", + "mainpll_d7_d4", + "mainpll_d4_d4" +}; + +static const u8 vlp_aud_parent_index[] = { 1, 2, 3 }; + +static const char * const vlp_spvlp_26m_parents[] = { + "clk26m", + "osc_d20" +}; + +static const char * const vlp_spu0_vlp_parents[] = { + "clk26m", + "osc_d20", + "mainpll_d4_d4", + "mainpll_d4_d2", + "mainpll_d7", + "mainpll_d6", + "mainpll_d5" +}; + +static const char * const vlp_spu1_vlp_parents[] = { + "clk26m", + "osc_d20", + "mainpll_d4_d4", + "mainpll_d4_d2", + "mainpll_d7", + "mainpll_d6", + "mainpll_d5" +}; + +static const struct mtk_mux vlp_muxes[] = { + /* VLP_CLK_CFG_0 */ + MUX_GATE_FENC_CLR_SET_UPD(CLK_VLP_SCP, "vlp_scp", vlp_scp_parents, + VLP_CLK_CFG_0, VLP_CLK_CFG_0_SET, VLP_CLK_CFG_0_CLR, + 0, 3, 7, VLP_CLK_CFG_UPDATE, TOP_MUX_SCP_SHIFT, + VLP_OCIC_FENC_STATUS_MON_0, 31), + MUX_CLR_SET_UPD(CLK_VLP_SCP_SPI, "vlp_scp_spi", + vlp_scp_spi_parents, VLP_CLK_CFG_0, VLP_CLK_CFG_0_SET, + VLP_CLK_CFG_0_CLR, 8, 2, + VLP_CLK_CFG_UPDATE, TOP_MUX_SCP_SPI_SHIFT), + MUX_CLR_SET_UPD(CLK_VLP_SCP_IIC, "vlp_scp_iic", + vlp_scp_iic_parents, VLP_CLK_CFG_0, VLP_CLK_CFG_0_SET, + VLP_CLK_CFG_0_CLR, 16, 2, + VLP_CLK_CFG_UPDATE, TOP_MUX_SCP_IIC_SHIFT), + MUX_CLR_SET_UPD(CLK_VLP_SCP_IIC_HS, "vlp_scp_iic_hs", + vlp_scp_iic_hs_parents, VLP_CLK_CFG_0, VLP_CLK_CFG_0_SET, + VLP_CLK_CFG_0_CLR, 24, 3, + VLP_CLK_CFG_UPDATE, TOP_MUX_SCP_IIC_HS_SHIFT), + /* VLP_CLK_CFG_1 */ + MUX_CLR_SET_UPD(CLK_VLP_PWRAP_ULPOSC, "vlp_pwrap_ulposc", + vlp_pwrap_ulposc_parents, VLP_CLK_CFG_1, VLP_CLK_CFG_1_SET, + VLP_CLK_CFG_1_CLR, 0, 2, + VLP_CLK_CFG_UPDATE, TOP_MUX_PWRAP_ULPOSC_SHIFT), + MUX_CLR_SET_UPD(CLK_VLP_SPMI_M_TIA_32K, "vlp_spmi_32k", + vlp_spmi_32k_parents, VLP_CLK_CFG_1, VLP_CLK_CFG_1_SET, + VLP_CLK_CFG_1_CLR, 8, 3, + VLP_CLK_CFG_UPDATE, TOP_MUX_SPMI_M_TIA_32K_SHIFT), + MUX_CLR_SET_UPD(CLK_VLP_APXGPT_26M_B, "vlp_apxgpt_26m_b", + vlp_apxgpt_26m_b_parents, VLP_CLK_CFG_1, VLP_CLK_CFG_1_SET, + VLP_CLK_CFG_1_CLR, 16, 1, + VLP_CLK_CFG_UPDATE, TOP_MUX_APXGPT_26M_B_SHIFT), + MUX_CLR_SET_UPD(CLK_VLP_DPSW, "vlp_dpsw", + vlp_dpsw_parents, VLP_CLK_CFG_1, VLP_CLK_CFG_1_SET, + VLP_CLK_CFG_1_CLR, 24, 2, + VLP_CLK_CFG_UPDATE, TOP_MUX_DPSW_SHIFT), + /* VLP_CLK_CFG_2 */ + MUX_CLR_SET_UPD(CLK_VLP_DPSW_CENTRAL, "vlp_dpsw_central", + vlp_dpsw_central_parents, VLP_CLK_CFG_2, VLP_CLK_CFG_2_SET, + VLP_CLK_CFG_2_CLR, 0, 2, + VLP_CLK_CFG_UPDATE, TOP_MUX_DPSW_CENTRAL_SHIFT), + MUX_CLR_SET_UPD(CLK_VLP_SPMI_M_MST, "vlp_spmi_m", + vlp_spmi_m_parents, VLP_CLK_CFG_2, VLP_CLK_CFG_2_SET, + VLP_CLK_CFG_2_CLR, 8, 2, + VLP_CLK_CFG_UPDATE, TOP_MUX_SPMI_M_MST_SHIFT), + MUX_CLR_SET_UPD(CLK_VLP_DVFSRC, "vlp_dvfsrc", + vlp_dvfsrc_parents, VLP_CLK_CFG_2, VLP_CLK_CFG_2_SET, + VLP_CLK_CFG_2_CLR, 16, 1, + VLP_CLK_CFG_UPDATE, TOP_MUX_DVFSRC_SHIFT), + MUX_GATE_FENC_CLR_SET_UPD(CLK_VLP_PWM_VLP, "vlp_pwm_vlp", vlp_pwm_vlp_parents, + VLP_CLK_CFG_2, VLP_CLK_CFG_2_SET, VLP_CLK_CFG_2_CLR, + 24, 3, 31, VLP_CLK_CFG_UPDATE, TOP_MUX_PWM_VLP_SHIFT, + VLP_OCIC_FENC_STATUS_MON_0, 20), + /* VLP_CLK_CFG_3 */ + MUX_CLR_SET_UPD(CLK_VLP_AXI_VLP, "vlp_axi_vlp", + vlp_axi_vlp_parents, VLP_CLK_CFG_3, VLP_CLK_CFG_3_SET, + VLP_CLK_CFG_3_CLR, 0, 3, + VLP_CLK_CFG_UPDATE, TOP_MUX_AXI_VLP_SHIFT), + MUX_CLR_SET_UPD(CLK_VLP_SYSTIMER_26M, "vlp_systimer_26m", + vlp_systimer_26m_parents, VLP_CLK_CFG_3, VLP_CLK_CFG_3_SET, + VLP_CLK_CFG_3_CLR, 8, 1, + VLP_CLK_CFG_UPDATE, TOP_MUX_SYSTIMER_26M_SHIFT), + MUX_CLR_SET_UPD(CLK_VLP_SSPM, "vlp_sspm", + vlp_sspm_parents, VLP_CLK_CFG_3, VLP_CLK_CFG_3_SET, + VLP_CLK_CFG_3_CLR, 16, 3, + VLP_CLK_CFG_UPDATE, TOP_MUX_SSPM_SHIFT), + MUX_CLR_SET_UPD(CLK_VLP_SRCK, "vlp_srck", + vlp_srck_parents, VLP_CLK_CFG_3, VLP_CLK_CFG_3_SET, + VLP_CLK_CFG_3_CLR, 24, 1, + VLP_CLK_CFG_UPDATE, TOP_MUX_SRCK_SHIFT), + /* VLP_CLK_CFG_4 */ + MUX_GATE_HWV_FENC_CLR_SET_UPD(CLK_VLP_CAMTG0, "vlp_camtg0", vlp_camtg0_1_parents, + VLP_CLK_CFG_4, VLP_CLK_CFG_4_SET, VLP_CLK_CFG_4_CLR, + HWV_CG_9_DONE, HWV_CG_9_SET, HWV_CG_9_CLR, + 0, 4, 7, VLP_CLK_CFG_UPDATE, TOP_MUX_CAMTG0_SHIFT, + VLP_OCIC_FENC_STATUS_MON_0, 15), + MUX_GATE_HWV_FENC_CLR_SET_UPD(CLK_VLP_CAMTG1, "vlp_camtg1", vlp_camtg0_1_parents, + VLP_CLK_CFG_4, VLP_CLK_CFG_4_SET, VLP_CLK_CFG_4_CLR, + HWV_CG_9_DONE, HWV_CG_9_SET, HWV_CG_9_CLR, + 8, 4, 15, VLP_CLK_CFG_UPDATE, TOP_MUX_CAMTG1_SHIFT, + VLP_OCIC_FENC_STATUS_MON_0, 14), + MUX_GATE_HWV_FENC_CLR_SET_UPD(CLK_VLP_CAMTG2, "vlp_camtg2", vlp_camtg2_7_parents, + VLP_CLK_CFG_4, VLP_CLK_CFG_4_SET, VLP_CLK_CFG_4_CLR, + HWV_CG_9_DONE, HWV_CG_9_SET, HWV_CG_9_CLR, + 16, 4, 23, VLP_CLK_CFG_UPDATE, TOP_MUX_CAMTG2_SHIFT, + VLP_OCIC_FENC_STATUS_MON_0, 13), + MUX_GATE_HWV_FENC_CLR_SET_UPD(CLK_VLP_CAMTG3, "vlp_camtg3", vlp_camtg2_7_parents, + VLP_CLK_CFG_4, VLP_CLK_CFG_4_SET, VLP_CLK_CFG_4_CLR, + HWV_CG_9_DONE, HWV_CG_9_SET, HWV_CG_9_CLR, + 24, 4, 31, VLP_CLK_CFG_UPDATE, TOP_MUX_CAMTG3_SHIFT, + VLP_OCIC_FENC_STATUS_MON_0, 12), + /* VLP_CLK_CFG_5 */ + MUX_GATE_HWV_FENC_CLR_SET_UPD(CLK_VLP_CAMTG4, "vlp_camtg4", vlp_camtg2_7_parents, + VLP_CLK_CFG_5, VLP_CLK_CFG_5_SET, VLP_CLK_CFG_5_CLR, + HWV_CG_10_DONE, HWV_CG_10_SET, HWV_CG_10_CLR, + 0, 4, 7, VLP_CLK_CFG_UPDATE, TOP_MUX_CAMTG4_SHIFT, + VLP_OCIC_FENC_STATUS_MON_0, 11), + MUX_GATE_HWV_FENC_CLR_SET_UPD(CLK_VLP_CAMTG5, "vlp_camtg5", vlp_camtg2_7_parents, + VLP_CLK_CFG_5, VLP_CLK_CFG_5_SET, VLP_CLK_CFG_5_CLR, + HWV_CG_10_DONE, HWV_CG_10_SET, HWV_CG_10_CLR, + 8, 4, 15, VLP_CLK_CFG_UPDATE, TOP_MUX_CAMTG5_SHIFT, + VLP_OCIC_FENC_STATUS_MON_0, 10), + MUX_GATE_HWV_FENC_CLR_SET_UPD(CLK_VLP_CAMTG6, "vlp_camtg6", vlp_camtg2_7_parents, + VLP_CLK_CFG_5, VLP_CLK_CFG_5_SET, VLP_CLK_CFG_5_CLR, + HWV_CG_10_DONE, HWV_CG_10_SET, HWV_CG_10_CLR, + 16, 4, 23, VLP_CLK_CFG_UPDATE, TOP_MUX_CAMTG6_SHIFT, + VLP_OCIC_FENC_STATUS_MON_0, 9), + MUX_GATE_HWV_FENC_CLR_SET_UPD(CLK_VLP_CAMTG7, "vlp_camtg7", vlp_camtg2_7_parents, + VLP_CLK_CFG_5, VLP_CLK_CFG_5_SET, VLP_CLK_CFG_5_CLR, + HWV_CG_10_DONE, HWV_CG_10_SET, HWV_CG_10_CLR, + 24, 4, 31, VLP_CLK_CFG_UPDATE, TOP_MUX_CAMTG7_SHIFT, + VLP_OCIC_FENC_STATUS_MON_0, 8), + /* VLP_CLK_CFG_6 */ + MUX_CLR_SET_UPD(CLK_VLP_SSPM_26M, "vlp_sspm_26m", + vlp_sspm_26m_parents, VLP_CLK_CFG_6, VLP_CLK_CFG_6_SET, + VLP_CLK_CFG_6_CLR, 8, 1, + VLP_CLK_CFG_UPDATE, TOP_MUX_SSPM_26M_SHIFT), + MUX_CLR_SET_UPD(CLK_VLP_ULPOSC_SSPM, "vlp_ulposc_sspm", + vlp_ulposc_sspm_parents, VLP_CLK_CFG_6, VLP_CLK_CFG_6_SET, + VLP_CLK_CFG_6_CLR, 16, 2, + VLP_CLK_CFG_UPDATE, TOP_MUX_ULPOSC_SSPM_SHIFT), + MUX_CLR_SET_UPD(CLK_VLP_VLP_PBUS_26M, "vlp_vlp_pbus_26m", + vlp_vlp_pbus_26m_parents, VLP_CLK_CFG_6, VLP_CLK_CFG_6_SET, + VLP_CLK_CFG_6_CLR, 24, 1, + VLP_CLK_CFG_UPDATE, TOP_MUX_VLP_PBUS_26M_SHIFT), + /* VLP_CLK_CFG_7 */ + MUX_CLR_SET_UPD(CLK_VLP_DEBUG_ERR_FLAG, "vlp_debug_err_flag", + vlp_debug_err_flag_parents, VLP_CLK_CFG_7, VLP_CLK_CFG_7_SET, + VLP_CLK_CFG_7_CLR, 0, 1, + VLP_CLK_CFG_UPDATE, TOP_MUX_DEBUG_ERR_FLAG_VLP_26M_SHIFT), + MUX_CLR_SET_UPD(CLK_VLP_DPMSRDMA, "vlp_dpmsrdma", + vlp_dpmsrdma_parents, VLP_CLK_CFG_7, VLP_CLK_CFG_7_SET, + VLP_CLK_CFG_7_CLR, 8, 1, + VLP_CLK_CFG_UPDATE, TOP_MUX_DPMSRDMA_SHIFT), + MUX_CLR_SET_UPD(CLK_VLP_VLP_PBUS_156M, "vlp_vlp_pbus_156m", + vlp_vlp_pbus_156m_parents, VLP_CLK_CFG_7, VLP_CLK_CFG_7_SET, + VLP_CLK_CFG_7_CLR, 16, 2, + VLP_CLK_CFG_UPDATE, TOP_MUX_VLP_PBUS_156M_SHIFT), + MUX_CLR_SET_UPD(CLK_VLP_SPM, "vlp_spm", + vlp_spm_parents, VLP_CLK_CFG_7, VLP_CLK_CFG_7_SET, + VLP_CLK_CFG_7_CLR, 24, 1, + VLP_CLK_CFG_UPDATE1, TOP_MUX_SPM_SHIFT), + /* VLP_CLK_CFG_8 */ + MUX_GATE_FENC_CLR_SET_UPD(CLK_VLP_MMINFRA, "vlp_mminfra", vlp_mminfra_parents, + VLP_CLK_CFG_8, VLP_CLK_CFG_8_SET, VLP_CLK_CFG_8_CLR, + 0, 2, 7, VLP_CLK_CFG_UPDATE1, TOP_MUX_MMINFRA_VLP_SHIFT, + VLP_OCIC_FENC_STATUS_MON_1, 31), + MUX_GATE_FENC_CLR_SET_UPD(CLK_VLP_USB_TOP, "vlp_usb", vlp_usb_parents, + VLP_CLK_CFG_8, VLP_CLK_CFG_8_SET, VLP_CLK_CFG_8_CLR, + 8, 1, 15, VLP_CLK_CFG_UPDATE1, TOP_MUX_USB_TOP_SHIFT, + VLP_OCIC_FENC_STATUS_MON_1, 30), + MUX_GATE_FENC_CLR_SET_UPD(CLK_VLP_USB_XHCI, "vlp_usb_xhci", vlp_usb_parents, + VLP_CLK_CFG_8, VLP_CLK_CFG_8_SET, VLP_CLK_CFG_8_CLR, + 16, 1, 23, VLP_CLK_CFG_UPDATE1, TOP_MUX_SSUSB_XHCI_SHIFT, + VLP_OCIC_FENC_STATUS_MON_1, 29), + MUX_CLR_SET_UPD(CLK_VLP_NOC_VLP, "vlp_noc_vlp", + vlp_noc_vlp_parents, VLP_CLK_CFG_8, VLP_CLK_CFG_8_SET, + VLP_CLK_CFG_8_CLR, 24, 2, + VLP_CLK_CFG_UPDATE1, TOP_MUX_NOC_VLP_SHIFT), + /* VLP_CLK_CFG_9 */ + MUX_GATE_FENC_CLR_SET_UPD_INDEXED(CLK_VLP_AUDIO_H, "vlp_audio_h", + vlp_audio_h_parents, vlp_aud_parent_index, + VLP_CLK_CFG_9, VLP_CLK_CFG_9_SET, VLP_CLK_CFG_9_CLR, + 0, 2, 7, VLP_CLK_CFG_UPDATE1, TOP_MUX_AUDIO_H_SHIFT, + VLP_OCIC_FENC_STATUS_MON_1, 27), + MUX_GATE_FENC_CLR_SET_UPD_INDEXED(CLK_VLP_AUD_ENGEN1, "vlp_aud_engen1", + vlp_aud_engen1_parents, vlp_aud_parent_index, + VLP_CLK_CFG_9, VLP_CLK_CFG_9_SET, VLP_CLK_CFG_9_CLR, + 8, 2, 15, VLP_CLK_CFG_UPDATE1, TOP_MUX_AUD_ENGEN1_SHIFT, + VLP_OCIC_FENC_STATUS_MON_1, 26), + MUX_GATE_FENC_CLR_SET_UPD_INDEXED(CLK_VLP_AUD_ENGEN2, "vlp_aud_engen2", + vlp_aud_engen2_parents, vlp_aud_parent_index, + VLP_CLK_CFG_9, VLP_CLK_CFG_9_SET, VLP_CLK_CFG_9_CLR, + 16, 2, 23, VLP_CLK_CFG_UPDATE1, TOP_MUX_AUD_ENGEN2_SHIFT, + VLP_OCIC_FENC_STATUS_MON_1, 25), + MUX_GATE_FENC_CLR_SET_UPD_INDEXED(CLK_VLP_AUD_INTBUS, "vlp_aud_intbus", + vlp_aud_intbus_parents, vlp_aud_parent_index, + VLP_CLK_CFG_9, VLP_CLK_CFG_9_SET, VLP_CLK_CFG_9_CLR, + 24, 2, 31, VLP_CLK_CFG_UPDATE1, TOP_MUX_AUD_INTBUS_SHIFT, + VLP_OCIC_FENC_STATUS_MON_1, 24), + /* VLP_CLK_CFG_10 */ + MUX_CLR_SET_UPD(CLK_VLP_SPVLP_26M, "vlp_spvlp_26m", + vlp_spvlp_26m_parents, VLP_CLK_CFG_10, VLP_CLK_CFG_10_SET, + VLP_CLK_CFG_10_CLR, 0, 1, + VLP_CLK_CFG_UPDATE1, TOP_MUX_SPU_VLP_26M_SHIFT), + MUX_CLR_SET_UPD(CLK_VLP_SPU0_VLP, "vlp_spu0_vlp", + vlp_spu0_vlp_parents, VLP_CLK_CFG_10, VLP_CLK_CFG_10_SET, + VLP_CLK_CFG_10_CLR, 8, 3, + VLP_CLK_CFG_UPDATE1, TOP_MUX_SPU0_VLP_SHIFT), + MUX_CLR_SET_UPD(CLK_VLP_SPU1_VLP, "vlp_spu1_vlp", + vlp_spu1_vlp_parents, VLP_CLK_CFG_10, VLP_CLK_CFG_10_SET, + VLP_CLK_CFG_10_CLR, 16, 3, + VLP_CLK_CFG_UPDATE1, TOP_MUX_SPU1_VLP_SHIFT), +}; + +static const struct mtk_pll_data vlp_plls[] = { + PLL_FENC(CLK_VLP_APLL1, "vlp_apll1", VLP_APLL1_CON0, 0x0358, 1, 0, + VLP_APLL1_CON1, 24, VLP_APLL1_CON2, 0, 32, 0), + PLL_FENC(CLK_VLP_APLL2, "vlp_apll2", VLP_APLL2_CON0, 0x0358, 0, 0, + VLP_APLL2_CON1, 24, VLP_APLL2_CON2, 0, 32, 1), +}; + +static const struct regmap_config vlpckgen_regmap_config = { + .reg_bits = 32, + .val_bits = 32, + .reg_stride = 4, + .max_register = 0x1000, + .fast_io = true, +}; + +static int clk_mt8196_vlp_probe(struct platform_device *pdev) +{ + static void __iomem *base; + struct clk_hw_onecell_data *clk_data; + int r; + struct device_node *node = pdev->dev.of_node; + struct device *dev = &pdev->dev; + struct regmap *regmap; + + clk_data = mtk_alloc_clk_data(ARRAY_SIZE(vlp_muxes) + + ARRAY_SIZE(vlp_plls) + + ARRAY_SIZE(vlp_divs)); + if (!clk_data) + return -ENOMEM; + + base = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(base)) + return PTR_ERR(base); + + regmap = devm_regmap_init_mmio(dev, base, &vlpckgen_regmap_config); + if (IS_ERR(regmap)) + return PTR_ERR(regmap); + + r = mtk_clk_register_factors(vlp_divs, ARRAY_SIZE(vlp_divs), clk_data); + if (r) + goto free_clk_data; + + r = mtk_clk_register_muxes(&pdev->dev, vlp_muxes, ARRAY_SIZE(vlp_muxes), + node, &mt8196_clk_vlp_lock, clk_data); + if (r) + goto unregister_factors; + + r = mtk_clk_register_plls(node, vlp_plls, ARRAY_SIZE(vlp_plls), + clk_data); + if (r) + goto unregister_muxes; + + r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data); + if (r) + goto unregister_plls; + + platform_set_drvdata(pdev, clk_data); + + /* Initialize APLL tuner registers */ + regmap_write(regmap, VLP_APLL1_TUNER_CON0, VLP_APLL1_TUNER_CON0_VALUE); + regmap_write(regmap, VLP_APLL2_TUNER_CON0, VLP_APLL2_TUNER_CON0_VALUE); + + return r; + +unregister_plls: + mtk_clk_unregister_plls(vlp_plls, ARRAY_SIZE(vlp_plls), clk_data); +unregister_muxes: + mtk_clk_unregister_muxes(vlp_muxes, ARRAY_SIZE(vlp_muxes), clk_data); +unregister_factors: + mtk_clk_unregister_factors(vlp_divs, ARRAY_SIZE(vlp_divs), clk_data); +free_clk_data: + mtk_free_clk_data(clk_data); + + return r; +} + +static void clk_mt8196_vlp_remove(struct platform_device *pdev) +{ + struct clk_hw_onecell_data *clk_data = platform_get_drvdata(pdev); + struct device_node *node = pdev->dev.of_node; + + of_clk_del_provider(node); + mtk_clk_unregister_plls(vlp_plls, ARRAY_SIZE(vlp_plls), clk_data); + mtk_clk_unregister_muxes(vlp_muxes, ARRAY_SIZE(vlp_muxes), clk_data); + mtk_clk_unregister_factors(vlp_divs, ARRAY_SIZE(vlp_divs), clk_data); + mtk_free_clk_data(clk_data); +} + +static const struct of_device_id of_match_clk_mt8196_vlp_ck[] = { + { .compatible = "mediatek,mt8196-vlpckgen" }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(of, of_match_clk_mt8196_vlp_ck); + +static struct platform_driver clk_mt8196_vlp_drv = { + .probe = clk_mt8196_vlp_probe, + .remove = clk_mt8196_vlp_remove, + .driver = { + .name = "clk-mt8196-vlpck", + .of_match_table = of_match_clk_mt8196_vlp_ck, + }, +}; + +MODULE_DESCRIPTION("MediaTek MT8196 VLP clock generator driver"); +module_platform_driver(clk_mt8196_vlp_drv); +MODULE_LICENSE("GPL"); diff --git a/drivers/clk/mediatek/clk-mtk.c b/drivers/clk/mediatek/clk-mtk.c index ba1d1c495bc2..19cd27941747 100644 --- a/drivers/clk/mediatek/clk-mtk.c +++ b/drivers/clk/mediatek/clk-mtk.c @@ -685,4 +685,20 @@ void mtk_clk_simple_remove(struct platform_device *pdev) } EXPORT_SYMBOL_GPL(mtk_clk_simple_remove); +struct regmap *mtk_clk_get_hwv_regmap(struct device_node *node) +{ + struct device_node *hwv_node; + struct regmap *regmap_hwv; + + hwv_node = of_parse_phandle(node, "mediatek,hardware-voter", 0); + if (!hwv_node) + return NULL; + + regmap_hwv = device_node_to_regmap(hwv_node); + of_node_put(hwv_node); + + return regmap_hwv; +} +EXPORT_SYMBOL_GPL(mtk_clk_get_hwv_regmap); + MODULE_LICENSE("GPL"); diff --git a/drivers/clk/mediatek/clk-mtk.h b/drivers/clk/mediatek/clk-mtk.h index c17fe1c2d732..5417b9264e6d 100644 --- a/drivers/clk/mediatek/clk-mtk.h +++ b/drivers/clk/mediatek/clk-mtk.h @@ -20,6 +20,8 @@ #define MHZ (1000 * 1000) +#define MTK_WAIT_HWV_DONE_US 30 + struct platform_device; /* @@ -173,6 +175,25 @@ struct mtk_composite { .flags = 0, \ } +#define MUX_DIV_GATE(_id, _name, _parents, \ + _mux_reg, _mux_shift, _mux_width, \ + _div_reg, _div_shift, _div_width, \ + _gate_reg, _gate_shift) { \ + .id = _id, \ + .name = _name, \ + .parent_names = _parents, \ + .num_parents = ARRAY_SIZE(_parents), \ + .mux_reg = _mux_reg, \ + .mux_shift = _mux_shift, \ + .mux_width = _mux_width, \ + .divider_reg = _div_reg, \ + .divider_shift = _div_shift, \ + .divider_width = _div_width, \ + .gate_reg = _gate_reg, \ + .gate_shift = _gate_shift, \ + .flags = CLK_SET_RATE_PARENT, \ + } + int mtk_clk_register_composites(struct device *dev, const struct mtk_composite *mcs, int num, void __iomem *base, spinlock_t *lock, @@ -245,5 +266,6 @@ int mtk_clk_pdev_probe(struct platform_device *pdev); void mtk_clk_pdev_remove(struct platform_device *pdev); int mtk_clk_simple_probe(struct platform_device *pdev); void mtk_clk_simple_remove(struct platform_device *pdev); +struct regmap *mtk_clk_get_hwv_regmap(struct device_node *node); #endif /* __DRV_CLK_MTK_H */ diff --git a/drivers/clk/mediatek/clk-mux.c b/drivers/clk/mediatek/clk-mux.c index 60990296450b..c5af6dc078a3 100644 --- a/drivers/clk/mediatek/clk-mux.c +++ b/drivers/clk/mediatek/clk-mux.c @@ -8,6 +8,7 @@ #include <linux/clk-provider.h> #include <linux/compiler_types.h> #include <linux/container_of.h> +#include <linux/dev_printk.h> #include <linux/err.h> #include <linux/mfd/syscon.h> #include <linux/module.h> @@ -15,11 +16,15 @@ #include <linux/spinlock.h> #include <linux/slab.h> +#include "clk-mtk.h" #include "clk-mux.h" +#define MTK_WAIT_FENC_DONE_US 30 + struct mtk_clk_mux { struct clk_hw hw; struct regmap *regmap; + struct regmap *regmap_hwv; const struct mtk_mux *data; spinlock_t *lock; bool reparent; @@ -30,6 +35,33 @@ static inline struct mtk_clk_mux *to_mtk_clk_mux(struct clk_hw *hw) return container_of(hw, struct mtk_clk_mux, hw); } +static int mtk_clk_mux_fenc_enable_setclr(struct clk_hw *hw) +{ + struct mtk_clk_mux *mux = to_mtk_clk_mux(hw); + unsigned long flags; + u32 val; + int ret; + + if (mux->lock) + spin_lock_irqsave(mux->lock, flags); + else + __acquire(mux->lock); + + regmap_write(mux->regmap, mux->data->clr_ofs, + BIT(mux->data->gate_shift)); + + ret = regmap_read_poll_timeout_atomic(mux->regmap, mux->data->fenc_sta_mon_ofs, + val, val & BIT(mux->data->fenc_shift), 1, + MTK_WAIT_FENC_DONE_US); + + if (mux->lock) + spin_unlock_irqrestore(mux->lock, flags); + else + __release(mux->lock); + + return ret; +} + static int mtk_clk_mux_enable_setclr(struct clk_hw *hw) { struct mtk_clk_mux *mux = to_mtk_clk_mux(hw); @@ -70,6 +102,16 @@ static void mtk_clk_mux_disable_setclr(struct clk_hw *hw) BIT(mux->data->gate_shift)); } +static int mtk_clk_mux_fenc_is_enabled(struct clk_hw *hw) +{ + struct mtk_clk_mux *mux = to_mtk_clk_mux(hw); + u32 val; + + regmap_read(mux->regmap, mux->data->fenc_sta_mon_ofs, &val); + + return !!(val & BIT(mux->data->fenc_shift)); +} + static int mtk_clk_mux_is_enabled(struct clk_hw *hw) { struct mtk_clk_mux *mux = to_mtk_clk_mux(hw); @@ -80,6 +122,41 @@ static int mtk_clk_mux_is_enabled(struct clk_hw *hw) return (val & BIT(mux->data->gate_shift)) == 0; } +static int mtk_clk_mux_hwv_fenc_enable(struct clk_hw *hw) +{ + struct mtk_clk_mux *mux = to_mtk_clk_mux(hw); + u32 val; + int ret; + + regmap_write(mux->regmap_hwv, mux->data->hwv_set_ofs, + BIT(mux->data->gate_shift)); + + ret = regmap_read_poll_timeout_atomic(mux->regmap_hwv, mux->data->hwv_sta_ofs, + val, val & BIT(mux->data->gate_shift), 0, + MTK_WAIT_HWV_DONE_US); + if (ret) + return ret; + + ret = regmap_read_poll_timeout_atomic(mux->regmap, mux->data->fenc_sta_mon_ofs, + val, val & BIT(mux->data->fenc_shift), 1, + MTK_WAIT_FENC_DONE_US); + + return ret; +} + +static void mtk_clk_mux_hwv_disable(struct clk_hw *hw) +{ + struct mtk_clk_mux *mux = to_mtk_clk_mux(hw); + u32 val; + + regmap_write(mux->regmap_hwv, mux->data->hwv_clr_ofs, + BIT(mux->data->gate_shift)); + + regmap_read_poll_timeout_atomic(mux->regmap_hwv, mux->data->hwv_sta_ofs, + val, (val & BIT(mux->data->gate_shift)), + 0, MTK_WAIT_HWV_DONE_US); +} + static u8 mtk_clk_mux_get_parent(struct clk_hw *hw) { struct mtk_clk_mux *mux = to_mtk_clk_mux(hw); @@ -146,9 +223,15 @@ static int mtk_clk_mux_set_parent_setclr_lock(struct clk_hw *hw, u8 index) static int mtk_clk_mux_determine_rate(struct clk_hw *hw, struct clk_rate_request *req) { - struct mtk_clk_mux *mux = to_mtk_clk_mux(hw); + return clk_mux_determine_rate_flags(hw, req, 0); +} + +static bool mtk_clk_mux_uses_hwv(const struct clk_ops *ops) +{ + if (ops == &mtk_mux_gate_hwv_fenc_clr_set_upd_ops) + return true; - return clk_mux_determine_rate_flags(hw, req, mux->data->flags); + return false; } const struct clk_ops mtk_mux_clr_set_upd_ops = { @@ -168,9 +251,30 @@ const struct clk_ops mtk_mux_gate_clr_set_upd_ops = { }; EXPORT_SYMBOL_GPL(mtk_mux_gate_clr_set_upd_ops); +const struct clk_ops mtk_mux_gate_fenc_clr_set_upd_ops = { + .enable = mtk_clk_mux_fenc_enable_setclr, + .disable = mtk_clk_mux_disable_setclr, + .is_enabled = mtk_clk_mux_fenc_is_enabled, + .get_parent = mtk_clk_mux_get_parent, + .set_parent = mtk_clk_mux_set_parent_setclr_lock, + .determine_rate = mtk_clk_mux_determine_rate, +}; +EXPORT_SYMBOL_GPL(mtk_mux_gate_fenc_clr_set_upd_ops); + +const struct clk_ops mtk_mux_gate_hwv_fenc_clr_set_upd_ops = { + .enable = mtk_clk_mux_hwv_fenc_enable, + .disable = mtk_clk_mux_hwv_disable, + .is_enabled = mtk_clk_mux_fenc_is_enabled, + .get_parent = mtk_clk_mux_get_parent, + .set_parent = mtk_clk_mux_set_parent_setclr_lock, + .determine_rate = mtk_clk_mux_determine_rate, +}; +EXPORT_SYMBOL_GPL(mtk_mux_gate_hwv_fenc_clr_set_upd_ops); + static struct clk_hw *mtk_clk_register_mux(struct device *dev, const struct mtk_mux *mux, struct regmap *regmap, + struct regmap *regmap_hwv, spinlock_t *lock) { struct mtk_clk_mux *clk_mux; @@ -186,8 +290,13 @@ static struct clk_hw *mtk_clk_register_mux(struct device *dev, init.parent_names = mux->parent_names; init.num_parents = mux->num_parents; init.ops = mux->ops; + if (mtk_clk_mux_uses_hwv(init.ops) && !regmap_hwv) + return dev_err_ptr_probe( + dev, -ENXIO, + "regmap not found for hardware voter clocks\n"); clk_mux->regmap = regmap; + clk_mux->regmap_hwv = regmap_hwv; clk_mux->data = mux; clk_mux->lock = lock; clk_mux->hw.init = &init; @@ -220,6 +329,7 @@ int mtk_clk_register_muxes(struct device *dev, struct clk_hw_onecell_data *clk_data) { struct regmap *regmap; + struct regmap *regmap_hwv; struct clk_hw *hw; int i; @@ -229,6 +339,12 @@ int mtk_clk_register_muxes(struct device *dev, return PTR_ERR(regmap); } + regmap_hwv = mtk_clk_get_hwv_regmap(node); + if (IS_ERR(regmap_hwv)) + return dev_err_probe( + dev, PTR_ERR(regmap_hwv), + "Cannot find hardware voter regmap for %pOF\n", node); + for (i = 0; i < num; i++) { const struct mtk_mux *mux = &muxes[i]; @@ -238,7 +354,7 @@ int mtk_clk_register_muxes(struct device *dev, continue; } - hw = mtk_clk_register_mux(dev, mux, regmap, lock); + hw = mtk_clk_register_mux(dev, mux, regmap, regmap_hwv, lock); if (IS_ERR(hw)) { pr_err("Failed to register clk %s: %pe\n", mux->name, diff --git a/drivers/clk/mediatek/clk-mux.h b/drivers/clk/mediatek/clk-mux.h index 943ad1d7ce4b..151e56dcf884 100644 --- a/drivers/clk/mediatek/clk-mux.h +++ b/drivers/clk/mediatek/clk-mux.h @@ -29,10 +29,16 @@ struct mtk_mux { u32 clr_ofs; u32 upd_ofs; + u32 hwv_set_ofs; + u32 hwv_clr_ofs; + u32 hwv_sta_ofs; + u32 fenc_sta_mon_ofs; + u8 mux_shift; u8 mux_width; u8 gate_shift; s8 upd_shift; + u8 fenc_shift; const struct clk_ops *ops; signed char num_parents; @@ -77,6 +83,8 @@ struct mtk_mux { extern const struct clk_ops mtk_mux_clr_set_upd_ops; extern const struct clk_ops mtk_mux_gate_clr_set_upd_ops; +extern const struct clk_ops mtk_mux_gate_fenc_clr_set_upd_ops; +extern const struct clk_ops mtk_mux_gate_hwv_fenc_clr_set_upd_ops; #define MUX_GATE_CLR_SET_UPD_FLAGS(_id, _name, _parents, _mux_ofs, \ _mux_set_ofs, _mux_clr_ofs, _shift, _width, \ @@ -118,6 +126,85 @@ extern const struct clk_ops mtk_mux_gate_clr_set_upd_ops; 0, _upd_ofs, _upd, CLK_SET_RATE_PARENT, \ mtk_mux_clr_set_upd_ops) +#define MUX_GATE_HWV_FENC_CLR_SET_UPD_FLAGS(_id, _name, _parents, \ + _mux_ofs, _mux_set_ofs, _mux_clr_ofs, \ + _hwv_sta_ofs, _hwv_set_ofs, _hwv_clr_ofs, \ + _shift, _width, _gate, _upd_ofs, _upd, \ + _fenc_sta_mon_ofs, _fenc, _flags) { \ + .id = _id, \ + .name = _name, \ + .mux_ofs = _mux_ofs, \ + .set_ofs = _mux_set_ofs, \ + .clr_ofs = _mux_clr_ofs, \ + .hwv_sta_ofs = _hwv_sta_ofs, \ + .hwv_set_ofs = _hwv_set_ofs, \ + .hwv_clr_ofs = _hwv_clr_ofs, \ + .upd_ofs = _upd_ofs, \ + .fenc_sta_mon_ofs = _fenc_sta_mon_ofs, \ + .mux_shift = _shift, \ + .mux_width = _width, \ + .gate_shift = _gate, \ + .upd_shift = _upd, \ + .fenc_shift = _fenc, \ + .parent_names = _parents, \ + .num_parents = ARRAY_SIZE(_parents), \ + .flags = _flags, \ + .ops = &mtk_mux_gate_hwv_fenc_clr_set_upd_ops, \ + } + +#define MUX_GATE_HWV_FENC_CLR_SET_UPD(_id, _name, _parents, \ + _mux_ofs, _mux_set_ofs, _mux_clr_ofs, \ + _hwv_sta_ofs, _hwv_set_ofs, _hwv_clr_ofs, \ + _shift, _width, _gate, _upd_ofs, _upd, \ + _fenc_sta_mon_ofs, _fenc) \ + MUX_GATE_HWV_FENC_CLR_SET_UPD_FLAGS(_id, _name, _parents, \ + _mux_ofs, _mux_set_ofs, _mux_clr_ofs, \ + _hwv_sta_ofs, _hwv_set_ofs, _hwv_clr_ofs, \ + _shift, _width, _gate, _upd_ofs, _upd, \ + _fenc_sta_mon_ofs, _fenc, 0) + +#define MUX_GATE_FENC_CLR_SET_UPD_FLAGS(_id, _name, _parents, _paridx, \ + _num_parents, _mux_ofs, _mux_set_ofs, _mux_clr_ofs, \ + _shift, _width, _gate, _upd_ofs, _upd, \ + _fenc_sta_mon_ofs, _fenc, _flags) { \ + .id = _id, \ + .name = _name, \ + .mux_ofs = _mux_ofs, \ + .set_ofs = _mux_set_ofs, \ + .clr_ofs = _mux_clr_ofs, \ + .upd_ofs = _upd_ofs, \ + .fenc_sta_mon_ofs = _fenc_sta_mon_ofs, \ + .mux_shift = _shift, \ + .mux_width = _width, \ + .gate_shift = _gate, \ + .upd_shift = _upd, \ + .fenc_shift = _fenc, \ + .parent_names = _parents, \ + .parent_index = _paridx, \ + .num_parents = _num_parents, \ + .flags = _flags, \ + .ops = &mtk_mux_gate_fenc_clr_set_upd_ops, \ + } + +#define MUX_GATE_FENC_CLR_SET_UPD(_id, _name, _parents, \ + _mux_ofs, _mux_set_ofs, _mux_clr_ofs, \ + _shift, _width, _gate, _upd_ofs, _upd, \ + _fenc_sta_mon_ofs, _fenc) \ + MUX_GATE_FENC_CLR_SET_UPD_FLAGS(_id, _name, _parents, \ + NULL, ARRAY_SIZE(_parents), _mux_ofs, \ + _mux_set_ofs, _mux_clr_ofs, _shift, \ + _width, _gate, _upd_ofs, _upd, \ + _fenc_sta_mon_ofs, _fenc, 0) + +#define MUX_GATE_FENC_CLR_SET_UPD_INDEXED(_id, _name, _parents, _paridx, \ + _mux_ofs, _mux_set_ofs, _mux_clr_ofs, \ + _shift, _width, _gate, _upd_ofs, _upd, \ + _fenc_sta_mon_ofs, _fenc) \ + MUX_GATE_FENC_CLR_SET_UPD_FLAGS(_id, _name, _parents, _paridx, \ + ARRAY_SIZE(_paridx), _mux_ofs, _mux_set_ofs, \ + _mux_clr_ofs, _shift, _width, _gate, _upd_ofs, _upd, \ + _fenc_sta_mon_ofs, _fenc, 0) + int mtk_clk_register_muxes(struct device *dev, const struct mtk_mux *muxes, int num, struct device_node *node, diff --git a/drivers/clk/mediatek/clk-pll.c b/drivers/clk/mediatek/clk-pll.c index ce453e1718e5..cd2b6ce551c6 100644 --- a/drivers/clk/mediatek/clk-pll.c +++ b/drivers/clk/mediatek/clk-pll.c @@ -37,6 +37,13 @@ int mtk_pll_is_prepared(struct clk_hw *hw) return (readl(pll->en_addr) & BIT(pll->data->pll_en_bit)) != 0; } +static int mtk_pll_fenc_is_prepared(struct clk_hw *hw) +{ + struct mtk_clk_pll *pll = to_mtk_clk_pll(hw); + + return !!(readl(pll->fenc_addr) & BIT(pll->data->fenc_sta_bit)); +} + static unsigned long __mtk_pll_recalc_rate(struct mtk_clk_pll *pll, u32 fin, u32 pcw, int postdiv) { @@ -200,16 +207,19 @@ unsigned long mtk_pll_recalc_rate(struct clk_hw *hw, unsigned long parent_rate) return __mtk_pll_recalc_rate(pll, parent_rate, pcw, postdiv); } -long mtk_pll_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *prate) +int mtk_pll_determine_rate(struct clk_hw *hw, struct clk_rate_request *req) { struct mtk_clk_pll *pll = to_mtk_clk_pll(hw); u32 pcw = 0; int postdiv; - mtk_pll_calc_values(pll, &pcw, &postdiv, rate, *prate); + mtk_pll_calc_values(pll, &pcw, &postdiv, req->rate, + req->best_parent_rate); + + req->rate = __mtk_pll_recalc_rate(pll, req->best_parent_rate, pcw, + postdiv); - return __mtk_pll_recalc_rate(pll, *prate, pcw, postdiv); + return 0; } int mtk_pll_prepare(struct clk_hw *hw) @@ -274,14 +284,43 @@ void mtk_pll_unprepare(struct clk_hw *hw) writel(r, pll->pwr_addr); } +static int mtk_pll_prepare_setclr(struct clk_hw *hw) +{ + struct mtk_clk_pll *pll = to_mtk_clk_pll(hw); + + writel(BIT(pll->data->pll_en_bit), pll->en_set_addr); + + /* Wait 20us after enable for the PLL to stabilize */ + udelay(20); + + return 0; +} + +static void mtk_pll_unprepare_setclr(struct clk_hw *hw) +{ + struct mtk_clk_pll *pll = to_mtk_clk_pll(hw); + + writel(BIT(pll->data->pll_en_bit), pll->en_clr_addr); +} + const struct clk_ops mtk_pll_ops = { .is_prepared = mtk_pll_is_prepared, .prepare = mtk_pll_prepare, .unprepare = mtk_pll_unprepare, .recalc_rate = mtk_pll_recalc_rate, - .round_rate = mtk_pll_round_rate, + .determine_rate = mtk_pll_determine_rate, + .set_rate = mtk_pll_set_rate, +}; + +const struct clk_ops mtk_pll_fenc_clr_set_ops = { + .is_prepared = mtk_pll_fenc_is_prepared, + .prepare = mtk_pll_prepare_setclr, + .unprepare = mtk_pll_unprepare_setclr, + .recalc_rate = mtk_pll_recalc_rate, + .determine_rate = mtk_pll_determine_rate, .set_rate = mtk_pll_set_rate, }; +EXPORT_SYMBOL_GPL(mtk_pll_fenc_clr_set_ops); struct clk_hw *mtk_clk_register_pll_ops(struct mtk_clk_pll *pll, const struct mtk_pll_data *data, @@ -308,9 +347,15 @@ struct clk_hw *mtk_clk_register_pll_ops(struct mtk_clk_pll *pll, pll->en_addr = base + data->en_reg; else pll->en_addr = pll->base_addr + REG_CON0; + if (data->en_set_reg) + pll->en_set_addr = base + data->en_set_reg; + if (data->en_clr_reg) + pll->en_clr_addr = base + data->en_clr_reg; pll->hw.init = &init; pll->data = data; + pll->fenc_addr = base + data->fenc_sta_ofs; + init.name = data->name; init.flags = (data->flags & PLL_AO) ? CLK_IS_CRITICAL : 0; init.ops = pll_ops; @@ -333,12 +378,13 @@ struct clk_hw *mtk_clk_register_pll(const struct mtk_pll_data *data, { struct mtk_clk_pll *pll; struct clk_hw *hw; + const struct clk_ops *pll_ops = data->ops ? data->ops : &mtk_pll_ops; pll = kzalloc(sizeof(*pll), GFP_KERNEL); if (!pll) return ERR_PTR(-ENOMEM); - hw = mtk_clk_register_pll_ops(pll, data, base, &mtk_pll_ops); + hw = mtk_clk_register_pll_ops(pll, data, base, pll_ops); if (IS_ERR(hw)) kfree(pll); diff --git a/drivers/clk/mediatek/clk-pll.h b/drivers/clk/mediatek/clk-pll.h index 285c8db958b3..d71c150ce83e 100644 --- a/drivers/clk/mediatek/clk-pll.h +++ b/drivers/clk/mediatek/clk-pll.h @@ -29,6 +29,7 @@ struct mtk_pll_data { u32 reg; u32 pwr_reg; u32 en_mask; + u32 fenc_sta_ofs; u32 pd_reg; u32 tuner_reg; u32 tuner_en_reg; @@ -47,8 +48,11 @@ struct mtk_pll_data { const struct mtk_pll_div_table *div_table; const char *parent_name; u32 en_reg; + u32 en_set_reg; + u32 en_clr_reg; u8 pll_en_bit; /* Assume 0, indicates BIT(0) by default */ u8 pcw_chg_bit; + u8 fenc_sta_bit; }; /* @@ -68,6 +72,9 @@ struct mtk_clk_pll { void __iomem *pcw_addr; void __iomem *pcw_chg_addr; void __iomem *en_addr; + void __iomem *en_set_addr; + void __iomem *en_clr_addr; + void __iomem *fenc_addr; const struct mtk_pll_data *data; }; @@ -78,6 +85,7 @@ void mtk_clk_unregister_plls(const struct mtk_pll_data *plls, int num_plls, struct clk_hw_onecell_data *clk_data); extern const struct clk_ops mtk_pll_ops; +extern const struct clk_ops mtk_pll_fenc_clr_set_ops; static inline struct mtk_clk_pll *to_mtk_clk_pll(struct clk_hw *hw) { @@ -96,8 +104,7 @@ void mtk_pll_calc_values(struct mtk_clk_pll *pll, u32 *pcw, u32 *postdiv, u32 freq, u32 fin); int mtk_pll_set_rate(struct clk_hw *hw, unsigned long rate, unsigned long parent_rate); -long mtk_pll_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *prate); +int mtk_pll_determine_rate(struct clk_hw *hw, struct clk_rate_request *req); struct clk_hw *mtk_clk_register_pll_ops(struct mtk_clk_pll *pll, const struct mtk_pll_data *data, diff --git a/drivers/clk/mediatek/clk-pllfh.c b/drivers/clk/mediatek/clk-pllfh.c index 094ec8a26d66..83630ee07ee9 100644 --- a/drivers/clk/mediatek/clk-pllfh.c +++ b/drivers/clk/mediatek/clk-pllfh.c @@ -42,7 +42,7 @@ static const struct clk_ops mtk_pllfh_ops = { .prepare = mtk_pll_prepare, .unprepare = mtk_pll_unprepare, .recalc_rate = mtk_pll_recalc_rate, - .round_rate = mtk_pll_round_rate, + .determine_rate = mtk_pll_determine_rate, .set_rate = mtk_fhctl_set_rate, }; diff --git a/drivers/clk/meson/Kconfig b/drivers/clk/meson/Kconfig index 7197d23543b8..71481607a6d5 100644 --- a/drivers/clk/meson/Kconfig +++ b/drivers/clk/meson/Kconfig @@ -36,6 +36,8 @@ config COMMON_CLK_MESON_VCLK select COMMON_CLK_MESON_REGMAP config COMMON_CLK_MESON_CLKC_UTILS + select REGMAP + select MFD_SYSCON tristate config COMMON_CLK_MESON_AO_CLKC @@ -44,11 +46,6 @@ config COMMON_CLK_MESON_AO_CLKC select COMMON_CLK_MESON_CLKC_UTILS select RESET_CONTROLLER -config COMMON_CLK_MESON_EE_CLKC - tristate - select COMMON_CLK_MESON_REGMAP - select COMMON_CLK_MESON_CLKC_UTILS - config COMMON_CLK_MESON_CPU_DYNDIV tristate select COMMON_CLK_MESON_REGMAP @@ -73,12 +70,12 @@ config COMMON_CLK_GXBB depends on ARM64 default ARCH_MESON select COMMON_CLK_MESON_REGMAP + select COMMON_CLK_MESON_CLKC_UTILS select COMMON_CLK_MESON_DUALDIV select COMMON_CLK_MESON_VID_PLL_DIV select COMMON_CLK_MESON_MPLL select COMMON_CLK_MESON_PLL select COMMON_CLK_MESON_AO_CLKC - select COMMON_CLK_MESON_EE_CLKC select MFD_SYSCON help Support for the clock controller on AmLogic S905 devices, aka gxbb. @@ -89,11 +86,11 @@ config COMMON_CLK_AXG depends on ARM64 default ARCH_MESON select COMMON_CLK_MESON_REGMAP + select COMMON_CLK_MESON_CLKC_UTILS select COMMON_CLK_MESON_DUALDIV select COMMON_CLK_MESON_MPLL select COMMON_CLK_MESON_PLL select COMMON_CLK_MESON_AO_CLKC - select COMMON_CLK_MESON_EE_CLKC select MFD_SYSCON help Support for the clock controller on AmLogic A113D devices, aka axg. @@ -167,11 +164,11 @@ config COMMON_CLK_G12A depends on ARM64 default ARCH_MESON select COMMON_CLK_MESON_REGMAP + select COMMON_CLK_MESON_CLKC_UTILS select COMMON_CLK_MESON_DUALDIV select COMMON_CLK_MESON_MPLL select COMMON_CLK_MESON_PLL select COMMON_CLK_MESON_AO_CLKC - select COMMON_CLK_MESON_EE_CLKC select COMMON_CLK_MESON_CPU_DYNDIV select COMMON_CLK_MESON_VID_PLL_DIV select COMMON_CLK_MESON_VCLK diff --git a/drivers/clk/meson/Makefile b/drivers/clk/meson/Makefile index bc56a47931c1..c6998e752c68 100644 --- a/drivers/clk/meson/Makefile +++ b/drivers/clk/meson/Makefile @@ -5,7 +5,6 @@ obj-$(CONFIG_COMMON_CLK_MESON_CLKC_UTILS) += meson-clkc-utils.o obj-$(CONFIG_COMMON_CLK_MESON_AO_CLKC) += meson-aoclk.o obj-$(CONFIG_COMMON_CLK_MESON_CPU_DYNDIV) += clk-cpu-dyndiv.o obj-$(CONFIG_COMMON_CLK_MESON_DUALDIV) += clk-dualdiv.o -obj-$(CONFIG_COMMON_CLK_MESON_EE_CLKC) += meson-eeclk.o obj-$(CONFIG_COMMON_CLK_MESON_MPLL) += clk-mpll.o obj-$(CONFIG_COMMON_CLK_MESON_PHASE) += clk-phase.o obj-$(CONFIG_COMMON_CLK_MESON_PLL) += clk-pll.o diff --git a/drivers/clk/meson/a1-peripherals.c b/drivers/clk/meson/a1-peripherals.c index 1f5d445d44fe..5e0d58c01405 100644 --- a/drivers/clk/meson/a1-peripherals.c +++ b/drivers/clk/meson/a1-peripherals.c @@ -46,7 +46,7 @@ #define PSRAM_CLK_CTRL 0xf4 #define DMC_CLK_CTRL 0xf8 -static struct clk_regmap xtal_in = { +static struct clk_regmap a1_xtal_in = { .data = &(struct clk_regmap_gate_data){ .offset = SYS_OSCIN_CTRL, .bit_idx = 0, @@ -61,7 +61,7 @@ static struct clk_regmap xtal_in = { }, }; -static struct clk_regmap fixpll_in = { +static struct clk_regmap a1_fixpll_in = { .data = &(struct clk_regmap_gate_data){ .offset = SYS_OSCIN_CTRL, .bit_idx = 1, @@ -76,7 +76,7 @@ static struct clk_regmap fixpll_in = { }, }; -static struct clk_regmap usb_phy_in = { +static struct clk_regmap a1_usb_phy_in = { .data = &(struct clk_regmap_gate_data){ .offset = SYS_OSCIN_CTRL, .bit_idx = 2, @@ -91,7 +91,7 @@ static struct clk_regmap usb_phy_in = { }, }; -static struct clk_regmap usb_ctrl_in = { +static struct clk_regmap a1_usb_ctrl_in = { .data = &(struct clk_regmap_gate_data){ .offset = SYS_OSCIN_CTRL, .bit_idx = 3, @@ -106,7 +106,7 @@ static struct clk_regmap usb_ctrl_in = { }, }; -static struct clk_regmap hifipll_in = { +static struct clk_regmap a1_hifipll_in = { .data = &(struct clk_regmap_gate_data){ .offset = SYS_OSCIN_CTRL, .bit_idx = 4, @@ -121,7 +121,7 @@ static struct clk_regmap hifipll_in = { }, }; -static struct clk_regmap syspll_in = { +static struct clk_regmap a1_syspll_in = { .data = &(struct clk_regmap_gate_data){ .offset = SYS_OSCIN_CTRL, .bit_idx = 5, @@ -136,7 +136,7 @@ static struct clk_regmap syspll_in = { }, }; -static struct clk_regmap dds_in = { +static struct clk_regmap a1_dds_in = { .data = &(struct clk_regmap_gate_data){ .offset = SYS_OSCIN_CTRL, .bit_idx = 6, @@ -151,7 +151,7 @@ static struct clk_regmap dds_in = { }, }; -static struct clk_regmap rtc_32k_in = { +static struct clk_regmap a1_rtc_32k_in = { .data = &(struct clk_regmap_gate_data){ .offset = RTC_BY_OSCIN_CTRL0, .bit_idx = 31, @@ -166,7 +166,7 @@ static struct clk_regmap rtc_32k_in = { }, }; -static const struct meson_clk_dualdiv_param clk_32k_div_table[] = { +static const struct meson_clk_dualdiv_param a1_32k_div_table[] = { { .dual = 1, .n1 = 733, @@ -177,7 +177,7 @@ static const struct meson_clk_dualdiv_param clk_32k_div_table[] = { {} }; -static struct clk_regmap rtc_32k_div = { +static struct clk_regmap a1_rtc_32k_div = { .data = &(struct meson_clk_dualdiv_data){ .n1 = { .reg_off = RTC_BY_OSCIN_CTRL0, @@ -204,19 +204,19 @@ static struct clk_regmap rtc_32k_div = { .shift = 28, .width = 1, }, - .table = clk_32k_div_table, + .table = a1_32k_div_table, }, .hw.init = &(struct clk_init_data){ .name = "rtc_32k_div", .ops = &meson_clk_dualdiv_ops, .parent_hws = (const struct clk_hw *[]) { - &rtc_32k_in.hw + &a1_rtc_32k_in.hw }, .num_parents = 1, }, }; -static struct clk_regmap rtc_32k_xtal = { +static struct clk_regmap a1_rtc_32k_xtal = { .data = &(struct clk_regmap_gate_data){ .offset = RTC_BY_OSCIN_CTRL1, .bit_idx = 24, @@ -225,13 +225,13 @@ static struct clk_regmap rtc_32k_xtal = { .name = "rtc_32k_xtal", .ops = &clk_regmap_gate_ops, .parent_hws = (const struct clk_hw *[]) { - &rtc_32k_in.hw + &a1_rtc_32k_in.hw }, .num_parents = 1, }, }; -static struct clk_regmap rtc_32k_sel = { +static struct clk_regmap a1_rtc_32k_sel = { .data = &(struct clk_regmap_mux_data) { .offset = RTC_CTRL, .mask = 0x3, @@ -242,15 +242,15 @@ static struct clk_regmap rtc_32k_sel = { .name = "rtc_32k_sel", .ops = &clk_regmap_mux_ops, .parent_hws = (const struct clk_hw *[]) { - &rtc_32k_xtal.hw, - &rtc_32k_div.hw, + &a1_rtc_32k_xtal.hw, + &a1_rtc_32k_div.hw, }, .num_parents = 2, .flags = CLK_SET_RATE_PARENT, }, }; -static struct clk_regmap rtc = { +static struct clk_regmap a1_rtc = { .data = &(struct clk_regmap_gate_data){ .offset = RTC_BY_OSCIN_CTRL0, .bit_idx = 30, @@ -259,38 +259,38 @@ static struct clk_regmap rtc = { .name = "rtc", .ops = &clk_regmap_gate_ops, .parent_hws = (const struct clk_hw *[]) { - &rtc_32k_sel.hw + &a1_rtc_32k_sel.hw }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, }; -static u32 mux_table_sys[] = { 0, 1, 2, 3, 7 }; -static const struct clk_parent_data sys_parents[] = { +static u32 a1_sys_parents_val_table[] = { 0, 1, 2, 3, 7 }; +static const struct clk_parent_data a1_sys_parents[] = { { .fw_name = "xtal" }, { .fw_name = "fclk_div2" }, { .fw_name = "fclk_div3" }, { .fw_name = "fclk_div5" }, - { .hw = &rtc.hw }, + { .hw = &a1_rtc.hw }, }; -static struct clk_regmap sys_b_sel = { +static struct clk_regmap a1_sys_b_sel = { .data = &(struct clk_regmap_mux_data){ .offset = SYS_CLK_CTRL0, .mask = 0x7, .shift = 26, - .table = mux_table_sys, + .table = a1_sys_parents_val_table, }, .hw.init = &(struct clk_init_data){ .name = "sys_b_sel", .ops = &clk_regmap_mux_ro_ops, - .parent_data = sys_parents, - .num_parents = ARRAY_SIZE(sys_parents), + .parent_data = a1_sys_parents, + .num_parents = ARRAY_SIZE(a1_sys_parents), }, }; -static struct clk_regmap sys_b_div = { +static struct clk_regmap a1_sys_b_div = { .data = &(struct clk_regmap_div_data){ .offset = SYS_CLK_CTRL0, .shift = 16, @@ -300,14 +300,14 @@ static struct clk_regmap sys_b_div = { .name = "sys_b_div", .ops = &clk_regmap_divider_ro_ops, .parent_hws = (const struct clk_hw *[]) { - &sys_b_sel.hw + &a1_sys_b_sel.hw }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, }; -static struct clk_regmap sys_b = { +static struct clk_regmap a1_sys_b = { .data = &(struct clk_regmap_gate_data){ .offset = SYS_CLK_CTRL0, .bit_idx = 29, @@ -316,29 +316,29 @@ static struct clk_regmap sys_b = { .name = "sys_b", .ops = &clk_regmap_gate_ro_ops, .parent_hws = (const struct clk_hw *[]) { - &sys_b_div.hw + &a1_sys_b_div.hw }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, }; -static struct clk_regmap sys_a_sel = { +static struct clk_regmap a1_sys_a_sel = { .data = &(struct clk_regmap_mux_data){ .offset = SYS_CLK_CTRL0, .mask = 0x7, .shift = 10, - .table = mux_table_sys, + .table = a1_sys_parents_val_table, }, .hw.init = &(struct clk_init_data){ .name = "sys_a_sel", .ops = &clk_regmap_mux_ro_ops, - .parent_data = sys_parents, - .num_parents = ARRAY_SIZE(sys_parents), + .parent_data = a1_sys_parents, + .num_parents = ARRAY_SIZE(a1_sys_parents), }, }; -static struct clk_regmap sys_a_div = { +static struct clk_regmap a1_sys_a_div = { .data = &(struct clk_regmap_div_data){ .offset = SYS_CLK_CTRL0, .shift = 0, @@ -348,14 +348,14 @@ static struct clk_regmap sys_a_div = { .name = "sys_a_div", .ops = &clk_regmap_divider_ro_ops, .parent_hws = (const struct clk_hw *[]) { - &sys_a_sel.hw + &a1_sys_a_sel.hw }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, }; -static struct clk_regmap sys_a = { +static struct clk_regmap a1_sys_a = { .data = &(struct clk_regmap_gate_data){ .offset = SYS_CLK_CTRL0, .bit_idx = 13, @@ -364,14 +364,14 @@ static struct clk_regmap sys_a = { .name = "sys_a", .ops = &clk_regmap_gate_ro_ops, .parent_hws = (const struct clk_hw *[]) { - &sys_a_div.hw + &a1_sys_a_div.hw }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, }; -static struct clk_regmap sys = { +static struct clk_regmap a1_sys = { .data = &(struct clk_regmap_mux_data){ .offset = SYS_CLK_CTRL0, .mask = 0x1, @@ -381,8 +381,8 @@ static struct clk_regmap sys = { .name = "sys", .ops = &clk_regmap_mux_ro_ops, .parent_hws = (const struct clk_hw *[]) { - &sys_a.hw, - &sys_b.hw, + &a1_sys_a.hw, + &a1_sys_b.hw, }, .num_parents = 2, /* @@ -398,32 +398,32 @@ static struct clk_regmap sys = { }, }; -static u32 mux_table_dsp_ab[] = { 0, 1, 2, 3, 4, 7 }; -static const struct clk_parent_data dsp_ab_parent_data[] = { +static u32 a1_dsp_parents_val_table[] = { 0, 1, 2, 3, 4, 7 }; +static const struct clk_parent_data a1_dsp_parents[] = { { .fw_name = "xtal", }, { .fw_name = "fclk_div2", }, { .fw_name = "fclk_div3", }, { .fw_name = "fclk_div5", }, { .fw_name = "hifi_pll", }, - { .hw = &rtc.hw }, + { .hw = &a1_rtc.hw }, }; -static struct clk_regmap dspa_a_sel = { +static struct clk_regmap a1_dspa_a_sel = { .data = &(struct clk_regmap_mux_data){ .offset = DSPA_CLK_CTRL0, .mask = 0x7, .shift = 10, - .table = mux_table_dsp_ab, + .table = a1_dsp_parents_val_table, }, .hw.init = &(struct clk_init_data){ .name = "dspa_a_sel", .ops = &clk_regmap_mux_ops, - .parent_data = dsp_ab_parent_data, - .num_parents = ARRAY_SIZE(dsp_ab_parent_data), + .parent_data = a1_dsp_parents, + .num_parents = ARRAY_SIZE(a1_dsp_parents), }, }; -static struct clk_regmap dspa_a_div = { +static struct clk_regmap a1_dspa_a_div = { .data = &(struct clk_regmap_div_data){ .offset = DSPA_CLK_CTRL0, .shift = 0, @@ -433,14 +433,14 @@ static struct clk_regmap dspa_a_div = { .name = "dspa_a_div", .ops = &clk_regmap_divider_ops, .parent_hws = (const struct clk_hw *[]) { - &dspa_a_sel.hw + &a1_dspa_a_sel.hw }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, }; -static struct clk_regmap dspa_a = { +static struct clk_regmap a1_dspa_a = { .data = &(struct clk_regmap_gate_data){ .offset = DSPA_CLK_CTRL0, .bit_idx = 13, @@ -449,29 +449,29 @@ static struct clk_regmap dspa_a = { .name = "dspa_a", .ops = &clk_regmap_gate_ops, .parent_hws = (const struct clk_hw *[]) { - &dspa_a_div.hw + &a1_dspa_a_div.hw }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, }; -static struct clk_regmap dspa_b_sel = { +static struct clk_regmap a1_dspa_b_sel = { .data = &(struct clk_regmap_mux_data){ .offset = DSPA_CLK_CTRL0, .mask = 0x7, .shift = 26, - .table = mux_table_dsp_ab, + .table = a1_dsp_parents_val_table, }, .hw.init = &(struct clk_init_data){ .name = "dspa_b_sel", .ops = &clk_regmap_mux_ops, - .parent_data = dsp_ab_parent_data, - .num_parents = ARRAY_SIZE(dsp_ab_parent_data), + .parent_data = a1_dsp_parents, + .num_parents = ARRAY_SIZE(a1_dsp_parents), }, }; -static struct clk_regmap dspa_b_div = { +static struct clk_regmap a1_dspa_b_div = { .data = &(struct clk_regmap_div_data){ .offset = DSPA_CLK_CTRL0, .shift = 16, @@ -481,14 +481,14 @@ static struct clk_regmap dspa_b_div = { .name = "dspa_b_div", .ops = &clk_regmap_divider_ops, .parent_hws = (const struct clk_hw *[]) { - &dspa_b_sel.hw + &a1_dspa_b_sel.hw }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, }; -static struct clk_regmap dspa_b = { +static struct clk_regmap a1_dspa_b = { .data = &(struct clk_regmap_gate_data){ .offset = DSPA_CLK_CTRL0, .bit_idx = 29, @@ -497,14 +497,14 @@ static struct clk_regmap dspa_b = { .name = "dspa_b", .ops = &clk_regmap_gate_ops, .parent_hws = (const struct clk_hw *[]) { - &dspa_b_div.hw + &a1_dspa_b_div.hw }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, }; -static struct clk_regmap dspa_sel = { +static struct clk_regmap a1_dspa_sel = { .data = &(struct clk_regmap_mux_data){ .offset = DSPA_CLK_CTRL0, .mask = 0x1, @@ -514,15 +514,15 @@ static struct clk_regmap dspa_sel = { .name = "dspa_sel", .ops = &clk_regmap_mux_ops, .parent_hws = (const struct clk_hw *[]) { - &dspa_a.hw, - &dspa_b.hw, + &a1_dspa_a.hw, + &a1_dspa_b.hw, }, .num_parents = 2, .flags = CLK_SET_RATE_PARENT, }, }; -static struct clk_regmap dspa_en = { +static struct clk_regmap a1_dspa_en = { .data = &(struct clk_regmap_gate_data){ .offset = DSPA_CLK_EN, .bit_idx = 1, @@ -531,14 +531,14 @@ static struct clk_regmap dspa_en = { .name = "dspa_en", .ops = &clk_regmap_gate_ops, .parent_hws = (const struct clk_hw *[]) { - &dspa_sel.hw + &a1_dspa_sel.hw }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, }; -static struct clk_regmap dspa_en_nic = { +static struct clk_regmap a1_dspa_en_nic = { .data = &(struct clk_regmap_gate_data){ .offset = DSPA_CLK_EN, .bit_idx = 0, @@ -547,29 +547,29 @@ static struct clk_regmap dspa_en_nic = { .name = "dspa_en_nic", .ops = &clk_regmap_gate_ops, .parent_hws = (const struct clk_hw *[]) { - &dspa_sel.hw + &a1_dspa_sel.hw }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, }; -static struct clk_regmap dspb_a_sel = { +static struct clk_regmap a1_dspb_a_sel = { .data = &(struct clk_regmap_mux_data){ .offset = DSPB_CLK_CTRL0, .mask = 0x7, .shift = 10, - .table = mux_table_dsp_ab, + .table = a1_dsp_parents_val_table, }, .hw.init = &(struct clk_init_data){ .name = "dspb_a_sel", .ops = &clk_regmap_mux_ops, - .parent_data = dsp_ab_parent_data, - .num_parents = ARRAY_SIZE(dsp_ab_parent_data), + .parent_data = a1_dsp_parents, + .num_parents = ARRAY_SIZE(a1_dsp_parents), }, }; -static struct clk_regmap dspb_a_div = { +static struct clk_regmap a1_dspb_a_div = { .data = &(struct clk_regmap_div_data){ .offset = DSPB_CLK_CTRL0, .shift = 0, @@ -579,14 +579,14 @@ static struct clk_regmap dspb_a_div = { .name = "dspb_a_div", .ops = &clk_regmap_divider_ops, .parent_hws = (const struct clk_hw *[]) { - &dspb_a_sel.hw + &a1_dspb_a_sel.hw }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, }; -static struct clk_regmap dspb_a = { +static struct clk_regmap a1_dspb_a = { .data = &(struct clk_regmap_gate_data){ .offset = DSPB_CLK_CTRL0, .bit_idx = 13, @@ -595,29 +595,29 @@ static struct clk_regmap dspb_a = { .name = "dspb_a", .ops = &clk_regmap_gate_ops, .parent_hws = (const struct clk_hw *[]) { - &dspb_a_div.hw + &a1_dspb_a_div.hw }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, }; -static struct clk_regmap dspb_b_sel = { +static struct clk_regmap a1_dspb_b_sel = { .data = &(struct clk_regmap_mux_data){ .offset = DSPB_CLK_CTRL0, .mask = 0x7, .shift = 26, - .table = mux_table_dsp_ab, + .table = a1_dsp_parents_val_table, }, .hw.init = &(struct clk_init_data){ .name = "dspb_b_sel", .ops = &clk_regmap_mux_ops, - .parent_data = dsp_ab_parent_data, - .num_parents = ARRAY_SIZE(dsp_ab_parent_data), + .parent_data = a1_dsp_parents, + .num_parents = ARRAY_SIZE(a1_dsp_parents), }, }; -static struct clk_regmap dspb_b_div = { +static struct clk_regmap a1_dspb_b_div = { .data = &(struct clk_regmap_div_data){ .offset = DSPB_CLK_CTRL0, .shift = 16, @@ -627,14 +627,14 @@ static struct clk_regmap dspb_b_div = { .name = "dspb_b_div", .ops = &clk_regmap_divider_ops, .parent_hws = (const struct clk_hw *[]) { - &dspb_b_sel.hw + &a1_dspb_b_sel.hw }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, }; -static struct clk_regmap dspb_b = { +static struct clk_regmap a1_dspb_b = { .data = &(struct clk_regmap_gate_data){ .offset = DSPB_CLK_CTRL0, .bit_idx = 29, @@ -643,14 +643,14 @@ static struct clk_regmap dspb_b = { .name = "dspb_b", .ops = &clk_regmap_gate_ops, .parent_hws = (const struct clk_hw *[]) { - &dspb_b_div.hw + &a1_dspb_b_div.hw }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, }; -static struct clk_regmap dspb_sel = { +static struct clk_regmap a1_dspb_sel = { .data = &(struct clk_regmap_mux_data){ .offset = DSPB_CLK_CTRL0, .mask = 0x1, @@ -660,15 +660,15 @@ static struct clk_regmap dspb_sel = { .name = "dspb_sel", .ops = &clk_regmap_mux_ops, .parent_hws = (const struct clk_hw *[]) { - &dspb_a.hw, - &dspb_b.hw, + &a1_dspb_a.hw, + &a1_dspb_b.hw, }, .num_parents = 2, .flags = CLK_SET_RATE_PARENT, }, }; -static struct clk_regmap dspb_en = { +static struct clk_regmap a1_dspb_en = { .data = &(struct clk_regmap_gate_data){ .offset = DSPB_CLK_EN, .bit_idx = 1, @@ -677,14 +677,14 @@ static struct clk_regmap dspb_en = { .name = "dspb_en", .ops = &clk_regmap_gate_ops, .parent_hws = (const struct clk_hw *[]) { - &dspb_sel.hw + &a1_dspb_sel.hw }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, }; -static struct clk_regmap dspb_en_nic = { +static struct clk_regmap a1_dspb_en_nic = { .data = &(struct clk_regmap_gate_data){ .offset = DSPB_CLK_EN, .bit_idx = 0, @@ -693,14 +693,14 @@ static struct clk_regmap dspb_en_nic = { .name = "dspb_en_nic", .ops = &clk_regmap_gate_ops, .parent_hws = (const struct clk_hw *[]) { - &dspb_sel.hw + &a1_dspb_sel.hw }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, }; -static struct clk_regmap clk_24m = { +static struct clk_regmap a1_24m = { .data = &(struct clk_regmap_gate_data){ .offset = CLK12_24_CTRL, .bit_idx = 11, @@ -715,20 +715,20 @@ static struct clk_regmap clk_24m = { }, }; -static struct clk_fixed_factor clk_24m_div2 = { +static struct clk_fixed_factor a1_24m_div2 = { .mult = 1, .div = 2, .hw.init = &(struct clk_init_data){ .name = "24m_div2", .ops = &clk_fixed_factor_ops, .parent_hws = (const struct clk_hw *[]) { - &clk_24m.hw + &a1_24m.hw }, .num_parents = 1, }, }; -static struct clk_regmap clk_12m = { +static struct clk_regmap a1_12m = { .data = &(struct clk_regmap_gate_data){ .offset = CLK12_24_CTRL, .bit_idx = 10, @@ -737,13 +737,13 @@ static struct clk_regmap clk_12m = { .name = "12m", .ops = &clk_regmap_gate_ops, .parent_hws = (const struct clk_hw *[]) { - &clk_24m_div2.hw + &a1_24m_div2.hw }, .num_parents = 1, }, }; -static struct clk_regmap fclk_div2_divn_pre = { +static struct clk_regmap a1_fclk_div2_divn_pre = { .data = &(struct clk_regmap_div_data){ .offset = CLK12_24_CTRL, .shift = 0, @@ -759,7 +759,7 @@ static struct clk_regmap fclk_div2_divn_pre = { }, }; -static struct clk_regmap fclk_div2_divn = { +static struct clk_regmap a1_fclk_div2_divn = { .data = &(struct clk_regmap_gate_data){ .offset = CLK12_24_CTRL, .bit_idx = 12, @@ -768,7 +768,7 @@ static struct clk_regmap fclk_div2_divn = { .name = "fclk_div2_divn", .ops = &clk_regmap_gate_ops, .parent_hws = (const struct clk_hw *[]) { - &fclk_div2_divn_pre.hw + &a1_fclk_div2_divn_pre.hw }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, @@ -779,10 +779,10 @@ static struct clk_regmap fclk_div2_divn = { * the index 2 is sys_pll_div16, it will be implemented in the CPU clock driver, * the index 4 is the clock measurement source, it's not supported yet */ -static u32 gen_table[] = { 0, 1, 3, 5, 6, 7, 8 }; -static const struct clk_parent_data gen_parent_data[] = { +static u32 a1_gen_parents_val_table[] = { 0, 1, 3, 5, 6, 7, 8 }; +static const struct clk_parent_data a1_gen_parents[] = { { .fw_name = "xtal", }, - { .hw = &rtc.hw }, + { .hw = &a1_rtc.hw }, { .fw_name = "hifi_pll", }, { .fw_name = "fclk_div2", }, { .fw_name = "fclk_div3", }, @@ -790,18 +790,18 @@ static const struct clk_parent_data gen_parent_data[] = { { .fw_name = "fclk_div7", }, }; -static struct clk_regmap gen_sel = { +static struct clk_regmap a1_gen_sel = { .data = &(struct clk_regmap_mux_data){ .offset = GEN_CLK_CTRL, .mask = 0xf, .shift = 12, - .table = gen_table, + .table = a1_gen_parents_val_table, }, .hw.init = &(struct clk_init_data){ .name = "gen_sel", .ops = &clk_regmap_mux_ops, - .parent_data = gen_parent_data, - .num_parents = ARRAY_SIZE(gen_parent_data), + .parent_data = a1_gen_parents, + .num_parents = ARRAY_SIZE(a1_gen_parents), /* * The GEN clock can be connected to an external pad, so it * may be set up directly from the device tree. Additionally, @@ -813,7 +813,7 @@ static struct clk_regmap gen_sel = { }, }; -static struct clk_regmap gen_div = { +static struct clk_regmap a1_gen_div = { .data = &(struct clk_regmap_div_data){ .offset = GEN_CLK_CTRL, .shift = 0, @@ -823,14 +823,14 @@ static struct clk_regmap gen_div = { .name = "gen_div", .ops = &clk_regmap_divider_ops, .parent_hws = (const struct clk_hw *[]) { - &gen_sel.hw + &a1_gen_sel.hw }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, }; -static struct clk_regmap gen = { +static struct clk_regmap a1_gen = { .data = &(struct clk_regmap_gate_data){ .offset = GEN_CLK_CTRL, .bit_idx = 11, @@ -839,14 +839,14 @@ static struct clk_regmap gen = { .name = "gen", .ops = &clk_regmap_gate_ops, .parent_hws = (const struct clk_hw *[]) { - &gen_div.hw + &a1_gen_div.hw }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, }; -static struct clk_regmap saradc_sel = { +static struct clk_regmap a1_saradc_sel = { .data = &(struct clk_regmap_mux_data){ .offset = SAR_ADC_CLK_CTRL, .mask = 0x1, @@ -857,13 +857,13 @@ static struct clk_regmap saradc_sel = { .ops = &clk_regmap_mux_ops, .parent_data = (const struct clk_parent_data []) { { .fw_name = "xtal", }, - { .hw = &sys.hw, }, + { .hw = &a1_sys.hw, }, }, .num_parents = 2, }, }; -static struct clk_regmap saradc_div = { +static struct clk_regmap a1_saradc_div = { .data = &(struct clk_regmap_div_data){ .offset = SAR_ADC_CLK_CTRL, .shift = 0, @@ -873,14 +873,14 @@ static struct clk_regmap saradc_div = { .name = "saradc_div", .ops = &clk_regmap_divider_ops, .parent_hws = (const struct clk_hw *[]) { - &saradc_sel.hw + &a1_saradc_sel.hw }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, }; -static struct clk_regmap saradc = { +static struct clk_regmap a1_saradc = { .data = &(struct clk_regmap_gate_data){ .offset = SAR_ADC_CLK_CTRL, .bit_idx = 8, @@ -889,20 +889,20 @@ static struct clk_regmap saradc = { .name = "saradc", .ops = &clk_regmap_gate_ops, .parent_hws = (const struct clk_hw *[]) { - &saradc_div.hw + &a1_saradc_div.hw }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, }; -static const struct clk_parent_data pwm_abcd_parents[] = { +static const struct clk_parent_data a1_pwm_abcd_parents[] = { { .fw_name = "xtal", }, - { .hw = &sys.hw }, - { .hw = &rtc.hw }, + { .hw = &a1_sys.hw }, + { .hw = &a1_rtc.hw }, }; -static struct clk_regmap pwm_a_sel = { +static struct clk_regmap a1_pwm_a_sel = { .data = &(struct clk_regmap_mux_data){ .offset = PWM_CLK_AB_CTRL, .mask = 0x1, @@ -911,12 +911,12 @@ static struct clk_regmap pwm_a_sel = { .hw.init = &(struct clk_init_data){ .name = "pwm_a_sel", .ops = &clk_regmap_mux_ops, - .parent_data = pwm_abcd_parents, - .num_parents = ARRAY_SIZE(pwm_abcd_parents), + .parent_data = a1_pwm_abcd_parents, + .num_parents = ARRAY_SIZE(a1_pwm_abcd_parents), }, }; -static struct clk_regmap pwm_a_div = { +static struct clk_regmap a1_pwm_a_div = { .data = &(struct clk_regmap_div_data){ .offset = PWM_CLK_AB_CTRL, .shift = 0, @@ -926,14 +926,14 @@ static struct clk_regmap pwm_a_div = { .name = "pwm_a_div", .ops = &clk_regmap_divider_ops, .parent_hws = (const struct clk_hw *[]) { - &pwm_a_sel.hw + &a1_pwm_a_sel.hw }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, }; -static struct clk_regmap pwm_a = { +static struct clk_regmap a1_pwm_a = { .data = &(struct clk_regmap_gate_data){ .offset = PWM_CLK_AB_CTRL, .bit_idx = 8, @@ -942,14 +942,14 @@ static struct clk_regmap pwm_a = { .name = "pwm_a", .ops = &clk_regmap_gate_ops, .parent_hws = (const struct clk_hw *[]) { - &pwm_a_div.hw + &a1_pwm_a_div.hw }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, }; -static struct clk_regmap pwm_b_sel = { +static struct clk_regmap a1_pwm_b_sel = { .data = &(struct clk_regmap_mux_data){ .offset = PWM_CLK_AB_CTRL, .mask = 0x1, @@ -958,12 +958,12 @@ static struct clk_regmap pwm_b_sel = { .hw.init = &(struct clk_init_data){ .name = "pwm_b_sel", .ops = &clk_regmap_mux_ops, - .parent_data = pwm_abcd_parents, - .num_parents = ARRAY_SIZE(pwm_abcd_parents), + .parent_data = a1_pwm_abcd_parents, + .num_parents = ARRAY_SIZE(a1_pwm_abcd_parents), }, }; -static struct clk_regmap pwm_b_div = { +static struct clk_regmap a1_pwm_b_div = { .data = &(struct clk_regmap_div_data){ .offset = PWM_CLK_AB_CTRL, .shift = 16, @@ -973,14 +973,14 @@ static struct clk_regmap pwm_b_div = { .name = "pwm_b_div", .ops = &clk_regmap_divider_ops, .parent_hws = (const struct clk_hw *[]) { - &pwm_b_sel.hw + &a1_pwm_b_sel.hw }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, }; -static struct clk_regmap pwm_b = { +static struct clk_regmap a1_pwm_b = { .data = &(struct clk_regmap_gate_data){ .offset = PWM_CLK_AB_CTRL, .bit_idx = 24, @@ -989,14 +989,14 @@ static struct clk_regmap pwm_b = { .name = "pwm_b", .ops = &clk_regmap_gate_ops, .parent_hws = (const struct clk_hw *[]) { - &pwm_b_div.hw + &a1_pwm_b_div.hw }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, }; -static struct clk_regmap pwm_c_sel = { +static struct clk_regmap a1_pwm_c_sel = { .data = &(struct clk_regmap_mux_data){ .offset = PWM_CLK_CD_CTRL, .mask = 0x1, @@ -1005,12 +1005,12 @@ static struct clk_regmap pwm_c_sel = { .hw.init = &(struct clk_init_data){ .name = "pwm_c_sel", .ops = &clk_regmap_mux_ops, - .parent_data = pwm_abcd_parents, - .num_parents = ARRAY_SIZE(pwm_abcd_parents), + .parent_data = a1_pwm_abcd_parents, + .num_parents = ARRAY_SIZE(a1_pwm_abcd_parents), }, }; -static struct clk_regmap pwm_c_div = { +static struct clk_regmap a1_pwm_c_div = { .data = &(struct clk_regmap_div_data){ .offset = PWM_CLK_CD_CTRL, .shift = 0, @@ -1020,14 +1020,14 @@ static struct clk_regmap pwm_c_div = { .name = "pwm_c_div", .ops = &clk_regmap_divider_ops, .parent_hws = (const struct clk_hw *[]) { - &pwm_c_sel.hw + &a1_pwm_c_sel.hw }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, }; -static struct clk_regmap pwm_c = { +static struct clk_regmap a1_pwm_c = { .data = &(struct clk_regmap_gate_data){ .offset = PWM_CLK_CD_CTRL, .bit_idx = 8, @@ -1036,14 +1036,14 @@ static struct clk_regmap pwm_c = { .name = "pwm_c", .ops = &clk_regmap_gate_ops, .parent_hws = (const struct clk_hw *[]) { - &pwm_c_div.hw + &a1_pwm_c_div.hw }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, }; -static struct clk_regmap pwm_d_sel = { +static struct clk_regmap a1_pwm_d_sel = { .data = &(struct clk_regmap_mux_data){ .offset = PWM_CLK_CD_CTRL, .mask = 0x1, @@ -1052,12 +1052,12 @@ static struct clk_regmap pwm_d_sel = { .hw.init = &(struct clk_init_data){ .name = "pwm_d_sel", .ops = &clk_regmap_mux_ops, - .parent_data = pwm_abcd_parents, - .num_parents = ARRAY_SIZE(pwm_abcd_parents), + .parent_data = a1_pwm_abcd_parents, + .num_parents = ARRAY_SIZE(a1_pwm_abcd_parents), }, }; -static struct clk_regmap pwm_d_div = { +static struct clk_regmap a1_pwm_d_div = { .data = &(struct clk_regmap_div_data){ .offset = PWM_CLK_CD_CTRL, .shift = 16, @@ -1067,14 +1067,14 @@ static struct clk_regmap pwm_d_div = { .name = "pwm_d_div", .ops = &clk_regmap_divider_ops, .parent_hws = (const struct clk_hw *[]) { - &pwm_d_sel.hw + &a1_pwm_d_sel.hw }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, }; -static struct clk_regmap pwm_d = { +static struct clk_regmap a1_pwm_d = { .data = &(struct clk_regmap_gate_data){ .offset = PWM_CLK_CD_CTRL, .bit_idx = 24, @@ -1083,21 +1083,21 @@ static struct clk_regmap pwm_d = { .name = "pwm_d", .ops = &clk_regmap_gate_ops, .parent_hws = (const struct clk_hw *[]) { - &pwm_d_div.hw + &a1_pwm_d_div.hw }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, }; -static const struct clk_parent_data pwm_ef_parents[] = { +static const struct clk_parent_data a1_pwm_ef_parents[] = { { .fw_name = "xtal", }, - { .hw = &sys.hw }, + { .hw = &a1_sys.hw }, { .fw_name = "fclk_div5", }, - { .hw = &rtc.hw }, + { .hw = &a1_rtc.hw }, }; -static struct clk_regmap pwm_e_sel = { +static struct clk_regmap a1_pwm_e_sel = { .data = &(struct clk_regmap_mux_data){ .offset = PWM_CLK_EF_CTRL, .mask = 0x3, @@ -1106,12 +1106,12 @@ static struct clk_regmap pwm_e_sel = { .hw.init = &(struct clk_init_data){ .name = "pwm_e_sel", .ops = &clk_regmap_mux_ops, - .parent_data = pwm_ef_parents, - .num_parents = ARRAY_SIZE(pwm_ef_parents), + .parent_data = a1_pwm_ef_parents, + .num_parents = ARRAY_SIZE(a1_pwm_ef_parents), }, }; -static struct clk_regmap pwm_e_div = { +static struct clk_regmap a1_pwm_e_div = { .data = &(struct clk_regmap_div_data){ .offset = PWM_CLK_EF_CTRL, .shift = 0, @@ -1121,14 +1121,14 @@ static struct clk_regmap pwm_e_div = { .name = "pwm_e_div", .ops = &clk_regmap_divider_ops, .parent_hws = (const struct clk_hw *[]) { - &pwm_e_sel.hw + &a1_pwm_e_sel.hw }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, }; -static struct clk_regmap pwm_e = { +static struct clk_regmap a1_pwm_e = { .data = &(struct clk_regmap_gate_data){ .offset = PWM_CLK_EF_CTRL, .bit_idx = 8, @@ -1137,14 +1137,14 @@ static struct clk_regmap pwm_e = { .name = "pwm_e", .ops = &clk_regmap_gate_ops, .parent_hws = (const struct clk_hw *[]) { - &pwm_e_div.hw + &a1_pwm_e_div.hw }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, }; -static struct clk_regmap pwm_f_sel = { +static struct clk_regmap a1_pwm_f_sel = { .data = &(struct clk_regmap_mux_data){ .offset = PWM_CLK_EF_CTRL, .mask = 0x3, @@ -1153,12 +1153,12 @@ static struct clk_regmap pwm_f_sel = { .hw.init = &(struct clk_init_data){ .name = "pwm_f_sel", .ops = &clk_regmap_mux_ops, - .parent_data = pwm_ef_parents, - .num_parents = ARRAY_SIZE(pwm_ef_parents), + .parent_data = a1_pwm_ef_parents, + .num_parents = ARRAY_SIZE(a1_pwm_ef_parents), }, }; -static struct clk_regmap pwm_f_div = { +static struct clk_regmap a1_pwm_f_div = { .data = &(struct clk_regmap_div_data){ .offset = PWM_CLK_EF_CTRL, .shift = 16, @@ -1168,14 +1168,14 @@ static struct clk_regmap pwm_f_div = { .name = "pwm_f_div", .ops = &clk_regmap_divider_ops, .parent_hws = (const struct clk_hw *[]) { - &pwm_f_sel.hw + &a1_pwm_f_sel.hw }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, }; -static struct clk_regmap pwm_f = { +static struct clk_regmap a1_pwm_f = { .data = &(struct clk_regmap_gate_data){ .offset = PWM_CLK_EF_CTRL, .bit_idx = 24, @@ -1184,7 +1184,7 @@ static struct clk_regmap pwm_f = { .name = "pwm_f", .ops = &clk_regmap_gate_ops, .parent_hws = (const struct clk_hw *[]) { - &pwm_f_div.hw + &a1_pwm_f_div.hw }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, @@ -1200,14 +1200,14 @@ static struct clk_regmap pwm_f = { * --------------------|/ * 24M */ -static const struct clk_parent_data spicc_spifc_parents[] = { +static const struct clk_parent_data a1_spi_parents[] = { { .fw_name = "fclk_div2"}, { .fw_name = "fclk_div3"}, { .fw_name = "fclk_div5"}, { .fw_name = "hifi_pll" }, }; -static struct clk_regmap spicc_sel = { +static struct clk_regmap a1_spicc_sel = { .data = &(struct clk_regmap_mux_data){ .offset = SPICC_CLK_CTRL, .mask = 0x3, @@ -1216,12 +1216,12 @@ static struct clk_regmap spicc_sel = { .hw.init = &(struct clk_init_data){ .name = "spicc_sel", .ops = &clk_regmap_mux_ops, - .parent_data = spicc_spifc_parents, - .num_parents = ARRAY_SIZE(spicc_spifc_parents), + .parent_data = a1_spi_parents, + .num_parents = ARRAY_SIZE(a1_spi_parents), }, }; -static struct clk_regmap spicc_div = { +static struct clk_regmap a1_spicc_div = { .data = &(struct clk_regmap_div_data){ .offset = SPICC_CLK_CTRL, .shift = 0, @@ -1231,14 +1231,14 @@ static struct clk_regmap spicc_div = { .name = "spicc_div", .ops = &clk_regmap_divider_ops, .parent_hws = (const struct clk_hw *[]) { - &spicc_sel.hw + &a1_spicc_sel.hw }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, }; -static struct clk_regmap spicc_sel2 = { +static struct clk_regmap a1_spicc_sel2 = { .data = &(struct clk_regmap_mux_data){ .offset = SPICC_CLK_CTRL, .mask = 0x1, @@ -1248,7 +1248,7 @@ static struct clk_regmap spicc_sel2 = { .name = "spicc_sel2", .ops = &clk_regmap_mux_ops, .parent_data = (const struct clk_parent_data []) { - { .hw = &spicc_div.hw }, + { .hw = &a1_spicc_div.hw }, { .fw_name = "xtal", }, }, .num_parents = 2, @@ -1256,7 +1256,7 @@ static struct clk_regmap spicc_sel2 = { }, }; -static struct clk_regmap spicc = { +static struct clk_regmap a1_spicc = { .data = &(struct clk_regmap_gate_data){ .offset = SPICC_CLK_CTRL, .bit_idx = 8, @@ -1265,14 +1265,14 @@ static struct clk_regmap spicc = { .name = "spicc", .ops = &clk_regmap_gate_ops, .parent_hws = (const struct clk_hw *[]) { - &spicc_sel2.hw + &a1_spicc_sel2.hw }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, }; -static struct clk_regmap ts_div = { +static struct clk_regmap a1_ts_div = { .data = &(struct clk_regmap_div_data){ .offset = TS_CLK_CTRL, .shift = 0, @@ -1288,7 +1288,7 @@ static struct clk_regmap ts_div = { }, }; -static struct clk_regmap ts = { +static struct clk_regmap a1_ts = { .data = &(struct clk_regmap_gate_data){ .offset = TS_CLK_CTRL, .bit_idx = 8, @@ -1297,14 +1297,14 @@ static struct clk_regmap ts = { .name = "ts", .ops = &clk_regmap_gate_ops, .parent_hws = (const struct clk_hw *[]) { - &ts_div.hw + &a1_ts_div.hw }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, }; -static struct clk_regmap spifc_sel = { +static struct clk_regmap a1_spifc_sel = { .data = &(struct clk_regmap_mux_data){ .offset = SPIFC_CLK_CTRL, .mask = 0x3, @@ -1313,12 +1313,12 @@ static struct clk_regmap spifc_sel = { .hw.init = &(struct clk_init_data){ .name = "spifc_sel", .ops = &clk_regmap_mux_ops, - .parent_data = spicc_spifc_parents, - .num_parents = ARRAY_SIZE(spicc_spifc_parents), + .parent_data = a1_spi_parents, + .num_parents = ARRAY_SIZE(a1_spi_parents), }, }; -static struct clk_regmap spifc_div = { +static struct clk_regmap a1_spifc_div = { .data = &(struct clk_regmap_div_data){ .offset = SPIFC_CLK_CTRL, .shift = 0, @@ -1328,14 +1328,14 @@ static struct clk_regmap spifc_div = { .name = "spifc_div", .ops = &clk_regmap_divider_ops, .parent_hws = (const struct clk_hw *[]) { - &spifc_sel.hw + &a1_spifc_sel.hw }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, }; -static struct clk_regmap spifc_sel2 = { +static struct clk_regmap a1_spifc_sel2 = { .data = &(struct clk_regmap_mux_data){ .offset = SPIFC_CLK_CTRL, .mask = 0x1, @@ -1345,7 +1345,7 @@ static struct clk_regmap spifc_sel2 = { .name = "spifc_sel2", .ops = &clk_regmap_mux_ops, .parent_data = (const struct clk_parent_data []) { - { .hw = &spifc_div.hw }, + { .hw = &a1_spifc_div.hw }, { .fw_name = "xtal", }, }, .num_parents = 2, @@ -1353,7 +1353,7 @@ static struct clk_regmap spifc_sel2 = { }, }; -static struct clk_regmap spifc = { +static struct clk_regmap a1_spifc = { .data = &(struct clk_regmap_gate_data){ .offset = SPIFC_CLK_CTRL, .bit_idx = 8, @@ -1362,21 +1362,21 @@ static struct clk_regmap spifc = { .name = "spifc", .ops = &clk_regmap_gate_ops, .parent_hws = (const struct clk_hw *[]) { - &spifc_sel2.hw + &a1_spifc_sel2.hw }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, }; -static const struct clk_parent_data usb_bus_parents[] = { +static const struct clk_parent_data a1_usb_bus_parents[] = { { .fw_name = "xtal", }, - { .hw = &sys.hw }, + { .hw = &a1_sys.hw }, { .fw_name = "fclk_div3", }, { .fw_name = "fclk_div5", }, }; -static struct clk_regmap usb_bus_sel = { +static struct clk_regmap a1_usb_bus_sel = { .data = &(struct clk_regmap_mux_data){ .offset = USB_BUSCLK_CTRL, .mask = 0x3, @@ -1385,13 +1385,13 @@ static struct clk_regmap usb_bus_sel = { .hw.init = &(struct clk_init_data){ .name = "usb_bus_sel", .ops = &clk_regmap_mux_ops, - .parent_data = usb_bus_parents, - .num_parents = ARRAY_SIZE(usb_bus_parents), + .parent_data = a1_usb_bus_parents, + .num_parents = ARRAY_SIZE(a1_usb_bus_parents), .flags = CLK_SET_RATE_PARENT, }, }; -static struct clk_regmap usb_bus_div = { +static struct clk_regmap a1_usb_bus_div = { .data = &(struct clk_regmap_div_data){ .offset = USB_BUSCLK_CTRL, .shift = 0, @@ -1401,14 +1401,14 @@ static struct clk_regmap usb_bus_div = { .name = "usb_bus_div", .ops = &clk_regmap_divider_ops, .parent_hws = (const struct clk_hw *[]) { - &usb_bus_sel.hw + &a1_usb_bus_sel.hw }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, }; -static struct clk_regmap usb_bus = { +static struct clk_regmap a1_usb_bus = { .data = &(struct clk_regmap_gate_data){ .offset = USB_BUSCLK_CTRL, .bit_idx = 8, @@ -1417,21 +1417,21 @@ static struct clk_regmap usb_bus = { .name = "usb_bus", .ops = &clk_regmap_gate_ops, .parent_hws = (const struct clk_hw *[]) { - &usb_bus_div.hw + &a1_usb_bus_div.hw }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, }; -static const struct clk_parent_data sd_emmc_psram_dmc_parents[] = { +static const struct clk_parent_data a1_sd_emmc_parents[] = { { .fw_name = "fclk_div2", }, { .fw_name = "fclk_div3", }, { .fw_name = "fclk_div5", }, { .fw_name = "hifi_pll", }, }; -static struct clk_regmap sd_emmc_sel = { +static struct clk_regmap a1_sd_emmc_sel = { .data = &(struct clk_regmap_mux_data){ .offset = SD_EMMC_CLK_CTRL, .mask = 0x3, @@ -1440,12 +1440,12 @@ static struct clk_regmap sd_emmc_sel = { .hw.init = &(struct clk_init_data){ .name = "sd_emmc_sel", .ops = &clk_regmap_mux_ops, - .parent_data = sd_emmc_psram_dmc_parents, - .num_parents = ARRAY_SIZE(sd_emmc_psram_dmc_parents), + .parent_data = a1_sd_emmc_parents, + .num_parents = ARRAY_SIZE(a1_sd_emmc_parents), }, }; -static struct clk_regmap sd_emmc_div = { +static struct clk_regmap a1_sd_emmc_div = { .data = &(struct clk_regmap_div_data){ .offset = SD_EMMC_CLK_CTRL, .shift = 0, @@ -1455,14 +1455,14 @@ static struct clk_regmap sd_emmc_div = { .name = "sd_emmc_div", .ops = &clk_regmap_divider_ops, .parent_hws = (const struct clk_hw *[]) { - &sd_emmc_sel.hw + &a1_sd_emmc_sel.hw }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, }; -static struct clk_regmap sd_emmc_sel2 = { +static struct clk_regmap a1_sd_emmc_sel2 = { .data = &(struct clk_regmap_mux_data){ .offset = SD_EMMC_CLK_CTRL, .mask = 0x1, @@ -1472,7 +1472,7 @@ static struct clk_regmap sd_emmc_sel2 = { .name = "sd_emmc_sel2", .ops = &clk_regmap_mux_ops, .parent_data = (const struct clk_parent_data []) { - { .hw = &sd_emmc_div.hw }, + { .hw = &a1_sd_emmc_div.hw }, { .fw_name = "xtal", }, }, .num_parents = 2, @@ -1480,7 +1480,7 @@ static struct clk_regmap sd_emmc_sel2 = { }, }; -static struct clk_regmap sd_emmc = { +static struct clk_regmap a1_sd_emmc = { .data = &(struct clk_regmap_gate_data){ .offset = SD_EMMC_CLK_CTRL, .bit_idx = 8, @@ -1489,14 +1489,14 @@ static struct clk_regmap sd_emmc = { .name = "sd_emmc", .ops = &clk_regmap_gate_ops, .parent_hws = (const struct clk_hw *[]) { - &sd_emmc_sel2.hw + &a1_sd_emmc_sel2.hw }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, }; -static struct clk_regmap psram_sel = { +static struct clk_regmap a1_psram_sel = { .data = &(struct clk_regmap_mux_data){ .offset = PSRAM_CLK_CTRL, .mask = 0x3, @@ -1505,12 +1505,12 @@ static struct clk_regmap psram_sel = { .hw.init = &(struct clk_init_data){ .name = "psram_sel", .ops = &clk_regmap_mux_ops, - .parent_data = sd_emmc_psram_dmc_parents, - .num_parents = ARRAY_SIZE(sd_emmc_psram_dmc_parents), + .parent_data = a1_sd_emmc_parents, + .num_parents = ARRAY_SIZE(a1_sd_emmc_parents), }, }; -static struct clk_regmap psram_div = { +static struct clk_regmap a1_psram_div = { .data = &(struct clk_regmap_div_data){ .offset = PSRAM_CLK_CTRL, .shift = 0, @@ -1520,14 +1520,14 @@ static struct clk_regmap psram_div = { .name = "psram_div", .ops = &clk_regmap_divider_ops, .parent_hws = (const struct clk_hw *[]) { - &psram_sel.hw + &a1_psram_sel.hw }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, }; -static struct clk_regmap psram_sel2 = { +static struct clk_regmap a1_psram_sel2 = { .data = &(struct clk_regmap_mux_data){ .offset = PSRAM_CLK_CTRL, .mask = 0x1, @@ -1537,7 +1537,7 @@ static struct clk_regmap psram_sel2 = { .name = "psram_sel2", .ops = &clk_regmap_mux_ops, .parent_data = (const struct clk_parent_data []) { - { .hw = &psram_div.hw }, + { .hw = &a1_psram_div.hw }, { .fw_name = "xtal", }, }, .num_parents = 2, @@ -1545,7 +1545,7 @@ static struct clk_regmap psram_sel2 = { }, }; -static struct clk_regmap psram = { +static struct clk_regmap a1_psram = { .data = &(struct clk_regmap_gate_data){ .offset = PSRAM_CLK_CTRL, .bit_idx = 8, @@ -1554,14 +1554,14 @@ static struct clk_regmap psram = { .name = "psram", .ops = &clk_regmap_gate_ops, .parent_hws = (const struct clk_hw *[]) { - &psram_sel2.hw + &a1_psram_sel2.hw }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, }; -static struct clk_regmap dmc_sel = { +static struct clk_regmap a1_dmc_sel = { .data = &(struct clk_regmap_mux_data){ .offset = DMC_CLK_CTRL, .mask = 0x3, @@ -1570,12 +1570,12 @@ static struct clk_regmap dmc_sel = { .hw.init = &(struct clk_init_data){ .name = "dmc_sel", .ops = &clk_regmap_mux_ops, - .parent_data = sd_emmc_psram_dmc_parents, - .num_parents = ARRAY_SIZE(sd_emmc_psram_dmc_parents), + .parent_data = a1_sd_emmc_parents, + .num_parents = ARRAY_SIZE(a1_sd_emmc_parents), }, }; -static struct clk_regmap dmc_div = { +static struct clk_regmap a1_dmc_div = { .data = &(struct clk_regmap_div_data){ .offset = DMC_CLK_CTRL, .shift = 0, @@ -1585,14 +1585,14 @@ static struct clk_regmap dmc_div = { .name = "dmc_div", .ops = &clk_regmap_divider_ops, .parent_hws = (const struct clk_hw *[]) { - &dmc_sel.hw + &a1_dmc_sel.hw }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, }; -static struct clk_regmap dmc_sel2 = { +static struct clk_regmap a1_dmc_sel2 = { .data = &(struct clk_regmap_mux_data){ .offset = DMC_CLK_CTRL, .mask = 0x1, @@ -1602,7 +1602,7 @@ static struct clk_regmap dmc_sel2 = { .name = "dmc_sel2", .ops = &clk_regmap_mux_ops, .parent_data = (const struct clk_parent_data []) { - { .hw = &dmc_div.hw }, + { .hw = &a1_dmc_div.hw }, { .fw_name = "xtal", }, }, .num_parents = 2, @@ -1610,7 +1610,7 @@ static struct clk_regmap dmc_sel2 = { }, }; -static struct clk_regmap dmc = { +static struct clk_regmap a1_dmc = { .data = &(struct clk_regmap_gate_data){ .offset = DMC_CLK_CTRL, .bit_idx = 8, @@ -1619,14 +1619,14 @@ static struct clk_regmap dmc = { .name = "dmc", .ops = &clk_regmap_gate_ro_ops, .parent_hws = (const struct clk_hw *[]) { - &dmc_sel2.hw + &a1_dmc_sel2.hw }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, }; -static struct clk_regmap ceca_32k_in = { +static struct clk_regmap a1_ceca_32k_in = { .data = &(struct clk_regmap_gate_data){ .offset = CECA_CLK_CTRL0, .bit_idx = 31, @@ -1641,7 +1641,7 @@ static struct clk_regmap ceca_32k_in = { }, }; -static struct clk_regmap ceca_32k_div = { +static struct clk_regmap a1_ceca_32k_div = { .data = &(struct meson_clk_dualdiv_data){ .n1 = { .reg_off = CECA_CLK_CTRL0, @@ -1668,19 +1668,19 @@ static struct clk_regmap ceca_32k_div = { .shift = 28, .width = 1, }, - .table = clk_32k_div_table, + .table = a1_32k_div_table, }, .hw.init = &(struct clk_init_data){ .name = "ceca_32k_div", .ops = &meson_clk_dualdiv_ops, .parent_hws = (const struct clk_hw *[]) { - &ceca_32k_in.hw + &a1_ceca_32k_in.hw }, .num_parents = 1, }, }; -static struct clk_regmap ceca_32k_sel_pre = { +static struct clk_regmap a1_ceca_32k_sel_pre = { .data = &(struct clk_regmap_mux_data) { .offset = CECA_CLK_CTRL1, .mask = 0x1, @@ -1691,15 +1691,15 @@ static struct clk_regmap ceca_32k_sel_pre = { .name = "ceca_32k_sel_pre", .ops = &clk_regmap_mux_ops, .parent_hws = (const struct clk_hw *[]) { - &ceca_32k_div.hw, - &ceca_32k_in.hw, + &a1_ceca_32k_div.hw, + &a1_ceca_32k_in.hw, }, .num_parents = 2, .flags = CLK_SET_RATE_PARENT, }, }; -static struct clk_regmap ceca_32k_sel = { +static struct clk_regmap a1_ceca_32k_sel = { .data = &(struct clk_regmap_mux_data) { .offset = CECA_CLK_CTRL1, .mask = 0x1, @@ -1710,14 +1710,14 @@ static struct clk_regmap ceca_32k_sel = { .name = "ceca_32k_sel", .ops = &clk_regmap_mux_ops, .parent_hws = (const struct clk_hw *[]) { - &ceca_32k_sel_pre.hw, - &rtc.hw, + &a1_ceca_32k_sel_pre.hw, + &a1_rtc.hw, }, .num_parents = 2, }, }; -static struct clk_regmap ceca_32k_out = { +static struct clk_regmap a1_ceca_32k_out = { .data = &(struct clk_regmap_gate_data){ .offset = CECA_CLK_CTRL0, .bit_idx = 30, @@ -1726,14 +1726,14 @@ static struct clk_regmap ceca_32k_out = { .name = "ceca_32k_out", .ops = &clk_regmap_gate_ops, .parent_hws = (const struct clk_hw *[]) { - &ceca_32k_sel.hw + &a1_ceca_32k_sel.hw }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, }; -static struct clk_regmap cecb_32k_in = { +static struct clk_regmap a1_cecb_32k_in = { .data = &(struct clk_regmap_gate_data){ .offset = CECB_CLK_CTRL0, .bit_idx = 31, @@ -1748,7 +1748,7 @@ static struct clk_regmap cecb_32k_in = { }, }; -static struct clk_regmap cecb_32k_div = { +static struct clk_regmap a1_cecb_32k_div = { .data = &(struct meson_clk_dualdiv_data){ .n1 = { .reg_off = CECB_CLK_CTRL0, @@ -1775,19 +1775,19 @@ static struct clk_regmap cecb_32k_div = { .shift = 28, .width = 1, }, - .table = clk_32k_div_table, + .table = a1_32k_div_table, }, .hw.init = &(struct clk_init_data){ .name = "cecb_32k_div", .ops = &meson_clk_dualdiv_ops, .parent_hws = (const struct clk_hw *[]) { - &cecb_32k_in.hw + &a1_cecb_32k_in.hw }, .num_parents = 1, }, }; -static struct clk_regmap cecb_32k_sel_pre = { +static struct clk_regmap a1_cecb_32k_sel_pre = { .data = &(struct clk_regmap_mux_data) { .offset = CECB_CLK_CTRL1, .mask = 0x1, @@ -1798,15 +1798,15 @@ static struct clk_regmap cecb_32k_sel_pre = { .name = "cecb_32k_sel_pre", .ops = &clk_regmap_mux_ops, .parent_hws = (const struct clk_hw *[]) { - &cecb_32k_div.hw, - &cecb_32k_in.hw, + &a1_cecb_32k_div.hw, + &a1_cecb_32k_in.hw, }, .num_parents = 2, .flags = CLK_SET_RATE_PARENT, }, }; -static struct clk_regmap cecb_32k_sel = { +static struct clk_regmap a1_cecb_32k_sel = { .data = &(struct clk_regmap_mux_data) { .offset = CECB_CLK_CTRL1, .mask = 0x1, @@ -1817,14 +1817,14 @@ static struct clk_regmap cecb_32k_sel = { .name = "cecb_32k_sel", .ops = &clk_regmap_mux_ops, .parent_hws = (const struct clk_hw *[]) { - &cecb_32k_sel_pre.hw, - &rtc.hw, + &a1_cecb_32k_sel_pre.hw, + &a1_rtc.hw, }, .num_parents = 2, }, }; -static struct clk_regmap cecb_32k_out = { +static struct clk_regmap a1_cecb_32k_out = { .data = &(struct clk_regmap_gate_data){ .offset = CECB_CLK_CTRL0, .bit_idx = 30, @@ -1833,282 +1833,265 @@ static struct clk_regmap cecb_32k_out = { .name = "cecb_32k_out", .ops = &clk_regmap_gate_ops, .parent_hws = (const struct clk_hw *[]) { - &cecb_32k_sel.hw + &a1_cecb_32k_sel.hw }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, }; -#define MESON_GATE(_name, _reg, _bit) \ - MESON_PCLK(_name, _reg, _bit, &sys.hw) - -static MESON_GATE(clktree, SYS_CLK_EN0, 0); -static MESON_GATE(reset_ctrl, SYS_CLK_EN0, 1); -static MESON_GATE(analog_ctrl, SYS_CLK_EN0, 2); -static MESON_GATE(pwr_ctrl, SYS_CLK_EN0, 3); -static MESON_GATE(pad_ctrl, SYS_CLK_EN0, 4); -static MESON_GATE(sys_ctrl, SYS_CLK_EN0, 5); -static MESON_GATE(temp_sensor, SYS_CLK_EN0, 6); -static MESON_GATE(am2axi_dev, SYS_CLK_EN0, 7); -static MESON_GATE(spicc_b, SYS_CLK_EN0, 8); -static MESON_GATE(spicc_a, SYS_CLK_EN0, 9); -static MESON_GATE(msr, SYS_CLK_EN0, 10); -static MESON_GATE(audio, SYS_CLK_EN0, 11); -static MESON_GATE(jtag_ctrl, SYS_CLK_EN0, 12); -static MESON_GATE(saradc_en, SYS_CLK_EN0, 13); -static MESON_GATE(pwm_ef, SYS_CLK_EN0, 14); -static MESON_GATE(pwm_cd, SYS_CLK_EN0, 15); -static MESON_GATE(pwm_ab, SYS_CLK_EN0, 16); -static MESON_GATE(cec, SYS_CLK_EN0, 17); -static MESON_GATE(i2c_s, SYS_CLK_EN0, 18); -static MESON_GATE(ir_ctrl, SYS_CLK_EN0, 19); -static MESON_GATE(i2c_m_d, SYS_CLK_EN0, 20); -static MESON_GATE(i2c_m_c, SYS_CLK_EN0, 21); -static MESON_GATE(i2c_m_b, SYS_CLK_EN0, 22); -static MESON_GATE(i2c_m_a, SYS_CLK_EN0, 23); -static MESON_GATE(acodec, SYS_CLK_EN0, 24); -static MESON_GATE(otp, SYS_CLK_EN0, 25); -static MESON_GATE(sd_emmc_a, SYS_CLK_EN0, 26); -static MESON_GATE(usb_phy, SYS_CLK_EN0, 27); -static MESON_GATE(usb_ctrl, SYS_CLK_EN0, 28); -static MESON_GATE(sys_dspb, SYS_CLK_EN0, 29); -static MESON_GATE(sys_dspa, SYS_CLK_EN0, 30); -static MESON_GATE(dma, SYS_CLK_EN0, 31); -static MESON_GATE(irq_ctrl, SYS_CLK_EN1, 0); -static MESON_GATE(nic, SYS_CLK_EN1, 1); -static MESON_GATE(gic, SYS_CLK_EN1, 2); -static MESON_GATE(uart_c, SYS_CLK_EN1, 3); -static MESON_GATE(uart_b, SYS_CLK_EN1, 4); -static MESON_GATE(uart_a, SYS_CLK_EN1, 5); -static MESON_GATE(sys_psram, SYS_CLK_EN1, 6); -static MESON_GATE(rsa, SYS_CLK_EN1, 8); -static MESON_GATE(coresight, SYS_CLK_EN1, 9); -static MESON_GATE(am2axi_vad, AXI_CLK_EN, 0); -static MESON_GATE(audio_vad, AXI_CLK_EN, 1); -static MESON_GATE(axi_dmc, AXI_CLK_EN, 3); -static MESON_GATE(axi_psram, AXI_CLK_EN, 4); -static MESON_GATE(ramb, AXI_CLK_EN, 5); -static MESON_GATE(rama, AXI_CLK_EN, 6); -static MESON_GATE(axi_spifc, AXI_CLK_EN, 7); -static MESON_GATE(axi_nic, AXI_CLK_EN, 8); -static MESON_GATE(axi_dma, AXI_CLK_EN, 9); -static MESON_GATE(cpu_ctrl, AXI_CLK_EN, 10); -static MESON_GATE(rom, AXI_CLK_EN, 11); -static MESON_GATE(prod_i2c, AXI_CLK_EN, 12); +static const struct clk_parent_data a1_pclk_parents = { .hw = &a1_sys.hw }; + +#define A1_PCLK(_name, _reg, _bit, _flags) \ + MESON_PCLK(a1_##_name, _reg, _bit, &a1_pclk_parents, _flags) + +/* + * NOTE: The gates below are marked with CLK_IGNORE_UNUSED for historic reasons + * Users are encouraged to test without it and submit changes to: + * - remove the flag if not necessary + * - replace the flag with something more adequate, such as CLK_IS_CRITICAL, + * if appropriate. + * - add a comment explaining why the use of CLK_IGNORE_UNUSED is desirable + * for a particular clock. + */ +static A1_PCLK(clktree, SYS_CLK_EN0, 0, CLK_IGNORE_UNUSED); +static A1_PCLK(reset_ctrl, SYS_CLK_EN0, 1, CLK_IGNORE_UNUSED); +static A1_PCLK(analog_ctrl, SYS_CLK_EN0, 2, CLK_IGNORE_UNUSED); +static A1_PCLK(pwr_ctrl, SYS_CLK_EN0, 3, CLK_IGNORE_UNUSED); +static A1_PCLK(pad_ctrl, SYS_CLK_EN0, 4, CLK_IGNORE_UNUSED); +static A1_PCLK(sys_ctrl, SYS_CLK_EN0, 5, CLK_IGNORE_UNUSED); +static A1_PCLK(temp_sensor, SYS_CLK_EN0, 6, CLK_IGNORE_UNUSED); +static A1_PCLK(am2axi_dev, SYS_CLK_EN0, 7, CLK_IGNORE_UNUSED); +static A1_PCLK(spicc_b, SYS_CLK_EN0, 8, CLK_IGNORE_UNUSED); +static A1_PCLK(spicc_a, SYS_CLK_EN0, 9, CLK_IGNORE_UNUSED); +static A1_PCLK(msr, SYS_CLK_EN0, 10, CLK_IGNORE_UNUSED); +static A1_PCLK(audio, SYS_CLK_EN0, 11, CLK_IGNORE_UNUSED); +static A1_PCLK(jtag_ctrl, SYS_CLK_EN0, 12, CLK_IGNORE_UNUSED); +static A1_PCLK(saradc_en, SYS_CLK_EN0, 13, CLK_IGNORE_UNUSED); +static A1_PCLK(pwm_ef, SYS_CLK_EN0, 14, CLK_IGNORE_UNUSED); +static A1_PCLK(pwm_cd, SYS_CLK_EN0, 15, CLK_IGNORE_UNUSED); +static A1_PCLK(pwm_ab, SYS_CLK_EN0, 16, CLK_IGNORE_UNUSED); +static A1_PCLK(cec, SYS_CLK_EN0, 17, CLK_IGNORE_UNUSED); +static A1_PCLK(i2c_s, SYS_CLK_EN0, 18, CLK_IGNORE_UNUSED); +static A1_PCLK(ir_ctrl, SYS_CLK_EN0, 19, CLK_IGNORE_UNUSED); +static A1_PCLK(i2c_m_d, SYS_CLK_EN0, 20, CLK_IGNORE_UNUSED); +static A1_PCLK(i2c_m_c, SYS_CLK_EN0, 21, CLK_IGNORE_UNUSED); +static A1_PCLK(i2c_m_b, SYS_CLK_EN0, 22, CLK_IGNORE_UNUSED); +static A1_PCLK(i2c_m_a, SYS_CLK_EN0, 23, CLK_IGNORE_UNUSED); +static A1_PCLK(acodec, SYS_CLK_EN0, 24, CLK_IGNORE_UNUSED); +static A1_PCLK(otp, SYS_CLK_EN0, 25, CLK_IGNORE_UNUSED); +static A1_PCLK(sd_emmc_a, SYS_CLK_EN0, 26, CLK_IGNORE_UNUSED); +static A1_PCLK(usb_phy, SYS_CLK_EN0, 27, CLK_IGNORE_UNUSED); +static A1_PCLK(usb_ctrl, SYS_CLK_EN0, 28, CLK_IGNORE_UNUSED); +static A1_PCLK(sys_dspb, SYS_CLK_EN0, 29, CLK_IGNORE_UNUSED); +static A1_PCLK(sys_dspa, SYS_CLK_EN0, 30, CLK_IGNORE_UNUSED); +static A1_PCLK(dma, SYS_CLK_EN0, 31, CLK_IGNORE_UNUSED); + +static A1_PCLK(irq_ctrl, SYS_CLK_EN1, 0, CLK_IGNORE_UNUSED); +static A1_PCLK(nic, SYS_CLK_EN1, 1, CLK_IGNORE_UNUSED); +static A1_PCLK(gic, SYS_CLK_EN1, 2, CLK_IGNORE_UNUSED); +static A1_PCLK(uart_c, SYS_CLK_EN1, 3, CLK_IGNORE_UNUSED); +static A1_PCLK(uart_b, SYS_CLK_EN1, 4, CLK_IGNORE_UNUSED); +static A1_PCLK(uart_a, SYS_CLK_EN1, 5, CLK_IGNORE_UNUSED); +static A1_PCLK(sys_psram, SYS_CLK_EN1, 6, CLK_IGNORE_UNUSED); +static A1_PCLK(rsa, SYS_CLK_EN1, 8, CLK_IGNORE_UNUSED); +static A1_PCLK(coresight, SYS_CLK_EN1, 9, CLK_IGNORE_UNUSED); + +static A1_PCLK(am2axi_vad, AXI_CLK_EN, 0, CLK_IGNORE_UNUSED); +static A1_PCLK(audio_vad, AXI_CLK_EN, 1, CLK_IGNORE_UNUSED); +static A1_PCLK(axi_dmc, AXI_CLK_EN, 3, CLK_IGNORE_UNUSED); +static A1_PCLK(axi_psram, AXI_CLK_EN, 4, CLK_IGNORE_UNUSED); +static A1_PCLK(ramb, AXI_CLK_EN, 5, CLK_IGNORE_UNUSED); +static A1_PCLK(rama, AXI_CLK_EN, 6, CLK_IGNORE_UNUSED); +static A1_PCLK(axi_spifc, AXI_CLK_EN, 7, CLK_IGNORE_UNUSED); +static A1_PCLK(axi_nic, AXI_CLK_EN, 8, CLK_IGNORE_UNUSED); +static A1_PCLK(axi_dma, AXI_CLK_EN, 9, CLK_IGNORE_UNUSED); +static A1_PCLK(cpu_ctrl, AXI_CLK_EN, 10, CLK_IGNORE_UNUSED); +static A1_PCLK(rom, AXI_CLK_EN, 11, CLK_IGNORE_UNUSED); +static A1_PCLK(prod_i2c, AXI_CLK_EN, 12, CLK_IGNORE_UNUSED); /* Array of all clocks registered by this provider */ -static struct clk_hw *a1_periphs_hw_clks[] = { - [CLKID_XTAL_IN] = &xtal_in.hw, - [CLKID_FIXPLL_IN] = &fixpll_in.hw, - [CLKID_USB_PHY_IN] = &usb_phy_in.hw, - [CLKID_USB_CTRL_IN] = &usb_ctrl_in.hw, - [CLKID_HIFIPLL_IN] = &hifipll_in.hw, - [CLKID_SYSPLL_IN] = &syspll_in.hw, - [CLKID_DDS_IN] = &dds_in.hw, - [CLKID_SYS] = &sys.hw, - [CLKID_CLKTREE] = &clktree.hw, - [CLKID_RESET_CTRL] = &reset_ctrl.hw, - [CLKID_ANALOG_CTRL] = &analog_ctrl.hw, - [CLKID_PWR_CTRL] = &pwr_ctrl.hw, - [CLKID_PAD_CTRL] = &pad_ctrl.hw, - [CLKID_SYS_CTRL] = &sys_ctrl.hw, - [CLKID_TEMP_SENSOR] = &temp_sensor.hw, - [CLKID_AM2AXI_DIV] = &am2axi_dev.hw, - [CLKID_SPICC_B] = &spicc_b.hw, - [CLKID_SPICC_A] = &spicc_a.hw, - [CLKID_MSR] = &msr.hw, - [CLKID_AUDIO] = &audio.hw, - [CLKID_JTAG_CTRL] = &jtag_ctrl.hw, - [CLKID_SARADC_EN] = &saradc_en.hw, - [CLKID_PWM_EF] = &pwm_ef.hw, - [CLKID_PWM_CD] = &pwm_cd.hw, - [CLKID_PWM_AB] = &pwm_ab.hw, - [CLKID_CEC] = &cec.hw, - [CLKID_I2C_S] = &i2c_s.hw, - [CLKID_IR_CTRL] = &ir_ctrl.hw, - [CLKID_I2C_M_D] = &i2c_m_d.hw, - [CLKID_I2C_M_C] = &i2c_m_c.hw, - [CLKID_I2C_M_B] = &i2c_m_b.hw, - [CLKID_I2C_M_A] = &i2c_m_a.hw, - [CLKID_ACODEC] = &acodec.hw, - [CLKID_OTP] = &otp.hw, - [CLKID_SD_EMMC_A] = &sd_emmc_a.hw, - [CLKID_USB_PHY] = &usb_phy.hw, - [CLKID_USB_CTRL] = &usb_ctrl.hw, - [CLKID_SYS_DSPB] = &sys_dspb.hw, - [CLKID_SYS_DSPA] = &sys_dspa.hw, - [CLKID_DMA] = &dma.hw, - [CLKID_IRQ_CTRL] = &irq_ctrl.hw, - [CLKID_NIC] = &nic.hw, - [CLKID_GIC] = &gic.hw, - [CLKID_UART_C] = &uart_c.hw, - [CLKID_UART_B] = &uart_b.hw, - [CLKID_UART_A] = &uart_a.hw, - [CLKID_SYS_PSRAM] = &sys_psram.hw, - [CLKID_RSA] = &rsa.hw, - [CLKID_CORESIGHT] = &coresight.hw, - [CLKID_AM2AXI_VAD] = &am2axi_vad.hw, - [CLKID_AUDIO_VAD] = &audio_vad.hw, - [CLKID_AXI_DMC] = &axi_dmc.hw, - [CLKID_AXI_PSRAM] = &axi_psram.hw, - [CLKID_RAMB] = &ramb.hw, - [CLKID_RAMA] = &rama.hw, - [CLKID_AXI_SPIFC] = &axi_spifc.hw, - [CLKID_AXI_NIC] = &axi_nic.hw, - [CLKID_AXI_DMA] = &axi_dma.hw, - [CLKID_CPU_CTRL] = &cpu_ctrl.hw, - [CLKID_ROM] = &rom.hw, - [CLKID_PROC_I2C] = &prod_i2c.hw, - [CLKID_DSPA_SEL] = &dspa_sel.hw, - [CLKID_DSPB_SEL] = &dspb_sel.hw, - [CLKID_DSPA_EN] = &dspa_en.hw, - [CLKID_DSPA_EN_NIC] = &dspa_en_nic.hw, - [CLKID_DSPB_EN] = &dspb_en.hw, - [CLKID_DSPB_EN_NIC] = &dspb_en_nic.hw, - [CLKID_RTC] = &rtc.hw, - [CLKID_CECA_32K] = &ceca_32k_out.hw, - [CLKID_CECB_32K] = &cecb_32k_out.hw, - [CLKID_24M] = &clk_24m.hw, - [CLKID_12M] = &clk_12m.hw, - [CLKID_FCLK_DIV2_DIVN] = &fclk_div2_divn.hw, - [CLKID_GEN] = &gen.hw, - [CLKID_SARADC_SEL] = &saradc_sel.hw, - [CLKID_SARADC] = &saradc.hw, - [CLKID_PWM_A] = &pwm_a.hw, - [CLKID_PWM_B] = &pwm_b.hw, - [CLKID_PWM_C] = &pwm_c.hw, - [CLKID_PWM_D] = &pwm_d.hw, - [CLKID_PWM_E] = &pwm_e.hw, - [CLKID_PWM_F] = &pwm_f.hw, - [CLKID_SPICC] = &spicc.hw, - [CLKID_TS] = &ts.hw, - [CLKID_SPIFC] = &spifc.hw, - [CLKID_USB_BUS] = &usb_bus.hw, - [CLKID_SD_EMMC] = &sd_emmc.hw, - [CLKID_PSRAM] = &psram.hw, - [CLKID_DMC] = &dmc.hw, - [CLKID_SYS_A_SEL] = &sys_a_sel.hw, - [CLKID_SYS_A_DIV] = &sys_a_div.hw, - [CLKID_SYS_A] = &sys_a.hw, - [CLKID_SYS_B_SEL] = &sys_b_sel.hw, - [CLKID_SYS_B_DIV] = &sys_b_div.hw, - [CLKID_SYS_B] = &sys_b.hw, - [CLKID_DSPA_A_SEL] = &dspa_a_sel.hw, - [CLKID_DSPA_A_DIV] = &dspa_a_div.hw, - [CLKID_DSPA_A] = &dspa_a.hw, - [CLKID_DSPA_B_SEL] = &dspa_b_sel.hw, - [CLKID_DSPA_B_DIV] = &dspa_b_div.hw, - [CLKID_DSPA_B] = &dspa_b.hw, - [CLKID_DSPB_A_SEL] = &dspb_a_sel.hw, - [CLKID_DSPB_A_DIV] = &dspb_a_div.hw, - [CLKID_DSPB_A] = &dspb_a.hw, - [CLKID_DSPB_B_SEL] = &dspb_b_sel.hw, - [CLKID_DSPB_B_DIV] = &dspb_b_div.hw, - [CLKID_DSPB_B] = &dspb_b.hw, - [CLKID_RTC_32K_IN] = &rtc_32k_in.hw, - [CLKID_RTC_32K_DIV] = &rtc_32k_div.hw, - [CLKID_RTC_32K_XTAL] = &rtc_32k_xtal.hw, - [CLKID_RTC_32K_SEL] = &rtc_32k_sel.hw, - [CLKID_CECB_32K_IN] = &cecb_32k_in.hw, - [CLKID_CECB_32K_DIV] = &cecb_32k_div.hw, - [CLKID_CECB_32K_SEL_PRE] = &cecb_32k_sel_pre.hw, - [CLKID_CECB_32K_SEL] = &cecb_32k_sel.hw, - [CLKID_CECA_32K_IN] = &ceca_32k_in.hw, - [CLKID_CECA_32K_DIV] = &ceca_32k_div.hw, - [CLKID_CECA_32K_SEL_PRE] = &ceca_32k_sel_pre.hw, - [CLKID_CECA_32K_SEL] = &ceca_32k_sel.hw, - [CLKID_DIV2_PRE] = &fclk_div2_divn_pre.hw, - [CLKID_24M_DIV2] = &clk_24m_div2.hw, - [CLKID_GEN_SEL] = &gen_sel.hw, - [CLKID_GEN_DIV] = &gen_div.hw, - [CLKID_SARADC_DIV] = &saradc_div.hw, - [CLKID_PWM_A_SEL] = &pwm_a_sel.hw, - [CLKID_PWM_A_DIV] = &pwm_a_div.hw, - [CLKID_PWM_B_SEL] = &pwm_b_sel.hw, - [CLKID_PWM_B_DIV] = &pwm_b_div.hw, - [CLKID_PWM_C_SEL] = &pwm_c_sel.hw, - [CLKID_PWM_C_DIV] = &pwm_c_div.hw, - [CLKID_PWM_D_SEL] = &pwm_d_sel.hw, - [CLKID_PWM_D_DIV] = &pwm_d_div.hw, - [CLKID_PWM_E_SEL] = &pwm_e_sel.hw, - [CLKID_PWM_E_DIV] = &pwm_e_div.hw, - [CLKID_PWM_F_SEL] = &pwm_f_sel.hw, - [CLKID_PWM_F_DIV] = &pwm_f_div.hw, - [CLKID_SPICC_SEL] = &spicc_sel.hw, - [CLKID_SPICC_DIV] = &spicc_div.hw, - [CLKID_SPICC_SEL2] = &spicc_sel2.hw, - [CLKID_TS_DIV] = &ts_div.hw, - [CLKID_SPIFC_SEL] = &spifc_sel.hw, - [CLKID_SPIFC_DIV] = &spifc_div.hw, - [CLKID_SPIFC_SEL2] = &spifc_sel2.hw, - [CLKID_USB_BUS_SEL] = &usb_bus_sel.hw, - [CLKID_USB_BUS_DIV] = &usb_bus_div.hw, - [CLKID_SD_EMMC_SEL] = &sd_emmc_sel.hw, - [CLKID_SD_EMMC_DIV] = &sd_emmc_div.hw, - [CLKID_SD_EMMC_SEL2] = &sd_emmc_sel2.hw, - [CLKID_PSRAM_SEL] = &psram_sel.hw, - [CLKID_PSRAM_DIV] = &psram_div.hw, - [CLKID_PSRAM_SEL2] = &psram_sel2.hw, - [CLKID_DMC_SEL] = &dmc_sel.hw, - [CLKID_DMC_DIV] = &dmc_div.hw, - [CLKID_DMC_SEL2] = &dmc_sel2.hw, -}; - -static const struct regmap_config a1_periphs_regmap_cfg = { - .reg_bits = 32, - .val_bits = 32, - .reg_stride = 4, - .max_register = DMC_CLK_CTRL, -}; - -static struct meson_clk_hw_data a1_periphs_clks = { - .hws = a1_periphs_hw_clks, - .num = ARRAY_SIZE(a1_periphs_hw_clks), -}; - -static int meson_a1_periphs_probe(struct platform_device *pdev) -{ - struct device *dev = &pdev->dev; - void __iomem *base; - struct regmap *map; - int clkid, err; - - base = devm_platform_ioremap_resource(pdev, 0); - if (IS_ERR(base)) - return dev_err_probe(dev, PTR_ERR(base), - "can't ioremap resource\n"); - - map = devm_regmap_init_mmio(dev, base, &a1_periphs_regmap_cfg); - if (IS_ERR(map)) - return dev_err_probe(dev, PTR_ERR(map), - "can't init regmap mmio region\n"); - - for (clkid = 0; clkid < a1_periphs_clks.num; clkid++) { - err = devm_clk_hw_register(dev, a1_periphs_clks.hws[clkid]); - if (err) - return dev_err_probe(dev, err, - "clock[%d] registration failed\n", - clkid); - } - - return devm_of_clk_add_hw_provider(dev, meson_clk_hw_get, &a1_periphs_clks); -} - -static const struct of_device_id a1_periphs_clkc_match_table[] = { - { .compatible = "amlogic,a1-peripherals-clkc", }, +static struct clk_hw *a1_peripherals_hw_clks[] = { + [CLKID_XTAL_IN] = &a1_xtal_in.hw, + [CLKID_FIXPLL_IN] = &a1_fixpll_in.hw, + [CLKID_USB_PHY_IN] = &a1_usb_phy_in.hw, + [CLKID_USB_CTRL_IN] = &a1_usb_ctrl_in.hw, + [CLKID_HIFIPLL_IN] = &a1_hifipll_in.hw, + [CLKID_SYSPLL_IN] = &a1_syspll_in.hw, + [CLKID_DDS_IN] = &a1_dds_in.hw, + [CLKID_SYS] = &a1_sys.hw, + [CLKID_CLKTREE] = &a1_clktree.hw, + [CLKID_RESET_CTRL] = &a1_reset_ctrl.hw, + [CLKID_ANALOG_CTRL] = &a1_analog_ctrl.hw, + [CLKID_PWR_CTRL] = &a1_pwr_ctrl.hw, + [CLKID_PAD_CTRL] = &a1_pad_ctrl.hw, + [CLKID_SYS_CTRL] = &a1_sys_ctrl.hw, + [CLKID_TEMP_SENSOR] = &a1_temp_sensor.hw, + [CLKID_AM2AXI_DIV] = &a1_am2axi_dev.hw, + [CLKID_SPICC_B] = &a1_spicc_b.hw, + [CLKID_SPICC_A] = &a1_spicc_a.hw, + [CLKID_MSR] = &a1_msr.hw, + [CLKID_AUDIO] = &a1_audio.hw, + [CLKID_JTAG_CTRL] = &a1_jtag_ctrl.hw, + [CLKID_SARADC_EN] = &a1_saradc_en.hw, + [CLKID_PWM_EF] = &a1_pwm_ef.hw, + [CLKID_PWM_CD] = &a1_pwm_cd.hw, + [CLKID_PWM_AB] = &a1_pwm_ab.hw, + [CLKID_CEC] = &a1_cec.hw, + [CLKID_I2C_S] = &a1_i2c_s.hw, + [CLKID_IR_CTRL] = &a1_ir_ctrl.hw, + [CLKID_I2C_M_D] = &a1_i2c_m_d.hw, + [CLKID_I2C_M_C] = &a1_i2c_m_c.hw, + [CLKID_I2C_M_B] = &a1_i2c_m_b.hw, + [CLKID_I2C_M_A] = &a1_i2c_m_a.hw, + [CLKID_ACODEC] = &a1_acodec.hw, + [CLKID_OTP] = &a1_otp.hw, + [CLKID_SD_EMMC_A] = &a1_sd_emmc_a.hw, + [CLKID_USB_PHY] = &a1_usb_phy.hw, + [CLKID_USB_CTRL] = &a1_usb_ctrl.hw, + [CLKID_SYS_DSPB] = &a1_sys_dspb.hw, + [CLKID_SYS_DSPA] = &a1_sys_dspa.hw, + [CLKID_DMA] = &a1_dma.hw, + [CLKID_IRQ_CTRL] = &a1_irq_ctrl.hw, + [CLKID_NIC] = &a1_nic.hw, + [CLKID_GIC] = &a1_gic.hw, + [CLKID_UART_C] = &a1_uart_c.hw, + [CLKID_UART_B] = &a1_uart_b.hw, + [CLKID_UART_A] = &a1_uart_a.hw, + [CLKID_SYS_PSRAM] = &a1_sys_psram.hw, + [CLKID_RSA] = &a1_rsa.hw, + [CLKID_CORESIGHT] = &a1_coresight.hw, + [CLKID_AM2AXI_VAD] = &a1_am2axi_vad.hw, + [CLKID_AUDIO_VAD] = &a1_audio_vad.hw, + [CLKID_AXI_DMC] = &a1_axi_dmc.hw, + [CLKID_AXI_PSRAM] = &a1_axi_psram.hw, + [CLKID_RAMB] = &a1_ramb.hw, + [CLKID_RAMA] = &a1_rama.hw, + [CLKID_AXI_SPIFC] = &a1_axi_spifc.hw, + [CLKID_AXI_NIC] = &a1_axi_nic.hw, + [CLKID_AXI_DMA] = &a1_axi_dma.hw, + [CLKID_CPU_CTRL] = &a1_cpu_ctrl.hw, + [CLKID_ROM] = &a1_rom.hw, + [CLKID_PROC_I2C] = &a1_prod_i2c.hw, + [CLKID_DSPA_SEL] = &a1_dspa_sel.hw, + [CLKID_DSPB_SEL] = &a1_dspb_sel.hw, + [CLKID_DSPA_EN] = &a1_dspa_en.hw, + [CLKID_DSPA_EN_NIC] = &a1_dspa_en_nic.hw, + [CLKID_DSPB_EN] = &a1_dspb_en.hw, + [CLKID_DSPB_EN_NIC] = &a1_dspb_en_nic.hw, + [CLKID_RTC] = &a1_rtc.hw, + [CLKID_CECA_32K] = &a1_ceca_32k_out.hw, + [CLKID_CECB_32K] = &a1_cecb_32k_out.hw, + [CLKID_24M] = &a1_24m.hw, + [CLKID_12M] = &a1_12m.hw, + [CLKID_FCLK_DIV2_DIVN] = &a1_fclk_div2_divn.hw, + [CLKID_GEN] = &a1_gen.hw, + [CLKID_SARADC_SEL] = &a1_saradc_sel.hw, + [CLKID_SARADC] = &a1_saradc.hw, + [CLKID_PWM_A] = &a1_pwm_a.hw, + [CLKID_PWM_B] = &a1_pwm_b.hw, + [CLKID_PWM_C] = &a1_pwm_c.hw, + [CLKID_PWM_D] = &a1_pwm_d.hw, + [CLKID_PWM_E] = &a1_pwm_e.hw, + [CLKID_PWM_F] = &a1_pwm_f.hw, + [CLKID_SPICC] = &a1_spicc.hw, + [CLKID_TS] = &a1_ts.hw, + [CLKID_SPIFC] = &a1_spifc.hw, + [CLKID_USB_BUS] = &a1_usb_bus.hw, + [CLKID_SD_EMMC] = &a1_sd_emmc.hw, + [CLKID_PSRAM] = &a1_psram.hw, + [CLKID_DMC] = &a1_dmc.hw, + [CLKID_SYS_A_SEL] = &a1_sys_a_sel.hw, + [CLKID_SYS_A_DIV] = &a1_sys_a_div.hw, + [CLKID_SYS_A] = &a1_sys_a.hw, + [CLKID_SYS_B_SEL] = &a1_sys_b_sel.hw, + [CLKID_SYS_B_DIV] = &a1_sys_b_div.hw, + [CLKID_SYS_B] = &a1_sys_b.hw, + [CLKID_DSPA_A_SEL] = &a1_dspa_a_sel.hw, + [CLKID_DSPA_A_DIV] = &a1_dspa_a_div.hw, + [CLKID_DSPA_A] = &a1_dspa_a.hw, + [CLKID_DSPA_B_SEL] = &a1_dspa_b_sel.hw, + [CLKID_DSPA_B_DIV] = &a1_dspa_b_div.hw, + [CLKID_DSPA_B] = &a1_dspa_b.hw, + [CLKID_DSPB_A_SEL] = &a1_dspb_a_sel.hw, + [CLKID_DSPB_A_DIV] = &a1_dspb_a_div.hw, + [CLKID_DSPB_A] = &a1_dspb_a.hw, + [CLKID_DSPB_B_SEL] = &a1_dspb_b_sel.hw, + [CLKID_DSPB_B_DIV] = &a1_dspb_b_div.hw, + [CLKID_DSPB_B] = &a1_dspb_b.hw, + [CLKID_RTC_32K_IN] = &a1_rtc_32k_in.hw, + [CLKID_RTC_32K_DIV] = &a1_rtc_32k_div.hw, + [CLKID_RTC_32K_XTAL] = &a1_rtc_32k_xtal.hw, + [CLKID_RTC_32K_SEL] = &a1_rtc_32k_sel.hw, + [CLKID_CECB_32K_IN] = &a1_cecb_32k_in.hw, + [CLKID_CECB_32K_DIV] = &a1_cecb_32k_div.hw, + [CLKID_CECB_32K_SEL_PRE] = &a1_cecb_32k_sel_pre.hw, + [CLKID_CECB_32K_SEL] = &a1_cecb_32k_sel.hw, + [CLKID_CECA_32K_IN] = &a1_ceca_32k_in.hw, + [CLKID_CECA_32K_DIV] = &a1_ceca_32k_div.hw, + [CLKID_CECA_32K_SEL_PRE] = &a1_ceca_32k_sel_pre.hw, + [CLKID_CECA_32K_SEL] = &a1_ceca_32k_sel.hw, + [CLKID_DIV2_PRE] = &a1_fclk_div2_divn_pre.hw, + [CLKID_24M_DIV2] = &a1_24m_div2.hw, + [CLKID_GEN_SEL] = &a1_gen_sel.hw, + [CLKID_GEN_DIV] = &a1_gen_div.hw, + [CLKID_SARADC_DIV] = &a1_saradc_div.hw, + [CLKID_PWM_A_SEL] = &a1_pwm_a_sel.hw, + [CLKID_PWM_A_DIV] = &a1_pwm_a_div.hw, + [CLKID_PWM_B_SEL] = &a1_pwm_b_sel.hw, + [CLKID_PWM_B_DIV] = &a1_pwm_b_div.hw, + [CLKID_PWM_C_SEL] = &a1_pwm_c_sel.hw, + [CLKID_PWM_C_DIV] = &a1_pwm_c_div.hw, + [CLKID_PWM_D_SEL] = &a1_pwm_d_sel.hw, + [CLKID_PWM_D_DIV] = &a1_pwm_d_div.hw, + [CLKID_PWM_E_SEL] = &a1_pwm_e_sel.hw, + [CLKID_PWM_E_DIV] = &a1_pwm_e_div.hw, + [CLKID_PWM_F_SEL] = &a1_pwm_f_sel.hw, + [CLKID_PWM_F_DIV] = &a1_pwm_f_div.hw, + [CLKID_SPICC_SEL] = &a1_spicc_sel.hw, + [CLKID_SPICC_DIV] = &a1_spicc_div.hw, + [CLKID_SPICC_SEL2] = &a1_spicc_sel2.hw, + [CLKID_TS_DIV] = &a1_ts_div.hw, + [CLKID_SPIFC_SEL] = &a1_spifc_sel.hw, + [CLKID_SPIFC_DIV] = &a1_spifc_div.hw, + [CLKID_SPIFC_SEL2] = &a1_spifc_sel2.hw, + [CLKID_USB_BUS_SEL] = &a1_usb_bus_sel.hw, + [CLKID_USB_BUS_DIV] = &a1_usb_bus_div.hw, + [CLKID_SD_EMMC_SEL] = &a1_sd_emmc_sel.hw, + [CLKID_SD_EMMC_DIV] = &a1_sd_emmc_div.hw, + [CLKID_SD_EMMC_SEL2] = &a1_sd_emmc_sel2.hw, + [CLKID_PSRAM_SEL] = &a1_psram_sel.hw, + [CLKID_PSRAM_DIV] = &a1_psram_div.hw, + [CLKID_PSRAM_SEL2] = &a1_psram_sel2.hw, + [CLKID_DMC_SEL] = &a1_dmc_sel.hw, + [CLKID_DMC_DIV] = &a1_dmc_div.hw, + [CLKID_DMC_SEL2] = &a1_dmc_sel2.hw, +}; + +static const struct meson_clkc_data a1_peripherals_clkc_data = { + .hw_clks = { + .hws = a1_peripherals_hw_clks, + .num = ARRAY_SIZE(a1_peripherals_hw_clks), + }, +}; + +static const struct of_device_id a1_peripherals_clkc_match_table[] = { + { + .compatible = "amlogic,a1-peripherals-clkc", + .data = &a1_peripherals_clkc_data, + }, {} }; -MODULE_DEVICE_TABLE(of, a1_periphs_clkc_match_table); +MODULE_DEVICE_TABLE(of, a1_peripherals_clkc_match_table); -static struct platform_driver a1_periphs_clkc_driver = { - .probe = meson_a1_periphs_probe, +static struct platform_driver a1_peripherals_clkc_driver = { + .probe = meson_clkc_mmio_probe, .driver = { .name = "a1-peripherals-clkc", - .of_match_table = a1_periphs_clkc_match_table, + .of_match_table = a1_peripherals_clkc_match_table, }, }; -module_platform_driver(a1_periphs_clkc_driver); +module_platform_driver(a1_peripherals_clkc_driver); MODULE_DESCRIPTION("Amlogic A1 Peripherals Clock Controller driver"); MODULE_AUTHOR("Jian Hu <jian.hu@amlogic.com>"); diff --git a/drivers/clk/meson/a1-pll.c b/drivers/clk/meson/a1-pll.c index dabd4fad1f57..1f82e9c7c14e 100644 --- a/drivers/clk/meson/a1-pll.c +++ b/drivers/clk/meson/a1-pll.c @@ -26,7 +26,7 @@ #include <dt-bindings/clock/amlogic,a1-pll-clkc.h> -static struct clk_regmap fixed_pll_dco = { +static struct clk_regmap a1_fixed_pll_dco = { .data = &(struct meson_clk_pll_data){ .en = { .reg_off = ANACTRL_FIXPLL_CTRL0, @@ -69,7 +69,7 @@ static struct clk_regmap fixed_pll_dco = { }, }; -static struct clk_regmap fixed_pll = { +static struct clk_regmap a1_fixed_pll = { .data = &(struct clk_regmap_gate_data){ .offset = ANACTRL_FIXPLL_CTRL0, .bit_idx = 20, @@ -78,18 +78,18 @@ static struct clk_regmap fixed_pll = { .name = "fixed_pll", .ops = &clk_regmap_gate_ops, .parent_hws = (const struct clk_hw *[]) { - &fixed_pll_dco.hw + &a1_fixed_pll_dco.hw }, .num_parents = 1, }, }; -static const struct pll_mult_range hifi_pll_mult_range = { +static const struct pll_mult_range a1_hifi_pll_range = { .min = 32, .max = 64, }; -static const struct reg_sequence hifi_init_regs[] = { +static const struct reg_sequence a1_hifi_pll_init_regs[] = { { .reg = ANACTRL_HIFIPLL_CTRL1, .def = 0x01800000 }, { .reg = ANACTRL_HIFIPLL_CTRL2, .def = 0x00001100 }, { .reg = ANACTRL_HIFIPLL_CTRL3, .def = 0x100a1100 }, @@ -97,7 +97,7 @@ static const struct reg_sequence hifi_init_regs[] = { { .reg = ANACTRL_HIFIPLL_CTRL0, .def = 0x01f18000 }, }; -static struct clk_regmap hifi_pll = { +static struct clk_regmap a1_hifi_pll = { .data = &(struct meson_clk_pll_data){ .en = { .reg_off = ANACTRL_HIFIPLL_CTRL0, @@ -134,9 +134,9 @@ static struct clk_regmap hifi_pll = { .shift = 6, .width = 1, }, - .range = &hifi_pll_mult_range, - .init_regs = hifi_init_regs, - .init_count = ARRAY_SIZE(hifi_init_regs), + .range = &a1_hifi_pll_range, + .init_regs = a1_hifi_pll_init_regs, + .init_count = ARRAY_SIZE(a1_hifi_pll_init_regs), }, .hw.init = &(struct clk_init_data){ .name = "hifi_pll", @@ -148,20 +148,20 @@ static struct clk_regmap hifi_pll = { }, }; -static struct clk_fixed_factor fclk_div2_div = { +static struct clk_fixed_factor a1_fclk_div2_div = { .mult = 1, .div = 2, .hw.init = &(struct clk_init_data){ .name = "fclk_div2_div", .ops = &clk_fixed_factor_ops, .parent_hws = (const struct clk_hw *[]) { - &fixed_pll.hw + &a1_fixed_pll.hw }, .num_parents = 1, }, }; -static struct clk_regmap fclk_div2 = { +static struct clk_regmap a1_fclk_div2 = { .data = &(struct clk_regmap_gate_data){ .offset = ANACTRL_FIXPLL_CTRL0, .bit_idx = 21, @@ -170,7 +170,7 @@ static struct clk_regmap fclk_div2 = { .name = "fclk_div2", .ops = &clk_regmap_gate_ops, .parent_hws = (const struct clk_hw *[]) { - &fclk_div2_div.hw + &a1_fclk_div2_div.hw }, .num_parents = 1, /* @@ -186,20 +186,20 @@ static struct clk_regmap fclk_div2 = { }, }; -static struct clk_fixed_factor fclk_div3_div = { +static struct clk_fixed_factor a1_fclk_div3_div = { .mult = 1, .div = 3, .hw.init = &(struct clk_init_data){ .name = "fclk_div3_div", .ops = &clk_fixed_factor_ops, .parent_hws = (const struct clk_hw *[]) { - &fixed_pll.hw + &a1_fixed_pll.hw }, .num_parents = 1, }, }; -static struct clk_regmap fclk_div3 = { +static struct clk_regmap a1_fclk_div3 = { .data = &(struct clk_regmap_gate_data){ .offset = ANACTRL_FIXPLL_CTRL0, .bit_idx = 22, @@ -208,7 +208,7 @@ static struct clk_regmap fclk_div3 = { .name = "fclk_div3", .ops = &clk_regmap_gate_ops, .parent_hws = (const struct clk_hw *[]) { - &fclk_div3_div.hw + &a1_fclk_div3_div.hw }, .num_parents = 1, /* @@ -219,20 +219,20 @@ static struct clk_regmap fclk_div3 = { }, }; -static struct clk_fixed_factor fclk_div5_div = { +static struct clk_fixed_factor a1_fclk_div5_div = { .mult = 1, .div = 5, .hw.init = &(struct clk_init_data){ .name = "fclk_div5_div", .ops = &clk_fixed_factor_ops, .parent_hws = (const struct clk_hw *[]) { - &fixed_pll.hw + &a1_fixed_pll.hw }, .num_parents = 1, }, }; -static struct clk_regmap fclk_div5 = { +static struct clk_regmap a1_fclk_div5 = { .data = &(struct clk_regmap_gate_data){ .offset = ANACTRL_FIXPLL_CTRL0, .bit_idx = 23, @@ -241,7 +241,7 @@ static struct clk_regmap fclk_div5 = { .name = "fclk_div5", .ops = &clk_regmap_gate_ops, .parent_hws = (const struct clk_hw *[]) { - &fclk_div5_div.hw + &a1_fclk_div5_div.hw }, .num_parents = 1, /* @@ -252,20 +252,20 @@ static struct clk_regmap fclk_div5 = { }, }; -static struct clk_fixed_factor fclk_div7_div = { +static struct clk_fixed_factor a1_fclk_div7_div = { .mult = 1, .div = 7, .hw.init = &(struct clk_init_data){ .name = "fclk_div7_div", .ops = &clk_fixed_factor_ops, .parent_hws = (const struct clk_hw *[]) { - &fixed_pll.hw + &a1_fixed_pll.hw }, .num_parents = 1, }, }; -static struct clk_regmap fclk_div7 = { +static struct clk_regmap a1_fclk_div7 = { .data = &(struct clk_regmap_gate_data){ .offset = ANACTRL_FIXPLL_CTRL0, .bit_idx = 24, @@ -274,7 +274,7 @@ static struct clk_regmap fclk_div7 = { .name = "fclk_div7", .ops = &clk_regmap_gate_ops, .parent_hws = (const struct clk_hw *[]) { - &fclk_div7_div.hw + &a1_fclk_div7_div.hw }, .num_parents = 1, }, @@ -282,69 +282,37 @@ static struct clk_regmap fclk_div7 = { /* Array of all clocks registered by this provider */ static struct clk_hw *a1_pll_hw_clks[] = { - [CLKID_FIXED_PLL_DCO] = &fixed_pll_dco.hw, - [CLKID_FIXED_PLL] = &fixed_pll.hw, - [CLKID_FCLK_DIV2_DIV] = &fclk_div2_div.hw, - [CLKID_FCLK_DIV3_DIV] = &fclk_div3_div.hw, - [CLKID_FCLK_DIV5_DIV] = &fclk_div5_div.hw, - [CLKID_FCLK_DIV7_DIV] = &fclk_div7_div.hw, - [CLKID_FCLK_DIV2] = &fclk_div2.hw, - [CLKID_FCLK_DIV3] = &fclk_div3.hw, - [CLKID_FCLK_DIV5] = &fclk_div5.hw, - [CLKID_FCLK_DIV7] = &fclk_div7.hw, - [CLKID_HIFI_PLL] = &hifi_pll.hw, + [CLKID_FIXED_PLL_DCO] = &a1_fixed_pll_dco.hw, + [CLKID_FIXED_PLL] = &a1_fixed_pll.hw, + [CLKID_FCLK_DIV2_DIV] = &a1_fclk_div2_div.hw, + [CLKID_FCLK_DIV3_DIV] = &a1_fclk_div3_div.hw, + [CLKID_FCLK_DIV5_DIV] = &a1_fclk_div5_div.hw, + [CLKID_FCLK_DIV7_DIV] = &a1_fclk_div7_div.hw, + [CLKID_FCLK_DIV2] = &a1_fclk_div2.hw, + [CLKID_FCLK_DIV3] = &a1_fclk_div3.hw, + [CLKID_FCLK_DIV5] = &a1_fclk_div5.hw, + [CLKID_FCLK_DIV7] = &a1_fclk_div7.hw, + [CLKID_HIFI_PLL] = &a1_hifi_pll.hw, }; -static const struct regmap_config a1_pll_regmap_cfg = { - .reg_bits = 32, - .val_bits = 32, - .reg_stride = 4, - .max_register = ANACTRL_HIFIPLL_STS, -}; - -static struct meson_clk_hw_data a1_pll_clks = { - .hws = a1_pll_hw_clks, - .num = ARRAY_SIZE(a1_pll_hw_clks), +static const struct meson_clkc_data a1_pll_clkc_data = { + .hw_clks = { + .hws = a1_pll_hw_clks, + .num = ARRAY_SIZE(a1_pll_hw_clks), + }, }; -static int meson_a1_pll_probe(struct platform_device *pdev) -{ - struct device *dev = &pdev->dev; - void __iomem *base; - struct regmap *map; - int clkid, err; - - base = devm_platform_ioremap_resource(pdev, 0); - if (IS_ERR(base)) - return dev_err_probe(dev, PTR_ERR(base), - "can't ioremap resource\n"); - - map = devm_regmap_init_mmio(dev, base, &a1_pll_regmap_cfg); - if (IS_ERR(map)) - return dev_err_probe(dev, PTR_ERR(map), - "can't init regmap mmio region\n"); - - /* Register clocks */ - for (clkid = 0; clkid < a1_pll_clks.num; clkid++) { - err = devm_clk_hw_register(dev, a1_pll_clks.hws[clkid]); - if (err) - return dev_err_probe(dev, err, - "clock[%d] registration failed\n", - clkid); - } - - return devm_of_clk_add_hw_provider(dev, meson_clk_hw_get, - &a1_pll_clks); -} - static const struct of_device_id a1_pll_clkc_match_table[] = { - { .compatible = "amlogic,a1-pll-clkc", }, + { + .compatible = "amlogic,a1-pll-clkc", + .data = &a1_pll_clkc_data, + }, {} }; MODULE_DEVICE_TABLE(of, a1_pll_clkc_match_table); static struct platform_driver a1_pll_clkc_driver = { - .probe = meson_a1_pll_probe, + .probe = meson_clkc_mmio_probe, .driver = { .name = "a1-pll-clkc", .of_match_table = a1_pll_clkc_match_table, diff --git a/drivers/clk/meson/axg-aoclk.c b/drivers/clk/meson/axg-aoclk.c index cd5d0b5ebdb2..902fbd34039c 100644 --- a/drivers/clk/meson/axg-aoclk.c +++ b/drivers/clk/meson/axg-aoclk.c @@ -34,32 +34,21 @@ #define AO_RTC_ALT_CLK_CNTL0 0x94 #define AO_RTC_ALT_CLK_CNTL1 0x98 -#define AXG_AO_GATE(_name, _bit) \ -static struct clk_regmap axg_aoclk_##_name = { \ - .data = &(struct clk_regmap_gate_data) { \ - .offset = (AO_RTI_GEN_CNTL_REG0), \ - .bit_idx = (_bit), \ - }, \ - .hw.init = &(struct clk_init_data) { \ - .name = "axg_ao_" #_name, \ - .ops = &clk_regmap_gate_ops, \ - .parent_data = &(const struct clk_parent_data) { \ - .fw_name = "mpeg-clk", \ - }, \ - .num_parents = 1, \ - .flags = CLK_IGNORE_UNUSED, \ - }, \ -} +static const struct clk_parent_data axg_ao_pclk_parents = { .fw_name = "mpeg-clk" }; -AXG_AO_GATE(remote, 0); -AXG_AO_GATE(i2c_master, 1); -AXG_AO_GATE(i2c_slave, 2); -AXG_AO_GATE(uart1, 3); -AXG_AO_GATE(uart2, 5); -AXG_AO_GATE(ir_blaster, 6); -AXG_AO_GATE(saradc, 7); +#define AXG_AO_GATE(_name, _bit, _flags) \ + MESON_PCLK(axg_ao_##_name, AO_RTI_GEN_CNTL_REG0, _bit, \ + &axg_ao_pclk_parents, _flags) -static struct clk_regmap axg_aoclk_cts_oscin = { +static AXG_AO_GATE(remote, 0, CLK_IGNORE_UNUSED); +static AXG_AO_GATE(i2c_master, 1, CLK_IGNORE_UNUSED); +static AXG_AO_GATE(i2c_slave, 2, CLK_IGNORE_UNUSED); +static AXG_AO_GATE(uart1, 3, CLK_IGNORE_UNUSED); +static AXG_AO_GATE(uart2, 5, CLK_IGNORE_UNUSED); +static AXG_AO_GATE(ir_blaster, 6, CLK_IGNORE_UNUSED); +static AXG_AO_GATE(saradc, 7, CLK_IGNORE_UNUSED); + +static struct clk_regmap axg_ao_cts_oscin = { .data = &(struct clk_regmap_gate_data){ .offset = AO_RTI_PWR_CNTL_REG0, .bit_idx = 14, @@ -74,7 +63,7 @@ static struct clk_regmap axg_aoclk_cts_oscin = { }, }; -static struct clk_regmap axg_aoclk_32k_pre = { +static struct clk_regmap axg_ao_32k_pre = { .data = &(struct clk_regmap_gate_data){ .offset = AO_RTC_ALT_CLK_CNTL0, .bit_idx = 31, @@ -83,7 +72,7 @@ static struct clk_regmap axg_aoclk_32k_pre = { .name = "axg_ao_32k_pre", .ops = &clk_regmap_gate_ops, .parent_hws = (const struct clk_hw *[]) { - &axg_aoclk_cts_oscin.hw + &axg_ao_cts_oscin.hw }, .num_parents = 1, }, @@ -99,7 +88,7 @@ static const struct meson_clk_dualdiv_param axg_32k_div_table[] = { }, {} }; -static struct clk_regmap axg_aoclk_32k_div = { +static struct clk_regmap axg_ao_32k_div = { .data = &(struct meson_clk_dualdiv_data){ .n1 = { .reg_off = AO_RTC_ALT_CLK_CNTL0, @@ -132,13 +121,13 @@ static struct clk_regmap axg_aoclk_32k_div = { .name = "axg_ao_32k_div", .ops = &meson_clk_dualdiv_ops, .parent_hws = (const struct clk_hw *[]) { - &axg_aoclk_32k_pre.hw + &axg_ao_32k_pre.hw }, .num_parents = 1, }, }; -static struct clk_regmap axg_aoclk_32k_sel = { +static struct clk_regmap axg_ao_32k_sel = { .data = &(struct clk_regmap_mux_data) { .offset = AO_RTC_ALT_CLK_CNTL1, .mask = 0x1, @@ -149,15 +138,15 @@ static struct clk_regmap axg_aoclk_32k_sel = { .name = "axg_ao_32k_sel", .ops = &clk_regmap_mux_ops, .parent_hws = (const struct clk_hw *[]) { - &axg_aoclk_32k_div.hw, - &axg_aoclk_32k_pre.hw, + &axg_ao_32k_div.hw, + &axg_ao_32k_pre.hw, }, .num_parents = 2, .flags = CLK_SET_RATE_PARENT, }, }; -static struct clk_regmap axg_aoclk_32k = { +static struct clk_regmap axg_ao_32k = { .data = &(struct clk_regmap_gate_data){ .offset = AO_RTC_ALT_CLK_CNTL0, .bit_idx = 30, @@ -166,14 +155,14 @@ static struct clk_regmap axg_aoclk_32k = { .name = "axg_ao_32k", .ops = &clk_regmap_gate_ops, .parent_hws = (const struct clk_hw *[]) { - &axg_aoclk_32k_sel.hw + &axg_ao_32k_sel.hw }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, }; -static struct clk_regmap axg_aoclk_cts_rtc_oscin = { +static struct clk_regmap axg_ao_cts_rtc_oscin = { .data = &(struct clk_regmap_mux_data) { .offset = AO_RTI_PWR_CNTL_REG0, .mask = 0x1, @@ -184,7 +173,7 @@ static struct clk_regmap axg_aoclk_cts_rtc_oscin = { .name = "axg_ao_cts_rtc_oscin", .ops = &clk_regmap_mux_ops, .parent_data = (const struct clk_parent_data []) { - { .hw = &axg_aoclk_32k.hw }, + { .hw = &axg_ao_32k.hw }, { .fw_name = "ext_32k-0", }, }, .num_parents = 2, @@ -192,7 +181,7 @@ static struct clk_regmap axg_aoclk_cts_rtc_oscin = { }, }; -static struct clk_regmap axg_aoclk_clk81 = { +static struct clk_regmap axg_ao_clk81 = { .data = &(struct clk_regmap_mux_data) { .offset = AO_RTI_PWR_CNTL_REG0, .mask = 0x1, @@ -200,68 +189,74 @@ static struct clk_regmap axg_aoclk_clk81 = { .flags = CLK_MUX_ROUND_CLOSEST, }, .hw.init = &(struct clk_init_data){ + /* + * NOTE: this is one of the infamous clock the pwm driver + * can request directly by its global name. It's wrong but + * there is not much we can do about it until the support + * for the old pwm bindings is dropped + */ .name = "axg_ao_clk81", .ops = &clk_regmap_mux_ro_ops, .parent_data = (const struct clk_parent_data []) { { .fw_name = "mpeg-clk", }, - { .hw = &axg_aoclk_cts_rtc_oscin.hw }, + { .hw = &axg_ao_cts_rtc_oscin.hw }, }, .num_parents = 2, .flags = CLK_SET_RATE_PARENT, }, }; -static struct clk_regmap axg_aoclk_saradc_mux = { +static struct clk_regmap axg_ao_saradc_mux = { .data = &(struct clk_regmap_mux_data) { .offset = AO_SAR_CLK, .mask = 0x3, .shift = 9, }, .hw.init = &(struct clk_init_data){ - .name = "axg_ao_saradc_mux", + .name = "ao_saradc_mux", .ops = &clk_regmap_mux_ops, .parent_data = (const struct clk_parent_data []) { { .fw_name = "xtal", }, - { .hw = &axg_aoclk_clk81.hw }, + { .hw = &axg_ao_clk81.hw }, }, .num_parents = 2, }, }; -static struct clk_regmap axg_aoclk_saradc_div = { +static struct clk_regmap axg_ao_saradc_div = { .data = &(struct clk_regmap_div_data) { .offset = AO_SAR_CLK, .shift = 0, .width = 8, }, .hw.init = &(struct clk_init_data){ - .name = "axg_ao_saradc_div", + .name = "ao_saradc_div", .ops = &clk_regmap_divider_ops, .parent_hws = (const struct clk_hw *[]) { - &axg_aoclk_saradc_mux.hw + &axg_ao_saradc_mux.hw }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, }; -static struct clk_regmap axg_aoclk_saradc_gate = { +static struct clk_regmap axg_ao_saradc_gate = { .data = &(struct clk_regmap_gate_data) { .offset = AO_SAR_CLK, .bit_idx = 8, }, .hw.init = &(struct clk_init_data){ - .name = "axg_ao_saradc_gate", + .name = "ao_saradc_gate", .ops = &clk_regmap_gate_ops, .parent_hws = (const struct clk_hw *[]) { - &axg_aoclk_saradc_div.hw + &axg_ao_saradc_div.hw }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, }; -static const unsigned int axg_aoclk_reset[] = { +static const unsigned int axg_ao_reset[] = { [RESET_AO_REMOTE] = 16, [RESET_AO_I2C_MASTER] = 18, [RESET_AO_I2C_SLAVE] = 19, @@ -270,53 +265,55 @@ static const unsigned int axg_aoclk_reset[] = { [RESET_AO_IR_BLASTER] = 23, }; -static struct clk_hw *axg_aoclk_hw_clks[] = { - [CLKID_AO_REMOTE] = &axg_aoclk_remote.hw, - [CLKID_AO_I2C_MASTER] = &axg_aoclk_i2c_master.hw, - [CLKID_AO_I2C_SLAVE] = &axg_aoclk_i2c_slave.hw, - [CLKID_AO_UART1] = &axg_aoclk_uart1.hw, - [CLKID_AO_UART2] = &axg_aoclk_uart2.hw, - [CLKID_AO_IR_BLASTER] = &axg_aoclk_ir_blaster.hw, - [CLKID_AO_SAR_ADC] = &axg_aoclk_saradc.hw, - [CLKID_AO_CLK81] = &axg_aoclk_clk81.hw, - [CLKID_AO_SAR_ADC_SEL] = &axg_aoclk_saradc_mux.hw, - [CLKID_AO_SAR_ADC_DIV] = &axg_aoclk_saradc_div.hw, - [CLKID_AO_SAR_ADC_CLK] = &axg_aoclk_saradc_gate.hw, - [CLKID_AO_CTS_OSCIN] = &axg_aoclk_cts_oscin.hw, - [CLKID_AO_32K_PRE] = &axg_aoclk_32k_pre.hw, - [CLKID_AO_32K_DIV] = &axg_aoclk_32k_div.hw, - [CLKID_AO_32K_SEL] = &axg_aoclk_32k_sel.hw, - [CLKID_AO_32K] = &axg_aoclk_32k.hw, - [CLKID_AO_CTS_RTC_OSCIN] = &axg_aoclk_cts_rtc_oscin.hw, +static struct clk_hw *axg_ao_hw_clks[] = { + [CLKID_AO_REMOTE] = &axg_ao_remote.hw, + [CLKID_AO_I2C_MASTER] = &axg_ao_i2c_master.hw, + [CLKID_AO_I2C_SLAVE] = &axg_ao_i2c_slave.hw, + [CLKID_AO_UART1] = &axg_ao_uart1.hw, + [CLKID_AO_UART2] = &axg_ao_uart2.hw, + [CLKID_AO_IR_BLASTER] = &axg_ao_ir_blaster.hw, + [CLKID_AO_SAR_ADC] = &axg_ao_saradc.hw, + [CLKID_AO_CLK81] = &axg_ao_clk81.hw, + [CLKID_AO_SAR_ADC_SEL] = &axg_ao_saradc_mux.hw, + [CLKID_AO_SAR_ADC_DIV] = &axg_ao_saradc_div.hw, + [CLKID_AO_SAR_ADC_CLK] = &axg_ao_saradc_gate.hw, + [CLKID_AO_CTS_OSCIN] = &axg_ao_cts_oscin.hw, + [CLKID_AO_32K_PRE] = &axg_ao_32k_pre.hw, + [CLKID_AO_32K_DIV] = &axg_ao_32k_div.hw, + [CLKID_AO_32K_SEL] = &axg_ao_32k_sel.hw, + [CLKID_AO_32K] = &axg_ao_32k.hw, + [CLKID_AO_CTS_RTC_OSCIN] = &axg_ao_cts_rtc_oscin.hw, }; -static const struct meson_aoclk_data axg_aoclkc_data = { +static const struct meson_aoclk_data axg_ao_clkc_data = { .reset_reg = AO_RTI_GEN_CNTL_REG0, - .num_reset = ARRAY_SIZE(axg_aoclk_reset), - .reset = axg_aoclk_reset, - .hw_clks = { - .hws = axg_aoclk_hw_clks, - .num = ARRAY_SIZE(axg_aoclk_hw_clks), + .num_reset = ARRAY_SIZE(axg_ao_reset), + .reset = axg_ao_reset, + .clkc_data = { + .hw_clks = { + .hws = axg_ao_hw_clks, + .num = ARRAY_SIZE(axg_ao_hw_clks), + }, }, }; -static const struct of_device_id axg_aoclkc_match_table[] = { +static const struct of_device_id axg_ao_clkc_match_table[] = { { .compatible = "amlogic,meson-axg-aoclkc", - .data = &axg_aoclkc_data, + .data = &axg_ao_clkc_data.clkc_data, }, { } }; -MODULE_DEVICE_TABLE(of, axg_aoclkc_match_table); +MODULE_DEVICE_TABLE(of, axg_ao_clkc_match_table); -static struct platform_driver axg_aoclkc_driver = { +static struct platform_driver axg_ao_clkc_driver = { .probe = meson_aoclkc_probe, .driver = { - .name = "axg-aoclkc", - .of_match_table = axg_aoclkc_match_table, + .name = "axg-ao-clkc", + .of_match_table = axg_ao_clkc_match_table, }, }; -module_platform_driver(axg_aoclkc_driver); +module_platform_driver(axg_ao_clkc_driver); MODULE_DESCRIPTION("Amlogic AXG Always-ON Clock Controller driver"); MODULE_LICENSE("GPL"); diff --git a/drivers/clk/meson/axg.c b/drivers/clk/meson/axg.c index 208833c3ee95..0a25c649ef1d 100644 --- a/drivers/clk/meson/axg.c +++ b/drivers/clk/meson/axg.c @@ -18,7 +18,7 @@ #include "clk-regmap.h" #include "clk-pll.h" #include "clk-mpll.h" -#include "meson-eeclk.h" +#include "meson-clkc-utils.h" #include <dt-bindings/clock/axg-clkc.h> @@ -333,7 +333,7 @@ static struct clk_regmap axg_gp0_pll = { }, }; -static const struct reg_sequence axg_hifi_init_regs[] = { +static const struct reg_sequence axg_hifi_pll_init_regs[] = { { .reg = HHI_HIFI_PLL_CNTL1, .def = 0xc084b000 }, { .reg = HHI_HIFI_PLL_CNTL2, .def = 0xb75020be }, { .reg = HHI_HIFI_PLL_CNTL3, .def = 0x0a6a3a88 }, @@ -374,8 +374,8 @@ static struct clk_regmap axg_hifi_pll_dco = { .width = 1, }, .table = axg_gp0_pll_params_table, - .init_regs = axg_hifi_init_regs, - .init_count = ARRAY_SIZE(axg_hifi_init_regs), + .init_regs = axg_hifi_pll_init_regs, + .init_count = ARRAY_SIZE(axg_hifi_pll_init_regs), .flags = CLK_MESON_PLL_ROUND_CLOSEST, }, .hw.init = &(struct clk_init_data){ @@ -780,7 +780,7 @@ static const struct pll_params_table axg_pcie_pll_params_table[] = { { /* sentinel */ }, }; -static const struct reg_sequence axg_pcie_init_regs[] = { +static const struct reg_sequence axg_pcie_pll_init_regs[] = { { .reg = HHI_PCIE_PLL_CNTL1, .def = 0x0084a2aa }, { .reg = HHI_PCIE_PLL_CNTL2, .def = 0xb75020be }, { .reg = HHI_PCIE_PLL_CNTL3, .def = 0x0a47488e }, @@ -823,8 +823,8 @@ static struct clk_regmap axg_pcie_pll_dco = { .width = 1, }, .table = axg_pcie_pll_params_table, - .init_regs = axg_pcie_init_regs, - .init_count = ARRAY_SIZE(axg_pcie_init_regs), + .init_regs = axg_pcie_pll_init_regs, + .init_count = ARRAY_SIZE(axg_pcie_pll_init_regs), }, .hw.init = &(struct clk_init_data){ .name = "pcie_pll_dco", @@ -935,8 +935,9 @@ static struct clk_regmap axg_pcie_cml_en1 = { }, }; -static u32 mux_table_clk81[] = { 0, 2, 3, 4, 5, 6, 7 }; -static const struct clk_parent_data clk81_parent_data[] = { +/* clk81 is often referred as "mpeg_clk" */ +static u32 clk81_parents_val_table[] = { 0, 2, 3, 4, 5, 6, 7 }; +static const struct clk_parent_data clk81_parents[] = { { .fw_name = "xtal", }, { .hw = &axg_fclk_div7.hw }, { .hw = &axg_mpll1.hw }, @@ -946,32 +947,32 @@ static const struct clk_parent_data clk81_parent_data[] = { { .hw = &axg_fclk_div5.hw }, }; -static struct clk_regmap axg_mpeg_clk_sel = { +static struct clk_regmap axg_clk81_sel = { .data = &(struct clk_regmap_mux_data){ .offset = HHI_MPEG_CLK_CNTL, .mask = 0x7, .shift = 12, - .table = mux_table_clk81, + .table = clk81_parents_val_table, }, .hw.init = &(struct clk_init_data){ - .name = "mpeg_clk_sel", + .name = "clk81_sel", .ops = &clk_regmap_mux_ro_ops, - .parent_data = clk81_parent_data, - .num_parents = ARRAY_SIZE(clk81_parent_data), + .parent_data = clk81_parents, + .num_parents = ARRAY_SIZE(clk81_parents), }, }; -static struct clk_regmap axg_mpeg_clk_div = { +static struct clk_regmap axg_clk81_div = { .data = &(struct clk_regmap_div_data){ .offset = HHI_MPEG_CLK_CNTL, .shift = 0, .width = 7, }, .hw.init = &(struct clk_init_data){ - .name = "mpeg_clk_div", + .name = "clk81_div", .ops = &clk_regmap_divider_ops, .parent_hws = (const struct clk_hw *[]) { - &axg_mpeg_clk_sel.hw + &axg_clk81_sel.hw }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, @@ -987,14 +988,14 @@ static struct clk_regmap axg_clk81 = { .name = "clk81", .ops = &clk_regmap_gate_ops, .parent_hws = (const struct clk_hw *[]) { - &axg_mpeg_clk_div.hw + &axg_clk81_div.hw }, .num_parents = 1, .flags = (CLK_SET_RATE_PARENT | CLK_IS_CRITICAL), }, }; -static const struct clk_parent_data axg_sd_emmc_clk0_parent_data[] = { +static const struct clk_parent_data axg_sd_emmc_clk0_parents[] = { { .fw_name = "xtal", }, { .hw = &axg_fclk_div2.hw }, { .hw = &axg_fclk_div3.hw }, @@ -1018,8 +1019,8 @@ static struct clk_regmap axg_sd_emmc_b_clk0_sel = { .hw.init = &(struct clk_init_data) { .name = "sd_emmc_b_clk0_sel", .ops = &clk_regmap_mux_ops, - .parent_data = axg_sd_emmc_clk0_parent_data, - .num_parents = ARRAY_SIZE(axg_sd_emmc_clk0_parent_data), + .parent_data = axg_sd_emmc_clk0_parents, + .num_parents = ARRAY_SIZE(axg_sd_emmc_clk0_parents), .flags = CLK_SET_RATE_PARENT, }, }; @@ -1068,8 +1069,8 @@ static struct clk_regmap axg_sd_emmc_c_clk0_sel = { .hw.init = &(struct clk_init_data) { .name = "sd_emmc_c_clk0_sel", .ops = &clk_regmap_mux_ops, - .parent_data = axg_sd_emmc_clk0_parent_data, - .num_parents = ARRAY_SIZE(axg_sd_emmc_clk0_parent_data), + .parent_data = axg_sd_emmc_clk0_parents, + .num_parents = ARRAY_SIZE(axg_sd_emmc_clk0_parents), .flags = CLK_SET_RATE_PARENT, }, }; @@ -1110,7 +1111,7 @@ static struct clk_regmap axg_sd_emmc_c_clk0 = { /* VPU Clock */ -static const struct clk_hw *axg_vpu_parent_hws[] = { +static const struct clk_hw *axg_vpu_parents[] = { &axg_fclk_div4.hw, &axg_fclk_div3.hw, &axg_fclk_div5.hw, @@ -1126,8 +1127,8 @@ static struct clk_regmap axg_vpu_0_sel = { .hw.init = &(struct clk_init_data){ .name = "vpu_0_sel", .ops = &clk_regmap_mux_ops, - .parent_hws = axg_vpu_parent_hws, - .num_parents = ARRAY_SIZE(axg_vpu_parent_hws), + .parent_hws = axg_vpu_parents, + .num_parents = ARRAY_SIZE(axg_vpu_parents), /* We need a specific parent for VPU clock source, let it be set in DT */ .flags = CLK_SET_RATE_NO_REPARENT, }, @@ -1175,8 +1176,8 @@ static struct clk_regmap axg_vpu_1_sel = { .hw.init = &(struct clk_init_data){ .name = "vpu_1_sel", .ops = &clk_regmap_mux_ops, - .parent_hws = axg_vpu_parent_hws, - .num_parents = ARRAY_SIZE(axg_vpu_parent_hws), + .parent_hws = axg_vpu_parents, + .num_parents = ARRAY_SIZE(axg_vpu_parents), /* We need a specific parent for VPU clock source, let it be set in DT */ .flags = CLK_SET_RATE_NO_REPARENT, }, @@ -1244,8 +1245,8 @@ static struct clk_regmap axg_vapb_0_sel = { .hw.init = &(struct clk_init_data){ .name = "vapb_0_sel", .ops = &clk_regmap_mux_ops, - .parent_hws = axg_vpu_parent_hws, - .num_parents = ARRAY_SIZE(axg_vpu_parent_hws), + .parent_hws = axg_vpu_parents, + .num_parents = ARRAY_SIZE(axg_vpu_parents), .flags = CLK_SET_RATE_NO_REPARENT, }, }; @@ -1292,8 +1293,8 @@ static struct clk_regmap axg_vapb_1_sel = { .hw.init = &(struct clk_init_data){ .name = "vapb_1_sel", .ops = &clk_regmap_mux_ops, - .parent_hws = axg_vpu_parent_hws, - .num_parents = ARRAY_SIZE(axg_vpu_parent_hws), + .parent_hws = axg_vpu_parents, + .num_parents = ARRAY_SIZE(axg_vpu_parents), .flags = CLK_SET_RATE_NO_REPARENT, }, }; @@ -1365,7 +1366,7 @@ static struct clk_regmap axg_vapb = { /* Video Clocks */ -static const struct clk_hw *axg_vclk_parent_hws[] = { +static const struct clk_hw *axg_vclk_parents[] = { &axg_gp0_pll.hw, &axg_fclk_div4.hw, &axg_fclk_div3.hw, @@ -1384,8 +1385,8 @@ static struct clk_regmap axg_vclk_sel = { .hw.init = &(struct clk_init_data){ .name = "vclk_sel", .ops = &clk_regmap_mux_ops, - .parent_hws = axg_vclk_parent_hws, - .num_parents = ARRAY_SIZE(axg_vclk_parent_hws), + .parent_hws = axg_vclk_parents, + .num_parents = ARRAY_SIZE(axg_vclk_parents), .flags = CLK_SET_RATE_NO_REPARENT | CLK_GET_RATE_NOCACHE, }, }; @@ -1399,8 +1400,8 @@ static struct clk_regmap axg_vclk2_sel = { .hw.init = &(struct clk_init_data){ .name = "vclk2_sel", .ops = &clk_regmap_mux_ops, - .parent_hws = axg_vclk_parent_hws, - .num_parents = ARRAY_SIZE(axg_vclk_parent_hws), + .parent_hws = axg_vclk_parents, + .num_parents = ARRAY_SIZE(axg_vclk_parents), .flags = CLK_SET_RATE_NO_REPARENT | CLK_GET_RATE_NOCACHE, }, }; @@ -1739,8 +1740,8 @@ static struct clk_fixed_factor axg_vclk2_div12 = { }, }; -static u32 mux_table_cts_sel[] = { 0, 1, 2, 3, 4, 8, 9, 10, 11, 12 }; -static const struct clk_hw *axg_cts_parent_hws[] = { +static u32 axg_cts_encl_parents_val_table[] = { 0, 1, 2, 3, 4, 8, 9, 10, 11, 12 }; +static const struct clk_hw *axg_cts_encl_parents[] = { &axg_vclk_div1.hw, &axg_vclk_div2.hw, &axg_vclk_div4.hw, @@ -1758,13 +1759,13 @@ static struct clk_regmap axg_cts_encl_sel = { .offset = HHI_VIID_CLK_DIV, .mask = 0xf, .shift = 12, - .table = mux_table_cts_sel, + .table = axg_cts_encl_parents_val_table, }, .hw.init = &(struct clk_init_data){ .name = "cts_encl_sel", .ops = &clk_regmap_mux_ops, - .parent_hws = axg_cts_parent_hws, - .num_parents = ARRAY_SIZE(axg_cts_parent_hws), + .parent_hws = axg_cts_encl_parents, + .num_parents = ARRAY_SIZE(axg_cts_encl_parents), .flags = CLK_SET_RATE_NO_REPARENT | CLK_GET_RATE_NOCACHE, }, }; @@ -1787,8 +1788,8 @@ static struct clk_regmap axg_cts_encl = { /* MIPI DSI Host Clock */ -static u32 mux_table_axg_vdin_meas[] = { 0, 1, 2, 3, 6, 7 }; -static const struct clk_parent_data axg_vdin_meas_parent_data[] = { +static u32 axg_vdin_meas_parents_val_table[] = { 0, 1, 2, 3, 6, 7 }; +static const struct clk_parent_data axg_vdin_meas_parents[] = { { .fw_name = "xtal", }, { .hw = &axg_fclk_div4.hw }, { .hw = &axg_fclk_div3.hw }, @@ -1803,13 +1804,13 @@ static struct clk_regmap axg_vdin_meas_sel = { .mask = 0x7, .shift = 21, .flags = CLK_MUX_ROUND_CLOSEST, - .table = mux_table_axg_vdin_meas, + .table = axg_vdin_meas_parents_val_table, }, .hw.init = &(struct clk_init_data){ .name = "vdin_meas_sel", .ops = &clk_regmap_mux_ops, - .parent_data = axg_vdin_meas_parent_data, - .num_parents = ARRAY_SIZE(axg_vdin_meas_parent_data), + .parent_data = axg_vdin_meas_parents, + .num_parents = ARRAY_SIZE(axg_vdin_meas_parents), .flags = CLK_SET_RATE_PARENT, }, }; @@ -1845,9 +1846,8 @@ static struct clk_regmap axg_vdin_meas = { }, }; -static u32 mux_table_gen_clk[] = { 0, 4, 5, 6, 7, 8, - 9, 10, 11, 13, 14, }; -static const struct clk_parent_data gen_clk_parent_data[] = { +static u32 gen_clk_parents_val_table[] = { 0, 4, 5, 6, 7, 8, 9, 10, 11, 13, 14, }; +static const struct clk_parent_data gen_clk_parents[] = { { .fw_name = "xtal", }, { .hw = &axg_hifi_pll.hw }, { .hw = &axg_mpll0.hw }, @@ -1866,7 +1866,7 @@ static struct clk_regmap axg_gen_clk_sel = { .offset = HHI_GEN_CLK_CNTL, .mask = 0xf, .shift = 12, - .table = mux_table_gen_clk, + .table = gen_clk_parents_val_table, }, .hw.init = &(struct clk_init_data){ .name = "gen_clk_sel", @@ -1877,8 +1877,8 @@ static struct clk_regmap axg_gen_clk_sel = { * hifi_pll, mpll0, mpll1, mpll2, mpll3, fdiv4, * fdiv3, fdiv5, [cts_msr_clk], fdiv7, gp0_pll */ - .parent_data = gen_clk_parent_data, - .num_parents = ARRAY_SIZE(gen_clk_parent_data), + .parent_data = gen_clk_parents, + .num_parents = ARRAY_SIZE(gen_clk_parents), }, }; @@ -1915,59 +1915,71 @@ static struct clk_regmap axg_gen_clk = { }, }; -#define MESON_GATE(_name, _reg, _bit) \ - MESON_PCLK(_name, _reg, _bit, &axg_clk81.hw) - -/* Everything Else (EE) domain gates */ -static MESON_GATE(axg_ddr, HHI_GCLK_MPEG0, 0); -static MESON_GATE(axg_audio_locker, HHI_GCLK_MPEG0, 2); -static MESON_GATE(axg_mipi_dsi_host, HHI_GCLK_MPEG0, 3); -static MESON_GATE(axg_isa, HHI_GCLK_MPEG0, 5); -static MESON_GATE(axg_pl301, HHI_GCLK_MPEG0, 6); -static MESON_GATE(axg_periphs, HHI_GCLK_MPEG0, 7); -static MESON_GATE(axg_spicc_0, HHI_GCLK_MPEG0, 8); -static MESON_GATE(axg_i2c, HHI_GCLK_MPEG0, 9); -static MESON_GATE(axg_rng0, HHI_GCLK_MPEG0, 12); -static MESON_GATE(axg_uart0, HHI_GCLK_MPEG0, 13); -static MESON_GATE(axg_mipi_dsi_phy, HHI_GCLK_MPEG0, 14); -static MESON_GATE(axg_spicc_1, HHI_GCLK_MPEG0, 15); -static MESON_GATE(axg_pcie_a, HHI_GCLK_MPEG0, 16); -static MESON_GATE(axg_pcie_b, HHI_GCLK_MPEG0, 17); -static MESON_GATE(axg_hiu_reg, HHI_GCLK_MPEG0, 19); -static MESON_GATE(axg_assist_misc, HHI_GCLK_MPEG0, 23); -static MESON_GATE(axg_emmc_b, HHI_GCLK_MPEG0, 25); -static MESON_GATE(axg_emmc_c, HHI_GCLK_MPEG0, 26); -static MESON_GATE(axg_dma, HHI_GCLK_MPEG0, 27); -static MESON_GATE(axg_spi, HHI_GCLK_MPEG0, 30); - -static MESON_GATE(axg_audio, HHI_GCLK_MPEG1, 0); -static MESON_GATE(axg_eth_core, HHI_GCLK_MPEG1, 3); -static MESON_GATE(axg_uart1, HHI_GCLK_MPEG1, 16); -static MESON_GATE(axg_g2d, HHI_GCLK_MPEG1, 20); -static MESON_GATE(axg_usb0, HHI_GCLK_MPEG1, 21); -static MESON_GATE(axg_usb1, HHI_GCLK_MPEG1, 22); -static MESON_GATE(axg_reset, HHI_GCLK_MPEG1, 23); -static MESON_GATE(axg_usb_general, HHI_GCLK_MPEG1, 26); -static MESON_GATE(axg_ahb_arb0, HHI_GCLK_MPEG1, 29); -static MESON_GATE(axg_efuse, HHI_GCLK_MPEG1, 30); -static MESON_GATE(axg_boot_rom, HHI_GCLK_MPEG1, 31); - -static MESON_GATE(axg_ahb_data_bus, HHI_GCLK_MPEG2, 1); -static MESON_GATE(axg_ahb_ctrl_bus, HHI_GCLK_MPEG2, 2); -static MESON_GATE(axg_usb1_to_ddr, HHI_GCLK_MPEG2, 8); -static MESON_GATE(axg_usb0_to_ddr, HHI_GCLK_MPEG2, 9); -static MESON_GATE(axg_mmc_pclk, HHI_GCLK_MPEG2, 11); -static MESON_GATE(axg_vpu_intr, HHI_GCLK_MPEG2, 25); -static MESON_GATE(axg_sec_ahb_ahb3_bridge, HHI_GCLK_MPEG2, 26); -static MESON_GATE(axg_gic, HHI_GCLK_MPEG2, 30); +static const struct clk_parent_data axg_pclk_parents = { .hw = &axg_clk81.hw }; + +#define AXG_PCLK(_name, _reg, _bit, _flags) \ + MESON_PCLK(axg_##_name, _reg, _bit, &axg_pclk_parents, _flags) + +/* + * Everything Else (EE) domain gates + * + * NOTE: The gates below are marked with CLK_IGNORE_UNUSED for historic reasons + * Users are encouraged to test without it and submit changes to: + * - remove the flag if not necessary + * - replace the flag with something more adequate, such as CLK_IS_CRITICAL, + * if appropriate. + * - add a comment explaining why the use of CLK_IGNORE_UNUSED is desirable + * for a particular clock. + */ +static AXG_PCLK(ddr, HHI_GCLK_MPEG0, 0, CLK_IGNORE_UNUSED); +static AXG_PCLK(audio_locker, HHI_GCLK_MPEG0, 2, CLK_IGNORE_UNUSED); +static AXG_PCLK(mipi_dsi_host, HHI_GCLK_MPEG0, 3, CLK_IGNORE_UNUSED); +static AXG_PCLK(isa, HHI_GCLK_MPEG0, 5, CLK_IGNORE_UNUSED); +static AXG_PCLK(pl301, HHI_GCLK_MPEG0, 6, CLK_IGNORE_UNUSED); +static AXG_PCLK(periphs, HHI_GCLK_MPEG0, 7, CLK_IGNORE_UNUSED); +static AXG_PCLK(spicc_0, HHI_GCLK_MPEG0, 8, CLK_IGNORE_UNUSED); +static AXG_PCLK(i2c, HHI_GCLK_MPEG0, 9, CLK_IGNORE_UNUSED); +static AXG_PCLK(rng0, HHI_GCLK_MPEG0, 12, CLK_IGNORE_UNUSED); +static AXG_PCLK(uart0, HHI_GCLK_MPEG0, 13, CLK_IGNORE_UNUSED); +static AXG_PCLK(mipi_dsi_phy, HHI_GCLK_MPEG0, 14, CLK_IGNORE_UNUSED); +static AXG_PCLK(spicc_1, HHI_GCLK_MPEG0, 15, CLK_IGNORE_UNUSED); +static AXG_PCLK(pcie_a, HHI_GCLK_MPEG0, 16, CLK_IGNORE_UNUSED); +static AXG_PCLK(pcie_b, HHI_GCLK_MPEG0, 17, CLK_IGNORE_UNUSED); +static AXG_PCLK(hiu_reg, HHI_GCLK_MPEG0, 19, CLK_IGNORE_UNUSED); +static AXG_PCLK(assist_misc, HHI_GCLK_MPEG0, 23, CLK_IGNORE_UNUSED); +static AXG_PCLK(emmc_b, HHI_GCLK_MPEG0, 25, CLK_IGNORE_UNUSED); +static AXG_PCLK(emmc_c, HHI_GCLK_MPEG0, 26, CLK_IGNORE_UNUSED); +static AXG_PCLK(dma, HHI_GCLK_MPEG0, 27, CLK_IGNORE_UNUSED); +static AXG_PCLK(spi, HHI_GCLK_MPEG0, 30, CLK_IGNORE_UNUSED); + +static AXG_PCLK(audio, HHI_GCLK_MPEG1, 0, CLK_IGNORE_UNUSED); +static AXG_PCLK(eth_core, HHI_GCLK_MPEG1, 3, CLK_IGNORE_UNUSED); +static AXG_PCLK(uart1, HHI_GCLK_MPEG1, 16, CLK_IGNORE_UNUSED); +static AXG_PCLK(g2d, HHI_GCLK_MPEG1, 20, CLK_IGNORE_UNUSED); +static AXG_PCLK(usb0, HHI_GCLK_MPEG1, 21, CLK_IGNORE_UNUSED); +static AXG_PCLK(usb1, HHI_GCLK_MPEG1, 22, CLK_IGNORE_UNUSED); +static AXG_PCLK(reset, HHI_GCLK_MPEG1, 23, CLK_IGNORE_UNUSED); +static AXG_PCLK(usb_general, HHI_GCLK_MPEG1, 26, CLK_IGNORE_UNUSED); +static AXG_PCLK(ahb_arb0, HHI_GCLK_MPEG1, 29, CLK_IGNORE_UNUSED); +static AXG_PCLK(efuse, HHI_GCLK_MPEG1, 30, CLK_IGNORE_UNUSED); +static AXG_PCLK(boot_rom, HHI_GCLK_MPEG1, 31, CLK_IGNORE_UNUSED); + +static AXG_PCLK(ahb_data_bus, HHI_GCLK_MPEG2, 1, CLK_IGNORE_UNUSED); +static AXG_PCLK(ahb_ctrl_bus, HHI_GCLK_MPEG2, 2, CLK_IGNORE_UNUSED); +static AXG_PCLK(usb1_to_ddr, HHI_GCLK_MPEG2, 8, CLK_IGNORE_UNUSED); +static AXG_PCLK(usb0_to_ddr, HHI_GCLK_MPEG2, 9, CLK_IGNORE_UNUSED); +static AXG_PCLK(mmc_pclk, HHI_GCLK_MPEG2, 11, CLK_IGNORE_UNUSED); +static AXG_PCLK(vpu_intr, HHI_GCLK_MPEG2, 25, CLK_IGNORE_UNUSED); +static AXG_PCLK(sec_ahb_ahb3_bridge, HHI_GCLK_MPEG2, 26, CLK_IGNORE_UNUSED); +static AXG_PCLK(gic, HHI_GCLK_MPEG2, 30, CLK_IGNORE_UNUSED); /* Always On (AO) domain gates */ -static MESON_GATE(axg_ao_media_cpu, HHI_GCLK_AO, 0); -static MESON_GATE(axg_ao_ahb_sram, HHI_GCLK_AO, 1); -static MESON_GATE(axg_ao_ahb_bus, HHI_GCLK_AO, 2); -static MESON_GATE(axg_ao_iface, HHI_GCLK_AO, 3); -static MESON_GATE(axg_ao_i2c, HHI_GCLK_AO, 4); +static AXG_PCLK(ao_media_cpu, HHI_GCLK_AO, 0, CLK_IGNORE_UNUSED); +static AXG_PCLK(ao_ahb_sram, HHI_GCLK_AO, 1, CLK_IGNORE_UNUSED); +static AXG_PCLK(ao_ahb_bus, HHI_GCLK_AO, 2, CLK_IGNORE_UNUSED); +static AXG_PCLK(ao_iface, HHI_GCLK_AO, 3, CLK_IGNORE_UNUSED); +static AXG_PCLK(ao_i2c, HHI_GCLK_AO, 4, CLK_IGNORE_UNUSED); /* Array of all clocks provided by this provider */ @@ -1980,8 +1992,8 @@ static struct clk_hw *axg_hw_clks[] = { [CLKID_FCLK_DIV5] = &axg_fclk_div5.hw, [CLKID_FCLK_DIV7] = &axg_fclk_div7.hw, [CLKID_GP0_PLL] = &axg_gp0_pll.hw, - [CLKID_MPEG_SEL] = &axg_mpeg_clk_sel.hw, - [CLKID_MPEG_DIV] = &axg_mpeg_clk_div.hw, + [CLKID_MPEG_SEL] = &axg_clk81_sel.hw, + [CLKID_MPEG_DIV] = &axg_clk81_div.hw, [CLKID_CLK81] = &axg_clk81.hw, [CLKID_MPLL0] = &axg_mpll0.hw, [CLKID_MPLL1] = &axg_mpll1.hw, @@ -2110,28 +2122,27 @@ static struct clk_hw *axg_hw_clks[] = { [CLKID_VDIN_MEAS] = &axg_vdin_meas.hw, }; -static const struct meson_eeclkc_data axg_clkc_data = { +static const struct meson_clkc_data axg_clkc_data = { .hw_clks = { .hws = axg_hw_clks, .num = ARRAY_SIZE(axg_hw_clks), }, }; - -static const struct of_device_id clkc_match_table[] = { +static const struct of_device_id axg_clkc_match_table[] = { { .compatible = "amlogic,axg-clkc", .data = &axg_clkc_data }, {} }; -MODULE_DEVICE_TABLE(of, clkc_match_table); +MODULE_DEVICE_TABLE(of, axg_clkc_match_table); -static struct platform_driver axg_driver = { - .probe = meson_eeclkc_probe, +static struct platform_driver axg_clkc_driver = { + .probe = meson_clkc_syscon_probe, .driver = { .name = "axg-clkc", - .of_match_table = clkc_match_table, + .of_match_table = axg_clkc_match_table, }, }; -module_platform_driver(axg_driver); +module_platform_driver(axg_clkc_driver); MODULE_DESCRIPTION("Amlogic AXG Main Clock Controller driver"); MODULE_LICENSE("GPL"); diff --git a/drivers/clk/meson/c3-peripherals.c b/drivers/clk/meson/c3-peripherals.c index a25e7d5dc669..b158756cfee4 100644 --- a/drivers/clk/meson/c3-peripherals.c +++ b/drivers/clk/meson/c3-peripherals.c @@ -48,7 +48,16 @@ #define SPIFC_CLK_CTRL 0x1a0 #define NNA_CLK_CTRL 0x220 -static struct clk_regmap rtc_xtal_clkin = { +#define C3_COMP_SEL(_name, _reg, _shift, _mask, _pdata) \ + MESON_COMP_SEL(c3_, _name, _reg, _shift, _mask, _pdata, NULL, 0, 0) + +#define C3_COMP_DIV(_name, _reg, _shift, _width) \ + MESON_COMP_DIV(c3_, _name, _reg, _shift, _width, 0, CLK_SET_RATE_PARENT) + +#define C3_COMP_GATE(_name, _reg, _bit) \ + MESON_COMP_GATE(c3_, _name, _reg, _bit, CLK_SET_RATE_PARENT) + +static struct clk_regmap c3_rtc_xtal_clkin = { .data = &(struct clk_regmap_gate_data) { .offset = RTC_BY_OSCIN_CTRL0, .bit_idx = 31, @@ -63,12 +72,12 @@ static struct clk_regmap rtc_xtal_clkin = { }, }; -static const struct meson_clk_dualdiv_param rtc_32k_div_table[] = { +static const struct meson_clk_dualdiv_param c3_rtc_32k_div_table[] = { { 733, 732, 8, 11, 1 }, { /* sentinel */ } }; -static struct clk_regmap rtc_32k_div = { +static struct clk_regmap c3_rtc_32k_div = { .data = &(struct meson_clk_dualdiv_data) { .n1 = { .reg_off = RTC_BY_OSCIN_CTRL0, @@ -95,39 +104,39 @@ static struct clk_regmap rtc_32k_div = { .shift = 28, .width = 1, }, - .table = rtc_32k_div_table, + .table = c3_rtc_32k_div_table, }, .hw.init = &(struct clk_init_data) { .name = "rtc_32k_div", .ops = &meson_clk_dualdiv_ops, .parent_hws = (const struct clk_hw *[]) { - &rtc_xtal_clkin.hw + &c3_rtc_xtal_clkin.hw }, .num_parents = 1, }, }; -static const struct clk_parent_data rtc_32k_mux_parent_data[] = { - { .hw = &rtc_32k_div.hw }, - { .hw = &rtc_xtal_clkin.hw } +static const struct clk_parent_data c3_rtc_32k_parents[] = { + { .hw = &c3_rtc_32k_div.hw }, + { .hw = &c3_rtc_xtal_clkin.hw } }; -static struct clk_regmap rtc_32k_mux = { +static struct clk_regmap c3_rtc_32k_sel = { .data = &(struct clk_regmap_mux_data) { .offset = RTC_BY_OSCIN_CTRL1, .mask = 0x1, .shift = 24, }, .hw.init = &(struct clk_init_data) { - .name = "rtc_32k_mux", + .name = "rtc_32k_sel", .ops = &clk_regmap_mux_ops, - .parent_data = rtc_32k_mux_parent_data, - .num_parents = ARRAY_SIZE(rtc_32k_mux_parent_data), + .parent_data = c3_rtc_32k_parents, + .num_parents = ARRAY_SIZE(c3_rtc_32k_parents), .flags = CLK_SET_RATE_PARENT, }, }; -static struct clk_regmap rtc_32k = { +static struct clk_regmap c3_rtc_32k = { .data = &(struct clk_regmap_gate_data) { .offset = RTC_BY_OSCIN_CTRL0, .bit_idx = 30, @@ -136,20 +145,20 @@ static struct clk_regmap rtc_32k = { .name = "rtc_32k", .ops = &clk_regmap_gate_ops, .parent_hws = (const struct clk_hw *[]) { - &rtc_32k_mux.hw + &c3_rtc_32k_sel.hw }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, }; -static const struct clk_parent_data rtc_clk_mux_parent_data[] = { +static const struct clk_parent_data c3_rtc_clk_parents[] = { { .fw_name = "oscin" }, - { .hw = &rtc_32k.hw }, + { .hw = &c3_rtc_32k.hw }, { .fw_name = "pad_osc" } }; -static struct clk_regmap rtc_clk = { +static struct clk_regmap c3_rtc_clk = { .data = &(struct clk_regmap_mux_data) { .offset = RTC_CTRL, .mask = 0x3, @@ -158,62 +167,45 @@ static struct clk_regmap rtc_clk = { .hw.init = &(struct clk_init_data) { .name = "rtc_clk", .ops = &clk_regmap_mux_ops, - .parent_data = rtc_clk_mux_parent_data, - .num_parents = ARRAY_SIZE(rtc_clk_mux_parent_data), + .parent_data = c3_rtc_clk_parents, + .num_parents = ARRAY_SIZE(c3_rtc_clk_parents), .flags = CLK_SET_RATE_PARENT, }, }; -#define C3_CLK_GATE(_name, _reg, _bit, _fw_name, _ops, _flags) \ -struct clk_regmap _name = { \ - .data = &(struct clk_regmap_gate_data){ \ - .offset = (_reg), \ - .bit_idx = (_bit), \ - }, \ - .hw.init = &(struct clk_init_data) { \ - .name = #_name, \ - .ops = _ops, \ - .parent_data = &(const struct clk_parent_data) { \ - .fw_name = #_fw_name, \ - }, \ - .num_parents = 1, \ - .flags = (_flags), \ - }, \ -} - -#define C3_SYS_GATE(_name, _reg, _bit, _flags) \ - C3_CLK_GATE(_name, _reg, _bit, sysclk, \ - &clk_regmap_gate_ops, _flags) - -#define C3_SYS_GATE_RO(_name, _reg, _bit) \ - C3_CLK_GATE(_name, _reg, _bit, sysclk, \ - &clk_regmap_gate_ro_ops, 0) - -static C3_SYS_GATE(sys_reset_ctrl, SYS_CLK_EN0_REG0, 1, 0); -static C3_SYS_GATE(sys_pwr_ctrl, SYS_CLK_EN0_REG0, 3, 0); -static C3_SYS_GATE(sys_pad_ctrl, SYS_CLK_EN0_REG0, 4, 0); -static C3_SYS_GATE(sys_ctrl, SYS_CLK_EN0_REG0, 5, 0); -static C3_SYS_GATE(sys_ts_pll, SYS_CLK_EN0_REG0, 6, 0); +static const struct clk_parent_data c3_sys_pclk_parents = { .fw_name = "sysclk" }; + +#define C3_SYS_PCLK(_name, _reg, _bit, _flags) \ + MESON_PCLK(c3_##_name, _reg, _bit, &c3_sys_pclk_parents, _flags) + +#define C3_SYS_PCLK_RO(_name, _reg, _bit) \ + MESON_PCLK_RO(c3_##_name, _reg, _bit, &c3_sys_pclk_parents, 0) + +static C3_SYS_PCLK(sys_reset_ctrl, SYS_CLK_EN0_REG0, 1, 0); +static C3_SYS_PCLK(sys_pwr_ctrl, SYS_CLK_EN0_REG0, 3, 0); +static C3_SYS_PCLK(sys_pad_ctrl, SYS_CLK_EN0_REG0, 4, 0); +static C3_SYS_PCLK(sys_ctrl, SYS_CLK_EN0_REG0, 5, 0); +static C3_SYS_PCLK(sys_ts_pll, SYS_CLK_EN0_REG0, 6, 0); /* * NOTE: sys_dev_arb provides the clock to the ETH and SPICC arbiters that * access the AXI bus. */ -static C3_SYS_GATE(sys_dev_arb, SYS_CLK_EN0_REG0, 7, 0); +static C3_SYS_PCLK(sys_dev_arb, SYS_CLK_EN0_REG0, 7, 0); /* * FIXME: sys_mmc_pclk provides the clock for the DDR PHY, DDR will only be * initialized in bl2, and this clock should not be touched in linux. */ -static C3_SYS_GATE_RO(sys_mmc_pclk, SYS_CLK_EN0_REG0, 8); +static C3_SYS_PCLK_RO(sys_mmc_pclk, SYS_CLK_EN0_REG0, 8); /* * NOTE: sys_cpu_ctrl provides the clock for CPU controller. After clock is * disabled, cpu_clk and other key CPU-related configurations cannot take effect. */ -static C3_SYS_GATE(sys_cpu_ctrl, SYS_CLK_EN0_REG0, 11, CLK_IS_CRITICAL); -static C3_SYS_GATE(sys_jtag_ctrl, SYS_CLK_EN0_REG0, 12, 0); -static C3_SYS_GATE(sys_ir_ctrl, SYS_CLK_EN0_REG0, 13, 0); +static C3_SYS_PCLK(sys_cpu_ctrl, SYS_CLK_EN0_REG0, 11, CLK_IS_CRITICAL); +static C3_SYS_PCLK(sys_jtag_ctrl, SYS_CLK_EN0_REG0, 12, 0); +static C3_SYS_PCLK(sys_ir_ctrl, SYS_CLK_EN0_REG0, 13, 0); /* * NOTE: sys_irq_ctrl provides the clock for IRQ controller. The IRQ controller @@ -221,18 +213,18 @@ static C3_SYS_GATE(sys_ir_ctrl, SYS_CLK_EN0_REG0, 13, 0); * AOCPU. If the clock is disabled, interrupt-related functions will occurs an * exception. */ -static C3_SYS_GATE(sys_irq_ctrl, SYS_CLK_EN0_REG0, 14, CLK_IS_CRITICAL); -static C3_SYS_GATE(sys_msr_clk, SYS_CLK_EN0_REG0, 15, 0); -static C3_SYS_GATE(sys_rom, SYS_CLK_EN0_REG0, 16, 0); -static C3_SYS_GATE(sys_uart_f, SYS_CLK_EN0_REG0, 17, 0); -static C3_SYS_GATE(sys_cpu_apb, SYS_CLK_EN0_REG0, 18, 0); -static C3_SYS_GATE(sys_rsa, SYS_CLK_EN0_REG0, 19, 0); -static C3_SYS_GATE(sys_sar_adc, SYS_CLK_EN0_REG0, 20, 0); -static C3_SYS_GATE(sys_startup, SYS_CLK_EN0_REG0, 21, 0); -static C3_SYS_GATE(sys_secure, SYS_CLK_EN0_REG0, 22, 0); -static C3_SYS_GATE(sys_spifc, SYS_CLK_EN0_REG0, 23, 0); -static C3_SYS_GATE(sys_nna, SYS_CLK_EN0_REG0, 25, 0); -static C3_SYS_GATE(sys_eth_mac, SYS_CLK_EN0_REG0, 26, 0); +static C3_SYS_PCLK(sys_irq_ctrl, SYS_CLK_EN0_REG0, 14, CLK_IS_CRITICAL); +static C3_SYS_PCLK(sys_msr_clk, SYS_CLK_EN0_REG0, 15, 0); +static C3_SYS_PCLK(sys_rom, SYS_CLK_EN0_REG0, 16, 0); +static C3_SYS_PCLK(sys_uart_f, SYS_CLK_EN0_REG0, 17, 0); +static C3_SYS_PCLK(sys_cpu_apb, SYS_CLK_EN0_REG0, 18, 0); +static C3_SYS_PCLK(sys_rsa, SYS_CLK_EN0_REG0, 19, 0); +static C3_SYS_PCLK(sys_sar_adc, SYS_CLK_EN0_REG0, 20, 0); +static C3_SYS_PCLK(sys_startup, SYS_CLK_EN0_REG0, 21, 0); +static C3_SYS_PCLK(sys_secure, SYS_CLK_EN0_REG0, 22, 0); +static C3_SYS_PCLK(sys_spifc, SYS_CLK_EN0_REG0, 23, 0); +static C3_SYS_PCLK(sys_nna, SYS_CLK_EN0_REG0, 25, 0); +static C3_SYS_PCLK(sys_eth_mac, SYS_CLK_EN0_REG0, 26, 0); /* * FIXME: sys_gic provides the clock for GIC(Generic Interrupt Controller). @@ -240,8 +232,8 @@ static C3_SYS_GATE(sys_eth_mac, SYS_CLK_EN0_REG0, 26, 0); * used by our GIC is the public driver in kernel, and there is no management * clock in the driver. */ -static C3_SYS_GATE(sys_gic, SYS_CLK_EN0_REG0, 27, CLK_IS_CRITICAL); -static C3_SYS_GATE(sys_rama, SYS_CLK_EN0_REG0, 28, 0); +static C3_SYS_PCLK(sys_gic, SYS_CLK_EN0_REG0, 27, CLK_IS_CRITICAL); +static C3_SYS_PCLK(sys_rama, SYS_CLK_EN0_REG0, 28, 0); /* * NOTE: sys_big_nic provides the clock to the control bus of the NIC(Network @@ -249,84 +241,85 @@ static C3_SYS_GATE(sys_rama, SYS_CLK_EN0_REG0, 28, 0); * SPIFC, CAPU, JTAG, EMMC, SDIO, sec_top, USB, Audio, ETH, SPICC) in the * system. After clock is disabled, The NIC cannot work. */ -static C3_SYS_GATE(sys_big_nic, SYS_CLK_EN0_REG0, 29, CLK_IS_CRITICAL); -static C3_SYS_GATE(sys_ramb, SYS_CLK_EN0_REG0, 30, 0); -static C3_SYS_GATE(sys_audio_pclk, SYS_CLK_EN0_REG0, 31, 0); -static C3_SYS_GATE(sys_pwm_kl, SYS_CLK_EN0_REG1, 0, 0); -static C3_SYS_GATE(sys_pwm_ij, SYS_CLK_EN0_REG1, 1, 0); -static C3_SYS_GATE(sys_usb, SYS_CLK_EN0_REG1, 2, 0); -static C3_SYS_GATE(sys_sd_emmc_a, SYS_CLK_EN0_REG1, 3, 0); -static C3_SYS_GATE(sys_sd_emmc_c, SYS_CLK_EN0_REG1, 4, 0); -static C3_SYS_GATE(sys_pwm_ab, SYS_CLK_EN0_REG1, 5, 0); -static C3_SYS_GATE(sys_pwm_cd, SYS_CLK_EN0_REG1, 6, 0); -static C3_SYS_GATE(sys_pwm_ef, SYS_CLK_EN0_REG1, 7, 0); -static C3_SYS_GATE(sys_pwm_gh, SYS_CLK_EN0_REG1, 8, 0); -static C3_SYS_GATE(sys_spicc_1, SYS_CLK_EN0_REG1, 9, 0); -static C3_SYS_GATE(sys_spicc_0, SYS_CLK_EN0_REG1, 10, 0); -static C3_SYS_GATE(sys_uart_a, SYS_CLK_EN0_REG1, 11, 0); -static C3_SYS_GATE(sys_uart_b, SYS_CLK_EN0_REG1, 12, 0); -static C3_SYS_GATE(sys_uart_c, SYS_CLK_EN0_REG1, 13, 0); -static C3_SYS_GATE(sys_uart_d, SYS_CLK_EN0_REG1, 14, 0); -static C3_SYS_GATE(sys_uart_e, SYS_CLK_EN0_REG1, 15, 0); -static C3_SYS_GATE(sys_i2c_m_a, SYS_CLK_EN0_REG1, 16, 0); -static C3_SYS_GATE(sys_i2c_m_b, SYS_CLK_EN0_REG1, 17, 0); -static C3_SYS_GATE(sys_i2c_m_c, SYS_CLK_EN0_REG1, 18, 0); -static C3_SYS_GATE(sys_i2c_m_d, SYS_CLK_EN0_REG1, 19, 0); -static C3_SYS_GATE(sys_i2c_s_a, SYS_CLK_EN0_REG1, 20, 0); -static C3_SYS_GATE(sys_rtc, SYS_CLK_EN0_REG1, 21, 0); -static C3_SYS_GATE(sys_ge2d, SYS_CLK_EN0_REG1, 22, 0); -static C3_SYS_GATE(sys_isp, SYS_CLK_EN0_REG1, 23, 0); -static C3_SYS_GATE(sys_gpv_isp_nic, SYS_CLK_EN0_REG1, 24, 0); -static C3_SYS_GATE(sys_gpv_cve_nic, SYS_CLK_EN0_REG1, 25, 0); -static C3_SYS_GATE(sys_mipi_dsi_host, SYS_CLK_EN0_REG1, 26, 0); -static C3_SYS_GATE(sys_mipi_dsi_phy, SYS_CLK_EN0_REG1, 27, 0); -static C3_SYS_GATE(sys_eth_phy, SYS_CLK_EN0_REG1, 28, 0); -static C3_SYS_GATE(sys_acodec, SYS_CLK_EN0_REG1, 29, 0); -static C3_SYS_GATE(sys_dwap, SYS_CLK_EN0_REG1, 30, 0); -static C3_SYS_GATE(sys_dos, SYS_CLK_EN0_REG1, 31, 0); -static C3_SYS_GATE(sys_cve, SYS_CLK_EN0_REG2, 0, 0); -static C3_SYS_GATE(sys_vout, SYS_CLK_EN0_REG2, 1, 0); -static C3_SYS_GATE(sys_vc9000e, SYS_CLK_EN0_REG2, 2, 0); -static C3_SYS_GATE(sys_pwm_mn, SYS_CLK_EN0_REG2, 3, 0); -static C3_SYS_GATE(sys_sd_emmc_b, SYS_CLK_EN0_REG2, 4, 0); - -#define C3_AXI_GATE(_name, _reg, _bit, _flags) \ - C3_CLK_GATE(_name, _reg, _bit, axiclk, \ - &clk_regmap_gate_ops, _flags) +static C3_SYS_PCLK(sys_big_nic, SYS_CLK_EN0_REG0, 29, CLK_IS_CRITICAL); +static C3_SYS_PCLK(sys_ramb, SYS_CLK_EN0_REG0, 30, 0); +static C3_SYS_PCLK(sys_audio_pclk, SYS_CLK_EN0_REG0, 31, 0); +static C3_SYS_PCLK(sys_pwm_kl, SYS_CLK_EN0_REG1, 0, 0); +static C3_SYS_PCLK(sys_pwm_ij, SYS_CLK_EN0_REG1, 1, 0); +static C3_SYS_PCLK(sys_usb, SYS_CLK_EN0_REG1, 2, 0); +static C3_SYS_PCLK(sys_sd_emmc_a, SYS_CLK_EN0_REG1, 3, 0); +static C3_SYS_PCLK(sys_sd_emmc_c, SYS_CLK_EN0_REG1, 4, 0); +static C3_SYS_PCLK(sys_pwm_ab, SYS_CLK_EN0_REG1, 5, 0); +static C3_SYS_PCLK(sys_pwm_cd, SYS_CLK_EN0_REG1, 6, 0); +static C3_SYS_PCLK(sys_pwm_ef, SYS_CLK_EN0_REG1, 7, 0); +static C3_SYS_PCLK(sys_pwm_gh, SYS_CLK_EN0_REG1, 8, 0); +static C3_SYS_PCLK(sys_spicc_1, SYS_CLK_EN0_REG1, 9, 0); +static C3_SYS_PCLK(sys_spicc_0, SYS_CLK_EN0_REG1, 10, 0); +static C3_SYS_PCLK(sys_uart_a, SYS_CLK_EN0_REG1, 11, 0); +static C3_SYS_PCLK(sys_uart_b, SYS_CLK_EN0_REG1, 12, 0); +static C3_SYS_PCLK(sys_uart_c, SYS_CLK_EN0_REG1, 13, 0); +static C3_SYS_PCLK(sys_uart_d, SYS_CLK_EN0_REG1, 14, 0); +static C3_SYS_PCLK(sys_uart_e, SYS_CLK_EN0_REG1, 15, 0); +static C3_SYS_PCLK(sys_i2c_m_a, SYS_CLK_EN0_REG1, 16, 0); +static C3_SYS_PCLK(sys_i2c_m_b, SYS_CLK_EN0_REG1, 17, 0); +static C3_SYS_PCLK(sys_i2c_m_c, SYS_CLK_EN0_REG1, 18, 0); +static C3_SYS_PCLK(sys_i2c_m_d, SYS_CLK_EN0_REG1, 19, 0); +static C3_SYS_PCLK(sys_i2c_s_a, SYS_CLK_EN0_REG1, 20, 0); +static C3_SYS_PCLK(sys_rtc, SYS_CLK_EN0_REG1, 21, 0); +static C3_SYS_PCLK(sys_ge2d, SYS_CLK_EN0_REG1, 22, 0); +static C3_SYS_PCLK(sys_isp, SYS_CLK_EN0_REG1, 23, 0); +static C3_SYS_PCLK(sys_gpv_isp_nic, SYS_CLK_EN0_REG1, 24, 0); +static C3_SYS_PCLK(sys_gpv_cve_nic, SYS_CLK_EN0_REG1, 25, 0); +static C3_SYS_PCLK(sys_mipi_dsi_host, SYS_CLK_EN0_REG1, 26, 0); +static C3_SYS_PCLK(sys_mipi_dsi_phy, SYS_CLK_EN0_REG1, 27, 0); +static C3_SYS_PCLK(sys_eth_phy, SYS_CLK_EN0_REG1, 28, 0); +static C3_SYS_PCLK(sys_acodec, SYS_CLK_EN0_REG1, 29, 0); +static C3_SYS_PCLK(sys_dwap, SYS_CLK_EN0_REG1, 30, 0); +static C3_SYS_PCLK(sys_dos, SYS_CLK_EN0_REG1, 31, 0); +static C3_SYS_PCLK(sys_cve, SYS_CLK_EN0_REG2, 0, 0); +static C3_SYS_PCLK(sys_vout, SYS_CLK_EN0_REG2, 1, 0); +static C3_SYS_PCLK(sys_vc9000e, SYS_CLK_EN0_REG2, 2, 0); +static C3_SYS_PCLK(sys_pwm_mn, SYS_CLK_EN0_REG2, 3, 0); +static C3_SYS_PCLK(sys_sd_emmc_b, SYS_CLK_EN0_REG2, 4, 0); + +static const struct clk_parent_data c3_axi_pclk_parents = { .fw_name = "axiclk" }; + +#define C3_AXI_PCLK(_name, _reg, _bit, _flags) \ + MESON_PCLK(c3_##_name, _reg, _bit, &c3_axi_pclk_parents, _flags) /* * NOTE: axi_sys_nic provides the clock to the AXI bus of the system NIC. After * clock is disabled, The NIC cannot work. */ -static C3_AXI_GATE(axi_sys_nic, AXI_CLK_EN0, 2, CLK_IS_CRITICAL); -static C3_AXI_GATE(axi_isp_nic, AXI_CLK_EN0, 3, 0); -static C3_AXI_GATE(axi_cve_nic, AXI_CLK_EN0, 4, 0); -static C3_AXI_GATE(axi_ramb, AXI_CLK_EN0, 5, 0); -static C3_AXI_GATE(axi_rama, AXI_CLK_EN0, 6, 0); +static C3_AXI_PCLK(axi_sys_nic, AXI_CLK_EN0, 2, CLK_IS_CRITICAL); +static C3_AXI_PCLK(axi_isp_nic, AXI_CLK_EN0, 3, 0); +static C3_AXI_PCLK(axi_cve_nic, AXI_CLK_EN0, 4, 0); +static C3_AXI_PCLK(axi_ramb, AXI_CLK_EN0, 5, 0); +static C3_AXI_PCLK(axi_rama, AXI_CLK_EN0, 6, 0); /* * NOTE: axi_cpu_dmc provides the clock to the AXI bus where the CPU accesses * the DDR. After clock is disabled, The CPU will not have access to the DDR. */ -static C3_AXI_GATE(axi_cpu_dmc, AXI_CLK_EN0, 7, CLK_IS_CRITICAL); -static C3_AXI_GATE(axi_nic, AXI_CLK_EN0, 8, 0); -static C3_AXI_GATE(axi_dma, AXI_CLK_EN0, 9, 0); +static C3_AXI_PCLK(axi_cpu_dmc, AXI_CLK_EN0, 7, CLK_IS_CRITICAL); +static C3_AXI_PCLK(axi_nic, AXI_CLK_EN0, 8, 0); +static C3_AXI_PCLK(axi_dma, AXI_CLK_EN0, 9, 0); /* * NOTE: axi_mux_nic provides the clock to the NIC's AXI bus for NN(Neural * Network) and other devices(CPU, EMMC, SDIO, sec_top, USB, Audio, ETH, SPICC) * to access RAM space. */ -static C3_AXI_GATE(axi_mux_nic, AXI_CLK_EN0, 10, 0); -static C3_AXI_GATE(axi_cve, AXI_CLK_EN0, 12, 0); +static C3_AXI_PCLK(axi_mux_nic, AXI_CLK_EN0, 10, 0); +static C3_AXI_PCLK(axi_cve, AXI_CLK_EN0, 12, 0); /* * NOTE: axi_dev1_dmc provides the clock for the peripherals(EMMC, SDIO, * sec_top, USB, Audio, ETH, SPICC) to access the AXI bus of the DDR. */ -static C3_AXI_GATE(axi_dev1_dmc, AXI_CLK_EN0, 13, 0); -static C3_AXI_GATE(axi_dev0_dmc, AXI_CLK_EN0, 14, 0); -static C3_AXI_GATE(axi_dsp_dmc, AXI_CLK_EN0, 15, 0); +static C3_AXI_PCLK(axi_dev1_dmc, AXI_CLK_EN0, 13, 0); +static C3_AXI_PCLK(axi_dev0_dmc, AXI_CLK_EN0, 14, 0); +static C3_AXI_PCLK(axi_dsp_dmc, AXI_CLK_EN0, 15, 0); /* * clk_12_24m model @@ -335,7 +328,7 @@ static C3_AXI_GATE(axi_dsp_dmc, AXI_CLK_EN0, 15, 0); * xtal---->| gate |---->| div |------------>| pad | * |------| |-----| |-----| */ -static struct clk_regmap clk_12_24m_in = { +static struct clk_regmap c3_clk_12_24m_in = { .data = &(struct clk_regmap_gate_data) { .offset = CLK12_24_CTRL, .bit_idx = 11, @@ -350,7 +343,7 @@ static struct clk_regmap clk_12_24m_in = { }, }; -static struct clk_regmap clk_12_24m = { +static struct clk_regmap c3_clk_12_24m = { .data = &(struct clk_regmap_div_data) { .offset = CLK12_24_CTRL, .shift = 10, @@ -360,14 +353,14 @@ static struct clk_regmap clk_12_24m = { .name = "clk_12_24m", .ops = &clk_regmap_divider_ops, .parent_hws = (const struct clk_hw *[]) { - &clk_12_24m_in.hw + &c3_clk_12_24m_in.hw }, .num_parents = 1, }, }; /* Fix me: set value 0 will div by 2 like value 1 */ -static struct clk_regmap fclk_25m_div = { +static struct clk_regmap c3_fclk_25m_div = { .data = &(struct clk_regmap_div_data) { .offset = CLK12_24_CTRL, .shift = 0, @@ -383,7 +376,7 @@ static struct clk_regmap fclk_25m_div = { }, }; -static struct clk_regmap fclk_25m = { +static struct clk_regmap c3_fclk_25m = { .data = &(struct clk_regmap_gate_data) { .offset = CLK12_24_CTRL, .bit_idx = 12, @@ -392,7 +385,7 @@ static struct clk_regmap fclk_25m = { .name = "fclk_25m", .ops = &clk_regmap_gate_ops, .parent_hws = (const struct clk_hw *[]) { - &fclk_25m_div.hw + &c3_fclk_25m_div.hw }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, @@ -404,11 +397,10 @@ static struct clk_regmap fclk_25m = { * is manged by clock measures module. Their hardware are out of clock tree. * Channel 4 8 9 10 11 13 14 15 16 18 are not connected. */ -static u32 gen_parent_table[] = { 0, 1, 2, 5, 6, 7, 17, 19, 20, 21, 22, 23, 24}; - -static const struct clk_parent_data gen_parent_data[] = { +static u32 c3_gen_parents_val_table[] = { 0, 1, 2, 5, 6, 7, 17, 19, 20, 21, 22, 23, 24}; +static const struct clk_parent_data c3_gen_parents[] = { { .fw_name = "oscin" }, - { .hw = &rtc_clk.hw }, + { .hw = &c3_rtc_clk.hw }, { .fw_name = "sysplldiv16" }, { .fw_name = "gp0" }, { .fw_name = "gp1" }, @@ -422,22 +414,22 @@ static const struct clk_parent_data gen_parent_data[] = { { .fw_name = "fdiv7" } }; -static struct clk_regmap gen_sel = { +static struct clk_regmap c3_gen_sel = { .data = &(struct clk_regmap_mux_data) { .offset = GEN_CLK_CTRL, .mask = 0x1f, .shift = 12, - .table = gen_parent_table, + .table = c3_gen_parents_val_table, }, .hw.init = &(struct clk_init_data) { .name = "gen_sel", .ops = &clk_regmap_mux_ops, - .parent_data = gen_parent_data, - .num_parents = ARRAY_SIZE(gen_parent_data), + .parent_data = c3_gen_parents, + .num_parents = ARRAY_SIZE(c3_gen_parents), }, }; -static struct clk_regmap gen_div = { +static struct clk_regmap c3_gen_div = { .data = &(struct clk_regmap_div_data) { .offset = GEN_CLK_CTRL, .shift = 0, @@ -447,14 +439,14 @@ static struct clk_regmap gen_div = { .name = "gen_div", .ops = &clk_regmap_divider_ops, .parent_hws = (const struct clk_hw *[]) { - &gen_sel.hw + &c3_gen_sel.hw }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, }; -static struct clk_regmap gen = { +static struct clk_regmap c3_gen = { .data = &(struct clk_regmap_gate_data) { .offset = GEN_CLK_CTRL, .bit_idx = 11, @@ -463,214 +455,86 @@ static struct clk_regmap gen = { .name = "gen", .ops = &clk_regmap_gate_ops, .parent_hws = (const struct clk_hw *[]) { - &gen_div.hw + &c3_gen_div.hw }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, }; -static const struct clk_parent_data saradc_parent_data[] = { +static const struct clk_parent_data c3_saradc_parents[] = { { .fw_name = "oscin" }, { .fw_name = "sysclk" } }; -static struct clk_regmap saradc_sel = { - .data = &(struct clk_regmap_mux_data) { - .offset = SAR_CLK_CTRL0, - .mask = 0x1, - .shift = 9, - }, - .hw.init = &(struct clk_init_data) { - .name = "saradc_sel", - .ops = &clk_regmap_mux_ops, - .parent_data = saradc_parent_data, - .num_parents = ARRAY_SIZE(saradc_parent_data), - }, -}; - -static struct clk_regmap saradc_div = { - .data = &(struct clk_regmap_div_data) { - .offset = SAR_CLK_CTRL0, - .shift = 0, - .width = 8, - }, - .hw.init = &(struct clk_init_data) { - .name = "saradc_div", - .ops = &clk_regmap_divider_ops, - .parent_hws = (const struct clk_hw *[]) { - &saradc_sel.hw - }, - .num_parents = 1, - .flags = CLK_SET_RATE_PARENT, - }, -}; - -static struct clk_regmap saradc = { - .data = &(struct clk_regmap_gate_data) { - .offset = SAR_CLK_CTRL0, - .bit_idx = 8, - }, - .hw.init = &(struct clk_init_data) { - .name = "saradc", - .ops = &clk_regmap_gate_ops, - .parent_hws = (const struct clk_hw *[]) { - &saradc_div.hw - }, - .num_parents = 1, - .flags = CLK_SET_RATE_PARENT, - }, -}; +static C3_COMP_SEL(saradc, SAR_CLK_CTRL0, 9, 0x1, c3_saradc_parents); +static C3_COMP_DIV(saradc, SAR_CLK_CTRL0, 0, 8); +static C3_COMP_GATE(saradc, SAR_CLK_CTRL0, 8); -static const struct clk_parent_data pwm_parent_data[] = { +static const struct clk_parent_data c3_pwm_parents[] = { { .fw_name = "oscin" }, { .fw_name = "gp1" }, { .fw_name = "fdiv4" }, { .fw_name = "fdiv3" } }; -#define AML_PWM_CLK_MUX(_name, _reg, _shift) { \ - .data = &(struct clk_regmap_mux_data) { \ - .offset = _reg, \ - .mask = 0x3, \ - .shift = _shift, \ - }, \ - .hw.init = &(struct clk_init_data) { \ - .name = #_name "_sel", \ - .ops = &clk_regmap_mux_ops, \ - .parent_data = pwm_parent_data, \ - .num_parents = ARRAY_SIZE(pwm_parent_data), \ - }, \ -} - -#define AML_PWM_CLK_DIV(_name, _reg, _shift) { \ - .data = &(struct clk_regmap_div_data) { \ - .offset = _reg, \ - .shift = _shift, \ - .width = 8, \ - }, \ - .hw.init = &(struct clk_init_data) { \ - .name = #_name "_div", \ - .ops = &clk_regmap_divider_ops, \ - .parent_names = (const char *[]) { #_name "_sel" },\ - .num_parents = 1, \ - .flags = CLK_SET_RATE_PARENT, \ - }, \ -} - -#define AML_PWM_CLK_GATE(_name, _reg, _bit) { \ - .data = &(struct clk_regmap_gate_data) { \ - .offset = _reg, \ - .bit_idx = _bit, \ - }, \ - .hw.init = &(struct clk_init_data) { \ - .name = #_name, \ - .ops = &clk_regmap_gate_ops, \ - .parent_names = (const char *[]) { #_name "_div" },\ - .num_parents = 1, \ - .flags = CLK_SET_RATE_PARENT, \ - }, \ -} - -static struct clk_regmap pwm_a_sel = - AML_PWM_CLK_MUX(pwm_a, PWM_CLK_AB_CTRL, 9); -static struct clk_regmap pwm_a_div = - AML_PWM_CLK_DIV(pwm_a, PWM_CLK_AB_CTRL, 0); -static struct clk_regmap pwm_a = - AML_PWM_CLK_GATE(pwm_a, PWM_CLK_AB_CTRL, 8); - -static struct clk_regmap pwm_b_sel = - AML_PWM_CLK_MUX(pwm_b, PWM_CLK_AB_CTRL, 25); -static struct clk_regmap pwm_b_div = - AML_PWM_CLK_DIV(pwm_b, PWM_CLK_AB_CTRL, 16); -static struct clk_regmap pwm_b = - AML_PWM_CLK_GATE(pwm_b, PWM_CLK_AB_CTRL, 24); - -static struct clk_regmap pwm_c_sel = - AML_PWM_CLK_MUX(pwm_c, PWM_CLK_CD_CTRL, 9); -static struct clk_regmap pwm_c_div = - AML_PWM_CLK_DIV(pwm_c, PWM_CLK_CD_CTRL, 0); -static struct clk_regmap pwm_c = - AML_PWM_CLK_GATE(pwm_c, PWM_CLK_CD_CTRL, 8); - -static struct clk_regmap pwm_d_sel = - AML_PWM_CLK_MUX(pwm_d, PWM_CLK_CD_CTRL, 25); -static struct clk_regmap pwm_d_div = - AML_PWM_CLK_DIV(pwm_d, PWM_CLK_CD_CTRL, 16); -static struct clk_regmap pwm_d = - AML_PWM_CLK_GATE(pwm_d, PWM_CLK_CD_CTRL, 24); - -static struct clk_regmap pwm_e_sel = - AML_PWM_CLK_MUX(pwm_e, PWM_CLK_EF_CTRL, 9); -static struct clk_regmap pwm_e_div = - AML_PWM_CLK_DIV(pwm_e, PWM_CLK_EF_CTRL, 0); -static struct clk_regmap pwm_e = - AML_PWM_CLK_GATE(pwm_e, PWM_CLK_EF_CTRL, 8); - -static struct clk_regmap pwm_f_sel = - AML_PWM_CLK_MUX(pwm_f, PWM_CLK_EF_CTRL, 25); -static struct clk_regmap pwm_f_div = - AML_PWM_CLK_DIV(pwm_f, PWM_CLK_EF_CTRL, 16); -static struct clk_regmap pwm_f = - AML_PWM_CLK_GATE(pwm_f, PWM_CLK_EF_CTRL, 24); - -static struct clk_regmap pwm_g_sel = - AML_PWM_CLK_MUX(pwm_g, PWM_CLK_GH_CTRL, 9); -static struct clk_regmap pwm_g_div = - AML_PWM_CLK_DIV(pwm_g, PWM_CLK_GH_CTRL, 0); -static struct clk_regmap pwm_g = - AML_PWM_CLK_GATE(pwm_g, PWM_CLK_GH_CTRL, 8); - -static struct clk_regmap pwm_h_sel = - AML_PWM_CLK_MUX(pwm_h, PWM_CLK_GH_CTRL, 25); -static struct clk_regmap pwm_h_div = - AML_PWM_CLK_DIV(pwm_h, PWM_CLK_GH_CTRL, 16); -static struct clk_regmap pwm_h = - AML_PWM_CLK_GATE(pwm_h, PWM_CLK_GH_CTRL, 24); - -static struct clk_regmap pwm_i_sel = - AML_PWM_CLK_MUX(pwm_i, PWM_CLK_IJ_CTRL, 9); -static struct clk_regmap pwm_i_div = - AML_PWM_CLK_DIV(pwm_i, PWM_CLK_IJ_CTRL, 0); -static struct clk_regmap pwm_i = - AML_PWM_CLK_GATE(pwm_i, PWM_CLK_IJ_CTRL, 8); - -static struct clk_regmap pwm_j_sel = - AML_PWM_CLK_MUX(pwm_j, PWM_CLK_IJ_CTRL, 25); -static struct clk_regmap pwm_j_div = - AML_PWM_CLK_DIV(pwm_j, PWM_CLK_IJ_CTRL, 16); -static struct clk_regmap pwm_j = - AML_PWM_CLK_GATE(pwm_j, PWM_CLK_IJ_CTRL, 24); - -static struct clk_regmap pwm_k_sel = - AML_PWM_CLK_MUX(pwm_k, PWM_CLK_KL_CTRL, 9); -static struct clk_regmap pwm_k_div = - AML_PWM_CLK_DIV(pwm_k, PWM_CLK_KL_CTRL, 0); -static struct clk_regmap pwm_k = - AML_PWM_CLK_GATE(pwm_k, PWM_CLK_KL_CTRL, 8); - -static struct clk_regmap pwm_l_sel = - AML_PWM_CLK_MUX(pwm_l, PWM_CLK_KL_CTRL, 25); -static struct clk_regmap pwm_l_div = - AML_PWM_CLK_DIV(pwm_l, PWM_CLK_KL_CTRL, 16); -static struct clk_regmap pwm_l = - AML_PWM_CLK_GATE(pwm_l, PWM_CLK_KL_CTRL, 24); - -static struct clk_regmap pwm_m_sel = - AML_PWM_CLK_MUX(pwm_m, PWM_CLK_MN_CTRL, 9); -static struct clk_regmap pwm_m_div = - AML_PWM_CLK_DIV(pwm_m, PWM_CLK_MN_CTRL, 0); -static struct clk_regmap pwm_m = - AML_PWM_CLK_GATE(pwm_m, PWM_CLK_MN_CTRL, 8); - -static struct clk_regmap pwm_n_sel = - AML_PWM_CLK_MUX(pwm_n, PWM_CLK_MN_CTRL, 25); -static struct clk_regmap pwm_n_div = - AML_PWM_CLK_DIV(pwm_n, PWM_CLK_MN_CTRL, 16); -static struct clk_regmap pwm_n = - AML_PWM_CLK_GATE(pwm_n, PWM_CLK_MN_CTRL, 24); - -static const struct clk_parent_data spicc_parent_data[] = { +static C3_COMP_SEL(pwm_a, PWM_CLK_AB_CTRL, 9, 0x3, c3_pwm_parents); +static C3_COMP_DIV(pwm_a, PWM_CLK_AB_CTRL, 0, 8); +static C3_COMP_GATE(pwm_a, PWM_CLK_AB_CTRL, 8); + +static C3_COMP_SEL(pwm_b, PWM_CLK_AB_CTRL, 25, 0x3, c3_pwm_parents); +static C3_COMP_DIV(pwm_b, PWM_CLK_AB_CTRL, 16, 8); +static C3_COMP_GATE(pwm_b, PWM_CLK_AB_CTRL, 24); + +static C3_COMP_SEL(pwm_c, PWM_CLK_CD_CTRL, 9, 0x3, c3_pwm_parents); +static C3_COMP_DIV(pwm_c, PWM_CLK_CD_CTRL, 0, 8); +static C3_COMP_GATE(pwm_c, PWM_CLK_CD_CTRL, 8); + +static C3_COMP_SEL(pwm_d, PWM_CLK_CD_CTRL, 25, 0x3, c3_pwm_parents); +static C3_COMP_DIV(pwm_d, PWM_CLK_CD_CTRL, 16, 8); +static C3_COMP_GATE(pwm_d, PWM_CLK_CD_CTRL, 24); + +static C3_COMP_SEL(pwm_e, PWM_CLK_EF_CTRL, 9, 0x3, c3_pwm_parents); +static C3_COMP_DIV(pwm_e, PWM_CLK_EF_CTRL, 0, 8); +static C3_COMP_GATE(pwm_e, PWM_CLK_EF_CTRL, 8); + +static C3_COMP_SEL(pwm_f, PWM_CLK_EF_CTRL, 25, 0x3, c3_pwm_parents); +static C3_COMP_DIV(pwm_f, PWM_CLK_EF_CTRL, 16, 8); +static C3_COMP_GATE(pwm_f, PWM_CLK_EF_CTRL, 24); + +static C3_COMP_SEL(pwm_g, PWM_CLK_GH_CTRL, 9, 0x3, c3_pwm_parents); +static C3_COMP_DIV(pwm_g, PWM_CLK_GH_CTRL, 0, 8); +static C3_COMP_GATE(pwm_g, PWM_CLK_GH_CTRL, 8); + +static C3_COMP_SEL(pwm_h, PWM_CLK_GH_CTRL, 25, 0x3, c3_pwm_parents); +static C3_COMP_DIV(pwm_h, PWM_CLK_GH_CTRL, 16, 8); +static C3_COMP_GATE(pwm_h, PWM_CLK_GH_CTRL, 24); + +static C3_COMP_SEL(pwm_i, PWM_CLK_IJ_CTRL, 9, 0x3, c3_pwm_parents); +static C3_COMP_DIV(pwm_i, PWM_CLK_IJ_CTRL, 0, 8); +static C3_COMP_GATE(pwm_i, PWM_CLK_IJ_CTRL, 8); + +static C3_COMP_SEL(pwm_j, PWM_CLK_IJ_CTRL, 25, 0x3, c3_pwm_parents); +static C3_COMP_DIV(pwm_j, PWM_CLK_IJ_CTRL, 16, 8); +static C3_COMP_GATE(pwm_j, PWM_CLK_IJ_CTRL, 24); + +static C3_COMP_SEL(pwm_k, PWM_CLK_KL_CTRL, 9, 0x3, c3_pwm_parents); +static C3_COMP_DIV(pwm_k, PWM_CLK_KL_CTRL, 0, 8); +static C3_COMP_GATE(pwm_k, PWM_CLK_KL_CTRL, 8); + +static C3_COMP_SEL(pwm_l, PWM_CLK_KL_CTRL, 25, 0x3, c3_pwm_parents); +static C3_COMP_DIV(pwm_l, PWM_CLK_KL_CTRL, 16, 8); +static C3_COMP_GATE(pwm_l, PWM_CLK_KL_CTRL, 24); + +static C3_COMP_SEL(pwm_m, PWM_CLK_MN_CTRL, 9, 0x3, c3_pwm_parents); +static C3_COMP_DIV(pwm_m, PWM_CLK_MN_CTRL, 0, 8); +static C3_COMP_GATE(pwm_m, PWM_CLK_MN_CTRL, 8); + +static C3_COMP_SEL(pwm_n, PWM_CLK_MN_CTRL, 25, 0x3, c3_pwm_parents); +static C3_COMP_DIV(pwm_n, PWM_CLK_MN_CTRL, 16, 8); +static C3_COMP_GATE(pwm_n, PWM_CLK_MN_CTRL, 24); + +static const struct clk_parent_data c3_spicc_parents[] = { { .fw_name = "oscin" }, { .fw_name = "sysclk" }, { .fw_name = "fdiv4" }, @@ -681,101 +545,15 @@ static const struct clk_parent_data spicc_parent_data[] = { { .fw_name = "gp1" } }; -static struct clk_regmap spicc_a_sel = { - .data = &(struct clk_regmap_mux_data) { - .offset = SPICC_CLK_CTRL, - .mask = 0x7, - .shift = 7, - }, - .hw.init = &(struct clk_init_data) { - .name = "spicc_a_sel", - .ops = &clk_regmap_mux_ops, - .parent_data = spicc_parent_data, - .num_parents = ARRAY_SIZE(spicc_parent_data), - }, -}; - -static struct clk_regmap spicc_a_div = { - .data = &(struct clk_regmap_div_data) { - .offset = SPICC_CLK_CTRL, - .shift = 0, - .width = 6, - }, - .hw.init = &(struct clk_init_data) { - .name = "spicc_a_div", - .ops = &clk_regmap_divider_ops, - .parent_hws = (const struct clk_hw *[]) { - &spicc_a_sel.hw - }, - .num_parents = 1, - .flags = CLK_SET_RATE_PARENT, - }, -}; +static C3_COMP_SEL(spicc_a, SPICC_CLK_CTRL, 7, 0x7, c3_spicc_parents); +static C3_COMP_DIV(spicc_a, SPICC_CLK_CTRL, 0, 6); +static C3_COMP_GATE(spicc_a, SPICC_CLK_CTRL, 6); -static struct clk_regmap spicc_a = { - .data = &(struct clk_regmap_gate_data) { - .offset = SPICC_CLK_CTRL, - .bit_idx = 6, - }, - .hw.init = &(struct clk_init_data) { - .name = "spicc_a", - .ops = &clk_regmap_gate_ops, - .parent_hws = (const struct clk_hw *[]) { - &spicc_a_div.hw - }, - .num_parents = 1, - .flags = CLK_SET_RATE_PARENT, - }, -}; +static C3_COMP_SEL(spicc_b, SPICC_CLK_CTRL, 23, 0x7, c3_spicc_parents); +static C3_COMP_DIV(spicc_b, SPICC_CLK_CTRL, 16, 6); +static C3_COMP_GATE(spicc_b, SPICC_CLK_CTRL, 22); -static struct clk_regmap spicc_b_sel = { - .data = &(struct clk_regmap_mux_data) { - .offset = SPICC_CLK_CTRL, - .mask = 0x7, - .shift = 23, - }, - .hw.init = &(struct clk_init_data) { - .name = "spicc_b_sel", - .ops = &clk_regmap_mux_ops, - .parent_data = spicc_parent_data, - .num_parents = ARRAY_SIZE(spicc_parent_data), - }, -}; - -static struct clk_regmap spicc_b_div = { - .data = &(struct clk_regmap_div_data) { - .offset = SPICC_CLK_CTRL, - .shift = 16, - .width = 6, - }, - .hw.init = &(struct clk_init_data) { - .name = "spicc_b_div", - .ops = &clk_regmap_divider_ops, - .parent_hws = (const struct clk_hw *[]) { - &spicc_b_sel.hw - }, - .num_parents = 1, - .flags = CLK_SET_RATE_PARENT, - }, -}; - -static struct clk_regmap spicc_b = { - .data = &(struct clk_regmap_gate_data) { - .offset = SPICC_CLK_CTRL, - .bit_idx = 22, - }, - .hw.init = &(struct clk_init_data) { - .name = "spicc_b", - .ops = &clk_regmap_gate_ops, - .parent_hws = (const struct clk_hw *[]) { - &spicc_b_div.hw - }, - .num_parents = 1, - .flags = CLK_SET_RATE_PARENT, - }, -}; - -static const struct clk_parent_data spifc_parent_data[] = { +static const struct clk_parent_data c3_spifc_parents[] = { { .fw_name = "gp0" }, { .fw_name = "fdiv2" }, { .fw_name = "fdiv3" }, @@ -786,54 +564,11 @@ static const struct clk_parent_data spifc_parent_data[] = { { .fw_name = "fdiv7" } }; -static struct clk_regmap spifc_sel = { - .data = &(struct clk_regmap_mux_data) { - .offset = SPIFC_CLK_CTRL, - .mask = 0x7, - .shift = 9, - }, - .hw.init = &(struct clk_init_data) { - .name = "spifc_sel", - .ops = &clk_regmap_mux_ops, - .parent_data = spifc_parent_data, - .num_parents = ARRAY_SIZE(spifc_parent_data), - }, -}; +static C3_COMP_SEL(spifc, SPIFC_CLK_CTRL, 9, 0x7, c3_spifc_parents); +static C3_COMP_DIV(spifc, SPIFC_CLK_CTRL, 0, 7); +static C3_COMP_GATE(spifc, SPIFC_CLK_CTRL, 8); -static struct clk_regmap spifc_div = { - .data = &(struct clk_regmap_div_data) { - .offset = SPIFC_CLK_CTRL, - .shift = 0, - .width = 7, - }, - .hw.init = &(struct clk_init_data) { - .name = "spifc_div", - .ops = &clk_regmap_divider_ops, - .parent_hws = (const struct clk_hw *[]) { - &spifc_sel.hw - }, - .num_parents = 1, - .flags = CLK_SET_RATE_PARENT, - }, -}; - -static struct clk_regmap spifc = { - .data = &(struct clk_regmap_gate_data) { - .offset = SPIFC_CLK_CTRL, - .bit_idx = 8, - }, - .hw.init = &(struct clk_init_data) { - .name = "spifc", - .ops = &clk_regmap_gate_ops, - .parent_hws = (const struct clk_hw *[]) { - &spifc_div.hw - }, - .num_parents = 1, - .flags = CLK_SET_RATE_PARENT, - }, -}; - -static const struct clk_parent_data emmc_parent_data[] = { +static const struct clk_parent_data c3_sd_emmc_parents[] = { { .fw_name = "oscin" }, { .fw_name = "fdiv2" }, { .fw_name = "fdiv3" }, @@ -844,148 +579,19 @@ static const struct clk_parent_data emmc_parent_data[] = { { .fw_name = "gp0" } }; -static struct clk_regmap sd_emmc_a_sel = { - .data = &(struct clk_regmap_mux_data) { - .offset = SD_EMMC_CLK_CTRL, - .mask = 0x7, - .shift = 9, - }, - .hw.init = &(struct clk_init_data) { - .name = "sd_emmc_a_sel", - .ops = &clk_regmap_mux_ops, - .parent_data = emmc_parent_data, - .num_parents = ARRAY_SIZE(emmc_parent_data), - }, -}; - -static struct clk_regmap sd_emmc_a_div = { - .data = &(struct clk_regmap_div_data) { - .offset = SD_EMMC_CLK_CTRL, - .shift = 0, - .width = 7, - }, - .hw.init = &(struct clk_init_data) { - .name = "sd_emmc_a_div", - .ops = &clk_regmap_divider_ops, - .parent_hws = (const struct clk_hw *[]) { - &sd_emmc_a_sel.hw - }, - .num_parents = 1, - .flags = CLK_SET_RATE_PARENT, - }, -}; - -static struct clk_regmap sd_emmc_a = { - .data = &(struct clk_regmap_gate_data) { - .offset = SD_EMMC_CLK_CTRL, - .bit_idx = 7, - }, - .hw.init = &(struct clk_init_data) { - .name = "sd_emmc_a", - .ops = &clk_regmap_gate_ops, - .parent_hws = (const struct clk_hw *[]) { - &sd_emmc_a_div.hw - }, - .num_parents = 1, - .flags = CLK_SET_RATE_PARENT, - }, -}; - -static struct clk_regmap sd_emmc_b_sel = { - .data = &(struct clk_regmap_mux_data) { - .offset = SD_EMMC_CLK_CTRL, - .mask = 0x7, - .shift = 25, - }, - .hw.init = &(struct clk_init_data) { - .name = "sd_emmc_b_sel", - .ops = &clk_regmap_mux_ops, - .parent_data = emmc_parent_data, - .num_parents = ARRAY_SIZE(emmc_parent_data), - }, -}; - -static struct clk_regmap sd_emmc_b_div = { - .data = &(struct clk_regmap_div_data) { - .offset = SD_EMMC_CLK_CTRL, - .shift = 16, - .width = 7, - }, - .hw.init = &(struct clk_init_data) { - .name = "sd_emmc_b_div", - .ops = &clk_regmap_divider_ops, - .parent_hws = (const struct clk_hw *[]) { - &sd_emmc_b_sel.hw - }, - .num_parents = 1, - .flags = CLK_SET_RATE_PARENT, - }, -}; - -static struct clk_regmap sd_emmc_b = { - .data = &(struct clk_regmap_gate_data) { - .offset = SD_EMMC_CLK_CTRL, - .bit_idx = 23, - }, - .hw.init = &(struct clk_init_data) { - .name = "sd_emmc_b", - .ops = &clk_regmap_gate_ops, - .parent_hws = (const struct clk_hw *[]) { - &sd_emmc_b_div.hw - }, - .num_parents = 1, - .flags = CLK_SET_RATE_PARENT, - }, -}; - -static struct clk_regmap sd_emmc_c_sel = { - .data = &(struct clk_regmap_mux_data) { - .offset = NAND_CLK_CTRL, - .mask = 0x7, - .shift = 9, - }, - .hw.init = &(struct clk_init_data) { - .name = "sd_emmc_c_sel", - .ops = &clk_regmap_mux_ops, - .parent_data = emmc_parent_data, - .num_parents = ARRAY_SIZE(emmc_parent_data), - }, -}; +static C3_COMP_SEL(sd_emmc_a, SD_EMMC_CLK_CTRL, 9, 0x7, c3_sd_emmc_parents); +static C3_COMP_DIV(sd_emmc_a, SD_EMMC_CLK_CTRL, 0, 7); +static C3_COMP_GATE(sd_emmc_a, SD_EMMC_CLK_CTRL, 7); -static struct clk_regmap sd_emmc_c_div = { - .data = &(struct clk_regmap_div_data) { - .offset = NAND_CLK_CTRL, - .shift = 0, - .width = 7, - }, - .hw.init = &(struct clk_init_data) { - .name = "sd_emmc_c_div", - .ops = &clk_regmap_divider_ops, - .parent_hws = (const struct clk_hw *[]) { - &sd_emmc_c_sel.hw - }, - .num_parents = 1, - .flags = CLK_SET_RATE_PARENT, - }, -}; +static C3_COMP_SEL(sd_emmc_b, SD_EMMC_CLK_CTRL, 25, 0x7, c3_sd_emmc_parents); +static C3_COMP_DIV(sd_emmc_b, SD_EMMC_CLK_CTRL, 16, 7); +static C3_COMP_GATE(sd_emmc_b, SD_EMMC_CLK_CTRL, 23); -static struct clk_regmap sd_emmc_c = { - .data = &(struct clk_regmap_gate_data) { - .offset = NAND_CLK_CTRL, - .bit_idx = 7, - }, - .hw.init = &(struct clk_init_data) { - .name = "sd_emmc_c", - .ops = &clk_regmap_gate_ops, - .parent_hws = (const struct clk_hw *[]) { - &sd_emmc_c_div.hw - }, - .num_parents = 1, - .flags = CLK_SET_RATE_PARENT, - }, -}; +static C3_COMP_SEL(sd_emmc_c, NAND_CLK_CTRL, 9, 0x7, c3_sd_emmc_parents); +static C3_COMP_DIV(sd_emmc_c, NAND_CLK_CTRL, 0, 7); +static C3_COMP_GATE(sd_emmc_c, NAND_CLK_CTRL, 7); -static struct clk_regmap ts_div = { +static struct clk_regmap c3_ts_div = { .data = &(struct clk_regmap_div_data) { .offset = TS_CLK_CTRL, .shift = 0, @@ -1001,7 +607,7 @@ static struct clk_regmap ts_div = { }, }; -static struct clk_regmap ts = { +static struct clk_regmap c3_ts = { .data = &(struct clk_regmap_gate_data) { .offset = TS_CLK_CTRL, .bit_idx = 8, @@ -1010,29 +616,29 @@ static struct clk_regmap ts = { .name = "ts", .ops = &clk_regmap_gate_ops, .parent_hws = (const struct clk_hw *[]) { - &ts_div.hw + &c3_ts_div.hw }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, }; -static const struct clk_parent_data eth_parent = { +static const struct clk_parent_data c3_eth_parents = { .fw_name = "fdiv2", }; -static struct clk_fixed_factor eth_125m_div = { +static struct clk_fixed_factor c3_eth_125m_div = { .mult = 1, .div = 8, .hw.init = &(struct clk_init_data) { .name = "eth_125m_div", .ops = &clk_fixed_factor_ops, - .parent_data = ð_parent, + .parent_data = &c3_eth_parents, .num_parents = 1, }, }; -static struct clk_regmap eth_125m = { +static struct clk_regmap c3_eth_125m = { .data = &(struct clk_regmap_gate_data) { .offset = ETH_CLK_CTRL, .bit_idx = 7, @@ -1041,14 +647,14 @@ static struct clk_regmap eth_125m = { .name = "eth_125m", .ops = &clk_regmap_gate_ops, .parent_hws = (const struct clk_hw *[]) { - ð_125m_div.hw + &c3_eth_125m_div.hw }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, }; -static struct clk_regmap eth_rmii_div = { +static struct clk_regmap c3_eth_rmii_div = { .data = &(struct clk_regmap_div_data) { .offset = ETH_CLK_CTRL, .shift = 0, @@ -1057,12 +663,12 @@ static struct clk_regmap eth_rmii_div = { .hw.init = &(struct clk_init_data) { .name = "eth_rmii_div", .ops = &clk_regmap_divider_ops, - .parent_data = ð_parent, + .parent_data = &c3_eth_parents, .num_parents = 1, }, }; -static struct clk_regmap eth_rmii = { +static struct clk_regmap c3_eth_rmii = { .data = &(struct clk_regmap_gate_data) { .offset = ETH_CLK_CTRL, .bit_idx = 8, @@ -1071,14 +677,14 @@ static struct clk_regmap eth_rmii = { .name = "eth_rmii", .ops = &clk_regmap_gate_ops, .parent_hws = (const struct clk_hw *[]) { - ð_rmii_div.hw + &c3_eth_rmii_div.hw }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, }; -static const struct clk_parent_data mipi_dsi_meas_parent_data[] = { +static const struct clk_parent_data c3_mipi_dsi_meas_parents[] = { { .fw_name = "oscin" }, { .fw_name = "fdiv4" }, { .fw_name = "fdiv3" }, @@ -1089,54 +695,11 @@ static const struct clk_parent_data mipi_dsi_meas_parent_data[] = { { .fw_name = "fdiv7" } }; -static struct clk_regmap mipi_dsi_meas_sel = { - .data = &(struct clk_regmap_mux_data) { - .offset = VDIN_MEAS_CLK_CTRL, - .mask = 0x7, - .shift = 21, - }, - .hw.init = &(struct clk_init_data) { - .name = "mipi_dsi_meas_sel", - .ops = &clk_regmap_mux_ops, - .parent_data = mipi_dsi_meas_parent_data, - .num_parents = ARRAY_SIZE(mipi_dsi_meas_parent_data), - }, -}; - -static struct clk_regmap mipi_dsi_meas_div = { - .data = &(struct clk_regmap_div_data) { - .offset = VDIN_MEAS_CLK_CTRL, - .shift = 12, - .width = 7, - }, - .hw.init = &(struct clk_init_data) { - .name = "mipi_dsi_meas_div", - .ops = &clk_regmap_divider_ops, - .parent_hws = (const struct clk_hw *[]) { - &mipi_dsi_meas_sel.hw - }, - .num_parents = 1, - .flags = CLK_SET_RATE_PARENT, - }, -}; +static C3_COMP_SEL(mipi_dsi_meas, VDIN_MEAS_CLK_CTRL, 21, 0x7, c3_mipi_dsi_meas_parents); +static C3_COMP_DIV(mipi_dsi_meas, VDIN_MEAS_CLK_CTRL, 12, 7); +static C3_COMP_GATE(mipi_dsi_meas, VDIN_MEAS_CLK_CTRL, 20); -static struct clk_regmap mipi_dsi_meas = { - .data = &(struct clk_regmap_gate_data) { - .offset = VDIN_MEAS_CLK_CTRL, - .bit_idx = 20, - }, - .hw.init = &(struct clk_init_data) { - .name = "mipi_dsi_meas", - .ops = &clk_regmap_gate_ops, - .parent_hws = (const struct clk_hw *[]) { - &mipi_dsi_meas_div.hw - }, - .num_parents = 1, - .flags = CLK_SET_RATE_PARENT, - }, -}; - -static const struct clk_parent_data dsi_phy_parent_data[] = { +static const struct clk_parent_data c3_dsi_phy_parents[] = { { .fw_name = "gp1" }, { .fw_name = "gp0" }, { .fw_name = "hifi" }, @@ -1147,54 +710,11 @@ static const struct clk_parent_data dsi_phy_parent_data[] = { { .fw_name = "fdiv7" } }; -static struct clk_regmap dsi_phy_sel = { - .data = &(struct clk_regmap_mux_data) { - .offset = MIPIDSI_PHY_CLK_CTRL, - .mask = 0x7, - .shift = 12, - }, - .hw.init = &(struct clk_init_data) { - .name = "dsi_phy_sel", - .ops = &clk_regmap_mux_ops, - .parent_data = dsi_phy_parent_data, - .num_parents = ARRAY_SIZE(dsi_phy_parent_data), - }, -}; - -static struct clk_regmap dsi_phy_div = { - .data = &(struct clk_regmap_div_data) { - .offset = MIPIDSI_PHY_CLK_CTRL, - .shift = 0, - .width = 7, - }, - .hw.init = &(struct clk_init_data) { - .name = "dsi_phy_div", - .ops = &clk_regmap_divider_ops, - .parent_hws = (const struct clk_hw *[]) { - &dsi_phy_sel.hw - }, - .num_parents = 1, - .flags = CLK_SET_RATE_PARENT, - }, -}; +static C3_COMP_SEL(dsi_phy, MIPIDSI_PHY_CLK_CTRL, 12, 0x7, c3_dsi_phy_parents); +static C3_COMP_DIV(dsi_phy, MIPIDSI_PHY_CLK_CTRL, 0, 7); +static C3_COMP_GATE(dsi_phy, MIPIDSI_PHY_CLK_CTRL, 8); -static struct clk_regmap dsi_phy = { - .data = &(struct clk_regmap_gate_data) { - .offset = MIPIDSI_PHY_CLK_CTRL, - .bit_idx = 8, - }, - .hw.init = &(struct clk_init_data) { - .name = "dsi_phy", - .ops = &clk_regmap_gate_ops, - .parent_hws = (const struct clk_hw *[]) { - &dsi_phy_div.hw - }, - .num_parents = 1, - .flags = CLK_SET_RATE_PARENT, - }, -}; - -static const struct clk_parent_data vout_mclk_parent_data[] = { +static const struct clk_parent_data c3_vout_mclk_parents[] = { { .fw_name = "fdiv2p5" }, { .fw_name = "fdiv3" }, { .fw_name = "fdiv4" }, @@ -1205,54 +725,11 @@ static const struct clk_parent_data vout_mclk_parent_data[] = { { .fw_name = "fdiv7" } }; -static struct clk_regmap vout_mclk_sel = { - .data = &(struct clk_regmap_mux_data) { - .offset = VOUTENC_CLK_CTRL, - .mask = 0x7, - .shift = 9, - }, - .hw.init = &(struct clk_init_data) { - .name = "vout_mclk_sel", - .ops = &clk_regmap_mux_ops, - .parent_data = vout_mclk_parent_data, - .num_parents = ARRAY_SIZE(vout_mclk_parent_data), - }, -}; +static C3_COMP_SEL(vout_mclk, VOUTENC_CLK_CTRL, 9, 0x7, c3_vout_mclk_parents); +static C3_COMP_DIV(vout_mclk, VOUTENC_CLK_CTRL, 0, 7); +static C3_COMP_GATE(vout_mclk, VOUTENC_CLK_CTRL, 8); -static struct clk_regmap vout_mclk_div = { - .data = &(struct clk_regmap_div_data) { - .offset = VOUTENC_CLK_CTRL, - .shift = 0, - .width = 7, - }, - .hw.init = &(struct clk_init_data) { - .name = "vout_mclk_div", - .ops = &clk_regmap_divider_ops, - .parent_hws = (const struct clk_hw *[]) { - &vout_mclk_sel.hw - }, - .num_parents = 1, - .flags = CLK_SET_RATE_PARENT, - }, -}; - -static struct clk_regmap vout_mclk = { - .data = &(struct clk_regmap_gate_data) { - .offset = VOUTENC_CLK_CTRL, - .bit_idx = 8, - }, - .hw.init = &(struct clk_init_data) { - .name = "vout_mclk", - .ops = &clk_regmap_gate_ops, - .parent_hws = (const struct clk_hw *[]) { - &vout_mclk_div.hw - }, - .num_parents = 1, - .flags = CLK_SET_RATE_PARENT, - }, -}; - -static const struct clk_parent_data vout_enc_parent_data[] = { +static const struct clk_parent_data c3_vout_enc_parents[] = { { .fw_name = "gp1" }, { .fw_name = "fdiv3" }, { .fw_name = "fdiv4" }, @@ -1263,54 +740,11 @@ static const struct clk_parent_data vout_enc_parent_data[] = { { .fw_name = "fdiv7" } }; -static struct clk_regmap vout_enc_sel = { - .data = &(struct clk_regmap_mux_data) { - .offset = VOUTENC_CLK_CTRL, - .mask = 0x7, - .shift = 25, - }, - .hw.init = &(struct clk_init_data) { - .name = "vout_enc_sel", - .ops = &clk_regmap_mux_ops, - .parent_data = vout_enc_parent_data, - .num_parents = ARRAY_SIZE(vout_enc_parent_data), - }, -}; - -static struct clk_regmap vout_enc_div = { - .data = &(struct clk_regmap_div_data) { - .offset = VOUTENC_CLK_CTRL, - .shift = 16, - .width = 7, - }, - .hw.init = &(struct clk_init_data) { - .name = "vout_enc_div", - .ops = &clk_regmap_divider_ops, - .parent_hws = (const struct clk_hw *[]) { - &vout_enc_sel.hw - }, - .num_parents = 1, - .flags = CLK_SET_RATE_PARENT, - }, -}; - -static struct clk_regmap vout_enc = { - .data = &(struct clk_regmap_gate_data) { - .offset = VOUTENC_CLK_CTRL, - .bit_idx = 24, - }, - .hw.init = &(struct clk_init_data) { - .name = "vout_enc", - .ops = &clk_regmap_gate_ops, - .parent_hws = (const struct clk_hw *[]) { - &vout_enc_div.hw - }, - .num_parents = 1, - .flags = CLK_SET_RATE_PARENT, - }, -}; +static C3_COMP_SEL(vout_enc, VOUTENC_CLK_CTRL, 25, 0x7, c3_vout_enc_parents); +static C3_COMP_DIV(vout_enc, VOUTENC_CLK_CTRL, 16, 7); +static C3_COMP_GATE(vout_enc, VOUTENC_CLK_CTRL, 24); -static const struct clk_parent_data hcodec_pre_parent_data[] = { +static const struct clk_parent_data c3_hcodec_pre_parents[] = { { .fw_name = "fdiv2p5" }, { .fw_name = "fdiv3" }, { .fw_name = "fdiv4" }, @@ -1321,106 +755,20 @@ static const struct clk_parent_data hcodec_pre_parent_data[] = { { .fw_name = "oscin" } }; -static struct clk_regmap hcodec_0_sel = { - .data = &(struct clk_regmap_mux_data) { - .offset = VDEC_CLK_CTRL, - .mask = 0x7, - .shift = 9, - }, - .hw.init = &(struct clk_init_data) { - .name = "hcodec_0_sel", - .ops = &clk_regmap_mux_ops, - .parent_data = hcodec_pre_parent_data, - .num_parents = ARRAY_SIZE(hcodec_pre_parent_data), - }, -}; +static C3_COMP_SEL(hcodec_0, VDEC_CLK_CTRL, 9, 0x7, c3_hcodec_pre_parents); +static C3_COMP_DIV(hcodec_0, VDEC_CLK_CTRL, 0, 7); +static C3_COMP_GATE(hcodec_0, VDEC_CLK_CTRL, 8); -static struct clk_regmap hcodec_0_div = { - .data = &(struct clk_regmap_div_data) { - .offset = VDEC_CLK_CTRL, - .shift = 0, - .width = 7, - }, - .hw.init = &(struct clk_init_data) { - .name = "hcodec_0_div", - .ops = &clk_regmap_divider_ops, - .parent_hws = (const struct clk_hw *[]) { - &hcodec_0_sel.hw - }, - .num_parents = 1, - .flags = CLK_SET_RATE_PARENT, - }, -}; +static C3_COMP_SEL(hcodec_1, VDEC3_CLK_CTRL, 9, 0x7, c3_hcodec_pre_parents); +static C3_COMP_DIV(hcodec_1, VDEC3_CLK_CTRL, 0, 7); +static C3_COMP_GATE(hcodec_1, VDEC3_CLK_CTRL, 8); -static struct clk_regmap hcodec_0 = { - .data = &(struct clk_regmap_gate_data) { - .offset = VDEC_CLK_CTRL, - .bit_idx = 8, - }, - .hw.init = &(struct clk_init_data) { - .name = "hcodec_0", - .ops = &clk_regmap_gate_ops, - .parent_hws = (const struct clk_hw *[]) { - &hcodec_0_div.hw - }, - .num_parents = 1, - .flags = CLK_SET_RATE_PARENT, - }, +static const struct clk_parent_data c3_hcodec_parents[] = { + { .hw = &c3_hcodec_0.hw }, + { .hw = &c3_hcodec_1.hw } }; -static struct clk_regmap hcodec_1_sel = { - .data = &(struct clk_regmap_mux_data) { - .offset = VDEC3_CLK_CTRL, - .mask = 0x7, - .shift = 9, - }, - .hw.init = &(struct clk_init_data) { - .name = "hcodec_1_sel", - .ops = &clk_regmap_mux_ops, - .parent_data = hcodec_pre_parent_data, - .num_parents = ARRAY_SIZE(hcodec_pre_parent_data), - }, -}; - -static struct clk_regmap hcodec_1_div = { - .data = &(struct clk_regmap_div_data) { - .offset = VDEC3_CLK_CTRL, - .shift = 0, - .width = 7, - }, - .hw.init = &(struct clk_init_data) { - .name = "hcodec_1_div", - .ops = &clk_regmap_divider_ops, - .parent_hws = (const struct clk_hw *[]) { - &hcodec_1_sel.hw - }, - .num_parents = 1, - .flags = CLK_SET_RATE_PARENT, - }, -}; - -static struct clk_regmap hcodec_1 = { - .data = &(struct clk_regmap_gate_data) { - .offset = VDEC3_CLK_CTRL, - .bit_idx = 8, - }, - .hw.init = &(struct clk_init_data) { - .name = "hcodec_1", - .ops = &clk_regmap_gate_ops, - .parent_hws = (const struct clk_hw *[]) { - &hcodec_1_div.hw - }, - .num_parents = 1, - .flags = CLK_SET_RATE_PARENT, - }, -}; - -static const struct clk_parent_data hcodec_parent_data[] = { - { .hw = &hcodec_0.hw }, - { .hw = &hcodec_1.hw } -}; - -static struct clk_regmap hcodec = { +static struct clk_regmap c3_hcodec = { .data = &(struct clk_regmap_mux_data) { .offset = VDEC3_CLK_CTRL, .mask = 0x1, @@ -1429,13 +777,13 @@ static struct clk_regmap hcodec = { .hw.init = &(struct clk_init_data) { .name = "hcodec", .ops = &clk_regmap_mux_ops, - .parent_data = hcodec_parent_data, - .num_parents = ARRAY_SIZE(hcodec_parent_data), + .parent_data = c3_hcodec_parents, + .num_parents = ARRAY_SIZE(c3_hcodec_parents), .flags = CLK_SET_RATE_PARENT, }, }; -static const struct clk_parent_data vc9000e_parent_data[] = { +static const struct clk_parent_data c3_vc9000e_parents[] = { { .fw_name = "oscin" }, { .fw_name = "fdiv4" }, { .fw_name = "fdiv3" }, @@ -1446,101 +794,15 @@ static const struct clk_parent_data vc9000e_parent_data[] = { { .fw_name = "gp0" } }; -static struct clk_regmap vc9000e_aclk_sel = { - .data = &(struct clk_regmap_mux_data) { - .offset = VC9000E_CLK_CTRL, - .mask = 0x7, - .shift = 9, - }, - .hw.init = &(struct clk_init_data) { - .name = "vc9000e_aclk_sel", - .ops = &clk_regmap_mux_ops, - .parent_data = vc9000e_parent_data, - .num_parents = ARRAY_SIZE(vc9000e_parent_data), - }, -}; - -static struct clk_regmap vc9000e_aclk_div = { - .data = &(struct clk_regmap_div_data) { - .offset = VC9000E_CLK_CTRL, - .shift = 0, - .width = 7, - }, - .hw.init = &(struct clk_init_data) { - .name = "vc9000e_aclk_div", - .ops = &clk_regmap_divider_ops, - .parent_hws = (const struct clk_hw *[]) { - &vc9000e_aclk_sel.hw - }, - .num_parents = 1, - .flags = CLK_SET_RATE_PARENT, - }, -}; - -static struct clk_regmap vc9000e_aclk = { - .data = &(struct clk_regmap_gate_data) { - .offset = VC9000E_CLK_CTRL, - .bit_idx = 8, - }, - .hw.init = &(struct clk_init_data) { - .name = "vc9000e_aclk", - .ops = &clk_regmap_gate_ops, - .parent_hws = (const struct clk_hw *[]) { - &vc9000e_aclk_div.hw - }, - .num_parents = 1, - .flags = CLK_SET_RATE_PARENT, - }, -}; +static C3_COMP_SEL(vc9000e_aclk, VC9000E_CLK_CTRL, 9, 0x7, c3_vc9000e_parents); +static C3_COMP_DIV(vc9000e_aclk, VC9000E_CLK_CTRL, 0, 7); +static C3_COMP_GATE(vc9000e_aclk, VC9000E_CLK_CTRL, 8); -static struct clk_regmap vc9000e_core_sel = { - .data = &(struct clk_regmap_mux_data) { - .offset = VC9000E_CLK_CTRL, - .mask = 0x7, - .shift = 25, - }, - .hw.init = &(struct clk_init_data) { - .name = "vc9000e_core_sel", - .ops = &clk_regmap_mux_ops, - .parent_data = vc9000e_parent_data, - .num_parents = ARRAY_SIZE(vc9000e_parent_data), - }, -}; +static C3_COMP_SEL(vc9000e_core, VC9000E_CLK_CTRL, 25, 0x7, c3_vc9000e_parents); +static C3_COMP_DIV(vc9000e_core, VC9000E_CLK_CTRL, 16, 7); +static C3_COMP_GATE(vc9000e_core, VC9000E_CLK_CTRL, 24); -static struct clk_regmap vc9000e_core_div = { - .data = &(struct clk_regmap_div_data) { - .offset = VC9000E_CLK_CTRL, - .shift = 16, - .width = 7, - }, - .hw.init = &(struct clk_init_data) { - .name = "vc9000e_core_div", - .ops = &clk_regmap_divider_ops, - .parent_hws = (const struct clk_hw *[]) { - &vc9000e_core_sel.hw - }, - .num_parents = 1, - .flags = CLK_SET_RATE_PARENT, - }, -}; - -static struct clk_regmap vc9000e_core = { - .data = &(struct clk_regmap_gate_data) { - .offset = VC9000E_CLK_CTRL, - .bit_idx = 24, - }, - .hw.init = &(struct clk_init_data) { - .name = "vc9000e_core", - .ops = &clk_regmap_gate_ops, - .parent_hws = (const struct clk_hw *[]) { - &vc9000e_core_div.hw - }, - .num_parents = 1, - .flags = CLK_SET_RATE_PARENT, - }, -}; - -static const struct clk_parent_data csi_phy_parent_data[] = { +static const struct clk_parent_data c3_csi_phy_parents[] = { { .fw_name = "fdiv2p5" }, { .fw_name = "fdiv3" }, { .fw_name = "fdiv4" }, @@ -1551,54 +813,11 @@ static const struct clk_parent_data csi_phy_parent_data[] = { { .fw_name = "oscin" } }; -static struct clk_regmap csi_phy0_sel = { - .data = &(struct clk_regmap_mux_data) { - .offset = ISP0_CLK_CTRL, - .mask = 0x7, - .shift = 25, - }, - .hw.init = &(struct clk_init_data) { - .name = "csi_phy0_sel", - .ops = &clk_regmap_mux_ops, - .parent_data = csi_phy_parent_data, - .num_parents = ARRAY_SIZE(csi_phy_parent_data), - }, -}; - -static struct clk_regmap csi_phy0_div = { - .data = &(struct clk_regmap_div_data) { - .offset = ISP0_CLK_CTRL, - .shift = 16, - .width = 7, - }, - .hw.init = &(struct clk_init_data) { - .name = "csi_phy0_div", - .ops = &clk_regmap_divider_ops, - .parent_hws = (const struct clk_hw *[]) { - &csi_phy0_sel.hw - }, - .num_parents = 1, - .flags = CLK_SET_RATE_PARENT, - }, -}; - -static struct clk_regmap csi_phy0 = { - .data = &(struct clk_regmap_gate_data) { - .offset = ISP0_CLK_CTRL, - .bit_idx = 24, - }, - .hw.init = &(struct clk_init_data) { - .name = "csi_phy0", - .ops = &clk_regmap_gate_ops, - .parent_hws = (const struct clk_hw *[]) { - &csi_phy0_div.hw - }, - .num_parents = 1, - .flags = CLK_SET_RATE_PARENT, - }, -}; +static C3_COMP_SEL(csi_phy0, ISP0_CLK_CTRL, 25, 0x7, c3_csi_phy_parents); +static C3_COMP_DIV(csi_phy0, ISP0_CLK_CTRL, 16, 7); +static C3_COMP_GATE(csi_phy0, ISP0_CLK_CTRL, 24); -static const struct clk_parent_data dewarpa_parent_data[] = { +static const struct clk_parent_data c3_dewarpa_parents[] = { { .fw_name = "fdiv2p5" }, { .fw_name = "fdiv3" }, { .fw_name = "fdiv4" }, @@ -1609,54 +828,11 @@ static const struct clk_parent_data dewarpa_parent_data[] = { { .fw_name = "fdiv7" } }; -static struct clk_regmap dewarpa_sel = { - .data = &(struct clk_regmap_mux_data) { - .offset = DEWARPA_CLK_CTRL, - .mask = 0x7, - .shift = 9, - }, - .hw.init = &(struct clk_init_data) { - .name = "dewarpa_sel", - .ops = &clk_regmap_mux_ops, - .parent_data = dewarpa_parent_data, - .num_parents = ARRAY_SIZE(dewarpa_parent_data), - }, -}; - -static struct clk_regmap dewarpa_div = { - .data = &(struct clk_regmap_div_data) { - .offset = DEWARPA_CLK_CTRL, - .shift = 0, - .width = 7, - }, - .hw.init = &(struct clk_init_data) { - .name = "dewarpa_div", - .ops = &clk_regmap_divider_ops, - .parent_hws = (const struct clk_hw *[]) { - &dewarpa_sel.hw - }, - .num_parents = 1, - .flags = CLK_SET_RATE_PARENT, - }, -}; - -static struct clk_regmap dewarpa = { - .data = &(struct clk_regmap_gate_data) { - .offset = DEWARPA_CLK_CTRL, - .bit_idx = 8, - }, - .hw.init = &(struct clk_init_data) { - .name = "dewarpa", - .ops = &clk_regmap_gate_ops, - .parent_hws = (const struct clk_hw *[]) { - &dewarpa_div.hw - }, - .num_parents = 1, - .flags = CLK_SET_RATE_PARENT, - }, -}; +static C3_COMP_SEL(dewarpa, DEWARPA_CLK_CTRL, 9, 0x7, c3_dewarpa_parents); +static C3_COMP_DIV(dewarpa, DEWARPA_CLK_CTRL, 0, 7); +static C3_COMP_GATE(dewarpa, DEWARPA_CLK_CTRL, 8); -static const struct clk_parent_data isp_parent_data[] = { +static const struct clk_parent_data c3_isp_parents[] = { { .fw_name = "fdiv2p5" }, { .fw_name = "fdiv3" }, { .fw_name = "fdiv4" }, @@ -1667,54 +843,11 @@ static const struct clk_parent_data isp_parent_data[] = { { .fw_name = "oscin" } }; -static struct clk_regmap isp0_sel = { - .data = &(struct clk_regmap_mux_data) { - .offset = ISP0_CLK_CTRL, - .mask = 0x7, - .shift = 9, - }, - .hw.init = &(struct clk_init_data) { - .name = "isp0_sel", - .ops = &clk_regmap_mux_ops, - .parent_data = isp_parent_data, - .num_parents = ARRAY_SIZE(isp_parent_data), - }, -}; - -static struct clk_regmap isp0_div = { - .data = &(struct clk_regmap_div_data) { - .offset = ISP0_CLK_CTRL, - .shift = 0, - .width = 7, - }, - .hw.init = &(struct clk_init_data) { - .name = "isp0_div", - .ops = &clk_regmap_divider_ops, - .parent_hws = (const struct clk_hw *[]) { - &isp0_sel.hw - }, - .num_parents = 1, - .flags = CLK_SET_RATE_PARENT, - }, -}; - -static struct clk_regmap isp0 = { - .data = &(struct clk_regmap_gate_data) { - .offset = ISP0_CLK_CTRL, - .bit_idx = 8, - }, - .hw.init = &(struct clk_init_data) { - .name = "isp0", - .ops = &clk_regmap_gate_ops, - .parent_hws = (const struct clk_hw *[]) { - &isp0_div.hw - }, - .num_parents = 1, - .flags = CLK_SET_RATE_PARENT, - }, -}; +static C3_COMP_SEL(isp0, ISP0_CLK_CTRL, 9, 0x7, c3_isp_parents); +static C3_COMP_DIV(isp0, ISP0_CLK_CTRL, 0, 7); +static C3_COMP_GATE(isp0, ISP0_CLK_CTRL, 8); -static const struct clk_parent_data nna_core_parent_data[] = { +static const struct clk_parent_data c3_nna_core_parents[] = { { .fw_name = "oscin" }, { .fw_name = "fdiv2p5" }, { .fw_name = "fdiv4" }, @@ -1725,54 +858,11 @@ static const struct clk_parent_data nna_core_parent_data[] = { { .fw_name = "hifi" } }; -static struct clk_regmap nna_core_sel = { - .data = &(struct clk_regmap_mux_data) { - .offset = NNA_CLK_CTRL, - .mask = 0x7, - .shift = 9, - }, - .hw.init = &(struct clk_init_data) { - .name = "nna_core_sel", - .ops = &clk_regmap_mux_ops, - .parent_data = nna_core_parent_data, - .num_parents = ARRAY_SIZE(nna_core_parent_data), - }, -}; +static C3_COMP_SEL(nna_core, NNA_CLK_CTRL, 9, 0x7, c3_nna_core_parents); +static C3_COMP_DIV(nna_core, NNA_CLK_CTRL, 0, 7); +static C3_COMP_GATE(nna_core, NNA_CLK_CTRL, 8); -static struct clk_regmap nna_core_div = { - .data = &(struct clk_regmap_div_data) { - .offset = NNA_CLK_CTRL, - .shift = 0, - .width = 7, - }, - .hw.init = &(struct clk_init_data) { - .name = "nna_core_div", - .ops = &clk_regmap_divider_ops, - .parent_hws = (const struct clk_hw *[]) { - &nna_core_sel.hw - }, - .num_parents = 1, - .flags = CLK_SET_RATE_PARENT, - }, -}; - -static struct clk_regmap nna_core = { - .data = &(struct clk_regmap_gate_data) { - .offset = NNA_CLK_CTRL, - .bit_idx = 8, - }, - .hw.init = &(struct clk_init_data) { - .name = "nna_core", - .ops = &clk_regmap_gate_ops, - .parent_hws = (const struct clk_hw *[]) { - &nna_core_div.hw - }, - .num_parents = 1, - .flags = CLK_SET_RATE_PARENT, - }, -}; - -static const struct clk_parent_data ge2d_parent_data[] = { +static const struct clk_parent_data c3_ge2d_parents[] = { { .fw_name = "oscin" }, { .fw_name = "fdiv2p5" }, { .fw_name = "fdiv3" }, @@ -1780,57 +870,14 @@ static const struct clk_parent_data ge2d_parent_data[] = { { .fw_name = "hifi" }, { .fw_name = "fdiv5" }, { .fw_name = "gp0" }, - { .hw = &rtc_clk.hw } -}; - -static struct clk_regmap ge2d_sel = { - .data = &(struct clk_regmap_mux_data) { - .offset = GE2D_CLK_CTRL, - .mask = 0x7, - .shift = 9, - }, - .hw.init = &(struct clk_init_data) { - .name = "ge2d_sel", - .ops = &clk_regmap_mux_ops, - .parent_data = ge2d_parent_data, - .num_parents = ARRAY_SIZE(ge2d_parent_data), - }, + { .hw = &c3_rtc_clk.hw } }; -static struct clk_regmap ge2d_div = { - .data = &(struct clk_regmap_div_data) { - .offset = GE2D_CLK_CTRL, - .shift = 0, - .width = 7, - }, - .hw.init = &(struct clk_init_data) { - .name = "ge2d_div", - .ops = &clk_regmap_divider_ops, - .parent_hws = (const struct clk_hw *[]) { - &ge2d_sel.hw - }, - .num_parents = 1, - .flags = CLK_SET_RATE_PARENT, - }, -}; +static C3_COMP_SEL(ge2d, GE2D_CLK_CTRL, 9, 0x7, c3_ge2d_parents); +static C3_COMP_DIV(ge2d, GE2D_CLK_CTRL, 0, 7); +static C3_COMP_GATE(ge2d, GE2D_CLK_CTRL, 8); -static struct clk_regmap ge2d = { - .data = &(struct clk_regmap_gate_data) { - .offset = GE2D_CLK_CTRL, - .bit_idx = 8, - }, - .hw.init = &(struct clk_init_data) { - .name = "ge2d", - .ops = &clk_regmap_gate_ops, - .parent_hws = (const struct clk_hw *[]) { - &ge2d_div.hw - }, - .num_parents = 1, - .flags = CLK_SET_RATE_PARENT, - }, -}; - -static const struct clk_parent_data vapb_parent_data[] = { +static const struct clk_parent_data c3_vapb_parents[] = { { .fw_name = "fdiv2p5" }, { .fw_name = "fdiv3" }, { .fw_name = "fdiv4" }, @@ -1841,317 +888,239 @@ static const struct clk_parent_data vapb_parent_data[] = { { .fw_name = "oscin" }, }; -static struct clk_regmap vapb_sel = { - .data = &(struct clk_regmap_mux_data) { - .offset = VAPB_CLK_CTRL, - .mask = 0x7, - .shift = 9, - }, - .hw.init = &(struct clk_init_data) { - .name = "vapb_sel", - .ops = &clk_regmap_mux_ops, - .parent_data = vapb_parent_data, - .num_parents = ARRAY_SIZE(vapb_parent_data), +static C3_COMP_SEL(vapb, VAPB_CLK_CTRL, 9, 0x7, c3_vapb_parents); +static C3_COMP_DIV(vapb, VAPB_CLK_CTRL, 0, 7); +static C3_COMP_GATE(vapb, VAPB_CLK_CTRL, 8); + +static struct clk_hw *c3_peripherals_hw_clks[] = { + [CLKID_RTC_XTAL_CLKIN] = &c3_rtc_xtal_clkin.hw, + [CLKID_RTC_32K_DIV] = &c3_rtc_32k_div.hw, + [CLKID_RTC_32K_MUX] = &c3_rtc_32k_sel.hw, + [CLKID_RTC_32K] = &c3_rtc_32k.hw, + [CLKID_RTC_CLK] = &c3_rtc_clk.hw, + [CLKID_SYS_RESET_CTRL] = &c3_sys_reset_ctrl.hw, + [CLKID_SYS_PWR_CTRL] = &c3_sys_pwr_ctrl.hw, + [CLKID_SYS_PAD_CTRL] = &c3_sys_pad_ctrl.hw, + [CLKID_SYS_CTRL] = &c3_sys_ctrl.hw, + [CLKID_SYS_TS_PLL] = &c3_sys_ts_pll.hw, + [CLKID_SYS_DEV_ARB] = &c3_sys_dev_arb.hw, + [CLKID_SYS_MMC_PCLK] = &c3_sys_mmc_pclk.hw, + [CLKID_SYS_CPU_CTRL] = &c3_sys_cpu_ctrl.hw, + [CLKID_SYS_JTAG_CTRL] = &c3_sys_jtag_ctrl.hw, + [CLKID_SYS_IR_CTRL] = &c3_sys_ir_ctrl.hw, + [CLKID_SYS_IRQ_CTRL] = &c3_sys_irq_ctrl.hw, + [CLKID_SYS_MSR_CLK] = &c3_sys_msr_clk.hw, + [CLKID_SYS_ROM] = &c3_sys_rom.hw, + [CLKID_SYS_UART_F] = &c3_sys_uart_f.hw, + [CLKID_SYS_CPU_ARB] = &c3_sys_cpu_apb.hw, + [CLKID_SYS_RSA] = &c3_sys_rsa.hw, + [CLKID_SYS_SAR_ADC] = &c3_sys_sar_adc.hw, + [CLKID_SYS_STARTUP] = &c3_sys_startup.hw, + [CLKID_SYS_SECURE] = &c3_sys_secure.hw, + [CLKID_SYS_SPIFC] = &c3_sys_spifc.hw, + [CLKID_SYS_NNA] = &c3_sys_nna.hw, + [CLKID_SYS_ETH_MAC] = &c3_sys_eth_mac.hw, + [CLKID_SYS_GIC] = &c3_sys_gic.hw, + [CLKID_SYS_RAMA] = &c3_sys_rama.hw, + [CLKID_SYS_BIG_NIC] = &c3_sys_big_nic.hw, + [CLKID_SYS_RAMB] = &c3_sys_ramb.hw, + [CLKID_SYS_AUDIO_PCLK] = &c3_sys_audio_pclk.hw, + [CLKID_SYS_PWM_KL] = &c3_sys_pwm_kl.hw, + [CLKID_SYS_PWM_IJ] = &c3_sys_pwm_ij.hw, + [CLKID_SYS_USB] = &c3_sys_usb.hw, + [CLKID_SYS_SD_EMMC_A] = &c3_sys_sd_emmc_a.hw, + [CLKID_SYS_SD_EMMC_C] = &c3_sys_sd_emmc_c.hw, + [CLKID_SYS_PWM_AB] = &c3_sys_pwm_ab.hw, + [CLKID_SYS_PWM_CD] = &c3_sys_pwm_cd.hw, + [CLKID_SYS_PWM_EF] = &c3_sys_pwm_ef.hw, + [CLKID_SYS_PWM_GH] = &c3_sys_pwm_gh.hw, + [CLKID_SYS_SPICC_1] = &c3_sys_spicc_1.hw, + [CLKID_SYS_SPICC_0] = &c3_sys_spicc_0.hw, + [CLKID_SYS_UART_A] = &c3_sys_uart_a.hw, + [CLKID_SYS_UART_B] = &c3_sys_uart_b.hw, + [CLKID_SYS_UART_C] = &c3_sys_uart_c.hw, + [CLKID_SYS_UART_D] = &c3_sys_uart_d.hw, + [CLKID_SYS_UART_E] = &c3_sys_uart_e.hw, + [CLKID_SYS_I2C_M_A] = &c3_sys_i2c_m_a.hw, + [CLKID_SYS_I2C_M_B] = &c3_sys_i2c_m_b.hw, + [CLKID_SYS_I2C_M_C] = &c3_sys_i2c_m_c.hw, + [CLKID_SYS_I2C_M_D] = &c3_sys_i2c_m_d.hw, + [CLKID_SYS_I2S_S_A] = &c3_sys_i2c_s_a.hw, + [CLKID_SYS_RTC] = &c3_sys_rtc.hw, + [CLKID_SYS_GE2D] = &c3_sys_ge2d.hw, + [CLKID_SYS_ISP] = &c3_sys_isp.hw, + [CLKID_SYS_GPV_ISP_NIC] = &c3_sys_gpv_isp_nic.hw, + [CLKID_SYS_GPV_CVE_NIC] = &c3_sys_gpv_cve_nic.hw, + [CLKID_SYS_MIPI_DSI_HOST] = &c3_sys_mipi_dsi_host.hw, + [CLKID_SYS_MIPI_DSI_PHY] = &c3_sys_mipi_dsi_phy.hw, + [CLKID_SYS_ETH_PHY] = &c3_sys_eth_phy.hw, + [CLKID_SYS_ACODEC] = &c3_sys_acodec.hw, + [CLKID_SYS_DWAP] = &c3_sys_dwap.hw, + [CLKID_SYS_DOS] = &c3_sys_dos.hw, + [CLKID_SYS_CVE] = &c3_sys_cve.hw, + [CLKID_SYS_VOUT] = &c3_sys_vout.hw, + [CLKID_SYS_VC9000E] = &c3_sys_vc9000e.hw, + [CLKID_SYS_PWM_MN] = &c3_sys_pwm_mn.hw, + [CLKID_SYS_SD_EMMC_B] = &c3_sys_sd_emmc_b.hw, + [CLKID_AXI_SYS_NIC] = &c3_axi_sys_nic.hw, + [CLKID_AXI_ISP_NIC] = &c3_axi_isp_nic.hw, + [CLKID_AXI_CVE_NIC] = &c3_axi_cve_nic.hw, + [CLKID_AXI_RAMB] = &c3_axi_ramb.hw, + [CLKID_AXI_RAMA] = &c3_axi_rama.hw, + [CLKID_AXI_CPU_DMC] = &c3_axi_cpu_dmc.hw, + [CLKID_AXI_NIC] = &c3_axi_nic.hw, + [CLKID_AXI_DMA] = &c3_axi_dma.hw, + [CLKID_AXI_MUX_NIC] = &c3_axi_mux_nic.hw, + [CLKID_AXI_CVE] = &c3_axi_cve.hw, + [CLKID_AXI_DEV1_DMC] = &c3_axi_dev1_dmc.hw, + [CLKID_AXI_DEV0_DMC] = &c3_axi_dev0_dmc.hw, + [CLKID_AXI_DSP_DMC] = &c3_axi_dsp_dmc.hw, + [CLKID_12_24M_IN] = &c3_clk_12_24m_in.hw, + [CLKID_12M_24M] = &c3_clk_12_24m.hw, + [CLKID_FCLK_25M_DIV] = &c3_fclk_25m_div.hw, + [CLKID_FCLK_25M] = &c3_fclk_25m.hw, + [CLKID_GEN_SEL] = &c3_gen_sel.hw, + [CLKID_GEN_DIV] = &c3_gen_div.hw, + [CLKID_GEN] = &c3_gen.hw, + [CLKID_SARADC_SEL] = &c3_saradc_sel.hw, + [CLKID_SARADC_DIV] = &c3_saradc_div.hw, + [CLKID_SARADC] = &c3_saradc.hw, + [CLKID_PWM_A_SEL] = &c3_pwm_a_sel.hw, + [CLKID_PWM_A_DIV] = &c3_pwm_a_div.hw, + [CLKID_PWM_A] = &c3_pwm_a.hw, + [CLKID_PWM_B_SEL] = &c3_pwm_b_sel.hw, + [CLKID_PWM_B_DIV] = &c3_pwm_b_div.hw, + [CLKID_PWM_B] = &c3_pwm_b.hw, + [CLKID_PWM_C_SEL] = &c3_pwm_c_sel.hw, + [CLKID_PWM_C_DIV] = &c3_pwm_c_div.hw, + [CLKID_PWM_C] = &c3_pwm_c.hw, + [CLKID_PWM_D_SEL] = &c3_pwm_d_sel.hw, + [CLKID_PWM_D_DIV] = &c3_pwm_d_div.hw, + [CLKID_PWM_D] = &c3_pwm_d.hw, + [CLKID_PWM_E_SEL] = &c3_pwm_e_sel.hw, + [CLKID_PWM_E_DIV] = &c3_pwm_e_div.hw, + [CLKID_PWM_E] = &c3_pwm_e.hw, + [CLKID_PWM_F_SEL] = &c3_pwm_f_sel.hw, + [CLKID_PWM_F_DIV] = &c3_pwm_f_div.hw, + [CLKID_PWM_F] = &c3_pwm_f.hw, + [CLKID_PWM_G_SEL] = &c3_pwm_g_sel.hw, + [CLKID_PWM_G_DIV] = &c3_pwm_g_div.hw, + [CLKID_PWM_G] = &c3_pwm_g.hw, + [CLKID_PWM_H_SEL] = &c3_pwm_h_sel.hw, + [CLKID_PWM_H_DIV] = &c3_pwm_h_div.hw, + [CLKID_PWM_H] = &c3_pwm_h.hw, + [CLKID_PWM_I_SEL] = &c3_pwm_i_sel.hw, + [CLKID_PWM_I_DIV] = &c3_pwm_i_div.hw, + [CLKID_PWM_I] = &c3_pwm_i.hw, + [CLKID_PWM_J_SEL] = &c3_pwm_j_sel.hw, + [CLKID_PWM_J_DIV] = &c3_pwm_j_div.hw, + [CLKID_PWM_J] = &c3_pwm_j.hw, + [CLKID_PWM_K_SEL] = &c3_pwm_k_sel.hw, + [CLKID_PWM_K_DIV] = &c3_pwm_k_div.hw, + [CLKID_PWM_K] = &c3_pwm_k.hw, + [CLKID_PWM_L_SEL] = &c3_pwm_l_sel.hw, + [CLKID_PWM_L_DIV] = &c3_pwm_l_div.hw, + [CLKID_PWM_L] = &c3_pwm_l.hw, + [CLKID_PWM_M_SEL] = &c3_pwm_m_sel.hw, + [CLKID_PWM_M_DIV] = &c3_pwm_m_div.hw, + [CLKID_PWM_M] = &c3_pwm_m.hw, + [CLKID_PWM_N_SEL] = &c3_pwm_n_sel.hw, + [CLKID_PWM_N_DIV] = &c3_pwm_n_div.hw, + [CLKID_PWM_N] = &c3_pwm_n.hw, + [CLKID_SPICC_A_SEL] = &c3_spicc_a_sel.hw, + [CLKID_SPICC_A_DIV] = &c3_spicc_a_div.hw, + [CLKID_SPICC_A] = &c3_spicc_a.hw, + [CLKID_SPICC_B_SEL] = &c3_spicc_b_sel.hw, + [CLKID_SPICC_B_DIV] = &c3_spicc_b_div.hw, + [CLKID_SPICC_B] = &c3_spicc_b.hw, + [CLKID_SPIFC_SEL] = &c3_spifc_sel.hw, + [CLKID_SPIFC_DIV] = &c3_spifc_div.hw, + [CLKID_SPIFC] = &c3_spifc.hw, + [CLKID_SD_EMMC_A_SEL] = &c3_sd_emmc_a_sel.hw, + [CLKID_SD_EMMC_A_DIV] = &c3_sd_emmc_a_div.hw, + [CLKID_SD_EMMC_A] = &c3_sd_emmc_a.hw, + [CLKID_SD_EMMC_B_SEL] = &c3_sd_emmc_b_sel.hw, + [CLKID_SD_EMMC_B_DIV] = &c3_sd_emmc_b_div.hw, + [CLKID_SD_EMMC_B] = &c3_sd_emmc_b.hw, + [CLKID_SD_EMMC_C_SEL] = &c3_sd_emmc_c_sel.hw, + [CLKID_SD_EMMC_C_DIV] = &c3_sd_emmc_c_div.hw, + [CLKID_SD_EMMC_C] = &c3_sd_emmc_c.hw, + [CLKID_TS_DIV] = &c3_ts_div.hw, + [CLKID_TS] = &c3_ts.hw, + [CLKID_ETH_125M_DIV] = &c3_eth_125m_div.hw, + [CLKID_ETH_125M] = &c3_eth_125m.hw, + [CLKID_ETH_RMII_DIV] = &c3_eth_rmii_div.hw, + [CLKID_ETH_RMII] = &c3_eth_rmii.hw, + [CLKID_MIPI_DSI_MEAS_SEL] = &c3_mipi_dsi_meas_sel.hw, + [CLKID_MIPI_DSI_MEAS_DIV] = &c3_mipi_dsi_meas_div.hw, + [CLKID_MIPI_DSI_MEAS] = &c3_mipi_dsi_meas.hw, + [CLKID_DSI_PHY_SEL] = &c3_dsi_phy_sel.hw, + [CLKID_DSI_PHY_DIV] = &c3_dsi_phy_div.hw, + [CLKID_DSI_PHY] = &c3_dsi_phy.hw, + [CLKID_VOUT_MCLK_SEL] = &c3_vout_mclk_sel.hw, + [CLKID_VOUT_MCLK_DIV] = &c3_vout_mclk_div.hw, + [CLKID_VOUT_MCLK] = &c3_vout_mclk.hw, + [CLKID_VOUT_ENC_SEL] = &c3_vout_enc_sel.hw, + [CLKID_VOUT_ENC_DIV] = &c3_vout_enc_div.hw, + [CLKID_VOUT_ENC] = &c3_vout_enc.hw, + [CLKID_HCODEC_0_SEL] = &c3_hcodec_0_sel.hw, + [CLKID_HCODEC_0_DIV] = &c3_hcodec_0_div.hw, + [CLKID_HCODEC_0] = &c3_hcodec_0.hw, + [CLKID_HCODEC_1_SEL] = &c3_hcodec_1_sel.hw, + [CLKID_HCODEC_1_DIV] = &c3_hcodec_1_div.hw, + [CLKID_HCODEC_1] = &c3_hcodec_1.hw, + [CLKID_HCODEC] = &c3_hcodec.hw, + [CLKID_VC9000E_ACLK_SEL] = &c3_vc9000e_aclk_sel.hw, + [CLKID_VC9000E_ACLK_DIV] = &c3_vc9000e_aclk_div.hw, + [CLKID_VC9000E_ACLK] = &c3_vc9000e_aclk.hw, + [CLKID_VC9000E_CORE_SEL] = &c3_vc9000e_core_sel.hw, + [CLKID_VC9000E_CORE_DIV] = &c3_vc9000e_core_div.hw, + [CLKID_VC9000E_CORE] = &c3_vc9000e_core.hw, + [CLKID_CSI_PHY0_SEL] = &c3_csi_phy0_sel.hw, + [CLKID_CSI_PHY0_DIV] = &c3_csi_phy0_div.hw, + [CLKID_CSI_PHY0] = &c3_csi_phy0.hw, + [CLKID_DEWARPA_SEL] = &c3_dewarpa_sel.hw, + [CLKID_DEWARPA_DIV] = &c3_dewarpa_div.hw, + [CLKID_DEWARPA] = &c3_dewarpa.hw, + [CLKID_ISP0_SEL] = &c3_isp0_sel.hw, + [CLKID_ISP0_DIV] = &c3_isp0_div.hw, + [CLKID_ISP0] = &c3_isp0.hw, + [CLKID_NNA_CORE_SEL] = &c3_nna_core_sel.hw, + [CLKID_NNA_CORE_DIV] = &c3_nna_core_div.hw, + [CLKID_NNA_CORE] = &c3_nna_core.hw, + [CLKID_GE2D_SEL] = &c3_ge2d_sel.hw, + [CLKID_GE2D_DIV] = &c3_ge2d_div.hw, + [CLKID_GE2D] = &c3_ge2d.hw, + [CLKID_VAPB_SEL] = &c3_vapb_sel.hw, + [CLKID_VAPB_DIV] = &c3_vapb_div.hw, + [CLKID_VAPB] = &c3_vapb.hw, +}; + +static const struct meson_clkc_data c3_peripherals_clkc_data = { + .hw_clks = { + .hws = c3_peripherals_hw_clks, + .num = ARRAY_SIZE(c3_peripherals_hw_clks), }, }; -static struct clk_regmap vapb_div = { - .data = &(struct clk_regmap_div_data) { - .offset = VAPB_CLK_CTRL, - .shift = 0, - .width = 7, - }, - .hw.init = &(struct clk_init_data) { - .name = "vapb_div", - .ops = &clk_regmap_divider_ops, - .parent_hws = (const struct clk_hw *[]) { - &vapb_sel.hw - }, - .num_parents = 1, - .flags = CLK_SET_RATE_PARENT, - }, -}; - -static struct clk_regmap vapb = { - .data = &(struct clk_regmap_gate_data) { - .offset = VAPB_CLK_CTRL, - .bit_idx = 8, - }, - .hw.init = &(struct clk_init_data) { - .name = "vapb", - .ops = &clk_regmap_gate_ops, - .parent_hws = (const struct clk_hw *[]) { - &vapb_div.hw - }, - .num_parents = 1, - .flags = CLK_SET_RATE_PARENT, - }, -}; - -static struct clk_hw *c3_periphs_hw_clks[] = { - [CLKID_RTC_XTAL_CLKIN] = &rtc_xtal_clkin.hw, - [CLKID_RTC_32K_DIV] = &rtc_32k_div.hw, - [CLKID_RTC_32K_MUX] = &rtc_32k_mux.hw, - [CLKID_RTC_32K] = &rtc_32k.hw, - [CLKID_RTC_CLK] = &rtc_clk.hw, - [CLKID_SYS_RESET_CTRL] = &sys_reset_ctrl.hw, - [CLKID_SYS_PWR_CTRL] = &sys_pwr_ctrl.hw, - [CLKID_SYS_PAD_CTRL] = &sys_pad_ctrl.hw, - [CLKID_SYS_CTRL] = &sys_ctrl.hw, - [CLKID_SYS_TS_PLL] = &sys_ts_pll.hw, - [CLKID_SYS_DEV_ARB] = &sys_dev_arb.hw, - [CLKID_SYS_MMC_PCLK] = &sys_mmc_pclk.hw, - [CLKID_SYS_CPU_CTRL] = &sys_cpu_ctrl.hw, - [CLKID_SYS_JTAG_CTRL] = &sys_jtag_ctrl.hw, - [CLKID_SYS_IR_CTRL] = &sys_ir_ctrl.hw, - [CLKID_SYS_IRQ_CTRL] = &sys_irq_ctrl.hw, - [CLKID_SYS_MSR_CLK] = &sys_msr_clk.hw, - [CLKID_SYS_ROM] = &sys_rom.hw, - [CLKID_SYS_UART_F] = &sys_uart_f.hw, - [CLKID_SYS_CPU_ARB] = &sys_cpu_apb.hw, - [CLKID_SYS_RSA] = &sys_rsa.hw, - [CLKID_SYS_SAR_ADC] = &sys_sar_adc.hw, - [CLKID_SYS_STARTUP] = &sys_startup.hw, - [CLKID_SYS_SECURE] = &sys_secure.hw, - [CLKID_SYS_SPIFC] = &sys_spifc.hw, - [CLKID_SYS_NNA] = &sys_nna.hw, - [CLKID_SYS_ETH_MAC] = &sys_eth_mac.hw, - [CLKID_SYS_GIC] = &sys_gic.hw, - [CLKID_SYS_RAMA] = &sys_rama.hw, - [CLKID_SYS_BIG_NIC] = &sys_big_nic.hw, - [CLKID_SYS_RAMB] = &sys_ramb.hw, - [CLKID_SYS_AUDIO_PCLK] = &sys_audio_pclk.hw, - [CLKID_SYS_PWM_KL] = &sys_pwm_kl.hw, - [CLKID_SYS_PWM_IJ] = &sys_pwm_ij.hw, - [CLKID_SYS_USB] = &sys_usb.hw, - [CLKID_SYS_SD_EMMC_A] = &sys_sd_emmc_a.hw, - [CLKID_SYS_SD_EMMC_C] = &sys_sd_emmc_c.hw, - [CLKID_SYS_PWM_AB] = &sys_pwm_ab.hw, - [CLKID_SYS_PWM_CD] = &sys_pwm_cd.hw, - [CLKID_SYS_PWM_EF] = &sys_pwm_ef.hw, - [CLKID_SYS_PWM_GH] = &sys_pwm_gh.hw, - [CLKID_SYS_SPICC_1] = &sys_spicc_1.hw, - [CLKID_SYS_SPICC_0] = &sys_spicc_0.hw, - [CLKID_SYS_UART_A] = &sys_uart_a.hw, - [CLKID_SYS_UART_B] = &sys_uart_b.hw, - [CLKID_SYS_UART_C] = &sys_uart_c.hw, - [CLKID_SYS_UART_D] = &sys_uart_d.hw, - [CLKID_SYS_UART_E] = &sys_uart_e.hw, - [CLKID_SYS_I2C_M_A] = &sys_i2c_m_a.hw, - [CLKID_SYS_I2C_M_B] = &sys_i2c_m_b.hw, - [CLKID_SYS_I2C_M_C] = &sys_i2c_m_c.hw, - [CLKID_SYS_I2C_M_D] = &sys_i2c_m_d.hw, - [CLKID_SYS_I2S_S_A] = &sys_i2c_s_a.hw, - [CLKID_SYS_RTC] = &sys_rtc.hw, - [CLKID_SYS_GE2D] = &sys_ge2d.hw, - [CLKID_SYS_ISP] = &sys_isp.hw, - [CLKID_SYS_GPV_ISP_NIC] = &sys_gpv_isp_nic.hw, - [CLKID_SYS_GPV_CVE_NIC] = &sys_gpv_cve_nic.hw, - [CLKID_SYS_MIPI_DSI_HOST] = &sys_mipi_dsi_host.hw, - [CLKID_SYS_MIPI_DSI_PHY] = &sys_mipi_dsi_phy.hw, - [CLKID_SYS_ETH_PHY] = &sys_eth_phy.hw, - [CLKID_SYS_ACODEC] = &sys_acodec.hw, - [CLKID_SYS_DWAP] = &sys_dwap.hw, - [CLKID_SYS_DOS] = &sys_dos.hw, - [CLKID_SYS_CVE] = &sys_cve.hw, - [CLKID_SYS_VOUT] = &sys_vout.hw, - [CLKID_SYS_VC9000E] = &sys_vc9000e.hw, - [CLKID_SYS_PWM_MN] = &sys_pwm_mn.hw, - [CLKID_SYS_SD_EMMC_B] = &sys_sd_emmc_b.hw, - [CLKID_AXI_SYS_NIC] = &axi_sys_nic.hw, - [CLKID_AXI_ISP_NIC] = &axi_isp_nic.hw, - [CLKID_AXI_CVE_NIC] = &axi_cve_nic.hw, - [CLKID_AXI_RAMB] = &axi_ramb.hw, - [CLKID_AXI_RAMA] = &axi_rama.hw, - [CLKID_AXI_CPU_DMC] = &axi_cpu_dmc.hw, - [CLKID_AXI_NIC] = &axi_nic.hw, - [CLKID_AXI_DMA] = &axi_dma.hw, - [CLKID_AXI_MUX_NIC] = &axi_mux_nic.hw, - [CLKID_AXI_CVE] = &axi_cve.hw, - [CLKID_AXI_DEV1_DMC] = &axi_dev1_dmc.hw, - [CLKID_AXI_DEV0_DMC] = &axi_dev0_dmc.hw, - [CLKID_AXI_DSP_DMC] = &axi_dsp_dmc.hw, - [CLKID_12_24M_IN] = &clk_12_24m_in.hw, - [CLKID_12M_24M] = &clk_12_24m.hw, - [CLKID_FCLK_25M_DIV] = &fclk_25m_div.hw, - [CLKID_FCLK_25M] = &fclk_25m.hw, - [CLKID_GEN_SEL] = &gen_sel.hw, - [CLKID_GEN_DIV] = &gen_div.hw, - [CLKID_GEN] = &gen.hw, - [CLKID_SARADC_SEL] = &saradc_sel.hw, - [CLKID_SARADC_DIV] = &saradc_div.hw, - [CLKID_SARADC] = &saradc.hw, - [CLKID_PWM_A_SEL] = &pwm_a_sel.hw, - [CLKID_PWM_A_DIV] = &pwm_a_div.hw, - [CLKID_PWM_A] = &pwm_a.hw, - [CLKID_PWM_B_SEL] = &pwm_b_sel.hw, - [CLKID_PWM_B_DIV] = &pwm_b_div.hw, - [CLKID_PWM_B] = &pwm_b.hw, - [CLKID_PWM_C_SEL] = &pwm_c_sel.hw, - [CLKID_PWM_C_DIV] = &pwm_c_div.hw, - [CLKID_PWM_C] = &pwm_c.hw, - [CLKID_PWM_D_SEL] = &pwm_d_sel.hw, - [CLKID_PWM_D_DIV] = &pwm_d_div.hw, - [CLKID_PWM_D] = &pwm_d.hw, - [CLKID_PWM_E_SEL] = &pwm_e_sel.hw, - [CLKID_PWM_E_DIV] = &pwm_e_div.hw, - [CLKID_PWM_E] = &pwm_e.hw, - [CLKID_PWM_F_SEL] = &pwm_f_sel.hw, - [CLKID_PWM_F_DIV] = &pwm_f_div.hw, - [CLKID_PWM_F] = &pwm_f.hw, - [CLKID_PWM_G_SEL] = &pwm_g_sel.hw, - [CLKID_PWM_G_DIV] = &pwm_g_div.hw, - [CLKID_PWM_G] = &pwm_g.hw, - [CLKID_PWM_H_SEL] = &pwm_h_sel.hw, - [CLKID_PWM_H_DIV] = &pwm_h_div.hw, - [CLKID_PWM_H] = &pwm_h.hw, - [CLKID_PWM_I_SEL] = &pwm_i_sel.hw, - [CLKID_PWM_I_DIV] = &pwm_i_div.hw, - [CLKID_PWM_I] = &pwm_i.hw, - [CLKID_PWM_J_SEL] = &pwm_j_sel.hw, - [CLKID_PWM_J_DIV] = &pwm_j_div.hw, - [CLKID_PWM_J] = &pwm_j.hw, - [CLKID_PWM_K_SEL] = &pwm_k_sel.hw, - [CLKID_PWM_K_DIV] = &pwm_k_div.hw, - [CLKID_PWM_K] = &pwm_k.hw, - [CLKID_PWM_L_SEL] = &pwm_l_sel.hw, - [CLKID_PWM_L_DIV] = &pwm_l_div.hw, - [CLKID_PWM_L] = &pwm_l.hw, - [CLKID_PWM_M_SEL] = &pwm_m_sel.hw, - [CLKID_PWM_M_DIV] = &pwm_m_div.hw, - [CLKID_PWM_M] = &pwm_m.hw, - [CLKID_PWM_N_SEL] = &pwm_n_sel.hw, - [CLKID_PWM_N_DIV] = &pwm_n_div.hw, - [CLKID_PWM_N] = &pwm_n.hw, - [CLKID_SPICC_A_SEL] = &spicc_a_sel.hw, - [CLKID_SPICC_A_DIV] = &spicc_a_div.hw, - [CLKID_SPICC_A] = &spicc_a.hw, - [CLKID_SPICC_B_SEL] = &spicc_b_sel.hw, - [CLKID_SPICC_B_DIV] = &spicc_b_div.hw, - [CLKID_SPICC_B] = &spicc_b.hw, - [CLKID_SPIFC_SEL] = &spifc_sel.hw, - [CLKID_SPIFC_DIV] = &spifc_div.hw, - [CLKID_SPIFC] = &spifc.hw, - [CLKID_SD_EMMC_A_SEL] = &sd_emmc_a_sel.hw, - [CLKID_SD_EMMC_A_DIV] = &sd_emmc_a_div.hw, - [CLKID_SD_EMMC_A] = &sd_emmc_a.hw, - [CLKID_SD_EMMC_B_SEL] = &sd_emmc_b_sel.hw, - [CLKID_SD_EMMC_B_DIV] = &sd_emmc_b_div.hw, - [CLKID_SD_EMMC_B] = &sd_emmc_b.hw, - [CLKID_SD_EMMC_C_SEL] = &sd_emmc_c_sel.hw, - [CLKID_SD_EMMC_C_DIV] = &sd_emmc_c_div.hw, - [CLKID_SD_EMMC_C] = &sd_emmc_c.hw, - [CLKID_TS_DIV] = &ts_div.hw, - [CLKID_TS] = &ts.hw, - [CLKID_ETH_125M_DIV] = ð_125m_div.hw, - [CLKID_ETH_125M] = ð_125m.hw, - [CLKID_ETH_RMII_DIV] = ð_rmii_div.hw, - [CLKID_ETH_RMII] = ð_rmii.hw, - [CLKID_MIPI_DSI_MEAS_SEL] = &mipi_dsi_meas_sel.hw, - [CLKID_MIPI_DSI_MEAS_DIV] = &mipi_dsi_meas_div.hw, - [CLKID_MIPI_DSI_MEAS] = &mipi_dsi_meas.hw, - [CLKID_DSI_PHY_SEL] = &dsi_phy_sel.hw, - [CLKID_DSI_PHY_DIV] = &dsi_phy_div.hw, - [CLKID_DSI_PHY] = &dsi_phy.hw, - [CLKID_VOUT_MCLK_SEL] = &vout_mclk_sel.hw, - [CLKID_VOUT_MCLK_DIV] = &vout_mclk_div.hw, - [CLKID_VOUT_MCLK] = &vout_mclk.hw, - [CLKID_VOUT_ENC_SEL] = &vout_enc_sel.hw, - [CLKID_VOUT_ENC_DIV] = &vout_enc_div.hw, - [CLKID_VOUT_ENC] = &vout_enc.hw, - [CLKID_HCODEC_0_SEL] = &hcodec_0_sel.hw, - [CLKID_HCODEC_0_DIV] = &hcodec_0_div.hw, - [CLKID_HCODEC_0] = &hcodec_0.hw, - [CLKID_HCODEC_1_SEL] = &hcodec_1_sel.hw, - [CLKID_HCODEC_1_DIV] = &hcodec_1_div.hw, - [CLKID_HCODEC_1] = &hcodec_1.hw, - [CLKID_HCODEC] = &hcodec.hw, - [CLKID_VC9000E_ACLK_SEL] = &vc9000e_aclk_sel.hw, - [CLKID_VC9000E_ACLK_DIV] = &vc9000e_aclk_div.hw, - [CLKID_VC9000E_ACLK] = &vc9000e_aclk.hw, - [CLKID_VC9000E_CORE_SEL] = &vc9000e_core_sel.hw, - [CLKID_VC9000E_CORE_DIV] = &vc9000e_core_div.hw, - [CLKID_VC9000E_CORE] = &vc9000e_core.hw, - [CLKID_CSI_PHY0_SEL] = &csi_phy0_sel.hw, - [CLKID_CSI_PHY0_DIV] = &csi_phy0_div.hw, - [CLKID_CSI_PHY0] = &csi_phy0.hw, - [CLKID_DEWARPA_SEL] = &dewarpa_sel.hw, - [CLKID_DEWARPA_DIV] = &dewarpa_div.hw, - [CLKID_DEWARPA] = &dewarpa.hw, - [CLKID_ISP0_SEL] = &isp0_sel.hw, - [CLKID_ISP0_DIV] = &isp0_div.hw, - [CLKID_ISP0] = &isp0.hw, - [CLKID_NNA_CORE_SEL] = &nna_core_sel.hw, - [CLKID_NNA_CORE_DIV] = &nna_core_div.hw, - [CLKID_NNA_CORE] = &nna_core.hw, - [CLKID_GE2D_SEL] = &ge2d_sel.hw, - [CLKID_GE2D_DIV] = &ge2d_div.hw, - [CLKID_GE2D] = &ge2d.hw, - [CLKID_VAPB_SEL] = &vapb_sel.hw, - [CLKID_VAPB_DIV] = &vapb_div.hw, - [CLKID_VAPB] = &vapb.hw, -}; - -static const struct regmap_config clkc_regmap_config = { - .reg_bits = 32, - .val_bits = 32, - .reg_stride = 4, - .max_register = NNA_CLK_CTRL, -}; - -static struct meson_clk_hw_data c3_periphs_clks = { - .hws = c3_periphs_hw_clks, - .num = ARRAY_SIZE(c3_periphs_hw_clks), -}; - -static int c3_peripherals_probe(struct platform_device *pdev) -{ - struct device *dev = &pdev->dev; - struct regmap *regmap; - void __iomem *base; - int clkid, ret; - - base = devm_platform_ioremap_resource(pdev, 0); - if (IS_ERR(base)) - return PTR_ERR(base); - - regmap = devm_regmap_init_mmio(dev, base, &clkc_regmap_config); - if (IS_ERR(regmap)) - return PTR_ERR(regmap); - - for (clkid = 0; clkid < c3_periphs_clks.num; clkid++) { - /* array might be sparse */ - if (!c3_periphs_clks.hws[clkid]) - continue; - - ret = devm_clk_hw_register(dev, c3_periphs_clks.hws[clkid]); - if (ret) { - dev_err(dev, "Clock registration failed\n"); - return ret; - } - } - - return devm_of_clk_add_hw_provider(dev, meson_clk_hw_get, - &c3_periphs_clks); -} - static const struct of_device_id c3_peripherals_clkc_match_table[] = { { .compatible = "amlogic,c3-peripherals-clkc", + .data = &c3_peripherals_clkc_data, }, { /* sentinel */ } }; MODULE_DEVICE_TABLE(of, c3_peripherals_clkc_match_table); -static struct platform_driver c3_peripherals_driver = { - .probe = c3_peripherals_probe, +static struct platform_driver c3_peripherals_clkc_driver = { + .probe = meson_clkc_mmio_probe, .driver = { .name = "c3-peripherals-clkc", .of_match_table = c3_peripherals_clkc_match_table, }, }; -module_platform_driver(c3_peripherals_driver); +module_platform_driver(c3_peripherals_clkc_driver); MODULE_DESCRIPTION("Amlogic C3 Peripherals Clock Controller driver"); MODULE_AUTHOR("Chuan Liu <chuan.liu@amlogic.com>"); diff --git a/drivers/clk/meson/c3-pll.c b/drivers/clk/meson/c3-pll.c index 2c5594b8e49a..dd047d17488c 100644 --- a/drivers/clk/meson/c3-pll.c +++ b/drivers/clk/meson/c3-pll.c @@ -34,7 +34,7 @@ #define ANACTRL_MPLL_CTRL3 0x18c #define ANACTRL_MPLL_CTRL4 0x190 -static struct clk_regmap fclk_50m_en = { +static struct clk_regmap c3_fclk_50m_en = { .data = &(struct clk_regmap_gate_data) { .offset = ANACTRL_FIXPLL_CTRL4, .bit_idx = 0, @@ -49,20 +49,20 @@ static struct clk_regmap fclk_50m_en = { }, }; -static struct clk_fixed_factor fclk_50m = { +static struct clk_fixed_factor c3_fclk_50m = { .mult = 1, .div = 40, .hw.init = &(struct clk_init_data) { .name = "fclk_50m", .ops = &clk_fixed_factor_ops, .parent_hws = (const struct clk_hw *[]) { - &fclk_50m_en.hw + &c3_fclk_50m_en.hw }, .num_parents = 1, }, }; -static struct clk_fixed_factor fclk_div2_div = { +static struct clk_fixed_factor c3_fclk_div2_div = { .mult = 1, .div = 2, .hw.init = &(struct clk_init_data) { @@ -75,7 +75,7 @@ static struct clk_fixed_factor fclk_div2_div = { }, }; -static struct clk_regmap fclk_div2 = { +static struct clk_regmap c3_fclk_div2 = { .data = &(struct clk_regmap_gate_data) { .offset = ANACTRL_FIXPLL_CTRL4, .bit_idx = 24, @@ -84,13 +84,13 @@ static struct clk_regmap fclk_div2 = { .name = "fclk_div2", .ops = &clk_regmap_gate_ro_ops, .parent_hws = (const struct clk_hw *[]) { - &fclk_div2_div.hw + &c3_fclk_div2_div.hw }, .num_parents = 1, }, }; -static struct clk_fixed_factor fclk_div2p5_div = { +static struct clk_fixed_factor c3_fclk_div2p5_div = { .mult = 2, .div = 5, .hw.init = &(struct clk_init_data) { @@ -103,7 +103,7 @@ static struct clk_fixed_factor fclk_div2p5_div = { }, }; -static struct clk_regmap fclk_div2p5 = { +static struct clk_regmap c3_fclk_div2p5 = { .data = &(struct clk_regmap_gate_data) { .offset = ANACTRL_FIXPLL_CTRL4, .bit_idx = 4, @@ -112,13 +112,13 @@ static struct clk_regmap fclk_div2p5 = { .name = "fclk_div2p5", .ops = &clk_regmap_gate_ro_ops, .parent_hws = (const struct clk_hw *[]) { - &fclk_div2p5_div.hw + &c3_fclk_div2p5_div.hw }, .num_parents = 1, }, }; -static struct clk_fixed_factor fclk_div3_div = { +static struct clk_fixed_factor c3_fclk_div3_div = { .mult = 1, .div = 3, .hw.init = &(struct clk_init_data) { @@ -131,7 +131,7 @@ static struct clk_fixed_factor fclk_div3_div = { }, }; -static struct clk_regmap fclk_div3 = { +static struct clk_regmap c3_fclk_div3 = { .data = &(struct clk_regmap_gate_data) { .offset = ANACTRL_FIXPLL_CTRL4, .bit_idx = 20, @@ -140,13 +140,13 @@ static struct clk_regmap fclk_div3 = { .name = "fclk_div3", .ops = &clk_regmap_gate_ro_ops, .parent_hws = (const struct clk_hw *[]) { - &fclk_div3_div.hw + &c3_fclk_div3_div.hw }, .num_parents = 1, }, }; -static struct clk_fixed_factor fclk_div4_div = { +static struct clk_fixed_factor c3_fclk_div4_div = { .mult = 1, .div = 4, .hw.init = &(struct clk_init_data) { @@ -159,7 +159,7 @@ static struct clk_fixed_factor fclk_div4_div = { }, }; -static struct clk_regmap fclk_div4 = { +static struct clk_regmap c3_fclk_div4 = { .data = &(struct clk_regmap_gate_data) { .offset = ANACTRL_FIXPLL_CTRL4, .bit_idx = 21, @@ -168,13 +168,13 @@ static struct clk_regmap fclk_div4 = { .name = "fclk_div4", .ops = &clk_regmap_gate_ro_ops, .parent_hws = (const struct clk_hw *[]) { - &fclk_div4_div.hw + &c3_fclk_div4_div.hw }, .num_parents = 1, }, }; -static struct clk_fixed_factor fclk_div5_div = { +static struct clk_fixed_factor c3_fclk_div5_div = { .mult = 1, .div = 5, .hw.init = &(struct clk_init_data) { @@ -187,7 +187,7 @@ static struct clk_fixed_factor fclk_div5_div = { }, }; -static struct clk_regmap fclk_div5 = { +static struct clk_regmap c3_fclk_div5 = { .data = &(struct clk_regmap_gate_data) { .offset = ANACTRL_FIXPLL_CTRL4, .bit_idx = 22, @@ -196,13 +196,13 @@ static struct clk_regmap fclk_div5 = { .name = "fclk_div5", .ops = &clk_regmap_gate_ro_ops, .parent_hws = (const struct clk_hw *[]) { - &fclk_div5_div.hw + &c3_fclk_div5_div.hw }, .num_parents = 1, }, }; -static struct clk_fixed_factor fclk_div7_div = { +static struct clk_fixed_factor c3_fclk_div7_div = { .mult = 1, .div = 7, .hw.init = &(struct clk_init_data) { @@ -215,7 +215,7 @@ static struct clk_fixed_factor fclk_div7_div = { }, }; -static struct clk_regmap fclk_div7 = { +static struct clk_regmap c3_fclk_div7 = { .data = &(struct clk_regmap_gate_data) { .offset = ANACTRL_FIXPLL_CTRL4, .bit_idx = 23, @@ -224,13 +224,13 @@ static struct clk_regmap fclk_div7 = { .name = "fclk_div7", .ops = &clk_regmap_gate_ro_ops, .parent_hws = (const struct clk_hw *[]) { - &fclk_div7_div.hw + &c3_fclk_div7_div.hw }, .num_parents = 1, }, }; -static const struct reg_sequence c3_gp0_init_regs[] = { +static const struct reg_sequence c3_gp0_pll_init_regs[] = { { .reg = ANACTRL_GP0PLL_CTRL2, .def = 0x0 }, { .reg = ANACTRL_GP0PLL_CTRL3, .def = 0x48681c00 }, { .reg = ANACTRL_GP0PLL_CTRL4, .def = 0x88770290 }, @@ -243,7 +243,7 @@ static const struct pll_mult_range c3_gp0_pll_mult_range = { .max = 250, }; -static struct clk_regmap gp0_pll_dco = { +static struct clk_regmap c3_gp0_pll_dco = { .data = &(struct meson_clk_pll_data) { .en = { .reg_off = ANACTRL_GP0PLL_CTRL0, @@ -276,8 +276,8 @@ static struct clk_regmap gp0_pll_dco = { .width = 1, }, .range = &c3_gp0_pll_mult_range, - .init_regs = c3_gp0_init_regs, - .init_count = ARRAY_SIZE(c3_gp0_init_regs), + .init_regs = c3_gp0_pll_init_regs, + .init_count = ARRAY_SIZE(c3_gp0_pll_init_regs), }, .hw.init = &(struct clk_init_data) { .name = "gp0_pll_dco", @@ -300,7 +300,7 @@ static const struct clk_div_table c3_gp0_pll_od_table[] = { { /* sentinel */ } }; -static struct clk_regmap gp0_pll = { +static struct clk_regmap c3_gp0_pll = { .data = &(struct clk_regmap_div_data) { .offset = ANACTRL_GP0PLL_CTRL0, .shift = 16, @@ -311,14 +311,14 @@ static struct clk_regmap gp0_pll = { .name = "gp0_pll", .ops = &clk_regmap_divider_ops, .parent_hws = (const struct clk_hw *[]) { - &gp0_pll_dco.hw + &c3_gp0_pll_dco.hw }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, }; -static const struct reg_sequence c3_hifi_init_regs[] = { +static const struct reg_sequence c3_hifi_pll_init_regs[] = { { .reg = ANACTRL_HIFIPLL_CTRL2, .def = 0x0 }, { .reg = ANACTRL_HIFIPLL_CTRL3, .def = 0x6a285c00 }, { .reg = ANACTRL_HIFIPLL_CTRL4, .def = 0x65771290 }, @@ -326,7 +326,7 @@ static const struct reg_sequence c3_hifi_init_regs[] = { { .reg = ANACTRL_HIFIPLL_CTRL6, .def = 0x56540000 }, }; -static struct clk_regmap hifi_pll_dco = { +static struct clk_regmap c3_hifi_pll_dco = { .data = &(struct meson_clk_pll_data) { .en = { .reg_off = ANACTRL_HIFIPLL_CTRL0, @@ -359,8 +359,8 @@ static struct clk_regmap hifi_pll_dco = { .width = 1, }, .range = &c3_gp0_pll_mult_range, - .init_regs = c3_hifi_init_regs, - .init_count = ARRAY_SIZE(c3_hifi_init_regs), + .init_regs = c3_hifi_pll_init_regs, + .init_count = ARRAY_SIZE(c3_hifi_pll_init_regs), .frac_max = 100000, }, .hw.init = &(struct clk_init_data) { @@ -373,7 +373,7 @@ static struct clk_regmap hifi_pll_dco = { }, }; -static struct clk_regmap hifi_pll = { +static struct clk_regmap c3_hifi_pll = { .data = &(struct clk_regmap_div_data) { .offset = ANACTRL_HIFIPLL_CTRL0, .shift = 16, @@ -384,14 +384,14 @@ static struct clk_regmap hifi_pll = { .name = "hifi_pll", .ops = &clk_regmap_divider_ops, .parent_hws = (const struct clk_hw *[]) { - &hifi_pll_dco.hw + &c3_hifi_pll_dco.hw }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, }; -static const struct reg_sequence c3_mclk_init_regs[] = { +static const struct reg_sequence c3_mclk_pll_init_regs[] = { { .reg = ANACTRL_MPLL_CTRL1, .def = 0x1420500f }, { .reg = ANACTRL_MPLL_CTRL2, .def = 0x00023041 }, { .reg = ANACTRL_MPLL_CTRL3, .def = 0x18180000 }, @@ -403,7 +403,7 @@ static const struct pll_mult_range c3_mclk_pll_mult_range = { .max = 133, }; -static struct clk_regmap mclk_pll_dco = { +static struct clk_regmap c3_mclk_pll_dco = { .data = &(struct meson_clk_pll_data) { .en = { .reg_off = ANACTRL_MPLL_CTRL0, @@ -431,8 +431,8 @@ static struct clk_regmap mclk_pll_dco = { .width = 1, }, .range = &c3_mclk_pll_mult_range, - .init_regs = c3_mclk_init_regs, - .init_count = ARRAY_SIZE(c3_mclk_init_regs), + .init_regs = c3_mclk_pll_init_regs, + .init_count = ARRAY_SIZE(c3_mclk_pll_init_regs), }, .hw.init = &(struct clk_init_data) { .name = "mclk_pll_dco", @@ -444,7 +444,7 @@ static struct clk_regmap mclk_pll_dco = { }, }; -static const struct clk_div_table c3_mpll_od_table[] = { +static const struct clk_div_table c3_mpll_pll_od_table[] = { { 0, 1 }, { 1, 2 }, { 2, 4 }, @@ -453,25 +453,25 @@ static const struct clk_div_table c3_mpll_od_table[] = { { /* sentinel */ } }; -static struct clk_regmap mclk_pll_od = { +static struct clk_regmap c3_mclk_pll_od = { .data = &(struct clk_regmap_div_data) { .offset = ANACTRL_MPLL_CTRL0, .shift = 12, .width = 3, - .table = c3_mpll_od_table, + .table = c3_mpll_pll_od_table, }, .hw.init = &(struct clk_init_data) { .name = "mclk_pll_od", .ops = &clk_regmap_divider_ops, .parent_hws = (const struct clk_hw *[]) { - &mclk_pll_dco.hw }, + &c3_mclk_pll_dco.hw }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, }; /* both value 0 and 1 gives divide the input rate by one */ -static struct clk_regmap mclk_pll = { +static struct clk_regmap c3_mclk_pll = { .data = &(struct clk_regmap_div_data) { .offset = ANACTRL_MPLL_CTRL4, .shift = 16, @@ -482,20 +482,20 @@ static struct clk_regmap mclk_pll = { .name = "mclk_pll", .ops = &clk_regmap_divider_ops, .parent_hws = (const struct clk_hw *[]) { - &mclk_pll_od.hw + &c3_mclk_pll_od.hw }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, }; -static const struct clk_parent_data mclk_parent[] = { - { .hw = &mclk_pll.hw }, +static const struct clk_parent_data c3_mclk_parents[] = { + { .hw = &c3_mclk_pll.hw }, { .fw_name = "mclk" }, - { .hw = &fclk_50m.hw } + { .hw = &c3_fclk_50m.hw } }; -static struct clk_regmap mclk0_sel = { +static struct clk_regmap c3_mclk0_sel = { .data = &(struct clk_regmap_mux_data) { .offset = ANACTRL_MPLL_CTRL4, .mask = 0x3, @@ -504,12 +504,12 @@ static struct clk_regmap mclk0_sel = { .hw.init = &(struct clk_init_data) { .name = "mclk0_sel", .ops = &clk_regmap_mux_ops, - .parent_data = mclk_parent, - .num_parents = ARRAY_SIZE(mclk_parent), + .parent_data = c3_mclk_parents, + .num_parents = ARRAY_SIZE(c3_mclk_parents), }, }; -static struct clk_regmap mclk0_div_en = { +static struct clk_regmap c3_mclk0_div_en = { .data = &(struct clk_regmap_gate_data) { .offset = ANACTRL_MPLL_CTRL4, .bit_idx = 1, @@ -518,14 +518,14 @@ static struct clk_regmap mclk0_div_en = { .name = "mclk0_div_en", .ops = &clk_regmap_gate_ops, .parent_hws = (const struct clk_hw *[]) { - &mclk0_sel.hw + &c3_mclk0_sel.hw }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, }; -static struct clk_regmap mclk0_div = { +static struct clk_regmap c3_mclk0_div = { .data = &(struct clk_regmap_div_data) { .offset = ANACTRL_MPLL_CTRL4, .shift = 2, @@ -535,14 +535,14 @@ static struct clk_regmap mclk0_div = { .name = "mclk0_div", .ops = &clk_regmap_divider_ops, .parent_hws = (const struct clk_hw *[]) { - &mclk0_div_en.hw + &c3_mclk0_div_en.hw }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, }; -static struct clk_regmap mclk0 = { +static struct clk_regmap c3_mclk0 = { .data = &(struct clk_regmap_gate_data) { .offset = ANACTRL_MPLL_CTRL4, .bit_idx = 0, @@ -551,14 +551,14 @@ static struct clk_regmap mclk0 = { .name = "mclk0", .ops = &clk_regmap_gate_ops, .parent_hws = (const struct clk_hw *[]) { - &mclk0_div.hw + &c3_mclk0_div.hw }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, }; -static struct clk_regmap mclk1_sel = { +static struct clk_regmap c3_mclk1_sel = { .data = &(struct clk_regmap_mux_data) { .offset = ANACTRL_MPLL_CTRL4, .mask = 0x3, @@ -567,12 +567,12 @@ static struct clk_regmap mclk1_sel = { .hw.init = &(struct clk_init_data) { .name = "mclk1_sel", .ops = &clk_regmap_mux_ops, - .parent_data = mclk_parent, - .num_parents = ARRAY_SIZE(mclk_parent), + .parent_data = c3_mclk_parents, + .num_parents = ARRAY_SIZE(c3_mclk_parents), }, }; -static struct clk_regmap mclk1_div_en = { +static struct clk_regmap c3_mclk1_div_en = { .data = &(struct clk_regmap_gate_data) { .offset = ANACTRL_MPLL_CTRL4, .bit_idx = 9, @@ -581,14 +581,14 @@ static struct clk_regmap mclk1_div_en = { .name = "mclk1_div_en", .ops = &clk_regmap_gate_ops, .parent_hws = (const struct clk_hw *[]) { - &mclk1_sel.hw + &c3_mclk1_sel.hw }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, }; -static struct clk_regmap mclk1_div = { +static struct clk_regmap c3_mclk1_div = { .data = &(struct clk_regmap_div_data) { .offset = ANACTRL_MPLL_CTRL4, .shift = 10, @@ -598,14 +598,14 @@ static struct clk_regmap mclk1_div = { .name = "mclk1_div", .ops = &clk_regmap_divider_ops, .parent_hws = (const struct clk_hw *[]) { - &mclk1_div_en.hw + &c3_mclk1_div_en.hw }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, }; -static struct clk_regmap mclk1 = { +static struct clk_regmap c3_mclk1 = { .data = &(struct clk_regmap_gate_data) { .offset = ANACTRL_MPLL_CTRL4, .bit_idx = 8, @@ -614,7 +614,7 @@ static struct clk_regmap mclk1 = { .name = "mclk1", .ops = &clk_regmap_gate_ops, .parent_hws = (const struct clk_hw *[]) { - &mclk1_div.hw + &c3_mclk1_div.hw }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, @@ -622,96 +622,61 @@ static struct clk_regmap mclk1 = { }; static struct clk_hw *c3_pll_hw_clks[] = { - [CLKID_FCLK_50M_EN] = &fclk_50m_en.hw, - [CLKID_FCLK_50M] = &fclk_50m.hw, - [CLKID_FCLK_DIV2_DIV] = &fclk_div2_div.hw, - [CLKID_FCLK_DIV2] = &fclk_div2.hw, - [CLKID_FCLK_DIV2P5_DIV] = &fclk_div2p5_div.hw, - [CLKID_FCLK_DIV2P5] = &fclk_div2p5.hw, - [CLKID_FCLK_DIV3_DIV] = &fclk_div3_div.hw, - [CLKID_FCLK_DIV3] = &fclk_div3.hw, - [CLKID_FCLK_DIV4_DIV] = &fclk_div4_div.hw, - [CLKID_FCLK_DIV4] = &fclk_div4.hw, - [CLKID_FCLK_DIV5_DIV] = &fclk_div5_div.hw, - [CLKID_FCLK_DIV5] = &fclk_div5.hw, - [CLKID_FCLK_DIV7_DIV] = &fclk_div7_div.hw, - [CLKID_FCLK_DIV7] = &fclk_div7.hw, - [CLKID_GP0_PLL_DCO] = &gp0_pll_dco.hw, - [CLKID_GP0_PLL] = &gp0_pll.hw, - [CLKID_HIFI_PLL_DCO] = &hifi_pll_dco.hw, - [CLKID_HIFI_PLL] = &hifi_pll.hw, - [CLKID_MCLK_PLL_DCO] = &mclk_pll_dco.hw, - [CLKID_MCLK_PLL_OD] = &mclk_pll_od.hw, - [CLKID_MCLK_PLL] = &mclk_pll.hw, - [CLKID_MCLK0_SEL] = &mclk0_sel.hw, - [CLKID_MCLK0_SEL_EN] = &mclk0_div_en.hw, - [CLKID_MCLK0_DIV] = &mclk0_div.hw, - [CLKID_MCLK0] = &mclk0.hw, - [CLKID_MCLK1_SEL] = &mclk1_sel.hw, - [CLKID_MCLK1_SEL_EN] = &mclk1_div_en.hw, - [CLKID_MCLK1_DIV] = &mclk1_div.hw, - [CLKID_MCLK1] = &mclk1.hw -}; - -static const struct regmap_config clkc_regmap_config = { - .reg_bits = 32, - .val_bits = 32, - .reg_stride = 4, - .max_register = ANACTRL_MPLL_CTRL4, -}; - -static struct meson_clk_hw_data c3_pll_clks = { - .hws = c3_pll_hw_clks, - .num = ARRAY_SIZE(c3_pll_hw_clks), -}; - -static int c3_pll_probe(struct platform_device *pdev) -{ - struct device *dev = &pdev->dev; - struct regmap *regmap; - void __iomem *base; - int clkid, ret; - - base = devm_platform_ioremap_resource(pdev, 0); - if (IS_ERR(base)) - return PTR_ERR(base); - - regmap = devm_regmap_init_mmio(dev, base, &clkc_regmap_config); - if (IS_ERR(regmap)) - return PTR_ERR(regmap); - - for (clkid = 0; clkid < c3_pll_clks.num; clkid++) { - /* array might be sparse */ - if (!c3_pll_clks.hws[clkid]) - continue; - - ret = devm_clk_hw_register(dev, c3_pll_clks.hws[clkid]); - if (ret) { - dev_err(dev, "Clock registration failed\n"); - return ret; - } - } - - return devm_of_clk_add_hw_provider(dev, meson_clk_hw_get, - &c3_pll_clks); -} + [CLKID_FCLK_50M_EN] = &c3_fclk_50m_en.hw, + [CLKID_FCLK_50M] = &c3_fclk_50m.hw, + [CLKID_FCLK_DIV2_DIV] = &c3_fclk_div2_div.hw, + [CLKID_FCLK_DIV2] = &c3_fclk_div2.hw, + [CLKID_FCLK_DIV2P5_DIV] = &c3_fclk_div2p5_div.hw, + [CLKID_FCLK_DIV2P5] = &c3_fclk_div2p5.hw, + [CLKID_FCLK_DIV3_DIV] = &c3_fclk_div3_div.hw, + [CLKID_FCLK_DIV3] = &c3_fclk_div3.hw, + [CLKID_FCLK_DIV4_DIV] = &c3_fclk_div4_div.hw, + [CLKID_FCLK_DIV4] = &c3_fclk_div4.hw, + [CLKID_FCLK_DIV5_DIV] = &c3_fclk_div5_div.hw, + [CLKID_FCLK_DIV5] = &c3_fclk_div5.hw, + [CLKID_FCLK_DIV7_DIV] = &c3_fclk_div7_div.hw, + [CLKID_FCLK_DIV7] = &c3_fclk_div7.hw, + [CLKID_GP0_PLL_DCO] = &c3_gp0_pll_dco.hw, + [CLKID_GP0_PLL] = &c3_gp0_pll.hw, + [CLKID_HIFI_PLL_DCO] = &c3_hifi_pll_dco.hw, + [CLKID_HIFI_PLL] = &c3_hifi_pll.hw, + [CLKID_MCLK_PLL_DCO] = &c3_mclk_pll_dco.hw, + [CLKID_MCLK_PLL_OD] = &c3_mclk_pll_od.hw, + [CLKID_MCLK_PLL] = &c3_mclk_pll.hw, + [CLKID_MCLK0_SEL] = &c3_mclk0_sel.hw, + [CLKID_MCLK0_SEL_EN] = &c3_mclk0_div_en.hw, + [CLKID_MCLK0_DIV] = &c3_mclk0_div.hw, + [CLKID_MCLK0] = &c3_mclk0.hw, + [CLKID_MCLK1_SEL] = &c3_mclk1_sel.hw, + [CLKID_MCLK1_SEL_EN] = &c3_mclk1_div_en.hw, + [CLKID_MCLK1_DIV] = &c3_mclk1_div.hw, + [CLKID_MCLK1] = &c3_mclk1.hw +}; + +static const struct meson_clkc_data c3_pll_clkc_data = { + .hw_clks = { + .hws = c3_pll_hw_clks, + .num = ARRAY_SIZE(c3_pll_hw_clks), + }, +}; static const struct of_device_id c3_pll_clkc_match_table[] = { { .compatible = "amlogic,c3-pll-clkc", + .data = &c3_pll_clkc_data, }, {} }; MODULE_DEVICE_TABLE(of, c3_pll_clkc_match_table); -static struct platform_driver c3_pll_driver = { - .probe = c3_pll_probe, +static struct platform_driver c3_pll_clkc_driver = { + .probe = meson_clkc_mmio_probe, .driver = { .name = "c3-pll-clkc", .of_match_table = c3_pll_clkc_match_table, }, }; -module_platform_driver(c3_pll_driver); +module_platform_driver(c3_pll_clkc_driver); MODULE_DESCRIPTION("Amlogic C3 PLL Clock Controller driver"); MODULE_AUTHOR("Chuan Liu <chuan.liu@amlogic.com>"); diff --git a/drivers/clk/meson/clk-regmap.h b/drivers/clk/meson/clk-regmap.h index f8cac2df5755..8e5c39b023e1 100644 --- a/drivers/clk/meson/clk-regmap.h +++ b/drivers/clk/meson/clk-regmap.h @@ -118,24 +118,4 @@ clk_get_regmap_mux_data(struct clk_regmap *clk) extern const struct clk_ops clk_regmap_mux_ops; extern const struct clk_ops clk_regmap_mux_ro_ops; -#define __MESON_PCLK(_name, _reg, _bit, _ops, _pname) \ -struct clk_regmap _name = { \ - .data = &(struct clk_regmap_gate_data){ \ - .offset = (_reg), \ - .bit_idx = (_bit), \ - }, \ - .hw.init = &(struct clk_init_data) { \ - .name = #_name, \ - .ops = _ops, \ - .parent_hws = (const struct clk_hw *[]) { _pname }, \ - .num_parents = 1, \ - .flags = (CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED), \ - }, \ -} - -#define MESON_PCLK(_name, _reg, _bit, _pname) \ - __MESON_PCLK(_name, _reg, _bit, &clk_regmap_gate_ops, _pname) - -#define MESON_PCLK_RO(_name, _reg, _bit, _pname) \ - __MESON_PCLK(_name, _reg, _bit, &clk_regmap_gate_ro_ops, _pname) #endif /* __CLK_REGMAP_H */ diff --git a/drivers/clk/meson/g12a-aoclk.c b/drivers/clk/meson/g12a-aoclk.c index 4095a1b2bb80..96981da271fa 100644 --- a/drivers/clk/meson/g12a-aoclk.c +++ b/drivers/clk/meson/g12a-aoclk.c @@ -37,46 +37,38 @@ #define AO_RTC_ALT_CLK_CNTL0 0x94 #define AO_RTC_ALT_CLK_CNTL1 0x98 +static const struct clk_parent_data g12a_ao_pclk_parents = { .fw_name = "mpeg-clk" }; + +#define G12A_AO_PCLK(_name, _reg, _bit, _flags) \ + MESON_PCLK(g12a_ao_##_name, _reg, _bit, &g12a_ao_pclk_parents, _flags) + /* - * Like every other peripheral clock gate in Amlogic Clock drivers, - * we are using CLK_IGNORE_UNUSED here, so we keep the state of the - * bootloader. The goal is to remove this flag at some point. - * Actually removing it will require some extensive test to be done safely. + * NOTE: The gates below are marked with CLK_IGNORE_UNUSED for historic reasons + * Users are encouraged to test without it and submit changes to: + * - remove the flag if not necessary + * - replace the flag with something more adequate, such as CLK_IS_CRITICAL, + * if appropriate. + * - add a comment explaining why the use of CLK_IGNORE_UNUSED is desirable + * for a particular clock. */ -#define AXG_AO_GATE(_name, _reg, _bit) \ -static struct clk_regmap g12a_aoclk_##_name = { \ - .data = &(struct clk_regmap_gate_data) { \ - .offset = (_reg), \ - .bit_idx = (_bit), \ - }, \ - .hw.init = &(struct clk_init_data) { \ - .name = "g12a_ao_" #_name, \ - .ops = &clk_regmap_gate_ops, \ - .parent_data = &(const struct clk_parent_data) { \ - .fw_name = "mpeg-clk", \ - }, \ - .num_parents = 1, \ - .flags = CLK_IGNORE_UNUSED, \ - }, \ -} +static G12A_AO_PCLK(ahb, AO_CLK_GATE0, 0, CLK_IGNORE_UNUSED); +static G12A_AO_PCLK(ir_in, AO_CLK_GATE0, 1, CLK_IGNORE_UNUSED); +static G12A_AO_PCLK(i2c_m0, AO_CLK_GATE0, 2, CLK_IGNORE_UNUSED); +static G12A_AO_PCLK(i2c_s0, AO_CLK_GATE0, 3, CLK_IGNORE_UNUSED); +static G12A_AO_PCLK(uart, AO_CLK_GATE0, 4, CLK_IGNORE_UNUSED); +static G12A_AO_PCLK(prod_i2c, AO_CLK_GATE0, 5, CLK_IGNORE_UNUSED); +static G12A_AO_PCLK(uart2, AO_CLK_GATE0, 6, CLK_IGNORE_UNUSED); +static G12A_AO_PCLK(ir_out, AO_CLK_GATE0, 7, CLK_IGNORE_UNUSED); +static G12A_AO_PCLK(saradc, AO_CLK_GATE0, 8, CLK_IGNORE_UNUSED); -AXG_AO_GATE(ahb, AO_CLK_GATE0, 0); -AXG_AO_GATE(ir_in, AO_CLK_GATE0, 1); -AXG_AO_GATE(i2c_m0, AO_CLK_GATE0, 2); -AXG_AO_GATE(i2c_s0, AO_CLK_GATE0, 3); -AXG_AO_GATE(uart, AO_CLK_GATE0, 4); -AXG_AO_GATE(prod_i2c, AO_CLK_GATE0, 5); -AXG_AO_GATE(uart2, AO_CLK_GATE0, 6); -AXG_AO_GATE(ir_out, AO_CLK_GATE0, 7); -AXG_AO_GATE(saradc, AO_CLK_GATE0, 8); -AXG_AO_GATE(mailbox, AO_CLK_GATE0_SP, 0); -AXG_AO_GATE(m3, AO_CLK_GATE0_SP, 1); -AXG_AO_GATE(ahb_sram, AO_CLK_GATE0_SP, 2); -AXG_AO_GATE(rti, AO_CLK_GATE0_SP, 3); -AXG_AO_GATE(m4_fclk, AO_CLK_GATE0_SP, 4); -AXG_AO_GATE(m4_hclk, AO_CLK_GATE0_SP, 5); +static G12A_AO_PCLK(mailbox, AO_CLK_GATE0_SP, 0, CLK_IGNORE_UNUSED); +static G12A_AO_PCLK(m3, AO_CLK_GATE0_SP, 1, CLK_IGNORE_UNUSED); +static G12A_AO_PCLK(ahb_sram, AO_CLK_GATE0_SP, 2, CLK_IGNORE_UNUSED); +static G12A_AO_PCLK(rti, AO_CLK_GATE0_SP, 3, CLK_IGNORE_UNUSED); +static G12A_AO_PCLK(m4_fclk, AO_CLK_GATE0_SP, 4, CLK_IGNORE_UNUSED); +static G12A_AO_PCLK(m4_hclk, AO_CLK_GATE0_SP, 5, CLK_IGNORE_UNUSED); -static struct clk_regmap g12a_aoclk_cts_oscin = { +static struct clk_regmap g12a_ao_cts_oscin = { .data = &(struct clk_regmap_gate_data){ .offset = AO_RTI_PWR_CNTL_REG0, .bit_idx = 14, @@ -103,22 +95,22 @@ static const struct meson_clk_dualdiv_param g12a_32k_div_table[] = { /* 32k_by_oscin clock */ -static struct clk_regmap g12a_aoclk_32k_by_oscin_pre = { +static struct clk_regmap g12a_ao_32k_by_oscin_pre = { .data = &(struct clk_regmap_gate_data){ .offset = AO_RTC_ALT_CLK_CNTL0, .bit_idx = 31, }, .hw.init = &(struct clk_init_data){ - .name = "g12a_ao_32k_by_oscin_pre", + .name = "ao_32k_by_oscin_pre", .ops = &clk_regmap_gate_ops, .parent_hws = (const struct clk_hw *[]) { - &g12a_aoclk_cts_oscin.hw + &g12a_ao_cts_oscin.hw }, .num_parents = 1, }, }; -static struct clk_regmap g12a_aoclk_32k_by_oscin_div = { +static struct clk_regmap g12a_ao_32k_by_oscin_div = { .data = &(struct meson_clk_dualdiv_data){ .n1 = { .reg_off = AO_RTC_ALT_CLK_CNTL0, @@ -148,16 +140,16 @@ static struct clk_regmap g12a_aoclk_32k_by_oscin_div = { .table = g12a_32k_div_table, }, .hw.init = &(struct clk_init_data){ - .name = "g12a_ao_32k_by_oscin_div", + .name = "ao_32k_by_oscin_div", .ops = &meson_clk_dualdiv_ops, .parent_hws = (const struct clk_hw *[]) { - &g12a_aoclk_32k_by_oscin_pre.hw + &g12a_ao_32k_by_oscin_pre.hw }, .num_parents = 1, }, }; -static struct clk_regmap g12a_aoclk_32k_by_oscin_sel = { +static struct clk_regmap g12a_ao_32k_by_oscin_sel = { .data = &(struct clk_regmap_mux_data) { .offset = AO_RTC_ALT_CLK_CNTL1, .mask = 0x1, @@ -165,27 +157,27 @@ static struct clk_regmap g12a_aoclk_32k_by_oscin_sel = { .flags = CLK_MUX_ROUND_CLOSEST, }, .hw.init = &(struct clk_init_data){ - .name = "g12a_ao_32k_by_oscin_sel", + .name = "ao_32k_by_oscin_sel", .ops = &clk_regmap_mux_ops, .parent_hws = (const struct clk_hw *[]) { - &g12a_aoclk_32k_by_oscin_div.hw, - &g12a_aoclk_32k_by_oscin_pre.hw, + &g12a_ao_32k_by_oscin_div.hw, + &g12a_ao_32k_by_oscin_pre.hw, }, .num_parents = 2, .flags = CLK_SET_RATE_PARENT, }, }; -static struct clk_regmap g12a_aoclk_32k_by_oscin = { +static struct clk_regmap g12a_ao_32k_by_oscin = { .data = &(struct clk_regmap_gate_data){ .offset = AO_RTC_ALT_CLK_CNTL0, .bit_idx = 30, }, .hw.init = &(struct clk_init_data){ - .name = "g12a_ao_32k_by_oscin", + .name = "ao_32k_by_oscin", .ops = &clk_regmap_gate_ops, .parent_hws = (const struct clk_hw *[]) { - &g12a_aoclk_32k_by_oscin_sel.hw + &g12a_ao_32k_by_oscin_sel.hw }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, @@ -194,22 +186,22 @@ static struct clk_regmap g12a_aoclk_32k_by_oscin = { /* cec clock */ -static struct clk_regmap g12a_aoclk_cec_pre = { +static struct clk_regmap g12a_ao_cec_pre = { .data = &(struct clk_regmap_gate_data){ .offset = AO_CEC_CLK_CNTL_REG0, .bit_idx = 31, }, .hw.init = &(struct clk_init_data){ - .name = "g12a_ao_cec_pre", + .name = "ao_cec_pre", .ops = &clk_regmap_gate_ops, .parent_hws = (const struct clk_hw *[]) { - &g12a_aoclk_cts_oscin.hw + &g12a_ao_cts_oscin.hw }, .num_parents = 1, }, }; -static struct clk_regmap g12a_aoclk_cec_div = { +static struct clk_regmap g12a_ao_cec_div = { .data = &(struct meson_clk_dualdiv_data){ .n1 = { .reg_off = AO_CEC_CLK_CNTL_REG0, @@ -239,16 +231,16 @@ static struct clk_regmap g12a_aoclk_cec_div = { .table = g12a_32k_div_table, }, .hw.init = &(struct clk_init_data){ - .name = "g12a_ao_cec_div", + .name = "ao_cec_div", .ops = &meson_clk_dualdiv_ops, .parent_hws = (const struct clk_hw *[]) { - &g12a_aoclk_cec_pre.hw + &g12a_ao_cec_pre.hw }, .num_parents = 1, }, }; -static struct clk_regmap g12a_aoclk_cec_sel = { +static struct clk_regmap g12a_ao_cec_sel = { .data = &(struct clk_regmap_mux_data) { .offset = AO_CEC_CLK_CNTL_REG1, .mask = 0x1, @@ -256,34 +248,34 @@ static struct clk_regmap g12a_aoclk_cec_sel = { .flags = CLK_MUX_ROUND_CLOSEST, }, .hw.init = &(struct clk_init_data){ - .name = "g12a_ao_cec_sel", + .name = "ao_cec_sel", .ops = &clk_regmap_mux_ops, .parent_hws = (const struct clk_hw *[]) { - &g12a_aoclk_cec_div.hw, - &g12a_aoclk_cec_pre.hw, + &g12a_ao_cec_div.hw, + &g12a_ao_cec_pre.hw, }, .num_parents = 2, .flags = CLK_SET_RATE_PARENT, }, }; -static struct clk_regmap g12a_aoclk_cec = { +static struct clk_regmap g12a_ao_cec = { .data = &(struct clk_regmap_gate_data){ .offset = AO_CEC_CLK_CNTL_REG0, .bit_idx = 30, }, .hw.init = &(struct clk_init_data){ - .name = "g12a_ao_cec", + .name = "ao_cec", .ops = &clk_regmap_gate_ops, .parent_hws = (const struct clk_hw *[]) { - &g12a_aoclk_cec_sel.hw + &g12a_ao_cec_sel.hw }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, }; -static struct clk_regmap g12a_aoclk_cts_rtc_oscin = { +static struct clk_regmap g12a_ao_cts_rtc_oscin = { .data = &(struct clk_regmap_mux_data) { .offset = AO_RTI_PWR_CNTL_REG0, .mask = 0x1, @@ -291,10 +283,10 @@ static struct clk_regmap g12a_aoclk_cts_rtc_oscin = { .flags = CLK_MUX_ROUND_CLOSEST, }, .hw.init = &(struct clk_init_data){ - .name = "g12a_ao_cts_rtc_oscin", + .name = "ao_cts_rtc_oscin", .ops = &clk_regmap_mux_ops, .parent_data = (const struct clk_parent_data []) { - { .hw = &g12a_aoclk_32k_by_oscin.hw }, + { .hw = &g12a_ao_32k_by_oscin.hw }, { .fw_name = "ext-32k-0", }, }, .num_parents = 2, @@ -302,7 +294,7 @@ static struct clk_regmap g12a_aoclk_cts_rtc_oscin = { }, }; -static struct clk_regmap g12a_aoclk_clk81 = { +static struct clk_regmap g12a_ao_clk81 = { .data = &(struct clk_regmap_mux_data) { .offset = AO_RTI_PWR_CNTL_REG0, .mask = 0x1, @@ -310,68 +302,74 @@ static struct clk_regmap g12a_aoclk_clk81 = { .flags = CLK_MUX_ROUND_CLOSEST, }, .hw.init = &(struct clk_init_data){ + /* + * NOTE: this is one of the infamous clock the pwm driver + * can request directly by its global name. It's wrong but + * there is not much we can do about it until the support + * for the old pwm bindings is dropped + */ .name = "g12a_ao_clk81", .ops = &clk_regmap_mux_ro_ops, .parent_data = (const struct clk_parent_data []) { { .fw_name = "mpeg-clk", }, - { .hw = &g12a_aoclk_cts_rtc_oscin.hw }, + { .hw = &g12a_ao_cts_rtc_oscin.hw }, }, .num_parents = 2, .flags = CLK_SET_RATE_PARENT, }, }; -static struct clk_regmap g12a_aoclk_saradc_mux = { +static struct clk_regmap g12a_ao_saradc_mux = { .data = &(struct clk_regmap_mux_data) { .offset = AO_SAR_CLK, .mask = 0x3, .shift = 9, }, .hw.init = &(struct clk_init_data){ - .name = "g12a_ao_saradc_mux", + .name = "ao_saradc_mux", .ops = &clk_regmap_mux_ops, .parent_data = (const struct clk_parent_data []) { { .fw_name = "xtal", }, - { .hw = &g12a_aoclk_clk81.hw }, + { .hw = &g12a_ao_clk81.hw }, }, .num_parents = 2, }, }; -static struct clk_regmap g12a_aoclk_saradc_div = { +static struct clk_regmap g12a_ao_saradc_div = { .data = &(struct clk_regmap_div_data) { .offset = AO_SAR_CLK, .shift = 0, .width = 8, }, .hw.init = &(struct clk_init_data){ - .name = "g12a_ao_saradc_div", + .name = "ao_saradc_div", .ops = &clk_regmap_divider_ops, .parent_hws = (const struct clk_hw *[]) { - &g12a_aoclk_saradc_mux.hw + &g12a_ao_saradc_mux.hw }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, }; -static struct clk_regmap g12a_aoclk_saradc_gate = { +static struct clk_regmap g12a_ao_saradc_gate = { .data = &(struct clk_regmap_gate_data) { .offset = AO_SAR_CLK, .bit_idx = 8, }, .hw.init = &(struct clk_init_data){ - .name = "g12a_ao_saradc_gate", + .name = "ao_saradc_gate", .ops = &clk_regmap_gate_ops, .parent_hws = (const struct clk_hw *[]) { - &g12a_aoclk_saradc_div.hw + &g12a_ao_saradc_div.hw }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, }; -static const unsigned int g12a_aoclk_reset[] = { +static const unsigned int g12a_ao_reset[] = { [RESET_AO_IR_IN] = 16, [RESET_AO_UART] = 17, [RESET_AO_I2C_M] = 18, @@ -381,65 +379,67 @@ static const unsigned int g12a_aoclk_reset[] = { [RESET_AO_IR_OUT] = 23, }; -static struct clk_hw *g12a_aoclk_hw_clks[] = { - [CLKID_AO_AHB] = &g12a_aoclk_ahb.hw, - [CLKID_AO_IR_IN] = &g12a_aoclk_ir_in.hw, - [CLKID_AO_I2C_M0] = &g12a_aoclk_i2c_m0.hw, - [CLKID_AO_I2C_S0] = &g12a_aoclk_i2c_s0.hw, - [CLKID_AO_UART] = &g12a_aoclk_uart.hw, - [CLKID_AO_PROD_I2C] = &g12a_aoclk_prod_i2c.hw, - [CLKID_AO_UART2] = &g12a_aoclk_uart2.hw, - [CLKID_AO_IR_OUT] = &g12a_aoclk_ir_out.hw, - [CLKID_AO_SAR_ADC] = &g12a_aoclk_saradc.hw, - [CLKID_AO_MAILBOX] = &g12a_aoclk_mailbox.hw, - [CLKID_AO_M3] = &g12a_aoclk_m3.hw, - [CLKID_AO_AHB_SRAM] = &g12a_aoclk_ahb_sram.hw, - [CLKID_AO_RTI] = &g12a_aoclk_rti.hw, - [CLKID_AO_M4_FCLK] = &g12a_aoclk_m4_fclk.hw, - [CLKID_AO_M4_HCLK] = &g12a_aoclk_m4_hclk.hw, - [CLKID_AO_CLK81] = &g12a_aoclk_clk81.hw, - [CLKID_AO_SAR_ADC_SEL] = &g12a_aoclk_saradc_mux.hw, - [CLKID_AO_SAR_ADC_DIV] = &g12a_aoclk_saradc_div.hw, - [CLKID_AO_SAR_ADC_CLK] = &g12a_aoclk_saradc_gate.hw, - [CLKID_AO_CTS_OSCIN] = &g12a_aoclk_cts_oscin.hw, - [CLKID_AO_32K_PRE] = &g12a_aoclk_32k_by_oscin_pre.hw, - [CLKID_AO_32K_DIV] = &g12a_aoclk_32k_by_oscin_div.hw, - [CLKID_AO_32K_SEL] = &g12a_aoclk_32k_by_oscin_sel.hw, - [CLKID_AO_32K] = &g12a_aoclk_32k_by_oscin.hw, - [CLKID_AO_CEC_PRE] = &g12a_aoclk_cec_pre.hw, - [CLKID_AO_CEC_DIV] = &g12a_aoclk_cec_div.hw, - [CLKID_AO_CEC_SEL] = &g12a_aoclk_cec_sel.hw, - [CLKID_AO_CEC] = &g12a_aoclk_cec.hw, - [CLKID_AO_CTS_RTC_OSCIN] = &g12a_aoclk_cts_rtc_oscin.hw, +static struct clk_hw *g12a_ao_hw_clks[] = { + [CLKID_AO_AHB] = &g12a_ao_ahb.hw, + [CLKID_AO_IR_IN] = &g12a_ao_ir_in.hw, + [CLKID_AO_I2C_M0] = &g12a_ao_i2c_m0.hw, + [CLKID_AO_I2C_S0] = &g12a_ao_i2c_s0.hw, + [CLKID_AO_UART] = &g12a_ao_uart.hw, + [CLKID_AO_PROD_I2C] = &g12a_ao_prod_i2c.hw, + [CLKID_AO_UART2] = &g12a_ao_uart2.hw, + [CLKID_AO_IR_OUT] = &g12a_ao_ir_out.hw, + [CLKID_AO_SAR_ADC] = &g12a_ao_saradc.hw, + [CLKID_AO_MAILBOX] = &g12a_ao_mailbox.hw, + [CLKID_AO_M3] = &g12a_ao_m3.hw, + [CLKID_AO_AHB_SRAM] = &g12a_ao_ahb_sram.hw, + [CLKID_AO_RTI] = &g12a_ao_rti.hw, + [CLKID_AO_M4_FCLK] = &g12a_ao_m4_fclk.hw, + [CLKID_AO_M4_HCLK] = &g12a_ao_m4_hclk.hw, + [CLKID_AO_CLK81] = &g12a_ao_clk81.hw, + [CLKID_AO_SAR_ADC_SEL] = &g12a_ao_saradc_mux.hw, + [CLKID_AO_SAR_ADC_DIV] = &g12a_ao_saradc_div.hw, + [CLKID_AO_SAR_ADC_CLK] = &g12a_ao_saradc_gate.hw, + [CLKID_AO_CTS_OSCIN] = &g12a_ao_cts_oscin.hw, + [CLKID_AO_32K_PRE] = &g12a_ao_32k_by_oscin_pre.hw, + [CLKID_AO_32K_DIV] = &g12a_ao_32k_by_oscin_div.hw, + [CLKID_AO_32K_SEL] = &g12a_ao_32k_by_oscin_sel.hw, + [CLKID_AO_32K] = &g12a_ao_32k_by_oscin.hw, + [CLKID_AO_CEC_PRE] = &g12a_ao_cec_pre.hw, + [CLKID_AO_CEC_DIV] = &g12a_ao_cec_div.hw, + [CLKID_AO_CEC_SEL] = &g12a_ao_cec_sel.hw, + [CLKID_AO_CEC] = &g12a_ao_cec.hw, + [CLKID_AO_CTS_RTC_OSCIN] = &g12a_ao_cts_rtc_oscin.hw, }; -static const struct meson_aoclk_data g12a_aoclkc_data = { +static const struct meson_aoclk_data g12a_ao_clkc_data = { .reset_reg = AO_RTI_GEN_CNTL_REG0, - .num_reset = ARRAY_SIZE(g12a_aoclk_reset), - .reset = g12a_aoclk_reset, - .hw_clks = { - .hws = g12a_aoclk_hw_clks, - .num = ARRAY_SIZE(g12a_aoclk_hw_clks), + .num_reset = ARRAY_SIZE(g12a_ao_reset), + .reset = g12a_ao_reset, + .clkc_data = { + .hw_clks = { + .hws = g12a_ao_hw_clks, + .num = ARRAY_SIZE(g12a_ao_hw_clks), + }, }, }; -static const struct of_device_id g12a_aoclkc_match_table[] = { +static const struct of_device_id g12a_ao_clkc_match_table[] = { { .compatible = "amlogic,meson-g12a-aoclkc", - .data = &g12a_aoclkc_data, + .data = &g12a_ao_clkc_data.clkc_data, }, { } }; -MODULE_DEVICE_TABLE(of, g12a_aoclkc_match_table); +MODULE_DEVICE_TABLE(of, g12a_ao_clkc_match_table); -static struct platform_driver g12a_aoclkc_driver = { +static struct platform_driver g12a_ao_clkc_driver = { .probe = meson_aoclkc_probe, .driver = { .name = "g12a-aoclkc", - .of_match_table = g12a_aoclkc_match_table, + .of_match_table = g12a_ao_clkc_match_table, }, }; -module_platform_driver(g12a_aoclkc_driver); +module_platform_driver(g12a_ao_clkc_driver); MODULE_DESCRIPTION("Amlogic G12A Always-ON Clock Controller driver"); MODULE_LICENSE("GPL"); diff --git a/drivers/clk/meson/g12a.c b/drivers/clk/meson/g12a.c index 66f0e817e416..185b6348251d 100644 --- a/drivers/clk/meson/g12a.c +++ b/drivers/clk/meson/g12a.c @@ -23,7 +23,7 @@ #include "clk-cpu-dyndiv.h" #include "vid-pll-div.h" #include "vclk.h" -#include "meson-eeclk.h" +#include "meson-clkc-utils.h" #include <dt-bindings/clock/g12a-clkc.h> @@ -386,6 +386,451 @@ static struct clk_fixed_factor g12b_sys1_pll_div16 = { }, }; +static const struct pll_mult_range g12a_gp0_pll_mult_range = { + .min = 125, + .max = 255, +}; + +/* + * Internal gp0 pll emulation configuration parameters + */ +static const struct reg_sequence g12a_gp0_pll_init_regs[] = { + { .reg = HHI_GP0_PLL_CNTL1, .def = 0x00000000 }, + { .reg = HHI_GP0_PLL_CNTL2, .def = 0x00000000 }, + { .reg = HHI_GP0_PLL_CNTL3, .def = 0x48681c00 }, + { .reg = HHI_GP0_PLL_CNTL4, .def = 0x33771290 }, + { .reg = HHI_GP0_PLL_CNTL5, .def = 0x39272000 }, + { .reg = HHI_GP0_PLL_CNTL6, .def = 0x56540000 }, +}; + +static struct clk_regmap g12a_gp0_pll_dco = { + .data = &(struct meson_clk_pll_data){ + .en = { + .reg_off = HHI_GP0_PLL_CNTL0, + .shift = 28, + .width = 1, + }, + .m = { + .reg_off = HHI_GP0_PLL_CNTL0, + .shift = 0, + .width = 8, + }, + .n = { + .reg_off = HHI_GP0_PLL_CNTL0, + .shift = 10, + .width = 5, + }, + .frac = { + .reg_off = HHI_GP0_PLL_CNTL1, + .shift = 0, + .width = 17, + }, + .l = { + .reg_off = HHI_GP0_PLL_CNTL0, + .shift = 31, + .width = 1, + }, + .rst = { + .reg_off = HHI_GP0_PLL_CNTL0, + .shift = 29, + .width = 1, + }, + .range = &g12a_gp0_pll_mult_range, + .init_regs = g12a_gp0_pll_init_regs, + .init_count = ARRAY_SIZE(g12a_gp0_pll_init_regs), + }, + .hw.init = &(struct clk_init_data){ + .name = "gp0_pll_dco", + .ops = &meson_clk_pll_ops, + .parent_data = &(const struct clk_parent_data) { + .fw_name = "xtal", + }, + .num_parents = 1, + }, +}; + +static struct clk_regmap g12a_gp0_pll = { + .data = &(struct clk_regmap_div_data){ + .offset = HHI_GP0_PLL_CNTL0, + .shift = 16, + .width = 3, + .flags = (CLK_DIVIDER_POWER_OF_TWO | + CLK_DIVIDER_ROUND_CLOSEST), + }, + .hw.init = &(struct clk_init_data){ + .name = "gp0_pll", + .ops = &clk_regmap_divider_ops, + .parent_hws = (const struct clk_hw *[]) { + &g12a_gp0_pll_dco.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap sm1_gp1_pll_dco = { + .data = &(struct meson_clk_pll_data){ + .en = { + .reg_off = HHI_GP1_PLL_CNTL0, + .shift = 28, + .width = 1, + }, + .m = { + .reg_off = HHI_GP1_PLL_CNTL0, + .shift = 0, + .width = 8, + }, + .n = { + .reg_off = HHI_GP1_PLL_CNTL0, + .shift = 10, + .width = 5, + }, + .frac = { + .reg_off = HHI_GP1_PLL_CNTL1, + .shift = 0, + .width = 17, + }, + .l = { + .reg_off = HHI_GP1_PLL_CNTL0, + .shift = 31, + .width = 1, + }, + .rst = { + .reg_off = HHI_GP1_PLL_CNTL0, + .shift = 29, + .width = 1, + }, + }, + .hw.init = &(struct clk_init_data){ + .name = "gp1_pll_dco", + .ops = &meson_clk_pll_ro_ops, + .parent_data = &(const struct clk_parent_data) { + .fw_name = "xtal", + }, + .num_parents = 1, + /* This clock feeds the DSU, avoid disabling it */ + .flags = CLK_IS_CRITICAL, + }, +}; + +static struct clk_regmap sm1_gp1_pll = { + .data = &(struct clk_regmap_div_data){ + .offset = HHI_GP1_PLL_CNTL0, + .shift = 16, + .width = 3, + .flags = (CLK_DIVIDER_POWER_OF_TWO | + CLK_DIVIDER_ROUND_CLOSEST), + }, + .hw.init = &(struct clk_init_data){ + .name = "gp1_pll", + .ops = &clk_regmap_divider_ro_ops, + .parent_hws = (const struct clk_hw *[]) { + &sm1_gp1_pll_dco.hw + }, + .num_parents = 1, + }, +}; + +/* + * Internal hifi pll emulation configuration parameters + */ +static const struct reg_sequence g12a_hifi_pll_init_regs[] = { + { .reg = HHI_HIFI_PLL_CNTL1, .def = 0x00000000 }, + { .reg = HHI_HIFI_PLL_CNTL2, .def = 0x00000000 }, + { .reg = HHI_HIFI_PLL_CNTL3, .def = 0x6a285c00 }, + { .reg = HHI_HIFI_PLL_CNTL4, .def = 0x65771290 }, + { .reg = HHI_HIFI_PLL_CNTL5, .def = 0x39272000 }, + { .reg = HHI_HIFI_PLL_CNTL6, .def = 0x56540000 }, +}; + +static struct clk_regmap g12a_hifi_pll_dco = { + .data = &(struct meson_clk_pll_data){ + .en = { + .reg_off = HHI_HIFI_PLL_CNTL0, + .shift = 28, + .width = 1, + }, + .m = { + .reg_off = HHI_HIFI_PLL_CNTL0, + .shift = 0, + .width = 8, + }, + .n = { + .reg_off = HHI_HIFI_PLL_CNTL0, + .shift = 10, + .width = 5, + }, + .frac = { + .reg_off = HHI_HIFI_PLL_CNTL1, + .shift = 0, + .width = 17, + }, + .l = { + .reg_off = HHI_HIFI_PLL_CNTL0, + .shift = 31, + .width = 1, + }, + .rst = { + .reg_off = HHI_HIFI_PLL_CNTL0, + .shift = 29, + .width = 1, + }, + .range = &g12a_gp0_pll_mult_range, + .init_regs = g12a_hifi_pll_init_regs, + .init_count = ARRAY_SIZE(g12a_hifi_pll_init_regs), + .flags = CLK_MESON_PLL_ROUND_CLOSEST, + }, + .hw.init = &(struct clk_init_data){ + .name = "hifi_pll_dco", + .ops = &meson_clk_pll_ops, + .parent_data = &(const struct clk_parent_data) { + .fw_name = "xtal", + }, + .num_parents = 1, + }, +}; + +static struct clk_regmap g12a_hifi_pll = { + .data = &(struct clk_regmap_div_data){ + .offset = HHI_HIFI_PLL_CNTL0, + .shift = 16, + .width = 2, + .flags = (CLK_DIVIDER_POWER_OF_TWO | + CLK_DIVIDER_ROUND_CLOSEST), + }, + .hw.init = &(struct clk_init_data){ + .name = "hifi_pll", + .ops = &clk_regmap_divider_ops, + .parent_hws = (const struct clk_hw *[]) { + &g12a_hifi_pll_dco.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +/* + * The Meson G12A PCIE PLL is fined tuned to deliver a very precise + * 100MHz reference clock for the PCIe Analog PHY, and thus requires + * a strict register sequence to enable the PLL. + */ +static const struct reg_sequence g12a_pcie_pll_init_regs[] = { + { .reg = HHI_PCIE_PLL_CNTL0, .def = 0x20090496 }, + { .reg = HHI_PCIE_PLL_CNTL0, .def = 0x30090496 }, + { .reg = HHI_PCIE_PLL_CNTL1, .def = 0x00000000 }, + { .reg = HHI_PCIE_PLL_CNTL2, .def = 0x00001100 }, + { .reg = HHI_PCIE_PLL_CNTL3, .def = 0x10058e00 }, + { .reg = HHI_PCIE_PLL_CNTL4, .def = 0x000100c0 }, + { .reg = HHI_PCIE_PLL_CNTL5, .def = 0x68000048 }, + { .reg = HHI_PCIE_PLL_CNTL5, .def = 0x68000068, .delay_us = 20 }, + { .reg = HHI_PCIE_PLL_CNTL4, .def = 0x008100c0, .delay_us = 10 }, + { .reg = HHI_PCIE_PLL_CNTL0, .def = 0x34090496 }, + { .reg = HHI_PCIE_PLL_CNTL0, .def = 0x14090496, .delay_us = 10 }, + { .reg = HHI_PCIE_PLL_CNTL2, .def = 0x00001000 }, +}; + +/* Keep a single entry table for recalc/round_rate() ops */ +static const struct pll_params_table g12a_pcie_pll_table[] = { + PLL_PARAMS(150, 1), + {0, 0}, +}; + +static struct clk_regmap g12a_pcie_pll_dco = { + .data = &(struct meson_clk_pll_data){ + .en = { + .reg_off = HHI_PCIE_PLL_CNTL0, + .shift = 28, + .width = 1, + }, + .m = { + .reg_off = HHI_PCIE_PLL_CNTL0, + .shift = 0, + .width = 8, + }, + .n = { + .reg_off = HHI_PCIE_PLL_CNTL0, + .shift = 10, + .width = 5, + }, + .frac = { + .reg_off = HHI_PCIE_PLL_CNTL1, + .shift = 0, + .width = 12, + }, + .l = { + .reg_off = HHI_PCIE_PLL_CNTL0, + .shift = 31, + .width = 1, + }, + .rst = { + .reg_off = HHI_PCIE_PLL_CNTL0, + .shift = 29, + .width = 1, + }, + .table = g12a_pcie_pll_table, + .init_regs = g12a_pcie_pll_init_regs, + .init_count = ARRAY_SIZE(g12a_pcie_pll_init_regs), + }, + .hw.init = &(struct clk_init_data){ + .name = "pcie_pll_dco", + .ops = &meson_clk_pcie_pll_ops, + .parent_data = &(const struct clk_parent_data) { + .fw_name = "xtal", + }, + .num_parents = 1, + }, +}; + +static struct clk_fixed_factor g12a_pcie_pll_dco_div2 = { + .mult = 1, + .div = 2, + .hw.init = &(struct clk_init_data){ + .name = "pcie_pll_dco_div2", + .ops = &clk_fixed_factor_ops, + .parent_hws = (const struct clk_hw *[]) { + &g12a_pcie_pll_dco.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap g12a_pcie_pll_od = { + .data = &(struct clk_regmap_div_data){ + .offset = HHI_PCIE_PLL_CNTL0, + .shift = 16, + .width = 5, + .flags = CLK_DIVIDER_ROUND_CLOSEST | + CLK_DIVIDER_ONE_BASED | + CLK_DIVIDER_ALLOW_ZERO, + }, + .hw.init = &(struct clk_init_data){ + .name = "pcie_pll_od", + .ops = &clk_regmap_divider_ops, + .parent_hws = (const struct clk_hw *[]) { + &g12a_pcie_pll_dco_div2.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_fixed_factor g12a_pcie_pll = { + .mult = 1, + .div = 2, + .hw.init = &(struct clk_init_data){ + .name = "pcie_pll_pll", + .ops = &clk_fixed_factor_ops, + .parent_hws = (const struct clk_hw *[]) { + &g12a_pcie_pll_od.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap g12a_hdmi_pll_dco = { + .data = &(struct meson_clk_pll_data){ + .en = { + .reg_off = HHI_HDMI_PLL_CNTL0, + .shift = 28, + .width = 1, + }, + .m = { + .reg_off = HHI_HDMI_PLL_CNTL0, + .shift = 0, + .width = 8, + }, + .n = { + .reg_off = HHI_HDMI_PLL_CNTL0, + .shift = 10, + .width = 5, + }, + .frac = { + .reg_off = HHI_HDMI_PLL_CNTL1, + .shift = 0, + .width = 16, + }, + .l = { + .reg_off = HHI_HDMI_PLL_CNTL0, + .shift = 30, + .width = 1, + }, + .rst = { + .reg_off = HHI_HDMI_PLL_CNTL0, + .shift = 29, + .width = 1, + }, + }, + .hw.init = &(struct clk_init_data){ + .name = "hdmi_pll_dco", + .ops = &meson_clk_pll_ro_ops, + .parent_data = &(const struct clk_parent_data) { + .fw_name = "xtal", + }, + .num_parents = 1, + /* + * Display directly handle hdmi pll registers ATM, we need + * NOCACHE to keep our view of the clock as accurate as possible + */ + .flags = CLK_GET_RATE_NOCACHE, + }, +}; + +static struct clk_regmap g12a_hdmi_pll_od = { + .data = &(struct clk_regmap_div_data){ + .offset = HHI_HDMI_PLL_CNTL0, + .shift = 16, + .width = 2, + .flags = CLK_DIVIDER_POWER_OF_TWO, + }, + .hw.init = &(struct clk_init_data){ + .name = "hdmi_pll_od", + .ops = &clk_regmap_divider_ro_ops, + .parent_hws = (const struct clk_hw *[]) { + &g12a_hdmi_pll_dco.hw + }, + .num_parents = 1, + .flags = CLK_GET_RATE_NOCACHE | CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap g12a_hdmi_pll_od2 = { + .data = &(struct clk_regmap_div_data){ + .offset = HHI_HDMI_PLL_CNTL0, + .shift = 18, + .width = 2, + .flags = CLK_DIVIDER_POWER_OF_TWO, + }, + .hw.init = &(struct clk_init_data){ + .name = "hdmi_pll_od2", + .ops = &clk_regmap_divider_ro_ops, + .parent_hws = (const struct clk_hw *[]) { + &g12a_hdmi_pll_od.hw + }, + .num_parents = 1, + .flags = CLK_GET_RATE_NOCACHE | CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap g12a_hdmi_pll = { + .data = &(struct clk_regmap_div_data){ + .offset = HHI_HDMI_PLL_CNTL0, + .shift = 20, + .width = 2, + .flags = CLK_DIVIDER_POWER_OF_TWO, + }, + .hw.init = &(struct clk_init_data){ + .name = "hdmi_pll", + .ops = &clk_regmap_divider_ro_ops, + .parent_hws = (const struct clk_hw *[]) { + &g12a_hdmi_pll_od2.hw + }, + .num_parents = 1, + .flags = CLK_GET_RATE_NOCACHE | CLK_SET_RATE_PARENT, + }, +}; + static struct clk_fixed_factor g12a_fclk_div2_div = { .mult = 1, .div = 2, @@ -459,36 +904,166 @@ static struct clk_regmap g12a_fclk_div3 = { }, }; -/* Datasheet names this field as "premux0" */ -static struct clk_regmap g12a_cpu_clk_premux0 = { + +static struct clk_fixed_factor g12a_fclk_div4_div = { + .mult = 1, + .div = 4, + .hw.init = &(struct clk_init_data){ + .name = "fclk_div4_div", + .ops = &clk_fixed_factor_ops, + .parent_hws = (const struct clk_hw *[]) { &g12a_fixed_pll.hw }, + .num_parents = 1, + }, +}; + +static struct clk_regmap g12a_fclk_div4 = { + .data = &(struct clk_regmap_gate_data){ + .offset = HHI_FIX_PLL_CNTL1, + .bit_idx = 21, + }, + .hw.init = &(struct clk_init_data){ + .name = "fclk_div4", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { + &g12a_fclk_div4_div.hw + }, + .num_parents = 1, + }, +}; + +static struct clk_fixed_factor g12a_fclk_div5_div = { + .mult = 1, + .div = 5, + .hw.init = &(struct clk_init_data){ + .name = "fclk_div5_div", + .ops = &clk_fixed_factor_ops, + .parent_hws = (const struct clk_hw *[]) { &g12a_fixed_pll.hw }, + .num_parents = 1, + }, +}; + +static struct clk_regmap g12a_fclk_div5 = { + .data = &(struct clk_regmap_gate_data){ + .offset = HHI_FIX_PLL_CNTL1, + .bit_idx = 22, + }, + .hw.init = &(struct clk_init_data){ + .name = "fclk_div5", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { + &g12a_fclk_div5_div.hw + }, + .num_parents = 1, + }, +}; + +static struct clk_fixed_factor g12a_fclk_div7_div = { + .mult = 1, + .div = 7, + .hw.init = &(struct clk_init_data){ + .name = "fclk_div7_div", + .ops = &clk_fixed_factor_ops, + .parent_hws = (const struct clk_hw *[]) { &g12a_fixed_pll.hw }, + .num_parents = 1, + }, +}; + +static struct clk_regmap g12a_fclk_div7 = { + .data = &(struct clk_regmap_gate_data){ + .offset = HHI_FIX_PLL_CNTL1, + .bit_idx = 23, + }, + .hw.init = &(struct clk_init_data){ + .name = "fclk_div7", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { + &g12a_fclk_div7_div.hw + }, + .num_parents = 1, + }, +}; + +static struct clk_fixed_factor g12a_fclk_div2p5_div = { + .mult = 1, + .div = 5, + .hw.init = &(struct clk_init_data){ + .name = "fclk_div2p5_div", + .ops = &clk_fixed_factor_ops, + .parent_hws = (const struct clk_hw *[]) { + &g12a_fixed_pll_dco.hw + }, + .num_parents = 1, + }, +}; + +static struct clk_regmap g12a_fclk_div2p5 = { + .data = &(struct clk_regmap_gate_data){ + .offset = HHI_FIX_PLL_CNTL1, + .bit_idx = 25, + }, + .hw.init = &(struct clk_init_data){ + .name = "fclk_div2p5", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { + &g12a_fclk_div2p5_div.hw + }, + .num_parents = 1, + }, +}; + +static struct clk_fixed_factor g12a_mpll_50m_div = { + .mult = 1, + .div = 80, + .hw.init = &(struct clk_init_data){ + .name = "mpll_50m_div", + .ops = &clk_fixed_factor_ops, + .parent_hws = (const struct clk_hw *[]) { + &g12a_fixed_pll_dco.hw + }, + .num_parents = 1, + }, +}; + +static struct clk_regmap g12a_mpll_50m = { .data = &(struct clk_regmap_mux_data){ - .offset = HHI_SYS_CPU_CLK_CNTL0, - .mask = 0x3, - .shift = 0, - .flags = CLK_MUX_ROUND_CLOSEST, + .offset = HHI_FIX_PLL_CNTL3, + .mask = 0x1, + .shift = 5, }, .hw.init = &(struct clk_init_data){ - .name = "cpu_clk_dyn0_sel", - .ops = &clk_regmap_mux_ops, + .name = "mpll_50m", + .ops = &clk_regmap_mux_ro_ops, .parent_data = (const struct clk_parent_data []) { { .fw_name = "xtal", }, - { .hw = &g12a_fclk_div2.hw }, - { .hw = &g12a_fclk_div3.hw }, + { .hw = &g12a_mpll_50m_div.hw }, }, - .num_parents = 3, - .flags = CLK_SET_RATE_PARENT, + .num_parents = 2, }, }; -/* Datasheet names this field as "premux1" */ -static struct clk_regmap g12a_cpu_clk_premux1 = { +static struct clk_fixed_factor g12a_mpll_prediv = { + .mult = 1, + .div = 2, + .hw.init = &(struct clk_init_data){ + .name = "mpll_prediv", + .ops = &clk_fixed_factor_ops, + .parent_hws = (const struct clk_hw *[]) { + &g12a_fixed_pll_dco.hw + }, + .num_parents = 1, + }, +}; + +/* Datasheet names this field as "premux0" */ +static struct clk_regmap g12a_cpu_clk_dyn0_sel = { .data = &(struct clk_regmap_mux_data){ .offset = HHI_SYS_CPU_CLK_CNTL0, .mask = 0x3, - .shift = 16, + .shift = 0, + .flags = CLK_MUX_ROUND_CLOSEST, }, .hw.init = &(struct clk_init_data){ - .name = "cpu_clk_dyn1_sel", + .name = "cpu_clk_dyn0_sel", .ops = &clk_regmap_mux_ops, .parent_data = (const struct clk_parent_data []) { { .fw_name = "xtal", }, @@ -496,13 +1071,12 @@ static struct clk_regmap g12a_cpu_clk_premux1 = { { .hw = &g12a_fclk_div3.hw }, }, .num_parents = 3, - /* This sub-tree is used a parking clock */ - .flags = CLK_SET_RATE_NO_REPARENT + .flags = CLK_SET_RATE_PARENT, }, }; /* Datasheet names this field as "mux0_divn_tcnt" */ -static struct clk_regmap g12a_cpu_clk_mux0_div = { +static struct clk_regmap g12a_cpu_clk_dyn0_div = { .data = &(struct meson_clk_cpu_dyndiv_data){ .div = { .reg_off = HHI_SYS_CPU_CLK_CNTL0, @@ -519,7 +1093,7 @@ static struct clk_regmap g12a_cpu_clk_mux0_div = { .name = "cpu_clk_dyn0_div", .ops = &meson_clk_cpu_dyndiv_ops, .parent_hws = (const struct clk_hw *[]) { - &g12a_cpu_clk_premux0.hw + &g12a_cpu_clk_dyn0_sel.hw }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, @@ -527,7 +1101,7 @@ static struct clk_regmap g12a_cpu_clk_mux0_div = { }; /* Datasheet names this field as "postmux0" */ -static struct clk_regmap g12a_cpu_clk_postmux0 = { +static struct clk_regmap g12a_cpu_clk_dyn0 = { .data = &(struct clk_regmap_mux_data){ .offset = HHI_SYS_CPU_CLK_CNTL0, .mask = 0x1, @@ -538,16 +1112,37 @@ static struct clk_regmap g12a_cpu_clk_postmux0 = { .name = "cpu_clk_dyn0", .ops = &clk_regmap_mux_ops, .parent_hws = (const struct clk_hw *[]) { - &g12a_cpu_clk_premux0.hw, - &g12a_cpu_clk_mux0_div.hw, + &g12a_cpu_clk_dyn0_sel.hw, + &g12a_cpu_clk_dyn0_div.hw, }, .num_parents = 2, .flags = CLK_SET_RATE_PARENT, }, }; +/* Datasheet names this field as "premux1" */ +static struct clk_regmap g12a_cpu_clk_dyn1_sel = { + .data = &(struct clk_regmap_mux_data){ + .offset = HHI_SYS_CPU_CLK_CNTL0, + .mask = 0x3, + .shift = 16, + }, + .hw.init = &(struct clk_init_data){ + .name = "cpu_clk_dyn1_sel", + .ops = &clk_regmap_mux_ops, + .parent_data = (const struct clk_parent_data []) { + { .fw_name = "xtal", }, + { .hw = &g12a_fclk_div2.hw }, + { .hw = &g12a_fclk_div3.hw }, + }, + .num_parents = 3, + /* This sub-tree is used a parking clock */ + .flags = CLK_SET_RATE_NO_REPARENT + }, +}; + /* Datasheet names this field as "Mux1_divn_tcnt" */ -static struct clk_regmap g12a_cpu_clk_mux1_div = { +static struct clk_regmap g12a_cpu_clk_dyn1_div = { .data = &(struct clk_regmap_div_data){ .offset = HHI_SYS_CPU_CLK_CNTL0, .shift = 20, @@ -557,14 +1152,14 @@ static struct clk_regmap g12a_cpu_clk_mux1_div = { .name = "cpu_clk_dyn1_div", .ops = &clk_regmap_divider_ro_ops, .parent_hws = (const struct clk_hw *[]) { - &g12a_cpu_clk_premux1.hw + &g12a_cpu_clk_dyn1_sel.hw }, .num_parents = 1, }, }; /* Datasheet names this field as "postmux1" */ -static struct clk_regmap g12a_cpu_clk_postmux1 = { +static struct clk_regmap g12a_cpu_clk_dyn1 = { .data = &(struct clk_regmap_mux_data){ .offset = HHI_SYS_CPU_CLK_CNTL0, .mask = 0x1, @@ -574,8 +1169,8 @@ static struct clk_regmap g12a_cpu_clk_postmux1 = { .name = "cpu_clk_dyn1", .ops = &clk_regmap_mux_ops, .parent_hws = (const struct clk_hw *[]) { - &g12a_cpu_clk_premux1.hw, - &g12a_cpu_clk_mux1_div.hw, + &g12a_cpu_clk_dyn1_sel.hw, + &g12a_cpu_clk_dyn1_div.hw, }, .num_parents = 2, /* This sub-tree is used a parking clock */ @@ -595,8 +1190,8 @@ static struct clk_regmap g12a_cpu_clk_dyn = { .name = "cpu_clk_dyn", .ops = &clk_regmap_mux_ops, .parent_hws = (const struct clk_hw *[]) { - &g12a_cpu_clk_postmux0.hw, - &g12a_cpu_clk_postmux1.hw, + &g12a_cpu_clk_dyn0.hw, + &g12a_cpu_clk_dyn1.hw, }, .num_parents = 2, .flags = CLK_SET_RATE_PARENT, @@ -644,7 +1239,7 @@ static struct clk_regmap g12b_cpu_clk = { }; /* Datasheet names this field as "premux0" */ -static struct clk_regmap g12b_cpub_clk_premux0 = { +static struct clk_regmap g12b_cpub_clk_dyn0_sel = { .data = &(struct clk_regmap_mux_data){ .offset = HHI_SYS_CPUB_CLK_CNTL, .mask = 0x3, @@ -665,7 +1260,7 @@ static struct clk_regmap g12b_cpub_clk_premux0 = { }; /* Datasheet names this field as "mux0_divn_tcnt" */ -static struct clk_regmap g12b_cpub_clk_mux0_div = { +static struct clk_regmap g12b_cpub_clk_dyn0_div = { .data = &(struct meson_clk_cpu_dyndiv_data){ .div = { .reg_off = HHI_SYS_CPUB_CLK_CNTL, @@ -682,7 +1277,7 @@ static struct clk_regmap g12b_cpub_clk_mux0_div = { .name = "cpub_clk_dyn0_div", .ops = &meson_clk_cpu_dyndiv_ops, .parent_hws = (const struct clk_hw *[]) { - &g12b_cpub_clk_premux0.hw + &g12b_cpub_clk_dyn0_sel.hw }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, @@ -690,7 +1285,7 @@ static struct clk_regmap g12b_cpub_clk_mux0_div = { }; /* Datasheet names this field as "postmux0" */ -static struct clk_regmap g12b_cpub_clk_postmux0 = { +static struct clk_regmap g12b_cpub_clk_dyn0 = { .data = &(struct clk_regmap_mux_data){ .offset = HHI_SYS_CPUB_CLK_CNTL, .mask = 0x1, @@ -701,8 +1296,8 @@ static struct clk_regmap g12b_cpub_clk_postmux0 = { .name = "cpub_clk_dyn0", .ops = &clk_regmap_mux_ops, .parent_hws = (const struct clk_hw *[]) { - &g12b_cpub_clk_premux0.hw, - &g12b_cpub_clk_mux0_div.hw + &g12b_cpub_clk_dyn0_sel.hw, + &g12b_cpub_clk_dyn0_div.hw }, .num_parents = 2, .flags = CLK_SET_RATE_PARENT, @@ -710,7 +1305,7 @@ static struct clk_regmap g12b_cpub_clk_postmux0 = { }; /* Datasheet names this field as "premux1" */ -static struct clk_regmap g12b_cpub_clk_premux1 = { +static struct clk_regmap g12b_cpub_clk_dyn1_sel = { .data = &(struct clk_regmap_mux_data){ .offset = HHI_SYS_CPUB_CLK_CNTL, .mask = 0x3, @@ -731,7 +1326,7 @@ static struct clk_regmap g12b_cpub_clk_premux1 = { }; /* Datasheet names this field as "Mux1_divn_tcnt" */ -static struct clk_regmap g12b_cpub_clk_mux1_div = { +static struct clk_regmap g12b_cpub_clk_dyn1_div = { .data = &(struct clk_regmap_div_data){ .offset = HHI_SYS_CPUB_CLK_CNTL, .shift = 20, @@ -741,14 +1336,14 @@ static struct clk_regmap g12b_cpub_clk_mux1_div = { .name = "cpub_clk_dyn1_div", .ops = &clk_regmap_divider_ro_ops, .parent_hws = (const struct clk_hw *[]) { - &g12b_cpub_clk_premux1.hw + &g12b_cpub_clk_dyn1_sel.hw }, .num_parents = 1, }, }; /* Datasheet names this field as "postmux1" */ -static struct clk_regmap g12b_cpub_clk_postmux1 = { +static struct clk_regmap g12b_cpub_clk_dyn1 = { .data = &(struct clk_regmap_mux_data){ .offset = HHI_SYS_CPUB_CLK_CNTL, .mask = 0x1, @@ -758,8 +1353,8 @@ static struct clk_regmap g12b_cpub_clk_postmux1 = { .name = "cpub_clk_dyn1", .ops = &clk_regmap_mux_ops, .parent_hws = (const struct clk_hw *[]) { - &g12b_cpub_clk_premux1.hw, - &g12b_cpub_clk_mux1_div.hw + &g12b_cpub_clk_dyn1_sel.hw, + &g12b_cpub_clk_dyn1_div.hw }, .num_parents = 2, /* This sub-tree is used a parking clock */ @@ -779,8 +1374,8 @@ static struct clk_regmap g12b_cpub_clk_dyn = { .name = "cpub_clk_dyn", .ops = &clk_regmap_mux_ops, .parent_hws = (const struct clk_hw *[]) { - &g12b_cpub_clk_postmux0.hw, - &g12b_cpub_clk_postmux1.hw + &g12b_cpub_clk_dyn0.hw, + &g12b_cpub_clk_dyn1.hw }, .num_parents = 2, .flags = CLK_SET_RATE_PARENT, @@ -807,10 +1402,8 @@ static struct clk_regmap g12b_cpub_clk = { }, }; -static struct clk_regmap sm1_gp1_pll; - /* Datasheet names this field as "premux0" */ -static struct clk_regmap sm1_dsu_clk_premux0 = { +static struct clk_regmap sm1_dsu_clk_dyn0_sel = { .data = &(struct clk_regmap_mux_data){ .offset = HHI_SYS_CPU_CLK_CNTL5, .mask = 0x3, @@ -829,28 +1422,8 @@ static struct clk_regmap sm1_dsu_clk_premux0 = { }, }; -/* Datasheet names this field as "premux1" */ -static struct clk_regmap sm1_dsu_clk_premux1 = { - .data = &(struct clk_regmap_mux_data){ - .offset = HHI_SYS_CPU_CLK_CNTL5, - .mask = 0x3, - .shift = 16, - }, - .hw.init = &(struct clk_init_data){ - .name = "dsu_clk_dyn1_sel", - .ops = &clk_regmap_mux_ro_ops, - .parent_data = (const struct clk_parent_data []) { - { .fw_name = "xtal", }, - { .hw = &g12a_fclk_div2.hw }, - { .hw = &g12a_fclk_div3.hw }, - { .hw = &sm1_gp1_pll.hw }, - }, - .num_parents = 4, - }, -}; - /* Datasheet names this field as "Mux0_divn_tcnt" */ -static struct clk_regmap sm1_dsu_clk_mux0_div = { +static struct clk_regmap sm1_dsu_clk_dyn0_div = { .data = &(struct clk_regmap_div_data){ .offset = HHI_SYS_CPU_CLK_CNTL5, .shift = 4, @@ -860,14 +1433,14 @@ static struct clk_regmap sm1_dsu_clk_mux0_div = { .name = "dsu_clk_dyn0_div", .ops = &clk_regmap_divider_ro_ops, .parent_hws = (const struct clk_hw *[]) { - &sm1_dsu_clk_premux0.hw + &sm1_dsu_clk_dyn0_sel.hw }, .num_parents = 1, }, }; /* Datasheet names this field as "postmux0" */ -static struct clk_regmap sm1_dsu_clk_postmux0 = { +static struct clk_regmap sm1_dsu_clk_dyn0 = { .data = &(struct clk_regmap_mux_data){ .offset = HHI_SYS_CPU_CLK_CNTL5, .mask = 0x1, @@ -877,15 +1450,35 @@ static struct clk_regmap sm1_dsu_clk_postmux0 = { .name = "dsu_clk_dyn0", .ops = &clk_regmap_mux_ro_ops, .parent_hws = (const struct clk_hw *[]) { - &sm1_dsu_clk_premux0.hw, - &sm1_dsu_clk_mux0_div.hw, + &sm1_dsu_clk_dyn0_sel.hw, + &sm1_dsu_clk_dyn0_div.hw, }, .num_parents = 2, }, }; +/* Datasheet names this field as "premux1" */ +static struct clk_regmap sm1_dsu_clk_dyn1_sel = { + .data = &(struct clk_regmap_mux_data){ + .offset = HHI_SYS_CPU_CLK_CNTL5, + .mask = 0x3, + .shift = 16, + }, + .hw.init = &(struct clk_init_data){ + .name = "dsu_clk_dyn1_sel", + .ops = &clk_regmap_mux_ro_ops, + .parent_data = (const struct clk_parent_data []) { + { .fw_name = "xtal", }, + { .hw = &g12a_fclk_div2.hw }, + { .hw = &g12a_fclk_div3.hw }, + { .hw = &sm1_gp1_pll.hw }, + }, + .num_parents = 4, + }, +}; + /* Datasheet names this field as "Mux1_divn_tcnt" */ -static struct clk_regmap sm1_dsu_clk_mux1_div = { +static struct clk_regmap sm1_dsu_clk_dyn1_div = { .data = &(struct clk_regmap_div_data){ .offset = HHI_SYS_CPU_CLK_CNTL5, .shift = 20, @@ -895,14 +1488,14 @@ static struct clk_regmap sm1_dsu_clk_mux1_div = { .name = "dsu_clk_dyn1_div", .ops = &clk_regmap_divider_ro_ops, .parent_hws = (const struct clk_hw *[]) { - &sm1_dsu_clk_premux1.hw + &sm1_dsu_clk_dyn1_sel.hw }, .num_parents = 1, }, }; /* Datasheet names this field as "postmux1" */ -static struct clk_regmap sm1_dsu_clk_postmux1 = { +static struct clk_regmap sm1_dsu_clk_dyn1 = { .data = &(struct clk_regmap_mux_data){ .offset = HHI_SYS_CPU_CLK_CNTL5, .mask = 0x1, @@ -912,8 +1505,8 @@ static struct clk_regmap sm1_dsu_clk_postmux1 = { .name = "dsu_clk_dyn1", .ops = &clk_regmap_mux_ro_ops, .parent_hws = (const struct clk_hw *[]) { - &sm1_dsu_clk_premux1.hw, - &sm1_dsu_clk_mux1_div.hw, + &sm1_dsu_clk_dyn1_sel.hw, + &sm1_dsu_clk_dyn1_div.hw, }, .num_parents = 2, }, @@ -930,8 +1523,8 @@ static struct clk_regmap sm1_dsu_clk_dyn = { .name = "dsu_clk_dyn", .ops = &clk_regmap_mux_ro_ops, .parent_hws = (const struct clk_hw *[]) { - &sm1_dsu_clk_postmux0.hw, - &sm1_dsu_clk_postmux1.hw, + &sm1_dsu_clk_dyn0.hw, + &sm1_dsu_clk_dyn1.hw, }, .num_parents = 2, }, @@ -1043,7 +1636,7 @@ static struct notifier_block g12a_cpu_clk_mux_nb = { .notifier_call = g12a_cpu_clk_mux_notifier_cb, }; -struct g12a_cpu_clk_postmux_nb_data { +struct g12a_cpu_clk_dyn_nb_data { struct notifier_block nb; struct clk_hw *xtal; struct clk_hw *cpu_clk_dyn; @@ -1052,33 +1645,33 @@ struct g12a_cpu_clk_postmux_nb_data { struct clk_hw *cpu_clk_premux1; }; -static int g12a_cpu_clk_postmux_notifier_cb(struct notifier_block *nb, - unsigned long event, void *data) +static int g12a_cpu_clk_dyn_notifier_cb(struct notifier_block *nb, + unsigned long event, void *data) { - struct g12a_cpu_clk_postmux_nb_data *nb_data = - container_of(nb, struct g12a_cpu_clk_postmux_nb_data, nb); + struct g12a_cpu_clk_dyn_nb_data *nb_data = + container_of(nb, struct g12a_cpu_clk_dyn_nb_data, nb); switch (event) { case PRE_RATE_CHANGE: /* - * This notifier means cpu_clk_postmux0 clock will be changed + * This notifier means cpu_clk_dyn0 clock will be changed * to feed cpu_clk, this is the current path : * cpu_clk * \- cpu_clk_dyn - * \- cpu_clk_postmux0 - * \- cpu_clk_muxX_div - * \- cpu_clk_premux0 + * \- cpu_clk_dyn0 + * \- cpu_clk_dyn0_div + * \- cpu_clk_dyn0_sel * \- fclk_div3 or fclk_div2 * OR - * \- cpu_clk_premux0 + * \- cpu_clk_dyn0_sel * \- fclk_div3 or fclk_div2 */ - /* Setup cpu_clk_premux1 to xtal */ + /* Setup cpu_clk_dyn1_sel to xtal */ clk_hw_set_parent(nb_data->cpu_clk_premux1, nb_data->xtal); - /* Setup cpu_clk_postmux1 to bypass divider */ + /* Setup cpu_clk_dyn1 to bypass divider */ clk_hw_set_parent(nb_data->cpu_clk_postmux1, nb_data->cpu_clk_premux1); @@ -1090,8 +1683,8 @@ static int g12a_cpu_clk_postmux_notifier_cb(struct notifier_block *nb, * Now, cpu_clk is 24MHz in the current path : * cpu_clk * \- cpu_clk_dyn - * \- cpu_clk_postmux1 - * \- cpu_clk_premux1 + * \- cpu_clk_dyn1 + * \- cpu_clk_dyn1_sel * \- xtal */ @@ -1101,8 +1694,8 @@ static int g12a_cpu_clk_postmux_notifier_cb(struct notifier_block *nb, case POST_RATE_CHANGE: /* - * The cpu_clk_postmux0 has ben updated, now switch back - * cpu_clk_dyn to cpu_clk_postmux0 and take the changes + * The cpu_clk_dyn0 has ben updated, now switch back + * cpu_clk_dyn to cpu_clk_dyn0 and take the changes * in account. */ @@ -1114,12 +1707,12 @@ static int g12a_cpu_clk_postmux_notifier_cb(struct notifier_block *nb, * new path : * cpu_clk * \- cpu_clk_dyn - * \- cpu_clk_postmux0 - * \- cpu_clk_muxX_div - * \- cpu_clk_premux0 + * \- cpu_clk_dyn0 + * \- cpu_clk_dyn0_div + * \- cpu_clk_dyn0_sel * \- fclk_div3 or fclk_div2 * OR - * \- cpu_clk_premux0 + * \- cpu_clk_dyn0_sel * \- fclk_div3 or fclk_div2 */ @@ -1132,20 +1725,20 @@ static int g12a_cpu_clk_postmux_notifier_cb(struct notifier_block *nb, } } -static struct g12a_cpu_clk_postmux_nb_data g12a_cpu_clk_postmux0_nb_data = { +static struct g12a_cpu_clk_dyn_nb_data g12a_cpu_clk_dyn0_nb_data = { .cpu_clk_dyn = &g12a_cpu_clk_dyn.hw, - .cpu_clk_postmux0 = &g12a_cpu_clk_postmux0.hw, - .cpu_clk_postmux1 = &g12a_cpu_clk_postmux1.hw, - .cpu_clk_premux1 = &g12a_cpu_clk_premux1.hw, - .nb.notifier_call = g12a_cpu_clk_postmux_notifier_cb, + .cpu_clk_postmux0 = &g12a_cpu_clk_dyn0.hw, + .cpu_clk_postmux1 = &g12a_cpu_clk_dyn1.hw, + .cpu_clk_premux1 = &g12a_cpu_clk_dyn1_sel.hw, + .nb.notifier_call = g12a_cpu_clk_dyn_notifier_cb, }; -static struct g12a_cpu_clk_postmux_nb_data g12b_cpub_clk_postmux0_nb_data = { +static struct g12a_cpu_clk_dyn_nb_data g12b_cpub_clk_dyn0_nb_data = { .cpu_clk_dyn = &g12b_cpub_clk_dyn.hw, - .cpu_clk_postmux0 = &g12b_cpub_clk_postmux0.hw, - .cpu_clk_postmux1 = &g12b_cpub_clk_postmux1.hw, - .cpu_clk_premux1 = &g12b_cpub_clk_premux1.hw, - .nb.notifier_call = g12a_cpu_clk_postmux_notifier_cb, + .cpu_clk_postmux0 = &g12b_cpub_clk_dyn0.hw, + .cpu_clk_postmux1 = &g12b_cpub_clk_dyn1.hw, + .cpu_clk_premux1 = &g12b_cpub_clk_dyn1_sel.hw, + .nb.notifier_call = g12a_cpu_clk_dyn_notifier_cb, }; struct g12a_sys_pll_nb_data { @@ -1551,27 +2144,29 @@ static struct clk_fixed_factor g12b_cpub_clk_div8 = { }, }; -static u32 mux_table_cpub[] = { 1, 2, 3, 4, 5, 6, 7 }; +static u32 g12b_cpub_clk_if_parents_val_table[] = { 1, 2, 3, 4, 5, 6, 7 }; +static const struct clk_hw *g12b_cpub_clk_if_parents[] = { + &g12b_cpub_clk_div2.hw, + &g12b_cpub_clk_div3.hw, + &g12b_cpub_clk_div4.hw, + &g12b_cpub_clk_div5.hw, + &g12b_cpub_clk_div6.hw, + &g12b_cpub_clk_div7.hw, + &g12b_cpub_clk_div8.hw, +}; + static struct clk_regmap g12b_cpub_clk_apb_sel = { .data = &(struct clk_regmap_mux_data){ .offset = HHI_SYS_CPUB_CLK_CNTL1, .mask = 7, .shift = 3, - .table = mux_table_cpub, + .table = g12b_cpub_clk_if_parents_val_table, }, .hw.init = &(struct clk_init_data){ .name = "cpub_clk_apb_sel", .ops = &clk_regmap_mux_ro_ops, - .parent_hws = (const struct clk_hw *[]) { - &g12b_cpub_clk_div2.hw, - &g12b_cpub_clk_div3.hw, - &g12b_cpub_clk_div4.hw, - &g12b_cpub_clk_div5.hw, - &g12b_cpub_clk_div6.hw, - &g12b_cpub_clk_div7.hw, - &g12b_cpub_clk_div8.hw - }, - .num_parents = 7, + .parent_hws = g12b_cpub_clk_if_parents, + .num_parents = ARRAY_SIZE(g12b_cpub_clk_if_parents), }, }; @@ -1600,21 +2195,13 @@ static struct clk_regmap g12b_cpub_clk_atb_sel = { .offset = HHI_SYS_CPUB_CLK_CNTL1, .mask = 7, .shift = 6, - .table = mux_table_cpub, + .table = g12b_cpub_clk_if_parents_val_table, }, .hw.init = &(struct clk_init_data){ .name = "cpub_clk_atb_sel", .ops = &clk_regmap_mux_ro_ops, - .parent_hws = (const struct clk_hw *[]) { - &g12b_cpub_clk_div2.hw, - &g12b_cpub_clk_div3.hw, - &g12b_cpub_clk_div4.hw, - &g12b_cpub_clk_div5.hw, - &g12b_cpub_clk_div6.hw, - &g12b_cpub_clk_div7.hw, - &g12b_cpub_clk_div8.hw - }, - .num_parents = 7, + .parent_hws = g12b_cpub_clk_if_parents, + .num_parents = ARRAY_SIZE(g12b_cpub_clk_if_parents), }, }; @@ -1643,21 +2230,13 @@ static struct clk_regmap g12b_cpub_clk_axi_sel = { .offset = HHI_SYS_CPUB_CLK_CNTL1, .mask = 7, .shift = 9, - .table = mux_table_cpub, + .table = g12b_cpub_clk_if_parents_val_table, }, .hw.init = &(struct clk_init_data){ .name = "cpub_clk_axi_sel", .ops = &clk_regmap_mux_ro_ops, - .parent_hws = (const struct clk_hw *[]) { - &g12b_cpub_clk_div2.hw, - &g12b_cpub_clk_div3.hw, - &g12b_cpub_clk_div4.hw, - &g12b_cpub_clk_div5.hw, - &g12b_cpub_clk_div6.hw, - &g12b_cpub_clk_div7.hw, - &g12b_cpub_clk_div8.hw - }, - .num_parents = 7, + .parent_hws = g12b_cpub_clk_if_parents, + .num_parents = ARRAY_SIZE(g12b_cpub_clk_if_parents), }, }; @@ -1686,21 +2265,13 @@ static struct clk_regmap g12b_cpub_clk_trace_sel = { .offset = HHI_SYS_CPUB_CLK_CNTL1, .mask = 7, .shift = 20, - .table = mux_table_cpub, + .table = g12b_cpub_clk_if_parents_val_table, }, .hw.init = &(struct clk_init_data){ .name = "cpub_clk_trace_sel", .ops = &clk_regmap_mux_ro_ops, - .parent_hws = (const struct clk_hw *[]) { - &g12b_cpub_clk_div2.hw, - &g12b_cpub_clk_div3.hw, - &g12b_cpub_clk_div4.hw, - &g12b_cpub_clk_div5.hw, - &g12b_cpub_clk_div6.hw, - &g12b_cpub_clk_div7.hw, - &g12b_cpub_clk_div8.hw - }, - .num_parents = 7, + .parent_hws = g12b_cpub_clk_if_parents, + .num_parents = ARRAY_SIZE(g12b_cpub_clk_if_parents), }, }; @@ -1724,600 +2295,6 @@ static struct clk_regmap g12b_cpub_clk_trace = { }, }; -static const struct pll_mult_range g12a_gp0_pll_mult_range = { - .min = 125, - .max = 255, -}; - -/* - * Internal gp0 pll emulation configuration parameters - */ -static const struct reg_sequence g12a_gp0_init_regs[] = { - { .reg = HHI_GP0_PLL_CNTL1, .def = 0x00000000 }, - { .reg = HHI_GP0_PLL_CNTL2, .def = 0x00000000 }, - { .reg = HHI_GP0_PLL_CNTL3, .def = 0x48681c00 }, - { .reg = HHI_GP0_PLL_CNTL4, .def = 0x33771290 }, - { .reg = HHI_GP0_PLL_CNTL5, .def = 0x39272000 }, - { .reg = HHI_GP0_PLL_CNTL6, .def = 0x56540000 }, -}; - -static struct clk_regmap g12a_gp0_pll_dco = { - .data = &(struct meson_clk_pll_data){ - .en = { - .reg_off = HHI_GP0_PLL_CNTL0, - .shift = 28, - .width = 1, - }, - .m = { - .reg_off = HHI_GP0_PLL_CNTL0, - .shift = 0, - .width = 8, - }, - .n = { - .reg_off = HHI_GP0_PLL_CNTL0, - .shift = 10, - .width = 5, - }, - .frac = { - .reg_off = HHI_GP0_PLL_CNTL1, - .shift = 0, - .width = 17, - }, - .l = { - .reg_off = HHI_GP0_PLL_CNTL0, - .shift = 31, - .width = 1, - }, - .rst = { - .reg_off = HHI_GP0_PLL_CNTL0, - .shift = 29, - .width = 1, - }, - .range = &g12a_gp0_pll_mult_range, - .init_regs = g12a_gp0_init_regs, - .init_count = ARRAY_SIZE(g12a_gp0_init_regs), - }, - .hw.init = &(struct clk_init_data){ - .name = "gp0_pll_dco", - .ops = &meson_clk_pll_ops, - .parent_data = &(const struct clk_parent_data) { - .fw_name = "xtal", - }, - .num_parents = 1, - }, -}; - -static struct clk_regmap g12a_gp0_pll = { - .data = &(struct clk_regmap_div_data){ - .offset = HHI_GP0_PLL_CNTL0, - .shift = 16, - .width = 3, - .flags = (CLK_DIVIDER_POWER_OF_TWO | - CLK_DIVIDER_ROUND_CLOSEST), - }, - .hw.init = &(struct clk_init_data){ - .name = "gp0_pll", - .ops = &clk_regmap_divider_ops, - .parent_hws = (const struct clk_hw *[]) { - &g12a_gp0_pll_dco.hw - }, - .num_parents = 1, - .flags = CLK_SET_RATE_PARENT, - }, -}; - -static struct clk_regmap sm1_gp1_pll_dco = { - .data = &(struct meson_clk_pll_data){ - .en = { - .reg_off = HHI_GP1_PLL_CNTL0, - .shift = 28, - .width = 1, - }, - .m = { - .reg_off = HHI_GP1_PLL_CNTL0, - .shift = 0, - .width = 8, - }, - .n = { - .reg_off = HHI_GP1_PLL_CNTL0, - .shift = 10, - .width = 5, - }, - .frac = { - .reg_off = HHI_GP1_PLL_CNTL1, - .shift = 0, - .width = 17, - }, - .l = { - .reg_off = HHI_GP1_PLL_CNTL0, - .shift = 31, - .width = 1, - }, - .rst = { - .reg_off = HHI_GP1_PLL_CNTL0, - .shift = 29, - .width = 1, - }, - }, - .hw.init = &(struct clk_init_data){ - .name = "gp1_pll_dco", - .ops = &meson_clk_pll_ro_ops, - .parent_data = &(const struct clk_parent_data) { - .fw_name = "xtal", - }, - .num_parents = 1, - /* This clock feeds the DSU, avoid disabling it */ - .flags = CLK_IS_CRITICAL, - }, -}; - -static struct clk_regmap sm1_gp1_pll = { - .data = &(struct clk_regmap_div_data){ - .offset = HHI_GP1_PLL_CNTL0, - .shift = 16, - .width = 3, - .flags = (CLK_DIVIDER_POWER_OF_TWO | - CLK_DIVIDER_ROUND_CLOSEST), - }, - .hw.init = &(struct clk_init_data){ - .name = "gp1_pll", - .ops = &clk_regmap_divider_ro_ops, - .parent_hws = (const struct clk_hw *[]) { - &sm1_gp1_pll_dco.hw - }, - .num_parents = 1, - }, -}; - -/* - * Internal hifi pll emulation configuration parameters - */ -static const struct reg_sequence g12a_hifi_init_regs[] = { - { .reg = HHI_HIFI_PLL_CNTL1, .def = 0x00000000 }, - { .reg = HHI_HIFI_PLL_CNTL2, .def = 0x00000000 }, - { .reg = HHI_HIFI_PLL_CNTL3, .def = 0x6a285c00 }, - { .reg = HHI_HIFI_PLL_CNTL4, .def = 0x65771290 }, - { .reg = HHI_HIFI_PLL_CNTL5, .def = 0x39272000 }, - { .reg = HHI_HIFI_PLL_CNTL6, .def = 0x56540000 }, -}; - -static struct clk_regmap g12a_hifi_pll_dco = { - .data = &(struct meson_clk_pll_data){ - .en = { - .reg_off = HHI_HIFI_PLL_CNTL0, - .shift = 28, - .width = 1, - }, - .m = { - .reg_off = HHI_HIFI_PLL_CNTL0, - .shift = 0, - .width = 8, - }, - .n = { - .reg_off = HHI_HIFI_PLL_CNTL0, - .shift = 10, - .width = 5, - }, - .frac = { - .reg_off = HHI_HIFI_PLL_CNTL1, - .shift = 0, - .width = 17, - }, - .l = { - .reg_off = HHI_HIFI_PLL_CNTL0, - .shift = 31, - .width = 1, - }, - .rst = { - .reg_off = HHI_HIFI_PLL_CNTL0, - .shift = 29, - .width = 1, - }, - .range = &g12a_gp0_pll_mult_range, - .init_regs = g12a_hifi_init_regs, - .init_count = ARRAY_SIZE(g12a_hifi_init_regs), - .flags = CLK_MESON_PLL_ROUND_CLOSEST, - }, - .hw.init = &(struct clk_init_data){ - .name = "hifi_pll_dco", - .ops = &meson_clk_pll_ops, - .parent_data = &(const struct clk_parent_data) { - .fw_name = "xtal", - }, - .num_parents = 1, - }, -}; - -static struct clk_regmap g12a_hifi_pll = { - .data = &(struct clk_regmap_div_data){ - .offset = HHI_HIFI_PLL_CNTL0, - .shift = 16, - .width = 2, - .flags = (CLK_DIVIDER_POWER_OF_TWO | - CLK_DIVIDER_ROUND_CLOSEST), - }, - .hw.init = &(struct clk_init_data){ - .name = "hifi_pll", - .ops = &clk_regmap_divider_ops, - .parent_hws = (const struct clk_hw *[]) { - &g12a_hifi_pll_dco.hw - }, - .num_parents = 1, - .flags = CLK_SET_RATE_PARENT, - }, -}; - -/* - * The Meson G12A PCIE PLL is fined tuned to deliver a very precise - * 100MHz reference clock for the PCIe Analog PHY, and thus requires - * a strict register sequence to enable the PLL. - */ -static const struct reg_sequence g12a_pcie_pll_init_regs[] = { - { .reg = HHI_PCIE_PLL_CNTL0, .def = 0x20090496 }, - { .reg = HHI_PCIE_PLL_CNTL0, .def = 0x30090496 }, - { .reg = HHI_PCIE_PLL_CNTL1, .def = 0x00000000 }, - { .reg = HHI_PCIE_PLL_CNTL2, .def = 0x00001100 }, - { .reg = HHI_PCIE_PLL_CNTL3, .def = 0x10058e00 }, - { .reg = HHI_PCIE_PLL_CNTL4, .def = 0x000100c0 }, - { .reg = HHI_PCIE_PLL_CNTL5, .def = 0x68000048 }, - { .reg = HHI_PCIE_PLL_CNTL5, .def = 0x68000068, .delay_us = 20 }, - { .reg = HHI_PCIE_PLL_CNTL4, .def = 0x008100c0, .delay_us = 10 }, - { .reg = HHI_PCIE_PLL_CNTL0, .def = 0x34090496 }, - { .reg = HHI_PCIE_PLL_CNTL0, .def = 0x14090496, .delay_us = 10 }, - { .reg = HHI_PCIE_PLL_CNTL2, .def = 0x00001000 }, -}; - -/* Keep a single entry table for recalc/round_rate() ops */ -static const struct pll_params_table g12a_pcie_pll_table[] = { - PLL_PARAMS(150, 1), - {0, 0}, -}; - -static struct clk_regmap g12a_pcie_pll_dco = { - .data = &(struct meson_clk_pll_data){ - .en = { - .reg_off = HHI_PCIE_PLL_CNTL0, - .shift = 28, - .width = 1, - }, - .m = { - .reg_off = HHI_PCIE_PLL_CNTL0, - .shift = 0, - .width = 8, - }, - .n = { - .reg_off = HHI_PCIE_PLL_CNTL0, - .shift = 10, - .width = 5, - }, - .frac = { - .reg_off = HHI_PCIE_PLL_CNTL1, - .shift = 0, - .width = 12, - }, - .l = { - .reg_off = HHI_PCIE_PLL_CNTL0, - .shift = 31, - .width = 1, - }, - .rst = { - .reg_off = HHI_PCIE_PLL_CNTL0, - .shift = 29, - .width = 1, - }, - .table = g12a_pcie_pll_table, - .init_regs = g12a_pcie_pll_init_regs, - .init_count = ARRAY_SIZE(g12a_pcie_pll_init_regs), - }, - .hw.init = &(struct clk_init_data){ - .name = "pcie_pll_dco", - .ops = &meson_clk_pcie_pll_ops, - .parent_data = &(const struct clk_parent_data) { - .fw_name = "xtal", - }, - .num_parents = 1, - }, -}; - -static struct clk_fixed_factor g12a_pcie_pll_dco_div2 = { - .mult = 1, - .div = 2, - .hw.init = &(struct clk_init_data){ - .name = "pcie_pll_dco_div2", - .ops = &clk_fixed_factor_ops, - .parent_hws = (const struct clk_hw *[]) { - &g12a_pcie_pll_dco.hw - }, - .num_parents = 1, - .flags = CLK_SET_RATE_PARENT, - }, -}; - -static struct clk_regmap g12a_pcie_pll_od = { - .data = &(struct clk_regmap_div_data){ - .offset = HHI_PCIE_PLL_CNTL0, - .shift = 16, - .width = 5, - .flags = CLK_DIVIDER_ROUND_CLOSEST | - CLK_DIVIDER_ONE_BASED | - CLK_DIVIDER_ALLOW_ZERO, - }, - .hw.init = &(struct clk_init_data){ - .name = "pcie_pll_od", - .ops = &clk_regmap_divider_ops, - .parent_hws = (const struct clk_hw *[]) { - &g12a_pcie_pll_dco_div2.hw - }, - .num_parents = 1, - .flags = CLK_SET_RATE_PARENT, - }, -}; - -static struct clk_fixed_factor g12a_pcie_pll = { - .mult = 1, - .div = 2, - .hw.init = &(struct clk_init_data){ - .name = "pcie_pll_pll", - .ops = &clk_fixed_factor_ops, - .parent_hws = (const struct clk_hw *[]) { - &g12a_pcie_pll_od.hw - }, - .num_parents = 1, - .flags = CLK_SET_RATE_PARENT, - }, -}; - -static struct clk_regmap g12a_hdmi_pll_dco = { - .data = &(struct meson_clk_pll_data){ - .en = { - .reg_off = HHI_HDMI_PLL_CNTL0, - .shift = 28, - .width = 1, - }, - .m = { - .reg_off = HHI_HDMI_PLL_CNTL0, - .shift = 0, - .width = 8, - }, - .n = { - .reg_off = HHI_HDMI_PLL_CNTL0, - .shift = 10, - .width = 5, - }, - .frac = { - .reg_off = HHI_HDMI_PLL_CNTL1, - .shift = 0, - .width = 16, - }, - .l = { - .reg_off = HHI_HDMI_PLL_CNTL0, - .shift = 30, - .width = 1, - }, - .rst = { - .reg_off = HHI_HDMI_PLL_CNTL0, - .shift = 29, - .width = 1, - }, - }, - .hw.init = &(struct clk_init_data){ - .name = "hdmi_pll_dco", - .ops = &meson_clk_pll_ro_ops, - .parent_data = &(const struct clk_parent_data) { - .fw_name = "xtal", - }, - .num_parents = 1, - /* - * Display directly handle hdmi pll registers ATM, we need - * NOCACHE to keep our view of the clock as accurate as possible - */ - .flags = CLK_GET_RATE_NOCACHE, - }, -}; - -static struct clk_regmap g12a_hdmi_pll_od = { - .data = &(struct clk_regmap_div_data){ - .offset = HHI_HDMI_PLL_CNTL0, - .shift = 16, - .width = 2, - .flags = CLK_DIVIDER_POWER_OF_TWO, - }, - .hw.init = &(struct clk_init_data){ - .name = "hdmi_pll_od", - .ops = &clk_regmap_divider_ro_ops, - .parent_hws = (const struct clk_hw *[]) { - &g12a_hdmi_pll_dco.hw - }, - .num_parents = 1, - .flags = CLK_GET_RATE_NOCACHE | CLK_SET_RATE_PARENT, - }, -}; - -static struct clk_regmap g12a_hdmi_pll_od2 = { - .data = &(struct clk_regmap_div_data){ - .offset = HHI_HDMI_PLL_CNTL0, - .shift = 18, - .width = 2, - .flags = CLK_DIVIDER_POWER_OF_TWO, - }, - .hw.init = &(struct clk_init_data){ - .name = "hdmi_pll_od2", - .ops = &clk_regmap_divider_ro_ops, - .parent_hws = (const struct clk_hw *[]) { - &g12a_hdmi_pll_od.hw - }, - .num_parents = 1, - .flags = CLK_GET_RATE_NOCACHE | CLK_SET_RATE_PARENT, - }, -}; - -static struct clk_regmap g12a_hdmi_pll = { - .data = &(struct clk_regmap_div_data){ - .offset = HHI_HDMI_PLL_CNTL0, - .shift = 20, - .width = 2, - .flags = CLK_DIVIDER_POWER_OF_TWO, - }, - .hw.init = &(struct clk_init_data){ - .name = "hdmi_pll", - .ops = &clk_regmap_divider_ro_ops, - .parent_hws = (const struct clk_hw *[]) { - &g12a_hdmi_pll_od2.hw - }, - .num_parents = 1, - .flags = CLK_GET_RATE_NOCACHE | CLK_SET_RATE_PARENT, - }, -}; - -static struct clk_fixed_factor g12a_fclk_div4_div = { - .mult = 1, - .div = 4, - .hw.init = &(struct clk_init_data){ - .name = "fclk_div4_div", - .ops = &clk_fixed_factor_ops, - .parent_hws = (const struct clk_hw *[]) { &g12a_fixed_pll.hw }, - .num_parents = 1, - }, -}; - -static struct clk_regmap g12a_fclk_div4 = { - .data = &(struct clk_regmap_gate_data){ - .offset = HHI_FIX_PLL_CNTL1, - .bit_idx = 21, - }, - .hw.init = &(struct clk_init_data){ - .name = "fclk_div4", - .ops = &clk_regmap_gate_ops, - .parent_hws = (const struct clk_hw *[]) { - &g12a_fclk_div4_div.hw - }, - .num_parents = 1, - }, -}; - -static struct clk_fixed_factor g12a_fclk_div5_div = { - .mult = 1, - .div = 5, - .hw.init = &(struct clk_init_data){ - .name = "fclk_div5_div", - .ops = &clk_fixed_factor_ops, - .parent_hws = (const struct clk_hw *[]) { &g12a_fixed_pll.hw }, - .num_parents = 1, - }, -}; - -static struct clk_regmap g12a_fclk_div5 = { - .data = &(struct clk_regmap_gate_data){ - .offset = HHI_FIX_PLL_CNTL1, - .bit_idx = 22, - }, - .hw.init = &(struct clk_init_data){ - .name = "fclk_div5", - .ops = &clk_regmap_gate_ops, - .parent_hws = (const struct clk_hw *[]) { - &g12a_fclk_div5_div.hw - }, - .num_parents = 1, - }, -}; - -static struct clk_fixed_factor g12a_fclk_div7_div = { - .mult = 1, - .div = 7, - .hw.init = &(struct clk_init_data){ - .name = "fclk_div7_div", - .ops = &clk_fixed_factor_ops, - .parent_hws = (const struct clk_hw *[]) { &g12a_fixed_pll.hw }, - .num_parents = 1, - }, -}; - -static struct clk_regmap g12a_fclk_div7 = { - .data = &(struct clk_regmap_gate_data){ - .offset = HHI_FIX_PLL_CNTL1, - .bit_idx = 23, - }, - .hw.init = &(struct clk_init_data){ - .name = "fclk_div7", - .ops = &clk_regmap_gate_ops, - .parent_hws = (const struct clk_hw *[]) { - &g12a_fclk_div7_div.hw - }, - .num_parents = 1, - }, -}; - -static struct clk_fixed_factor g12a_fclk_div2p5_div = { - .mult = 1, - .div = 5, - .hw.init = &(struct clk_init_data){ - .name = "fclk_div2p5_div", - .ops = &clk_fixed_factor_ops, - .parent_hws = (const struct clk_hw *[]) { - &g12a_fixed_pll_dco.hw - }, - .num_parents = 1, - }, -}; - -static struct clk_regmap g12a_fclk_div2p5 = { - .data = &(struct clk_regmap_gate_data){ - .offset = HHI_FIX_PLL_CNTL1, - .bit_idx = 25, - }, - .hw.init = &(struct clk_init_data){ - .name = "fclk_div2p5", - .ops = &clk_regmap_gate_ops, - .parent_hws = (const struct clk_hw *[]) { - &g12a_fclk_div2p5_div.hw - }, - .num_parents = 1, - }, -}; - -static struct clk_fixed_factor g12a_mpll_50m_div = { - .mult = 1, - .div = 80, - .hw.init = &(struct clk_init_data){ - .name = "mpll_50m_div", - .ops = &clk_fixed_factor_ops, - .parent_hws = (const struct clk_hw *[]) { - &g12a_fixed_pll_dco.hw - }, - .num_parents = 1, - }, -}; - -static struct clk_regmap g12a_mpll_50m = { - .data = &(struct clk_regmap_mux_data){ - .offset = HHI_FIX_PLL_CNTL3, - .mask = 0x1, - .shift = 5, - }, - .hw.init = &(struct clk_init_data){ - .name = "mpll_50m", - .ops = &clk_regmap_mux_ro_ops, - .parent_data = (const struct clk_parent_data []) { - { .fw_name = "xtal", }, - { .hw = &g12a_mpll_50m_div.hw }, - }, - .num_parents = 2, - }, -}; - -static struct clk_fixed_factor g12a_mpll_prediv = { - .mult = 1, - .div = 2, - .hw.init = &(struct clk_init_data){ - .name = "mpll_prediv", - .ops = &clk_fixed_factor_ops, - .parent_hws = (const struct clk_hw *[]) { - &g12a_fixed_pll_dco.hw - }, - .num_parents = 1, - }, -}; - static const struct reg_sequence g12a_mpll0_init_regs[] = { { .reg = HHI_MPLL_CNTL2, .def = 0x40000033 }, }; @@ -2530,8 +2507,9 @@ static struct clk_regmap g12a_mpll3 = { }, }; -static u32 mux_table_clk81[] = { 0, 2, 3, 4, 5, 6, 7 }; -static const struct clk_parent_data clk81_parent_data[] = { +/* clk81 is often referred as "mpeg_clk" */ +static u32 g12a_clk81_parents_val_table[] = { 0, 2, 3, 4, 5, 6, 7 }; +static const struct clk_parent_data g12a_clk81_parents[] = { { .fw_name = "xtal", }, { .hw = &g12a_fclk_div7.hw }, { .hw = &g12a_mpll1.hw }, @@ -2541,32 +2519,32 @@ static const struct clk_parent_data clk81_parent_data[] = { { .hw = &g12a_fclk_div5.hw }, }; -static struct clk_regmap g12a_mpeg_clk_sel = { +static struct clk_regmap g12a_clk81_sel = { .data = &(struct clk_regmap_mux_data){ .offset = HHI_MPEG_CLK_CNTL, .mask = 0x7, .shift = 12, - .table = mux_table_clk81, + .table = g12a_clk81_parents_val_table, }, .hw.init = &(struct clk_init_data){ - .name = "mpeg_clk_sel", + .name = "clk81_sel", .ops = &clk_regmap_mux_ro_ops, - .parent_data = clk81_parent_data, - .num_parents = ARRAY_SIZE(clk81_parent_data), + .parent_data = g12a_clk81_parents, + .num_parents = ARRAY_SIZE(g12a_clk81_parents), }, }; -static struct clk_regmap g12a_mpeg_clk_div = { +static struct clk_regmap g12a_clk81_div = { .data = &(struct clk_regmap_div_data){ .offset = HHI_MPEG_CLK_CNTL, .shift = 0, .width = 7, }, .hw.init = &(struct clk_init_data){ - .name = "mpeg_clk_div", + .name = "clk81_div", .ops = &clk_regmap_divider_ops, .parent_hws = (const struct clk_hw *[]) { - &g12a_mpeg_clk_sel.hw + &g12a_clk81_sel.hw }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, @@ -2582,14 +2560,14 @@ static struct clk_regmap g12a_clk81 = { .name = "clk81", .ops = &clk_regmap_gate_ops, .parent_hws = (const struct clk_hw *[]) { - &g12a_mpeg_clk_div.hw + &g12a_clk81_div.hw }, .num_parents = 1, .flags = (CLK_SET_RATE_PARENT | CLK_IS_CRITICAL), }, }; -static const struct clk_parent_data g12a_sd_emmc_clk0_parent_data[] = { +static const struct clk_parent_data g12a_sd_emmc_clk0_parents[] = { { .fw_name = "xtal", }, { .hw = &g12a_fclk_div2.hw }, { .hw = &g12a_fclk_div3.hw }, @@ -2613,8 +2591,8 @@ static struct clk_regmap g12a_sd_emmc_a_clk0_sel = { .hw.init = &(struct clk_init_data) { .name = "sd_emmc_a_clk0_sel", .ops = &clk_regmap_mux_ops, - .parent_data = g12a_sd_emmc_clk0_parent_data, - .num_parents = ARRAY_SIZE(g12a_sd_emmc_clk0_parent_data), + .parent_data = g12a_sd_emmc_clk0_parents, + .num_parents = ARRAY_SIZE(g12a_sd_emmc_clk0_parents), .flags = CLK_SET_RATE_PARENT, }, }; @@ -2662,8 +2640,8 @@ static struct clk_regmap g12a_sd_emmc_b_clk0_sel = { .hw.init = &(struct clk_init_data) { .name = "sd_emmc_b_clk0_sel", .ops = &clk_regmap_mux_ops, - .parent_data = g12a_sd_emmc_clk0_parent_data, - .num_parents = ARRAY_SIZE(g12a_sd_emmc_clk0_parent_data), + .parent_data = g12a_sd_emmc_clk0_parents, + .num_parents = ARRAY_SIZE(g12a_sd_emmc_clk0_parents), .flags = CLK_SET_RATE_PARENT, }, }; @@ -2711,8 +2689,8 @@ static struct clk_regmap g12a_sd_emmc_c_clk0_sel = { .hw.init = &(struct clk_init_data) { .name = "sd_emmc_c_clk0_sel", .ops = &clk_regmap_mux_ops, - .parent_data = g12a_sd_emmc_clk0_parent_data, - .num_parents = ARRAY_SIZE(g12a_sd_emmc_clk0_parent_data), + .parent_data = g12a_sd_emmc_clk0_parents, + .num_parents = ARRAY_SIZE(g12a_sd_emmc_clk0_parents), .flags = CLK_SET_RATE_PARENT, }, }; @@ -2774,7 +2752,7 @@ static struct clk_regmap g12a_vid_pll_div = { }, }; -static const struct clk_hw *g12a_vid_pll_parent_hws[] = { +static const struct clk_hw *g12a_vid_pll_parents[] = { &g12a_vid_pll_div.hw, &g12a_hdmi_pll.hw, }; @@ -2792,8 +2770,8 @@ static struct clk_regmap g12a_vid_pll_sel = { * bit 18 selects from 2 possible parents: * vid_pll_div or hdmi_pll */ - .parent_hws = g12a_vid_pll_parent_hws, - .num_parents = ARRAY_SIZE(g12a_vid_pll_parent_hws), + .parent_hws = g12a_vid_pll_parents, + .num_parents = ARRAY_SIZE(g12a_vid_pll_parents), .flags = CLK_SET_RATE_NO_REPARENT | CLK_GET_RATE_NOCACHE, }, }; @@ -2816,7 +2794,7 @@ static struct clk_regmap g12a_vid_pll = { /* VPU Clock */ -static const struct clk_hw *g12a_vpu_parent_hws[] = { +static const struct clk_hw *g12a_vpu_parents[] = { &g12a_fclk_div3.hw, &g12a_fclk_div4.hw, &g12a_fclk_div5.hw, @@ -2836,8 +2814,8 @@ static struct clk_regmap g12a_vpu_0_sel = { .hw.init = &(struct clk_init_data){ .name = "vpu_0_sel", .ops = &clk_regmap_mux_ops, - .parent_hws = g12a_vpu_parent_hws, - .num_parents = ARRAY_SIZE(g12a_vpu_parent_hws), + .parent_hws = g12a_vpu_parents, + .num_parents = ARRAY_SIZE(g12a_vpu_parents), .flags = CLK_SET_RATE_NO_REPARENT, }, }; @@ -2880,8 +2858,8 @@ static struct clk_regmap g12a_vpu_1_sel = { .hw.init = &(struct clk_init_data){ .name = "vpu_1_sel", .ops = &clk_regmap_mux_ops, - .parent_hws = g12a_vpu_parent_hws, - .num_parents = ARRAY_SIZE(g12a_vpu_parent_hws), + .parent_hws = g12a_vpu_parents, + .num_parents = ARRAY_SIZE(g12a_vpu_parents), .flags = CLK_SET_RATE_NO_REPARENT, }, }; @@ -2939,7 +2917,7 @@ static struct clk_regmap g12a_vpu = { /* VDEC clocks */ -static const struct clk_hw *g12a_vdec_parent_hws[] = { +static const struct clk_hw *g12a_vdec_parents[] = { &g12a_fclk_div2p5.hw, &g12a_fclk_div3.hw, &g12a_fclk_div4.hw, @@ -2959,8 +2937,8 @@ static struct clk_regmap g12a_vdec_1_sel = { .hw.init = &(struct clk_init_data){ .name = "vdec_1_sel", .ops = &clk_regmap_mux_ops, - .parent_hws = g12a_vdec_parent_hws, - .num_parents = ARRAY_SIZE(g12a_vdec_parent_hws), + .parent_hws = g12a_vdec_parents, + .num_parents = ARRAY_SIZE(g12a_vdec_parents), .flags = CLK_SET_RATE_PARENT, }, }; @@ -3009,8 +2987,8 @@ static struct clk_regmap g12a_vdec_hevcf_sel = { .hw.init = &(struct clk_init_data){ .name = "vdec_hevcf_sel", .ops = &clk_regmap_mux_ops, - .parent_hws = g12a_vdec_parent_hws, - .num_parents = ARRAY_SIZE(g12a_vdec_parent_hws), + .parent_hws = g12a_vdec_parents, + .num_parents = ARRAY_SIZE(g12a_vdec_parents), .flags = CLK_SET_RATE_PARENT, }, }; @@ -3059,8 +3037,8 @@ static struct clk_regmap g12a_vdec_hevc_sel = { .hw.init = &(struct clk_init_data){ .name = "vdec_hevc_sel", .ops = &clk_regmap_mux_ops, - .parent_hws = g12a_vdec_parent_hws, - .num_parents = ARRAY_SIZE(g12a_vdec_parent_hws), + .parent_hws = g12a_vdec_parents, + .num_parents = ARRAY_SIZE(g12a_vdec_parents), .flags = CLK_SET_RATE_PARENT, }, }; @@ -3101,7 +3079,7 @@ static struct clk_regmap g12a_vdec_hevc = { /* VAPB Clock */ -static const struct clk_hw *g12a_vapb_parent_hws[] = { +static const struct clk_hw *g12a_vapb_parents[] = { &g12a_fclk_div4.hw, &g12a_fclk_div3.hw, &g12a_fclk_div5.hw, @@ -3121,8 +3099,8 @@ static struct clk_regmap g12a_vapb_0_sel = { .hw.init = &(struct clk_init_data){ .name = "vapb_0_sel", .ops = &clk_regmap_mux_ops, - .parent_hws = g12a_vapb_parent_hws, - .num_parents = ARRAY_SIZE(g12a_vapb_parent_hws), + .parent_hws = g12a_vapb_parents, + .num_parents = ARRAY_SIZE(g12a_vapb_parents), .flags = CLK_SET_RATE_NO_REPARENT, }, }; @@ -3169,8 +3147,8 @@ static struct clk_regmap g12a_vapb_1_sel = { .hw.init = &(struct clk_init_data){ .name = "vapb_1_sel", .ops = &clk_regmap_mux_ops, - .parent_hws = g12a_vapb_parent_hws, - .num_parents = ARRAY_SIZE(g12a_vapb_parent_hws), + .parent_hws = g12a_vapb_parents, + .num_parents = ARRAY_SIZE(g12a_vapb_parents), .flags = CLK_SET_RATE_NO_REPARENT, }, }; @@ -3244,7 +3222,7 @@ static struct clk_regmap g12a_vapb = { }, }; -static const struct clk_hw *g12a_vclk_parent_hws[] = { +static const struct clk_hw *g12a_vclk_parents[] = { &g12a_vid_pll.hw, &g12a_gp0_pll.hw, &g12a_hifi_pll.hw, @@ -3264,8 +3242,8 @@ static struct clk_regmap g12a_vclk_sel = { .hw.init = &(struct clk_init_data){ .name = "vclk_sel", .ops = &clk_regmap_mux_ops, - .parent_hws = g12a_vclk_parent_hws, - .num_parents = ARRAY_SIZE(g12a_vclk_parent_hws), + .parent_hws = g12a_vclk_parents, + .num_parents = ARRAY_SIZE(g12a_vclk_parents), .flags = CLK_SET_RATE_NO_REPARENT | CLK_GET_RATE_NOCACHE, }, }; @@ -3279,8 +3257,8 @@ static struct clk_regmap g12a_vclk2_sel = { .hw.init = &(struct clk_init_data){ .name = "vclk2_sel", .ops = &clk_regmap_mux_ops, - .parent_hws = g12a_vclk_parent_hws, - .num_parents = ARRAY_SIZE(g12a_vclk_parent_hws), + .parent_hws = g12a_vclk_parents, + .num_parents = ARRAY_SIZE(g12a_vclk_parents), .flags = CLK_SET_RATE_NO_REPARENT, }, }; @@ -3643,8 +3621,8 @@ static struct clk_fixed_factor g12a_vclk2_div12 = { }, }; -static u32 mux_table_cts_sel[] = { 0, 1, 2, 3, 4, 8, 9, 10, 11, 12 }; -static const struct clk_hw *g12a_cts_parent_hws[] = { +static u32 g12a_cts_parents_val_table[] = { 0, 1, 2, 3, 4, 8, 9, 10, 11, 12 }; +static const struct clk_hw *g12a_cts_parents[] = { &g12a_vclk_div1.hw, &g12a_vclk_div2.hw, &g12a_vclk_div4.hw, @@ -3662,13 +3640,13 @@ static struct clk_regmap g12a_cts_enci_sel = { .offset = HHI_VID_CLK_DIV, .mask = 0xf, .shift = 28, - .table = mux_table_cts_sel, + .table = g12a_cts_parents_val_table, }, .hw.init = &(struct clk_init_data){ .name = "cts_enci_sel", .ops = &clk_regmap_mux_ops, - .parent_hws = g12a_cts_parent_hws, - .num_parents = ARRAY_SIZE(g12a_cts_parent_hws), + .parent_hws = g12a_cts_parents, + .num_parents = ARRAY_SIZE(g12a_cts_parents), .flags = CLK_SET_RATE_NO_REPARENT | CLK_GET_RATE_NOCACHE, }, }; @@ -3678,13 +3656,13 @@ static struct clk_regmap g12a_cts_encp_sel = { .offset = HHI_VID_CLK_DIV, .mask = 0xf, .shift = 20, - .table = mux_table_cts_sel, + .table = g12a_cts_parents_val_table, }, .hw.init = &(struct clk_init_data){ .name = "cts_encp_sel", .ops = &clk_regmap_mux_ops, - .parent_hws = g12a_cts_parent_hws, - .num_parents = ARRAY_SIZE(g12a_cts_parent_hws), + .parent_hws = g12a_cts_parents, + .num_parents = ARRAY_SIZE(g12a_cts_parents), .flags = CLK_SET_RATE_NO_REPARENT | CLK_GET_RATE_NOCACHE, }, }; @@ -3694,13 +3672,13 @@ static struct clk_regmap g12a_cts_encl_sel = { .offset = HHI_VIID_CLK_DIV, .mask = 0xf, .shift = 12, - .table = mux_table_cts_sel, + .table = g12a_cts_parents_val_table, }, .hw.init = &(struct clk_init_data){ .name = "cts_encl_sel", .ops = &clk_regmap_mux_ops, - .parent_hws = g12a_cts_parent_hws, - .num_parents = ARRAY_SIZE(g12a_cts_parent_hws), + .parent_hws = g12a_cts_parents, + .num_parents = ARRAY_SIZE(g12a_cts_parents), .flags = CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT, }, }; @@ -3710,20 +3688,20 @@ static struct clk_regmap g12a_cts_vdac_sel = { .offset = HHI_VIID_CLK_DIV, .mask = 0xf, .shift = 28, - .table = mux_table_cts_sel, + .table = g12a_cts_parents_val_table, }, .hw.init = &(struct clk_init_data){ .name = "cts_vdac_sel", .ops = &clk_regmap_mux_ops, - .parent_hws = g12a_cts_parent_hws, - .num_parents = ARRAY_SIZE(g12a_cts_parent_hws), + .parent_hws = g12a_cts_parents, + .num_parents = ARRAY_SIZE(g12a_cts_parents), .flags = CLK_SET_RATE_NO_REPARENT | CLK_GET_RATE_NOCACHE, }, }; /* TOFIX: add support for cts_tcon */ -static u32 mux_table_hdmi_tx_sel[] = { 0, 1, 2, 3, 4, 8, 9, 10, 11, 12 }; -static const struct clk_hw *g12a_cts_hdmi_tx_parent_hws[] = { +static u32 g12a_hdmi_tx_parents_val_table[] = { 0, 1, 2, 3, 4, 8, 9, 10, 11, 12 }; +static const struct clk_hw *g12a_hdmi_tx_parents[] = { &g12a_vclk_div1.hw, &g12a_vclk_div2.hw, &g12a_vclk_div4.hw, @@ -3741,13 +3719,13 @@ static struct clk_regmap g12a_hdmi_tx_sel = { .offset = HHI_HDMI_CLK_CNTL, .mask = 0xf, .shift = 16, - .table = mux_table_hdmi_tx_sel, + .table = g12a_hdmi_tx_parents_val_table, }, .hw.init = &(struct clk_init_data){ .name = "hdmi_tx_sel", .ops = &clk_regmap_mux_ops, - .parent_hws = g12a_cts_hdmi_tx_parent_hws, - .num_parents = ARRAY_SIZE(g12a_cts_hdmi_tx_parent_hws), + .parent_hws = g12a_hdmi_tx_parents, + .num_parents = ARRAY_SIZE(g12a_hdmi_tx_parents), .flags = CLK_SET_RATE_NO_REPARENT | CLK_GET_RATE_NOCACHE, }, }; @@ -3834,7 +3812,7 @@ static struct clk_regmap g12a_hdmi_tx = { /* MIPI DSI Host Clocks */ -static const struct clk_hw *g12a_mipi_dsi_pxclk_parent_hws[] = { +static const struct clk_hw *g12a_mipi_dsi_pxclk_parents[] = { &g12a_vid_pll.hw, &g12a_gp0_pll.hw, &g12a_hifi_pll.hw, @@ -3855,8 +3833,8 @@ static struct clk_regmap g12a_mipi_dsi_pxclk_sel = { .hw.init = &(struct clk_init_data){ .name = "mipi_dsi_pxclk_sel", .ops = &clk_regmap_mux_ops, - .parent_hws = g12a_mipi_dsi_pxclk_parent_hws, - .num_parents = ARRAY_SIZE(g12a_mipi_dsi_pxclk_parent_hws), + .parent_hws = g12a_mipi_dsi_pxclk_parents, + .num_parents = ARRAY_SIZE(g12a_mipi_dsi_pxclk_parents), .flags = CLK_SET_RATE_NO_REPARENT | CLK_SET_RATE_PARENT, }, }; @@ -3907,7 +3885,7 @@ static struct clk_regmap g12a_mipi_dsi_pxclk = { /* MIPI ISP Clocks */ -static const struct clk_parent_data g12b_mipi_isp_parent_data[] = { +static const struct clk_parent_data g12b_mipi_isp_parents[] = { { .fw_name = "xtal", }, { .hw = &g12a_gp0_pll.hw }, { .hw = &g12a_hifi_pll.hw }, @@ -3927,8 +3905,8 @@ static struct clk_regmap g12b_mipi_isp_sel = { .hw.init = &(struct clk_init_data){ .name = "mipi_isp_sel", .ops = &clk_regmap_mux_ops, - .parent_data = g12b_mipi_isp_parent_data, - .num_parents = ARRAY_SIZE(g12b_mipi_isp_parent_data), + .parent_data = g12b_mipi_isp_parents, + .num_parents = ARRAY_SIZE(g12b_mipi_isp_parents), }, }; @@ -3967,7 +3945,7 @@ static struct clk_regmap g12b_mipi_isp = { /* HDMI Clocks */ -static const struct clk_parent_data g12a_hdmi_parent_data[] = { +static const struct clk_parent_data g12a_hdmi_parents[] = { { .fw_name = "xtal", }, { .hw = &g12a_fclk_div4.hw }, { .hw = &g12a_fclk_div3.hw }, @@ -3984,8 +3962,8 @@ static struct clk_regmap g12a_hdmi_sel = { .hw.init = &(struct clk_init_data){ .name = "hdmi_sel", .ops = &clk_regmap_mux_ops, - .parent_data = g12a_hdmi_parent_data, - .num_parents = ARRAY_SIZE(g12a_hdmi_parent_data), + .parent_data = g12a_hdmi_parents, + .num_parents = ARRAY_SIZE(g12a_hdmi_parents), .flags = CLK_SET_RATE_NO_REPARENT | CLK_GET_RATE_NOCACHE, }, }; @@ -4025,7 +4003,7 @@ static struct clk_regmap g12a_hdmi = { * mux because it does top-to-bottom updates the each clock tree and * switches to the "inactive" one when CLK_SET_RATE_GATE is set. */ -static const struct clk_parent_data g12a_mali_0_1_parent_data[] = { +static const struct clk_parent_data g12a_mali_parents[] = { { .fw_name = "xtal", }, { .hw = &g12a_gp0_pll.hw }, { .hw = &g12a_hifi_pll.hw }, @@ -4045,8 +4023,8 @@ static struct clk_regmap g12a_mali_0_sel = { .hw.init = &(struct clk_init_data){ .name = "mali_0_sel", .ops = &clk_regmap_mux_ops, - .parent_data = g12a_mali_0_1_parent_data, - .num_parents = 8, + .parent_data = g12a_mali_parents, + .num_parents = ARRAY_SIZE(g12a_mali_parents), /* * Don't request the parent to change the rate because * all GPU frequencies can be derived from the fclk_* @@ -4099,8 +4077,8 @@ static struct clk_regmap g12a_mali_1_sel = { .hw.init = &(struct clk_init_data){ .name = "mali_1_sel", .ops = &clk_regmap_mux_ops, - .parent_data = g12a_mali_0_1_parent_data, - .num_parents = 8, + .parent_data = g12a_mali_parents, + .num_parents = ARRAY_SIZE(g12a_mali_parents), /* * Don't request the parent to change the rate because * all GPU frequencies can be derived from the fclk_* @@ -4144,11 +4122,6 @@ static struct clk_regmap g12a_mali_1 = { }, }; -static const struct clk_hw *g12a_mali_parent_hws[] = { - &g12a_mali_0.hw, - &g12a_mali_1.hw, -}; - static struct clk_regmap g12a_mali = { .data = &(struct clk_regmap_mux_data){ .offset = HHI_MALI_CLK_CNTL, @@ -4158,7 +4131,10 @@ static struct clk_regmap g12a_mali = { .hw.init = &(struct clk_init_data){ .name = "mali", .ops = &clk_regmap_mux_ops, - .parent_hws = g12a_mali_parent_hws, + .parent_hws = (const struct clk_hw *[]) { + &g12a_mali_0.hw, + &g12a_mali_1.hw, + }, .num_parents = 2, .flags = CLK_SET_RATE_PARENT, }, @@ -4197,7 +4173,7 @@ static struct clk_regmap g12a_ts = { /* SPICC SCLK source clock */ -static const struct clk_parent_data spicc_sclk_parent_data[] = { +static const struct clk_parent_data g12a_spicc_sclk_parents[] = { { .fw_name = "xtal", }, { .hw = &g12a_clk81.hw }, { .hw = &g12a_fclk_div4.hw }, @@ -4216,8 +4192,8 @@ static struct clk_regmap g12a_spicc0_sclk_sel = { .hw.init = &(struct clk_init_data){ .name = "spicc0_sclk_sel", .ops = &clk_regmap_mux_ops, - .parent_data = spicc_sclk_parent_data, - .num_parents = ARRAY_SIZE(spicc_sclk_parent_data), + .parent_data = g12a_spicc_sclk_parents, + .num_parents = ARRAY_SIZE(g12a_spicc_sclk_parents), }, }; @@ -4263,8 +4239,8 @@ static struct clk_regmap g12a_spicc1_sclk_sel = { .hw.init = &(struct clk_init_data){ .name = "spicc1_sclk_sel", .ops = &clk_regmap_mux_ops, - .parent_data = spicc_sclk_parent_data, - .num_parents = ARRAY_SIZE(spicc_sclk_parent_data), + .parent_data = g12a_spicc_sclk_parents, + .num_parents = ARRAY_SIZE(g12a_spicc_sclk_parents), }, }; @@ -4303,7 +4279,7 @@ static struct clk_regmap g12a_spicc1_sclk = { /* Neural Network Accelerator source clock */ -static const struct clk_parent_data nna_clk_parent_data[] = { +static const struct clk_parent_data sm1_nna_clk_parents[] = { { .fw_name = "xtal", }, { .hw = &g12a_gp0_pll.hw, }, { .hw = &g12a_hifi_pll.hw, }, @@ -4323,8 +4299,8 @@ static struct clk_regmap sm1_nna_axi_clk_sel = { .hw.init = &(struct clk_init_data){ .name = "nna_axi_clk_sel", .ops = &clk_regmap_mux_ops, - .parent_data = nna_clk_parent_data, - .num_parents = ARRAY_SIZE(nna_clk_parent_data), + .parent_data = sm1_nna_clk_parents, + .num_parents = ARRAY_SIZE(sm1_nna_clk_parents), }, }; @@ -4370,8 +4346,8 @@ static struct clk_regmap sm1_nna_core_clk_sel = { .hw.init = &(struct clk_init_data){ .name = "nna_core_clk_sel", .ops = &clk_regmap_mux_ops, - .parent_data = nna_clk_parent_data, - .num_parents = ARRAY_SIZE(nna_clk_parent_data), + .parent_data = sm1_nna_clk_parents, + .num_parents = ARRAY_SIZE(sm1_nna_clk_parents), }, }; @@ -4408,89 +4384,101 @@ static struct clk_regmap sm1_nna_core_clk = { }, }; -#define MESON_GATE(_name, _reg, _bit) \ - MESON_PCLK(_name, _reg, _bit, &g12a_clk81.hw) - -#define MESON_GATE_RO(_name, _reg, _bit) \ - MESON_PCLK_RO(_name, _reg, _bit, &g12a_clk81.hw) - -/* Everything Else (EE) domain gates */ -static MESON_GATE(g12a_ddr, HHI_GCLK_MPEG0, 0); -static MESON_GATE(g12a_dos, HHI_GCLK_MPEG0, 1); -static MESON_GATE(g12a_audio_locker, HHI_GCLK_MPEG0, 2); -static MESON_GATE(g12a_mipi_dsi_host, HHI_GCLK_MPEG0, 3); -static MESON_GATE(g12a_eth_phy, HHI_GCLK_MPEG0, 4); -static MESON_GATE(g12a_isa, HHI_GCLK_MPEG0, 5); -static MESON_GATE(g12a_pl301, HHI_GCLK_MPEG0, 6); -static MESON_GATE(g12a_periphs, HHI_GCLK_MPEG0, 7); -static MESON_GATE(g12a_spicc_0, HHI_GCLK_MPEG0, 8); -static MESON_GATE(g12a_i2c, HHI_GCLK_MPEG0, 9); -static MESON_GATE(g12a_sana, HHI_GCLK_MPEG0, 10); -static MESON_GATE(g12a_sd, HHI_GCLK_MPEG0, 11); -static MESON_GATE(g12a_rng0, HHI_GCLK_MPEG0, 12); -static MESON_GATE(g12a_uart0, HHI_GCLK_MPEG0, 13); -static MESON_GATE(g12a_spicc_1, HHI_GCLK_MPEG0, 14); -static MESON_GATE(g12a_hiu_reg, HHI_GCLK_MPEG0, 19); -static MESON_GATE(g12a_mipi_dsi_phy, HHI_GCLK_MPEG0, 20); -static MESON_GATE(g12a_assist_misc, HHI_GCLK_MPEG0, 23); -static MESON_GATE(g12a_emmc_a, HHI_GCLK_MPEG0, 24); -static MESON_GATE(g12a_emmc_b, HHI_GCLK_MPEG0, 25); -static MESON_GATE(g12a_emmc_c, HHI_GCLK_MPEG0, 26); -static MESON_GATE(g12a_audio_codec, HHI_GCLK_MPEG0, 28); - -static MESON_GATE(g12a_audio, HHI_GCLK_MPEG1, 0); -static MESON_GATE(g12a_eth_core, HHI_GCLK_MPEG1, 3); -static MESON_GATE(g12a_demux, HHI_GCLK_MPEG1, 4); -static MESON_GATE(g12a_audio_ififo, HHI_GCLK_MPEG1, 11); -static MESON_GATE(g12a_adc, HHI_GCLK_MPEG1, 13); -static MESON_GATE(g12a_uart1, HHI_GCLK_MPEG1, 16); -static MESON_GATE(g12a_g2d, HHI_GCLK_MPEG1, 20); -static MESON_GATE(g12a_reset, HHI_GCLK_MPEG1, 23); -static MESON_GATE(g12a_pcie_comb, HHI_GCLK_MPEG1, 24); -static MESON_GATE(g12a_parser, HHI_GCLK_MPEG1, 25); -static MESON_GATE(g12a_usb_general, HHI_GCLK_MPEG1, 26); -static MESON_GATE(g12a_pcie_phy, HHI_GCLK_MPEG1, 27); -static MESON_GATE(g12a_ahb_arb0, HHI_GCLK_MPEG1, 29); - -static MESON_GATE(g12a_ahb_data_bus, HHI_GCLK_MPEG2, 1); -static MESON_GATE(g12a_ahb_ctrl_bus, HHI_GCLK_MPEG2, 2); -static MESON_GATE(g12a_htx_hdcp22, HHI_GCLK_MPEG2, 3); -static MESON_GATE(g12a_htx_pclk, HHI_GCLK_MPEG2, 4); -static MESON_GATE(g12a_bt656, HHI_GCLK_MPEG2, 6); -static MESON_GATE(g12a_usb1_to_ddr, HHI_GCLK_MPEG2, 8); -static MESON_GATE(g12b_mipi_isp_gate, HHI_GCLK_MPEG2, 17); -static MESON_GATE(g12a_mmc_pclk, HHI_GCLK_MPEG2, 11); -static MESON_GATE(g12a_uart2, HHI_GCLK_MPEG2, 15); -static MESON_GATE(g12a_vpu_intr, HHI_GCLK_MPEG2, 25); -static MESON_GATE(g12b_csi_phy1, HHI_GCLK_MPEG2, 28); -static MESON_GATE(g12b_csi_phy0, HHI_GCLK_MPEG2, 29); -static MESON_GATE(g12a_gic, HHI_GCLK_MPEG2, 30); - -static MESON_GATE(g12a_vclk2_venci0, HHI_GCLK_OTHER, 1); -static MESON_GATE(g12a_vclk2_venci1, HHI_GCLK_OTHER, 2); -static MESON_GATE(g12a_vclk2_vencp0, HHI_GCLK_OTHER, 3); -static MESON_GATE(g12a_vclk2_vencp1, HHI_GCLK_OTHER, 4); -static MESON_GATE(g12a_vclk2_venct0, HHI_GCLK_OTHER, 5); -static MESON_GATE(g12a_vclk2_venct1, HHI_GCLK_OTHER, 6); -static MESON_GATE(g12a_vclk2_other, HHI_GCLK_OTHER, 7); -static MESON_GATE(g12a_vclk2_enci, HHI_GCLK_OTHER, 8); -static MESON_GATE(g12a_vclk2_encp, HHI_GCLK_OTHER, 9); -static MESON_GATE(g12a_dac_clk, HHI_GCLK_OTHER, 10); -static MESON_GATE(g12a_aoclk_gate, HHI_GCLK_OTHER, 14); -static MESON_GATE(g12a_iec958_gate, HHI_GCLK_OTHER, 16); -static MESON_GATE(g12a_enc480p, HHI_GCLK_OTHER, 20); -static MESON_GATE(g12a_rng1, HHI_GCLK_OTHER, 21); -static MESON_GATE(g12a_vclk2_enct, HHI_GCLK_OTHER, 22); -static MESON_GATE(g12a_vclk2_encl, HHI_GCLK_OTHER, 23); -static MESON_GATE(g12a_vclk2_venclmmc, HHI_GCLK_OTHER, 24); -static MESON_GATE(g12a_vclk2_vencl, HHI_GCLK_OTHER, 25); -static MESON_GATE(g12a_vclk2_other1, HHI_GCLK_OTHER, 26); - -static MESON_GATE_RO(g12a_dma, HHI_GCLK_OTHER2, 0); -static MESON_GATE_RO(g12a_efuse, HHI_GCLK_OTHER2, 1); -static MESON_GATE_RO(g12a_rom_boot, HHI_GCLK_OTHER2, 2); -static MESON_GATE_RO(g12a_reset_sec, HHI_GCLK_OTHER2, 3); -static MESON_GATE_RO(g12a_sec_ahb_apb3, HHI_GCLK_OTHER2, 4); +static const struct clk_parent_data g12a_pclk_parents = { .hw = &g12a_clk81.hw }; + +#define G12A_PCLK(_name, _reg, _bit, _flags) \ + MESON_PCLK(_name, _reg, _bit, &g12a_pclk_parents, _flags) + +#define G12A_PCLK_RO(_name, _reg, _bit, _flags) \ + MESON_PCLK_RO(_name, _reg, _bit, &g12a_pclk_parents, _flags) + +/* + * Everything Else (EE) domain gates + * + * NOTE: The gates below are marked with CLK_IGNORE_UNUSED for historic reasons + * Users are encouraged to test without it and submit changes to: + * - remove the flag if not necessary + * - replace the flag with something more adequate, such as CLK_IS_CRITICAL, + * if appropriate. + * - add a comment explaining why the use of CLK_IGNORE_UNUSED is desirable + * for a particular clock. + */ +static G12A_PCLK(g12a_ddr, HHI_GCLK_MPEG0, 0, CLK_IGNORE_UNUSED); +static G12A_PCLK(g12a_dos, HHI_GCLK_MPEG0, 1, CLK_IGNORE_UNUSED); +static G12A_PCLK(g12a_audio_locker, HHI_GCLK_MPEG0, 2, CLK_IGNORE_UNUSED); +static G12A_PCLK(g12a_mipi_dsi_host, HHI_GCLK_MPEG0, 3, CLK_IGNORE_UNUSED); +static G12A_PCLK(g12a_eth_phy, HHI_GCLK_MPEG0, 4, CLK_IGNORE_UNUSED); +static G12A_PCLK(g12a_isa, HHI_GCLK_MPEG0, 5, CLK_IGNORE_UNUSED); +static G12A_PCLK(g12a_pl301, HHI_GCLK_MPEG0, 6, CLK_IGNORE_UNUSED); +static G12A_PCLK(g12a_periphs, HHI_GCLK_MPEG0, 7, CLK_IGNORE_UNUSED); +static G12A_PCLK(g12a_spicc_0, HHI_GCLK_MPEG0, 8, CLK_IGNORE_UNUSED); +static G12A_PCLK(g12a_i2c, HHI_GCLK_MPEG0, 9, CLK_IGNORE_UNUSED); +static G12A_PCLK(g12a_sana, HHI_GCLK_MPEG0, 10, CLK_IGNORE_UNUSED); +static G12A_PCLK(g12a_sd, HHI_GCLK_MPEG0, 11, CLK_IGNORE_UNUSED); +static G12A_PCLK(g12a_rng0, HHI_GCLK_MPEG0, 12, CLK_IGNORE_UNUSED); +static G12A_PCLK(g12a_uart0, HHI_GCLK_MPEG0, 13, CLK_IGNORE_UNUSED); +static G12A_PCLK(g12a_spicc_1, HHI_GCLK_MPEG0, 14, CLK_IGNORE_UNUSED); +static G12A_PCLK(g12a_hiu_reg, HHI_GCLK_MPEG0, 19, CLK_IGNORE_UNUSED); +static G12A_PCLK(g12a_mipi_dsi_phy, HHI_GCLK_MPEG0, 20, CLK_IGNORE_UNUSED); +static G12A_PCLK(g12a_assist_misc, HHI_GCLK_MPEG0, 23, CLK_IGNORE_UNUSED); +static G12A_PCLK(g12a_emmc_a, HHI_GCLK_MPEG0, 24, CLK_IGNORE_UNUSED); +static G12A_PCLK(g12a_emmc_b, HHI_GCLK_MPEG0, 25, CLK_IGNORE_UNUSED); +static G12A_PCLK(g12a_emmc_c, HHI_GCLK_MPEG0, 26, CLK_IGNORE_UNUSED); +static G12A_PCLK(g12a_audio_codec, HHI_GCLK_MPEG0, 28, CLK_IGNORE_UNUSED); + +static G12A_PCLK(g12a_audio, HHI_GCLK_MPEG1, 0, CLK_IGNORE_UNUSED); +static G12A_PCLK(g12a_eth_core, HHI_GCLK_MPEG1, 3, CLK_IGNORE_UNUSED); +static G12A_PCLK(g12a_demux, HHI_GCLK_MPEG1, 4, CLK_IGNORE_UNUSED); +static G12A_PCLK(g12a_audio_ififo, HHI_GCLK_MPEG1, 11, CLK_IGNORE_UNUSED); +static G12A_PCLK(g12a_adc, HHI_GCLK_MPEG1, 13, CLK_IGNORE_UNUSED); +static G12A_PCLK(g12a_uart1, HHI_GCLK_MPEG1, 16, CLK_IGNORE_UNUSED); +static G12A_PCLK(g12a_g2d, HHI_GCLK_MPEG1, 20, CLK_IGNORE_UNUSED); +static G12A_PCLK(g12a_reset, HHI_GCLK_MPEG1, 23, CLK_IGNORE_UNUSED); +static G12A_PCLK(g12a_pcie_comb, HHI_GCLK_MPEG1, 24, CLK_IGNORE_UNUSED); +static G12A_PCLK(g12a_parser, HHI_GCLK_MPEG1, 25, CLK_IGNORE_UNUSED); +static G12A_PCLK(g12a_usb_general, HHI_GCLK_MPEG1, 26, CLK_IGNORE_UNUSED); +static G12A_PCLK(g12a_pcie_phy, HHI_GCLK_MPEG1, 27, CLK_IGNORE_UNUSED); +static G12A_PCLK(g12a_ahb_arb0, HHI_GCLK_MPEG1, 29, CLK_IGNORE_UNUSED); + +static G12A_PCLK(g12a_ahb_data_bus, HHI_GCLK_MPEG2, 1, CLK_IGNORE_UNUSED); +static G12A_PCLK(g12a_ahb_ctrl_bus, HHI_GCLK_MPEG2, 2, CLK_IGNORE_UNUSED); +static G12A_PCLK(g12a_htx_hdcp22, HHI_GCLK_MPEG2, 3, CLK_IGNORE_UNUSED); +static G12A_PCLK(g12a_htx_pclk, HHI_GCLK_MPEG2, 4, CLK_IGNORE_UNUSED); +static G12A_PCLK(g12a_bt656, HHI_GCLK_MPEG2, 6, CLK_IGNORE_UNUSED); +static G12A_PCLK(g12a_usb1_to_ddr, HHI_GCLK_MPEG2, 8, CLK_IGNORE_UNUSED); +static G12A_PCLK(g12b_mipi_isp_gate, HHI_GCLK_MPEG2, 17, CLK_IGNORE_UNUSED); +static G12A_PCLK(g12a_mmc_pclk, HHI_GCLK_MPEG2, 11, CLK_IGNORE_UNUSED); +static G12A_PCLK(g12a_uart2, HHI_GCLK_MPEG2, 15, CLK_IGNORE_UNUSED); +static G12A_PCLK(g12a_vpu_intr, HHI_GCLK_MPEG2, 25, CLK_IGNORE_UNUSED); +static G12A_PCLK(g12b_csi_phy1, HHI_GCLK_MPEG2, 28, CLK_IGNORE_UNUSED); +static G12A_PCLK(g12b_csi_phy0, HHI_GCLK_MPEG2, 29, CLK_IGNORE_UNUSED); +static G12A_PCLK(g12a_gic, HHI_GCLK_MPEG2, 30, CLK_IGNORE_UNUSED); + +static G12A_PCLK(g12a_vclk2_venci0, HHI_GCLK_OTHER, 1, CLK_IGNORE_UNUSED); +static G12A_PCLK(g12a_vclk2_venci1, HHI_GCLK_OTHER, 2, CLK_IGNORE_UNUSED); +static G12A_PCLK(g12a_vclk2_vencp0, HHI_GCLK_OTHER, 3, CLK_IGNORE_UNUSED); +static G12A_PCLK(g12a_vclk2_vencp1, HHI_GCLK_OTHER, 4, CLK_IGNORE_UNUSED); +static G12A_PCLK(g12a_vclk2_venct0, HHI_GCLK_OTHER, 5, CLK_IGNORE_UNUSED); +static G12A_PCLK(g12a_vclk2_venct1, HHI_GCLK_OTHER, 6, CLK_IGNORE_UNUSED); +static G12A_PCLK(g12a_vclk2_other, HHI_GCLK_OTHER, 7, CLK_IGNORE_UNUSED); +static G12A_PCLK(g12a_vclk2_enci, HHI_GCLK_OTHER, 8, CLK_IGNORE_UNUSED); +static G12A_PCLK(g12a_vclk2_encp, HHI_GCLK_OTHER, 9, CLK_IGNORE_UNUSED); +static G12A_PCLK(g12a_dac_clk, HHI_GCLK_OTHER, 10, CLK_IGNORE_UNUSED); +static G12A_PCLK(g12a_aoclk_gate, HHI_GCLK_OTHER, 14, CLK_IGNORE_UNUSED); +static G12A_PCLK(g12a_iec958_gate, HHI_GCLK_OTHER, 16, CLK_IGNORE_UNUSED); +static G12A_PCLK(g12a_enc480p, HHI_GCLK_OTHER, 20, CLK_IGNORE_UNUSED); +static G12A_PCLK(g12a_rng1, HHI_GCLK_OTHER, 21, CLK_IGNORE_UNUSED); +static G12A_PCLK(g12a_vclk2_enct, HHI_GCLK_OTHER, 22, CLK_IGNORE_UNUSED); +static G12A_PCLK(g12a_vclk2_encl, HHI_GCLK_OTHER, 23, CLK_IGNORE_UNUSED); +static G12A_PCLK(g12a_vclk2_venclmmc, HHI_GCLK_OTHER, 24, CLK_IGNORE_UNUSED); +static G12A_PCLK(g12a_vclk2_vencl, HHI_GCLK_OTHER, 25, CLK_IGNORE_UNUSED); +static G12A_PCLK(g12a_vclk2_other1, HHI_GCLK_OTHER, 26, CLK_IGNORE_UNUSED); + +static G12A_PCLK_RO(g12a_dma, HHI_GCLK_OTHER2, 0, 0); +static G12A_PCLK_RO(g12a_efuse, HHI_GCLK_OTHER2, 1, 0); +static G12A_PCLK_RO(g12a_rom_boot, HHI_GCLK_OTHER2, 2, 0); +static G12A_PCLK_RO(g12a_reset_sec, HHI_GCLK_OTHER2, 3, 0); +static G12A_PCLK_RO(g12a_sec_ahb_apb3, HHI_GCLK_OTHER2, 4, 0); /* Array of all clocks provided by this provider */ static struct clk_hw *g12a_hw_clks[] = { @@ -4503,8 +4491,8 @@ static struct clk_hw *g12a_hw_clks[] = { [CLKID_FCLK_DIV7] = &g12a_fclk_div7.hw, [CLKID_FCLK_DIV2P5] = &g12a_fclk_div2p5.hw, [CLKID_GP0_PLL] = &g12a_gp0_pll.hw, - [CLKID_MPEG_SEL] = &g12a_mpeg_clk_sel.hw, - [CLKID_MPEG_DIV] = &g12a_mpeg_clk_div.hw, + [CLKID_MPEG_SEL] = &g12a_clk81_sel.hw, + [CLKID_MPEG_DIV] = &g12a_clk81_div.hw, [CLKID_CLK81] = &g12a_clk81.hw, [CLKID_MPLL0] = &g12a_mpll0.hw, [CLKID_MPLL1] = &g12a_mpll1.hw, @@ -4676,12 +4664,12 @@ static struct clk_hw *g12a_hw_clks[] = { [CLKID_MPLL_50M] = &g12a_mpll_50m.hw, [CLKID_SYS_PLL_DIV16_EN] = &g12a_sys_pll_div16_en.hw, [CLKID_SYS_PLL_DIV16] = &g12a_sys_pll_div16.hw, - [CLKID_CPU_CLK_DYN0_SEL] = &g12a_cpu_clk_premux0.hw, - [CLKID_CPU_CLK_DYN0_DIV] = &g12a_cpu_clk_mux0_div.hw, - [CLKID_CPU_CLK_DYN0] = &g12a_cpu_clk_postmux0.hw, - [CLKID_CPU_CLK_DYN1_SEL] = &g12a_cpu_clk_premux1.hw, - [CLKID_CPU_CLK_DYN1_DIV] = &g12a_cpu_clk_mux1_div.hw, - [CLKID_CPU_CLK_DYN1] = &g12a_cpu_clk_postmux1.hw, + [CLKID_CPU_CLK_DYN0_SEL] = &g12a_cpu_clk_dyn0_sel.hw, + [CLKID_CPU_CLK_DYN0_DIV] = &g12a_cpu_clk_dyn0_div.hw, + [CLKID_CPU_CLK_DYN0] = &g12a_cpu_clk_dyn0.hw, + [CLKID_CPU_CLK_DYN1_SEL] = &g12a_cpu_clk_dyn1_sel.hw, + [CLKID_CPU_CLK_DYN1_DIV] = &g12a_cpu_clk_dyn1_div.hw, + [CLKID_CPU_CLK_DYN1] = &g12a_cpu_clk_dyn1.hw, [CLKID_CPU_CLK_DYN] = &g12a_cpu_clk_dyn.hw, [CLKID_CPU_CLK] = &g12a_cpu_clk.hw, [CLKID_CPU_CLK_DIV16_EN] = &g12a_cpu_clk_div16_en.hw, @@ -4730,8 +4718,8 @@ static struct clk_hw *g12b_hw_clks[] = { [CLKID_FCLK_DIV7] = &g12a_fclk_div7.hw, [CLKID_FCLK_DIV2P5] = &g12a_fclk_div2p5.hw, [CLKID_GP0_PLL] = &g12a_gp0_pll.hw, - [CLKID_MPEG_SEL] = &g12a_mpeg_clk_sel.hw, - [CLKID_MPEG_DIV] = &g12a_mpeg_clk_div.hw, + [CLKID_MPEG_SEL] = &g12a_clk81_sel.hw, + [CLKID_MPEG_DIV] = &g12a_clk81_div.hw, [CLKID_CLK81] = &g12a_clk81.hw, [CLKID_MPLL0] = &g12a_mpll0.hw, [CLKID_MPLL1] = &g12a_mpll1.hw, @@ -4903,12 +4891,12 @@ static struct clk_hw *g12b_hw_clks[] = { [CLKID_MPLL_50M] = &g12a_mpll_50m.hw, [CLKID_SYS_PLL_DIV16_EN] = &g12a_sys_pll_div16_en.hw, [CLKID_SYS_PLL_DIV16] = &g12a_sys_pll_div16.hw, - [CLKID_CPU_CLK_DYN0_SEL] = &g12a_cpu_clk_premux0.hw, - [CLKID_CPU_CLK_DYN0_DIV] = &g12a_cpu_clk_mux0_div.hw, - [CLKID_CPU_CLK_DYN0] = &g12a_cpu_clk_postmux0.hw, - [CLKID_CPU_CLK_DYN1_SEL] = &g12a_cpu_clk_premux1.hw, - [CLKID_CPU_CLK_DYN1_DIV] = &g12a_cpu_clk_mux1_div.hw, - [CLKID_CPU_CLK_DYN1] = &g12a_cpu_clk_postmux1.hw, + [CLKID_CPU_CLK_DYN0_SEL] = &g12a_cpu_clk_dyn0_sel.hw, + [CLKID_CPU_CLK_DYN0_DIV] = &g12a_cpu_clk_dyn0_div.hw, + [CLKID_CPU_CLK_DYN0] = &g12a_cpu_clk_dyn0.hw, + [CLKID_CPU_CLK_DYN1_SEL] = &g12a_cpu_clk_dyn1_sel.hw, + [CLKID_CPU_CLK_DYN1_DIV] = &g12a_cpu_clk_dyn1_div.hw, + [CLKID_CPU_CLK_DYN1] = &g12a_cpu_clk_dyn1.hw, [CLKID_CPU_CLK_DYN] = &g12a_cpu_clk_dyn.hw, [CLKID_CPU_CLK] = &g12b_cpu_clk.hw, [CLKID_CPU_CLK_DIV16_EN] = &g12a_cpu_clk_div16_en.hw, @@ -4940,12 +4928,12 @@ static struct clk_hw *g12b_hw_clks[] = { [CLKID_SYS1_PLL] = &g12b_sys1_pll.hw, [CLKID_SYS1_PLL_DIV16_EN] = &g12b_sys1_pll_div16_en.hw, [CLKID_SYS1_PLL_DIV16] = &g12b_sys1_pll_div16.hw, - [CLKID_CPUB_CLK_DYN0_SEL] = &g12b_cpub_clk_premux0.hw, - [CLKID_CPUB_CLK_DYN0_DIV] = &g12b_cpub_clk_mux0_div.hw, - [CLKID_CPUB_CLK_DYN0] = &g12b_cpub_clk_postmux0.hw, - [CLKID_CPUB_CLK_DYN1_SEL] = &g12b_cpub_clk_premux1.hw, - [CLKID_CPUB_CLK_DYN1_DIV] = &g12b_cpub_clk_mux1_div.hw, - [CLKID_CPUB_CLK_DYN1] = &g12b_cpub_clk_postmux1.hw, + [CLKID_CPUB_CLK_DYN0_SEL] = &g12b_cpub_clk_dyn0_sel.hw, + [CLKID_CPUB_CLK_DYN0_DIV] = &g12b_cpub_clk_dyn0_div.hw, + [CLKID_CPUB_CLK_DYN0] = &g12b_cpub_clk_dyn0.hw, + [CLKID_CPUB_CLK_DYN1_SEL] = &g12b_cpub_clk_dyn1_sel.hw, + [CLKID_CPUB_CLK_DYN1_DIV] = &g12b_cpub_clk_dyn1_div.hw, + [CLKID_CPUB_CLK_DYN1] = &g12b_cpub_clk_dyn1.hw, [CLKID_CPUB_CLK_DYN] = &g12b_cpub_clk_dyn.hw, [CLKID_CPUB_CLK] = &g12b_cpub_clk.hw, [CLKID_CPUB_CLK_DIV16_EN] = &g12b_cpub_clk_div16_en.hw, @@ -4998,8 +4986,8 @@ static struct clk_hw *sm1_hw_clks[] = { [CLKID_FCLK_DIV7] = &g12a_fclk_div7.hw, [CLKID_FCLK_DIV2P5] = &g12a_fclk_div2p5.hw, [CLKID_GP0_PLL] = &g12a_gp0_pll.hw, - [CLKID_MPEG_SEL] = &g12a_mpeg_clk_sel.hw, - [CLKID_MPEG_DIV] = &g12a_mpeg_clk_div.hw, + [CLKID_MPEG_SEL] = &g12a_clk81_sel.hw, + [CLKID_MPEG_DIV] = &g12a_clk81_div.hw, [CLKID_CLK81] = &g12a_clk81.hw, [CLKID_MPLL0] = &g12a_mpll0.hw, [CLKID_MPLL1] = &g12a_mpll1.hw, @@ -5171,12 +5159,12 @@ static struct clk_hw *sm1_hw_clks[] = { [CLKID_MPLL_50M] = &g12a_mpll_50m.hw, [CLKID_SYS_PLL_DIV16_EN] = &g12a_sys_pll_div16_en.hw, [CLKID_SYS_PLL_DIV16] = &g12a_sys_pll_div16.hw, - [CLKID_CPU_CLK_DYN0_SEL] = &g12a_cpu_clk_premux0.hw, - [CLKID_CPU_CLK_DYN0_DIV] = &g12a_cpu_clk_mux0_div.hw, - [CLKID_CPU_CLK_DYN0] = &g12a_cpu_clk_postmux0.hw, - [CLKID_CPU_CLK_DYN1_SEL] = &g12a_cpu_clk_premux1.hw, - [CLKID_CPU_CLK_DYN1_DIV] = &g12a_cpu_clk_mux1_div.hw, - [CLKID_CPU_CLK_DYN1] = &g12a_cpu_clk_postmux1.hw, + [CLKID_CPU_CLK_DYN0_SEL] = &g12a_cpu_clk_dyn0_sel.hw, + [CLKID_CPU_CLK_DYN0_DIV] = &g12a_cpu_clk_dyn0_div.hw, + [CLKID_CPU_CLK_DYN0] = &g12a_cpu_clk_dyn0.hw, + [CLKID_CPU_CLK_DYN1_SEL] = &g12a_cpu_clk_dyn1_sel.hw, + [CLKID_CPU_CLK_DYN1_DIV] = &g12a_cpu_clk_dyn1_div.hw, + [CLKID_CPU_CLK_DYN1] = &g12a_cpu_clk_dyn1.hw, [CLKID_CPU_CLK_DYN] = &g12a_cpu_clk_dyn.hw, [CLKID_CPU_CLK] = &g12a_cpu_clk.hw, [CLKID_CPU_CLK_DIV16_EN] = &g12a_cpu_clk_div16_en.hw, @@ -5206,12 +5194,12 @@ static struct clk_hw *sm1_hw_clks[] = { [CLKID_TS] = &g12a_ts.hw, [CLKID_GP1_PLL_DCO] = &sm1_gp1_pll_dco.hw, [CLKID_GP1_PLL] = &sm1_gp1_pll.hw, - [CLKID_DSU_CLK_DYN0_SEL] = &sm1_dsu_clk_premux0.hw, - [CLKID_DSU_CLK_DYN0_DIV] = &sm1_dsu_clk_premux1.hw, - [CLKID_DSU_CLK_DYN0] = &sm1_dsu_clk_mux0_div.hw, - [CLKID_DSU_CLK_DYN1_SEL] = &sm1_dsu_clk_postmux0.hw, - [CLKID_DSU_CLK_DYN1_DIV] = &sm1_dsu_clk_mux1_div.hw, - [CLKID_DSU_CLK_DYN1] = &sm1_dsu_clk_postmux1.hw, + [CLKID_DSU_CLK_DYN0_SEL] = &sm1_dsu_clk_dyn0_sel.hw, + [CLKID_DSU_CLK_DYN0_DIV] = &sm1_dsu_clk_dyn0_div.hw, + [CLKID_DSU_CLK_DYN0] = &sm1_dsu_clk_dyn0.hw, + [CLKID_DSU_CLK_DYN1_SEL] = &sm1_dsu_clk_dyn1_sel.hw, + [CLKID_DSU_CLK_DYN1_DIV] = &sm1_dsu_clk_dyn1_div.hw, + [CLKID_DSU_CLK_DYN1] = &sm1_dsu_clk_dyn1.hw, [CLKID_DSU_CLK_DYN] = &sm1_dsu_clk_dyn.hw, [CLKID_DSU_CLK_FINAL] = &sm1_dsu_final_clk.hw, [CLKID_DSU_CLK] = &sm1_dsu_clk.hw, @@ -5241,8 +5229,7 @@ static const struct reg_sequence g12a_init_regs[] = { #define DVFS_CON_ID "dvfs" -static int meson_g12a_dvfs_setup_common(struct device *dev, - struct clk_hw **hws) +static int g12a_dvfs_setup_common(struct device *dev, struct clk_hw **hws) { struct clk *notifier_clk; struct clk_hw *xtal; @@ -5251,13 +5238,13 @@ static int meson_g12a_dvfs_setup_common(struct device *dev, xtal = clk_hw_get_parent_by_index(hws[CLKID_CPU_CLK_DYN1_SEL], 0); /* Setup clock notifier for cpu_clk_postmux0 */ - g12a_cpu_clk_postmux0_nb_data.xtal = xtal; - notifier_clk = devm_clk_hw_get_clk(dev, &g12a_cpu_clk_postmux0.hw, + g12a_cpu_clk_dyn0_nb_data.xtal = xtal; + notifier_clk = devm_clk_hw_get_clk(dev, &g12a_cpu_clk_dyn0.hw, DVFS_CON_ID); ret = devm_clk_notifier_register(dev, notifier_clk, - &g12a_cpu_clk_postmux0_nb_data.nb); + &g12a_cpu_clk_dyn0_nb_data.nb); if (ret) { - dev_err(dev, "failed to register the cpu_clk_postmux0 notifier\n"); + dev_err(dev, "failed to register the cpu_clk_dyn0 notifier\n"); return ret; } @@ -5274,7 +5261,7 @@ static int meson_g12a_dvfs_setup_common(struct device *dev, return 0; } -static int meson_g12b_dvfs_setup(struct platform_device *pdev) +static int g12b_dvfs_setup(struct platform_device *pdev) { struct clk_hw **hws = g12b_hw_clks; struct device *dev = &pdev->dev; @@ -5282,7 +5269,7 @@ static int meson_g12b_dvfs_setup(struct platform_device *pdev) struct clk_hw *xtal; int ret; - ret = meson_g12a_dvfs_setup_common(dev, hws); + ret = g12a_dvfs_setup_common(dev, hws); if (ret) return ret; @@ -5311,18 +5298,19 @@ static int meson_g12b_dvfs_setup(struct platform_device *pdev) /* Add notifiers for the second CPU cluster */ /* Setup clock notifier for cpub_clk_postmux0 */ - g12b_cpub_clk_postmux0_nb_data.xtal = xtal; - notifier_clk = devm_clk_hw_get_clk(dev, &g12b_cpub_clk_postmux0.hw, + g12b_cpub_clk_dyn0_nb_data.xtal = xtal; + notifier_clk = devm_clk_hw_get_clk(dev, &g12b_cpub_clk_dyn0.hw, DVFS_CON_ID); ret = devm_clk_notifier_register(dev, notifier_clk, - &g12b_cpub_clk_postmux0_nb_data.nb); + &g12b_cpub_clk_dyn0_nb_data.nb); if (ret) { - dev_err(dev, "failed to register the cpub_clk_postmux0 notifier\n"); + dev_err(dev, "failed to register the cpub_clk_dyn0 notifier\n"); return ret; } /* Setup clock notifier for cpub_clk_dyn mux */ - notifier_clk = devm_clk_hw_get_clk(dev, &g12b_cpub_clk_dyn.hw, "dvfs"); + notifier_clk = devm_clk_hw_get_clk(dev, &g12b_cpub_clk_dyn.hw, + DVFS_CON_ID); ret = devm_clk_notifier_register(dev, notifier_clk, &g12a_cpu_clk_mux_nb); if (ret) { @@ -5351,14 +5339,14 @@ static int meson_g12b_dvfs_setup(struct platform_device *pdev) return 0; } -static int meson_g12a_dvfs_setup(struct platform_device *pdev) +static int g12a_dvfs_setup(struct platform_device *pdev) { struct clk_hw **hws = g12a_hw_clks; struct device *dev = &pdev->dev; struct clk *notifier_clk; int ret; - ret = meson_g12a_dvfs_setup_common(dev, hws); + ret = g12a_dvfs_setup_common(dev, hws); if (ret) return ret; @@ -5383,27 +5371,27 @@ static int meson_g12a_dvfs_setup(struct platform_device *pdev) return 0; } -struct meson_g12a_data { - const struct meson_eeclkc_data eeclkc_data; +struct g12a_clkc_data { + const struct meson_clkc_data clkc_data; int (*dvfs_setup)(struct platform_device *pdev); }; -static int meson_g12a_probe(struct platform_device *pdev) +static int g12a_clkc_probe(struct platform_device *pdev) { - const struct meson_eeclkc_data *eeclkc_data; - const struct meson_g12a_data *g12a_data; + const struct meson_clkc_data *clkc_data; + const struct g12a_clkc_data *g12a_data; int ret; - eeclkc_data = of_device_get_match_data(&pdev->dev); - if (!eeclkc_data) + clkc_data = of_device_get_match_data(&pdev->dev); + if (!clkc_data) return -EINVAL; - ret = meson_eeclkc_probe(pdev); + ret = meson_clkc_syscon_probe(pdev); if (ret) return ret; - g12a_data = container_of(eeclkc_data, struct meson_g12a_data, - eeclkc_data); + g12a_data = container_of(clkc_data, struct g12a_clkc_data, + clkc_data); if (g12a_data->dvfs_setup) return g12a_data->dvfs_setup(pdev); @@ -5411,8 +5399,8 @@ static int meson_g12a_probe(struct platform_device *pdev) return 0; } -static const struct meson_g12a_data g12a_clkc_data = { - .eeclkc_data = { +static const struct g12a_clkc_data g12a_clkc_data = { + .clkc_data = { .hw_clks = { .hws = g12a_hw_clks, .num = ARRAY_SIZE(g12a_hw_clks), @@ -5420,54 +5408,54 @@ static const struct meson_g12a_data g12a_clkc_data = { .init_regs = g12a_init_regs, .init_count = ARRAY_SIZE(g12a_init_regs), }, - .dvfs_setup = meson_g12a_dvfs_setup, + .dvfs_setup = g12a_dvfs_setup, }; -static const struct meson_g12a_data g12b_clkc_data = { - .eeclkc_data = { +static const struct g12a_clkc_data g12b_clkc_data = { + .clkc_data = { .hw_clks = { .hws = g12b_hw_clks, .num = ARRAY_SIZE(g12b_hw_clks), }, }, - .dvfs_setup = meson_g12b_dvfs_setup, + .dvfs_setup = g12b_dvfs_setup, }; -static const struct meson_g12a_data sm1_clkc_data = { - .eeclkc_data = { +static const struct g12a_clkc_data sm1_clkc_data = { + .clkc_data = { .hw_clks = { .hws = sm1_hw_clks, .num = ARRAY_SIZE(sm1_hw_clks), }, }, - .dvfs_setup = meson_g12a_dvfs_setup, + .dvfs_setup = g12a_dvfs_setup, }; -static const struct of_device_id clkc_match_table[] = { +static const struct of_device_id g12a_clkc_match_table[] = { { .compatible = "amlogic,g12a-clkc", - .data = &g12a_clkc_data.eeclkc_data + .data = &g12a_clkc_data.clkc_data }, { .compatible = "amlogic,g12b-clkc", - .data = &g12b_clkc_data.eeclkc_data + .data = &g12b_clkc_data.clkc_data }, { .compatible = "amlogic,sm1-clkc", - .data = &sm1_clkc_data.eeclkc_data + .data = &sm1_clkc_data.clkc_data }, {} }; -MODULE_DEVICE_TABLE(of, clkc_match_table); +MODULE_DEVICE_TABLE(of, g12a_clkc_match_table); -static struct platform_driver g12a_driver = { - .probe = meson_g12a_probe, +static struct platform_driver g12a_clkc_driver = { + .probe = g12a_clkc_probe, .driver = { .name = "g12a-clkc", - .of_match_table = clkc_match_table, + .of_match_table = g12a_clkc_match_table, }, }; -module_platform_driver(g12a_driver); +module_platform_driver(g12a_clkc_driver); MODULE_DESCRIPTION("Amlogic G12/SM1 Main Clock Controller driver"); MODULE_LICENSE("GPL"); diff --git a/drivers/clk/meson/gxbb-aoclk.c b/drivers/clk/meson/gxbb-aoclk.c index f075fbd450f3..c7dfb3a06cb5 100644 --- a/drivers/clk/meson/gxbb-aoclk.c +++ b/drivers/clk/meson/gxbb-aoclk.c @@ -23,31 +23,20 @@ #define AO_RTC_ALT_CLK_CNTL0 0x94 #define AO_RTC_ALT_CLK_CNTL1 0x98 -#define GXBB_AO_GATE(_name, _bit) \ -static struct clk_regmap _name##_ao = { \ - .data = &(struct clk_regmap_gate_data) { \ - .offset = AO_RTI_GEN_CNTL_REG0, \ - .bit_idx = (_bit), \ - }, \ - .hw.init = &(struct clk_init_data) { \ - .name = #_name "_ao", \ - .ops = &clk_regmap_gate_ops, \ - .parent_data = &(const struct clk_parent_data) { \ - .fw_name = "mpeg-clk", \ - }, \ - .num_parents = 1, \ - .flags = CLK_IGNORE_UNUSED, \ - }, \ -} +static const struct clk_parent_data gxbb_ao_pclk_parents = { .fw_name = "mpeg-clk" }; -GXBB_AO_GATE(remote, 0); -GXBB_AO_GATE(i2c_master, 1); -GXBB_AO_GATE(i2c_slave, 2); -GXBB_AO_GATE(uart1, 3); -GXBB_AO_GATE(uart2, 5); -GXBB_AO_GATE(ir_blaster, 6); +#define GXBB_AO_PCLK(_name, _bit, _flags) \ + MESON_PCLK(gxbb_ao_##_name, AO_RTI_GEN_CNTL_REG0, _bit, \ + &gxbb_ao_pclk_parents, _flags) -static struct clk_regmap ao_cts_oscin = { +static GXBB_AO_PCLK(remote, 0, CLK_IGNORE_UNUSED); +static GXBB_AO_PCLK(i2c_master, 1, CLK_IGNORE_UNUSED); +static GXBB_AO_PCLK(i2c_slave, 2, CLK_IGNORE_UNUSED); +static GXBB_AO_PCLK(uart1, 3, CLK_IGNORE_UNUSED); +static GXBB_AO_PCLK(uart2, 5, CLK_IGNORE_UNUSED); +static GXBB_AO_PCLK(ir_blaster, 6, CLK_IGNORE_UNUSED); + +static struct clk_regmap gxbb_ao_cts_oscin = { .data = &(struct clk_regmap_gate_data){ .offset = AO_RTI_PWR_CNTL_REG0, .bit_idx = 6, @@ -62,7 +51,7 @@ static struct clk_regmap ao_cts_oscin = { }, }; -static struct clk_regmap ao_32k_pre = { +static struct clk_regmap gxbb_ao_32k_pre = { .data = &(struct clk_regmap_gate_data){ .offset = AO_RTC_ALT_CLK_CNTL0, .bit_idx = 31, @@ -70,7 +59,7 @@ static struct clk_regmap ao_32k_pre = { .hw.init = &(struct clk_init_data){ .name = "ao_32k_pre", .ops = &clk_regmap_gate_ops, - .parent_hws = (const struct clk_hw *[]) { &ao_cts_oscin.hw }, + .parent_hws = (const struct clk_hw *[]) { &gxbb_ao_cts_oscin.hw }, .num_parents = 1, }, }; @@ -85,7 +74,7 @@ static const struct meson_clk_dualdiv_param gxbb_32k_div_table[] = { }, {} }; -static struct clk_regmap ao_32k_div = { +static struct clk_regmap gxbb_ao_32k_div = { .data = &(struct meson_clk_dualdiv_data){ .n1 = { .reg_off = AO_RTC_ALT_CLK_CNTL0, @@ -117,12 +106,12 @@ static struct clk_regmap ao_32k_div = { .hw.init = &(struct clk_init_data){ .name = "ao_32k_div", .ops = &meson_clk_dualdiv_ops, - .parent_hws = (const struct clk_hw *[]) { &ao_32k_pre.hw }, + .parent_hws = (const struct clk_hw *[]) { &gxbb_ao_32k_pre.hw }, .num_parents = 1, }, }; -static struct clk_regmap ao_32k_sel = { +static struct clk_regmap gxbb_ao_32k_sel = { .data = &(struct clk_regmap_mux_data) { .offset = AO_RTC_ALT_CLK_CNTL1, .mask = 0x1, @@ -133,15 +122,15 @@ static struct clk_regmap ao_32k_sel = { .name = "ao_32k_sel", .ops = &clk_regmap_mux_ops, .parent_hws = (const struct clk_hw *[]) { - &ao_32k_div.hw, - &ao_32k_pre.hw + &gxbb_ao_32k_div.hw, + &gxbb_ao_32k_pre.hw }, .num_parents = 2, .flags = CLK_SET_RATE_PARENT, }, }; -static struct clk_regmap ao_32k = { +static struct clk_regmap gxbb_ao_32k = { .data = &(struct clk_regmap_gate_data){ .offset = AO_RTC_ALT_CLK_CNTL0, .bit_idx = 30, @@ -149,13 +138,13 @@ static struct clk_regmap ao_32k = { .hw.init = &(struct clk_init_data){ .name = "ao_32k", .ops = &clk_regmap_gate_ops, - .parent_hws = (const struct clk_hw *[]) { &ao_32k_sel.hw }, + .parent_hws = (const struct clk_hw *[]) { &gxbb_ao_32k_sel.hw }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, }; -static struct clk_regmap ao_cts_rtc_oscin = { +static struct clk_regmap gxbb_ao_cts_rtc_oscin = { .data = &(struct clk_regmap_mux_data) { .offset = AO_RTI_PWR_CNTL_REG0, .mask = 0x7, @@ -170,14 +159,14 @@ static struct clk_regmap ao_cts_rtc_oscin = { { .fw_name = "ext-32k-0", }, { .fw_name = "ext-32k-1", }, { .fw_name = "ext-32k-2", }, - { .hw = &ao_32k.hw }, + { .hw = &gxbb_ao_32k.hw }, }, .num_parents = 4, .flags = CLK_SET_RATE_PARENT, }, }; -static struct clk_regmap ao_clk81 = { +static struct clk_regmap gxbb_ao_clk81 = { .data = &(struct clk_regmap_mux_data) { .offset = AO_RTI_PWR_CNTL_REG0, .mask = 0x1, @@ -189,14 +178,14 @@ static struct clk_regmap ao_clk81 = { .ops = &clk_regmap_mux_ro_ops, .parent_data = (const struct clk_parent_data []) { { .fw_name = "mpeg-clk", }, - { .hw = &ao_cts_rtc_oscin.hw }, + { .hw = &gxbb_ao_cts_rtc_oscin.hw }, }, .num_parents = 2, .flags = CLK_SET_RATE_PARENT, }, }; -static struct clk_regmap ao_cts_cec = { +static struct clk_regmap gxbb_ao_cts_cec = { .data = &(struct clk_regmap_mux_data) { .offset = AO_CRT_CLK_CNTL1, .mask = 0x1, @@ -221,14 +210,14 @@ static struct clk_regmap ao_cts_cec = { */ .parent_data = (const struct clk_parent_data []) { { .name = "fixme", .index = -1, }, - { .hw = &ao_cts_rtc_oscin.hw }, + { .hw = &gxbb_ao_cts_rtc_oscin.hw }, }, .num_parents = 2, .flags = CLK_SET_RATE_PARENT, }, }; -static const unsigned int gxbb_aoclk_reset[] = { +static const unsigned int gxbb_ao_reset[] = { [RESET_AO_REMOTE] = 16, [RESET_AO_I2C_MASTER] = 18, [RESET_AO_I2C_SLAVE] = 19, @@ -237,50 +226,52 @@ static const unsigned int gxbb_aoclk_reset[] = { [RESET_AO_IR_BLASTER] = 23, }; -static struct clk_hw *gxbb_aoclk_hw_clks[] = { - [CLKID_AO_REMOTE] = &remote_ao.hw, - [CLKID_AO_I2C_MASTER] = &i2c_master_ao.hw, - [CLKID_AO_I2C_SLAVE] = &i2c_slave_ao.hw, - [CLKID_AO_UART1] = &uart1_ao.hw, - [CLKID_AO_UART2] = &uart2_ao.hw, - [CLKID_AO_IR_BLASTER] = &ir_blaster_ao.hw, - [CLKID_AO_CEC_32K] = &ao_cts_cec.hw, - [CLKID_AO_CTS_OSCIN] = &ao_cts_oscin.hw, - [CLKID_AO_32K_PRE] = &ao_32k_pre.hw, - [CLKID_AO_32K_DIV] = &ao_32k_div.hw, - [CLKID_AO_32K_SEL] = &ao_32k_sel.hw, - [CLKID_AO_32K] = &ao_32k.hw, - [CLKID_AO_CTS_RTC_OSCIN] = &ao_cts_rtc_oscin.hw, - [CLKID_AO_CLK81] = &ao_clk81.hw, +static struct clk_hw *gxbb_ao_hw_clks[] = { + [CLKID_AO_REMOTE] = &gxbb_ao_remote.hw, + [CLKID_AO_I2C_MASTER] = &gxbb_ao_i2c_master.hw, + [CLKID_AO_I2C_SLAVE] = &gxbb_ao_i2c_slave.hw, + [CLKID_AO_UART1] = &gxbb_ao_uart1.hw, + [CLKID_AO_UART2] = &gxbb_ao_uart2.hw, + [CLKID_AO_IR_BLASTER] = &gxbb_ao_ir_blaster.hw, + [CLKID_AO_CEC_32K] = &gxbb_ao_cts_cec.hw, + [CLKID_AO_CTS_OSCIN] = &gxbb_ao_cts_oscin.hw, + [CLKID_AO_32K_PRE] = &gxbb_ao_32k_pre.hw, + [CLKID_AO_32K_DIV] = &gxbb_ao_32k_div.hw, + [CLKID_AO_32K_SEL] = &gxbb_ao_32k_sel.hw, + [CLKID_AO_32K] = &gxbb_ao_32k.hw, + [CLKID_AO_CTS_RTC_OSCIN] = &gxbb_ao_cts_rtc_oscin.hw, + [CLKID_AO_CLK81] = &gxbb_ao_clk81.hw, }; -static const struct meson_aoclk_data gxbb_aoclkc_data = { +static const struct meson_aoclk_data gxbb_ao_clkc_data = { .reset_reg = AO_RTI_GEN_CNTL_REG0, - .num_reset = ARRAY_SIZE(gxbb_aoclk_reset), - .reset = gxbb_aoclk_reset, - .hw_clks = { - .hws = gxbb_aoclk_hw_clks, - .num = ARRAY_SIZE(gxbb_aoclk_hw_clks), + .num_reset = ARRAY_SIZE(gxbb_ao_reset), + .reset = gxbb_ao_reset, + .clkc_data = { + .hw_clks = { + .hws = gxbb_ao_hw_clks, + .num = ARRAY_SIZE(gxbb_ao_hw_clks), + }, }, }; -static const struct of_device_id gxbb_aoclkc_match_table[] = { +static const struct of_device_id gxbb_ao_clkc_match_table[] = { { .compatible = "amlogic,meson-gx-aoclkc", - .data = &gxbb_aoclkc_data, + .data = &gxbb_ao_clkc_data.clkc_data, }, { } }; -MODULE_DEVICE_TABLE(of, gxbb_aoclkc_match_table); +MODULE_DEVICE_TABLE(of, gxbb_ao_clkc_match_table); -static struct platform_driver gxbb_aoclkc_driver = { +static struct platform_driver gxbb_ao_clkc_driver = { .probe = meson_aoclkc_probe, .driver = { .name = "gxbb-aoclkc", - .of_match_table = gxbb_aoclkc_match_table, + .of_match_table = gxbb_ao_clkc_match_table, }, }; -module_platform_driver(gxbb_aoclkc_driver); +module_platform_driver(gxbb_ao_clkc_driver); MODULE_DESCRIPTION("Amlogic GXBB Always-ON Clock Controller driver"); MODULE_LICENSE("GPL"); diff --git a/drivers/clk/meson/gxbb.c b/drivers/clk/meson/gxbb.c index 362d1b87ea5b..5a229c4ffae1 100644 --- a/drivers/clk/meson/gxbb.c +++ b/drivers/clk/meson/gxbb.c @@ -13,7 +13,7 @@ #include "clk-regmap.h" #include "clk-pll.h" #include "clk-mpll.h" -#include "meson-eeclk.h" +#include "meson-clkc-utils.h" #include "vid-pll-div.h" #include <dt-bindings/clock/gxbb-clkc.h> @@ -116,70 +116,6 @@ #define HHI_BT656_CLK_CNTL 0x3d4 #define HHI_SAR_CLK_CNTL 0x3d8 -static const struct pll_params_table gxbb_gp0_pll_params_table[] = { - PLL_PARAMS(32, 1), - PLL_PARAMS(33, 1), - PLL_PARAMS(34, 1), - PLL_PARAMS(35, 1), - PLL_PARAMS(36, 1), - PLL_PARAMS(37, 1), - PLL_PARAMS(38, 1), - PLL_PARAMS(39, 1), - PLL_PARAMS(40, 1), - PLL_PARAMS(41, 1), - PLL_PARAMS(42, 1), - PLL_PARAMS(43, 1), - PLL_PARAMS(44, 1), - PLL_PARAMS(45, 1), - PLL_PARAMS(46, 1), - PLL_PARAMS(47, 1), - PLL_PARAMS(48, 1), - PLL_PARAMS(49, 1), - PLL_PARAMS(50, 1), - PLL_PARAMS(51, 1), - PLL_PARAMS(52, 1), - PLL_PARAMS(53, 1), - PLL_PARAMS(54, 1), - PLL_PARAMS(55, 1), - PLL_PARAMS(56, 1), - PLL_PARAMS(57, 1), - PLL_PARAMS(58, 1), - PLL_PARAMS(59, 1), - PLL_PARAMS(60, 1), - PLL_PARAMS(61, 1), - PLL_PARAMS(62, 1), - { /* sentinel */ }, -}; - -static const struct pll_params_table gxl_gp0_pll_params_table[] = { - PLL_PARAMS(42, 1), - PLL_PARAMS(43, 1), - PLL_PARAMS(44, 1), - PLL_PARAMS(45, 1), - PLL_PARAMS(46, 1), - PLL_PARAMS(47, 1), - PLL_PARAMS(48, 1), - PLL_PARAMS(49, 1), - PLL_PARAMS(50, 1), - PLL_PARAMS(51, 1), - PLL_PARAMS(52, 1), - PLL_PARAMS(53, 1), - PLL_PARAMS(54, 1), - PLL_PARAMS(55, 1), - PLL_PARAMS(56, 1), - PLL_PARAMS(57, 1), - PLL_PARAMS(58, 1), - PLL_PARAMS(59, 1), - PLL_PARAMS(60, 1), - PLL_PARAMS(61, 1), - PLL_PARAMS(62, 1), - PLL_PARAMS(63, 1), - PLL_PARAMS(64, 1), - PLL_PARAMS(65, 1), - PLL_PARAMS(66, 1), - { /* sentinel */ }, -}; - static struct clk_regmap gxbb_fixed_pll_dco = { .data = &(struct meson_clk_pll_data){ .en = { @@ -523,7 +459,42 @@ static struct clk_regmap gxbb_sys_pll = { }, }; -static const struct reg_sequence gxbb_gp0_init_regs[] = { +static const struct pll_params_table gxbb_gp0_pll_params_table[] = { + PLL_PARAMS(32, 1), + PLL_PARAMS(33, 1), + PLL_PARAMS(34, 1), + PLL_PARAMS(35, 1), + PLL_PARAMS(36, 1), + PLL_PARAMS(37, 1), + PLL_PARAMS(38, 1), + PLL_PARAMS(39, 1), + PLL_PARAMS(40, 1), + PLL_PARAMS(41, 1), + PLL_PARAMS(42, 1), + PLL_PARAMS(43, 1), + PLL_PARAMS(44, 1), + PLL_PARAMS(45, 1), + PLL_PARAMS(46, 1), + PLL_PARAMS(47, 1), + PLL_PARAMS(48, 1), + PLL_PARAMS(49, 1), + PLL_PARAMS(50, 1), + PLL_PARAMS(51, 1), + PLL_PARAMS(52, 1), + PLL_PARAMS(53, 1), + PLL_PARAMS(54, 1), + PLL_PARAMS(55, 1), + PLL_PARAMS(56, 1), + PLL_PARAMS(57, 1), + PLL_PARAMS(58, 1), + PLL_PARAMS(59, 1), + PLL_PARAMS(60, 1), + PLL_PARAMS(61, 1), + PLL_PARAMS(62, 1), + { /* sentinel */ }, +}; + +static const struct reg_sequence gxbb_gp0_pll_init_regs[] = { { .reg = HHI_GP0_PLL_CNTL2, .def = 0x69c80000 }, { .reg = HHI_GP0_PLL_CNTL3, .def = 0x0a5590c4 }, { .reg = HHI_GP0_PLL_CNTL4, .def = 0x0000500d }, @@ -557,8 +528,8 @@ static struct clk_regmap gxbb_gp0_pll_dco = { .width = 1, }, .table = gxbb_gp0_pll_params_table, - .init_regs = gxbb_gp0_init_regs, - .init_count = ARRAY_SIZE(gxbb_gp0_init_regs), + .init_regs = gxbb_gp0_pll_init_regs, + .init_count = ARRAY_SIZE(gxbb_gp0_pll_init_regs), }, .hw.init = &(struct clk_init_data){ .name = "gp0_pll_dco", @@ -570,7 +541,36 @@ static struct clk_regmap gxbb_gp0_pll_dco = { }, }; -static const struct reg_sequence gxl_gp0_init_regs[] = { +static const struct pll_params_table gxl_gp0_pll_params_table[] = { + PLL_PARAMS(42, 1), + PLL_PARAMS(43, 1), + PLL_PARAMS(44, 1), + PLL_PARAMS(45, 1), + PLL_PARAMS(46, 1), + PLL_PARAMS(47, 1), + PLL_PARAMS(48, 1), + PLL_PARAMS(49, 1), + PLL_PARAMS(50, 1), + PLL_PARAMS(51, 1), + PLL_PARAMS(52, 1), + PLL_PARAMS(53, 1), + PLL_PARAMS(54, 1), + PLL_PARAMS(55, 1), + PLL_PARAMS(56, 1), + PLL_PARAMS(57, 1), + PLL_PARAMS(58, 1), + PLL_PARAMS(59, 1), + PLL_PARAMS(60, 1), + PLL_PARAMS(61, 1), + PLL_PARAMS(62, 1), + PLL_PARAMS(63, 1), + PLL_PARAMS(64, 1), + PLL_PARAMS(65, 1), + PLL_PARAMS(66, 1), + { /* sentinel */ }, +}; + +static const struct reg_sequence gxl_gp0_pll_init_regs[] = { { .reg = HHI_GP0_PLL_CNTL1, .def = 0xc084b000 }, { .reg = HHI_GP0_PLL_CNTL2, .def = 0xb75020be }, { .reg = HHI_GP0_PLL_CNTL3, .def = 0x0a59a288 }, @@ -611,8 +611,8 @@ static struct clk_regmap gxl_gp0_pll_dco = { .width = 1, }, .table = gxl_gp0_pll_params_table, - .init_regs = gxl_gp0_init_regs, - .init_count = ARRAY_SIZE(gxl_gp0_init_regs), + .init_regs = gxl_gp0_pll_init_regs, + .init_count = ARRAY_SIZE(gxl_gp0_pll_init_regs), }, .hw.init = &(struct clk_init_data){ .name = "gp0_pll_dco", @@ -972,8 +972,9 @@ static struct clk_regmap gxbb_mpll2 = { }, }; -static u32 mux_table_clk81[] = { 0, 2, 3, 4, 5, 6, 7 }; -static const struct clk_parent_data clk81_parent_data[] = { +/* clk81 is often referred as "mpeg_clk" */ +static u32 clk81_parents_val_table[] = { 0, 2, 3, 4, 5, 6, 7 }; +static const struct clk_parent_data clk81_parents[] = { { .fw_name = "xtal", }, { .hw = &gxbb_fclk_div7.hw }, { .hw = &gxbb_mpll1.hw }, @@ -983,37 +984,37 @@ static const struct clk_parent_data clk81_parent_data[] = { { .hw = &gxbb_fclk_div5.hw }, }; -static struct clk_regmap gxbb_mpeg_clk_sel = { +static struct clk_regmap gxbb_clk81_sel = { .data = &(struct clk_regmap_mux_data){ .offset = HHI_MPEG_CLK_CNTL, .mask = 0x7, .shift = 12, - .table = mux_table_clk81, + .table = clk81_parents_val_table, }, .hw.init = &(struct clk_init_data){ - .name = "mpeg_clk_sel", + .name = "clk81_sel", .ops = &clk_regmap_mux_ro_ops, /* * bits 14:12 selects from 8 possible parents: * xtal, 1'b0 (wtf), fclk_div7, mpll_clkout1, mpll_clkout2, * fclk_div4, fclk_div3, fclk_div5 */ - .parent_data = clk81_parent_data, - .num_parents = ARRAY_SIZE(clk81_parent_data), + .parent_data = clk81_parents, + .num_parents = ARRAY_SIZE(clk81_parents), }, }; -static struct clk_regmap gxbb_mpeg_clk_div = { +static struct clk_regmap gxbb_clk81_div = { .data = &(struct clk_regmap_div_data){ .offset = HHI_MPEG_CLK_CNTL, .shift = 0, .width = 7, }, .hw.init = &(struct clk_init_data){ - .name = "mpeg_clk_div", + .name = "clk81_div", .ops = &clk_regmap_divider_ro_ops, .parent_hws = (const struct clk_hw *[]) { - &gxbb_mpeg_clk_sel.hw + &gxbb_clk81_sel.hw }, .num_parents = 1, }, @@ -1029,7 +1030,7 @@ static struct clk_regmap gxbb_clk81 = { .name = "clk81", .ops = &clk_regmap_gate_ops, .parent_hws = (const struct clk_hw *[]) { - &gxbb_mpeg_clk_div.hw + &gxbb_clk81_div.hw }, .num_parents = 1, .flags = CLK_IS_CRITICAL, @@ -1094,7 +1095,7 @@ static struct clk_regmap gxbb_sar_adc_clk = { * switches to the "inactive" one when CLK_SET_RATE_GATE is set. */ -static const struct clk_parent_data gxbb_mali_0_1_parent_data[] = { +static const struct clk_parent_data gxbb_mali_parents[] = { { .fw_name = "xtal", }, { .hw = &gxbb_gp0_pll.hw }, { .hw = &gxbb_mpll2.hw }, @@ -1114,8 +1115,8 @@ static struct clk_regmap gxbb_mali_0_sel = { .hw.init = &(struct clk_init_data){ .name = "mali_0_sel", .ops = &clk_regmap_mux_ops, - .parent_data = gxbb_mali_0_1_parent_data, - .num_parents = 8, + .parent_data = gxbb_mali_parents, + .num_parents = ARRAY_SIZE(gxbb_mali_parents), /* * Don't request the parent to change the rate because * all GPU frequencies can be derived from the fclk_* @@ -1168,8 +1169,8 @@ static struct clk_regmap gxbb_mali_1_sel = { .hw.init = &(struct clk_init_data){ .name = "mali_1_sel", .ops = &clk_regmap_mux_ops, - .parent_data = gxbb_mali_0_1_parent_data, - .num_parents = 8, + .parent_data = gxbb_mali_parents, + .num_parents = ARRAY_SIZE(gxbb_mali_parents), /* * Don't request the parent to change the rate because * all GPU frequencies can be derived from the fclk_* @@ -1213,11 +1214,6 @@ static struct clk_regmap gxbb_mali_1 = { }, }; -static const struct clk_hw *gxbb_mali_parent_hws[] = { - &gxbb_mali_0.hw, - &gxbb_mali_1.hw, -}; - static struct clk_regmap gxbb_mali = { .data = &(struct clk_regmap_mux_data){ .offset = HHI_MALI_CLK_CNTL, @@ -1227,29 +1223,35 @@ static struct clk_regmap gxbb_mali = { .hw.init = &(struct clk_init_data){ .name = "mali", .ops = &clk_regmap_mux_ops, - .parent_hws = gxbb_mali_parent_hws, + .parent_hws = (const struct clk_hw *[]) { + &gxbb_mali_0.hw, + &gxbb_mali_1.hw, + }, .num_parents = 2, .flags = CLK_SET_RATE_PARENT, }, }; +static u32 gxbb_cts_mclk_parents_val_table[] = { 1, 2, 3 }; +static const struct clk_hw *gxbb_cts_mclk_parents[] = { + &gxbb_mpll0.hw, + &gxbb_mpll1.hw, + &gxbb_mpll2.hw, +}; + static struct clk_regmap gxbb_cts_amclk_sel = { .data = &(struct clk_regmap_mux_data){ .offset = HHI_AUD_CLK_CNTL, .mask = 0x3, .shift = 9, - .table = (u32[]){ 1, 2, 3 }, + .table = gxbb_cts_mclk_parents_val_table, .flags = CLK_MUX_ROUND_CLOSEST, }, .hw.init = &(struct clk_init_data){ .name = "cts_amclk_sel", .ops = &clk_regmap_mux_ops, - .parent_hws = (const struct clk_hw *[]) { - &gxbb_mpll0.hw, - &gxbb_mpll1.hw, - &gxbb_mpll2.hw, - }, - .num_parents = 3, + .parent_hws = gxbb_cts_mclk_parents, + .num_parents = ARRAY_SIZE(gxbb_cts_mclk_parents), }, }; @@ -1292,18 +1294,14 @@ static struct clk_regmap gxbb_cts_mclk_i958_sel = { .offset = HHI_AUD_CLK_CNTL2, .mask = 0x3, .shift = 25, - .table = (u32[]){ 1, 2, 3 }, + .table = gxbb_cts_mclk_parents_val_table, .flags = CLK_MUX_ROUND_CLOSEST, }, .hw.init = &(struct clk_init_data) { .name = "cts_mclk_i958_sel", .ops = &clk_regmap_mux_ops, - .parent_hws = (const struct clk_hw *[]) { - &gxbb_mpll0.hw, - &gxbb_mpll1.hw, - &gxbb_mpll2.hw, - }, - .num_parents = 3, + .parent_hws = gxbb_cts_mclk_parents, + .num_parents = ARRAY_SIZE(gxbb_cts_mclk_parents), }, }; @@ -1368,7 +1366,7 @@ static struct clk_regmap gxbb_cts_i958 = { * This clock does not exist yet in this controller or the AO one */ static u32 gxbb_32k_clk_parents_val_table[] = { 0, 2, 3 }; -static const struct clk_parent_data gxbb_32k_clk_parent_data[] = { +static const struct clk_parent_data gxbb_32k_clk_parents[] = { { .fw_name = "xtal", }, { .hw = &gxbb_fclk_div3.hw }, { .hw = &gxbb_fclk_div5.hw }, @@ -1380,11 +1378,11 @@ static struct clk_regmap gxbb_32k_clk_sel = { .mask = 0x3, .shift = 16, .table = gxbb_32k_clk_parents_val_table, - }, + }, .hw.init = &(struct clk_init_data){ .name = "32k_clk_sel", .ops = &clk_regmap_mux_ops, - .parent_data = gxbb_32k_clk_parent_data, + .parent_data = gxbb_32k_clk_parents, .num_parents = 4, .flags = CLK_SET_RATE_PARENT, }, @@ -1423,7 +1421,7 @@ static struct clk_regmap gxbb_32k_clk = { }, }; -static const struct clk_parent_data gxbb_sd_emmc_clk0_parent_data[] = { +static const struct clk_parent_data gxbb_sd_emmc_clk0_parents[] = { { .fw_name = "xtal", }, { .hw = &gxbb_fclk_div2.hw }, { .hw = &gxbb_fclk_div3.hw }, @@ -1447,8 +1445,8 @@ static struct clk_regmap gxbb_sd_emmc_a_clk0_sel = { .hw.init = &(struct clk_init_data) { .name = "sd_emmc_a_clk0_sel", .ops = &clk_regmap_mux_ops, - .parent_data = gxbb_sd_emmc_clk0_parent_data, - .num_parents = ARRAY_SIZE(gxbb_sd_emmc_clk0_parent_data), + .parent_data = gxbb_sd_emmc_clk0_parents, + .num_parents = ARRAY_SIZE(gxbb_sd_emmc_clk0_parents), .flags = CLK_SET_RATE_PARENT, }, }; @@ -1497,8 +1495,8 @@ static struct clk_regmap gxbb_sd_emmc_b_clk0_sel = { .hw.init = &(struct clk_init_data) { .name = "sd_emmc_b_clk0_sel", .ops = &clk_regmap_mux_ops, - .parent_data = gxbb_sd_emmc_clk0_parent_data, - .num_parents = ARRAY_SIZE(gxbb_sd_emmc_clk0_parent_data), + .parent_data = gxbb_sd_emmc_clk0_parents, + .num_parents = ARRAY_SIZE(gxbb_sd_emmc_clk0_parents), .flags = CLK_SET_RATE_PARENT, }, }; @@ -1547,8 +1545,8 @@ static struct clk_regmap gxbb_sd_emmc_c_clk0_sel = { .hw.init = &(struct clk_init_data) { .name = "sd_emmc_c_clk0_sel", .ops = &clk_regmap_mux_ops, - .parent_data = gxbb_sd_emmc_clk0_parent_data, - .num_parents = ARRAY_SIZE(gxbb_sd_emmc_clk0_parent_data), + .parent_data = gxbb_sd_emmc_clk0_parents, + .num_parents = ARRAY_SIZE(gxbb_sd_emmc_clk0_parents), .flags = CLK_SET_RATE_PARENT, }, }; @@ -1589,7 +1587,7 @@ static struct clk_regmap gxbb_sd_emmc_c_clk0 = { /* VPU Clock */ -static const struct clk_hw *gxbb_vpu_parent_hws[] = { +static const struct clk_hw *gxbb_vpu_parents[] = { &gxbb_fclk_div4.hw, &gxbb_fclk_div3.hw, &gxbb_fclk_div5.hw, @@ -1609,8 +1607,8 @@ static struct clk_regmap gxbb_vpu_0_sel = { * bits 9:10 selects from 4 possible parents: * fclk_div4, fclk_div3, fclk_div5, fclk_div7, */ - .parent_hws = gxbb_vpu_parent_hws, - .num_parents = ARRAY_SIZE(gxbb_vpu_parent_hws), + .parent_hws = gxbb_vpu_parents, + .num_parents = ARRAY_SIZE(gxbb_vpu_parents), .flags = CLK_SET_RATE_NO_REPARENT, }, }; @@ -1657,8 +1655,8 @@ static struct clk_regmap gxbb_vpu_1_sel = { * bits 25:26 selects from 4 possible parents: * fclk_div4, fclk_div3, fclk_div5, fclk_div7, */ - .parent_hws = gxbb_vpu_parent_hws, - .num_parents = ARRAY_SIZE(gxbb_vpu_parent_hws), + .parent_hws = gxbb_vpu_parents, + .num_parents = ARRAY_SIZE(gxbb_vpu_parents), .flags = CLK_SET_RATE_NO_REPARENT, }, }; @@ -1716,7 +1714,7 @@ static struct clk_regmap gxbb_vpu = { /* VAPB Clock */ -static const struct clk_hw *gxbb_vapb_parent_hws[] = { +static const struct clk_hw *gxbb_vapb_parents[] = { &gxbb_fclk_div4.hw, &gxbb_fclk_div3.hw, &gxbb_fclk_div5.hw, @@ -1736,8 +1734,8 @@ static struct clk_regmap gxbb_vapb_0_sel = { * bits 9:10 selects from 4 possible parents: * fclk_div4, fclk_div3, fclk_div5, fclk_div7, */ - .parent_hws = gxbb_vapb_parent_hws, - .num_parents = ARRAY_SIZE(gxbb_vapb_parent_hws), + .parent_hws = gxbb_vapb_parents, + .num_parents = ARRAY_SIZE(gxbb_vapb_parents), .flags = CLK_SET_RATE_NO_REPARENT, }, }; @@ -1788,8 +1786,8 @@ static struct clk_regmap gxbb_vapb_1_sel = { * bits 25:26 selects from 4 possible parents: * fclk_div4, fclk_div3, fclk_div5, fclk_div7, */ - .parent_hws = gxbb_vapb_parent_hws, - .num_parents = ARRAY_SIZE(gxbb_vapb_parent_hws), + .parent_hws = gxbb_vapb_parents, + .num_parents = ARRAY_SIZE(gxbb_vapb_parents), .flags = CLK_SET_RATE_NO_REPARENT, }, }; @@ -1897,7 +1895,7 @@ static struct clk_regmap gxbb_vid_pll_div = { }, }; -static const struct clk_parent_data gxbb_vid_pll_parent_data[] = { +static const struct clk_parent_data gxbb_vid_pll_parents[] = { { .hw = &gxbb_vid_pll_div.hw }, /* * Note: @@ -1922,8 +1920,8 @@ static struct clk_regmap gxbb_vid_pll_sel = { * bit 18 selects from 2 possible parents: * vid_pll_div or hdmi_pll */ - .parent_data = gxbb_vid_pll_parent_data, - .num_parents = ARRAY_SIZE(gxbb_vid_pll_parent_data), + .parent_data = gxbb_vid_pll_parents, + .num_parents = ARRAY_SIZE(gxbb_vid_pll_parents), .flags = CLK_SET_RATE_NO_REPARENT | CLK_GET_RATE_NOCACHE, }, }; @@ -1944,7 +1942,7 @@ static struct clk_regmap gxbb_vid_pll = { }, }; -static const struct clk_hw *gxbb_vclk_parent_hws[] = { +static const struct clk_hw *gxbb_vclk_parents[] = { &gxbb_vid_pll.hw, &gxbb_fclk_div4.hw, &gxbb_fclk_div3.hw, @@ -1968,8 +1966,8 @@ static struct clk_regmap gxbb_vclk_sel = { * vid_pll, fclk_div4, fclk_div3, fclk_div5, * vid_pll, fclk_div7, mp1 */ - .parent_hws = gxbb_vclk_parent_hws, - .num_parents = ARRAY_SIZE(gxbb_vclk_parent_hws), + .parent_hws = gxbb_vclk_parents, + .num_parents = ARRAY_SIZE(gxbb_vclk_parents), .flags = CLK_SET_RATE_NO_REPARENT | CLK_GET_RATE_NOCACHE, }, }; @@ -1988,8 +1986,8 @@ static struct clk_regmap gxbb_vclk2_sel = { * vid_pll, fclk_div4, fclk_div3, fclk_div5, * vid_pll, fclk_div7, mp1 */ - .parent_hws = gxbb_vclk_parent_hws, - .num_parents = ARRAY_SIZE(gxbb_vclk_parent_hws), + .parent_hws = gxbb_vclk_parents, + .num_parents = ARRAY_SIZE(gxbb_vclk_parents), .flags = CLK_SET_RATE_NO_REPARENT | CLK_GET_RATE_NOCACHE, }, }; @@ -2328,8 +2326,8 @@ static struct clk_fixed_factor gxbb_vclk2_div12 = { }, }; -static u32 mux_table_cts_sel[] = { 0, 1, 2, 3, 4, 8, 9, 10, 11, 12 }; -static const struct clk_hw *gxbb_cts_parent_hws[] = { +static u32 gxbb_cts_parents_val_table[] = { 0, 1, 2, 3, 4, 8, 9, 10, 11, 12 }; +static const struct clk_hw *gxbb_cts_parents[] = { &gxbb_vclk_div1.hw, &gxbb_vclk_div2.hw, &gxbb_vclk_div4.hw, @@ -2347,13 +2345,13 @@ static struct clk_regmap gxbb_cts_enci_sel = { .offset = HHI_VID_CLK_DIV, .mask = 0xf, .shift = 28, - .table = mux_table_cts_sel, + .table = gxbb_cts_parents_val_table, }, .hw.init = &(struct clk_init_data){ .name = "cts_enci_sel", .ops = &clk_regmap_mux_ops, - .parent_hws = gxbb_cts_parent_hws, - .num_parents = ARRAY_SIZE(gxbb_cts_parent_hws), + .parent_hws = gxbb_cts_parents, + .num_parents = ARRAY_SIZE(gxbb_cts_parents), .flags = CLK_SET_RATE_NO_REPARENT | CLK_GET_RATE_NOCACHE, }, }; @@ -2363,13 +2361,13 @@ static struct clk_regmap gxbb_cts_encp_sel = { .offset = HHI_VID_CLK_DIV, .mask = 0xf, .shift = 20, - .table = mux_table_cts_sel, + .table = gxbb_cts_parents_val_table, }, .hw.init = &(struct clk_init_data){ .name = "cts_encp_sel", .ops = &clk_regmap_mux_ops, - .parent_hws = gxbb_cts_parent_hws, - .num_parents = ARRAY_SIZE(gxbb_cts_parent_hws), + .parent_hws = gxbb_cts_parents, + .num_parents = ARRAY_SIZE(gxbb_cts_parents), .flags = CLK_SET_RATE_NO_REPARENT | CLK_GET_RATE_NOCACHE, }, }; @@ -2379,50 +2377,13 @@ static struct clk_regmap gxbb_cts_vdac_sel = { .offset = HHI_VIID_CLK_DIV, .mask = 0xf, .shift = 28, - .table = mux_table_cts_sel, + .table = gxbb_cts_parents_val_table, }, .hw.init = &(struct clk_init_data){ .name = "cts_vdac_sel", .ops = &clk_regmap_mux_ops, - .parent_hws = gxbb_cts_parent_hws, - .num_parents = ARRAY_SIZE(gxbb_cts_parent_hws), - .flags = CLK_SET_RATE_NO_REPARENT | CLK_GET_RATE_NOCACHE, - }, -}; - -/* TOFIX: add support for cts_tcon */ -static u32 mux_table_hdmi_tx_sel[] = { 0, 1, 2, 3, 4, 8, 9, 10, 11, 12 }; -static const struct clk_hw *gxbb_cts_hdmi_tx_parent_hws[] = { - &gxbb_vclk_div1.hw, - &gxbb_vclk_div2.hw, - &gxbb_vclk_div4.hw, - &gxbb_vclk_div6.hw, - &gxbb_vclk_div12.hw, - &gxbb_vclk2_div1.hw, - &gxbb_vclk2_div2.hw, - &gxbb_vclk2_div4.hw, - &gxbb_vclk2_div6.hw, - &gxbb_vclk2_div12.hw, -}; - -static struct clk_regmap gxbb_hdmi_tx_sel = { - .data = &(struct clk_regmap_mux_data){ - .offset = HHI_HDMI_CLK_CNTL, - .mask = 0xf, - .shift = 16, - .table = mux_table_hdmi_tx_sel, - }, - .hw.init = &(struct clk_init_data){ - .name = "hdmi_tx_sel", - .ops = &clk_regmap_mux_ops, - /* - * bits 31:28 selects from 12 possible parents: - * vclk_div1, vclk_div2, vclk_div4, vclk_div6, vclk_div12 - * vclk2_div1, vclk2_div2, vclk2_div4, vclk2_div6, vclk2_div12, - * cts_tcon - */ - .parent_hws = gxbb_cts_hdmi_tx_parent_hws, - .num_parents = ARRAY_SIZE(gxbb_cts_hdmi_tx_parent_hws), + .parent_hws = gxbb_cts_parents, + .num_parents = ARRAY_SIZE(gxbb_cts_parents), .flags = CLK_SET_RATE_NO_REPARENT | CLK_GET_RATE_NOCACHE, }, }; @@ -2475,6 +2436,43 @@ static struct clk_regmap gxbb_cts_vdac = { }, }; +/* TOFIX: add support for cts_tcon */ +static u32 gxbb_hdmi_tx_parents_val_table[] = { 0, 1, 2, 3, 4, 8, 9, 10, 11, 12 }; +static const struct clk_hw *gxbb_hdmi_tx_parents[] = { + &gxbb_vclk_div1.hw, + &gxbb_vclk_div2.hw, + &gxbb_vclk_div4.hw, + &gxbb_vclk_div6.hw, + &gxbb_vclk_div12.hw, + &gxbb_vclk2_div1.hw, + &gxbb_vclk2_div2.hw, + &gxbb_vclk2_div4.hw, + &gxbb_vclk2_div6.hw, + &gxbb_vclk2_div12.hw, +}; + +static struct clk_regmap gxbb_hdmi_tx_sel = { + .data = &(struct clk_regmap_mux_data){ + .offset = HHI_HDMI_CLK_CNTL, + .mask = 0xf, + .shift = 16, + .table = gxbb_hdmi_tx_parents_val_table, + }, + .hw.init = &(struct clk_init_data){ + .name = "hdmi_tx_sel", + .ops = &clk_regmap_mux_ops, + /* + * bits 31:28 selects from 12 possible parents: + * vclk_div1, vclk_div2, vclk_div4, vclk_div6, vclk_div12 + * vclk2_div1, vclk2_div2, vclk2_div4, vclk2_div6, vclk2_div12, + * cts_tcon + */ + .parent_hws = gxbb_hdmi_tx_parents, + .num_parents = ARRAY_SIZE(gxbb_hdmi_tx_parents), + .flags = CLK_SET_RATE_NO_REPARENT | CLK_GET_RATE_NOCACHE, + }, +}; + static struct clk_regmap gxbb_hdmi_tx = { .data = &(struct clk_regmap_gate_data){ .offset = HHI_VID_CLK_CNTL2, @@ -2493,7 +2491,7 @@ static struct clk_regmap gxbb_hdmi_tx = { /* HDMI Clocks */ -static const struct clk_parent_data gxbb_hdmi_parent_data[] = { +static const struct clk_parent_data gxbb_hdmi_parents[] = { { .fw_name = "xtal", }, { .hw = &gxbb_fclk_div4.hw }, { .hw = &gxbb_fclk_div3.hw }, @@ -2510,8 +2508,8 @@ static struct clk_regmap gxbb_hdmi_sel = { .hw.init = &(struct clk_init_data){ .name = "hdmi_sel", .ops = &clk_regmap_mux_ops, - .parent_data = gxbb_hdmi_parent_data, - .num_parents = ARRAY_SIZE(gxbb_hdmi_parent_data), + .parent_data = gxbb_hdmi_parents, + .num_parents = ARRAY_SIZE(gxbb_hdmi_parents), .flags = CLK_SET_RATE_NO_REPARENT | CLK_GET_RATE_NOCACHE, }, }; @@ -2547,7 +2545,7 @@ static struct clk_regmap gxbb_hdmi = { /* VDEC clocks */ -static const struct clk_hw *gxbb_vdec_parent_hws[] = { +static const struct clk_hw *gxbb_vdec_parents[] = { &gxbb_fclk_div4.hw, &gxbb_fclk_div3.hw, &gxbb_fclk_div5.hw, @@ -2564,8 +2562,8 @@ static struct clk_regmap gxbb_vdec_1_sel = { .hw.init = &(struct clk_init_data){ .name = "vdec_1_sel", .ops = &clk_regmap_mux_ops, - .parent_hws = gxbb_vdec_parent_hws, - .num_parents = ARRAY_SIZE(gxbb_vdec_parent_hws), + .parent_hws = gxbb_vdec_parents, + .num_parents = ARRAY_SIZE(gxbb_vdec_parents), .flags = CLK_SET_RATE_PARENT, }, }; @@ -2614,8 +2612,8 @@ static struct clk_regmap gxbb_vdec_hevc_sel = { .hw.init = &(struct clk_init_data){ .name = "vdec_hevc_sel", .ops = &clk_regmap_mux_ops, - .parent_hws = gxbb_vdec_parent_hws, - .num_parents = ARRAY_SIZE(gxbb_vdec_parent_hws), + .parent_hws = gxbb_vdec_parents, + .num_parents = ARRAY_SIZE(gxbb_vdec_parents), .flags = CLK_SET_RATE_PARENT, }, }; @@ -2654,9 +2652,8 @@ static struct clk_regmap gxbb_vdec_hevc = { }, }; -static u32 mux_table_gen_clk[] = { 0, 4, 5, 6, 7, 8, - 9, 10, 11, 13, 14, }; -static const struct clk_parent_data gen_clk_parent_data[] = { +static u32 gxbb_gen_clk_parents_val_table[] = { 0, 4, 5, 6, 7, 8, 9, 10, 11, 13, 14, }; +static const struct clk_parent_data gxbb_gen_clk_parents[] = { { .fw_name = "xtal", }, { .hw = &gxbb_vdec_1.hw }, { .hw = &gxbb_vdec_hevc.hw }, @@ -2675,7 +2672,7 @@ static struct clk_regmap gxbb_gen_clk_sel = { .offset = HHI_GEN_CLK_CNTL, .mask = 0xf, .shift = 12, - .table = mux_table_gen_clk, + .table = gxbb_gen_clk_parents_val_table, }, .hw.init = &(struct clk_init_data){ .name = "gen_clk_sel", @@ -2686,8 +2683,8 @@ static struct clk_regmap gxbb_gen_clk_sel = { * vid_pll, vid2_pll (hevc), mpll0, mpll1, mpll2, fdiv4, * fdiv3, fdiv5, [cts_msr_clk], fdiv7, gp0_pll */ - .parent_data = gen_clk_parent_data, - .num_parents = ARRAY_SIZE(gen_clk_parent_data), + .parent_data = gxbb_gen_clk_parents, + .num_parents = ARRAY_SIZE(gxbb_gen_clk_parents), }, }; @@ -2724,100 +2721,118 @@ static struct clk_regmap gxbb_gen_clk = { }, }; -#define MESON_GATE(_name, _reg, _bit) \ - MESON_PCLK(_name, _reg, _bit, &gxbb_clk81.hw) - -/* Everything Else (EE) domain gates */ -static MESON_GATE(gxbb_ddr, HHI_GCLK_MPEG0, 0); -static MESON_GATE(gxbb_dos, HHI_GCLK_MPEG0, 1); -static MESON_GATE(gxbb_isa, HHI_GCLK_MPEG0, 5); -static MESON_GATE(gxbb_pl301, HHI_GCLK_MPEG0, 6); -static MESON_GATE(gxbb_periphs, HHI_GCLK_MPEG0, 7); -static MESON_GATE(gxbb_spicc, HHI_GCLK_MPEG0, 8); -static MESON_GATE(gxbb_i2c, HHI_GCLK_MPEG0, 9); -static MESON_GATE(gxbb_sana, HHI_GCLK_MPEG0, 10); -static MESON_GATE(gxbb_smart_card, HHI_GCLK_MPEG0, 11); -static MESON_GATE(gxbb_rng0, HHI_GCLK_MPEG0, 12); -static MESON_GATE(gxbb_uart0, HHI_GCLK_MPEG0, 13); -static MESON_GATE(gxbb_sdhc, HHI_GCLK_MPEG0, 14); -static MESON_GATE(gxbb_stream, HHI_GCLK_MPEG0, 15); -static MESON_GATE(gxbb_async_fifo, HHI_GCLK_MPEG0, 16); -static MESON_GATE(gxbb_sdio, HHI_GCLK_MPEG0, 17); -static MESON_GATE(gxbb_abuf, HHI_GCLK_MPEG0, 18); -static MESON_GATE(gxbb_hiu_iface, HHI_GCLK_MPEG0, 19); -static MESON_GATE(gxbb_assist_misc, HHI_GCLK_MPEG0, 23); -static MESON_GATE(gxbb_emmc_a, HHI_GCLK_MPEG0, 24); -static MESON_GATE(gxbb_emmc_b, HHI_GCLK_MPEG0, 25); -static MESON_GATE(gxbb_emmc_c, HHI_GCLK_MPEG0, 26); -static MESON_GATE(gxl_acodec, HHI_GCLK_MPEG0, 28); -static MESON_GATE(gxbb_spi, HHI_GCLK_MPEG0, 30); - -static MESON_GATE(gxbb_i2s_spdif, HHI_GCLK_MPEG1, 2); -static MESON_GATE(gxbb_eth, HHI_GCLK_MPEG1, 3); -static MESON_GATE(gxbb_demux, HHI_GCLK_MPEG1, 4); -static MESON_GATE(gxbb_blkmv, HHI_GCLK_MPEG1, 14); -static MESON_GATE(gxbb_aiu, HHI_GCLK_MPEG1, 15); -static MESON_GATE(gxbb_uart1, HHI_GCLK_MPEG1, 16); -static MESON_GATE(gxbb_g2d, HHI_GCLK_MPEG1, 20); -static MESON_GATE(gxbb_usb0, HHI_GCLK_MPEG1, 21); -static MESON_GATE(gxbb_usb1, HHI_GCLK_MPEG1, 22); -static MESON_GATE(gxbb_reset, HHI_GCLK_MPEG1, 23); -static MESON_GATE(gxbb_nand, HHI_GCLK_MPEG1, 24); -static MESON_GATE(gxbb_dos_parser, HHI_GCLK_MPEG1, 25); -static MESON_GATE(gxbb_usb, HHI_GCLK_MPEG1, 26); -static MESON_GATE(gxbb_vdin1, HHI_GCLK_MPEG1, 28); -static MESON_GATE(gxbb_ahb_arb0, HHI_GCLK_MPEG1, 29); -static MESON_GATE(gxbb_efuse, HHI_GCLK_MPEG1, 30); -static MESON_GATE(gxbb_boot_rom, HHI_GCLK_MPEG1, 31); - -static MESON_GATE(gxbb_ahb_data_bus, HHI_GCLK_MPEG2, 1); -static MESON_GATE(gxbb_ahb_ctrl_bus, HHI_GCLK_MPEG2, 2); -static MESON_GATE(gxbb_hdmi_intr_sync, HHI_GCLK_MPEG2, 3); -static MESON_GATE(gxbb_hdmi_pclk, HHI_GCLK_MPEG2, 4); -static MESON_GATE(gxbb_usb1_ddr_bridge, HHI_GCLK_MPEG2, 8); -static MESON_GATE(gxbb_usb0_ddr_bridge, HHI_GCLK_MPEG2, 9); -static MESON_GATE(gxbb_mmc_pclk, HHI_GCLK_MPEG2, 11); -static MESON_GATE(gxbb_dvin, HHI_GCLK_MPEG2, 12); -static MESON_GATE(gxbb_uart2, HHI_GCLK_MPEG2, 15); -static MESON_GATE(gxbb_sar_adc, HHI_GCLK_MPEG2, 22); -static MESON_GATE(gxbb_vpu_intr, HHI_GCLK_MPEG2, 25); -static MESON_GATE(gxbb_sec_ahb_ahb3_bridge, HHI_GCLK_MPEG2, 26); -static MESON_GATE(gxbb_clk81_a53, HHI_GCLK_MPEG2, 29); - -static MESON_GATE(gxbb_vclk2_venci0, HHI_GCLK_OTHER, 1); -static MESON_GATE(gxbb_vclk2_venci1, HHI_GCLK_OTHER, 2); -static MESON_GATE(gxbb_vclk2_vencp0, HHI_GCLK_OTHER, 3); -static MESON_GATE(gxbb_vclk2_vencp1, HHI_GCLK_OTHER, 4); -static MESON_GATE(gxbb_gclk_venci_int0, HHI_GCLK_OTHER, 8); -static MESON_GATE(gxbb_gclk_vencp_int, HHI_GCLK_OTHER, 9); -static MESON_GATE(gxbb_dac_clk, HHI_GCLK_OTHER, 10); -static MESON_GATE(gxbb_aoclk_gate, HHI_GCLK_OTHER, 14); -static MESON_GATE(gxbb_iec958_gate, HHI_GCLK_OTHER, 16); -static MESON_GATE(gxbb_enc480p, HHI_GCLK_OTHER, 20); -static MESON_GATE(gxbb_rng1, HHI_GCLK_OTHER, 21); -static MESON_GATE(gxbb_gclk_venci_int1, HHI_GCLK_OTHER, 22); -static MESON_GATE(gxbb_vclk2_venclmcc, HHI_GCLK_OTHER, 24); -static MESON_GATE(gxbb_vclk2_vencl, HHI_GCLK_OTHER, 25); -static MESON_GATE(gxbb_vclk_other, HHI_GCLK_OTHER, 26); -static MESON_GATE(gxbb_edp, HHI_GCLK_OTHER, 31); +static const struct clk_parent_data gxbb_pclk_parents = { .hw = &gxbb_clk81.hw }; + +#define GXBB_PCLK(_name, _reg, _bit, _flags) \ + MESON_PCLK(_name, _reg, _bit, &gxbb_pclk_parents, _flags) + +/* + * Everything Else (EE) domain gates + * + * NOTE: The gates below are marked with CLK_IGNORE_UNUSED for historic reasons + * Users are encouraged to test without it and submit changes to: + * - remove the flag if not necessary + * - replace the flag with something more adequate, such as CLK_IS_CRITICAL, + * if appropriate. + * - add a comment explaining why the use of CLK_IGNORE_UNUSED is desirable + * for a particular clock. + */ +static GXBB_PCLK(gxbb_ddr, HHI_GCLK_MPEG0, 0, CLK_IGNORE_UNUSED); +static GXBB_PCLK(gxbb_dos, HHI_GCLK_MPEG0, 1, CLK_IGNORE_UNUSED); +static GXBB_PCLK(gxbb_isa, HHI_GCLK_MPEG0, 5, CLK_IGNORE_UNUSED); +static GXBB_PCLK(gxbb_pl301, HHI_GCLK_MPEG0, 6, CLK_IGNORE_UNUSED); +static GXBB_PCLK(gxbb_periphs, HHI_GCLK_MPEG0, 7, CLK_IGNORE_UNUSED); +static GXBB_PCLK(gxbb_spicc, HHI_GCLK_MPEG0, 8, CLK_IGNORE_UNUSED); +static GXBB_PCLK(gxbb_i2c, HHI_GCLK_MPEG0, 9, CLK_IGNORE_UNUSED); +static GXBB_PCLK(gxbb_sana, HHI_GCLK_MPEG0, 10, CLK_IGNORE_UNUSED); +static GXBB_PCLK(gxbb_smart_card, HHI_GCLK_MPEG0, 11, CLK_IGNORE_UNUSED); +static GXBB_PCLK(gxbb_rng0, HHI_GCLK_MPEG0, 12, CLK_IGNORE_UNUSED); +static GXBB_PCLK(gxbb_uart0, HHI_GCLK_MPEG0, 13, CLK_IGNORE_UNUSED); +static GXBB_PCLK(gxbb_sdhc, HHI_GCLK_MPEG0, 14, CLK_IGNORE_UNUSED); +static GXBB_PCLK(gxbb_stream, HHI_GCLK_MPEG0, 15, CLK_IGNORE_UNUSED); +static GXBB_PCLK(gxbb_async_fifo, HHI_GCLK_MPEG0, 16, CLK_IGNORE_UNUSED); +static GXBB_PCLK(gxbb_sdio, HHI_GCLK_MPEG0, 17, CLK_IGNORE_UNUSED); +static GXBB_PCLK(gxbb_abuf, HHI_GCLK_MPEG0, 18, CLK_IGNORE_UNUSED); +static GXBB_PCLK(gxbb_hiu_iface, HHI_GCLK_MPEG0, 19, CLK_IGNORE_UNUSED); +static GXBB_PCLK(gxbb_assist_misc, HHI_GCLK_MPEG0, 23, CLK_IGNORE_UNUSED); +static GXBB_PCLK(gxbb_emmc_a, HHI_GCLK_MPEG0, 24, CLK_IGNORE_UNUSED); +static GXBB_PCLK(gxbb_emmc_b, HHI_GCLK_MPEG0, 25, CLK_IGNORE_UNUSED); +static GXBB_PCLK(gxbb_emmc_c, HHI_GCLK_MPEG0, 26, CLK_IGNORE_UNUSED); +static GXBB_PCLK(gxl_acodec, HHI_GCLK_MPEG0, 28, CLK_IGNORE_UNUSED); +static GXBB_PCLK(gxbb_spi, HHI_GCLK_MPEG0, 30, CLK_IGNORE_UNUSED); + +static GXBB_PCLK(gxbb_i2s_spdif, HHI_GCLK_MPEG1, 2, CLK_IGNORE_UNUSED); +static GXBB_PCLK(gxbb_eth, HHI_GCLK_MPEG1, 3, CLK_IGNORE_UNUSED); +static GXBB_PCLK(gxbb_demux, HHI_GCLK_MPEG1, 4, CLK_IGNORE_UNUSED); +static GXBB_PCLK(gxbb_blkmv, HHI_GCLK_MPEG1, 14, CLK_IGNORE_UNUSED); +static GXBB_PCLK(gxbb_aiu, HHI_GCLK_MPEG1, 15, CLK_IGNORE_UNUSED); +static GXBB_PCLK(gxbb_uart1, HHI_GCLK_MPEG1, 16, CLK_IGNORE_UNUSED); +static GXBB_PCLK(gxbb_g2d, HHI_GCLK_MPEG1, 20, CLK_IGNORE_UNUSED); +static GXBB_PCLK(gxbb_usb0, HHI_GCLK_MPEG1, 21, CLK_IGNORE_UNUSED); +static GXBB_PCLK(gxbb_usb1, HHI_GCLK_MPEG1, 22, CLK_IGNORE_UNUSED); +static GXBB_PCLK(gxbb_reset, HHI_GCLK_MPEG1, 23, CLK_IGNORE_UNUSED); +static GXBB_PCLK(gxbb_nand, HHI_GCLK_MPEG1, 24, CLK_IGNORE_UNUSED); +static GXBB_PCLK(gxbb_dos_parser, HHI_GCLK_MPEG1, 25, CLK_IGNORE_UNUSED); +static GXBB_PCLK(gxbb_usb, HHI_GCLK_MPEG1, 26, CLK_IGNORE_UNUSED); +static GXBB_PCLK(gxbb_vdin1, HHI_GCLK_MPEG1, 28, CLK_IGNORE_UNUSED); +static GXBB_PCLK(gxbb_ahb_arb0, HHI_GCLK_MPEG1, 29, CLK_IGNORE_UNUSED); +static GXBB_PCLK(gxbb_efuse, HHI_GCLK_MPEG1, 30, CLK_IGNORE_UNUSED); +static GXBB_PCLK(gxbb_boot_rom, HHI_GCLK_MPEG1, 31, CLK_IGNORE_UNUSED); + +static GXBB_PCLK(gxbb_ahb_data_bus, HHI_GCLK_MPEG2, 1, CLK_IGNORE_UNUSED); +static GXBB_PCLK(gxbb_ahb_ctrl_bus, HHI_GCLK_MPEG2, 2, CLK_IGNORE_UNUSED); +static GXBB_PCLK(gxbb_hdmi_intr_sync, HHI_GCLK_MPEG2, 3, CLK_IGNORE_UNUSED); +static GXBB_PCLK(gxbb_hdmi_pclk, HHI_GCLK_MPEG2, 4, CLK_IGNORE_UNUSED); +static GXBB_PCLK(gxbb_usb1_ddr_bridge, HHI_GCLK_MPEG2, 8, CLK_IGNORE_UNUSED); +static GXBB_PCLK(gxbb_usb0_ddr_bridge, HHI_GCLK_MPEG2, 9, CLK_IGNORE_UNUSED); +static GXBB_PCLK(gxbb_mmc_pclk, HHI_GCLK_MPEG2, 11, CLK_IGNORE_UNUSED); +static GXBB_PCLK(gxbb_dvin, HHI_GCLK_MPEG2, 12, CLK_IGNORE_UNUSED); +static GXBB_PCLK(gxbb_uart2, HHI_GCLK_MPEG2, 15, CLK_IGNORE_UNUSED); +static GXBB_PCLK(gxbb_sar_adc, HHI_GCLK_MPEG2, 22, CLK_IGNORE_UNUSED); +static GXBB_PCLK(gxbb_vpu_intr, HHI_GCLK_MPEG2, 25, CLK_IGNORE_UNUSED); +static GXBB_PCLK(gxbb_sec_ahb_ahb3_bridge, HHI_GCLK_MPEG2, 26, CLK_IGNORE_UNUSED); +static GXBB_PCLK(gxbb_clk81_a53, HHI_GCLK_MPEG2, 29, CLK_IGNORE_UNUSED); + +static GXBB_PCLK(gxbb_vclk2_venci0, HHI_GCLK_OTHER, 1, CLK_IGNORE_UNUSED); +static GXBB_PCLK(gxbb_vclk2_venci1, HHI_GCLK_OTHER, 2, CLK_IGNORE_UNUSED); +static GXBB_PCLK(gxbb_vclk2_vencp0, HHI_GCLK_OTHER, 3, CLK_IGNORE_UNUSED); +static GXBB_PCLK(gxbb_vclk2_vencp1, HHI_GCLK_OTHER, 4, CLK_IGNORE_UNUSED); +static GXBB_PCLK(gxbb_gclk_venci_int0, HHI_GCLK_OTHER, 8, CLK_IGNORE_UNUSED); +static GXBB_PCLK(gxbb_gclk_vencp_int, HHI_GCLK_OTHER, 9, CLK_IGNORE_UNUSED); +static GXBB_PCLK(gxbb_dac_clk, HHI_GCLK_OTHER, 10, CLK_IGNORE_UNUSED); +static GXBB_PCLK(gxbb_aoclk_gate, HHI_GCLK_OTHER, 14, CLK_IGNORE_UNUSED); +static GXBB_PCLK(gxbb_iec958_gate, HHI_GCLK_OTHER, 16, CLK_IGNORE_UNUSED); +static GXBB_PCLK(gxbb_enc480p, HHI_GCLK_OTHER, 20, CLK_IGNORE_UNUSED); +static GXBB_PCLK(gxbb_rng1, HHI_GCLK_OTHER, 21, CLK_IGNORE_UNUSED); +static GXBB_PCLK(gxbb_gclk_venci_int1, HHI_GCLK_OTHER, 22, CLK_IGNORE_UNUSED); +static GXBB_PCLK(gxbb_vclk2_venclmcc, HHI_GCLK_OTHER, 24, CLK_IGNORE_UNUSED); +static GXBB_PCLK(gxbb_vclk2_vencl, HHI_GCLK_OTHER, 25, CLK_IGNORE_UNUSED); +static GXBB_PCLK(gxbb_vclk_other, HHI_GCLK_OTHER, 26, CLK_IGNORE_UNUSED); +static GXBB_PCLK(gxbb_edp, HHI_GCLK_OTHER, 31, CLK_IGNORE_UNUSED); /* Always On (AO) domain gates */ -static MESON_GATE(gxbb_ao_media_cpu, HHI_GCLK_AO, 0); -static MESON_GATE(gxbb_ao_ahb_sram, HHI_GCLK_AO, 1); -static MESON_GATE(gxbb_ao_ahb_bus, HHI_GCLK_AO, 2); -static MESON_GATE(gxbb_ao_iface, HHI_GCLK_AO, 3); -static MESON_GATE(gxbb_ao_i2c, HHI_GCLK_AO, 4); +static GXBB_PCLK(gxbb_ao_media_cpu, HHI_GCLK_AO, 0, CLK_IGNORE_UNUSED); +static GXBB_PCLK(gxbb_ao_ahb_sram, HHI_GCLK_AO, 1, CLK_IGNORE_UNUSED); +static GXBB_PCLK(gxbb_ao_ahb_bus, HHI_GCLK_AO, 2, CLK_IGNORE_UNUSED); +static GXBB_PCLK(gxbb_ao_iface, HHI_GCLK_AO, 3, CLK_IGNORE_UNUSED); +static GXBB_PCLK(gxbb_ao_i2c, HHI_GCLK_AO, 4, CLK_IGNORE_UNUSED); /* AIU gates */ -static MESON_PCLK(gxbb_aiu_glue, HHI_GCLK_MPEG1, 6, &gxbb_aiu.hw); -static MESON_PCLK(gxbb_iec958, HHI_GCLK_MPEG1, 7, &gxbb_aiu_glue.hw); -static MESON_PCLK(gxbb_i2s_out, HHI_GCLK_MPEG1, 8, &gxbb_aiu_glue.hw); -static MESON_PCLK(gxbb_amclk, HHI_GCLK_MPEG1, 9, &gxbb_aiu_glue.hw); -static MESON_PCLK(gxbb_aififo2, HHI_GCLK_MPEG1, 10, &gxbb_aiu_glue.hw); -static MESON_PCLK(gxbb_mixer, HHI_GCLK_MPEG1, 11, &gxbb_aiu_glue.hw); -static MESON_PCLK(gxbb_mixer_iface, HHI_GCLK_MPEG1, 12, &gxbb_aiu_glue.hw); -static MESON_PCLK(gxbb_adc, HHI_GCLK_MPEG1, 13, &gxbb_aiu_glue.hw); +static const struct clk_parent_data gxbb_aiu_glue_parents = { .hw = &gxbb_aiu.hw }; +static MESON_PCLK(gxbb_aiu_glue, HHI_GCLK_MPEG1, 6, &gxbb_aiu_glue_parents, CLK_IGNORE_UNUSED); + +static const struct clk_parent_data gxbb_aiu_pclk_parents = { .hw = &gxbb_aiu_glue.hw }; +#define GXBB_AIU_PCLK(_name, _bit, _flags) \ + MESON_PCLK(_name, HHI_GCLK_MPEG1, _bit, &gxbb_aiu_pclk_parents, _flags) + +static GXBB_AIU_PCLK(gxbb_iec958, 7, CLK_IGNORE_UNUSED); +static GXBB_AIU_PCLK(gxbb_i2s_out, 8, CLK_IGNORE_UNUSED); +static GXBB_AIU_PCLK(gxbb_amclk, 9, CLK_IGNORE_UNUSED); +static GXBB_AIU_PCLK(gxbb_aififo2, 10, CLK_IGNORE_UNUSED); +static GXBB_AIU_PCLK(gxbb_mixer, 11, CLK_IGNORE_UNUSED); +static GXBB_AIU_PCLK(gxbb_mixer_iface, 12, CLK_IGNORE_UNUSED); +static GXBB_AIU_PCLK(gxbb_adc, 13, CLK_IGNORE_UNUSED); /* Array of all clocks provided by this provider */ @@ -2831,8 +2846,8 @@ static struct clk_hw *gxbb_hw_clks[] = { [CLKID_FCLK_DIV5] = &gxbb_fclk_div5.hw, [CLKID_FCLK_DIV7] = &gxbb_fclk_div7.hw, [CLKID_GP0_PLL] = &gxbb_gp0_pll.hw, - [CLKID_MPEG_SEL] = &gxbb_mpeg_clk_sel.hw, - [CLKID_MPEG_DIV] = &gxbb_mpeg_clk_div.hw, + [CLKID_MPEG_SEL] = &gxbb_clk81_sel.hw, + [CLKID_MPEG_DIV] = &gxbb_clk81_div.hw, [CLKID_CLK81] = &gxbb_clk81.hw, [CLKID_MPLL0] = &gxbb_mpll0.hw, [CLKID_MPLL1] = &gxbb_mpll1.hw, @@ -3039,8 +3054,8 @@ static struct clk_hw *gxl_hw_clks[] = { [CLKID_FCLK_DIV5] = &gxbb_fclk_div5.hw, [CLKID_FCLK_DIV7] = &gxbb_fclk_div7.hw, [CLKID_GP0_PLL] = &gxbb_gp0_pll.hw, - [CLKID_MPEG_SEL] = &gxbb_mpeg_clk_sel.hw, - [CLKID_MPEG_DIV] = &gxbb_mpeg_clk_div.hw, + [CLKID_MPEG_SEL] = &gxbb_clk81_sel.hw, + [CLKID_MPEG_DIV] = &gxbb_clk81_div.hw, [CLKID_CLK81] = &gxbb_clk81.hw, [CLKID_MPLL0] = &gxbb_mpll0.hw, [CLKID_MPLL1] = &gxbb_mpll1.hw, @@ -3237,35 +3252,35 @@ static struct clk_hw *gxl_hw_clks[] = { [CLKID_ACODEC] = &gxl_acodec.hw, }; -static const struct meson_eeclkc_data gxbb_clkc_data = { +static const struct meson_clkc_data gxbb_clkc_data = { .hw_clks = { .hws = gxbb_hw_clks, .num = ARRAY_SIZE(gxbb_hw_clks), }, }; -static const struct meson_eeclkc_data gxl_clkc_data = { +static const struct meson_clkc_data gxl_clkc_data = { .hw_clks = { .hws = gxl_hw_clks, .num = ARRAY_SIZE(gxl_hw_clks), }, }; -static const struct of_device_id clkc_match_table[] = { +static const struct of_device_id gxbb_clkc_match_table[] = { { .compatible = "amlogic,gxbb-clkc", .data = &gxbb_clkc_data }, { .compatible = "amlogic,gxl-clkc", .data = &gxl_clkc_data }, {}, }; -MODULE_DEVICE_TABLE(of, clkc_match_table); +MODULE_DEVICE_TABLE(of, gxbb_clkc_match_table); -static struct platform_driver gxbb_driver = { - .probe = meson_eeclkc_probe, +static struct platform_driver gxbb_clkc_driver = { + .probe = meson_clkc_syscon_probe, .driver = { .name = "gxbb-clkc", - .of_match_table = clkc_match_table, + .of_match_table = gxbb_clkc_match_table, }, }; -module_platform_driver(gxbb_driver); +module_platform_driver(gxbb_clkc_driver); MODULE_DESCRIPTION("Amlogic GXBB Main Clock Controller driver"); MODULE_LICENSE("GPL"); diff --git a/drivers/clk/meson/meson-aoclk.c b/drivers/clk/meson/meson-aoclk.c index 894c02fda072..8f6bdea18119 100644 --- a/drivers/clk/meson/meson-aoclk.c +++ b/drivers/clk/meson/meson-aoclk.c @@ -37,15 +37,23 @@ static const struct reset_control_ops meson_aoclk_reset_ops = { int meson_aoclkc_probe(struct platform_device *pdev) { struct meson_aoclk_reset_controller *rstc; - struct meson_aoclk_data *data; + const struct meson_clkc_data *clkc_data; + const struct meson_aoclk_data *data; struct device *dev = &pdev->dev; struct device_node *np; struct regmap *regmap; - int ret, clkid; + int ret; - data = (struct meson_aoclk_data *) of_device_get_match_data(dev); - if (!data) - return -ENODEV; + clkc_data = of_device_get_match_data(dev); + if (!clkc_data) + return -EINVAL; + + ret = meson_clkc_syscon_probe(pdev); + if (ret) + return ret; + + data = container_of(clkc_data, struct meson_aoclk_data, + clkc_data); rstc = devm_kzalloc(dev, sizeof(*rstc), GFP_KERNEL); if (!rstc) @@ -71,19 +79,7 @@ int meson_aoclkc_probe(struct platform_device *pdev) return ret; } - /* Register all clks */ - for (clkid = 0; clkid < data->hw_clks.num; clkid++) { - if (!data->hw_clks.hws[clkid]) - continue; - - ret = devm_clk_hw_register(dev, data->hw_clks.hws[clkid]); - if (ret) { - dev_err(dev, "Clock registration failed\n"); - return ret; - } - } - - return devm_of_clk_add_hw_provider(dev, meson_clk_hw_get, (void *)&data->hw_clks); + return 0; } EXPORT_SYMBOL_NS_GPL(meson_aoclkc_probe, "CLK_MESON"); diff --git a/drivers/clk/meson/meson-aoclk.h b/drivers/clk/meson/meson-aoclk.h index ea5fc61308af..2c83e73d3a77 100644 --- a/drivers/clk/meson/meson-aoclk.h +++ b/drivers/clk/meson/meson-aoclk.h @@ -20,10 +20,10 @@ #include "meson-clkc-utils.h" struct meson_aoclk_data { + const struct meson_clkc_data clkc_data; const unsigned int reset_reg; const int num_reset; const unsigned int *reset; - struct meson_clk_hw_data hw_clks; }; struct meson_aoclk_reset_controller { diff --git a/drivers/clk/meson/meson-clkc-utils.c b/drivers/clk/meson/meson-clkc-utils.c index 6937d1482719..870f50548e26 100644 --- a/drivers/clk/meson/meson-clkc-utils.c +++ b/drivers/clk/meson/meson-clkc-utils.c @@ -3,9 +3,13 @@ * Copyright (c) 2023 Neil Armstrong <neil.armstrong@linaro.org> */ -#include <linux/of_device.h> #include <linux/clk-provider.h> +#include <linux/mfd/syscon.h> #include <linux/module.h> +#include <linux/of_device.h> +#include <linux/platform_device.h> +#include <linux/regmap.h> + #include "meson-clkc-utils.h" struct clk_hw *meson_clk_hw_get(struct of_phandle_args *clkspec, void *clk_hw_data) @@ -22,6 +26,86 @@ struct clk_hw *meson_clk_hw_get(struct of_phandle_args *clkspec, void *clk_hw_da } EXPORT_SYMBOL_NS_GPL(meson_clk_hw_get, "CLK_MESON"); +static int meson_clkc_init(struct device *dev, struct regmap *map) +{ + const struct meson_clkc_data *data; + struct clk_hw *hw; + int ret, i; + + data = of_device_get_match_data(dev); + if (!data) + return -EINVAL; + + if (data->init_count) + regmap_multi_reg_write(map, data->init_regs, data->init_count); + + for (i = 0; i < data->hw_clks.num; i++) { + hw = data->hw_clks.hws[i]; + + /* array might be sparse */ + if (!hw) + continue; + + ret = devm_clk_hw_register(dev, hw); + if (ret) { + dev_err(dev, "registering %s clock failed\n", + hw->init->name); + return ret; + } + } + + return devm_of_clk_add_hw_provider(dev, meson_clk_hw_get, (void *)&data->hw_clks); +} + +int meson_clkc_syscon_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct device_node *np; + struct regmap *map; + + np = of_get_parent(dev->of_node); + map = syscon_node_to_regmap(np); + of_node_put(np); + if (IS_ERR(map)) { + dev_err(dev, "failed to get parent syscon regmap\n"); + return PTR_ERR(map); + } + + return meson_clkc_init(dev, map); +} +EXPORT_SYMBOL_NS_GPL(meson_clkc_syscon_probe, "CLK_MESON"); + +int meson_clkc_mmio_probe(struct platform_device *pdev) +{ + const struct meson_clkc_data *data; + struct device *dev = &pdev->dev; + struct resource *res; + void __iomem *base; + struct regmap *map; + struct regmap_config regmap_cfg = { + .reg_bits = 32, + .val_bits = 32, + .reg_stride = 4, + }; + + data = of_device_get_match_data(dev); + if (!data) + return -EINVAL; + + base = devm_platform_get_and_ioremap_resource(pdev, 0, &res); + if (IS_ERR(base)) + return PTR_ERR(base); + + regmap_cfg.max_register = resource_size(res) - regmap_cfg.reg_stride; + + map = devm_regmap_init_mmio(dev, base, ®map_cfg); + if (IS_ERR(map)) + return PTR_ERR(map); + + return meson_clkc_init(dev, map); +} +EXPORT_SYMBOL_NS_GPL(meson_clkc_mmio_probe, "CLK_MESON"); + MODULE_DESCRIPTION("Amlogic Clock Controller Utilities"); MODULE_LICENSE("GPL"); MODULE_IMPORT_NS("CLK_MESON"); diff --git a/drivers/clk/meson/meson-clkc-utils.h b/drivers/clk/meson/meson-clkc-utils.h index fe6f40728949..ddadf14b4923 100644 --- a/drivers/clk/meson/meson-clkc-utils.h +++ b/drivers/clk/meson/meson-clkc-utils.h @@ -9,6 +9,8 @@ #include <linux/of_device.h> #include <linux/clk-provider.h> +struct platform_device; + struct meson_clk_hw_data { struct clk_hw **hws; unsigned int num; @@ -16,4 +18,91 @@ struct meson_clk_hw_data { struct clk_hw *meson_clk_hw_get(struct of_phandle_args *clkspec, void *clk_hw_data); +struct meson_clkc_data { + const struct reg_sequence *init_regs; + unsigned int init_count; + struct meson_clk_hw_data hw_clks; +}; + +int meson_clkc_syscon_probe(struct platform_device *pdev); +int meson_clkc_mmio_probe(struct platform_device *pdev); + +#define __MESON_PCLK(_name, _reg, _bit, _ops, _pdata, _flags) \ +struct clk_regmap _name = { \ + .data = &(struct clk_regmap_gate_data) { \ + .offset = (_reg), \ + .bit_idx = (_bit), \ + }, \ + .hw.init = &(struct clk_init_data) { \ + .name = #_name, \ + .ops = _ops, \ + .parent_data = (_pdata), \ + .num_parents = 1, \ + .flags = (_flags), \ + }, \ +} + +#define MESON_PCLK(_name, _reg, _bit, _pdata, _flags) \ + __MESON_PCLK(_name, _reg, _bit, &clk_regmap_gate_ops, _pdata, _flags) + +#define MESON_PCLK_RO(_name, _reg, _bit, _pdata, _flags) \ + __MESON_PCLK(_name, _reg, _bit, &clk_regmap_gate_ro_ops, _pdata, _flags) + +/* Helpers for the usual sel/div/gate composite clocks */ +#define MESON_COMP_SEL(_prefix, _name, _reg, _shift, _mask, _pdata, \ + _table, _dflags, _iflags) \ +struct clk_regmap _prefix##_name##_sel = { \ + .data = &(struct clk_regmap_mux_data) { \ + .offset = (_reg), \ + .mask = (_mask), \ + .shift = (_shift), \ + .flags = (_dflags), \ + .table = (_table), \ + }, \ + .hw.init = &(struct clk_init_data){ \ + .name = #_name "_sel", \ + .ops = &clk_regmap_mux_ops, \ + .parent_data = _pdata, \ + .num_parents = ARRAY_SIZE(_pdata), \ + .flags = (_iflags), \ + }, \ +} + +#define MESON_COMP_DIV(_prefix, _name, _reg, _shift, _width, \ + _dflags, _iflags) \ +struct clk_regmap _prefix##_name##_div = { \ + .data = &(struct clk_regmap_div_data) { \ + .offset = (_reg), \ + .shift = (_shift), \ + .width = (_width), \ + .flags = (_dflags), \ + }, \ + .hw.init = &(struct clk_init_data) { \ + .name = #_name "_div", \ + .ops = &clk_regmap_divider_ops, \ + .parent_hws = (const struct clk_hw *[]) { \ + &_prefix##_name##_sel.hw \ + }, \ + .num_parents = 1, \ + .flags = (_iflags), \ + }, \ +} + +#define MESON_COMP_GATE(_prefix, _name, _reg, _bit, _iflags) \ +struct clk_regmap _prefix##_name = { \ + .data = &(struct clk_regmap_gate_data) { \ + .offset = (_reg), \ + .bit_idx = (_bit), \ + }, \ + .hw.init = &(struct clk_init_data) { \ + .name = #_name, \ + .ops = &clk_regmap_gate_ops, \ + .parent_hws = (const struct clk_hw *[]) { \ + &_prefix##_name##_div.hw \ + }, \ + .num_parents = 1, \ + .flags = (_iflags), \ + }, \ +} + #endif diff --git a/drivers/clk/meson/meson-eeclk.c b/drivers/clk/meson/meson-eeclk.c deleted file mode 100644 index 6236bf970d79..000000000000 --- a/drivers/clk/meson/meson-eeclk.c +++ /dev/null @@ -1,60 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * Copyright (c) 2019 BayLibre, SAS. - * Author: Jerome Brunet <jbrunet@baylibre.com> - */ - -#include <linux/clk-provider.h> -#include <linux/of.h> -#include <linux/platform_device.h> -#include <linux/mfd/syscon.h> -#include <linux/regmap.h> -#include <linux/module.h> - -#include "clk-regmap.h" -#include "meson-eeclk.h" - -int meson_eeclkc_probe(struct platform_device *pdev) -{ - const struct meson_eeclkc_data *data; - struct device *dev = &pdev->dev; - struct device_node *np; - struct regmap *map; - int ret, i; - - data = of_device_get_match_data(dev); - if (!data) - return -EINVAL; - - /* Get the hhi system controller node */ - np = of_get_parent(dev->of_node); - map = syscon_node_to_regmap(np); - of_node_put(np); - if (IS_ERR(map)) { - dev_err(dev, - "failed to get HHI regmap\n"); - return PTR_ERR(map); - } - - if (data->init_count) - regmap_multi_reg_write(map, data->init_regs, data->init_count); - - for (i = 0; i < data->hw_clks.num; i++) { - /* array might be sparse */ - if (!data->hw_clks.hws[i]) - continue; - - ret = devm_clk_hw_register(dev, data->hw_clks.hws[i]); - if (ret) { - dev_err(dev, "Clock registration failed\n"); - return ret; - } - } - - return devm_of_clk_add_hw_provider(dev, meson_clk_hw_get, (void *)&data->hw_clks); -} -EXPORT_SYMBOL_NS_GPL(meson_eeclkc_probe, "CLK_MESON"); - -MODULE_DESCRIPTION("Amlogic Main Clock Controller Helpers"); -MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS("CLK_MESON"); diff --git a/drivers/clk/meson/meson-eeclk.h b/drivers/clk/meson/meson-eeclk.h deleted file mode 100644 index 6a81d67b46b2..000000000000 --- a/drivers/clk/meson/meson-eeclk.h +++ /dev/null @@ -1,24 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* - * Copyright (c) 2019 BayLibre, SAS. - * Author: Jerome Brunet <jbrunet@baylibre.com> - */ - -#ifndef __MESON_CLKC_H -#define __MESON_CLKC_H - -#include <linux/clk-provider.h> -#include "clk-regmap.h" -#include "meson-clkc-utils.h" - -struct platform_device; - -struct meson_eeclkc_data { - const struct reg_sequence *init_regs; - unsigned int init_count; - struct meson_clk_hw_data hw_clks; -}; - -int meson_eeclkc_probe(struct platform_device *pdev); - -#endif /* __MESON_CLKC_H */ diff --git a/drivers/clk/meson/meson8-ddr.c b/drivers/clk/meson/meson8-ddr.c index 1975fc3987e2..0f93774f7371 100644 --- a/drivers/clk/meson/meson8-ddr.c +++ b/drivers/clk/meson/meson8-ddr.c @@ -12,6 +12,7 @@ #include "clk-regmap.h" #include "clk-pll.h" +#include "meson-clkc-utils.h" #define AM_DDR_PLL_CNTL 0x00 #define AM_DDR_PLL_CNTL1 0x04 @@ -77,60 +78,31 @@ static struct clk_regmap meson8_ddr_pll = { }, }; -static struct clk_hw_onecell_data meson8_ddr_clk_hw_onecell_data = { - .hws = { - [DDR_CLKID_DDR_PLL_DCO] = &meson8_ddr_pll_dco.hw, - [DDR_CLKID_DDR_PLL] = &meson8_ddr_pll.hw, - }, - .num = 2, +static struct clk_hw *meson8_ddr_hw_clks[] = { + [DDR_CLKID_DDR_PLL_DCO] = &meson8_ddr_pll_dco.hw, + [DDR_CLKID_DDR_PLL] = &meson8_ddr_pll.hw, }; -static const struct regmap_config meson8_ddr_clkc_regmap_config = { - .reg_bits = 8, - .val_bits = 32, - .reg_stride = 4, - .max_register = DDR_CLK_STS, +static const struct meson_clkc_data meson8_ddr_clkc_data = { + .hw_clks = { + .hws = meson8_ddr_hw_clks, + .num = ARRAY_SIZE(meson8_ddr_hw_clks), + }, }; -static int meson8_ddr_clkc_probe(struct platform_device *pdev) -{ - struct regmap *regmap; - void __iomem *base; - struct clk_hw *hw; - int ret, i; - - base = devm_platform_ioremap_resource(pdev, 0); - if (IS_ERR(base)) - return PTR_ERR(base); - - regmap = devm_regmap_init_mmio(&pdev->dev, base, - &meson8_ddr_clkc_regmap_config); - if (IS_ERR(regmap)) - return PTR_ERR(regmap); - - /* Register all clks */ - for (i = 0; i < meson8_ddr_clk_hw_onecell_data.num; i++) { - hw = meson8_ddr_clk_hw_onecell_data.hws[i]; - - ret = devm_clk_hw_register(&pdev->dev, hw); - if (ret) { - dev_err(&pdev->dev, "Clock registration failed\n"); - return ret; - } - } - - return devm_of_clk_add_hw_provider(&pdev->dev, of_clk_hw_onecell_get, - &meson8_ddr_clk_hw_onecell_data); -} - static const struct of_device_id meson8_ddr_clkc_match_table[] = { - { .compatible = "amlogic,meson8-ddr-clkc" }, - { .compatible = "amlogic,meson8b-ddr-clkc" }, + { + .compatible = "amlogic,meson8-ddr-clkc", + .data = &meson8_ddr_clkc_data, + }, { + .compatible = "amlogic,meson8b-ddr-clkc", + .data = &meson8_ddr_clkc_data, + }, { /* sentinel */ } }; static struct platform_driver meson8_ddr_clkc_driver = { - .probe = meson8_ddr_clkc_probe, + .probe = meson_clkc_mmio_probe, .driver = { .name = "meson8-ddr-clkc", .of_match_table = meson8_ddr_clkc_match_table, diff --git a/drivers/clk/meson/meson8b.c b/drivers/clk/meson/meson8b.c index 206538326614..95d0b9cbd904 100644 --- a/drivers/clk/meson/meson8b.c +++ b/drivers/clk/meson/meson8b.c @@ -214,7 +214,7 @@ static const struct reg_sequence meson8b_hdmi_pll_init_regs[] = { { .reg = HHI_VID2_PLL_CNTL2, .def = 0x0430a800 }, }; -static const struct pll_params_table hdmi_pll_params_table[] = { +static const struct pll_params_table meson8b_hdmi_pll_params_table[] = { PLL_PARAMS(40, 1), PLL_PARAMS(42, 1), PLL_PARAMS(44, 1), @@ -267,7 +267,7 @@ static struct clk_regmap meson8b_hdmi_pll_dco = { .shift = 29, .width = 1, }, - .table = hdmi_pll_params_table, + .table = meson8b_hdmi_pll_params_table, .init_regs = meson8b_hdmi_pll_init_regs, .init_count = ARRAY_SIZE(meson8b_hdmi_pll_init_regs), }, @@ -670,16 +670,17 @@ static struct clk_regmap meson8b_mpll2 = { }, }; -static u32 mux_table_clk81[] = { 6, 5, 7 }; -static struct clk_regmap meson8b_mpeg_clk_sel = { +/* clk81 is often referred as "mpeg_clk" */ +static u32 meson8b_clk81_parents_val_table[] = { 6, 5, 7 }; +static struct clk_regmap meson8b_clk81_sel = { .data = &(struct clk_regmap_mux_data){ .offset = HHI_MPEG_CLK_CNTL, .mask = 0x7, .shift = 12, - .table = mux_table_clk81, + .table = meson8b_clk81_parents_val_table, }, .hw.init = &(struct clk_init_data){ - .name = "mpeg_clk_sel", + .name = "clk81_sel", .ops = &clk_regmap_mux_ro_ops, /* * FIXME bits 14:12 selects from 8 possible parents: @@ -695,17 +696,17 @@ static struct clk_regmap meson8b_mpeg_clk_sel = { }, }; -static struct clk_regmap meson8b_mpeg_clk_div = { +static struct clk_regmap meson8b_clk81_div = { .data = &(struct clk_regmap_div_data){ .offset = HHI_MPEG_CLK_CNTL, .shift = 0, .width = 7, }, .hw.init = &(struct clk_init_data){ - .name = "mpeg_clk_div", + .name = "clk81_div", .ops = &clk_regmap_divider_ro_ops, .parent_hws = (const struct clk_hw *[]) { - &meson8b_mpeg_clk_sel.hw + &meson8b_clk81_sel.hw }, .num_parents = 1, }, @@ -720,7 +721,7 @@ static struct clk_regmap meson8b_clk81 = { .name = "clk81", .ops = &clk_regmap_gate_ops, .parent_hws = (const struct clk_hw *[]) { - &meson8b_mpeg_clk_div.hw + &meson8b_clk81_div.hw }, .num_parents = 1, .flags = CLK_IS_CRITICAL, @@ -774,7 +775,7 @@ static struct clk_fixed_factor meson8b_cpu_in_div3 = { }, }; -static const struct clk_div_table cpu_scale_table[] = { +static const struct clk_div_table meson8b_cpu_scale_div_table[] = { { .val = 1, .div = 4 }, { .val = 2, .div = 6 }, { .val = 3, .div = 8 }, @@ -791,7 +792,7 @@ static struct clk_regmap meson8b_cpu_scale_div = { .offset = HHI_SYS_CPU_CLK_CNTL1, .shift = 20, .width = 10, - .table = cpu_scale_table, + .table = meson8b_cpu_scale_div_table, .flags = CLK_DIVIDER_ALLOW_ZERO, }, .hw.init = &(struct clk_init_data){ @@ -805,13 +806,13 @@ static struct clk_regmap meson8b_cpu_scale_div = { }, }; -static u32 mux_table_cpu_scale_out_sel[] = { 0, 1, 3 }; +static u32 meson8b_cpu_scale_out_parents_val_table[] = { 0, 1, 3 }; static struct clk_regmap meson8b_cpu_scale_out_sel = { .data = &(struct clk_regmap_mux_data){ .offset = HHI_SYS_CPU_CLK_CNTL0, .mask = 0x3, .shift = 2, - .table = mux_table_cpu_scale_out_sel, + .table = meson8b_cpu_scale_out_parents_val_table, }, .hw.init = &(struct clk_init_data){ .name = "cpu_scale_out_sel", @@ -893,13 +894,13 @@ static struct clk_regmap meson8b_nand_clk_div = { }, }; -static struct clk_regmap meson8b_nand_clk_gate = { +static struct clk_regmap meson8b_nand_clk = { .data = &(struct clk_regmap_gate_data){ .offset = HHI_NAND_CLK_CNTL, .bit_idx = 8, }, .hw.init = &(struct clk_init_data){ - .name = "nand_clk_gate", + .name = "nand_clk", .ops = &clk_regmap_gate_ops, .parent_hws = (const struct clk_hw *[]) { &meson8b_nand_clk_div.hw @@ -1000,160 +1001,137 @@ static struct clk_fixed_factor meson8b_cpu_clk_div8 = { }, }; -static u32 mux_table_apb[] = { 1, 2, 3, 4, 5, 6, 7 }; -static struct clk_regmap meson8b_apb_clk_sel = { +static u32 meson8b_cpu_if_parents_val_table[] = { 1, 2, 3, 4, 5, 6, 7 }; +static const struct clk_hw *meson8b_cpu_if_parents[] = { + &meson8b_cpu_clk_div2.hw, + &meson8b_cpu_clk_div3.hw, + &meson8b_cpu_clk_div4.hw, + &meson8b_cpu_clk_div5.hw, + &meson8b_cpu_clk_div6.hw, + &meson8b_cpu_clk_div7.hw, + &meson8b_cpu_clk_div8.hw, +}; + +static struct clk_regmap meson8b_apb_sel = { .data = &(struct clk_regmap_mux_data){ .offset = HHI_SYS_CPU_CLK_CNTL1, .mask = 0x7, .shift = 3, - .table = mux_table_apb, + .table = meson8b_cpu_if_parents_val_table, }, .hw.init = &(struct clk_init_data){ - .name = "apb_clk_sel", + .name = "apb_sel", .ops = &clk_regmap_mux_ops, - .parent_hws = (const struct clk_hw *[]) { - &meson8b_cpu_clk_div2.hw, - &meson8b_cpu_clk_div3.hw, - &meson8b_cpu_clk_div4.hw, - &meson8b_cpu_clk_div5.hw, - &meson8b_cpu_clk_div6.hw, - &meson8b_cpu_clk_div7.hw, - &meson8b_cpu_clk_div8.hw, - }, - .num_parents = 7, + .parent_hws = meson8b_cpu_if_parents, + .num_parents = ARRAY_SIZE(meson8b_cpu_if_parents), }, }; -static struct clk_regmap meson8b_apb_clk_gate = { +static struct clk_regmap meson8b_apb = { .data = &(struct clk_regmap_gate_data){ .offset = HHI_SYS_CPU_CLK_CNTL1, .bit_idx = 16, .flags = CLK_GATE_SET_TO_DISABLE, }, .hw.init = &(struct clk_init_data){ - .name = "apb_clk_dis", + .name = "apb", .ops = &clk_regmap_gate_ro_ops, .parent_hws = (const struct clk_hw *[]) { - &meson8b_apb_clk_sel.hw + &meson8b_apb_sel.hw }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, }; -static struct clk_regmap meson8b_periph_clk_sel = { +static struct clk_regmap meson8b_periph_sel = { .data = &(struct clk_regmap_mux_data){ .offset = HHI_SYS_CPU_CLK_CNTL1, .mask = 0x7, .shift = 6, }, .hw.init = &(struct clk_init_data){ - .name = "periph_clk_sel", + .name = "periph_sel", .ops = &clk_regmap_mux_ops, - .parent_hws = (const struct clk_hw *[]) { - &meson8b_cpu_clk_div2.hw, - &meson8b_cpu_clk_div3.hw, - &meson8b_cpu_clk_div4.hw, - &meson8b_cpu_clk_div5.hw, - &meson8b_cpu_clk_div6.hw, - &meson8b_cpu_clk_div7.hw, - &meson8b_cpu_clk_div8.hw, - }, - .num_parents = 7, + .parent_hws = meson8b_cpu_if_parents, + .num_parents = ARRAY_SIZE(meson8b_cpu_if_parents), }, }; -static struct clk_regmap meson8b_periph_clk_gate = { +static struct clk_regmap meson8b_periph = { .data = &(struct clk_regmap_gate_data){ .offset = HHI_SYS_CPU_CLK_CNTL1, .bit_idx = 17, .flags = CLK_GATE_SET_TO_DISABLE, }, .hw.init = &(struct clk_init_data){ - .name = "periph_clk_dis", + .name = "periph", .ops = &clk_regmap_gate_ro_ops, .parent_hws = (const struct clk_hw *[]) { - &meson8b_periph_clk_sel.hw + &meson8b_periph_sel.hw }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, }; -static u32 mux_table_axi[] = { 1, 2, 3, 4, 5, 6, 7 }; -static struct clk_regmap meson8b_axi_clk_sel = { +static struct clk_regmap meson8b_axi_sel = { .data = &(struct clk_regmap_mux_data){ .offset = HHI_SYS_CPU_CLK_CNTL1, .mask = 0x7, .shift = 9, - .table = mux_table_axi, + .table = meson8b_cpu_if_parents_val_table, }, .hw.init = &(struct clk_init_data){ - .name = "axi_clk_sel", + .name = "axi_sel", .ops = &clk_regmap_mux_ops, - .parent_hws = (const struct clk_hw *[]) { - &meson8b_cpu_clk_div2.hw, - &meson8b_cpu_clk_div3.hw, - &meson8b_cpu_clk_div4.hw, - &meson8b_cpu_clk_div5.hw, - &meson8b_cpu_clk_div6.hw, - &meson8b_cpu_clk_div7.hw, - &meson8b_cpu_clk_div8.hw, - }, - .num_parents = 7, + .parent_hws = meson8b_cpu_if_parents, + .num_parents = ARRAY_SIZE(meson8b_cpu_if_parents), }, }; -static struct clk_regmap meson8b_axi_clk_gate = { +static struct clk_regmap meson8b_axi = { .data = &(struct clk_regmap_gate_data){ .offset = HHI_SYS_CPU_CLK_CNTL1, .bit_idx = 18, .flags = CLK_GATE_SET_TO_DISABLE, }, .hw.init = &(struct clk_init_data){ - .name = "axi_clk_dis", + .name = "axi", .ops = &clk_regmap_gate_ro_ops, .parent_hws = (const struct clk_hw *[]) { - &meson8b_axi_clk_sel.hw + &meson8b_axi_sel.hw }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, }; -static struct clk_regmap meson8b_l2_dram_clk_sel = { +static struct clk_regmap meson8b_l2_dram_sel = { .data = &(struct clk_regmap_mux_data){ .offset = HHI_SYS_CPU_CLK_CNTL1, .mask = 0x7, .shift = 12, }, .hw.init = &(struct clk_init_data){ - .name = "l2_dram_clk_sel", + .name = "l2_dram_sel", .ops = &clk_regmap_mux_ops, - .parent_hws = (const struct clk_hw *[]) { - &meson8b_cpu_clk_div2.hw, - &meson8b_cpu_clk_div3.hw, - &meson8b_cpu_clk_div4.hw, - &meson8b_cpu_clk_div5.hw, - &meson8b_cpu_clk_div6.hw, - &meson8b_cpu_clk_div7.hw, - &meson8b_cpu_clk_div8.hw, - }, - .num_parents = 7, + .parent_hws = meson8b_cpu_if_parents, + .num_parents = ARRAY_SIZE(meson8b_cpu_if_parents), }, }; -static struct clk_regmap meson8b_l2_dram_clk_gate = { +static struct clk_regmap meson8b_l2_dram = { .data = &(struct clk_regmap_gate_data){ .offset = HHI_SYS_CPU_CLK_CNTL1, .bit_idx = 19, .flags = CLK_GATE_SET_TO_DISABLE, }, .hw.init = &(struct clk_init_data){ - .name = "l2_dram_clk_dis", + .name = "l2_dram", .ops = &clk_regmap_gate_ro_ops, .parent_hws = (const struct clk_hw *[]) { - &meson8b_l2_dram_clk_sel.hw + &meson8b_l2_dram_sel.hw }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, @@ -1286,7 +1264,7 @@ static struct clk_regmap meson8b_vid_pll_final_div = { }, }; -static const struct clk_hw *meson8b_vclk_mux_parent_hws[] = { +static const struct clk_hw *meson8b_vclk_parents[] = { &meson8b_vid_pll_final_div.hw, &meson8b_fclk_div4.hw, &meson8b_fclk_div3.hw, @@ -1305,8 +1283,8 @@ static struct clk_regmap meson8b_vclk_in_sel = { .hw.init = &(struct clk_init_data){ .name = "vclk_in_sel", .ops = &clk_regmap_mux_ops, - .parent_hws = meson8b_vclk_mux_parent_hws, - .num_parents = ARRAY_SIZE(meson8b_vclk_mux_parent_hws), + .parent_hws = meson8b_vclk_parents, + .num_parents = ARRAY_SIZE(meson8b_vclk_parents), .flags = CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT, }, }; @@ -1343,13 +1321,13 @@ static struct clk_regmap meson8b_vclk_en = { }, }; -static struct clk_regmap meson8b_vclk_div1_gate = { +static struct clk_regmap meson8b_vclk_div1 = { .data = &(struct clk_regmap_gate_data){ .offset = HHI_VID_CLK_CNTL, .bit_idx = 0, }, .hw.init = &(struct clk_init_data){ - .name = "vclk_div1_en", + .name = "vclk_div1", .ops = &clk_regmap_gate_ops, .parent_hws = (const struct clk_hw *[]) { &meson8b_vclk_en.hw @@ -1363,7 +1341,7 @@ static struct clk_fixed_factor meson8b_vclk_div2_div = { .mult = 1, .div = 2, .hw.init = &(struct clk_init_data){ - .name = "vclk_div2", + .name = "vclk_div2_div", .ops = &clk_fixed_factor_ops, .parent_hws = (const struct clk_hw *[]) { &meson8b_vclk_en.hw @@ -1373,13 +1351,13 @@ static struct clk_fixed_factor meson8b_vclk_div2_div = { } }; -static struct clk_regmap meson8b_vclk_div2_div_gate = { +static struct clk_regmap meson8b_vclk_div2 = { .data = &(struct clk_regmap_gate_data){ .offset = HHI_VID_CLK_CNTL, .bit_idx = 1, }, .hw.init = &(struct clk_init_data){ - .name = "vclk_div2_en", + .name = "vclk_div2", .ops = &clk_regmap_gate_ops, .parent_hws = (const struct clk_hw *[]) { &meson8b_vclk_div2_div.hw @@ -1393,7 +1371,7 @@ static struct clk_fixed_factor meson8b_vclk_div4_div = { .mult = 1, .div = 4, .hw.init = &(struct clk_init_data){ - .name = "vclk_div4", + .name = "vclk_div4_div", .ops = &clk_fixed_factor_ops, .parent_hws = (const struct clk_hw *[]) { &meson8b_vclk_en.hw @@ -1403,13 +1381,13 @@ static struct clk_fixed_factor meson8b_vclk_div4_div = { } }; -static struct clk_regmap meson8b_vclk_div4_div_gate = { +static struct clk_regmap meson8b_vclk_div4 = { .data = &(struct clk_regmap_gate_data){ .offset = HHI_VID_CLK_CNTL, .bit_idx = 2, }, .hw.init = &(struct clk_init_data){ - .name = "vclk_div4_en", + .name = "vclk_div4", .ops = &clk_regmap_gate_ops, .parent_hws = (const struct clk_hw *[]) { &meson8b_vclk_div4_div.hw @@ -1423,7 +1401,7 @@ static struct clk_fixed_factor meson8b_vclk_div6_div = { .mult = 1, .div = 6, .hw.init = &(struct clk_init_data){ - .name = "vclk_div6", + .name = "vclk_div6_div", .ops = &clk_fixed_factor_ops, .parent_hws = (const struct clk_hw *[]) { &meson8b_vclk_en.hw @@ -1433,13 +1411,13 @@ static struct clk_fixed_factor meson8b_vclk_div6_div = { } }; -static struct clk_regmap meson8b_vclk_div6_div_gate = { +static struct clk_regmap meson8b_vclk_div6 = { .data = &(struct clk_regmap_gate_data){ .offset = HHI_VID_CLK_CNTL, .bit_idx = 3, }, .hw.init = &(struct clk_init_data){ - .name = "vclk_div6_en", + .name = "vclk_div6", .ops = &clk_regmap_gate_ops, .parent_hws = (const struct clk_hw *[]) { &meson8b_vclk_div6_div.hw @@ -1453,7 +1431,7 @@ static struct clk_fixed_factor meson8b_vclk_div12_div = { .mult = 1, .div = 12, .hw.init = &(struct clk_init_data){ - .name = "vclk_div12", + .name = "vclk_div12_div", .ops = &clk_fixed_factor_ops, .parent_hws = (const struct clk_hw *[]) { &meson8b_vclk_en.hw @@ -1463,13 +1441,13 @@ static struct clk_fixed_factor meson8b_vclk_div12_div = { } }; -static struct clk_regmap meson8b_vclk_div12_div_gate = { +static struct clk_regmap meson8b_vclk_div12 = { .data = &(struct clk_regmap_gate_data){ .offset = HHI_VID_CLK_CNTL, .bit_idx = 4, }, .hw.init = &(struct clk_init_data){ - .name = "vclk_div12_en", + .name = "vclk_div12", .ops = &clk_regmap_gate_ops, .parent_hws = (const struct clk_hw *[]) { &meson8b_vclk_div12_div.hw @@ -1488,13 +1466,13 @@ static struct clk_regmap meson8b_vclk2_in_sel = { .hw.init = &(struct clk_init_data){ .name = "vclk2_in_sel", .ops = &clk_regmap_mux_ops, - .parent_hws = meson8b_vclk_mux_parent_hws, - .num_parents = ARRAY_SIZE(meson8b_vclk_mux_parent_hws), + .parent_hws = meson8b_vclk_parents, + .num_parents = ARRAY_SIZE(meson8b_vclk_parents), .flags = CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT, }, }; -static struct clk_regmap meson8b_vclk2_clk_in_en = { +static struct clk_regmap meson8b_vclk2_in_en = { .data = &(struct clk_regmap_gate_data){ .offset = HHI_VIID_CLK_DIV, .bit_idx = 16, @@ -1510,7 +1488,7 @@ static struct clk_regmap meson8b_vclk2_clk_in_en = { }, }; -static struct clk_regmap meson8b_vclk2_clk_en = { +static struct clk_regmap meson8b_vclk2_en = { .data = &(struct clk_regmap_gate_data){ .offset = HHI_VIID_CLK_DIV, .bit_idx = 19, @@ -1519,23 +1497,23 @@ static struct clk_regmap meson8b_vclk2_clk_en = { .name = "vclk2_en", .ops = &clk_regmap_gate_ops, .parent_hws = (const struct clk_hw *[]) { - &meson8b_vclk2_clk_in_en.hw + &meson8b_vclk2_in_en.hw }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, }; -static struct clk_regmap meson8b_vclk2_div1_gate = { +static struct clk_regmap meson8b_vclk2_div1 = { .data = &(struct clk_regmap_gate_data){ .offset = HHI_VIID_CLK_DIV, .bit_idx = 0, }, .hw.init = &(struct clk_init_data){ - .name = "vclk2_div1_en", + .name = "vclk2_div1", .ops = &clk_regmap_gate_ops, .parent_hws = (const struct clk_hw *[]) { - &meson8b_vclk2_clk_en.hw + &meson8b_vclk2_en.hw }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, @@ -1546,23 +1524,23 @@ static struct clk_fixed_factor meson8b_vclk2_div2_div = { .mult = 1, .div = 2, .hw.init = &(struct clk_init_data){ - .name = "vclk2_div2", + .name = "vclk2_div2_div", .ops = &clk_fixed_factor_ops, .parent_hws = (const struct clk_hw *[]) { - &meson8b_vclk2_clk_en.hw + &meson8b_vclk2_en.hw }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, } }; -static struct clk_regmap meson8b_vclk2_div2_div_gate = { +static struct clk_regmap meson8b_vclk2_div2 = { .data = &(struct clk_regmap_gate_data){ .offset = HHI_VIID_CLK_DIV, .bit_idx = 1, }, .hw.init = &(struct clk_init_data){ - .name = "vclk2_div2_en", + .name = "vclk2_div2", .ops = &clk_regmap_gate_ops, .parent_hws = (const struct clk_hw *[]) { &meson8b_vclk2_div2_div.hw @@ -1576,23 +1554,23 @@ static struct clk_fixed_factor meson8b_vclk2_div4_div = { .mult = 1, .div = 4, .hw.init = &(struct clk_init_data){ - .name = "vclk2_div4", + .name = "vclk2_div4_div", .ops = &clk_fixed_factor_ops, .parent_hws = (const struct clk_hw *[]) { - &meson8b_vclk2_clk_en.hw + &meson8b_vclk2_en.hw }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, } }; -static struct clk_regmap meson8b_vclk2_div4_div_gate = { +static struct clk_regmap meson8b_vclk2_div4 = { .data = &(struct clk_regmap_gate_data){ .offset = HHI_VIID_CLK_DIV, .bit_idx = 2, }, .hw.init = &(struct clk_init_data){ - .name = "vclk2_div4_en", + .name = "vclk2_div4", .ops = &clk_regmap_gate_ops, .parent_hws = (const struct clk_hw *[]) { &meson8b_vclk2_div4_div.hw @@ -1606,23 +1584,23 @@ static struct clk_fixed_factor meson8b_vclk2_div6_div = { .mult = 1, .div = 6, .hw.init = &(struct clk_init_data){ - .name = "vclk2_div6", + .name = "vclk2_div6_div", .ops = &clk_fixed_factor_ops, .parent_hws = (const struct clk_hw *[]) { - &meson8b_vclk2_clk_en.hw + &meson8b_vclk2_en.hw }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, } }; -static struct clk_regmap meson8b_vclk2_div6_div_gate = { +static struct clk_regmap meson8b_vclk2_div6 = { .data = &(struct clk_regmap_gate_data){ .offset = HHI_VIID_CLK_DIV, .bit_idx = 3, }, .hw.init = &(struct clk_init_data){ - .name = "vclk2_div6_en", + .name = "vclk2_div6", .ops = &clk_regmap_gate_ops, .parent_hws = (const struct clk_hw *[]) { &meson8b_vclk2_div6_div.hw @@ -1636,23 +1614,23 @@ static struct clk_fixed_factor meson8b_vclk2_div12_div = { .mult = 1, .div = 12, .hw.init = &(struct clk_init_data){ - .name = "vclk2_div12", + .name = "vclk2_div12_div", .ops = &clk_fixed_factor_ops, .parent_hws = (const struct clk_hw *[]) { - &meson8b_vclk2_clk_en.hw + &meson8b_vclk2_en.hw }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, } }; -static struct clk_regmap meson8b_vclk2_div12_div_gate = { +static struct clk_regmap meson8b_vclk2_div12 = { .data = &(struct clk_regmap_gate_data){ .offset = HHI_VIID_CLK_DIV, .bit_idx = 4, }, .hw.init = &(struct clk_init_data){ - .name = "vclk2_div12_en", + .name = "vclk2_div12", .ops = &clk_regmap_gate_ops, .parent_hws = (const struct clk_hw *[]) { &meson8b_vclk2_div12_div.hw @@ -1662,12 +1640,12 @@ static struct clk_regmap meson8b_vclk2_div12_div_gate = { }, }; -static const struct clk_hw *meson8b_vclk_enc_mux_parent_hws[] = { - &meson8b_vclk_div1_gate.hw, - &meson8b_vclk_div2_div_gate.hw, - &meson8b_vclk_div4_div_gate.hw, - &meson8b_vclk_div6_div_gate.hw, - &meson8b_vclk_div12_div_gate.hw, +static const struct clk_hw *meson8b_vclk_enc_parents[] = { + &meson8b_vclk_div1.hw, + &meson8b_vclk_div2.hw, + &meson8b_vclk_div4.hw, + &meson8b_vclk_div6.hw, + &meson8b_vclk_div12.hw, }; static struct clk_regmap meson8b_cts_enct_sel = { @@ -1679,8 +1657,8 @@ static struct clk_regmap meson8b_cts_enct_sel = { .hw.init = &(struct clk_init_data){ .name = "cts_enct_sel", .ops = &clk_regmap_mux_ops, - .parent_hws = meson8b_vclk_enc_mux_parent_hws, - .num_parents = ARRAY_SIZE(meson8b_vclk_enc_mux_parent_hws), + .parent_hws = meson8b_vclk_enc_parents, + .num_parents = ARRAY_SIZE(meson8b_vclk_enc_parents), .flags = CLK_SET_RATE_PARENT, }, }; @@ -1710,8 +1688,8 @@ static struct clk_regmap meson8b_cts_encp_sel = { .hw.init = &(struct clk_init_data){ .name = "cts_encp_sel", .ops = &clk_regmap_mux_ops, - .parent_hws = meson8b_vclk_enc_mux_parent_hws, - .num_parents = ARRAY_SIZE(meson8b_vclk_enc_mux_parent_hws), + .parent_hws = meson8b_vclk_enc_parents, + .num_parents = ARRAY_SIZE(meson8b_vclk_enc_parents), .flags = CLK_SET_RATE_PARENT, }, }; @@ -1741,8 +1719,8 @@ static struct clk_regmap meson8b_cts_enci_sel = { .hw.init = &(struct clk_init_data){ .name = "cts_enci_sel", .ops = &clk_regmap_mux_ops, - .parent_hws = meson8b_vclk_enc_mux_parent_hws, - .num_parents = ARRAY_SIZE(meson8b_vclk_enc_mux_parent_hws), + .parent_hws = meson8b_vclk_enc_parents, + .num_parents = ARRAY_SIZE(meson8b_vclk_enc_parents), .flags = CLK_SET_RATE_PARENT, }, }; @@ -1772,8 +1750,8 @@ static struct clk_regmap meson8b_hdmi_tx_pixel_sel = { .hw.init = &(struct clk_init_data){ .name = "hdmi_tx_pixel_sel", .ops = &clk_regmap_mux_ops, - .parent_hws = meson8b_vclk_enc_mux_parent_hws, - .num_parents = ARRAY_SIZE(meson8b_vclk_enc_mux_parent_hws), + .parent_hws = meson8b_vclk_enc_parents, + .num_parents = ARRAY_SIZE(meson8b_vclk_enc_parents), .flags = CLK_SET_RATE_PARENT, }, }; @@ -1794,14 +1772,6 @@ static struct clk_regmap meson8b_hdmi_tx_pixel = { }, }; -static const struct clk_hw *meson8b_vclk2_enc_mux_parent_hws[] = { - &meson8b_vclk2_div1_gate.hw, - &meson8b_vclk2_div2_div_gate.hw, - &meson8b_vclk2_div4_div_gate.hw, - &meson8b_vclk2_div6_div_gate.hw, - &meson8b_vclk2_div12_div_gate.hw, -}; - static struct clk_regmap meson8b_cts_encl_sel = { .data = &(struct clk_regmap_mux_data){ .offset = HHI_VIID_CLK_DIV, @@ -1811,8 +1781,8 @@ static struct clk_regmap meson8b_cts_encl_sel = { .hw.init = &(struct clk_init_data){ .name = "cts_encl_sel", .ops = &clk_regmap_mux_ops, - .parent_hws = meson8b_vclk2_enc_mux_parent_hws, - .num_parents = ARRAY_SIZE(meson8b_vclk2_enc_mux_parent_hws), + .parent_hws = meson8b_vclk_enc_parents, + .num_parents = ARRAY_SIZE(meson8b_vclk_enc_parents), .flags = CLK_SET_RATE_PARENT, }, }; @@ -1842,8 +1812,8 @@ static struct clk_regmap meson8b_cts_vdac0_sel = { .hw.init = &(struct clk_init_data){ .name = "cts_vdac0_sel", .ops = &clk_regmap_mux_ops, - .parent_hws = meson8b_vclk2_enc_mux_parent_hws, - .num_parents = ARRAY_SIZE(meson8b_vclk2_enc_mux_parent_hws), + .parent_hws = meson8b_vclk_enc_parents, + .num_parents = ARRAY_SIZE(meson8b_vclk_enc_parents), .flags = CLK_SET_RATE_PARENT, }, }; @@ -1926,7 +1896,8 @@ static struct clk_regmap meson8b_hdmi_sys = { * CLK_SET_RATE_GATE is set. * Meson8 only has mali_0 and no glitch-free mux. */ -static const struct clk_parent_data meson8b_mali_0_1_parent_data[] = { +static u32 meson8b_mali_parents_val_table[] = { 0, 2, 3, 4, 5, 6, 7 }; +static const struct clk_parent_data meson8b_mali_parents[] = { { .fw_name = "xtal", .name = "xtal", .index = -1, }, { .hw = &meson8b_mpll2.hw, }, { .hw = &meson8b_mpll1.hw, }, @@ -1936,20 +1907,18 @@ static const struct clk_parent_data meson8b_mali_0_1_parent_data[] = { { .hw = &meson8b_fclk_div5.hw, }, }; -static u32 meson8b_mali_0_1_mux_table[] = { 0, 2, 3, 4, 5, 6, 7 }; - static struct clk_regmap meson8b_mali_0_sel = { .data = &(struct clk_regmap_mux_data){ .offset = HHI_MALI_CLK_CNTL, .mask = 0x7, .shift = 9, - .table = meson8b_mali_0_1_mux_table, + .table = meson8b_mali_parents_val_table, }, .hw.init = &(struct clk_init_data){ .name = "mali_0_sel", .ops = &clk_regmap_mux_ops, - .parent_data = meson8b_mali_0_1_parent_data, - .num_parents = ARRAY_SIZE(meson8b_mali_0_1_parent_data), + .parent_data = meson8b_mali_parents, + .num_parents = ARRAY_SIZE(meson8b_mali_parents), /* * Don't propagate rate changes up because the only changeable * parents are mpll1 and mpll2 but we need those for audio and @@ -1998,13 +1967,13 @@ static struct clk_regmap meson8b_mali_1_sel = { .offset = HHI_MALI_CLK_CNTL, .mask = 0x7, .shift = 25, - .table = meson8b_mali_0_1_mux_table, + .table = meson8b_mali_parents_val_table, }, .hw.init = &(struct clk_init_data){ .name = "mali_1_sel", .ops = &clk_regmap_mux_ops, - .parent_data = meson8b_mali_0_1_parent_data, - .num_parents = ARRAY_SIZE(meson8b_mali_0_1_parent_data), + .parent_data = meson8b_mali_parents, + .num_parents = ARRAY_SIZE(meson8b_mali_parents), /* * Don't propagate rate changes up because the only changeable * parents are mpll1 and mpll2 but we need those for audio and @@ -2139,20 +2108,13 @@ static struct clk_regmap meson8m2_gp_pll = { }, }; -static const struct clk_hw *meson8b_vpu_0_1_parent_hws[] = { +static const struct clk_hw *meson8b_vpu_parents[] = { &meson8b_fclk_div4.hw, &meson8b_fclk_div3.hw, &meson8b_fclk_div5.hw, &meson8b_fclk_div7.hw, }; -static const struct clk_hw *mmeson8m2_vpu_0_1_parent_hws[] = { - &meson8b_fclk_div4.hw, - &meson8b_fclk_div3.hw, - &meson8b_fclk_div5.hw, - &meson8m2_gp_pll.hw, -}; - static struct clk_regmap meson8b_vpu_0_sel = { .data = &(struct clk_regmap_mux_data){ .offset = HHI_VPU_CLK_CNTL, @@ -2162,12 +2124,19 @@ static struct clk_regmap meson8b_vpu_0_sel = { .hw.init = &(struct clk_init_data){ .name = "vpu_0_sel", .ops = &clk_regmap_mux_ops, - .parent_hws = meson8b_vpu_0_1_parent_hws, - .num_parents = ARRAY_SIZE(meson8b_vpu_0_1_parent_hws), + .parent_hws = meson8b_vpu_parents, + .num_parents = ARRAY_SIZE(meson8b_vpu_parents), .flags = CLK_SET_RATE_PARENT, }, }; +static const struct clk_hw *mmeson8m2_vpu_parents[] = { + &meson8b_fclk_div4.hw, + &meson8b_fclk_div3.hw, + &meson8b_fclk_div5.hw, + &meson8m2_gp_pll.hw, +}; + static struct clk_regmap meson8m2_vpu_0_sel = { .data = &(struct clk_regmap_mux_data){ .offset = HHI_VPU_CLK_CNTL, @@ -2177,8 +2146,8 @@ static struct clk_regmap meson8m2_vpu_0_sel = { .hw.init = &(struct clk_init_data){ .name = "vpu_0_sel", .ops = &clk_regmap_mux_ops, - .parent_hws = mmeson8m2_vpu_0_1_parent_hws, - .num_parents = ARRAY_SIZE(mmeson8m2_vpu_0_1_parent_hws), + .parent_hws = mmeson8m2_vpu_parents, + .num_parents = ARRAY_SIZE(mmeson8m2_vpu_parents), .flags = CLK_SET_RATE_PARENT, }, }; @@ -2233,8 +2202,8 @@ static struct clk_regmap meson8b_vpu_1_sel = { .hw.init = &(struct clk_init_data){ .name = "vpu_1_sel", .ops = &clk_regmap_mux_ops, - .parent_hws = meson8b_vpu_0_1_parent_hws, - .num_parents = ARRAY_SIZE(meson8b_vpu_0_1_parent_hws), + .parent_hws = meson8b_vpu_parents, + .num_parents = ARRAY_SIZE(meson8b_vpu_parents), .flags = CLK_SET_RATE_PARENT, }, }; @@ -2248,8 +2217,8 @@ static struct clk_regmap meson8m2_vpu_1_sel = { .hw.init = &(struct clk_init_data){ .name = "vpu_1_sel", .ops = &clk_regmap_mux_ops, - .parent_hws = mmeson8m2_vpu_0_1_parent_hws, - .num_parents = ARRAY_SIZE(mmeson8m2_vpu_0_1_parent_hws), + .parent_hws = mmeson8m2_vpu_parents, + .num_parents = ARRAY_SIZE(mmeson8m2_vpu_parents), .flags = CLK_SET_RATE_PARENT, }, }; @@ -2321,7 +2290,7 @@ static struct clk_regmap meson8b_vpu = { }, }; -static const struct clk_hw *meson8b_vdec_parent_hws[] = { +static const struct clk_hw *meson8b_vdec_parents[] = { &meson8b_fclk_div4.hw, &meson8b_fclk_div3.hw, &meson8b_fclk_div5.hw, @@ -2340,8 +2309,8 @@ static struct clk_regmap meson8b_vdec_1_sel = { .hw.init = &(struct clk_init_data){ .name = "vdec_1_sel", .ops = &clk_regmap_mux_ops, - .parent_hws = meson8b_vdec_parent_hws, - .num_parents = ARRAY_SIZE(meson8b_vdec_parent_hws), + .parent_hws = meson8b_vdec_parents, + .num_parents = ARRAY_SIZE(meson8b_vdec_parents), .flags = CLK_SET_RATE_PARENT, }, }; @@ -2443,8 +2412,8 @@ static struct clk_regmap meson8b_vdec_hcodec_sel = { .hw.init = &(struct clk_init_data){ .name = "vdec_hcodec_sel", .ops = &clk_regmap_mux_ops, - .parent_hws = meson8b_vdec_parent_hws, - .num_parents = ARRAY_SIZE(meson8b_vdec_parent_hws), + .parent_hws = meson8b_vdec_parents, + .num_parents = ARRAY_SIZE(meson8b_vdec_parents), .flags = CLK_SET_RATE_PARENT, }, }; @@ -2493,8 +2462,8 @@ static struct clk_regmap meson8b_vdec_2_sel = { .hw.init = &(struct clk_init_data){ .name = "vdec_2_sel", .ops = &clk_regmap_mux_ops, - .parent_hws = meson8b_vdec_parent_hws, - .num_parents = ARRAY_SIZE(meson8b_vdec_parent_hws), + .parent_hws = meson8b_vdec_parents, + .num_parents = ARRAY_SIZE(meson8b_vdec_parents), .flags = CLK_SET_RATE_PARENT, }, }; @@ -2543,8 +2512,8 @@ static struct clk_regmap meson8b_vdec_hevc_sel = { .hw.init = &(struct clk_init_data){ .name = "vdec_hevc_sel", .ops = &clk_regmap_mux_ops, - .parent_hws = meson8b_vdec_parent_hws, - .num_parents = ARRAY_SIZE(meson8b_vdec_parent_hws), + .parent_hws = meson8b_vdec_parents, + .num_parents = ARRAY_SIZE(meson8b_vdec_parents), .flags = CLK_SET_RATE_PARENT, }, }; @@ -2603,27 +2572,26 @@ static struct clk_regmap meson8b_vdec_hevc = { }; /* TODO: the clock at index 0 is "DDR_PLL" which we don't support yet */ -static const struct clk_hw *meson8b_cts_amclk_parent_hws[] = { +static u32 meson8b_cts_mclk_parents_val_table[] = { 1, 2, 3 }; +static const struct clk_hw *meson8b_cts_mclk_parents[] = { &meson8b_mpll0.hw, &meson8b_mpll1.hw, &meson8b_mpll2.hw }; -static u32 meson8b_cts_amclk_mux_table[] = { 1, 2, 3 }; - static struct clk_regmap meson8b_cts_amclk_sel = { .data = &(struct clk_regmap_mux_data){ .offset = HHI_AUD_CLK_CNTL, .mask = 0x3, .shift = 9, - .table = meson8b_cts_amclk_mux_table, + .table = meson8b_cts_mclk_parents_val_table, .flags = CLK_MUX_ROUND_CLOSEST, }, .hw.init = &(struct clk_init_data){ .name = "cts_amclk_sel", .ops = &clk_regmap_mux_ops, - .parent_hws = meson8b_cts_amclk_parent_hws, - .num_parents = ARRAY_SIZE(meson8b_cts_amclk_parent_hws), + .parent_hws = meson8b_cts_mclk_parents, + .num_parents = ARRAY_SIZE(meson8b_cts_mclk_parents), }, }; @@ -2661,28 +2629,19 @@ static struct clk_regmap meson8b_cts_amclk = { }, }; -/* TODO: the clock at index 0 is "DDR_PLL" which we don't support yet */ -static const struct clk_hw *meson8b_cts_mclk_i958_parent_hws[] = { - &meson8b_mpll0.hw, - &meson8b_mpll1.hw, - &meson8b_mpll2.hw -}; - -static u32 meson8b_cts_mclk_i958_mux_table[] = { 1, 2, 3 }; - static struct clk_regmap meson8b_cts_mclk_i958_sel = { .data = &(struct clk_regmap_mux_data){ .offset = HHI_AUD_CLK_CNTL2, .mask = 0x3, .shift = 25, - .table = meson8b_cts_mclk_i958_mux_table, + .table = meson8b_cts_mclk_parents_val_table, .flags = CLK_MUX_ROUND_CLOSEST, }, .hw.init = &(struct clk_init_data) { .name = "cts_mclk_i958_sel", .ops = &clk_regmap_mux_ops, - .parent_hws = meson8b_cts_mclk_i958_parent_hws, - .num_parents = ARRAY_SIZE(meson8b_cts_mclk_i958_parent_hws), + .parent_hws = meson8b_cts_mclk_parents, + .num_parents = ARRAY_SIZE(meson8b_cts_mclk_parents), }, }; @@ -2742,113 +2701,128 @@ static struct clk_regmap meson8b_cts_i958 = { }, }; -#define MESON_GATE(_name, _reg, _bit) \ - MESON_PCLK(_name, _reg, _bit, &meson8b_clk81.hw) - -/* Everything Else (EE) domain gates */ - -static MESON_GATE(meson8b_ddr, HHI_GCLK_MPEG0, 0); -static MESON_GATE(meson8b_dos, HHI_GCLK_MPEG0, 1); -static MESON_GATE(meson8b_isa, HHI_GCLK_MPEG0, 5); -static MESON_GATE(meson8b_pl301, HHI_GCLK_MPEG0, 6); -static MESON_GATE(meson8b_periphs, HHI_GCLK_MPEG0, 7); -static MESON_GATE(meson8b_spicc, HHI_GCLK_MPEG0, 8); -static MESON_GATE(meson8b_i2c, HHI_GCLK_MPEG0, 9); -static MESON_GATE(meson8b_sar_adc, HHI_GCLK_MPEG0, 10); -static MESON_GATE(meson8b_smart_card, HHI_GCLK_MPEG0, 11); -static MESON_GATE(meson8b_rng0, HHI_GCLK_MPEG0, 12); -static MESON_GATE(meson8b_uart0, HHI_GCLK_MPEG0, 13); -static MESON_GATE(meson8b_sdhc, HHI_GCLK_MPEG0, 14); -static MESON_GATE(meson8b_stream, HHI_GCLK_MPEG0, 15); -static MESON_GATE(meson8b_async_fifo, HHI_GCLK_MPEG0, 16); -static MESON_GATE(meson8b_sdio, HHI_GCLK_MPEG0, 17); -static MESON_GATE(meson8b_abuf, HHI_GCLK_MPEG0, 18); -static MESON_GATE(meson8b_hiu_iface, HHI_GCLK_MPEG0, 19); -static MESON_GATE(meson8b_assist_misc, HHI_GCLK_MPEG0, 23); -static MESON_GATE(meson8b_spi, HHI_GCLK_MPEG0, 30); - -static MESON_GATE(meson8b_i2s_spdif, HHI_GCLK_MPEG1, 2); -static MESON_GATE(meson8b_eth, HHI_GCLK_MPEG1, 3); -static MESON_GATE(meson8b_demux, HHI_GCLK_MPEG1, 4); -static MESON_GATE(meson8b_blkmv, HHI_GCLK_MPEG1, 14); -static MESON_GATE(meson8b_aiu, HHI_GCLK_MPEG1, 15); -static MESON_GATE(meson8b_uart1, HHI_GCLK_MPEG1, 16); -static MESON_GATE(meson8b_g2d, HHI_GCLK_MPEG1, 20); -static MESON_GATE(meson8b_usb0, HHI_GCLK_MPEG1, 21); -static MESON_GATE(meson8b_usb1, HHI_GCLK_MPEG1, 22); -static MESON_GATE(meson8b_reset, HHI_GCLK_MPEG1, 23); -static MESON_GATE(meson8b_nand, HHI_GCLK_MPEG1, 24); -static MESON_GATE(meson8b_dos_parser, HHI_GCLK_MPEG1, 25); -static MESON_GATE(meson8b_usb, HHI_GCLK_MPEG1, 26); -static MESON_GATE(meson8b_vdin1, HHI_GCLK_MPEG1, 28); -static MESON_GATE(meson8b_ahb_arb0, HHI_GCLK_MPEG1, 29); -static MESON_GATE(meson8b_efuse, HHI_GCLK_MPEG1, 30); -static MESON_GATE(meson8b_boot_rom, HHI_GCLK_MPEG1, 31); - -static MESON_GATE(meson8b_ahb_data_bus, HHI_GCLK_MPEG2, 1); -static MESON_GATE(meson8b_ahb_ctrl_bus, HHI_GCLK_MPEG2, 2); -static MESON_GATE(meson8b_hdmi_intr_sync, HHI_GCLK_MPEG2, 3); -static MESON_GATE(meson8b_hdmi_pclk, HHI_GCLK_MPEG2, 4); -static MESON_GATE(meson8b_usb1_ddr_bridge, HHI_GCLK_MPEG2, 8); -static MESON_GATE(meson8b_usb0_ddr_bridge, HHI_GCLK_MPEG2, 9); -static MESON_GATE(meson8b_mmc_pclk, HHI_GCLK_MPEG2, 11); -static MESON_GATE(meson8b_dvin, HHI_GCLK_MPEG2, 12); -static MESON_GATE(meson8b_uart2, HHI_GCLK_MPEG2, 15); -static MESON_GATE(meson8b_sana, HHI_GCLK_MPEG2, 22); -static MESON_GATE(meson8b_vpu_intr, HHI_GCLK_MPEG2, 25); -static MESON_GATE(meson8b_sec_ahb_ahb3_bridge, HHI_GCLK_MPEG2, 26); -static MESON_GATE(meson8b_clk81_a9, HHI_GCLK_MPEG2, 29); - -static MESON_GATE(meson8b_vclk2_venci0, HHI_GCLK_OTHER, 1); -static MESON_GATE(meson8b_vclk2_venci1, HHI_GCLK_OTHER, 2); -static MESON_GATE(meson8b_vclk2_vencp0, HHI_GCLK_OTHER, 3); -static MESON_GATE(meson8b_vclk2_vencp1, HHI_GCLK_OTHER, 4); -static MESON_GATE(meson8b_gclk_venci_int, HHI_GCLK_OTHER, 8); -static MESON_GATE(meson8b_gclk_vencp_int, HHI_GCLK_OTHER, 9); -static MESON_GATE(meson8b_dac_clk, HHI_GCLK_OTHER, 10); -static MESON_GATE(meson8b_aoclk_gate, HHI_GCLK_OTHER, 14); -static MESON_GATE(meson8b_iec958_gate, HHI_GCLK_OTHER, 16); -static MESON_GATE(meson8b_enc480p, HHI_GCLK_OTHER, 20); -static MESON_GATE(meson8b_rng1, HHI_GCLK_OTHER, 21); -static MESON_GATE(meson8b_gclk_vencl_int, HHI_GCLK_OTHER, 22); -static MESON_GATE(meson8b_vclk2_venclmcc, HHI_GCLK_OTHER, 24); -static MESON_GATE(meson8b_vclk2_vencl, HHI_GCLK_OTHER, 25); -static MESON_GATE(meson8b_vclk2_other, HHI_GCLK_OTHER, 26); -static MESON_GATE(meson8b_edp, HHI_GCLK_OTHER, 31); +static const struct clk_parent_data meson8b_pclk_parents = { .hw = &meson8b_clk81.hw }; + +#define MESON8B_PCLK(_name, _reg, _bit, _flags) \ + MESON_PCLK(_name, _reg, _bit, &meson8b_pclk_parents, _flags) + +/* + * Everything Else (EE) domain gates + * + * NOTE: The gates below are marked with CLK_IGNORE_UNUSED for historic reasons + * Users are encouraged to test without it and submit changes to: + * - remove the flag if not necessary + * - replace the flag with something more adequate, such as CLK_IS_CRITICAL, + * if appropriate. + * - add a comment explaining why the use of CLK_IGNORE_UNUSED is desirable + * for a particular clock. + */ +static MESON8B_PCLK(meson8b_ddr, HHI_GCLK_MPEG0, 0, CLK_IGNORE_UNUSED); +static MESON8B_PCLK(meson8b_dos, HHI_GCLK_MPEG0, 1, CLK_IGNORE_UNUSED); +static MESON8B_PCLK(meson8b_isa, HHI_GCLK_MPEG0, 5, CLK_IGNORE_UNUSED); +static MESON8B_PCLK(meson8b_pl301, HHI_GCLK_MPEG0, 6, CLK_IGNORE_UNUSED); +static MESON8B_PCLK(meson8b_periphs, HHI_GCLK_MPEG0, 7, CLK_IGNORE_UNUSED); +static MESON8B_PCLK(meson8b_spicc, HHI_GCLK_MPEG0, 8, CLK_IGNORE_UNUSED); +static MESON8B_PCLK(meson8b_i2c, HHI_GCLK_MPEG0, 9, CLK_IGNORE_UNUSED); +static MESON8B_PCLK(meson8b_sar_adc, HHI_GCLK_MPEG0, 10, CLK_IGNORE_UNUSED); +static MESON8B_PCLK(meson8b_smart_card, HHI_GCLK_MPEG0, 11, CLK_IGNORE_UNUSED); +static MESON8B_PCLK(meson8b_rng0, HHI_GCLK_MPEG0, 12, CLK_IGNORE_UNUSED); +static MESON8B_PCLK(meson8b_uart0, HHI_GCLK_MPEG0, 13, CLK_IGNORE_UNUSED); +static MESON8B_PCLK(meson8b_sdhc, HHI_GCLK_MPEG0, 14, CLK_IGNORE_UNUSED); +static MESON8B_PCLK(meson8b_stream, HHI_GCLK_MPEG0, 15, CLK_IGNORE_UNUSED); +static MESON8B_PCLK(meson8b_async_fifo, HHI_GCLK_MPEG0, 16, CLK_IGNORE_UNUSED); +static MESON8B_PCLK(meson8b_sdio, HHI_GCLK_MPEG0, 17, CLK_IGNORE_UNUSED); +static MESON8B_PCLK(meson8b_abuf, HHI_GCLK_MPEG0, 18, CLK_IGNORE_UNUSED); +static MESON8B_PCLK(meson8b_hiu_iface, HHI_GCLK_MPEG0, 19, CLK_IGNORE_UNUSED); +static MESON8B_PCLK(meson8b_assist_misc, HHI_GCLK_MPEG0, 23, CLK_IGNORE_UNUSED); +static MESON8B_PCLK(meson8b_spi, HHI_GCLK_MPEG0, 30, CLK_IGNORE_UNUSED); + +static MESON8B_PCLK(meson8b_i2s_spdif, HHI_GCLK_MPEG1, 2, CLK_IGNORE_UNUSED); +static MESON8B_PCLK(meson8b_eth, HHI_GCLK_MPEG1, 3, CLK_IGNORE_UNUSED); +static MESON8B_PCLK(meson8b_demux, HHI_GCLK_MPEG1, 4, CLK_IGNORE_UNUSED); +static MESON8B_PCLK(meson8b_blkmv, HHI_GCLK_MPEG1, 14, CLK_IGNORE_UNUSED); +static MESON8B_PCLK(meson8b_aiu, HHI_GCLK_MPEG1, 15, CLK_IGNORE_UNUSED); +static MESON8B_PCLK(meson8b_uart1, HHI_GCLK_MPEG1, 16, CLK_IGNORE_UNUSED); +static MESON8B_PCLK(meson8b_g2d, HHI_GCLK_MPEG1, 20, CLK_IGNORE_UNUSED); +static MESON8B_PCLK(meson8b_usb0, HHI_GCLK_MPEG1, 21, CLK_IGNORE_UNUSED); +static MESON8B_PCLK(meson8b_usb1, HHI_GCLK_MPEG1, 22, CLK_IGNORE_UNUSED); +static MESON8B_PCLK(meson8b_reset, HHI_GCLK_MPEG1, 23, CLK_IGNORE_UNUSED); +static MESON8B_PCLK(meson8b_nand, HHI_GCLK_MPEG1, 24, CLK_IGNORE_UNUSED); +static MESON8B_PCLK(meson8b_dos_parser, HHI_GCLK_MPEG1, 25, CLK_IGNORE_UNUSED); +static MESON8B_PCLK(meson8b_usb, HHI_GCLK_MPEG1, 26, CLK_IGNORE_UNUSED); +static MESON8B_PCLK(meson8b_vdin1, HHI_GCLK_MPEG1, 28, CLK_IGNORE_UNUSED); +static MESON8B_PCLK(meson8b_ahb_arb0, HHI_GCLK_MPEG1, 29, CLK_IGNORE_UNUSED); +static MESON8B_PCLK(meson8b_efuse, HHI_GCLK_MPEG1, 30, CLK_IGNORE_UNUSED); +static MESON8B_PCLK(meson8b_boot_rom, HHI_GCLK_MPEG1, 31, CLK_IGNORE_UNUSED); + +static MESON8B_PCLK(meson8b_ahb_data_bus, HHI_GCLK_MPEG2, 1, CLK_IGNORE_UNUSED); +static MESON8B_PCLK(meson8b_ahb_ctrl_bus, HHI_GCLK_MPEG2, 2, CLK_IGNORE_UNUSED); +static MESON8B_PCLK(meson8b_hdmi_intr_sync, HHI_GCLK_MPEG2, 3, CLK_IGNORE_UNUSED); +static MESON8B_PCLK(meson8b_hdmi_pclk, HHI_GCLK_MPEG2, 4, CLK_IGNORE_UNUSED); +static MESON8B_PCLK(meson8b_usb1_ddr_bridge, HHI_GCLK_MPEG2, 8, CLK_IGNORE_UNUSED); +static MESON8B_PCLK(meson8b_usb0_ddr_bridge, HHI_GCLK_MPEG2, 9, CLK_IGNORE_UNUSED); +static MESON8B_PCLK(meson8b_mmc_pclk, HHI_GCLK_MPEG2, 11, CLK_IGNORE_UNUSED); +static MESON8B_PCLK(meson8b_dvin, HHI_GCLK_MPEG2, 12, CLK_IGNORE_UNUSED); +static MESON8B_PCLK(meson8b_uart2, HHI_GCLK_MPEG2, 15, CLK_IGNORE_UNUSED); +static MESON8B_PCLK(meson8b_sana, HHI_GCLK_MPEG2, 22, CLK_IGNORE_UNUSED); +static MESON8B_PCLK(meson8b_vpu_intr, HHI_GCLK_MPEG2, 25, CLK_IGNORE_UNUSED); +static MESON8B_PCLK(meson8b_sec_ahb_ahb3_bridge, HHI_GCLK_MPEG2, 26, CLK_IGNORE_UNUSED); +static MESON8B_PCLK(meson8b_clk81_a9, HHI_GCLK_MPEG2, 29, CLK_IGNORE_UNUSED); + +static MESON8B_PCLK(meson8b_vclk2_venci0, HHI_GCLK_OTHER, 1, CLK_IGNORE_UNUSED); +static MESON8B_PCLK(meson8b_vclk2_venci1, HHI_GCLK_OTHER, 2, CLK_IGNORE_UNUSED); +static MESON8B_PCLK(meson8b_vclk2_vencp0, HHI_GCLK_OTHER, 3, CLK_IGNORE_UNUSED); +static MESON8B_PCLK(meson8b_vclk2_vencp1, HHI_GCLK_OTHER, 4, CLK_IGNORE_UNUSED); +static MESON8B_PCLK(meson8b_gclk_venci_int, HHI_GCLK_OTHER, 8, CLK_IGNORE_UNUSED); +static MESON8B_PCLK(meson8b_gclk_vencp_int, HHI_GCLK_OTHER, 9, CLK_IGNORE_UNUSED); +static MESON8B_PCLK(meson8b_dac_clk, HHI_GCLK_OTHER, 10, CLK_IGNORE_UNUSED); +static MESON8B_PCLK(meson8b_aoclk_gate, HHI_GCLK_OTHER, 14, CLK_IGNORE_UNUSED); +static MESON8B_PCLK(meson8b_iec958_gate, HHI_GCLK_OTHER, 16, CLK_IGNORE_UNUSED); +static MESON8B_PCLK(meson8b_enc480p, HHI_GCLK_OTHER, 20, CLK_IGNORE_UNUSED); +static MESON8B_PCLK(meson8b_rng1, HHI_GCLK_OTHER, 21, CLK_IGNORE_UNUSED); +static MESON8B_PCLK(meson8b_gclk_vencl_int, HHI_GCLK_OTHER, 22, CLK_IGNORE_UNUSED); +static MESON8B_PCLK(meson8b_vclk2_venclmcc, HHI_GCLK_OTHER, 24, CLK_IGNORE_UNUSED); +static MESON8B_PCLK(meson8b_vclk2_vencl, HHI_GCLK_OTHER, 25, CLK_IGNORE_UNUSED); +static MESON8B_PCLK(meson8b_vclk2_other, HHI_GCLK_OTHER, 26, CLK_IGNORE_UNUSED); +static MESON8B_PCLK(meson8b_edp, HHI_GCLK_OTHER, 31, CLK_IGNORE_UNUSED); /* AIU gates */ -#define MESON_AIU_GLUE_GATE(_name, _reg, _bit) \ - MESON_PCLK(_name, _reg, _bit, &meson8b_aiu_glue.hw) - -static MESON_PCLK(meson8b_aiu_glue, HHI_GCLK_MPEG1, 6, &meson8b_aiu.hw); -static MESON_AIU_GLUE_GATE(meson8b_iec958, HHI_GCLK_MPEG1, 7); -static MESON_AIU_GLUE_GATE(meson8b_i2s_out, HHI_GCLK_MPEG1, 8); -static MESON_AIU_GLUE_GATE(meson8b_amclk, HHI_GCLK_MPEG1, 9); -static MESON_AIU_GLUE_GATE(meson8b_aififo2, HHI_GCLK_MPEG1, 10); -static MESON_AIU_GLUE_GATE(meson8b_mixer, HHI_GCLK_MPEG1, 11); -static MESON_AIU_GLUE_GATE(meson8b_mixer_iface, HHI_GCLK_MPEG1, 12); -static MESON_AIU_GLUE_GATE(meson8b_adc, HHI_GCLK_MPEG1, 13); +static const struct clk_parent_data meson8b_aiu_glue_parents = { .hw = &meson8b_aiu.hw }; +static MESON_PCLK(meson8b_aiu_glue, HHI_GCLK_MPEG1, 6, + &meson8b_aiu_glue_parents, CLK_IGNORE_UNUSED); + +static const struct clk_parent_data meson8b_aiu_pclk_parents = { .hw = &meson8b_aiu_glue.hw }; +#define MESON8B_AIU_PCLK(_name, _bit, _flags) \ + MESON_PCLK(_name, HHI_GCLK_MPEG1, _bit, &meson8b_aiu_pclk_parents, _flags) + +static MESON8B_AIU_PCLK(meson8b_iec958, 7, CLK_IGNORE_UNUSED); +static MESON8B_AIU_PCLK(meson8b_i2s_out, 8, CLK_IGNORE_UNUSED); +static MESON8B_AIU_PCLK(meson8b_amclk, 9, CLK_IGNORE_UNUSED); +static MESON8B_AIU_PCLK(meson8b_aififo2, 10, CLK_IGNORE_UNUSED); +static MESON8B_AIU_PCLK(meson8b_mixer, 11, CLK_IGNORE_UNUSED); +static MESON8B_AIU_PCLK(meson8b_mixer_iface, 12, CLK_IGNORE_UNUSED); +static MESON8B_AIU_PCLK(meson8b_adc, 13, CLK_IGNORE_UNUSED); /* Always On (AO) domain gates */ -static MESON_GATE(meson8b_ao_media_cpu, HHI_GCLK_AO, 0); -static MESON_GATE(meson8b_ao_ahb_sram, HHI_GCLK_AO, 1); -static MESON_GATE(meson8b_ao_ahb_bus, HHI_GCLK_AO, 2); -static MESON_GATE(meson8b_ao_iface, HHI_GCLK_AO, 3); +static MESON8B_PCLK(meson8b_ao_media_cpu, HHI_GCLK_AO, 0, CLK_IGNORE_UNUSED); +static MESON8B_PCLK(meson8b_ao_ahb_sram, HHI_GCLK_AO, 1, CLK_IGNORE_UNUSED); +static MESON8B_PCLK(meson8b_ao_ahb_bus, HHI_GCLK_AO, 2, CLK_IGNORE_UNUSED); +static MESON8B_PCLK(meson8b_ao_iface, HHI_GCLK_AO, 3, CLK_IGNORE_UNUSED); static struct clk_hw *meson8_hw_clks[] = { - [CLKID_PLL_FIXED] = &meson8b_fixed_pll.hw, - [CLKID_PLL_VID] = &meson8b_vid_pll.hw, - [CLKID_PLL_SYS] = &meson8b_sys_pll.hw, - [CLKID_FCLK_DIV2] = &meson8b_fclk_div2.hw, - [CLKID_FCLK_DIV3] = &meson8b_fclk_div3.hw, - [CLKID_FCLK_DIV4] = &meson8b_fclk_div4.hw, - [CLKID_FCLK_DIV5] = &meson8b_fclk_div5.hw, - [CLKID_FCLK_DIV7] = &meson8b_fclk_div7.hw, - [CLKID_CPUCLK] = &meson8b_cpu_clk.hw, - [CLKID_MPEG_SEL] = &meson8b_mpeg_clk_sel.hw, - [CLKID_MPEG_DIV] = &meson8b_mpeg_clk_div.hw, - [CLKID_CLK81] = &meson8b_clk81.hw, + [CLKID_PLL_FIXED] = &meson8b_fixed_pll.hw, + [CLKID_PLL_VID] = &meson8b_vid_pll.hw, + [CLKID_PLL_SYS] = &meson8b_sys_pll.hw, + [CLKID_FCLK_DIV2] = &meson8b_fclk_div2.hw, + [CLKID_FCLK_DIV3] = &meson8b_fclk_div3.hw, + [CLKID_FCLK_DIV4] = &meson8b_fclk_div4.hw, + [CLKID_FCLK_DIV5] = &meson8b_fclk_div5.hw, + [CLKID_FCLK_DIV7] = &meson8b_fclk_div7.hw, + [CLKID_CPUCLK] = &meson8b_cpu_clk.hw, + [CLKID_MPEG_SEL] = &meson8b_clk81_sel.hw, + [CLKID_MPEG_DIV] = &meson8b_clk81_div.hw, + [CLKID_CLK81] = &meson8b_clk81.hw, [CLKID_DDR] = &meson8b_ddr.hw, [CLKID_DOS] = &meson8b_dos.hw, [CLKID_ISA] = &meson8b_isa.hw, @@ -2945,7 +2919,7 @@ static struct clk_hw *meson8_hw_clks[] = { [CLKID_FCLK_DIV7_DIV] = &meson8b_fclk_div7_div.hw, [CLKID_NAND_SEL] = &meson8b_nand_clk_sel.hw, [CLKID_NAND_DIV] = &meson8b_nand_clk_div.hw, - [CLKID_NAND_CLK] = &meson8b_nand_clk_gate.hw, + [CLKID_NAND_CLK] = &meson8b_nand_clk.hw, [CLKID_PLL_FIXED_DCO] = &meson8b_fixed_pll_dco.hw, [CLKID_HDMI_PLL_DCO] = &meson8b_hdmi_pll_dco.hw, [CLKID_PLL_SYS_DCO] = &meson8b_sys_pll_dco.hw, @@ -2956,14 +2930,14 @@ static struct clk_hw *meson8_hw_clks[] = { [CLKID_CPU_CLK_DIV6] = &meson8b_cpu_clk_div6.hw, [CLKID_CPU_CLK_DIV7] = &meson8b_cpu_clk_div7.hw, [CLKID_CPU_CLK_DIV8] = &meson8b_cpu_clk_div8.hw, - [CLKID_APB_SEL] = &meson8b_apb_clk_sel.hw, - [CLKID_APB] = &meson8b_apb_clk_gate.hw, - [CLKID_PERIPH_SEL] = &meson8b_periph_clk_sel.hw, - [CLKID_PERIPH] = &meson8b_periph_clk_gate.hw, - [CLKID_AXI_SEL] = &meson8b_axi_clk_sel.hw, - [CLKID_AXI] = &meson8b_axi_clk_gate.hw, - [CLKID_L2_DRAM_SEL] = &meson8b_l2_dram_clk_sel.hw, - [CLKID_L2_DRAM] = &meson8b_l2_dram_clk_gate.hw, + [CLKID_APB_SEL] = &meson8b_apb_sel.hw, + [CLKID_APB] = &meson8b_apb.hw, + [CLKID_PERIPH_SEL] = &meson8b_periph_sel.hw, + [CLKID_PERIPH] = &meson8b_periph.hw, + [CLKID_AXI_SEL] = &meson8b_axi_sel.hw, + [CLKID_AXI] = &meson8b_axi.hw, + [CLKID_L2_DRAM_SEL] = &meson8b_l2_dram_sel.hw, + [CLKID_L2_DRAM] = &meson8b_l2_dram.hw, [CLKID_HDMI_PLL_LVDS_OUT] = &meson8b_hdmi_pll_lvds_out.hw, [CLKID_HDMI_PLL_HDMI_OUT] = &meson8b_hdmi_pll_hdmi_out.hw, [CLKID_VID_PLL_IN_SEL] = &meson8b_vid_pll_in_sel.hw, @@ -2974,27 +2948,27 @@ static struct clk_hw *meson8_hw_clks[] = { [CLKID_VCLK_IN_SEL] = &meson8b_vclk_in_sel.hw, [CLKID_VCLK_IN_EN] = &meson8b_vclk_in_en.hw, [CLKID_VCLK_EN] = &meson8b_vclk_en.hw, - [CLKID_VCLK_DIV1] = &meson8b_vclk_div1_gate.hw, + [CLKID_VCLK_DIV1] = &meson8b_vclk_div1.hw, [CLKID_VCLK_DIV2_DIV] = &meson8b_vclk_div2_div.hw, - [CLKID_VCLK_DIV2] = &meson8b_vclk_div2_div_gate.hw, + [CLKID_VCLK_DIV2] = &meson8b_vclk_div2.hw, [CLKID_VCLK_DIV4_DIV] = &meson8b_vclk_div4_div.hw, - [CLKID_VCLK_DIV4] = &meson8b_vclk_div4_div_gate.hw, + [CLKID_VCLK_DIV4] = &meson8b_vclk_div4.hw, [CLKID_VCLK_DIV6_DIV] = &meson8b_vclk_div6_div.hw, - [CLKID_VCLK_DIV6] = &meson8b_vclk_div6_div_gate.hw, + [CLKID_VCLK_DIV6] = &meson8b_vclk_div6.hw, [CLKID_VCLK_DIV12_DIV] = &meson8b_vclk_div12_div.hw, - [CLKID_VCLK_DIV12] = &meson8b_vclk_div12_div_gate.hw, + [CLKID_VCLK_DIV12] = &meson8b_vclk_div12.hw, [CLKID_VCLK2_IN_SEL] = &meson8b_vclk2_in_sel.hw, - [CLKID_VCLK2_IN_EN] = &meson8b_vclk2_clk_in_en.hw, - [CLKID_VCLK2_EN] = &meson8b_vclk2_clk_en.hw, - [CLKID_VCLK2_DIV1] = &meson8b_vclk2_div1_gate.hw, + [CLKID_VCLK2_IN_EN] = &meson8b_vclk2_in_en.hw, + [CLKID_VCLK2_EN] = &meson8b_vclk2_en.hw, + [CLKID_VCLK2_DIV1] = &meson8b_vclk2_div1.hw, [CLKID_VCLK2_DIV2_DIV] = &meson8b_vclk2_div2_div.hw, - [CLKID_VCLK2_DIV2] = &meson8b_vclk2_div2_div_gate.hw, + [CLKID_VCLK2_DIV2] = &meson8b_vclk2_div2.hw, [CLKID_VCLK2_DIV4_DIV] = &meson8b_vclk2_div4_div.hw, - [CLKID_VCLK2_DIV4] = &meson8b_vclk2_div4_div_gate.hw, + [CLKID_VCLK2_DIV4] = &meson8b_vclk2_div4.hw, [CLKID_VCLK2_DIV6_DIV] = &meson8b_vclk2_div6_div.hw, - [CLKID_VCLK2_DIV6] = &meson8b_vclk2_div6_div_gate.hw, + [CLKID_VCLK2_DIV6] = &meson8b_vclk2_div6.hw, [CLKID_VCLK2_DIV12_DIV] = &meson8b_vclk2_div12_div.hw, - [CLKID_VCLK2_DIV12] = &meson8b_vclk2_div12_div_gate.hw, + [CLKID_VCLK2_DIV12] = &meson8b_vclk2_div12.hw, [CLKID_CTS_ENCT_SEL] = &meson8b_cts_enct_sel.hw, [CLKID_CTS_ENCT] = &meson8b_cts_enct.hw, [CLKID_CTS_ENCP_SEL] = &meson8b_cts_encp_sel.hw, @@ -3041,18 +3015,18 @@ static struct clk_hw *meson8_hw_clks[] = { }; static struct clk_hw *meson8b_hw_clks[] = { - [CLKID_PLL_FIXED] = &meson8b_fixed_pll.hw, - [CLKID_PLL_VID] = &meson8b_vid_pll.hw, - [CLKID_PLL_SYS] = &meson8b_sys_pll.hw, - [CLKID_FCLK_DIV2] = &meson8b_fclk_div2.hw, - [CLKID_FCLK_DIV3] = &meson8b_fclk_div3.hw, - [CLKID_FCLK_DIV4] = &meson8b_fclk_div4.hw, - [CLKID_FCLK_DIV5] = &meson8b_fclk_div5.hw, - [CLKID_FCLK_DIV7] = &meson8b_fclk_div7.hw, - [CLKID_CPUCLK] = &meson8b_cpu_clk.hw, - [CLKID_MPEG_SEL] = &meson8b_mpeg_clk_sel.hw, - [CLKID_MPEG_DIV] = &meson8b_mpeg_clk_div.hw, - [CLKID_CLK81] = &meson8b_clk81.hw, + [CLKID_PLL_FIXED] = &meson8b_fixed_pll.hw, + [CLKID_PLL_VID] = &meson8b_vid_pll.hw, + [CLKID_PLL_SYS] = &meson8b_sys_pll.hw, + [CLKID_FCLK_DIV2] = &meson8b_fclk_div2.hw, + [CLKID_FCLK_DIV3] = &meson8b_fclk_div3.hw, + [CLKID_FCLK_DIV4] = &meson8b_fclk_div4.hw, + [CLKID_FCLK_DIV5] = &meson8b_fclk_div5.hw, + [CLKID_FCLK_DIV7] = &meson8b_fclk_div7.hw, + [CLKID_CPUCLK] = &meson8b_cpu_clk.hw, + [CLKID_MPEG_SEL] = &meson8b_clk81_sel.hw, + [CLKID_MPEG_DIV] = &meson8b_clk81_div.hw, + [CLKID_CLK81] = &meson8b_clk81.hw, [CLKID_DDR] = &meson8b_ddr.hw, [CLKID_DOS] = &meson8b_dos.hw, [CLKID_ISA] = &meson8b_isa.hw, @@ -3149,7 +3123,7 @@ static struct clk_hw *meson8b_hw_clks[] = { [CLKID_FCLK_DIV7_DIV] = &meson8b_fclk_div7_div.hw, [CLKID_NAND_SEL] = &meson8b_nand_clk_sel.hw, [CLKID_NAND_DIV] = &meson8b_nand_clk_div.hw, - [CLKID_NAND_CLK] = &meson8b_nand_clk_gate.hw, + [CLKID_NAND_CLK] = &meson8b_nand_clk.hw, [CLKID_PLL_FIXED_DCO] = &meson8b_fixed_pll_dco.hw, [CLKID_HDMI_PLL_DCO] = &meson8b_hdmi_pll_dco.hw, [CLKID_PLL_SYS_DCO] = &meson8b_sys_pll_dco.hw, @@ -3160,14 +3134,14 @@ static struct clk_hw *meson8b_hw_clks[] = { [CLKID_CPU_CLK_DIV6] = &meson8b_cpu_clk_div6.hw, [CLKID_CPU_CLK_DIV7] = &meson8b_cpu_clk_div7.hw, [CLKID_CPU_CLK_DIV8] = &meson8b_cpu_clk_div8.hw, - [CLKID_APB_SEL] = &meson8b_apb_clk_sel.hw, - [CLKID_APB] = &meson8b_apb_clk_gate.hw, - [CLKID_PERIPH_SEL] = &meson8b_periph_clk_sel.hw, - [CLKID_PERIPH] = &meson8b_periph_clk_gate.hw, - [CLKID_AXI_SEL] = &meson8b_axi_clk_sel.hw, - [CLKID_AXI] = &meson8b_axi_clk_gate.hw, - [CLKID_L2_DRAM_SEL] = &meson8b_l2_dram_clk_sel.hw, - [CLKID_L2_DRAM] = &meson8b_l2_dram_clk_gate.hw, + [CLKID_APB_SEL] = &meson8b_apb_sel.hw, + [CLKID_APB] = &meson8b_apb.hw, + [CLKID_PERIPH_SEL] = &meson8b_periph_sel.hw, + [CLKID_PERIPH] = &meson8b_periph.hw, + [CLKID_AXI_SEL] = &meson8b_axi_sel.hw, + [CLKID_AXI] = &meson8b_axi.hw, + [CLKID_L2_DRAM_SEL] = &meson8b_l2_dram_sel.hw, + [CLKID_L2_DRAM] = &meson8b_l2_dram.hw, [CLKID_HDMI_PLL_LVDS_OUT] = &meson8b_hdmi_pll_lvds_out.hw, [CLKID_HDMI_PLL_HDMI_OUT] = &meson8b_hdmi_pll_hdmi_out.hw, [CLKID_VID_PLL_IN_SEL] = &meson8b_vid_pll_in_sel.hw, @@ -3178,27 +3152,27 @@ static struct clk_hw *meson8b_hw_clks[] = { [CLKID_VCLK_IN_SEL] = &meson8b_vclk_in_sel.hw, [CLKID_VCLK_IN_EN] = &meson8b_vclk_in_en.hw, [CLKID_VCLK_EN] = &meson8b_vclk_en.hw, - [CLKID_VCLK_DIV1] = &meson8b_vclk_div1_gate.hw, + [CLKID_VCLK_DIV1] = &meson8b_vclk_div1.hw, [CLKID_VCLK_DIV2_DIV] = &meson8b_vclk_div2_div.hw, - [CLKID_VCLK_DIV2] = &meson8b_vclk_div2_div_gate.hw, + [CLKID_VCLK_DIV2] = &meson8b_vclk_div2.hw, [CLKID_VCLK_DIV4_DIV] = &meson8b_vclk_div4_div.hw, - [CLKID_VCLK_DIV4] = &meson8b_vclk_div4_div_gate.hw, + [CLKID_VCLK_DIV4] = &meson8b_vclk_div4.hw, [CLKID_VCLK_DIV6_DIV] = &meson8b_vclk_div6_div.hw, - [CLKID_VCLK_DIV6] = &meson8b_vclk_div6_div_gate.hw, + [CLKID_VCLK_DIV6] = &meson8b_vclk_div6.hw, [CLKID_VCLK_DIV12_DIV] = &meson8b_vclk_div12_div.hw, - [CLKID_VCLK_DIV12] = &meson8b_vclk_div12_div_gate.hw, + [CLKID_VCLK_DIV12] = &meson8b_vclk_div12.hw, [CLKID_VCLK2_IN_SEL] = &meson8b_vclk2_in_sel.hw, - [CLKID_VCLK2_IN_EN] = &meson8b_vclk2_clk_in_en.hw, - [CLKID_VCLK2_EN] = &meson8b_vclk2_clk_en.hw, - [CLKID_VCLK2_DIV1] = &meson8b_vclk2_div1_gate.hw, + [CLKID_VCLK2_IN_EN] = &meson8b_vclk2_in_en.hw, + [CLKID_VCLK2_EN] = &meson8b_vclk2_en.hw, + [CLKID_VCLK2_DIV1] = &meson8b_vclk2_div1.hw, [CLKID_VCLK2_DIV2_DIV] = &meson8b_vclk2_div2_div.hw, - [CLKID_VCLK2_DIV2] = &meson8b_vclk2_div2_div_gate.hw, + [CLKID_VCLK2_DIV2] = &meson8b_vclk2_div2.hw, [CLKID_VCLK2_DIV4_DIV] = &meson8b_vclk2_div4_div.hw, - [CLKID_VCLK2_DIV4] = &meson8b_vclk2_div4_div_gate.hw, + [CLKID_VCLK2_DIV4] = &meson8b_vclk2_div4.hw, [CLKID_VCLK2_DIV6_DIV] = &meson8b_vclk2_div6_div.hw, - [CLKID_VCLK2_DIV6] = &meson8b_vclk2_div6_div_gate.hw, + [CLKID_VCLK2_DIV6] = &meson8b_vclk2_div6.hw, [CLKID_VCLK2_DIV12_DIV] = &meson8b_vclk2_div12_div.hw, - [CLKID_VCLK2_DIV12] = &meson8b_vclk2_div12_div_gate.hw, + [CLKID_VCLK2_DIV12] = &meson8b_vclk2_div12.hw, [CLKID_CTS_ENCT_SEL] = &meson8b_cts_enct_sel.hw, [CLKID_CTS_ENCT] = &meson8b_cts_enct.hw, [CLKID_CTS_ENCP_SEL] = &meson8b_cts_encp_sel.hw, @@ -3256,18 +3230,18 @@ static struct clk_hw *meson8b_hw_clks[] = { }; static struct clk_hw *meson8m2_hw_clks[] = { - [CLKID_PLL_FIXED] = &meson8b_fixed_pll.hw, - [CLKID_PLL_VID] = &meson8b_vid_pll.hw, - [CLKID_PLL_SYS] = &meson8b_sys_pll.hw, - [CLKID_FCLK_DIV2] = &meson8b_fclk_div2.hw, - [CLKID_FCLK_DIV3] = &meson8b_fclk_div3.hw, - [CLKID_FCLK_DIV4] = &meson8b_fclk_div4.hw, - [CLKID_FCLK_DIV5] = &meson8b_fclk_div5.hw, - [CLKID_FCLK_DIV7] = &meson8b_fclk_div7.hw, - [CLKID_CPUCLK] = &meson8b_cpu_clk.hw, - [CLKID_MPEG_SEL] = &meson8b_mpeg_clk_sel.hw, - [CLKID_MPEG_DIV] = &meson8b_mpeg_clk_div.hw, - [CLKID_CLK81] = &meson8b_clk81.hw, + [CLKID_PLL_FIXED] = &meson8b_fixed_pll.hw, + [CLKID_PLL_VID] = &meson8b_vid_pll.hw, + [CLKID_PLL_SYS] = &meson8b_sys_pll.hw, + [CLKID_FCLK_DIV2] = &meson8b_fclk_div2.hw, + [CLKID_FCLK_DIV3] = &meson8b_fclk_div3.hw, + [CLKID_FCLK_DIV4] = &meson8b_fclk_div4.hw, + [CLKID_FCLK_DIV5] = &meson8b_fclk_div5.hw, + [CLKID_FCLK_DIV7] = &meson8b_fclk_div7.hw, + [CLKID_CPUCLK] = &meson8b_cpu_clk.hw, + [CLKID_MPEG_SEL] = &meson8b_clk81_sel.hw, + [CLKID_MPEG_DIV] = &meson8b_clk81_div.hw, + [CLKID_CLK81] = &meson8b_clk81.hw, [CLKID_DDR] = &meson8b_ddr.hw, [CLKID_DOS] = &meson8b_dos.hw, [CLKID_ISA] = &meson8b_isa.hw, @@ -3364,7 +3338,7 @@ static struct clk_hw *meson8m2_hw_clks[] = { [CLKID_FCLK_DIV7_DIV] = &meson8b_fclk_div7_div.hw, [CLKID_NAND_SEL] = &meson8b_nand_clk_sel.hw, [CLKID_NAND_DIV] = &meson8b_nand_clk_div.hw, - [CLKID_NAND_CLK] = &meson8b_nand_clk_gate.hw, + [CLKID_NAND_CLK] = &meson8b_nand_clk.hw, [CLKID_PLL_FIXED_DCO] = &meson8b_fixed_pll_dco.hw, [CLKID_HDMI_PLL_DCO] = &meson8b_hdmi_pll_dco.hw, [CLKID_PLL_SYS_DCO] = &meson8b_sys_pll_dco.hw, @@ -3375,14 +3349,14 @@ static struct clk_hw *meson8m2_hw_clks[] = { [CLKID_CPU_CLK_DIV6] = &meson8b_cpu_clk_div6.hw, [CLKID_CPU_CLK_DIV7] = &meson8b_cpu_clk_div7.hw, [CLKID_CPU_CLK_DIV8] = &meson8b_cpu_clk_div8.hw, - [CLKID_APB_SEL] = &meson8b_apb_clk_sel.hw, - [CLKID_APB] = &meson8b_apb_clk_gate.hw, - [CLKID_PERIPH_SEL] = &meson8b_periph_clk_sel.hw, - [CLKID_PERIPH] = &meson8b_periph_clk_gate.hw, - [CLKID_AXI_SEL] = &meson8b_axi_clk_sel.hw, - [CLKID_AXI] = &meson8b_axi_clk_gate.hw, - [CLKID_L2_DRAM_SEL] = &meson8b_l2_dram_clk_sel.hw, - [CLKID_L2_DRAM] = &meson8b_l2_dram_clk_gate.hw, + [CLKID_APB_SEL] = &meson8b_apb_sel.hw, + [CLKID_APB] = &meson8b_apb.hw, + [CLKID_PERIPH_SEL] = &meson8b_periph_sel.hw, + [CLKID_PERIPH] = &meson8b_periph.hw, + [CLKID_AXI_SEL] = &meson8b_axi_sel.hw, + [CLKID_AXI] = &meson8b_axi.hw, + [CLKID_L2_DRAM_SEL] = &meson8b_l2_dram_sel.hw, + [CLKID_L2_DRAM] = &meson8b_l2_dram.hw, [CLKID_HDMI_PLL_LVDS_OUT] = &meson8b_hdmi_pll_lvds_out.hw, [CLKID_HDMI_PLL_HDMI_OUT] = &meson8b_hdmi_pll_hdmi_out.hw, [CLKID_VID_PLL_IN_SEL] = &meson8b_vid_pll_in_sel.hw, @@ -3393,27 +3367,27 @@ static struct clk_hw *meson8m2_hw_clks[] = { [CLKID_VCLK_IN_SEL] = &meson8b_vclk_in_sel.hw, [CLKID_VCLK_IN_EN] = &meson8b_vclk_in_en.hw, [CLKID_VCLK_EN] = &meson8b_vclk_en.hw, - [CLKID_VCLK_DIV1] = &meson8b_vclk_div1_gate.hw, + [CLKID_VCLK_DIV1] = &meson8b_vclk_div1.hw, [CLKID_VCLK_DIV2_DIV] = &meson8b_vclk_div2_div.hw, - [CLKID_VCLK_DIV2] = &meson8b_vclk_div2_div_gate.hw, + [CLKID_VCLK_DIV2] = &meson8b_vclk_div2.hw, [CLKID_VCLK_DIV4_DIV] = &meson8b_vclk_div4_div.hw, - [CLKID_VCLK_DIV4] = &meson8b_vclk_div4_div_gate.hw, + [CLKID_VCLK_DIV4] = &meson8b_vclk_div4.hw, [CLKID_VCLK_DIV6_DIV] = &meson8b_vclk_div6_div.hw, - [CLKID_VCLK_DIV6] = &meson8b_vclk_div6_div_gate.hw, + [CLKID_VCLK_DIV6] = &meson8b_vclk_div6.hw, [CLKID_VCLK_DIV12_DIV] = &meson8b_vclk_div12_div.hw, - [CLKID_VCLK_DIV12] = &meson8b_vclk_div12_div_gate.hw, + [CLKID_VCLK_DIV12] = &meson8b_vclk_div12.hw, [CLKID_VCLK2_IN_SEL] = &meson8b_vclk2_in_sel.hw, - [CLKID_VCLK2_IN_EN] = &meson8b_vclk2_clk_in_en.hw, - [CLKID_VCLK2_EN] = &meson8b_vclk2_clk_en.hw, - [CLKID_VCLK2_DIV1] = &meson8b_vclk2_div1_gate.hw, + [CLKID_VCLK2_IN_EN] = &meson8b_vclk2_in_en.hw, + [CLKID_VCLK2_EN] = &meson8b_vclk2_en.hw, + [CLKID_VCLK2_DIV1] = &meson8b_vclk2_div1.hw, [CLKID_VCLK2_DIV2_DIV] = &meson8b_vclk2_div2_div.hw, - [CLKID_VCLK2_DIV2] = &meson8b_vclk2_div2_div_gate.hw, + [CLKID_VCLK2_DIV2] = &meson8b_vclk2_div2.hw, [CLKID_VCLK2_DIV4_DIV] = &meson8b_vclk2_div4_div.hw, - [CLKID_VCLK2_DIV4] = &meson8b_vclk2_div4_div_gate.hw, + [CLKID_VCLK2_DIV4] = &meson8b_vclk2_div4.hw, [CLKID_VCLK2_DIV6_DIV] = &meson8b_vclk2_div6_div.hw, - [CLKID_VCLK2_DIV6] = &meson8b_vclk2_div6_div_gate.hw, + [CLKID_VCLK2_DIV6] = &meson8b_vclk2_div6.hw, [CLKID_VCLK2_DIV12_DIV] = &meson8b_vclk2_div12_div.hw, - [CLKID_VCLK2_DIV12] = &meson8b_vclk2_div12_div_gate.hw, + [CLKID_VCLK2_DIV12] = &meson8b_vclk2_div12.hw, [CLKID_CTS_ENCT_SEL] = &meson8b_cts_enct_sel.hw, [CLKID_CTS_ENCT] = &meson8b_cts_enct.hw, [CLKID_CTS_ENCP_SEL] = &meson8b_cts_encp_sel.hw, diff --git a/drivers/clk/meson/s4-peripherals.c b/drivers/clk/meson/s4-peripherals.c index c9400cf54c84..6d69b132d1e1 100644 --- a/drivers/clk/meson/s4-peripherals.c +++ b/drivers/clk/meson/s4-peripherals.c @@ -62,6 +62,15 @@ #define CLKCTRL_PWM_CLK_IJ_CTRL 0x190 #define CLKCTRL_DEMOD_CLK_CTRL 0x200 +#define S4_COMP_SEL(_name, _reg, _shift, _mask, _pdata) \ + MESON_COMP_SEL(s4_, _name, _reg, _shift, _mask, _pdata, NULL, 0, 0) + +#define S4_COMP_DIV(_name, _reg, _shift, _width) \ + MESON_COMP_DIV(s4_, _name, _reg, _shift, _width, 0, CLK_SET_RATE_PARENT) + +#define S4_COMP_GATE(_name, _reg, _bit) \ + MESON_COMP_GATE(s4_, _name, _reg, _bit, CLK_SET_RATE_PARENT) + static struct clk_regmap s4_rtc_32k_by_oscin_clkin = { .data = &(struct clk_regmap_gate_data){ .offset = CLKCTRL_RTC_BY_OSCIN_CTRL0, @@ -182,8 +191,8 @@ static struct clk_regmap s4_rtc_clk = { }; /* The index 5 is AXI_CLK, which is dedicated to AXI. So skip it. */ -static u32 mux_table_sys_ab_clk_sel[] = { 0, 1, 2, 3, 4, 6, 7 }; -static const struct clk_parent_data sys_ab_clk_parent_data[] = { +static u32 s4_sysclk_parents_val_table[] = { 0, 1, 2, 3, 4, 6, 7 }; +static const struct clk_parent_data s4_sysclk_parents[] = { { .fw_name = "xtal" }, { .fw_name = "fclk_div2" }, { .fw_name = "fclk_div3" }, @@ -205,13 +214,13 @@ static struct clk_regmap s4_sysclk_b_sel = { .offset = CLKCTRL_SYS_CLK_CTRL0, .mask = 0x7, .shift = 26, - .table = mux_table_sys_ab_clk_sel, + .table = s4_sysclk_parents_val_table, }, .hw.init = &(struct clk_init_data){ .name = "sysclk_b_sel", .ops = &clk_regmap_mux_ro_ops, - .parent_data = sys_ab_clk_parent_data, - .num_parents = ARRAY_SIZE(sys_ab_clk_parent_data), + .parent_data = s4_sysclk_parents, + .num_parents = ARRAY_SIZE(s4_sysclk_parents), }, }; @@ -251,13 +260,13 @@ static struct clk_regmap s4_sysclk_a_sel = { .offset = CLKCTRL_SYS_CLK_CTRL0, .mask = 0x7, .shift = 10, - .table = mux_table_sys_ab_clk_sel, + .table = s4_sysclk_parents_val_table, }, .hw.init = &(struct clk_init_data){ .name = "sysclk_a_sel", .ops = &clk_regmap_mux_ro_ops, - .parent_data = sys_ab_clk_parent_data, - .num_parents = ARRAY_SIZE(sys_ab_clk_parent_data), + .parent_data = s4_sysclk_parents, + .num_parents = ARRAY_SIZE(s4_sysclk_parents), }, }; @@ -523,24 +532,24 @@ static struct clk_regmap s4_cecb_32k_clkout = { }, }; -static const struct clk_parent_data s4_sc_parent_data[] = { +static const struct clk_parent_data s4_sc_clk_parents[] = { { .fw_name = "fclk_div4" }, { .fw_name = "fclk_div3" }, { .fw_name = "fclk_div5" }, { .fw_name = "xtal", } }; -static struct clk_regmap s4_sc_clk_mux = { +static struct clk_regmap s4_sc_clk_sel = { .data = &(struct clk_regmap_mux_data){ .offset = CLKCTRL_SC_CLK_CTRL, .mask = 0x3, .shift = 9, }, .hw.init = &(struct clk_init_data) { - .name = "sc_clk_mux", + .name = "sc_clk_sel", .ops = &clk_regmap_mux_ops, - .parent_data = s4_sc_parent_data, - .num_parents = ARRAY_SIZE(s4_sc_parent_data), + .parent_data = s4_sc_clk_parents, + .num_parents = ARRAY_SIZE(s4_sc_clk_parents), .flags = CLK_SET_RATE_PARENT, }, }; @@ -555,20 +564,20 @@ static struct clk_regmap s4_sc_clk_div = { .name = "sc_clk_div", .ops = &clk_regmap_divider_ops, .parent_hws = (const struct clk_hw *[]) { - &s4_sc_clk_mux.hw + &s4_sc_clk_sel.hw }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, }; -static struct clk_regmap s4_sc_clk_gate = { +static struct clk_regmap s4_sc_clk = { .data = &(struct clk_regmap_gate_data){ .offset = CLKCTRL_SC_CLK_CTRL, .bit_idx = 8, }, .hw.init = &(struct clk_init_data){ - .name = "sc_clk_gate", + .name = "sc_clk", .ops = &clk_regmap_gate_ops, .parent_hws = (const struct clk_hw *[]) { &s4_sc_clk_div.hw @@ -578,13 +587,13 @@ static struct clk_regmap s4_sc_clk_gate = { }, }; -static struct clk_regmap s4_12_24M_clk_gate = { +static struct clk_regmap s4_12_24M = { .data = &(struct clk_regmap_gate_data){ .offset = CLKCTRL_CLK12_24_CTRL, .bit_idx = 11, }, .hw.init = &(struct clk_init_data) { - .name = "12_24m_gate", + .name = "12_24M", .ops = &clk_regmap_gate_ops, .parent_data = (const struct clk_parent_data []) { { .fw_name = "xtal", } @@ -593,32 +602,32 @@ static struct clk_regmap s4_12_24M_clk_gate = { }, }; -static struct clk_fixed_factor s4_12M_clk_div = { +static struct clk_fixed_factor s4_12M_div = { .mult = 1, .div = 2, .hw.init = &(struct clk_init_data){ - .name = "12M", + .name = "12M_div", .ops = &clk_fixed_factor_ops, .parent_hws = (const struct clk_hw *[]) { - &s4_12_24M_clk_gate.hw + &s4_12_24M.hw }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, }; -static struct clk_regmap s4_12_24M_clk = { +static struct clk_regmap s4_12_24M_sel = { .data = &(struct clk_regmap_mux_data){ .offset = CLKCTRL_CLK12_24_CTRL, .mask = 0x1, .shift = 10, }, .hw.init = &(struct clk_init_data) { - .name = "12_24m", + .name = "12_24M_sel", .ops = &clk_regmap_mux_ops, .parent_hws = (const struct clk_hw *[]) { - &s4_12_24M_clk_gate.hw, - &s4_12M_clk_div.hw, + &s4_12_24M.hw, + &s4_12M_div.hw, }, .num_parents = 2, .flags = CLK_SET_RATE_PARENT, @@ -687,7 +696,7 @@ static struct clk_regmap s4_vid_pll = { }, }; -static const struct clk_parent_data s4_vclk_parent_data[] = { +static const struct clk_parent_data s4_vclk_parents[] = { { .hw = &s4_vid_pll.hw }, { .fw_name = "gp0_pll", }, { .fw_name = "hifi_pll", }, @@ -707,8 +716,8 @@ static struct clk_regmap s4_vclk_sel = { .hw.init = &(struct clk_init_data){ .name = "vclk_sel", .ops = &clk_regmap_mux_ops, - .parent_data = s4_vclk_parent_data, - .num_parents = ARRAY_SIZE(s4_vclk_parent_data), + .parent_data = s4_vclk_parents, + .num_parents = ARRAY_SIZE(s4_vclk_parents), .flags = 0, }, }; @@ -722,8 +731,8 @@ static struct clk_regmap s4_vclk2_sel = { .hw.init = &(struct clk_init_data){ .name = "vclk2_sel", .ops = &clk_regmap_mux_ops, - .parent_data = s4_vclk_parent_data, - .num_parents = ARRAY_SIZE(s4_vclk_parent_data), + .parent_data = s4_vclk_parents, + .num_parents = ARRAY_SIZE(s4_vclk_parents), .flags = 0, }, }; @@ -1071,8 +1080,8 @@ static struct clk_fixed_factor s4_vclk2_div12 = { }; /* The 5,6,7 indexes corresponds to no real clock, so there are not used. */ -static u32 mux_table_cts_sel[] = { 0, 1, 2, 3, 4, 8, 9, 10, 11, 12 }; -static const struct clk_hw *s4_cts_parent_hws[] = { +static u32 s4_cts_parents_val_table[] = { 0, 1, 2, 3, 4, 8, 9, 10, 11, 12 }; +static const struct clk_hw *s4_cts_parents[] = { &s4_vclk_div1.hw, &s4_vclk_div2.hw, &s4_vclk_div4.hw, @@ -1090,13 +1099,13 @@ static struct clk_regmap s4_cts_enci_sel = { .offset = CLKCTRL_VID_CLK_DIV, .mask = 0xf, .shift = 28, - .table = mux_table_cts_sel, + .table = s4_cts_parents_val_table, }, .hw.init = &(struct clk_init_data){ .name = "cts_enci_sel", .ops = &clk_regmap_mux_ops, - .parent_hws = s4_cts_parent_hws, - .num_parents = ARRAY_SIZE(s4_cts_parent_hws), + .parent_hws = s4_cts_parents, + .num_parents = ARRAY_SIZE(s4_cts_parents), .flags = CLK_SET_RATE_PARENT, }, }; @@ -1106,13 +1115,13 @@ static struct clk_regmap s4_cts_encp_sel = { .offset = CLKCTRL_VID_CLK_DIV, .mask = 0xf, .shift = 20, - .table = mux_table_cts_sel, + .table = s4_cts_parents_val_table, }, .hw.init = &(struct clk_init_data){ .name = "cts_encp_sel", .ops = &clk_regmap_mux_ops, - .parent_hws = s4_cts_parent_hws, - .num_parents = ARRAY_SIZE(s4_cts_parent_hws), + .parent_hws = s4_cts_parents, + .num_parents = ARRAY_SIZE(s4_cts_parents), .flags = CLK_SET_RATE_PARENT, }, }; @@ -1122,20 +1131,20 @@ static struct clk_regmap s4_cts_vdac_sel = { .offset = CLKCTRL_VIID_CLK_DIV, .mask = 0xf, .shift = 28, - .table = mux_table_cts_sel, + .table = s4_cts_parents_val_table, }, .hw.init = &(struct clk_init_data){ .name = "cts_vdac_sel", .ops = &clk_regmap_mux_ops, - .parent_hws = s4_cts_parent_hws, - .num_parents = ARRAY_SIZE(s4_cts_parent_hws), + .parent_hws = s4_cts_parents, + .num_parents = ARRAY_SIZE(s4_cts_parents), .flags = CLK_SET_RATE_PARENT, }, }; /* The 5,6,7 indexes corresponds to no real clock, so there are not used. */ -static u32 mux_table_hdmi_tx_sel[] = { 0, 1, 2, 3, 4, 8, 9, 10, 11, 12 }; -static const struct clk_hw *s4_cts_hdmi_tx_parent_hws[] = { +static u32 s4_hdmi_tx_parents_val_table[] = { 0, 1, 2, 3, 4, 8, 9, 10, 11, 12 }; +static const struct clk_hw *s4_hdmi_tx_parents[] = { &s4_vclk_div1.hw, &s4_vclk_div2.hw, &s4_vclk_div4.hw, @@ -1153,13 +1162,13 @@ static struct clk_regmap s4_hdmi_tx_sel = { .offset = CLKCTRL_HDMI_CLK_CTRL, .mask = 0xf, .shift = 16, - .table = mux_table_hdmi_tx_sel, + .table = s4_hdmi_tx_parents_val_table, }, .hw.init = &(struct clk_init_data){ .name = "hdmi_tx_sel", .ops = &clk_regmap_mux_ops, - .parent_hws = s4_cts_hdmi_tx_parent_hws, - .num_parents = ARRAY_SIZE(s4_cts_hdmi_tx_parent_hws), + .parent_hws = s4_hdmi_tx_parents, + .num_parents = ARRAY_SIZE(s4_hdmi_tx_parents), .flags = CLK_SET_RATE_PARENT, }, }; @@ -1229,7 +1238,7 @@ static struct clk_regmap s4_hdmi_tx = { }; /* HDMI Clocks */ -static const struct clk_parent_data s4_hdmi_parent_data[] = { +static const struct clk_parent_data s4_hdmi_parents[] = { { .fw_name = "xtal", }, { .fw_name = "fclk_div4", }, { .fw_name = "fclk_div3", }, @@ -1246,8 +1255,8 @@ static struct clk_regmap s4_hdmi_sel = { .hw.init = &(struct clk_init_data){ .name = "hdmi_sel", .ops = &clk_regmap_mux_ops, - .parent_data = s4_hdmi_parent_data, - .num_parents = ARRAY_SIZE(s4_hdmi_parent_data), + .parent_data = s4_hdmi_parents, + .num_parents = ARRAY_SIZE(s4_hdmi_parents), .flags = CLK_SET_RATE_PARENT, }, }; @@ -1298,7 +1307,7 @@ static struct clk_regmap s4_ts_clk_div = { }, }; -static struct clk_regmap s4_ts_clk_gate = { +static struct clk_regmap s4_ts_clk = { .data = &(struct clk_regmap_gate_data){ .offset = CLKCTRL_TS_CLK_CTRL, .bit_idx = 8, @@ -1320,7 +1329,7 @@ static struct clk_regmap s4_ts_clk_gate = { * mux because it does top-to-bottom updates the each clock tree and * switches to the "inactive" one when CLK_SET_RATE_GATE is set. */ -static const struct clk_parent_data s4_mali_0_1_parent_data[] = { +static const struct clk_parent_data s4_mali_parents[] = { { .fw_name = "xtal", }, { .fw_name = "gp0_pll", }, { .fw_name = "hifi_pll", }, @@ -1340,8 +1349,8 @@ static struct clk_regmap s4_mali_0_sel = { .hw.init = &(struct clk_init_data){ .name = "mali_0_sel", .ops = &clk_regmap_mux_ops, - .parent_data = s4_mali_0_1_parent_data, - .num_parents = ARRAY_SIZE(s4_mali_0_1_parent_data), + .parent_data = s4_mali_parents, + .num_parents = ARRAY_SIZE(s4_mali_parents), /* * Don't request the parent to change the rate because * all GPU frequencies can be derived from the fclk_* @@ -1394,8 +1403,8 @@ static struct clk_regmap s4_mali_1_sel = { .hw.init = &(struct clk_init_data){ .name = "mali_1_sel", .ops = &clk_regmap_mux_ops, - .parent_data = s4_mali_0_1_parent_data, - .num_parents = ARRAY_SIZE(s4_mali_0_1_parent_data), + .parent_data = s4_mali_parents, + .num_parents = ARRAY_SIZE(s4_mali_parents), .flags = 0, }, }; @@ -1433,28 +1442,26 @@ static struct clk_regmap s4_mali_1 = { }, }; -static const struct clk_hw *s4_mali_parent_hws[] = { - &s4_mali_0.hw, - &s4_mali_1.hw -}; - -static struct clk_regmap s4_mali_mux = { +static struct clk_regmap s4_mali_sel = { .data = &(struct clk_regmap_mux_data){ .offset = CLKCTRL_MALI_CLK_CTRL, .mask = 1, .shift = 31, }, .hw.init = &(struct clk_init_data){ - .name = "mali", + .name = "mali_sel", .ops = &clk_regmap_mux_ops, - .parent_hws = s4_mali_parent_hws, + .parent_hws = (const struct clk_hw *[]) { + &s4_mali_0.hw, + &s4_mali_1.hw, + }, .num_parents = 2, .flags = CLK_SET_RATE_PARENT, }, }; /* VDEC clocks */ -static const struct clk_parent_data s4_dec_parent_data[] = { +static const struct clk_parent_data s4_dec_parents[] = { { .fw_name = "fclk_div2p5", }, { .fw_name = "fclk_div3", }, { .fw_name = "fclk_div4", }, @@ -1465,7 +1472,7 @@ static const struct clk_parent_data s4_dec_parent_data[] = { { .fw_name = "xtal", } }; -static struct clk_regmap s4_vdec_p0_mux = { +static struct clk_regmap s4_vdec_p0_sel = { .data = &(struct clk_regmap_mux_data){ .offset = CLKCTRL_VDEC_CLK_CTRL, .mask = 0x7, @@ -1473,10 +1480,10 @@ static struct clk_regmap s4_vdec_p0_mux = { .flags = CLK_MUX_ROUND_CLOSEST, }, .hw.init = &(struct clk_init_data) { - .name = "vdec_p0_mux", + .name = "vdec_p0_sel", .ops = &clk_regmap_mux_ops, - .parent_data = s4_dec_parent_data, - .num_parents = ARRAY_SIZE(s4_dec_parent_data), + .parent_data = s4_dec_parents, + .num_parents = ARRAY_SIZE(s4_dec_parents), .flags = 0, }, }; @@ -1492,7 +1499,7 @@ static struct clk_regmap s4_vdec_p0_div = { .name = "vdec_p0_div", .ops = &clk_regmap_divider_ops, .parent_hws = (const struct clk_hw *[]) { - &s4_vdec_p0_mux.hw + &s4_vdec_p0_sel.hw }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, @@ -1515,7 +1522,7 @@ static struct clk_regmap s4_vdec_p0 = { }, }; -static struct clk_regmap s4_vdec_p1_mux = { +static struct clk_regmap s4_vdec_p1_sel = { .data = &(struct clk_regmap_mux_data){ .offset = CLKCTRL_VDEC3_CLK_CTRL, .mask = 0x7, @@ -1523,10 +1530,10 @@ static struct clk_regmap s4_vdec_p1_mux = { .flags = CLK_MUX_ROUND_CLOSEST, }, .hw.init = &(struct clk_init_data) { - .name = "vdec_p1_mux", + .name = "vdec_p1_sel", .ops = &clk_regmap_mux_ops, - .parent_data = s4_dec_parent_data, - .num_parents = ARRAY_SIZE(s4_dec_parent_data), + .parent_data = s4_dec_parents, + .num_parents = ARRAY_SIZE(s4_dec_parents), .flags = 0, }, }; @@ -1542,7 +1549,7 @@ static struct clk_regmap s4_vdec_p1_div = { .name = "vdec_p1_div", .ops = &clk_regmap_divider_ops, .parent_hws = (const struct clk_hw *[]) { - &s4_vdec_p1_mux.hw + &s4_vdec_p1_sel.hw }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, @@ -1565,27 +1572,25 @@ static struct clk_regmap s4_vdec_p1 = { }, }; -static const struct clk_hw *s4_vdec_mux_parent_hws[] = { - &s4_vdec_p0.hw, - &s4_vdec_p1.hw -}; - -static struct clk_regmap s4_vdec_mux = { +static struct clk_regmap s4_vdec_sel = { .data = &(struct clk_regmap_mux_data){ .offset = CLKCTRL_VDEC3_CLK_CTRL, .mask = 0x1, .shift = 15, }, .hw.init = &(struct clk_init_data) { - .name = "vdec_mux", + .name = "vdec_sel", .ops = &clk_regmap_mux_ops, - .parent_hws = s4_vdec_mux_parent_hws, - .num_parents = ARRAY_SIZE(s4_vdec_mux_parent_hws), + .parent_hws = (const struct clk_hw *[]) { + &s4_vdec_p0.hw, + &s4_vdec_p1.hw, + }, + .num_parents = 2, .flags = CLK_SET_RATE_PARENT, }, }; -static struct clk_regmap s4_hevcf_p0_mux = { +static struct clk_regmap s4_hevcf_p0_sel = { .data = &(struct clk_regmap_mux_data){ .offset = CLKCTRL_VDEC2_CLK_CTRL, .mask = 0x7, @@ -1593,10 +1598,10 @@ static struct clk_regmap s4_hevcf_p0_mux = { .flags = CLK_MUX_ROUND_CLOSEST, }, .hw.init = &(struct clk_init_data) { - .name = "hevcf_p0_mux", + .name = "hevcf_p0_sel", .ops = &clk_regmap_mux_ops, - .parent_data = s4_dec_parent_data, - .num_parents = ARRAY_SIZE(s4_dec_parent_data), + .parent_data = s4_dec_parents, + .num_parents = ARRAY_SIZE(s4_dec_parents), .flags = 0, }, }; @@ -1612,7 +1617,7 @@ static struct clk_regmap s4_hevcf_p0_div = { .name = "hevcf_p0_div", .ops = &clk_regmap_divider_ops, .parent_hws = (const struct clk_hw *[]) { - &s4_hevcf_p0_mux.hw + &s4_hevcf_p0_sel.hw }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, @@ -1625,7 +1630,7 @@ static struct clk_regmap s4_hevcf_p0 = { .bit_idx = 8, }, .hw.init = &(struct clk_init_data){ - .name = "hevcf_p0_gate", + .name = "hevcf_p0", .ops = &clk_regmap_gate_ops, .parent_hws = (const struct clk_hw *[]) { &s4_hevcf_p0_div.hw @@ -1635,7 +1640,7 @@ static struct clk_regmap s4_hevcf_p0 = { }, }; -static struct clk_regmap s4_hevcf_p1_mux = { +static struct clk_regmap s4_hevcf_p1_sel = { .data = &(struct clk_regmap_mux_data){ .offset = CLKCTRL_VDEC4_CLK_CTRL, .mask = 0x7, @@ -1643,10 +1648,10 @@ static struct clk_regmap s4_hevcf_p1_mux = { .flags = CLK_MUX_ROUND_CLOSEST, }, .hw.init = &(struct clk_init_data) { - .name = "hevcf_p1_mux", + .name = "hevcf_p1_sel", .ops = &clk_regmap_mux_ops, - .parent_data = s4_dec_parent_data, - .num_parents = ARRAY_SIZE(s4_dec_parent_data), + .parent_data = s4_dec_parents, + .num_parents = ARRAY_SIZE(s4_dec_parents), .flags = 0, }, }; @@ -1662,7 +1667,7 @@ static struct clk_regmap s4_hevcf_p1_div = { .name = "hevcf_p1_div", .ops = &clk_regmap_divider_ops, .parent_hws = (const struct clk_hw *[]) { - &s4_hevcf_p1_mux.hw + &s4_hevcf_p1_sel.hw }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, @@ -1685,28 +1690,26 @@ static struct clk_regmap s4_hevcf_p1 = { }, }; -static const struct clk_hw *s4_hevcf_mux_parent_hws[] = { - &s4_hevcf_p0.hw, - &s4_hevcf_p1.hw -}; - -static struct clk_regmap s4_hevcf_mux = { +static struct clk_regmap s4_hevcf_sel = { .data = &(struct clk_regmap_mux_data){ .offset = CLKCTRL_VDEC4_CLK_CTRL, .mask = 0x1, .shift = 15, }, .hw.init = &(struct clk_init_data) { - .name = "hevcf", + .name = "hevcf_sel", .ops = &clk_regmap_mux_ops, - .parent_hws = s4_hevcf_mux_parent_hws, - .num_parents = ARRAY_SIZE(s4_hevcf_mux_parent_hws), + .parent_hws = (const struct clk_hw *[]) { + &s4_hevcf_p0.hw, + &s4_hevcf_p1.hw, + }, + .num_parents = 2, .flags = CLK_SET_RATE_PARENT, }, }; /* VPU Clock */ -static const struct clk_parent_data s4_vpu_parent_data[] = { +static const struct clk_parent_data s4_vpu_parents[] = { { .fw_name = "fclk_div3", }, { .fw_name = "fclk_div4", }, { .fw_name = "fclk_div5", }, @@ -1726,8 +1729,8 @@ static struct clk_regmap s4_vpu_0_sel = { .hw.init = &(struct clk_init_data){ .name = "vpu_0_sel", .ops = &clk_regmap_mux_ops, - .parent_data = s4_vpu_parent_data, - .num_parents = ARRAY_SIZE(s4_vpu_parent_data), + .parent_data = s4_vpu_parents, + .num_parents = ARRAY_SIZE(s4_vpu_parents), .flags = 0, }, }; @@ -1770,8 +1773,8 @@ static struct clk_regmap s4_vpu_1_sel = { .hw.init = &(struct clk_init_data){ .name = "vpu_1_sel", .ops = &clk_regmap_mux_ops, - .parent_data = s4_vpu_parent_data, - .num_parents = ARRAY_SIZE(s4_vpu_parent_data), + .parent_data = s4_vpu_parents, + .num_parents = ARRAY_SIZE(s4_vpu_parents), .flags = 0, }, }; @@ -1823,24 +1826,24 @@ static struct clk_regmap s4_vpu = { }, }; -static const struct clk_parent_data vpu_clkb_tmp_parent_data[] = { +static const struct clk_parent_data vpu_clkb_tmp_parents[] = { { .hw = &s4_vpu.hw }, { .fw_name = "fclk_div4", }, { .fw_name = "fclk_div5", }, { .fw_name = "fclk_div7", } }; -static struct clk_regmap s4_vpu_clkb_tmp_mux = { +static struct clk_regmap s4_vpu_clkb_tmp_sel = { .data = &(struct clk_regmap_mux_data){ .offset = CLKCTRL_VPU_CLKB_CTRL, .mask = 0x3, .shift = 20, }, .hw.init = &(struct clk_init_data) { - .name = "vpu_clkb_tmp_mux", + .name = "vpu_clkb_tmp_sel", .ops = &clk_regmap_mux_ops, - .parent_data = vpu_clkb_tmp_parent_data, - .num_parents = ARRAY_SIZE(vpu_clkb_tmp_parent_data), + .parent_data = vpu_clkb_tmp_parents, + .num_parents = ARRAY_SIZE(vpu_clkb_tmp_parents), .flags = CLK_SET_RATE_PARENT, }, }; @@ -1855,7 +1858,7 @@ static struct clk_regmap s4_vpu_clkb_tmp_div = { .name = "vpu_clkb_tmp_div", .ops = &clk_regmap_divider_ops, .parent_hws = (const struct clk_hw *[]) { - &s4_vpu_clkb_tmp_mux.hw + &s4_vpu_clkb_tmp_sel.hw }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, @@ -1911,7 +1914,7 @@ static struct clk_regmap s4_vpu_clkb = { }, }; -static const struct clk_parent_data s4_vpu_clkc_parent_data[] = { +static const struct clk_parent_data s4_vpu_clkc_parents[] = { { .fw_name = "fclk_div4", }, { .fw_name = "fclk_div3", }, { .fw_name = "fclk_div5", }, @@ -1922,17 +1925,17 @@ static const struct clk_parent_data s4_vpu_clkc_parent_data[] = { { .fw_name = "gp0_pll", }, }; -static struct clk_regmap s4_vpu_clkc_p0_mux = { +static struct clk_regmap s4_vpu_clkc_p0_sel = { .data = &(struct clk_regmap_mux_data){ .offset = CLKCTRL_VPU_CLKC_CTRL, .mask = 0x7, .shift = 9, }, .hw.init = &(struct clk_init_data) { - .name = "vpu_clkc_p0_mux", + .name = "vpu_clkc_p0_sel", .ops = &clk_regmap_mux_ops, - .parent_data = s4_vpu_clkc_parent_data, - .num_parents = ARRAY_SIZE(s4_vpu_clkc_parent_data), + .parent_data = s4_vpu_clkc_parents, + .num_parents = ARRAY_SIZE(s4_vpu_clkc_parents), .flags = 0, }, }; @@ -1947,7 +1950,7 @@ static struct clk_regmap s4_vpu_clkc_p0_div = { .name = "vpu_clkc_p0_div", .ops = &clk_regmap_divider_ops, .parent_hws = (const struct clk_hw *[]) { - &s4_vpu_clkc_p0_mux.hw + &s4_vpu_clkc_p0_sel.hw }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, @@ -1970,17 +1973,17 @@ static struct clk_regmap s4_vpu_clkc_p0 = { }, }; -static struct clk_regmap s4_vpu_clkc_p1_mux = { +static struct clk_regmap s4_vpu_clkc_p1_sel = { .data = &(struct clk_regmap_mux_data){ .offset = CLKCTRL_VPU_CLKC_CTRL, .mask = 0x7, .shift = 25, }, .hw.init = &(struct clk_init_data) { - .name = "vpu_clkc_p1_mux", + .name = "vpu_clkc_p1_sel", .ops = &clk_regmap_mux_ops, - .parent_data = s4_vpu_clkc_parent_data, - .num_parents = ARRAY_SIZE(s4_vpu_clkc_parent_data), + .parent_data = s4_vpu_clkc_parents, + .num_parents = ARRAY_SIZE(s4_vpu_clkc_parents), .flags = 0, }, }; @@ -1995,7 +1998,7 @@ static struct clk_regmap s4_vpu_clkc_p1_div = { .name = "vpu_clkc_p1_div", .ops = &clk_regmap_divider_ops, .parent_hws = (const struct clk_hw *[]) { - &s4_vpu_clkc_p1_mux.hw + &s4_vpu_clkc_p1_sel.hw }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, @@ -2018,28 +2021,26 @@ static struct clk_regmap s4_vpu_clkc_p1 = { }, }; -static const struct clk_hw *s4_vpu_mux_parent_hws[] = { - &s4_vpu_clkc_p0.hw, - &s4_vpu_clkc_p1.hw -}; - -static struct clk_regmap s4_vpu_clkc_mux = { +static struct clk_regmap s4_vpu_clkc_sel = { .data = &(struct clk_regmap_mux_data){ .offset = CLKCTRL_VPU_CLKC_CTRL, .mask = 0x1, .shift = 31, }, .hw.init = &(struct clk_init_data) { - .name = "vpu_clkc_mux", + .name = "vpu_clkc_sel", .ops = &clk_regmap_mux_ops, - .parent_hws = s4_vpu_mux_parent_hws, - .num_parents = ARRAY_SIZE(s4_vpu_mux_parent_hws), + .parent_hws = (const struct clk_hw *[]) { + &s4_vpu_clkc_p0.hw, + &s4_vpu_clkc_p1.hw, + }, + .num_parents = 2, .flags = CLK_SET_RATE_PARENT, }, }; /* VAPB Clock */ -static const struct clk_parent_data s4_vapb_parent_data[] = { +static const struct clk_parent_data s4_vapb_parents[] = { { .fw_name = "fclk_div4", }, { .fw_name = "fclk_div3", }, { .fw_name = "fclk_div5", }, @@ -2059,8 +2060,8 @@ static struct clk_regmap s4_vapb_0_sel = { .hw.init = &(struct clk_init_data){ .name = "vapb_0_sel", .ops = &clk_regmap_mux_ops, - .parent_data = s4_vapb_parent_data, - .num_parents = ARRAY_SIZE(s4_vapb_parent_data), + .parent_data = s4_vapb_parents, + .num_parents = ARRAY_SIZE(s4_vapb_parents), .flags = 0, }, }; @@ -2107,8 +2108,8 @@ static struct clk_regmap s4_vapb_1_sel = { .hw.init = &(struct clk_init_data){ .name = "vapb_1_sel", .ops = &clk_regmap_mux_ops, - .parent_data = s4_vapb_parent_data, - .num_parents = ARRAY_SIZE(s4_vapb_parent_data), + .parent_data = s4_vapb_parents, + .num_parents = ARRAY_SIZE(s4_vapb_parents), .flags = 0, }, }; @@ -2164,13 +2165,13 @@ static struct clk_regmap s4_vapb = { }, }; -static struct clk_regmap s4_ge2d_gate = { +static struct clk_regmap s4_ge2d = { .data = &(struct clk_regmap_gate_data){ .offset = CLKCTRL_VAPBCLK_CTRL, .bit_idx = 30, }, .hw.init = &(struct clk_init_data) { - .name = "ge2d_clk", + .name = "ge2d", .ops = &clk_regmap_gate_ops, .parent_hws = (const struct clk_hw *[]) { &s4_vapb.hw }, .num_parents = 1, @@ -2178,24 +2179,24 @@ static struct clk_regmap s4_ge2d_gate = { }, }; -static const struct clk_parent_data s4_esmclk_parent_data[] = { +static const struct clk_parent_data s4_hdcp22_esmclk_parents[] = { { .fw_name = "fclk_div7", }, { .fw_name = "fclk_div4", }, { .fw_name = "fclk_div3", }, { .fw_name = "fclk_div5", }, }; -static struct clk_regmap s4_hdcp22_esmclk_mux = { +static struct clk_regmap s4_hdcp22_esmclk_sel = { .data = &(struct clk_regmap_mux_data){ .offset = CLKCTRL_HDCP22_CTRL, .mask = 0x3, .shift = 9, }, .hw.init = &(struct clk_init_data) { - .name = "hdcp22_esmclk_mux", + .name = "hdcp22_esmclk_sel", .ops = &clk_regmap_mux_ops, - .parent_data = s4_esmclk_parent_data, - .num_parents = ARRAY_SIZE(s4_esmclk_parent_data), + .parent_data = s4_hdcp22_esmclk_parents, + .num_parents = ARRAY_SIZE(s4_hdcp22_esmclk_parents), .flags = CLK_SET_RATE_PARENT, }, }; @@ -2210,20 +2211,20 @@ static struct clk_regmap s4_hdcp22_esmclk_div = { .name = "hdcp22_esmclk_div", .ops = &clk_regmap_divider_ops, .parent_hws = (const struct clk_hw *[]) { - &s4_hdcp22_esmclk_mux.hw + &s4_hdcp22_esmclk_sel.hw }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, }; -static struct clk_regmap s4_hdcp22_esmclk_gate = { +static struct clk_regmap s4_hdcp22_esmclk = { .data = &(struct clk_regmap_gate_data){ .offset = CLKCTRL_HDCP22_CTRL, .bit_idx = 8, }, .hw.init = &(struct clk_init_data){ - .name = "hdcp22_esmclk_gate", + .name = "hdcp22_esmclk", .ops = &clk_regmap_gate_ops, .parent_hws = (const struct clk_hw *[]) { &s4_hdcp22_esmclk_div.hw @@ -2233,24 +2234,24 @@ static struct clk_regmap s4_hdcp22_esmclk_gate = { }, }; -static const struct clk_parent_data s4_skpclk_parent_data[] = { +static const struct clk_parent_data s4_hdcp22_skpclk_parents[] = { { .fw_name = "xtal", }, { .fw_name = "fclk_div4", }, { .fw_name = "fclk_div3", }, { .fw_name = "fclk_div5", }, }; -static struct clk_regmap s4_hdcp22_skpclk_mux = { +static struct clk_regmap s4_hdcp22_skpclk_sel = { .data = &(struct clk_regmap_mux_data){ .offset = CLKCTRL_HDCP22_CTRL, .mask = 0x3, .shift = 25, }, .hw.init = &(struct clk_init_data) { - .name = "hdcp22_skpclk_mux", + .name = "hdcp22_skpclk_sel", .ops = &clk_regmap_mux_ops, - .parent_data = s4_skpclk_parent_data, - .num_parents = ARRAY_SIZE(s4_skpclk_parent_data), + .parent_data = s4_hdcp22_skpclk_parents, + .num_parents = ARRAY_SIZE(s4_hdcp22_skpclk_parents), .flags = CLK_SET_RATE_PARENT, }, }; @@ -2265,20 +2266,20 @@ static struct clk_regmap s4_hdcp22_skpclk_div = { .name = "hdcp22_skpclk_div", .ops = &clk_regmap_divider_ops, .parent_hws = (const struct clk_hw *[]) { - &s4_hdcp22_skpclk_mux.hw + &s4_hdcp22_skpclk_sel.hw }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, }; -static struct clk_regmap s4_hdcp22_skpclk_gate = { +static struct clk_regmap s4_hdcp22_skpclk = { .data = &(struct clk_regmap_gate_data){ .offset = CLKCTRL_HDCP22_CTRL, .bit_idx = 24, }, .hw.init = &(struct clk_init_data){ - .name = "hdcp22_skpclk_gate", + .name = "hdcp22_skpclk", .ops = &clk_regmap_gate_ops, .parent_hws = (const struct clk_hw *[]) { &s4_hdcp22_skpclk_div.hw @@ -2288,7 +2289,7 @@ static struct clk_regmap s4_hdcp22_skpclk_gate = { }, }; -static const struct clk_parent_data s4_vdin_parent_data[] = { +static const struct clk_parent_data s4_vdin_parents[] = { { .fw_name = "xtal", }, { .fw_name = "fclk_div4", }, { .fw_name = "fclk_div3", }, @@ -2296,17 +2297,17 @@ static const struct clk_parent_data s4_vdin_parent_data[] = { { .hw = &s4_vid_pll.hw } }; -static struct clk_regmap s4_vdin_meas_mux = { +static struct clk_regmap s4_vdin_meas_sel = { .data = &(struct clk_regmap_mux_data){ .offset = CLKCTRL_VDIN_MEAS_CLK_CTRL, .mask = 0x7, .shift = 9, }, .hw.init = &(struct clk_init_data) { - .name = "vdin_meas_mux", + .name = "vdin_meas_sel", .ops = &clk_regmap_mux_ops, - .parent_data = s4_vdin_parent_data, - .num_parents = ARRAY_SIZE(s4_vdin_parent_data), + .parent_data = s4_vdin_parents, + .num_parents = ARRAY_SIZE(s4_vdin_parents), .flags = CLK_SET_RATE_PARENT, }, }; @@ -2321,20 +2322,20 @@ static struct clk_regmap s4_vdin_meas_div = { .name = "vdin_meas_div", .ops = &clk_regmap_divider_ops, .parent_hws = (const struct clk_hw *[]) { - &s4_vdin_meas_mux.hw + &s4_vdin_meas_sel.hw }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, }; -static struct clk_regmap s4_vdin_meas_gate = { +static struct clk_regmap s4_vdin_meas = { .data = &(struct clk_regmap_gate_data){ .offset = CLKCTRL_VDIN_MEAS_CLK_CTRL, .bit_idx = 8, }, .hw.init = &(struct clk_init_data){ - .name = "vdin_meas_gate", + .name = "vdin_meas", .ops = &clk_regmap_gate_ops, .parent_hws = (const struct clk_hw *[]) { &s4_vdin_meas_div.hw @@ -2345,7 +2346,7 @@ static struct clk_regmap s4_vdin_meas_gate = { }; /* EMMC/NAND clock */ -static const struct clk_parent_data s4_sd_emmc_clk0_parent_data[] = { +static const struct clk_parent_data s4_sd_emmc_clk0_parents[] = { { .fw_name = "xtal", }, { .fw_name = "fclk_div2", }, { .fw_name = "fclk_div3", }, @@ -2365,8 +2366,8 @@ static struct clk_regmap s4_sd_emmc_c_clk0_sel = { .hw.init = &(struct clk_init_data) { .name = "sd_emmc_c_clk0_sel", .ops = &clk_regmap_mux_ops, - .parent_data = s4_sd_emmc_clk0_parent_data, - .num_parents = ARRAY_SIZE(s4_sd_emmc_clk0_parent_data), + .parent_data = s4_sd_emmc_clk0_parents, + .num_parents = ARRAY_SIZE(s4_sd_emmc_clk0_parents), .flags = 0, }, }; @@ -2413,8 +2414,8 @@ static struct clk_regmap s4_sd_emmc_a_clk0_sel = { .hw.init = &(struct clk_init_data) { .name = "sd_emmc_a_clk0_sel", .ops = &clk_regmap_mux_ops, - .parent_data = s4_sd_emmc_clk0_parent_data, - .num_parents = ARRAY_SIZE(s4_sd_emmc_clk0_parent_data), + .parent_data = s4_sd_emmc_clk0_parents, + .num_parents = ARRAY_SIZE(s4_sd_emmc_clk0_parents), .flags = 0, }, }; @@ -2461,8 +2462,8 @@ static struct clk_regmap s4_sd_emmc_b_clk0_sel = { .hw.init = &(struct clk_init_data) { .name = "sd_emmc_b_clk0_sel", .ops = &clk_regmap_mux_ops, - .parent_data = s4_sd_emmc_clk0_parent_data, - .num_parents = ARRAY_SIZE(s4_sd_emmc_clk0_parent_data), + .parent_data = s4_sd_emmc_clk0_parents, + .num_parents = ARRAY_SIZE(s4_sd_emmc_clk0_parents), .flags = 0, }, }; @@ -2501,7 +2502,7 @@ static struct clk_regmap s4_sd_emmc_b_clk0 = { }; /* SPICC Clock */ -static const struct clk_parent_data s4_spicc_parent_data[] = { +static const struct clk_parent_data s4_spicc_parents[] = { { .fw_name = "xtal", }, { .hw = &s4_sys_clk.hw }, { .fw_name = "fclk_div4", }, @@ -2511,17 +2512,17 @@ static const struct clk_parent_data s4_spicc_parent_data[] = { { .fw_name = "fclk_div7", }, }; -static struct clk_regmap s4_spicc0_mux = { +static struct clk_regmap s4_spicc0_sel = { .data = &(struct clk_regmap_mux_data){ .offset = CLKCTRL_SPICC_CLK_CTRL, .mask = 0x7, .shift = 7, }, .hw.init = &(struct clk_init_data) { - .name = "spicc0_mux", + .name = "spicc0_sel", .ops = &clk_regmap_mux_ops, - .parent_data = s4_spicc_parent_data, - .num_parents = ARRAY_SIZE(s4_spicc_parent_data), + .parent_data = s4_spicc_parents, + .num_parents = ARRAY_SIZE(s4_spicc_parents), .flags = CLK_SET_RATE_PARENT, }, }; @@ -2536,20 +2537,20 @@ static struct clk_regmap s4_spicc0_div = { .name = "spicc0_div", .ops = &clk_regmap_divider_ops, .parent_hws = (const struct clk_hw *[]) { - &s4_spicc0_mux.hw + &s4_spicc0_sel.hw }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, }; -static struct clk_regmap s4_spicc0_gate = { +static struct clk_regmap s4_spicc0_en = { .data = &(struct clk_regmap_gate_data){ .offset = CLKCTRL_SPICC_CLK_CTRL, .bit_idx = 6, }, .hw.init = &(struct clk_init_data){ - .name = "spicc0", + .name = "spicc0_en", .ops = &clk_regmap_gate_ops, .parent_hws = (const struct clk_hw *[]) { &s4_spicc0_div.hw @@ -2560,500 +2561,61 @@ static struct clk_regmap s4_spicc0_gate = { }; /* PWM Clock */ -static const struct clk_parent_data s4_pwm_parent_data[] = { +static const struct clk_parent_data s4_pwm_parents[] = { { .fw_name = "xtal", }, { .hw = &s4_vid_pll.hw }, { .fw_name = "fclk_div4", }, { .fw_name = "fclk_div3", }, }; -static struct clk_regmap s4_pwm_a_mux = { - .data = &(struct clk_regmap_mux_data) { - .offset = CLKCTRL_PWM_CLK_AB_CTRL, - .mask = 0x3, - .shift = 9, - }, - .hw.init = &(struct clk_init_data){ - .name = "pwm_a_mux", - .ops = &clk_regmap_mux_ops, - .parent_data = s4_pwm_parent_data, - .num_parents = ARRAY_SIZE(s4_pwm_parent_data), - .flags = 0, - }, -}; - -static struct clk_regmap s4_pwm_a_div = { - .data = &(struct clk_regmap_div_data) { - .offset = CLKCTRL_PWM_CLK_AB_CTRL, - .shift = 0, - .width = 8, - }, - .hw.init = &(struct clk_init_data){ - .name = "pwm_a_div", - .ops = &clk_regmap_divider_ops, - .parent_hws = (const struct clk_hw *[]) { - &s4_pwm_a_mux.hw - }, - .num_parents = 1, - .flags = CLK_SET_RATE_PARENT, - }, -}; - -static struct clk_regmap s4_pwm_a_gate = { - .data = &(struct clk_regmap_gate_data) { - .offset = CLKCTRL_PWM_CLK_AB_CTRL, - .bit_idx = 8, - }, - .hw.init = &(struct clk_init_data){ - .name = "pwm_a_gate", - .ops = &clk_regmap_gate_ops, - .parent_hws = (const struct clk_hw *[]) { - &s4_pwm_a_div.hw - }, - .num_parents = 1, - .flags = CLK_SET_RATE_PARENT, - }, -}; - -static struct clk_regmap s4_pwm_b_mux = { - .data = &(struct clk_regmap_mux_data) { - .offset = CLKCTRL_PWM_CLK_AB_CTRL, - .mask = 0x3, - .shift = 25, - }, - .hw.init = &(struct clk_init_data){ - .name = "pwm_b_mux", - .ops = &clk_regmap_mux_ops, - .parent_data = s4_pwm_parent_data, - .num_parents = ARRAY_SIZE(s4_pwm_parent_data), - .flags = 0, - }, -}; - -static struct clk_regmap s4_pwm_b_div = { - .data = &(struct clk_regmap_div_data) { - .offset = CLKCTRL_PWM_CLK_AB_CTRL, - .shift = 16, - .width = 8, - }, - .hw.init = &(struct clk_init_data){ - .name = "pwm_b_div", - .ops = &clk_regmap_divider_ops, - .parent_hws = (const struct clk_hw *[]) { - &s4_pwm_b_mux.hw - }, - .num_parents = 1, - .flags = CLK_SET_RATE_PARENT, - }, -}; - -static struct clk_regmap s4_pwm_b_gate = { - .data = &(struct clk_regmap_gate_data) { - .offset = CLKCTRL_PWM_CLK_AB_CTRL, - .bit_idx = 24, - }, - .hw.init = &(struct clk_init_data){ - .name = "pwm_b_gate", - .ops = &clk_regmap_gate_ops, - .parent_hws = (const struct clk_hw *[]) { - &s4_pwm_b_div.hw - }, - .num_parents = 1, - .flags = CLK_SET_RATE_PARENT, - }, -}; - -static struct clk_regmap s4_pwm_c_mux = { - .data = &(struct clk_regmap_mux_data) { - .offset = CLKCTRL_PWM_CLK_CD_CTRL, - .mask = 0x3, - .shift = 9, - }, - .hw.init = &(struct clk_init_data){ - .name = "pwm_c_mux", - .ops = &clk_regmap_mux_ops, - .parent_data = s4_pwm_parent_data, - .num_parents = ARRAY_SIZE(s4_pwm_parent_data), - .flags = 0, - }, -}; - -static struct clk_regmap s4_pwm_c_div = { - .data = &(struct clk_regmap_div_data) { - .offset = CLKCTRL_PWM_CLK_CD_CTRL, - .shift = 0, - .width = 8, - }, - .hw.init = &(struct clk_init_data){ - .name = "pwm_c_div", - .ops = &clk_regmap_divider_ops, - .parent_hws = (const struct clk_hw *[]) { - &s4_pwm_c_mux.hw - }, - .num_parents = 1, - }, -}; - -static struct clk_regmap s4_pwm_c_gate = { - .data = &(struct clk_regmap_gate_data) { - .offset = CLKCTRL_PWM_CLK_CD_CTRL, - .bit_idx = 8, - }, - .hw.init = &(struct clk_init_data){ - .name = "pwm_c_gate", - .ops = &clk_regmap_gate_ops, - .parent_hws = (const struct clk_hw *[]) { - &s4_pwm_c_div.hw - }, - .num_parents = 1, - .flags = CLK_SET_RATE_PARENT, - }, -}; - -static struct clk_regmap s4_pwm_d_mux = { - .data = &(struct clk_regmap_mux_data) { - .offset = CLKCTRL_PWM_CLK_CD_CTRL, - .mask = 0x3, - .shift = 25, - }, - .hw.init = &(struct clk_init_data){ - .name = "pwm_d_mux", - .ops = &clk_regmap_mux_ops, - .parent_data = s4_pwm_parent_data, - .num_parents = ARRAY_SIZE(s4_pwm_parent_data), - .flags = 0, - }, -}; - -static struct clk_regmap s4_pwm_d_div = { - .data = &(struct clk_regmap_div_data) { - .offset = CLKCTRL_PWM_CLK_CD_CTRL, - .shift = 16, - .width = 8, - }, - .hw.init = &(struct clk_init_data){ - .name = "pwm_d_div", - .ops = &clk_regmap_divider_ops, - .parent_hws = (const struct clk_hw *[]) { - &s4_pwm_d_mux.hw - }, - .num_parents = 1, - .flags = CLK_SET_RATE_PARENT, - }, -}; - -static struct clk_regmap s4_pwm_d_gate = { - .data = &(struct clk_regmap_gate_data) { - .offset = CLKCTRL_PWM_CLK_CD_CTRL, - .bit_idx = 24, - }, - .hw.init = &(struct clk_init_data){ - .name = "pwm_d_gate", - .ops = &clk_regmap_gate_ops, - .parent_hws = (const struct clk_hw *[]) { - &s4_pwm_d_div.hw - }, - .num_parents = 1, - .flags = CLK_SET_RATE_PARENT, - }, -}; - -static struct clk_regmap s4_pwm_e_mux = { - .data = &(struct clk_regmap_mux_data) { - .offset = CLKCTRL_PWM_CLK_EF_CTRL, - .mask = 0x3, - .shift = 9, - }, - .hw.init = &(struct clk_init_data){ - .name = "pwm_e_mux", - .ops = &clk_regmap_mux_ops, - .parent_data = s4_pwm_parent_data, - .num_parents = ARRAY_SIZE(s4_pwm_parent_data), - .flags = 0, - }, -}; - -static struct clk_regmap s4_pwm_e_div = { - .data = &(struct clk_regmap_div_data) { - .offset = CLKCTRL_PWM_CLK_EF_CTRL, - .shift = 0, - .width = 8, - }, - .hw.init = &(struct clk_init_data){ - .name = "pwm_e_div", - .ops = &clk_regmap_divider_ops, - .parent_hws = (const struct clk_hw *[]) { - &s4_pwm_e_mux.hw - }, - .num_parents = 1, - .flags = CLK_SET_RATE_PARENT, - }, -}; - -static struct clk_regmap s4_pwm_e_gate = { - .data = &(struct clk_regmap_gate_data) { - .offset = CLKCTRL_PWM_CLK_EF_CTRL, - .bit_idx = 8, - }, - .hw.init = &(struct clk_init_data){ - .name = "pwm_e_gate", - .ops = &clk_regmap_gate_ops, - .parent_hws = (const struct clk_hw *[]) { - &s4_pwm_e_div.hw - }, - .num_parents = 1, - .flags = CLK_SET_RATE_PARENT, - }, -}; - -static struct clk_regmap s4_pwm_f_mux = { - .data = &(struct clk_regmap_mux_data) { - .offset = CLKCTRL_PWM_CLK_EF_CTRL, - .mask = 0x3, - .shift = 25, - }, - .hw.init = &(struct clk_init_data){ - .name = "pwm_f_mux", - .ops = &clk_regmap_mux_ops, - .parent_data = s4_pwm_parent_data, - .num_parents = ARRAY_SIZE(s4_pwm_parent_data), - .flags = 0, - }, -}; +static S4_COMP_SEL(pwm_a, CLKCTRL_PWM_CLK_AB_CTRL, 9, 0x3, s4_pwm_parents); +static S4_COMP_DIV(pwm_a, CLKCTRL_PWM_CLK_AB_CTRL, 0, 8); +static S4_COMP_GATE(pwm_a, CLKCTRL_PWM_CLK_AB_CTRL, 8); -static struct clk_regmap s4_pwm_f_div = { - .data = &(struct clk_regmap_div_data) { - .offset = CLKCTRL_PWM_CLK_EF_CTRL, - .shift = 16, - .width = 8, - }, - .hw.init = &(struct clk_init_data){ - .name = "pwm_f_div", - .ops = &clk_regmap_divider_ops, - .parent_hws = (const struct clk_hw *[]) { - &s4_pwm_f_mux.hw - }, - .num_parents = 1, - .flags = CLK_SET_RATE_PARENT, - }, -}; +static S4_COMP_SEL(pwm_b, CLKCTRL_PWM_CLK_AB_CTRL, 25, 0x3, s4_pwm_parents); +static S4_COMP_DIV(pwm_b, CLKCTRL_PWM_CLK_AB_CTRL, 16, 8); +static S4_COMP_GATE(pwm_b, CLKCTRL_PWM_CLK_AB_CTRL, 24); -static struct clk_regmap s4_pwm_f_gate = { - .data = &(struct clk_regmap_gate_data) { - .offset = CLKCTRL_PWM_CLK_EF_CTRL, - .bit_idx = 24, - }, - .hw.init = &(struct clk_init_data){ - .name = "pwm_f_gate", - .ops = &clk_regmap_gate_ops, - .parent_hws = (const struct clk_hw *[]) { - &s4_pwm_f_div.hw - }, - .num_parents = 1, - .flags = CLK_SET_RATE_PARENT, - }, -}; +static S4_COMP_SEL(pwm_c, CLKCTRL_PWM_CLK_CD_CTRL, 9, 0x3, s4_pwm_parents); +static S4_COMP_DIV(pwm_c, CLKCTRL_PWM_CLK_CD_CTRL, 0, 8); +static S4_COMP_GATE(pwm_c, CLKCTRL_PWM_CLK_CD_CTRL, 8); -static struct clk_regmap s4_pwm_g_mux = { - .data = &(struct clk_regmap_mux_data) { - .offset = CLKCTRL_PWM_CLK_GH_CTRL, - .mask = 0x3, - .shift = 9, - }, - .hw.init = &(struct clk_init_data){ - .name = "pwm_g_mux", - .ops = &clk_regmap_mux_ops, - .parent_data = s4_pwm_parent_data, - .num_parents = ARRAY_SIZE(s4_pwm_parent_data), - .flags = 0, - }, -}; +static S4_COMP_SEL(pwm_d, CLKCTRL_PWM_CLK_CD_CTRL, 25, 0x3, s4_pwm_parents); +static S4_COMP_DIV(pwm_d, CLKCTRL_PWM_CLK_CD_CTRL, 16, 8); +static S4_COMP_GATE(pwm_d, CLKCTRL_PWM_CLK_CD_CTRL, 24); -static struct clk_regmap s4_pwm_g_div = { - .data = &(struct clk_regmap_div_data) { - .offset = CLKCTRL_PWM_CLK_GH_CTRL, - .shift = 0, - .width = 8, - }, - .hw.init = &(struct clk_init_data){ - .name = "pwm_g_div", - .ops = &clk_regmap_divider_ops, - .parent_hws = (const struct clk_hw *[]) { - &s4_pwm_g_mux.hw - }, - .num_parents = 1, - .flags = CLK_SET_RATE_PARENT, - }, -}; +static S4_COMP_SEL(pwm_e, CLKCTRL_PWM_CLK_EF_CTRL, 9, 0x3, s4_pwm_parents); +static S4_COMP_DIV(pwm_e, CLKCTRL_PWM_CLK_EF_CTRL, 0, 8); +static S4_COMP_GATE(pwm_e, CLKCTRL_PWM_CLK_EF_CTRL, 8); -static struct clk_regmap s4_pwm_g_gate = { - .data = &(struct clk_regmap_gate_data) { - .offset = CLKCTRL_PWM_CLK_GH_CTRL, - .bit_idx = 8, - }, - .hw.init = &(struct clk_init_data){ - .name = "pwm_g_gate", - .ops = &clk_regmap_gate_ops, - .parent_hws = (const struct clk_hw *[]) { - &s4_pwm_g_div.hw - }, - .num_parents = 1, - .flags = CLK_SET_RATE_PARENT, - }, -}; +static S4_COMP_SEL(pwm_f, CLKCTRL_PWM_CLK_EF_CTRL, 25, 0x3, s4_pwm_parents); +static S4_COMP_DIV(pwm_f, CLKCTRL_PWM_CLK_EF_CTRL, 16, 8); +static S4_COMP_GATE(pwm_f, CLKCTRL_PWM_CLK_EF_CTRL, 24); -static struct clk_regmap s4_pwm_h_mux = { - .data = &(struct clk_regmap_mux_data) { - .offset = CLKCTRL_PWM_CLK_GH_CTRL, - .mask = 0x3, - .shift = 25, - }, - .hw.init = &(struct clk_init_data){ - .name = "pwm_h_mux", - .ops = &clk_regmap_mux_ops, - .parent_data = s4_pwm_parent_data, - .num_parents = ARRAY_SIZE(s4_pwm_parent_data), - .flags = 0, - }, -}; +static S4_COMP_SEL(pwm_g, CLKCTRL_PWM_CLK_GH_CTRL, 9, 0x3, s4_pwm_parents); +static S4_COMP_DIV(pwm_g, CLKCTRL_PWM_CLK_GH_CTRL, 0, 8); +static S4_COMP_GATE(pwm_g, CLKCTRL_PWM_CLK_GH_CTRL, 8); -static struct clk_regmap s4_pwm_h_div = { - .data = &(struct clk_regmap_div_data) { - .offset = CLKCTRL_PWM_CLK_GH_CTRL, - .shift = 16, - .width = 8, - }, - .hw.init = &(struct clk_init_data){ - .name = "pwm_h_div", - .ops = &clk_regmap_divider_ops, - .parent_hws = (const struct clk_hw *[]) { - &s4_pwm_h_mux.hw - }, - .num_parents = 1, - .flags = CLK_SET_RATE_PARENT, - }, -}; +static S4_COMP_SEL(pwm_h, CLKCTRL_PWM_CLK_GH_CTRL, 25, 0x3, s4_pwm_parents); +static S4_COMP_DIV(pwm_h, CLKCTRL_PWM_CLK_GH_CTRL, 16, 8); +static S4_COMP_GATE(pwm_h, CLKCTRL_PWM_CLK_GH_CTRL, 24); -static struct clk_regmap s4_pwm_h_gate = { - .data = &(struct clk_regmap_gate_data) { - .offset = CLKCTRL_PWM_CLK_GH_CTRL, - .bit_idx = 24, - }, - .hw.init = &(struct clk_init_data){ - .name = "pwm_h_gate", - .ops = &clk_regmap_gate_ops, - .parent_hws = (const struct clk_hw *[]) { - &s4_pwm_h_div.hw - }, - .num_parents = 1, - .flags = CLK_SET_RATE_PARENT, - }, -}; +static S4_COMP_SEL(pwm_i, CLKCTRL_PWM_CLK_IJ_CTRL, 9, 0x3, s4_pwm_parents); +static S4_COMP_DIV(pwm_i, CLKCTRL_PWM_CLK_IJ_CTRL, 0, 8); +static S4_COMP_GATE(pwm_i, CLKCTRL_PWM_CLK_IJ_CTRL, 8); -static struct clk_regmap s4_pwm_i_mux = { - .data = &(struct clk_regmap_mux_data) { - .offset = CLKCTRL_PWM_CLK_IJ_CTRL, - .mask = 0x3, - .shift = 9, - }, - .hw.init = &(struct clk_init_data){ - .name = "pwm_i_mux", - .ops = &clk_regmap_mux_ops, - .parent_data = s4_pwm_parent_data, - .num_parents = ARRAY_SIZE(s4_pwm_parent_data), - .flags = 0, - }, -}; +static S4_COMP_SEL(pwm_j, CLKCTRL_PWM_CLK_IJ_CTRL, 25, 0x3, s4_pwm_parents); +static S4_COMP_DIV(pwm_j, CLKCTRL_PWM_CLK_IJ_CTRL, 16, 8); +static S4_COMP_GATE(pwm_j, CLKCTRL_PWM_CLK_IJ_CTRL, 24); -static struct clk_regmap s4_pwm_i_div = { - .data = &(struct clk_regmap_div_data) { - .offset = CLKCTRL_PWM_CLK_IJ_CTRL, - .shift = 0, - .width = 8, - }, - .hw.init = &(struct clk_init_data){ - .name = "pwm_i_div", - .ops = &clk_regmap_divider_ops, - .parent_hws = (const struct clk_hw *[]) { - &s4_pwm_i_mux.hw - }, - .num_parents = 1, - .flags = CLK_SET_RATE_PARENT, - }, -}; - -static struct clk_regmap s4_pwm_i_gate = { - .data = &(struct clk_regmap_gate_data) { - .offset = CLKCTRL_PWM_CLK_IJ_CTRL, - .bit_idx = 8, - }, - .hw.init = &(struct clk_init_data){ - .name = "pwm_i_gate", - .ops = &clk_regmap_gate_ops, - .parent_hws = (const struct clk_hw *[]) { - &s4_pwm_i_div.hw - }, - .num_parents = 1, - .flags = CLK_SET_RATE_PARENT, - }, -}; - -static struct clk_regmap s4_pwm_j_mux = { - .data = &(struct clk_regmap_mux_data) { - .offset = CLKCTRL_PWM_CLK_IJ_CTRL, - .mask = 0x3, - .shift = 25, - }, - .hw.init = &(struct clk_init_data){ - .name = "pwm_j_mux", - .ops = &clk_regmap_mux_ops, - .parent_data = s4_pwm_parent_data, - .num_parents = ARRAY_SIZE(s4_pwm_parent_data), - .flags = 0, - }, -}; - -static struct clk_regmap s4_pwm_j_div = { - .data = &(struct clk_regmap_div_data) { - .offset = CLKCTRL_PWM_CLK_IJ_CTRL, - .shift = 16, - .width = 8, - }, - .hw.init = &(struct clk_init_data){ - .name = "pwm_j_div", - .ops = &clk_regmap_divider_ops, - .parent_hws = (const struct clk_hw *[]) { - &s4_pwm_j_mux.hw - }, - .num_parents = 1, - .flags = CLK_SET_RATE_PARENT, - }, -}; - -static struct clk_regmap s4_pwm_j_gate = { - .data = &(struct clk_regmap_gate_data) { - .offset = CLKCTRL_PWM_CLK_IJ_CTRL, - .bit_idx = 24, - }, - .hw.init = &(struct clk_init_data){ - .name = "pwm_j_gate", - .ops = &clk_regmap_gate_ops, - .parent_hws = (const struct clk_hw *[]) { - &s4_pwm_j_div.hw - }, - .num_parents = 1, - .flags = CLK_SET_RATE_PARENT, - }, -}; - -static struct clk_regmap s4_saradc_mux = { +static struct clk_regmap s4_saradc_sel = { .data = &(struct clk_regmap_mux_data) { .offset = CLKCTRL_SAR_CLK_CTRL, .mask = 0x3, .shift = 9, }, .hw.init = &(struct clk_init_data){ - .name = "saradc_mux", + .name = "saradc_sel", .ops = &clk_regmap_mux_ops, .parent_data = (const struct clk_parent_data []) { { .fw_name = "xtal", }, @@ -3074,20 +2636,20 @@ static struct clk_regmap s4_saradc_div = { .name = "saradc_div", .ops = &clk_regmap_divider_ops, .parent_hws = (const struct clk_hw *[]) { - &s4_saradc_mux.hw + &s4_saradc_sel.hw }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, }; -static struct clk_regmap s4_saradc_gate = { +static struct clk_regmap s4_saradc = { .data = &(struct clk_regmap_gate_data) { .offset = CLKCTRL_SAR_CLK_CTRL, .bit_idx = 8, }, .hw.init = &(struct clk_init_data){ - .name = "saradc_clk", + .name = "saradc", .ops = &clk_regmap_gate_ops, .parent_hws = (const struct clk_hw *[]) { &s4_saradc_div.hw @@ -3102,9 +2664,8 @@ static struct clk_regmap s4_saradc_gate = { * corresponding clock sources are not described in the clock tree and internal clock * for debug, so they are skipped. */ -static u32 s4_gen_clk_mux_table[] = { 0, 4, 5, 7, 19, 21, 22, - 23, 24, 25, 26, 27, 28 }; -static const struct clk_parent_data s4_gen_clk_parent_data[] = { +static u32 s4_gen_clk_parents_val_table[] = { 0, 4, 5, 7, 19, 21, 22, 23, 24, 25, 26, 27, 28 }; +static const struct clk_parent_data s4_gen_clk_parents[] = { { .fw_name = "xtal", }, { .hw = &s4_vid_pll.hw }, { .fw_name = "gp0_pll", }, @@ -3125,13 +2686,13 @@ static struct clk_regmap s4_gen_clk_sel = { .offset = CLKCTRL_GEN_CLK_CTRL, .mask = 0x1f, .shift = 12, - .table = s4_gen_clk_mux_table, + .table = s4_gen_clk_parents_val_table, }, .hw.init = &(struct clk_init_data){ .name = "gen_clk_sel", .ops = &clk_regmap_mux_ops, - .parent_data = s4_gen_clk_parent_data, - .num_parents = ARRAY_SIZE(s4_gen_clk_parent_data), + .parent_data = s4_gen_clk_parents, + .num_parents = ARRAY_SIZE(s4_gen_clk_parents), /* * Because the GEN clock can be connected to an external pad * and may be set up directly from the device tree. Don't @@ -3174,61 +2735,75 @@ static struct clk_regmap s4_gen_clk = { }, }; -#define MESON_GATE(_name, _reg, _bit) \ - MESON_PCLK(_name, _reg, _bit, &s4_sys_clk.hw) - -static MESON_GATE(s4_ddr, CLKCTRL_SYS_CLK_EN0_REG0, 0); -static MESON_GATE(s4_dos, CLKCTRL_SYS_CLK_EN0_REG0, 1); -static MESON_GATE(s4_ethphy, CLKCTRL_SYS_CLK_EN0_REG0, 4); -static MESON_GATE(s4_mali, CLKCTRL_SYS_CLK_EN0_REG0, 6); -static MESON_GATE(s4_aocpu, CLKCTRL_SYS_CLK_EN0_REG0, 13); -static MESON_GATE(s4_aucpu, CLKCTRL_SYS_CLK_EN0_REG0, 14); -static MESON_GATE(s4_cec, CLKCTRL_SYS_CLK_EN0_REG0, 16); -static MESON_GATE(s4_sdemmca, CLKCTRL_SYS_CLK_EN0_REG0, 24); -static MESON_GATE(s4_sdemmcb, CLKCTRL_SYS_CLK_EN0_REG0, 25); -static MESON_GATE(s4_nand, CLKCTRL_SYS_CLK_EN0_REG0, 26); -static MESON_GATE(s4_smartcard, CLKCTRL_SYS_CLK_EN0_REG0, 27); -static MESON_GATE(s4_acodec, CLKCTRL_SYS_CLK_EN0_REG0, 28); -static MESON_GATE(s4_spifc, CLKCTRL_SYS_CLK_EN0_REG0, 29); -static MESON_GATE(s4_msr_clk, CLKCTRL_SYS_CLK_EN0_REG0, 30); -static MESON_GATE(s4_ir_ctrl, CLKCTRL_SYS_CLK_EN0_REG0, 31); -static MESON_GATE(s4_audio, CLKCTRL_SYS_CLK_EN0_REG1, 0); -static MESON_GATE(s4_eth, CLKCTRL_SYS_CLK_EN0_REG1, 3); -static MESON_GATE(s4_uart_a, CLKCTRL_SYS_CLK_EN0_REG1, 5); -static MESON_GATE(s4_uart_b, CLKCTRL_SYS_CLK_EN0_REG1, 6); -static MESON_GATE(s4_uart_c, CLKCTRL_SYS_CLK_EN0_REG1, 7); -static MESON_GATE(s4_uart_d, CLKCTRL_SYS_CLK_EN0_REG1, 8); -static MESON_GATE(s4_uart_e, CLKCTRL_SYS_CLK_EN0_REG1, 9); -static MESON_GATE(s4_aififo, CLKCTRL_SYS_CLK_EN0_REG1, 11); -static MESON_GATE(s4_ts_ddr, CLKCTRL_SYS_CLK_EN0_REG1, 15); -static MESON_GATE(s4_ts_pll, CLKCTRL_SYS_CLK_EN0_REG1, 16); -static MESON_GATE(s4_g2d, CLKCTRL_SYS_CLK_EN0_REG1, 20); -static MESON_GATE(s4_spicc0, CLKCTRL_SYS_CLK_EN0_REG1, 21); -static MESON_GATE(s4_usb, CLKCTRL_SYS_CLK_EN0_REG1, 26); -static MESON_GATE(s4_i2c_m_a, CLKCTRL_SYS_CLK_EN0_REG1, 30); -static MESON_GATE(s4_i2c_m_b, CLKCTRL_SYS_CLK_EN0_REG1, 31); -static MESON_GATE(s4_i2c_m_c, CLKCTRL_SYS_CLK_EN0_REG2, 0); -static MESON_GATE(s4_i2c_m_d, CLKCTRL_SYS_CLK_EN0_REG2, 1); -static MESON_GATE(s4_i2c_m_e, CLKCTRL_SYS_CLK_EN0_REG2, 2); -static MESON_GATE(s4_hdmitx_apb, CLKCTRL_SYS_CLK_EN0_REG2, 4); -static MESON_GATE(s4_i2c_s_a, CLKCTRL_SYS_CLK_EN0_REG2, 5); -static MESON_GATE(s4_usb1_to_ddr, CLKCTRL_SYS_CLK_EN0_REG2, 8); -static MESON_GATE(s4_hdcp22, CLKCTRL_SYS_CLK_EN0_REG2, 10); -static MESON_GATE(s4_mmc_apb, CLKCTRL_SYS_CLK_EN0_REG2, 11); -static MESON_GATE(s4_rsa, CLKCTRL_SYS_CLK_EN0_REG2, 18); -static MESON_GATE(s4_cpu_debug, CLKCTRL_SYS_CLK_EN0_REG2, 19); -static MESON_GATE(s4_vpu_intr, CLKCTRL_SYS_CLK_EN0_REG2, 25); -static MESON_GATE(s4_demod, CLKCTRL_SYS_CLK_EN0_REG2, 27); -static MESON_GATE(s4_sar_adc, CLKCTRL_SYS_CLK_EN0_REG2, 28); -static MESON_GATE(s4_gic, CLKCTRL_SYS_CLK_EN0_REG2, 30); -static MESON_GATE(s4_pwm_ab, CLKCTRL_SYS_CLK_EN0_REG3, 7); -static MESON_GATE(s4_pwm_cd, CLKCTRL_SYS_CLK_EN0_REG3, 8); -static MESON_GATE(s4_pwm_ef, CLKCTRL_SYS_CLK_EN0_REG3, 9); -static MESON_GATE(s4_pwm_gh, CLKCTRL_SYS_CLK_EN0_REG3, 10); -static MESON_GATE(s4_pwm_ij, CLKCTRL_SYS_CLK_EN0_REG3, 11); +static const struct clk_parent_data s4_pclk_parents = { .hw = &s4_sys_clk.hw }; + +#define S4_PCLK(_name, _reg, _bit, _flags) \ + MESON_PCLK(_name, _reg, _bit, &s4_pclk_parents, _flags) + +/* + * NOTE: The gates below are marked with CLK_IGNORE_UNUSED for historic reasons + * Users are encouraged to test without it and submit changes to: + * - remove the flag if not necessary + * - replace the flag with something more adequate, such as CLK_IS_CRITICAL, + * if appropriate. + * - add a comment explaining why the use of CLK_IGNORE_UNUSED is desirable + * for a particular clock. + */ +static S4_PCLK(s4_ddr, CLKCTRL_SYS_CLK_EN0_REG0, 0, CLK_IGNORE_UNUSED); +static S4_PCLK(s4_dos, CLKCTRL_SYS_CLK_EN0_REG0, 1, CLK_IGNORE_UNUSED); +static S4_PCLK(s4_ethphy, CLKCTRL_SYS_CLK_EN0_REG0, 4, CLK_IGNORE_UNUSED); +static S4_PCLK(s4_mali, CLKCTRL_SYS_CLK_EN0_REG0, 6, CLK_IGNORE_UNUSED); +static S4_PCLK(s4_aocpu, CLKCTRL_SYS_CLK_EN0_REG0, 13, CLK_IGNORE_UNUSED); +static S4_PCLK(s4_aucpu, CLKCTRL_SYS_CLK_EN0_REG0, 14, CLK_IGNORE_UNUSED); +static S4_PCLK(s4_cec, CLKCTRL_SYS_CLK_EN0_REG0, 16, CLK_IGNORE_UNUSED); +static S4_PCLK(s4_sdemmca, CLKCTRL_SYS_CLK_EN0_REG0, 24, CLK_IGNORE_UNUSED); +static S4_PCLK(s4_sdemmcb, CLKCTRL_SYS_CLK_EN0_REG0, 25, CLK_IGNORE_UNUSED); +static S4_PCLK(s4_nand, CLKCTRL_SYS_CLK_EN0_REG0, 26, CLK_IGNORE_UNUSED); +static S4_PCLK(s4_smartcard, CLKCTRL_SYS_CLK_EN0_REG0, 27, CLK_IGNORE_UNUSED); +static S4_PCLK(s4_acodec, CLKCTRL_SYS_CLK_EN0_REG0, 28, CLK_IGNORE_UNUSED); +static S4_PCLK(s4_spifc, CLKCTRL_SYS_CLK_EN0_REG0, 29, CLK_IGNORE_UNUSED); +static S4_PCLK(s4_msr_clk, CLKCTRL_SYS_CLK_EN0_REG0, 30, CLK_IGNORE_UNUSED); +static S4_PCLK(s4_ir_ctrl, CLKCTRL_SYS_CLK_EN0_REG0, 31, CLK_IGNORE_UNUSED); + +static S4_PCLK(s4_audio, CLKCTRL_SYS_CLK_EN0_REG1, 0, CLK_IGNORE_UNUSED); +static S4_PCLK(s4_eth, CLKCTRL_SYS_CLK_EN0_REG1, 3, CLK_IGNORE_UNUSED); +static S4_PCLK(s4_uart_a, CLKCTRL_SYS_CLK_EN0_REG1, 5, CLK_IGNORE_UNUSED); +static S4_PCLK(s4_uart_b, CLKCTRL_SYS_CLK_EN0_REG1, 6, CLK_IGNORE_UNUSED); +static S4_PCLK(s4_uart_c, CLKCTRL_SYS_CLK_EN0_REG1, 7, CLK_IGNORE_UNUSED); +static S4_PCLK(s4_uart_d, CLKCTRL_SYS_CLK_EN0_REG1, 8, CLK_IGNORE_UNUSED); +static S4_PCLK(s4_uart_e, CLKCTRL_SYS_CLK_EN0_REG1, 9, CLK_IGNORE_UNUSED); +static S4_PCLK(s4_aififo, CLKCTRL_SYS_CLK_EN0_REG1, 11, CLK_IGNORE_UNUSED); +static S4_PCLK(s4_ts_ddr, CLKCTRL_SYS_CLK_EN0_REG1, 15, CLK_IGNORE_UNUSED); +static S4_PCLK(s4_ts_pll, CLKCTRL_SYS_CLK_EN0_REG1, 16, CLK_IGNORE_UNUSED); +static S4_PCLK(s4_g2d, CLKCTRL_SYS_CLK_EN0_REG1, 20, CLK_IGNORE_UNUSED); +static S4_PCLK(s4_spicc0, CLKCTRL_SYS_CLK_EN0_REG1, 21, CLK_IGNORE_UNUSED); +static S4_PCLK(s4_usb, CLKCTRL_SYS_CLK_EN0_REG1, 26, CLK_IGNORE_UNUSED); +static S4_PCLK(s4_i2c_m_a, CLKCTRL_SYS_CLK_EN0_REG1, 30, CLK_IGNORE_UNUSED); +static S4_PCLK(s4_i2c_m_b, CLKCTRL_SYS_CLK_EN0_REG1, 31, CLK_IGNORE_UNUSED); + +static S4_PCLK(s4_i2c_m_c, CLKCTRL_SYS_CLK_EN0_REG2, 0, CLK_IGNORE_UNUSED); +static S4_PCLK(s4_i2c_m_d, CLKCTRL_SYS_CLK_EN0_REG2, 1, CLK_IGNORE_UNUSED); +static S4_PCLK(s4_i2c_m_e, CLKCTRL_SYS_CLK_EN0_REG2, 2, CLK_IGNORE_UNUSED); +static S4_PCLK(s4_hdmitx_apb, CLKCTRL_SYS_CLK_EN0_REG2, 4, CLK_IGNORE_UNUSED); +static S4_PCLK(s4_i2c_s_a, CLKCTRL_SYS_CLK_EN0_REG2, 5, CLK_IGNORE_UNUSED); +static S4_PCLK(s4_usb1_to_ddr, CLKCTRL_SYS_CLK_EN0_REG2, 8, CLK_IGNORE_UNUSED); +static S4_PCLK(s4_hdcp22, CLKCTRL_SYS_CLK_EN0_REG2, 10, CLK_IGNORE_UNUSED); +static S4_PCLK(s4_mmc_apb, CLKCTRL_SYS_CLK_EN0_REG2, 11, CLK_IGNORE_UNUSED); +static S4_PCLK(s4_rsa, CLKCTRL_SYS_CLK_EN0_REG2, 18, CLK_IGNORE_UNUSED); +static S4_PCLK(s4_cpu_debug, CLKCTRL_SYS_CLK_EN0_REG2, 19, CLK_IGNORE_UNUSED); +static S4_PCLK(s4_vpu_intr, CLKCTRL_SYS_CLK_EN0_REG2, 25, CLK_IGNORE_UNUSED); +static S4_PCLK(s4_demod, CLKCTRL_SYS_CLK_EN0_REG2, 27, CLK_IGNORE_UNUSED); +static S4_PCLK(s4_sar_adc, CLKCTRL_SYS_CLK_EN0_REG2, 28, CLK_IGNORE_UNUSED); +static S4_PCLK(s4_gic, CLKCTRL_SYS_CLK_EN0_REG2, 30, CLK_IGNORE_UNUSED); + +static S4_PCLK(s4_pwm_ab, CLKCTRL_SYS_CLK_EN0_REG3, 7, CLK_IGNORE_UNUSED); +static S4_PCLK(s4_pwm_cd, CLKCTRL_SYS_CLK_EN0_REG3, 8, CLK_IGNORE_UNUSED); +static S4_PCLK(s4_pwm_ef, CLKCTRL_SYS_CLK_EN0_REG3, 9, CLK_IGNORE_UNUSED); +static S4_PCLK(s4_pwm_gh, CLKCTRL_SYS_CLK_EN0_REG3, 10, CLK_IGNORE_UNUSED); +static S4_PCLK(s4_pwm_ij, CLKCTRL_SYS_CLK_EN0_REG3, 11, CLK_IGNORE_UNUSED); /* Array of all clocks provided by this provider */ -static struct clk_hw *s4_periphs_hw_clks[] = { +static struct clk_hw *s4_peripherals_hw_clks[] = { [CLKID_RTC_32K_CLKIN] = &s4_rtc_32k_by_oscin_clkin.hw, [CLKID_RTC_32K_DIV] = &s4_rtc_32k_by_oscin_div.hw, [CLKID_RTC_32K_SEL] = &s4_rtc_32k_by_oscin_sel.hw, @@ -3251,12 +2826,12 @@ static struct clk_hw *s4_periphs_hw_clks[] = { [CLKID_CECB_32K_SEL_PRE] = &s4_cecb_32k_sel_pre.hw, [CLKID_CECB_32K_SEL] = &s4_cecb_32k_sel.hw, [CLKID_CECB_32K_CLKOUT] = &s4_cecb_32k_clkout.hw, - [CLKID_SC_CLK_SEL] = &s4_sc_clk_mux.hw, + [CLKID_SC_CLK_SEL] = &s4_sc_clk_sel.hw, [CLKID_SC_CLK_DIV] = &s4_sc_clk_div.hw, - [CLKID_SC] = &s4_sc_clk_gate.hw, - [CLKID_12_24M] = &s4_12_24M_clk_gate.hw, - [CLKID_12M_CLK_DIV] = &s4_12M_clk_div.hw, - [CLKID_12_24M_CLK_SEL] = &s4_12_24M_clk.hw, + [CLKID_SC] = &s4_sc_clk.hw, + [CLKID_12_24M] = &s4_12_24M.hw, + [CLKID_12M_CLK_DIV] = &s4_12M_div.hw, + [CLKID_12_24M_CLK_SEL] = &s4_12_24M_sel.hw, [CLKID_VID_PLL_DIV] = &s4_vid_pll_div.hw, [CLKID_VID_PLL_SEL] = &s4_vid_pll_sel.hw, [CLKID_VID_PLL] = &s4_vid_pll.hw, @@ -3298,28 +2873,28 @@ static struct clk_hw *s4_periphs_hw_clks[] = { [CLKID_HDMI_DIV] = &s4_hdmi_div.hw, [CLKID_HDMI] = &s4_hdmi.hw, [CLKID_TS_CLK_DIV] = &s4_ts_clk_div.hw, - [CLKID_TS] = &s4_ts_clk_gate.hw, + [CLKID_TS] = &s4_ts_clk.hw, [CLKID_MALI_0_SEL] = &s4_mali_0_sel.hw, [CLKID_MALI_0_DIV] = &s4_mali_0_div.hw, [CLKID_MALI_0] = &s4_mali_0.hw, [CLKID_MALI_1_SEL] = &s4_mali_1_sel.hw, [CLKID_MALI_1_DIV] = &s4_mali_1_div.hw, [CLKID_MALI_1] = &s4_mali_1.hw, - [CLKID_MALI_SEL] = &s4_mali_mux.hw, - [CLKID_VDEC_P0_SEL] = &s4_vdec_p0_mux.hw, + [CLKID_MALI_SEL] = &s4_mali_sel.hw, + [CLKID_VDEC_P0_SEL] = &s4_vdec_p0_sel.hw, [CLKID_VDEC_P0_DIV] = &s4_vdec_p0_div.hw, [CLKID_VDEC_P0] = &s4_vdec_p0.hw, - [CLKID_VDEC_P1_SEL] = &s4_vdec_p1_mux.hw, + [CLKID_VDEC_P1_SEL] = &s4_vdec_p1_sel.hw, [CLKID_VDEC_P1_DIV] = &s4_vdec_p1_div.hw, [CLKID_VDEC_P1] = &s4_vdec_p1.hw, - [CLKID_VDEC_SEL] = &s4_vdec_mux.hw, - [CLKID_HEVCF_P0_SEL] = &s4_hevcf_p0_mux.hw, + [CLKID_VDEC_SEL] = &s4_vdec_sel.hw, + [CLKID_HEVCF_P0_SEL] = &s4_hevcf_p0_sel.hw, [CLKID_HEVCF_P0_DIV] = &s4_hevcf_p0_div.hw, [CLKID_HEVCF_P0] = &s4_hevcf_p0.hw, - [CLKID_HEVCF_P1_SEL] = &s4_hevcf_p1_mux.hw, + [CLKID_HEVCF_P1_SEL] = &s4_hevcf_p1_sel.hw, [CLKID_HEVCF_P1_DIV] = &s4_hevcf_p1_div.hw, [CLKID_HEVCF_P1] = &s4_hevcf_p1.hw, - [CLKID_HEVCF_SEL] = &s4_hevcf_mux.hw, + [CLKID_HEVCF_SEL] = &s4_hevcf_sel.hw, [CLKID_VPU_0_SEL] = &s4_vpu_0_sel.hw, [CLKID_VPU_0_DIV] = &s4_vpu_0_div.hw, [CLKID_VPU_0] = &s4_vpu_0.hw, @@ -3327,18 +2902,18 @@ static struct clk_hw *s4_periphs_hw_clks[] = { [CLKID_VPU_1_DIV] = &s4_vpu_1_div.hw, [CLKID_VPU_1] = &s4_vpu_1.hw, [CLKID_VPU] = &s4_vpu.hw, - [CLKID_VPU_CLKB_TMP_SEL] = &s4_vpu_clkb_tmp_mux.hw, + [CLKID_VPU_CLKB_TMP_SEL] = &s4_vpu_clkb_tmp_sel.hw, [CLKID_VPU_CLKB_TMP_DIV] = &s4_vpu_clkb_tmp_div.hw, [CLKID_VPU_CLKB_TMP] = &s4_vpu_clkb_tmp.hw, [CLKID_VPU_CLKB_DIV] = &s4_vpu_clkb_div.hw, [CLKID_VPU_CLKB] = &s4_vpu_clkb.hw, - [CLKID_VPU_CLKC_P0_SEL] = &s4_vpu_clkc_p0_mux.hw, + [CLKID_VPU_CLKC_P0_SEL] = &s4_vpu_clkc_p0_sel.hw, [CLKID_VPU_CLKC_P0_DIV] = &s4_vpu_clkc_p0_div.hw, [CLKID_VPU_CLKC_P0] = &s4_vpu_clkc_p0.hw, - [CLKID_VPU_CLKC_P1_SEL] = &s4_vpu_clkc_p1_mux.hw, + [CLKID_VPU_CLKC_P1_SEL] = &s4_vpu_clkc_p1_sel.hw, [CLKID_VPU_CLKC_P1_DIV] = &s4_vpu_clkc_p1_div.hw, [CLKID_VPU_CLKC_P1] = &s4_vpu_clkc_p1.hw, - [CLKID_VPU_CLKC_SEL] = &s4_vpu_clkc_mux.hw, + [CLKID_VPU_CLKC_SEL] = &s4_vpu_clkc_sel.hw, [CLKID_VAPB_0_SEL] = &s4_vapb_0_sel.hw, [CLKID_VAPB_0_DIV] = &s4_vapb_0_div.hw, [CLKID_VAPB_0] = &s4_vapb_0.hw, @@ -3346,10 +2921,10 @@ static struct clk_hw *s4_periphs_hw_clks[] = { [CLKID_VAPB_1_DIV] = &s4_vapb_1_div.hw, [CLKID_VAPB_1] = &s4_vapb_1.hw, [CLKID_VAPB] = &s4_vapb.hw, - [CLKID_GE2D] = &s4_ge2d_gate.hw, - [CLKID_VDIN_MEAS_SEL] = &s4_vdin_meas_mux.hw, + [CLKID_GE2D] = &s4_ge2d.hw, + [CLKID_VDIN_MEAS_SEL] = &s4_vdin_meas_sel.hw, [CLKID_VDIN_MEAS_DIV] = &s4_vdin_meas_div.hw, - [CLKID_VDIN_MEAS] = &s4_vdin_meas_gate.hw, + [CLKID_VDIN_MEAS] = &s4_vdin_meas.hw, [CLKID_SD_EMMC_C_CLK_SEL] = &s4_sd_emmc_c_clk0_sel.hw, [CLKID_SD_EMMC_C_CLK_DIV] = &s4_sd_emmc_c_clk0_div.hw, [CLKID_SD_EMMC_C] = &s4_sd_emmc_c_clk0.hw, @@ -3359,42 +2934,42 @@ static struct clk_hw *s4_periphs_hw_clks[] = { [CLKID_SD_EMMC_B_CLK_SEL] = &s4_sd_emmc_b_clk0_sel.hw, [CLKID_SD_EMMC_B_CLK_DIV] = &s4_sd_emmc_b_clk0_div.hw, [CLKID_SD_EMMC_B] = &s4_sd_emmc_b_clk0.hw, - [CLKID_SPICC0_SEL] = &s4_spicc0_mux.hw, + [CLKID_SPICC0_SEL] = &s4_spicc0_sel.hw, [CLKID_SPICC0_DIV] = &s4_spicc0_div.hw, - [CLKID_SPICC0_EN] = &s4_spicc0_gate.hw, - [CLKID_PWM_A_SEL] = &s4_pwm_a_mux.hw, + [CLKID_SPICC0_EN] = &s4_spicc0_en.hw, + [CLKID_PWM_A_SEL] = &s4_pwm_a_sel.hw, [CLKID_PWM_A_DIV] = &s4_pwm_a_div.hw, - [CLKID_PWM_A] = &s4_pwm_a_gate.hw, - [CLKID_PWM_B_SEL] = &s4_pwm_b_mux.hw, + [CLKID_PWM_A] = &s4_pwm_a.hw, + [CLKID_PWM_B_SEL] = &s4_pwm_b_sel.hw, [CLKID_PWM_B_DIV] = &s4_pwm_b_div.hw, - [CLKID_PWM_B] = &s4_pwm_b_gate.hw, - [CLKID_PWM_C_SEL] = &s4_pwm_c_mux.hw, + [CLKID_PWM_B] = &s4_pwm_b.hw, + [CLKID_PWM_C_SEL] = &s4_pwm_c_sel.hw, [CLKID_PWM_C_DIV] = &s4_pwm_c_div.hw, - [CLKID_PWM_C] = &s4_pwm_c_gate.hw, - [CLKID_PWM_D_SEL] = &s4_pwm_d_mux.hw, + [CLKID_PWM_C] = &s4_pwm_c.hw, + [CLKID_PWM_D_SEL] = &s4_pwm_d_sel.hw, [CLKID_PWM_D_DIV] = &s4_pwm_d_div.hw, - [CLKID_PWM_D] = &s4_pwm_d_gate.hw, - [CLKID_PWM_E_SEL] = &s4_pwm_e_mux.hw, + [CLKID_PWM_D] = &s4_pwm_d.hw, + [CLKID_PWM_E_SEL] = &s4_pwm_e_sel.hw, [CLKID_PWM_E_DIV] = &s4_pwm_e_div.hw, - [CLKID_PWM_E] = &s4_pwm_e_gate.hw, - [CLKID_PWM_F_SEL] = &s4_pwm_f_mux.hw, + [CLKID_PWM_E] = &s4_pwm_e.hw, + [CLKID_PWM_F_SEL] = &s4_pwm_f_sel.hw, [CLKID_PWM_F_DIV] = &s4_pwm_f_div.hw, - [CLKID_PWM_F] = &s4_pwm_f_gate.hw, - [CLKID_PWM_G_SEL] = &s4_pwm_g_mux.hw, + [CLKID_PWM_F] = &s4_pwm_f.hw, + [CLKID_PWM_G_SEL] = &s4_pwm_g_sel.hw, [CLKID_PWM_G_DIV] = &s4_pwm_g_div.hw, - [CLKID_PWM_G] = &s4_pwm_g_gate.hw, - [CLKID_PWM_H_SEL] = &s4_pwm_h_mux.hw, + [CLKID_PWM_G] = &s4_pwm_g.hw, + [CLKID_PWM_H_SEL] = &s4_pwm_h_sel.hw, [CLKID_PWM_H_DIV] = &s4_pwm_h_div.hw, - [CLKID_PWM_H] = &s4_pwm_h_gate.hw, - [CLKID_PWM_I_SEL] = &s4_pwm_i_mux.hw, + [CLKID_PWM_H] = &s4_pwm_h.hw, + [CLKID_PWM_I_SEL] = &s4_pwm_i_sel.hw, [CLKID_PWM_I_DIV] = &s4_pwm_i_div.hw, - [CLKID_PWM_I] = &s4_pwm_i_gate.hw, - [CLKID_PWM_J_SEL] = &s4_pwm_j_mux.hw, + [CLKID_PWM_I] = &s4_pwm_i.hw, + [CLKID_PWM_J_SEL] = &s4_pwm_j_sel.hw, [CLKID_PWM_J_DIV] = &s4_pwm_j_div.hw, - [CLKID_PWM_J] = &s4_pwm_j_gate.hw, - [CLKID_SARADC_SEL] = &s4_saradc_mux.hw, + [CLKID_PWM_J] = &s4_pwm_j.hw, + [CLKID_SARADC_SEL] = &s4_saradc_sel.hw, [CLKID_SARADC_DIV] = &s4_saradc_div.hw, - [CLKID_SARADC] = &s4_saradc_gate.hw, + [CLKID_SARADC] = &s4_saradc.hw, [CLKID_GEN_SEL] = &s4_gen_clk_sel.hw, [CLKID_GEN_DIV] = &s4_gen_clk_div.hw, [CLKID_GEN] = &s4_gen_clk.hw, @@ -3447,73 +3022,38 @@ static struct clk_hw *s4_periphs_hw_clks[] = { [CLKID_PWM_EF] = &s4_pwm_ef.hw, [CLKID_PWM_GH] = &s4_pwm_gh.hw, [CLKID_PWM_IJ] = &s4_pwm_ij.hw, - [CLKID_HDCP22_ESMCLK_SEL] = &s4_hdcp22_esmclk_mux.hw, + [CLKID_HDCP22_ESMCLK_SEL] = &s4_hdcp22_esmclk_sel.hw, [CLKID_HDCP22_ESMCLK_DIV] = &s4_hdcp22_esmclk_div.hw, - [CLKID_HDCP22_ESMCLK] = &s4_hdcp22_esmclk_gate.hw, - [CLKID_HDCP22_SKPCLK_SEL] = &s4_hdcp22_skpclk_mux.hw, + [CLKID_HDCP22_ESMCLK] = &s4_hdcp22_esmclk.hw, + [CLKID_HDCP22_SKPCLK_SEL] = &s4_hdcp22_skpclk_sel.hw, [CLKID_HDCP22_SKPCLK_DIV] = &s4_hdcp22_skpclk_div.hw, - [CLKID_HDCP22_SKPCLK] = &s4_hdcp22_skpclk_gate.hw, -}; - -static const struct regmap_config clkc_regmap_config = { - .reg_bits = 32, - .val_bits = 32, - .reg_stride = 4, - .max_register = CLKCTRL_DEMOD_CLK_CTRL, + [CLKID_HDCP22_SKPCLK] = &s4_hdcp22_skpclk.hw, }; -static struct meson_clk_hw_data s4_periphs_clks = { - .hws = s4_periphs_hw_clks, - .num = ARRAY_SIZE(s4_periphs_hw_clks), +static const struct meson_clkc_data s4_peripherals_clkc_data = { + .hw_clks = { + .hws = s4_peripherals_hw_clks, + .num = ARRAY_SIZE(s4_peripherals_hw_clks), + }, }; -static int meson_s4_periphs_probe(struct platform_device *pdev) -{ - struct device *dev = &pdev->dev; - struct regmap *regmap; - void __iomem *base; - int ret, i; - - base = devm_platform_ioremap_resource(pdev, 0); - if (IS_ERR(base)) - return dev_err_probe(dev, PTR_ERR(base), - "can't ioremap resource\n"); - - regmap = devm_regmap_init_mmio(dev, base, &clkc_regmap_config); - if (IS_ERR(regmap)) - return dev_err_probe(dev, PTR_ERR(regmap), - "can't init regmap mmio region\n"); - - for (i = 0; i < s4_periphs_clks.num; i++) { - /* array might be sparse */ - if (!s4_periphs_clks.hws[i]) - continue; - - ret = devm_clk_hw_register(dev, s4_periphs_clks.hws[i]); - if (ret) - return dev_err_probe(dev, ret, - "clock[%d] registration failed\n", i); - } - - return devm_of_clk_add_hw_provider(dev, meson_clk_hw_get, &s4_periphs_clks); -} - -static const struct of_device_id clkc_match_table[] = { +static const struct of_device_id s4_peripherals_clkc_match_table[] = { { .compatible = "amlogic,s4-peripherals-clkc", + .data = &s4_peripherals_clkc_data, }, {} }; -MODULE_DEVICE_TABLE(of, clkc_match_table); +MODULE_DEVICE_TABLE(of, s4_peripherals_clkc_match_table); -static struct platform_driver s4_driver = { - .probe = meson_s4_periphs_probe, +static struct platform_driver s4_peripherals_clkc_driver = { + .probe = meson_clkc_mmio_probe, .driver = { - .name = "s4-periphs-clkc", - .of_match_table = clkc_match_table, + .name = "s4-peripherals-clkc", + .of_match_table = s4_peripherals_clkc_match_table, }, }; -module_platform_driver(s4_driver); +module_platform_driver(s4_peripherals_clkc_driver); MODULE_DESCRIPTION("Amlogic S4 Peripherals Clock Controller driver"); MODULE_AUTHOR("Yu Tu <yu.tu@amlogic.com>"); diff --git a/drivers/clk/meson/s4-pll.c b/drivers/clk/meson/s4-pll.c index 3d689d2f003e..56ce6f566e53 100644 --- a/drivers/clk/meson/s4-pll.c +++ b/drivers/clk/meson/s4-pll.c @@ -281,7 +281,7 @@ static const struct pll_mult_range s4_gp0_pll_mult_range = { /* * Internal gp0 pll emulation configuration parameters */ -static const struct reg_sequence s4_gp0_init_regs[] = { +static const struct reg_sequence s4_gp0_pll_init_regs[] = { { .reg = ANACTRL_GP0PLL_CTRL1, .def = 0x00000000 }, { .reg = ANACTRL_GP0PLL_CTRL2, .def = 0x00000000 }, { .reg = ANACTRL_GP0PLL_CTRL3, .def = 0x48681c00 }, @@ -318,8 +318,8 @@ static struct clk_regmap s4_gp0_pll_dco = { .width = 1, }, .range = &s4_gp0_pll_mult_range, - .init_regs = s4_gp0_init_regs, - .init_count = ARRAY_SIZE(s4_gp0_init_regs), + .init_regs = s4_gp0_pll_init_regs, + .init_count = ARRAY_SIZE(s4_gp0_pll_init_regs), }, .hw.init = &(struct clk_init_data){ .name = "gp0_pll_dco", @@ -353,7 +353,7 @@ static struct clk_regmap s4_gp0_pll = { /* * Internal hifi pll emulation configuration parameters */ -static const struct reg_sequence s4_hifi_init_regs[] = { +static const struct reg_sequence s4_hifi_pll_init_regs[] = { { .reg = ANACTRL_HIFIPLL_CTRL2, .def = 0x00000000 }, { .reg = ANACTRL_HIFIPLL_CTRL3, .def = 0x6a285c00 }, { .reg = ANACTRL_HIFIPLL_CTRL4, .def = 0x65771290 }, @@ -394,8 +394,8 @@ static struct clk_regmap s4_hifi_pll_dco = { .width = 1, }, .range = &s4_gp0_pll_mult_range, - .init_regs = s4_hifi_init_regs, - .init_count = ARRAY_SIZE(s4_hifi_init_regs), + .init_regs = s4_hifi_pll_init_regs, + .init_count = ARRAY_SIZE(s4_hifi_pll_init_regs), .frac_max = 100000, .flags = CLK_MESON_PLL_ROUND_CLOSEST, }, @@ -794,76 +794,36 @@ static struct clk_hw *s4_pll_hw_clks[] = { [CLKID_MPLL3] = &s4_mpll3.hw, }; -static const struct reg_sequence s4_init_regs[] = { +static const struct reg_sequence s4_pll_init_regs[] = { { .reg = ANACTRL_MPLL_CTRL0, .def = 0x00000543 }, }; -static const struct regmap_config clkc_regmap_config = { - .reg_bits = 32, - .val_bits = 32, - .reg_stride = 4, - .max_register = ANACTRL_HDMIPLL_CTRL0, -}; - -static struct meson_clk_hw_data s4_pll_clks = { - .hws = s4_pll_hw_clks, - .num = ARRAY_SIZE(s4_pll_hw_clks), +static const struct meson_clkc_data s4_pll_clkc_data = { + .hw_clks = { + .hws = s4_pll_hw_clks, + .num = ARRAY_SIZE(s4_pll_hw_clks), + }, + .init_regs = s4_pll_init_regs, + .init_count = ARRAY_SIZE(s4_pll_init_regs), }; -static int meson_s4_pll_probe(struct platform_device *pdev) -{ - struct device *dev = &pdev->dev; - struct regmap *regmap; - void __iomem *base; - int ret, i; - - base = devm_platform_ioremap_resource(pdev, 0); - if (IS_ERR(base)) - return dev_err_probe(dev, PTR_ERR(base), - "can't ioremap resource\n"); - - regmap = devm_regmap_init_mmio(dev, base, &clkc_regmap_config); - if (IS_ERR(regmap)) - return dev_err_probe(dev, PTR_ERR(regmap), - "can't init regmap mmio region\n"); - - ret = regmap_multi_reg_write(regmap, s4_init_regs, ARRAY_SIZE(s4_init_regs)); - if (ret) - return dev_err_probe(dev, ret, - "Failed to init registers\n"); - - /* Register clocks */ - for (i = 0; i < s4_pll_clks.num; i++) { - /* array might be sparse */ - if (!s4_pll_clks.hws[i]) - continue; - - ret = devm_clk_hw_register(dev, s4_pll_clks.hws[i]); - if (ret) - return dev_err_probe(dev, ret, - "clock[%d] registration failed\n", i); - } - - return devm_of_clk_add_hw_provider(dev, meson_clk_hw_get, - &s4_pll_clks); -} - -static const struct of_device_id clkc_match_table[] = { +static const struct of_device_id s4_pll_clkc_match_table[] = { { .compatible = "amlogic,s4-pll-clkc", + .data = &s4_pll_clkc_data, }, {} }; -MODULE_DEVICE_TABLE(of, clkc_match_table); +MODULE_DEVICE_TABLE(of, s4_pll_clkc_match_table); -static struct platform_driver s4_driver = { - .probe = meson_s4_pll_probe, +static struct platform_driver s4_pll_clkc_driver = { + .probe = meson_clkc_mmio_probe, .driver = { .name = "s4-pll-clkc", - .of_match_table = clkc_match_table, + .of_match_table = s4_pll_clkc_match_table, }, }; -module_platform_driver(s4_driver); +module_platform_driver(s4_pll_clkc_driver); MODULE_DESCRIPTION("Amlogic S4 PLL Clock Controller driver"); MODULE_AUTHOR("Yu Tu <yu.tu@amlogic.com>"); diff --git a/drivers/clk/microchip/clk-core.c b/drivers/clk/microchip/clk-core.c index 6fbc6dc50ca3..b34348d491f3 100644 --- a/drivers/clk/microchip/clk-core.c +++ b/drivers/clk/microchip/clk-core.c @@ -155,11 +155,13 @@ static unsigned long pbclk_recalc_rate(struct clk_hw *hw, return parent_rate / pbclk_read_pbdiv(pb); } -static long pbclk_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *parent_rate) +static int pbclk_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { - return calc_best_divided_rate(rate, *parent_rate, - PB_DIV_MAX, PB_DIV_MIN); + req->rate = calc_best_divided_rate(req->rate, req->best_parent_rate, + PB_DIV_MAX, PB_DIV_MIN); + + return 0; } static int pbclk_set_rate(struct clk_hw *hw, unsigned long rate, @@ -207,7 +209,7 @@ const struct clk_ops pic32_pbclk_ops = { .disable = pbclk_disable, .is_enabled = pbclk_is_enabled, .recalc_rate = pbclk_recalc_rate, - .round_rate = pbclk_round_rate, + .determine_rate = pbclk_determine_rate, .set_rate = pbclk_set_rate, }; @@ -372,18 +374,6 @@ static unsigned long roclk_recalc_rate(struct clk_hw *hw, return roclk_calc_rate(parent_rate, rodiv, rotrim); } -static long roclk_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *parent_rate) -{ - u32 rotrim, rodiv; - - /* calculate dividers for new rate */ - roclk_calc_div_trim(rate, *parent_rate, &rodiv, &rotrim); - - /* caclulate new rate (rounding) based on new rodiv & rotrim */ - return roclk_calc_rate(*parent_rate, rodiv, rotrim); -} - static int roclk_determine_rate(struct clk_hw *hw, struct clk_rate_request *req) { @@ -394,6 +384,8 @@ static int roclk_determine_rate(struct clk_hw *hw, /* find a parent which can generate nearest clkrate >= rate */ for (i = 0; i < clk_hw_get_num_parents(hw); i++) { + u32 rotrim, rodiv; + /* get parent */ parent_clk = clk_hw_get_parent_by_index(hw, i); if (!parent_clk) @@ -404,7 +396,12 @@ static int roclk_determine_rate(struct clk_hw *hw, if (req->rate > parent_rate) continue; - nearest_rate = roclk_round_rate(hw, req->rate, &parent_rate); + /* calculate dividers for new rate */ + roclk_calc_div_trim(req->rate, req->best_parent_rate, &rodiv, &rotrim); + + /* caclulate new rate (rounding) based on new rodiv & rotrim */ + nearest_rate = roclk_calc_rate(req->best_parent_rate, rodiv, rotrim); + delta = abs(nearest_rate - req->rate); if ((nearest_rate >= req->rate) && (delta < best_delta)) { best_parent_clk = parent_clk; @@ -665,12 +662,15 @@ static unsigned long spll_clk_recalc_rate(struct clk_hw *hw, return rate64; } -static long spll_clk_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *parent_rate) +static int spll_clk_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { struct pic32_sys_pll *pll = clkhw_to_spll(hw); - return spll_calc_mult_div(pll, rate, *parent_rate, NULL, NULL); + req->rate = spll_calc_mult_div(pll, req->rate, req->best_parent_rate, + NULL, NULL); + + return 0; } static int spll_clk_set_rate(struct clk_hw *hw, unsigned long rate, @@ -725,7 +725,7 @@ static int spll_clk_set_rate(struct clk_hw *hw, unsigned long rate, /* SPLL clock operation */ const struct clk_ops pic32_spll_ops = { .recalc_rate = spll_clk_recalc_rate, - .round_rate = spll_clk_round_rate, + .determine_rate = spll_clk_determine_rate, .set_rate = spll_clk_set_rate, }; @@ -780,10 +780,13 @@ static unsigned long sclk_get_rate(struct clk_hw *hw, unsigned long parent_rate) return parent_rate / div; } -static long sclk_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *parent_rate) +static int sclk_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { - return calc_best_divided_rate(rate, *parent_rate, SLEW_SYSDIV, 1); + req->rate = calc_best_divided_rate(req->rate, req->best_parent_rate, + SLEW_SYSDIV, 1); + + return 0; } static int sclk_set_rate(struct clk_hw *hw, @@ -909,7 +912,7 @@ static int sclk_init(struct clk_hw *hw) const struct clk_ops pic32_sclk_ops = { .get_parent = sclk_get_parent, .set_parent = sclk_set_parent, - .round_rate = sclk_round_rate, + .determine_rate = sclk_determine_rate, .set_rate = sclk_set_rate, .recalc_rate = sclk_get_rate, .init = sclk_init, diff --git a/drivers/clk/mmp/Kconfig b/drivers/clk/mmp/Kconfig new file mode 100644 index 000000000000..b0d2fea3cda5 --- /dev/null +++ b/drivers/clk/mmp/Kconfig @@ -0,0 +1,10 @@ +# SPDX-License-Identifier: GPL-2.0-only + +config COMMON_CLK_PXA1908 + bool "Clock driver for Marvell PXA1908" + depends on ARCH_MMP || COMPILE_TEST + depends on OF + default y if ARCH_MMP && ARM64 + select AUXILIARY_BUS + help + This driver supports the Marvell PXA1908 SoC clocks. diff --git a/drivers/clk/mmp/Makefile b/drivers/clk/mmp/Makefile index 062cd87fa8dd..0a94f2f08563 100644 --- a/drivers/clk/mmp/Makefile +++ b/drivers/clk/mmp/Makefile @@ -11,4 +11,7 @@ obj-$(CONFIG_MACH_MMP_DT) += clk-of-pxa168.o clk-of-pxa910.o obj-$(CONFIG_COMMON_CLK_MMP2) += clk-of-mmp2.o clk-pll.o pwr-island.o obj-$(CONFIG_COMMON_CLK_MMP2_AUDIO) += clk-audio.o -obj-$(CONFIG_ARCH_MMP) += clk-of-pxa1928.o clk-pxa1908-apbc.o clk-pxa1908-apbcp.o clk-pxa1908-apmu.o clk-pxa1908-mpmu.o +obj-$(CONFIG_COMMON_CLK_PXA1908) += clk-pxa1908-apbc.o clk-pxa1908-apbcp.o \ + clk-pxa1908-mpmu.o clk-pxa1908-apmu.o + +obj-$(CONFIG_ARCH_MMP) += clk-of-pxa1928.o diff --git a/drivers/clk/mmp/clk-audio.c b/drivers/clk/mmp/clk-audio.c index 88d798d510cd..ed27fc796c94 100644 --- a/drivers/clk/mmp/clk-audio.c +++ b/drivers/clk/mmp/clk-audio.c @@ -164,23 +164,23 @@ static unsigned long audio_pll_recalc_rate(struct clk_hw *hw, return 0; } -static long audio_pll_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *parent_rate) +static int audio_pll_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { unsigned int prediv; unsigned int postdiv; long rounded = 0; for (prediv = 0; prediv < ARRAY_SIZE(predivs); prediv++) { - if (predivs[prediv].parent_rate != *parent_rate) + if (predivs[prediv].parent_rate != req->best_parent_rate) continue; for (postdiv = 0; postdiv < ARRAY_SIZE(postdivs); postdiv++) { long freq = predivs[prediv].freq_vco; freq /= postdivs[postdiv].divisor; - if (freq == rate) - return rate; - if (freq < rate) + if (freq == req->rate) + return 0; + if (freq < req->rate) continue; if (rounded && freq > rounded) continue; @@ -188,7 +188,9 @@ static long audio_pll_round_rate(struct clk_hw *hw, unsigned long rate, } } - return rounded; + req->rate = rounded; + + return 0; } static int audio_pll_set_rate(struct clk_hw *hw, unsigned long rate, @@ -228,7 +230,7 @@ static int audio_pll_set_rate(struct clk_hw *hw, unsigned long rate, static const struct clk_ops audio_pll_ops = { .recalc_rate = audio_pll_recalc_rate, - .round_rate = audio_pll_round_rate, + .determine_rate = audio_pll_determine_rate, .set_rate = audio_pll_set_rate, }; diff --git a/drivers/clk/mmp/clk-frac.c b/drivers/clk/mmp/clk-frac.c index 6556f6ada2e8..0b1bb01346f0 100644 --- a/drivers/clk/mmp/clk-frac.c +++ b/drivers/clk/mmp/clk-frac.c @@ -21,8 +21,8 @@ #define to_clk_factor(hw) container_of(hw, struct mmp_clk_factor, hw) -static long clk_factor_round_rate(struct clk_hw *hw, unsigned long drate, - unsigned long *prate) +static int clk_factor_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { struct mmp_clk_factor *factor = to_clk_factor(hw); u64 rate = 0, prev_rate; @@ -33,19 +33,20 @@ static long clk_factor_round_rate(struct clk_hw *hw, unsigned long drate, d = &factor->ftbl[i]; prev_rate = rate; - rate = (u64)(*prate) * d->denominator; + rate = (u64)(req->best_parent_rate) * d->denominator; do_div(rate, d->numerator * factor->masks->factor); - if (rate > drate) + if (rate > req->rate) break; } - if ((i == 0) || (i == factor->ftbl_cnt)) { - return rate; - } else { - if ((drate - prev_rate) > (rate - drate)) - return rate; - else - return prev_rate; - } + + if ((i == 0) || (i == factor->ftbl_cnt)) + req->rate = rate; + else if ((req->rate - prev_rate) > (rate - req->rate)) + req->rate = rate; + else + req->rate = prev_rate; + + return 0; } static unsigned long clk_factor_recalc_rate(struct clk_hw *hw, @@ -160,7 +161,7 @@ static int clk_factor_init(struct clk_hw *hw) static const struct clk_ops clk_factor_ops = { .recalc_rate = clk_factor_recalc_rate, - .round_rate = clk_factor_round_rate, + .determine_rate = clk_factor_determine_rate, .set_rate = clk_factor_set_rate, .init = clk_factor_init, }; diff --git a/drivers/clk/mmp/clk-pxa1908-apmu.c b/drivers/clk/mmp/clk-pxa1908-apmu.c index d3a070687fc5..7594a495a009 100644 --- a/drivers/clk/mmp/clk-pxa1908-apmu.c +++ b/drivers/clk/mmp/clk-pxa1908-apmu.c @@ -1,4 +1,5 @@ // SPDX-License-Identifier: GPL-2.0-only +#include <linux/auxiliary_bus.h> #include <linux/clk-provider.h> #include <linux/module.h> #include <linux/platform_device.h> @@ -85,6 +86,7 @@ static void pxa1908_axi_periph_clk_init(struct pxa1908_clk_unit *pxa_unit) static int pxa1908_apmu_probe(struct platform_device *pdev) { struct pxa1908_clk_unit *pxa_unit; + struct auxiliary_device *adev; pxa_unit = devm_kzalloc(&pdev->dev, sizeof(*pxa_unit), GFP_KERNEL); if (!pxa_unit) @@ -94,6 +96,11 @@ static int pxa1908_apmu_probe(struct platform_device *pdev) if (IS_ERR(pxa_unit->base)) return PTR_ERR(pxa_unit->base); + adev = devm_auxiliary_device_create(&pdev->dev, "power", NULL); + if (IS_ERR(adev)) + return dev_err_probe(&pdev->dev, PTR_ERR(adev), + "Failed to register power controller\n"); + mmp_clk_init(pdev->dev.of_node, &pxa_unit->unit, APMU_NR_CLKS); pxa1908_axi_periph_clk_init(pxa_unit); diff --git a/drivers/clk/mstar/clk-msc313-cpupll.c b/drivers/clk/mstar/clk-msc313-cpupll.c index a93e2dba09d3..3e643be02fe2 100644 --- a/drivers/clk/mstar/clk-msc313-cpupll.c +++ b/drivers/clk/mstar/clk-msc313-cpupll.c @@ -140,20 +140,22 @@ static unsigned long msc313_cpupll_recalc_rate(struct clk_hw *hw, unsigned long parent_rate); } -static long msc313_cpupll_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *parent_rate) +static int msc313_cpupll_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { - u32 reg = msc313_cpupll_regforfrequecy(rate, *parent_rate); - long rounded = msc313_cpupll_frequencyforreg(reg, *parent_rate); + u32 reg = msc313_cpupll_regforfrequecy(req->rate, req->best_parent_rate); + long rounded = msc313_cpupll_frequencyforreg(reg, req->best_parent_rate); /* * This is my poor attempt at making sure the resulting * rate doesn't overshoot the requested rate. */ - for (; rounded >= rate && reg > 0; reg--) - rounded = msc313_cpupll_frequencyforreg(reg, *parent_rate); + for (; rounded >= req->rate && reg > 0; reg--) + rounded = msc313_cpupll_frequencyforreg(reg, req->best_parent_rate); - return rounded; + req->rate = rounded; + + return 0; } static int msc313_cpupll_set_rate(struct clk_hw *hw, unsigned long rate, unsigned long parent_rate) @@ -168,7 +170,7 @@ static int msc313_cpupll_set_rate(struct clk_hw *hw, unsigned long rate, unsigne static const struct clk_ops msc313_cpupll_ops = { .recalc_rate = msc313_cpupll_recalc_rate, - .round_rate = msc313_cpupll_round_rate, + .determine_rate = msc313_cpupll_determine_rate, .set_rate = msc313_cpupll_set_rate, }; diff --git a/drivers/clk/mvebu/ap-cpu-clk.c b/drivers/clk/mvebu/ap-cpu-clk.c index 677cc3514849..1e44ace7d951 100644 --- a/drivers/clk/mvebu/ap-cpu-clk.c +++ b/drivers/clk/mvebu/ap-cpu-clk.c @@ -210,19 +210,21 @@ static int ap_cpu_clk_set_rate(struct clk_hw *hw, unsigned long rate, return 0; } -static long ap_cpu_clk_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *parent_rate) +static int ap_cpu_clk_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { - int divider = *parent_rate / rate; + int divider = req->best_parent_rate / req->rate; divider = min(divider, APN806_MAX_DIVIDER); - return *parent_rate / divider; + req->rate = req->best_parent_rate / divider; + + return 0; } static const struct clk_ops ap_cpu_clk_ops = { .recalc_rate = ap_cpu_clk_recalc_rate, - .round_rate = ap_cpu_clk_round_rate, + .determine_rate = ap_cpu_clk_determine_rate, .set_rate = ap_cpu_clk_set_rate, }; diff --git a/drivers/clk/mvebu/armada-37xx-periph.c b/drivers/clk/mvebu/armada-37xx-periph.c index 13906e31bef8..bd0bc8e7b1e7 100644 --- a/drivers/clk/mvebu/armada-37xx-periph.c +++ b/drivers/clk/mvebu/armada-37xx-periph.c @@ -454,12 +454,12 @@ static unsigned long clk_pm_cpu_recalc_rate(struct clk_hw *hw, return DIV_ROUND_UP_ULL((u64)parent_rate, div); } -static long clk_pm_cpu_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *parent_rate) +static int clk_pm_cpu_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { struct clk_pm_cpu *pm_cpu = to_clk_pm_cpu(hw); struct regmap *base = pm_cpu->nb_pm_base; - unsigned int div = *parent_rate / rate; + unsigned int div = req->best_parent_rate / req->rate; unsigned int load_level; /* only available when DVFS is enabled */ if (!armada_3700_pm_dvfs_is_enabled(base)) @@ -474,13 +474,16 @@ static long clk_pm_cpu_round_rate(struct clk_hw *hw, unsigned long rate, val >>= offset; val &= ARMADA_37XX_NB_TBG_DIV_MASK; - if (val == div) + if (val == div) { /* * We found a load level matching the target * divider, switch to this load level and * return. */ - return *parent_rate / div; + req->rate = req->best_parent_rate / div; + + return 0; + } } /* We didn't find any valid divider */ @@ -600,7 +603,7 @@ static int clk_pm_cpu_set_rate(struct clk_hw *hw, unsigned long rate, static const struct clk_ops clk_pm_cpu_ops = { .get_parent = clk_pm_cpu_get_parent, - .round_rate = clk_pm_cpu_round_rate, + .determine_rate = clk_pm_cpu_determine_rate, .set_rate = clk_pm_cpu_set_rate, .recalc_rate = clk_pm_cpu_recalc_rate, }; diff --git a/drivers/clk/mvebu/clk-corediv.c b/drivers/clk/mvebu/clk-corediv.c index 818b175391fa..628032341cbb 100644 --- a/drivers/clk/mvebu/clk-corediv.c +++ b/drivers/clk/mvebu/clk-corediv.c @@ -135,19 +135,21 @@ static unsigned long clk_corediv_recalc_rate(struct clk_hw *hwclk, return parent_rate / div; } -static long clk_corediv_round_rate(struct clk_hw *hwclk, unsigned long rate, - unsigned long *parent_rate) +static int clk_corediv_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { /* Valid ratio are 1:4, 1:5, 1:6 and 1:8 */ u32 div; - div = *parent_rate / rate; + div = req->best_parent_rate / req->rate; if (div < 4) div = 4; else if (div > 6) div = 8; - return *parent_rate / div; + req->rate = req->best_parent_rate / div; + + return 0; } static int clk_corediv_set_rate(struct clk_hw *hwclk, unsigned long rate, @@ -199,7 +201,7 @@ static const struct clk_corediv_soc_desc armada370_corediv_soc = { .disable = clk_corediv_disable, .is_enabled = clk_corediv_is_enabled, .recalc_rate = clk_corediv_recalc_rate, - .round_rate = clk_corediv_round_rate, + .determine_rate = clk_corediv_determine_rate, .set_rate = clk_corediv_set_rate, }, .ratio_reload = BIT(8), @@ -215,7 +217,7 @@ static const struct clk_corediv_soc_desc armada380_corediv_soc = { .disable = clk_corediv_disable, .is_enabled = clk_corediv_is_enabled, .recalc_rate = clk_corediv_recalc_rate, - .round_rate = clk_corediv_round_rate, + .determine_rate = clk_corediv_determine_rate, .set_rate = clk_corediv_set_rate, }, .ratio_reload = BIT(8), @@ -228,7 +230,7 @@ static const struct clk_corediv_soc_desc armada375_corediv_soc = { .ndescs = ARRAY_SIZE(mvebu_corediv_desc), .ops = { .recalc_rate = clk_corediv_recalc_rate, - .round_rate = clk_corediv_round_rate, + .determine_rate = clk_corediv_determine_rate, .set_rate = clk_corediv_set_rate, }, .ratio_reload = BIT(8), @@ -240,7 +242,7 @@ static const struct clk_corediv_soc_desc mv98dx3236_corediv_soc = { .ndescs = ARRAY_SIZE(mv98dx3236_corediv_desc), .ops = { .recalc_rate = clk_corediv_recalc_rate, - .round_rate = clk_corediv_round_rate, + .determine_rate = clk_corediv_determine_rate, .set_rate = clk_corediv_set_rate, }, .ratio_reload = BIT(10), diff --git a/drivers/clk/mvebu/clk-cpu.c b/drivers/clk/mvebu/clk-cpu.c index db2b38c21304..0de7660e73d2 100644 --- a/drivers/clk/mvebu/clk-cpu.c +++ b/drivers/clk/mvebu/clk-cpu.c @@ -56,19 +56,21 @@ static unsigned long clk_cpu_recalc_rate(struct clk_hw *hwclk, return parent_rate / div; } -static long clk_cpu_round_rate(struct clk_hw *hwclk, unsigned long rate, - unsigned long *parent_rate) +static int clk_cpu_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { /* Valid ratio are 1:1, 1:2 and 1:3 */ u32 div; - div = *parent_rate / rate; + div = req->best_parent_rate / req->rate; if (div == 0) div = 1; else if (div > 3) div = 3; - return *parent_rate / div; + req->rate = req->best_parent_rate / div; + + return 0; } static int clk_cpu_off_set_rate(struct clk_hw *hwclk, unsigned long rate, @@ -159,7 +161,7 @@ static int clk_cpu_set_rate(struct clk_hw *hwclk, unsigned long rate, static const struct clk_ops cpu_ops = { .recalc_rate = clk_cpu_recalc_rate, - .round_rate = clk_cpu_round_rate, + .determine_rate = clk_cpu_determine_rate, .set_rate = clk_cpu_set_rate, }; diff --git a/drivers/clk/mvebu/dove-divider.c b/drivers/clk/mvebu/dove-divider.c index 0a90452ee808..47cc49e4cd99 100644 --- a/drivers/clk/mvebu/dove-divider.c +++ b/drivers/clk/mvebu/dove-divider.c @@ -108,23 +108,23 @@ static unsigned long dove_recalc_rate(struct clk_hw *hw, unsigned long parent) return rate; } -static long dove_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *parent) +static int dove_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { struct dove_clk *dc = to_dove_clk(hw); - unsigned long parent_rate = *parent; + unsigned long parent_rate = req->best_parent_rate; int divider; - divider = dove_calc_divider(dc, rate, parent_rate, false); + divider = dove_calc_divider(dc, req->rate, parent_rate, false); if (divider < 0) return divider; - rate = DIV_ROUND_CLOSEST(parent_rate, divider); + req->rate = DIV_ROUND_CLOSEST(parent_rate, divider); pr_debug("%s(): %s divider=%u parent=%lu rate=%lu\n", - __func__, dc->name, divider, parent_rate, rate); + __func__, dc->name, divider, parent_rate, req->rate); - return rate; + return 0; } static int dove_set_clock(struct clk_hw *hw, unsigned long rate, @@ -154,7 +154,7 @@ static int dove_set_clock(struct clk_hw *hw, unsigned long rate, static const struct clk_ops dove_divider_ops = { .set_rate = dove_set_clock, - .round_rate = dove_round_rate, + .determine_rate = dove_determine_rate, .recalc_rate = dove_recalc_rate, }; diff --git a/drivers/clk/mxs/clk-div.c b/drivers/clk/mxs/clk-div.c index 0a78ef380646..8afe1a9c1552 100644 --- a/drivers/clk/mxs/clk-div.c +++ b/drivers/clk/mxs/clk-div.c @@ -40,12 +40,12 @@ static unsigned long clk_div_recalc_rate(struct clk_hw *hw, return div->ops->recalc_rate(&div->divider.hw, parent_rate); } -static long clk_div_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *prate) +static int clk_div_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { struct clk_div *div = to_clk_div(hw); - return div->ops->round_rate(&div->divider.hw, rate, prate); + return div->ops->determine_rate(&div->divider.hw, req); } static int clk_div_set_rate(struct clk_hw *hw, unsigned long rate, @@ -63,7 +63,7 @@ static int clk_div_set_rate(struct clk_hw *hw, unsigned long rate, static const struct clk_ops clk_div_ops = { .recalc_rate = clk_div_recalc_rate, - .round_rate = clk_div_round_rate, + .determine_rate = clk_div_determine_rate, .set_rate = clk_div_set_rate, }; diff --git a/drivers/clk/mxs/clk-frac.c b/drivers/clk/mxs/clk-frac.c index bba0d840dd76..73f514fb84ff 100644 --- a/drivers/clk/mxs/clk-frac.c +++ b/drivers/clk/mxs/clk-frac.c @@ -44,18 +44,18 @@ static unsigned long clk_frac_recalc_rate(struct clk_hw *hw, return tmp_rate >> frac->width; } -static long clk_frac_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *prate) +static int clk_frac_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { struct clk_frac *frac = to_clk_frac(hw); - unsigned long parent_rate = *prate; + unsigned long parent_rate = req->best_parent_rate; u32 div; u64 tmp, tmp_rate, result; - if (rate > parent_rate) + if (req->rate > parent_rate) return -EINVAL; - tmp = rate; + tmp = req->rate; tmp <<= frac->width; do_div(tmp, parent_rate); div = tmp; @@ -67,7 +67,9 @@ static long clk_frac_round_rate(struct clk_hw *hw, unsigned long rate, result = tmp_rate >> frac->width; if ((result << frac->width) < tmp_rate) result += 1; - return result; + req->rate = result; + + return 0; } static int clk_frac_set_rate(struct clk_hw *hw, unsigned long rate, @@ -103,7 +105,7 @@ static int clk_frac_set_rate(struct clk_hw *hw, unsigned long rate, static const struct clk_ops clk_frac_ops = { .recalc_rate = clk_frac_recalc_rate, - .round_rate = clk_frac_round_rate, + .determine_rate = clk_frac_determine_rate, .set_rate = clk_frac_set_rate, }; diff --git a/drivers/clk/mxs/clk-ref.c b/drivers/clk/mxs/clk-ref.c index 2297259da89a..a99ee4cd2ece 100644 --- a/drivers/clk/mxs/clk-ref.c +++ b/drivers/clk/mxs/clk-ref.c @@ -57,22 +57,24 @@ static unsigned long clk_ref_recalc_rate(struct clk_hw *hw, return tmp; } -static long clk_ref_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *prate) +static int clk_ref_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { - unsigned long parent_rate = *prate; + unsigned long parent_rate = req->best_parent_rate; u64 tmp = parent_rate; u8 frac; - tmp = tmp * 18 + rate / 2; - do_div(tmp, rate); + tmp = tmp * 18 + req->rate / 2; + do_div(tmp, req->rate); frac = clamp(tmp, 18, 35); tmp = parent_rate; tmp *= 18; do_div(tmp, frac); - return tmp; + req->rate = tmp; + + return 0; } static int clk_ref_set_rate(struct clk_hw *hw, unsigned long rate, @@ -104,7 +106,7 @@ static const struct clk_ops clk_ref_ops = { .enable = clk_ref_enable, .disable = clk_ref_disable, .recalc_rate = clk_ref_recalc_rate, - .round_rate = clk_ref_round_rate, + .determine_rate = clk_ref_determine_rate, .set_rate = clk_ref_set_rate, }; diff --git a/drivers/clk/nuvoton/clk-ma35d1-divider.c b/drivers/clk/nuvoton/clk-ma35d1-divider.c index bb8c23d2b895..e39f53d5bf45 100644 --- a/drivers/clk/nuvoton/clk-ma35d1-divider.c +++ b/drivers/clk/nuvoton/clk-ma35d1-divider.c @@ -39,12 +39,16 @@ static unsigned long ma35d1_clkdiv_recalc_rate(struct clk_hw *hw, unsigned long CLK_DIVIDER_ROUND_CLOSEST, dclk->width); } -static long ma35d1_clkdiv_round_rate(struct clk_hw *hw, unsigned long rate, unsigned long *prate) +static int ma35d1_clkdiv_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { struct ma35d1_adc_clk_div *dclk = to_ma35d1_adc_clk_div(hw); - return divider_round_rate(hw, rate, prate, dclk->table, - dclk->width, CLK_DIVIDER_ROUND_CLOSEST); + req->rate = divider_round_rate(hw, req->rate, &req->best_parent_rate, + dclk->table, dclk->width, + CLK_DIVIDER_ROUND_CLOSEST); + + return 0; } static int ma35d1_clkdiv_set_rate(struct clk_hw *hw, unsigned long rate, unsigned long parent_rate) @@ -71,7 +75,7 @@ static int ma35d1_clkdiv_set_rate(struct clk_hw *hw, unsigned long rate, unsigne static const struct clk_ops ma35d1_adc_clkdiv_ops = { .recalc_rate = ma35d1_clkdiv_recalc_rate, - .round_rate = ma35d1_clkdiv_round_rate, + .determine_rate = ma35d1_clkdiv_determine_rate, .set_rate = ma35d1_clkdiv_set_rate, }; diff --git a/drivers/clk/nuvoton/clk-ma35d1-pll.c b/drivers/clk/nuvoton/clk-ma35d1-pll.c index ff3fb8b87c24..4620acfe47e8 100644 --- a/drivers/clk/nuvoton/clk-ma35d1-pll.c +++ b/drivers/clk/nuvoton/clk-ma35d1-pll.c @@ -244,35 +244,43 @@ static unsigned long ma35d1_clk_pll_recalc_rate(struct clk_hw *hw, unsigned long return 0; } -static long ma35d1_clk_pll_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *parent_rate) +static int ma35d1_clk_pll_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { struct ma35d1_clk_pll *pll = to_ma35d1_clk_pll(hw); u32 reg_ctl[3] = { 0 }; unsigned long pll_freq; long ret; - if (*parent_rate < PLL_FREF_MIN_FREQ || *parent_rate > PLL_FREF_MAX_FREQ) + if (req->best_parent_rate < PLL_FREF_MIN_FREQ || req->best_parent_rate > PLL_FREF_MAX_FREQ) return -EINVAL; - ret = ma35d1_pll_find_closest(pll, rate, *parent_rate, reg_ctl, &pll_freq); + ret = ma35d1_pll_find_closest(pll, req->rate, req->best_parent_rate, + reg_ctl, &pll_freq); if (ret < 0) return ret; switch (pll->id) { case CAPLL: reg_ctl[0] = readl_relaxed(pll->ctl0_base); - pll_freq = ma35d1_calc_smic_pll_freq(reg_ctl[0], *parent_rate); - return pll_freq; + pll_freq = ma35d1_calc_smic_pll_freq(reg_ctl[0], req->best_parent_rate); + req->rate = pll_freq; + + return 0; case DDRPLL: case APLL: case EPLL: case VPLL: reg_ctl[0] = readl_relaxed(pll->ctl0_base); reg_ctl[1] = readl_relaxed(pll->ctl1_base); - pll_freq = ma35d1_calc_pll_freq(pll->mode, reg_ctl, *parent_rate); - return pll_freq; + pll_freq = ma35d1_calc_pll_freq(pll->mode, reg_ctl, req->best_parent_rate); + req->rate = pll_freq; + + return 0; } + + req->rate = 0; + return 0; } @@ -311,12 +319,12 @@ static const struct clk_ops ma35d1_clk_pll_ops = { .unprepare = ma35d1_clk_pll_unprepare, .set_rate = ma35d1_clk_pll_set_rate, .recalc_rate = ma35d1_clk_pll_recalc_rate, - .round_rate = ma35d1_clk_pll_round_rate, + .determine_rate = ma35d1_clk_pll_determine_rate, }; static const struct clk_ops ma35d1_clk_fixed_pll_ops = { .recalc_rate = ma35d1_clk_pll_recalc_rate, - .round_rate = ma35d1_clk_pll_round_rate, + .determine_rate = ma35d1_clk_pll_determine_rate, }; struct clk_hw *ma35d1_reg_clk_pll(struct device *dev, u32 id, u8 u8mode, const char *name, diff --git a/drivers/clk/nxp/clk-lpc18xx-cgu.c b/drivers/clk/nxp/clk-lpc18xx-cgu.c index 81efa885069b..b9e204d63a97 100644 --- a/drivers/clk/nxp/clk-lpc18xx-cgu.c +++ b/drivers/clk/nxp/clk-lpc18xx-cgu.c @@ -370,23 +370,25 @@ static unsigned long lpc18xx_pll0_recalc_rate(struct clk_hw *hw, return 0; } -static long lpc18xx_pll0_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *prate) +static int lpc18xx_pll0_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { unsigned long m; - if (*prate < rate) { + if (req->best_parent_rate < req->rate) { pr_warn("%s: pll dividers not supported\n", __func__); return -EINVAL; } - m = DIV_ROUND_UP_ULL(*prate, rate * 2); - if (m <= 0 && m > LPC18XX_PLL0_MSEL_MAX) { - pr_warn("%s: unable to support rate %lu\n", __func__, rate); + m = DIV_ROUND_UP_ULL(req->best_parent_rate, req->rate * 2); + if (m == 0 || m > LPC18XX_PLL0_MSEL_MAX) { + pr_warn("%s: unable to support rate %lu\n", __func__, req->rate); return -EINVAL; } - return 2 * *prate * m; + req->rate = 2 * req->best_parent_rate * m; + + return 0; } static int lpc18xx_pll0_set_rate(struct clk_hw *hw, unsigned long rate, @@ -402,7 +404,7 @@ static int lpc18xx_pll0_set_rate(struct clk_hw *hw, unsigned long rate, } m = DIV_ROUND_UP_ULL(parent_rate, rate * 2); - if (m <= 0 && m > LPC18XX_PLL0_MSEL_MAX) { + if (m == 0 || m > LPC18XX_PLL0_MSEL_MAX) { pr_warn("%s: unable to support rate %lu\n", __func__, rate); return -EINVAL; } @@ -443,7 +445,7 @@ static int lpc18xx_pll0_set_rate(struct clk_hw *hw, unsigned long rate, static const struct clk_ops lpc18xx_pll0_ops = { .recalc_rate = lpc18xx_pll0_recalc_rate, - .round_rate = lpc18xx_pll0_round_rate, + .determine_rate = lpc18xx_pll0_determine_rate, .set_rate = lpc18xx_pll0_set_rate, }; diff --git a/drivers/clk/nxp/clk-lpc32xx.c b/drivers/clk/nxp/clk-lpc32xx.c index e00f270bc6aa..23f980cf6a2b 100644 --- a/drivers/clk/nxp/clk-lpc32xx.c +++ b/drivers/clk/nxp/clk-lpc32xx.c @@ -68,7 +68,6 @@ static const struct regmap_config lpc32xx_scb_regmap_config = { .reg_stride = 4, .val_format_endian = REGMAP_ENDIAN_LITTLE, .max_register = 0x114, - .fast_io = true, }; static struct regmap *clk_regmap; @@ -579,17 +578,17 @@ static int clk_pll_set_rate(struct clk_hw *hw, unsigned long rate, return regmap_update_bits(clk_regmap, clk->reg, 0x1FFFF, val); } -static long clk_hclk_pll_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *parent_rate) +static int clk_hclk_pll_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { struct lpc32xx_pll_clk *clk = to_lpc32xx_pll_clk(hw); - u64 m_i, o = rate, i = *parent_rate, d = (u64)rate << 6; + u64 m_i, o = req->rate, i = req->best_parent_rate, d = (u64)req->rate << 6; u64 m = 0, n = 0, p = 0; int p_i, n_i; - pr_debug("%s: %lu/%lu\n", clk_hw_get_name(hw), *parent_rate, rate); + pr_debug("%s: %lu/%lu\n", clk_hw_get_name(hw), req->best_parent_rate, req->rate); - if (rate > 266500000) + if (req->rate > 266500000) return -EINVAL; /* Have to check all 20 possibilities to find the minimal M */ @@ -614,9 +613,9 @@ static long clk_hclk_pll_round_rate(struct clk_hw *hw, unsigned long rate, } } - if (d == (u64)rate << 6) { + if (d == (u64)req->rate << 6) { pr_err("%s: %lu: no valid PLL parameters are found\n", - clk_hw_get_name(hw), rate); + clk_hw_get_name(hw), req->rate); return -EINVAL; } @@ -634,22 +633,25 @@ static long clk_hclk_pll_round_rate(struct clk_hw *hw, unsigned long rate, if (!d) pr_debug("%s: %lu: found exact match: %llu/%llu/%llu\n", - clk_hw_get_name(hw), rate, m, n, p); + clk_hw_get_name(hw), req->rate, m, n, p); else pr_debug("%s: %lu: found closest: %llu/%llu/%llu - %llu\n", - clk_hw_get_name(hw), rate, m, n, p, o); + clk_hw_get_name(hw), req->rate, m, n, p, o); - return o; + req->rate = o; + + return 0; } -static long clk_usb_pll_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *parent_rate) +static int clk_usb_pll_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { struct lpc32xx_pll_clk *clk = to_lpc32xx_pll_clk(hw); struct clk_hw *usb_div_hw, *osc_hw; u64 d_i, n_i, m, o; - pr_debug("%s: %lu/%lu\n", clk_hw_get_name(hw), *parent_rate, rate); + pr_debug("%s: %lu/%lu\n", clk_hw_get_name(hw), req->best_parent_rate, + req->rate); /* * The only supported USB clock is 48MHz, with PLL internal constraints @@ -657,7 +659,7 @@ static long clk_usb_pll_round_rate(struct clk_hw *hw, unsigned long rate, * and post-divider must be 4, this slightly simplifies calculation of * USB divider, USB PLL N and M parameters. */ - if (rate != 48000000) + if (req->rate != 48000000) return -EINVAL; /* USB divider clock */ @@ -685,30 +687,30 @@ static long clk_usb_pll_round_rate(struct clk_hw *hw, unsigned long rate, clk->m_div = m; clk->p_div = 2; clk->mode = PLL_NON_INTEGER; - *parent_rate = div64_u64(o, d_i); + req->best_parent_rate = div64_u64(o, d_i); - return rate; + return 0; } } return -EINVAL; } -#define LPC32XX_DEFINE_PLL_OPS(_name, _rc, _sr, _rr) \ +#define LPC32XX_DEFINE_PLL_OPS(_name, _rc, _sr, _dr) \ static const struct clk_ops clk_ ##_name ## _ops = { \ .enable = clk_pll_enable, \ .disable = clk_pll_disable, \ .is_enabled = clk_pll_is_enabled, \ .recalc_rate = _rc, \ .set_rate = _sr, \ - .round_rate = _rr, \ + .determine_rate = _dr, \ } LPC32XX_DEFINE_PLL_OPS(pll_397x, clk_pll_397x_recalc_rate, NULL, NULL); LPC32XX_DEFINE_PLL_OPS(hclk_pll, clk_pll_recalc_rate, - clk_pll_set_rate, clk_hclk_pll_round_rate); + clk_pll_set_rate, clk_hclk_pll_determine_rate); LPC32XX_DEFINE_PLL_OPS(usb_pll, clk_pll_recalc_rate, - clk_pll_set_rate, clk_usb_pll_round_rate); + clk_pll_set_rate, clk_usb_pll_determine_rate); static int clk_ddram_is_enabled(struct clk_hw *hw) { @@ -955,8 +957,8 @@ static unsigned long clk_divider_recalc_rate(struct clk_hw *hw, divider->flags, divider->width); } -static long clk_divider_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *prate) +static int clk_divider_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { struct lpc32xx_clk_div *divider = to_lpc32xx_div(hw); unsigned int bestdiv; @@ -968,11 +970,15 @@ static long clk_divider_round_rate(struct clk_hw *hw, unsigned long rate, bestdiv &= div_mask(divider->width); bestdiv = _get_div(divider->table, bestdiv, divider->flags, divider->width); - return DIV_ROUND_UP(*prate, bestdiv); + req->rate = DIV_ROUND_UP(req->best_parent_rate, bestdiv); + + return 0; } - return divider_round_rate(hw, rate, prate, divider->table, - divider->width, divider->flags); + req->rate = divider_round_rate(hw, req->rate, &req->best_parent_rate, + divider->table, divider->width, divider->flags); + + return 0; } static int clk_divider_set_rate(struct clk_hw *hw, unsigned long rate, @@ -991,7 +997,7 @@ static int clk_divider_set_rate(struct clk_hw *hw, unsigned long rate, static const struct clk_ops lpc32xx_clk_divider_ops = { .recalc_rate = clk_divider_recalc_rate, - .round_rate = clk_divider_round_rate, + .determine_rate = clk_divider_determine_rate, .set_rate = clk_divider_set_rate, }; diff --git a/drivers/clk/pistachio/clk-pll.c b/drivers/clk/pistachio/clk-pll.c index 025b9df76cdb..d05337915e2b 100644 --- a/drivers/clk/pistachio/clk-pll.c +++ b/drivers/clk/pistachio/clk-pll.c @@ -139,19 +139,23 @@ pll_get_params(struct pistachio_clk_pll *pll, unsigned long fref, return NULL; } -static long pll_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *parent_rate) +static int pll_determine_rate(struct clk_hw *hw, struct clk_rate_request *req) { struct pistachio_clk_pll *pll = to_pistachio_pll(hw); unsigned int i; for (i = 0; i < pll->nr_rates; i++) { - if (i > 0 && pll->rates[i].fref == *parent_rate && - pll->rates[i].fout <= rate) - return pll->rates[i - 1].fout; + if (i > 0 && pll->rates[i].fref == req->best_parent_rate && + pll->rates[i].fout <= req->rate) { + req->rate = pll->rates[i - 1].fout; + + return 0; + } } - return pll->rates[0].fout; + req->rate = pll->rates[0].fout; + + return 0; } static int pll_gf40lp_frac_enable(struct clk_hw *hw) @@ -300,7 +304,7 @@ static const struct clk_ops pll_gf40lp_frac_ops = { .disable = pll_gf40lp_frac_disable, .is_enabled = pll_gf40lp_frac_is_enabled, .recalc_rate = pll_gf40lp_frac_recalc_rate, - .round_rate = pll_round_rate, + .determine_rate = pll_determine_rate, .set_rate = pll_gf40lp_frac_set_rate, }; @@ -432,7 +436,7 @@ static const struct clk_ops pll_gf40lp_laint_ops = { .disable = pll_gf40lp_laint_disable, .is_enabled = pll_gf40lp_laint_is_enabled, .recalc_rate = pll_gf40lp_laint_recalc_rate, - .round_rate = pll_round_rate, + .determine_rate = pll_determine_rate, .set_rate = pll_gf40lp_laint_set_rate, }; diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig index 6cb6cd3e1778..78a303842613 100644 --- a/drivers/clk/qcom/Kconfig +++ b/drivers/clk/qcom/Kconfig @@ -19,6 +19,33 @@ menuconfig COMMON_CLK_QCOM if COMMON_CLK_QCOM +config CLK_GLYMUR_DISPCC + tristate "GLYMUR Display Clock Controller" + depends on ARM64 || COMPILE_TEST + select CLK_GLYMUR_GCC + help + Support for the display clock controllers on Qualcomm + Technologies, Inc. GLYMUR devices. + Say Y if you want to support display devices and functionality such as + splash screen. + +config CLK_GLYMUR_GCC + tristate "GLYMUR Global Clock Controller" + depends on ARM64 || COMPILE_TEST + select QCOM_GDSC + help + Support for the global clock controller on GLYMUR devices. + Say Y if you want to use peripheral devices such as UART, SPI, + I2C, USB, UFS, SDCC, etc. + +config CLK_GLYMUR_TCSRCC + tristate "GLYMUR TCSR Clock Controller" + depends on ARM64 || COMPILE_TEST + select QCOM_GDSC + help + Support for the TCSR clock controller on GLYMUR devices. + Say Y if you want to use peripheral devices such as USB/PCIe/EDP. + config CLK_X1E80100_CAMCC tristate "X1E80100 Camera Clock Controller" depends on ARM64 || COMPILE_TEST @@ -187,6 +214,15 @@ config IPQ_APSS_PLL Say Y if you want to support CPU frequency scaling on ipq based devices. +config IPQ_APSS_5424 + tristate "IPQ APSS Clock Controller" + select IPQ_APSS_PLL + default y if IPQ_GCC_5424 + help + Support for APSS Clock controller on Qualcom IPQ5424 platform. + Say Y if you want to support CPU frequency scaling on ipq based + devices. + config IPQ_APSS_6018 tristate "IPQ APSS Clock Controller" select IPQ_APSS_PLL @@ -323,12 +359,12 @@ config MSM_GCC_8916 SD/eMMC, display, graphics, camera etc. config MSM_GCC_8917 - tristate "MSM8917/QM215 Global Clock Controller" + tristate "MSM89(17/37)/QM215 Global Clock Controller" depends on ARM64 || COMPILE_TEST select QCOM_GDSC help - Support for the global clock controller on msm8917 and qm215 - devices. + Support for the global clock controller on msm8917, msm8937 + and qm215 devices. Say Y if you want to use devices such as UART, SPI i2c, USB, SD/eMMC, display, graphics, camera etc. @@ -495,7 +531,7 @@ config QCM_DISPCC_2290 config QCS_DISPCC_615 tristate "QCS615 Display Clock Controller" - select QCM_GCC_615 + select QCS_GCC_615 help Support for the display clock controller on Qualcomm Technologies, Inc QCS615 devices. diff --git a/drivers/clk/qcom/Makefile b/drivers/clk/qcom/Makefile index ddb7e06fae40..8051d481c439 100644 --- a/drivers/clk/qcom/Makefile +++ b/drivers/clk/qcom/Makefile @@ -21,6 +21,9 @@ clk-qcom-$(CONFIG_QCOM_GDSC) += gdsc.o obj-$(CONFIG_APQ_GCC_8084) += gcc-apq8084.o obj-$(CONFIG_APQ_MMCC_8084) += mmcc-apq8084.o obj-$(CONFIG_CLK_GFM_LPASS_SM8250) += lpass-gfm-sm8250.o +obj-$(CONFIG_CLK_GLYMUR_DISPCC) += dispcc-glymur.o +obj-$(CONFIG_CLK_GLYMUR_GCC) += gcc-glymur.o +obj-$(CONFIG_CLK_GLYMUR_TCSRCC) += tcsrcc-glymur.o obj-$(CONFIG_CLK_X1E80100_CAMCC) += camcc-x1e80100.o obj-$(CONFIG_CLK_X1E80100_DISPCC) += dispcc-x1e80100.o obj-$(CONFIG_CLK_X1E80100_GCC) += gcc-x1e80100.o @@ -29,6 +32,7 @@ obj-$(CONFIG_CLK_X1E80100_TCSRCC) += tcsrcc-x1e80100.o obj-$(CONFIG_CLK_X1P42100_GPUCC) += gpucc-x1p42100.o obj-$(CONFIG_CLK_QCM2290_GPUCC) += gpucc-qcm2290.o obj-$(CONFIG_IPQ_APSS_PLL) += apss-ipq-pll.o +obj-$(CONFIG_IPQ_APSS_5424) += apss-ipq5424.o obj-$(CONFIG_IPQ_APSS_6018) += apss-ipq6018.o obj-$(CONFIG_IPQ_CMN_PLL) += ipq-cmn-pll.o obj-$(CONFIG_IPQ_GCC_4019) += gcc-ipq4019.o diff --git a/drivers/clk/qcom/a53-pll.c b/drivers/clk/qcom/a53-pll.c index f43d455ab4b8..724a642311e5 100644 --- a/drivers/clk/qcom/a53-pll.c +++ b/drivers/clk/qcom/a53-pll.c @@ -33,7 +33,6 @@ static const struct regmap_config a53pll_regmap_config = { .reg_stride = 4, .val_bits = 32, .max_register = 0x40, - .fast_io = true, }; static struct pll_freq_tbl *qcom_a53pll_get_freq_tbl(struct device *dev) diff --git a/drivers/clk/qcom/a7-pll.c b/drivers/clk/qcom/a7-pll.c index c4a53e5db229..04b5492a3c21 100644 --- a/drivers/clk/qcom/a7-pll.c +++ b/drivers/clk/qcom/a7-pll.c @@ -27,7 +27,7 @@ static struct clk_alpha_pll a7pll = { .clkr = { .hw.init = &(struct clk_init_data){ .name = "a7pll", - .parent_data = &(const struct clk_parent_data){ + .parent_data = &(const struct clk_parent_data){ .fw_name = "bi_tcxo", }, .num_parents = 1, @@ -50,7 +50,6 @@ static const struct regmap_config a7pll_regmap_config = { .reg_stride = 4, .val_bits = 32, .max_register = 0x1000, - .fast_io = true, }; static int qcom_a7pll_probe(struct platform_device *pdev) diff --git a/drivers/clk/qcom/apss-ipq-pll.c b/drivers/clk/qcom/apss-ipq-pll.c index d6c1aea7e9e1..3a8987fe7008 100644 --- a/drivers/clk/qcom/apss-ipq-pll.c +++ b/drivers/clk/qcom/apss-ipq-pll.c @@ -169,7 +169,6 @@ static const struct regmap_config ipq_pll_regmap_config = { .reg_stride = 4, .val_bits = 32, .max_register = 0x40, - .fast_io = true, }; static int apss_ipq_pll_probe(struct platform_device *pdev) diff --git a/drivers/clk/qcom/apss-ipq5424.c b/drivers/clk/qcom/apss-ipq5424.c new file mode 100644 index 000000000000..4c67f722e009 --- /dev/null +++ b/drivers/clk/qcom/apss-ipq5424.c @@ -0,0 +1,265 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2018, The Linux Foundation. All rights reserved. + * Copyright (c) 2025, Qualcomm Innovation Center, Inc. All rights reserved. + */ + +#include <linux/clk.h> +#include <linux/clk-provider.h> +#include <linux/err.h> +#include <linux/interconnect-provider.h> +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/platform_device.h> +#include <linux/regmap.h> + +#include <dt-bindings/arm/qcom,ids.h> +#include <dt-bindings/clock/qcom,apss-ipq.h> +#include <dt-bindings/interconnect/qcom,ipq5424.h> + +#include "clk-alpha-pll.h" +#include "clk-branch.h" +#include "clk-rcg.h" +#include "clk-regmap.h" +#include "common.h" + +enum { + DT_XO, + DT_CLK_REF, +}; + +enum { + P_XO, + P_GPLL0, + P_APSS_PLL_EARLY, + P_L3_PLL, +}; + +struct apss_clk { + struct notifier_block cpu_clk_notifier; + struct clk_hw *hw; + struct device *dev; + struct clk *l3_clk; +}; + +static const struct alpha_pll_config apss_pll_config = { + .l = 0x3b, + .config_ctl_val = 0x08200920, + .config_ctl_hi_val = 0x05008001, + .config_ctl_hi1_val = 0x04000000, + .user_ctl_val = 0xf, +}; + +static struct clk_alpha_pll ipq5424_apss_pll = { + .offset = 0x0, + .config = &apss_pll_config, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_HUAYRA_2290], + .flags = SUPPORTS_DYNAMIC_UPDATE, + .clkr = { + .enable_reg = 0x0, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "apss_pll", + .parent_data = &(const struct clk_parent_data) { + .index = DT_XO, + }, + .num_parents = 1, + .ops = &clk_alpha_pll_huayra_ops, + }, + }, +}; + +static const struct clk_parent_data parents_apss_silver_clk_src[] = { + { .index = DT_XO }, + { .index = DT_CLK_REF }, + { .hw = &ipq5424_apss_pll.clkr.hw }, +}; + +static const struct parent_map parents_apss_silver_clk_src_map[] = { + { P_XO, 0 }, + { P_GPLL0, 4 }, + { P_APSS_PLL_EARLY, 5 }, +}; + +static const struct freq_tbl ftbl_apss_clk_src[] = { + F(816000000, P_APSS_PLL_EARLY, 1, 0, 0), + F(1416000000, P_APSS_PLL_EARLY, 1, 0, 0), + F(1800000000, P_APSS_PLL_EARLY, 1, 0, 0), + { } +}; + +static struct clk_rcg2 apss_silver_clk_src = { + .cmd_rcgr = 0x0080, + .freq_tbl = ftbl_apss_clk_src, + .hid_width = 5, + .parent_map = parents_apss_silver_clk_src_map, + .clkr.hw.init = &(struct clk_init_data) { + .name = "apss_silver_clk_src", + .parent_data = parents_apss_silver_clk_src, + .num_parents = ARRAY_SIZE(parents_apss_silver_clk_src), + .ops = &clk_rcg2_ops, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_branch apss_silver_core_clk = { + .halt_reg = 0x008c, + .clkr = { + .enable_reg = 0x008c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data) { + .name = "apss_silver_core_clk", + .parent_hws = (const struct clk_hw *[]) { + &apss_silver_clk_src.clkr.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT | CLK_IS_CRITICAL, + .ops = &clk_branch2_ops, + }, + }, +}; + +static const struct alpha_pll_config l3_pll_config = { + .l = 0x29, + .config_ctl_val = 0x08200920, + .config_ctl_hi_val = 0x05008001, + .config_ctl_hi1_val = 0x04000000, + .user_ctl_val = 0xf, +}; + +static struct clk_alpha_pll ipq5424_l3_pll = { + .offset = 0x10000, + .config = &l3_pll_config, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_HUAYRA_2290], + .flags = SUPPORTS_DYNAMIC_UPDATE, + .clkr = { + .enable_reg = 0x0, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data) { + .name = "l3_pll", + .parent_data = &(const struct clk_parent_data) { + .index = DT_XO, + }, + .num_parents = 1, + .ops = &clk_alpha_pll_huayra_ops, + }, + }, +}; + +static const struct clk_parent_data parents_l3_clk_src[] = { + { .index = DT_XO }, + { .index = DT_CLK_REF }, + { .hw = &ipq5424_l3_pll.clkr.hw }, +}; + +static const struct parent_map parents_l3_clk_src_map[] = { + { P_XO, 0 }, + { P_GPLL0, 4 }, + { P_L3_PLL, 5 }, +}; + +static const struct freq_tbl ftbl_l3_clk_src[] = { + F(816000000, P_L3_PLL, 1, 0, 0), + F(984000000, P_L3_PLL, 1, 0, 0), + F(1272000000, P_L3_PLL, 1, 0, 0), + { } +}; + +static struct clk_rcg2 l3_clk_src = { + .cmd_rcgr = 0x10080, + .freq_tbl = ftbl_l3_clk_src, + .hid_width = 5, + .parent_map = parents_l3_clk_src_map, + .clkr.hw.init = &(struct clk_init_data) { + .name = "l3_clk_src", + .parent_data = parents_l3_clk_src, + .num_parents = ARRAY_SIZE(parents_l3_clk_src), + .ops = &clk_rcg2_ops, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_branch l3_core_clk = { + .halt_reg = 0x1008c, + .clkr = { + .enable_reg = 0x1008c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data) { + .name = "l3_clk", + .parent_hws = (const struct clk_hw *[]) { + &l3_clk_src.clkr.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT | CLK_IS_CRITICAL, + .ops = &clk_branch2_ops, + }, + }, +}; + +static const struct regmap_config apss_ipq5424_regmap_config = { + .reg_bits = 32, + .reg_stride = 4, + .val_bits = 32, + .max_register = 0x20000, + .fast_io = true, +}; + +static struct clk_regmap *apss_ipq5424_clks[] = { + [APSS_PLL_EARLY] = &ipq5424_apss_pll.clkr, + [APSS_SILVER_CLK_SRC] = &apss_silver_clk_src.clkr, + [APSS_SILVER_CORE_CLK] = &apss_silver_core_clk.clkr, + [L3_PLL] = &ipq5424_l3_pll.clkr, + [L3_CLK_SRC] = &l3_clk_src.clkr, + [L3_CORE_CLK] = &l3_core_clk.clkr, +}; + +static struct clk_alpha_pll *ipa5424_apss_plls[] = { + &ipq5424_l3_pll, + &ipq5424_apss_pll, +}; + +static struct qcom_cc_driver_data ipa5424_apss_driver_data = { + .alpha_plls = ipa5424_apss_plls, + .num_alpha_plls = ARRAY_SIZE(ipa5424_apss_plls), +}; + +#define IPQ_APPS_PLL_ID (5424 * 3) /* some unique value */ + +static const struct qcom_icc_hws_data icc_ipq5424_cpu_l3[] = { + { MASTER_CPU, SLAVE_L3, L3_CORE_CLK }, +}; + +static const struct qcom_cc_desc apss_ipq5424_desc = { + .config = &apss_ipq5424_regmap_config, + .clks = apss_ipq5424_clks, + .num_clks = ARRAY_SIZE(apss_ipq5424_clks), + .icc_hws = icc_ipq5424_cpu_l3, + .num_icc_hws = ARRAY_SIZE(icc_ipq5424_cpu_l3), + .icc_first_node_id = IPQ_APPS_PLL_ID, + .driver_data = &ipa5424_apss_driver_data, +}; + +static int apss_ipq5424_probe(struct platform_device *pdev) +{ + return qcom_cc_probe(pdev, &apss_ipq5424_desc); +} + +static const struct of_device_id apss_ipq5424_match_table[] = { + { .compatible = "qcom,ipq5424-apss-clk" }, + { } +}; +MODULE_DEVICE_TABLE(of, apss_ipq5424_match_table); + +static struct platform_driver apss_ipq5424_driver = { + .probe = apss_ipq5424_probe, + .driver = { + .name = "apss-ipq5424-clk", + .of_match_table = apss_ipq5424_match_table, + .sync_state = icc_sync_state, + }, +}; + +module_platform_driver(apss_ipq5424_driver); + +MODULE_DESCRIPTION("QCOM APSS IPQ5424 CLK Driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/clk/qcom/camcc-milos.c b/drivers/clk/qcom/camcc-milos.c index 75bd939f7dd1..0077c9c9249f 100644 --- a/drivers/clk/qcom/camcc-milos.c +++ b/drivers/clk/qcom/camcc-milos.c @@ -2124,7 +2124,7 @@ static struct qcom_cc_driver_data cam_cc_milos_driver_data = { .num_clk_cbcrs = ARRAY_SIZE(cam_cc_milos_critical_cbcrs), }; -static struct qcom_cc_desc cam_cc_milos_desc = { +static const struct qcom_cc_desc cam_cc_milos_desc = { .config = &cam_cc_milos_regmap_config, .clks = cam_cc_milos_clocks, .num_clks = ARRAY_SIZE(cam_cc_milos_clocks), diff --git a/drivers/clk/qcom/clk-alpha-pll.c b/drivers/clk/qcom/clk-alpha-pll.c index fec6eb376e27..6aeba40358c1 100644 --- a/drivers/clk/qcom/clk-alpha-pll.c +++ b/drivers/clk/qcom/clk-alpha-pll.c @@ -66,7 +66,7 @@ #define GET_PLL_TYPE(pll) (((pll)->regs - clk_alpha_pll_regs[0]) / PLL_OFF_MAX_REGS) const u8 clk_alpha_pll_regs[][PLL_OFF_MAX_REGS] = { - [CLK_ALPHA_PLL_TYPE_DEFAULT] = { + [CLK_ALPHA_PLL_TYPE_DEFAULT] = { [PLL_OFF_L_VAL] = 0x04, [PLL_OFF_ALPHA_VAL] = 0x08, [PLL_OFF_ALPHA_VAL_U] = 0x0c, @@ -77,7 +77,7 @@ const u8 clk_alpha_pll_regs[][PLL_OFF_MAX_REGS] = { [PLL_OFF_TEST_CTL_U] = 0x20, [PLL_OFF_STATUS] = 0x24, }, - [CLK_ALPHA_PLL_TYPE_HUAYRA] = { + [CLK_ALPHA_PLL_TYPE_HUAYRA] = { [PLL_OFF_L_VAL] = 0x04, [PLL_OFF_ALPHA_VAL] = 0x08, [PLL_OFF_USER_CTL] = 0x10, @@ -87,7 +87,7 @@ const u8 clk_alpha_pll_regs[][PLL_OFF_MAX_REGS] = { [PLL_OFF_TEST_CTL_U] = 0x20, [PLL_OFF_STATUS] = 0x24, }, - [CLK_ALPHA_PLL_TYPE_HUAYRA_APSS] = { + [CLK_ALPHA_PLL_TYPE_HUAYRA_APSS] = { [PLL_OFF_L_VAL] = 0x08, [PLL_OFF_ALPHA_VAL] = 0x10, [PLL_OFF_USER_CTL] = 0x18, @@ -97,7 +97,7 @@ const u8 clk_alpha_pll_regs[][PLL_OFF_MAX_REGS] = { [PLL_OFF_TEST_CTL] = 0x30, [PLL_OFF_TEST_CTL_U] = 0x34, }, - [CLK_ALPHA_PLL_TYPE_HUAYRA_2290] = { + [CLK_ALPHA_PLL_TYPE_HUAYRA_2290] = { [PLL_OFF_L_VAL] = 0x04, [PLL_OFF_ALPHA_VAL] = 0x08, [PLL_OFF_USER_CTL] = 0x0c, @@ -110,7 +110,7 @@ const u8 clk_alpha_pll_regs[][PLL_OFF_MAX_REGS] = { [PLL_OFF_OPMODE] = 0x28, [PLL_OFF_STATUS] = 0x38, }, - [CLK_ALPHA_PLL_TYPE_BRAMMO] = { + [CLK_ALPHA_PLL_TYPE_BRAMMO] = { [PLL_OFF_L_VAL] = 0x04, [PLL_OFF_ALPHA_VAL] = 0x08, [PLL_OFF_ALPHA_VAL_U] = 0x0c, @@ -119,7 +119,7 @@ const u8 clk_alpha_pll_regs[][PLL_OFF_MAX_REGS] = { [PLL_OFF_TEST_CTL] = 0x1c, [PLL_OFF_STATUS] = 0x24, }, - [CLK_ALPHA_PLL_TYPE_FABIA] = { + [CLK_ALPHA_PLL_TYPE_FABIA] = { [PLL_OFF_L_VAL] = 0x04, [PLL_OFF_USER_CTL] = 0x0c, [PLL_OFF_USER_CTL_U] = 0x10, @@ -147,7 +147,7 @@ const u8 clk_alpha_pll_regs[][PLL_OFF_MAX_REGS] = { [PLL_OFF_OPMODE] = 0x38, [PLL_OFF_ALPHA_VAL] = 0x40, }, - [CLK_ALPHA_PLL_TYPE_AGERA] = { + [CLK_ALPHA_PLL_TYPE_AGERA] = { [PLL_OFF_L_VAL] = 0x04, [PLL_OFF_ALPHA_VAL] = 0x08, [PLL_OFF_USER_CTL] = 0x0c, @@ -157,7 +157,7 @@ const u8 clk_alpha_pll_regs[][PLL_OFF_MAX_REGS] = { [PLL_OFF_TEST_CTL_U] = 0x1c, [PLL_OFF_STATUS] = 0x2c, }, - [CLK_ALPHA_PLL_TYPE_ZONDA] = { + [CLK_ALPHA_PLL_TYPE_ZONDA] = { [PLL_OFF_L_VAL] = 0x04, [PLL_OFF_ALPHA_VAL] = 0x08, [PLL_OFF_USER_CTL] = 0x0c, @@ -243,7 +243,7 @@ const u8 clk_alpha_pll_regs[][PLL_OFF_MAX_REGS] = { [PLL_OFF_TEST_CTL] = 0x28, [PLL_OFF_TEST_CTL_U] = 0x2c, }, - [CLK_ALPHA_PLL_TYPE_DEFAULT_EVO] = { + [CLK_ALPHA_PLL_TYPE_DEFAULT_EVO] = { [PLL_OFF_L_VAL] = 0x04, [PLL_OFF_ALPHA_VAL] = 0x08, [PLL_OFF_ALPHA_VAL_U] = 0x0c, @@ -254,7 +254,7 @@ const u8 clk_alpha_pll_regs[][PLL_OFF_MAX_REGS] = { [PLL_OFF_CONFIG_CTL] = 0x20, [PLL_OFF_STATUS] = 0x24, }, - [CLK_ALPHA_PLL_TYPE_BRAMMO_EVO] = { + [CLK_ALPHA_PLL_TYPE_BRAMMO_EVO] = { [PLL_OFF_L_VAL] = 0x04, [PLL_OFF_ALPHA_VAL] = 0x08, [PLL_OFF_ALPHA_VAL_U] = 0x0c, @@ -275,7 +275,7 @@ const u8 clk_alpha_pll_regs[][PLL_OFF_MAX_REGS] = { [PLL_OFF_TEST_CTL] = 0x30, [PLL_OFF_TEST_CTL_U] = 0x34, }, - [CLK_ALPHA_PLL_TYPE_STROMER_PLUS] = { + [CLK_ALPHA_PLL_TYPE_STROMER_PLUS] = { [PLL_OFF_L_VAL] = 0x04, [PLL_OFF_USER_CTL] = 0x08, [PLL_OFF_USER_CTL_U] = 0x0c, @@ -286,7 +286,7 @@ const u8 clk_alpha_pll_regs[][PLL_OFF_MAX_REGS] = { [PLL_OFF_ALPHA_VAL] = 0x24, [PLL_OFF_ALPHA_VAL_U] = 0x28, }, - [CLK_ALPHA_PLL_TYPE_ZONDA_OLE] = { + [CLK_ALPHA_PLL_TYPE_ZONDA_OLE] = { [PLL_OFF_L_VAL] = 0x04, [PLL_OFF_ALPHA_VAL] = 0x08, [PLL_OFF_USER_CTL] = 0x0c, @@ -301,7 +301,7 @@ const u8 clk_alpha_pll_regs[][PLL_OFF_MAX_REGS] = { [PLL_OFF_OPMODE] = 0x30, [PLL_OFF_STATUS] = 0x3c, }, - [CLK_ALPHA_PLL_TYPE_NSS_HUAYRA] = { + [CLK_ALPHA_PLL_TYPE_NSS_HUAYRA] = { [PLL_OFF_L_VAL] = 0x04, [PLL_OFF_ALPHA_VAL] = 0x08, [PLL_OFF_TEST_CTL] = 0x0c, @@ -849,22 +849,25 @@ static int clk_alpha_pll_hwfsm_set_rate(struct clk_hw *hw, unsigned long rate, clk_alpha_pll_hwfsm_is_enabled); } -static long clk_alpha_pll_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *prate) +static int clk_alpha_pll_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { struct clk_alpha_pll *pll = to_clk_alpha_pll(hw); u32 l, alpha_width = pll_alpha_width(pll); u64 a; unsigned long min_freq, max_freq; - rate = alpha_pll_round_rate(rate, *prate, &l, &a, alpha_width); - if (!pll->vco_table || alpha_pll_find_vco(pll, rate)) - return rate; + req->rate = alpha_pll_round_rate(req->rate, req->best_parent_rate, &l, + &a, alpha_width); + if (!pll->vco_table || alpha_pll_find_vco(pll, req->rate)) + return 0; min_freq = pll->vco_table[0].min_freq; max_freq = pll->vco_table[pll->num_vco - 1].max_freq; - return clamp(rate, min_freq, max_freq); + req->rate = clamp(req->rate, min_freq, max_freq); + + return 0; } void clk_huayra_2290_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap, @@ -1048,12 +1051,15 @@ static int alpha_pll_huayra_set_rate(struct clk_hw *hw, unsigned long rate, return 0; } -static long alpha_pll_huayra_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *prate) +static int alpha_pll_huayra_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { u32 l, a; - return alpha_huayra_pll_round_rate(rate, *prate, &l, &a); + req->rate = alpha_huayra_pll_round_rate(req->rate, + req->best_parent_rate, &l, &a); + + return 0; } static int trion_pll_is_enabled(struct clk_alpha_pll *pll, @@ -1175,7 +1181,7 @@ const struct clk_ops clk_alpha_pll_ops = { .disable = clk_alpha_pll_disable, .is_enabled = clk_alpha_pll_is_enabled, .recalc_rate = clk_alpha_pll_recalc_rate, - .round_rate = clk_alpha_pll_round_rate, + .determine_rate = clk_alpha_pll_determine_rate, .set_rate = clk_alpha_pll_set_rate, }; EXPORT_SYMBOL_GPL(clk_alpha_pll_ops); @@ -1185,7 +1191,7 @@ const struct clk_ops clk_alpha_pll_huayra_ops = { .disable = clk_alpha_pll_disable, .is_enabled = clk_alpha_pll_is_enabled, .recalc_rate = alpha_pll_huayra_recalc_rate, - .round_rate = alpha_pll_huayra_round_rate, + .determine_rate = alpha_pll_huayra_determine_rate, .set_rate = alpha_pll_huayra_set_rate, }; EXPORT_SYMBOL_GPL(clk_alpha_pll_huayra_ops); @@ -1195,7 +1201,7 @@ const struct clk_ops clk_alpha_pll_hwfsm_ops = { .disable = clk_alpha_pll_hwfsm_disable, .is_enabled = clk_alpha_pll_hwfsm_is_enabled, .recalc_rate = clk_alpha_pll_recalc_rate, - .round_rate = clk_alpha_pll_round_rate, + .determine_rate = clk_alpha_pll_determine_rate, .set_rate = clk_alpha_pll_hwfsm_set_rate, }; EXPORT_SYMBOL_GPL(clk_alpha_pll_hwfsm_ops); @@ -1205,7 +1211,7 @@ const struct clk_ops clk_alpha_pll_fixed_trion_ops = { .disable = clk_trion_pll_disable, .is_enabled = clk_trion_pll_is_enabled, .recalc_rate = clk_trion_pll_recalc_rate, - .round_rate = clk_alpha_pll_round_rate, + .determine_rate = clk_alpha_pll_determine_rate, }; EXPORT_SYMBOL_GPL(clk_alpha_pll_fixed_trion_ops); @@ -1240,9 +1246,8 @@ static const struct clk_div_table clk_alpha_2bit_div_table[] = { { } }; -static long -clk_alpha_pll_postdiv_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *prate) +static int clk_alpha_pll_postdiv_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { struct clk_alpha_pll_postdiv *pll = to_clk_alpha_pll_postdiv(hw); const struct clk_div_table *table; @@ -1252,13 +1257,15 @@ clk_alpha_pll_postdiv_round_rate(struct clk_hw *hw, unsigned long rate, else table = clk_alpha_div_table; - return divider_round_rate(hw, rate, prate, table, - pll->width, CLK_DIVIDER_POWER_OF_TWO); + req->rate = divider_round_rate(hw, req->rate, &req->best_parent_rate, + table, pll->width, + CLK_DIVIDER_POWER_OF_TWO); + + return 0; } -static long -clk_alpha_pll_postdiv_round_ro_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *prate) +static int clk_alpha_pll_postdiv_ro_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { struct clk_alpha_pll_postdiv *pll = to_clk_alpha_pll_postdiv(hw); u32 ctl, div; @@ -1270,9 +1277,12 @@ clk_alpha_pll_postdiv_round_ro_rate(struct clk_hw *hw, unsigned long rate, div = 1 << fls(ctl); if (clk_hw_get_flags(hw) & CLK_SET_RATE_PARENT) - *prate = clk_hw_round_rate(clk_hw_get_parent(hw), div * rate); + req->best_parent_rate = clk_hw_round_rate(clk_hw_get_parent(hw), + div * req->rate); + + req->rate = DIV_ROUND_UP_ULL((u64)req->best_parent_rate, div); - return DIV_ROUND_UP_ULL((u64)*prate, div); + return 0; } static int clk_alpha_pll_postdiv_set_rate(struct clk_hw *hw, unsigned long rate, @@ -1291,13 +1301,13 @@ static int clk_alpha_pll_postdiv_set_rate(struct clk_hw *hw, unsigned long rate, const struct clk_ops clk_alpha_pll_postdiv_ops = { .recalc_rate = clk_alpha_pll_postdiv_recalc_rate, - .round_rate = clk_alpha_pll_postdiv_round_rate, + .determine_rate = clk_alpha_pll_postdiv_determine_rate, .set_rate = clk_alpha_pll_postdiv_set_rate, }; EXPORT_SYMBOL_GPL(clk_alpha_pll_postdiv_ops); const struct clk_ops clk_alpha_pll_postdiv_ro_ops = { - .round_rate = clk_alpha_pll_postdiv_round_ro_rate, + .determine_rate = clk_alpha_pll_postdiv_ro_determine_rate, .recalc_rate = clk_alpha_pll_postdiv_recalc_rate, }; EXPORT_SYMBOL_GPL(clk_alpha_pll_postdiv_ro_ops); @@ -1542,7 +1552,7 @@ const struct clk_ops clk_alpha_pll_fabia_ops = { .is_enabled = clk_alpha_pll_is_enabled, .set_rate = alpha_pll_fabia_set_rate, .recalc_rate = alpha_pll_fabia_recalc_rate, - .round_rate = clk_alpha_pll_round_rate, + .determine_rate = clk_alpha_pll_determine_rate, }; EXPORT_SYMBOL_GPL(clk_alpha_pll_fabia_ops); @@ -1551,7 +1561,7 @@ const struct clk_ops clk_alpha_pll_fixed_fabia_ops = { .disable = alpha_pll_fabia_disable, .is_enabled = clk_alpha_pll_is_enabled, .recalc_rate = alpha_pll_fabia_recalc_rate, - .round_rate = clk_alpha_pll_round_rate, + .determine_rate = clk_alpha_pll_determine_rate, }; EXPORT_SYMBOL_GPL(clk_alpha_pll_fixed_fabia_ops); @@ -1602,14 +1612,16 @@ clk_trion_pll_postdiv_recalc_rate(struct clk_hw *hw, unsigned long parent_rate) return (parent_rate / div); } -static long -clk_trion_pll_postdiv_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *prate) +static int clk_trion_pll_postdiv_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { struct clk_alpha_pll_postdiv *pll = to_clk_alpha_pll_postdiv(hw); - return divider_round_rate(hw, rate, prate, pll->post_div_table, - pll->width, CLK_DIVIDER_ROUND_CLOSEST); + req->rate = divider_round_rate(hw, req->rate, &req->best_parent_rate, + pll->post_div_table, + pll->width, CLK_DIVIDER_ROUND_CLOSEST); + + return 0; }; static int @@ -1635,18 +1647,21 @@ clk_trion_pll_postdiv_set_rate(struct clk_hw *hw, unsigned long rate, const struct clk_ops clk_alpha_pll_postdiv_trion_ops = { .recalc_rate = clk_trion_pll_postdiv_recalc_rate, - .round_rate = clk_trion_pll_postdiv_round_rate, + .determine_rate = clk_trion_pll_postdiv_determine_rate, .set_rate = clk_trion_pll_postdiv_set_rate, }; EXPORT_SYMBOL_GPL(clk_alpha_pll_postdiv_trion_ops); -static long clk_alpha_pll_postdiv_fabia_round_rate(struct clk_hw *hw, - unsigned long rate, unsigned long *prate) +static int clk_alpha_pll_postdiv_fabia_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { struct clk_alpha_pll_postdiv *pll = to_clk_alpha_pll_postdiv(hw); - return divider_round_rate(hw, rate, prate, pll->post_div_table, - pll->width, CLK_DIVIDER_ROUND_CLOSEST); + req->rate = divider_round_rate(hw, req->rate, &req->best_parent_rate, + pll->post_div_table, + pll->width, CLK_DIVIDER_ROUND_CLOSEST); + + return 0; } static int clk_alpha_pll_postdiv_fabia_set_rate(struct clk_hw *hw, @@ -1681,7 +1696,7 @@ static int clk_alpha_pll_postdiv_fabia_set_rate(struct clk_hw *hw, const struct clk_ops clk_alpha_pll_postdiv_fabia_ops = { .recalc_rate = clk_alpha_pll_postdiv_fabia_recalc_rate, - .round_rate = clk_alpha_pll_postdiv_fabia_round_rate, + .determine_rate = clk_alpha_pll_postdiv_fabia_determine_rate, .set_rate = clk_alpha_pll_postdiv_fabia_set_rate, }; EXPORT_SYMBOL_GPL(clk_alpha_pll_postdiv_fabia_ops); @@ -1833,7 +1848,7 @@ const struct clk_ops clk_alpha_pll_trion_ops = { .disable = clk_trion_pll_disable, .is_enabled = clk_trion_pll_is_enabled, .recalc_rate = clk_trion_pll_recalc_rate, - .round_rate = clk_alpha_pll_round_rate, + .determine_rate = clk_alpha_pll_determine_rate, .set_rate = alpha_pll_trion_set_rate, }; EXPORT_SYMBOL_GPL(clk_alpha_pll_trion_ops); @@ -1844,14 +1859,14 @@ const struct clk_ops clk_alpha_pll_lucid_ops = { .disable = clk_trion_pll_disable, .is_enabled = clk_trion_pll_is_enabled, .recalc_rate = clk_trion_pll_recalc_rate, - .round_rate = clk_alpha_pll_round_rate, + .determine_rate = clk_alpha_pll_determine_rate, .set_rate = alpha_pll_trion_set_rate, }; EXPORT_SYMBOL_GPL(clk_alpha_pll_lucid_ops); const struct clk_ops clk_alpha_pll_postdiv_lucid_ops = { .recalc_rate = clk_alpha_pll_postdiv_fabia_recalc_rate, - .round_rate = clk_alpha_pll_postdiv_fabia_round_rate, + .determine_rate = clk_alpha_pll_postdiv_fabia_determine_rate, .set_rate = clk_alpha_pll_postdiv_fabia_set_rate, }; EXPORT_SYMBOL_GPL(clk_alpha_pll_postdiv_lucid_ops); @@ -1903,7 +1918,7 @@ const struct clk_ops clk_alpha_pll_agera_ops = { .disable = clk_alpha_pll_disable, .is_enabled = clk_alpha_pll_is_enabled, .recalc_rate = alpha_pll_fabia_recalc_rate, - .round_rate = clk_alpha_pll_round_rate, + .determine_rate = clk_alpha_pll_determine_rate, .set_rate = clk_alpha_pll_agera_set_rate, }; EXPORT_SYMBOL_GPL(clk_alpha_pll_agera_ops); @@ -2119,7 +2134,7 @@ const struct clk_ops clk_alpha_pll_lucid_5lpe_ops = { .disable = alpha_pll_lucid_5lpe_disable, .is_enabled = clk_trion_pll_is_enabled, .recalc_rate = clk_trion_pll_recalc_rate, - .round_rate = clk_alpha_pll_round_rate, + .determine_rate = clk_alpha_pll_determine_rate, .set_rate = alpha_pll_lucid_5lpe_set_rate, }; EXPORT_SYMBOL_GPL(clk_alpha_pll_lucid_5lpe_ops); @@ -2129,13 +2144,13 @@ const struct clk_ops clk_alpha_pll_fixed_lucid_5lpe_ops = { .disable = alpha_pll_lucid_5lpe_disable, .is_enabled = clk_trion_pll_is_enabled, .recalc_rate = clk_trion_pll_recalc_rate, - .round_rate = clk_alpha_pll_round_rate, + .determine_rate = clk_alpha_pll_determine_rate, }; EXPORT_SYMBOL_GPL(clk_alpha_pll_fixed_lucid_5lpe_ops); const struct clk_ops clk_alpha_pll_postdiv_lucid_5lpe_ops = { .recalc_rate = clk_alpha_pll_postdiv_fabia_recalc_rate, - .round_rate = clk_alpha_pll_postdiv_fabia_round_rate, + .determine_rate = clk_alpha_pll_postdiv_fabia_determine_rate, .set_rate = clk_lucid_5lpe_pll_postdiv_set_rate, }; EXPORT_SYMBOL_GPL(clk_alpha_pll_postdiv_lucid_5lpe_ops); @@ -2304,7 +2319,7 @@ const struct clk_ops clk_alpha_pll_zonda_ops = { .disable = clk_zonda_pll_disable, .is_enabled = clk_trion_pll_is_enabled, .recalc_rate = clk_trion_pll_recalc_rate, - .round_rate = clk_alpha_pll_round_rate, + .determine_rate = clk_alpha_pll_determine_rate, .set_rate = clk_zonda_pll_set_rate, }; EXPORT_SYMBOL_GPL(clk_alpha_pll_zonda_ops); @@ -2529,13 +2544,13 @@ const struct clk_ops clk_alpha_pll_fixed_lucid_evo_ops = { .disable = alpha_pll_lucid_evo_disable, .is_enabled = clk_trion_pll_is_enabled, .recalc_rate = alpha_pll_lucid_evo_recalc_rate, - .round_rate = clk_alpha_pll_round_rate, + .determine_rate = clk_alpha_pll_determine_rate, }; EXPORT_SYMBOL_GPL(clk_alpha_pll_fixed_lucid_evo_ops); const struct clk_ops clk_alpha_pll_postdiv_lucid_evo_ops = { .recalc_rate = clk_alpha_pll_postdiv_fabia_recalc_rate, - .round_rate = clk_alpha_pll_postdiv_fabia_round_rate, + .determine_rate = clk_alpha_pll_postdiv_fabia_determine_rate, .set_rate = clk_lucid_evo_pll_postdiv_set_rate, }; EXPORT_SYMBOL_GPL(clk_alpha_pll_postdiv_lucid_evo_ops); @@ -2546,7 +2561,7 @@ const struct clk_ops clk_alpha_pll_lucid_evo_ops = { .disable = alpha_pll_lucid_evo_disable, .is_enabled = clk_trion_pll_is_enabled, .recalc_rate = alpha_pll_lucid_evo_recalc_rate, - .round_rate = clk_alpha_pll_round_rate, + .determine_rate = clk_alpha_pll_determine_rate, .set_rate = alpha_pll_lucid_5lpe_set_rate, }; EXPORT_SYMBOL_GPL(clk_alpha_pll_lucid_evo_ops); @@ -2557,7 +2572,7 @@ const struct clk_ops clk_alpha_pll_reset_lucid_evo_ops = { .disable = alpha_pll_reset_lucid_evo_disable, .is_enabled = clk_trion_pll_is_enabled, .recalc_rate = alpha_pll_lucid_evo_recalc_rate, - .round_rate = clk_alpha_pll_round_rate, + .determine_rate = clk_alpha_pll_determine_rate, .set_rate = alpha_pll_lucid_5lpe_set_rate, }; EXPORT_SYMBOL_GPL(clk_alpha_pll_reset_lucid_evo_ops); @@ -2732,22 +2747,25 @@ static unsigned long clk_rivian_evo_pll_recalc_rate(struct clk_hw *hw, return parent_rate * l; } -static long clk_rivian_evo_pll_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *prate) +static int clk_rivian_evo_pll_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { struct clk_alpha_pll *pll = to_clk_alpha_pll(hw); unsigned long min_freq, max_freq; u32 l; u64 a; - rate = alpha_pll_round_rate(rate, *prate, &l, &a, 0); - if (!pll->vco_table || alpha_pll_find_vco(pll, rate)) - return rate; + req->rate = alpha_pll_round_rate(req->rate, req->best_parent_rate, &l, + &a, 0); + if (!pll->vco_table || alpha_pll_find_vco(pll, req->rate)) + return 0; min_freq = pll->vco_table[0].min_freq; max_freq = pll->vco_table[pll->num_vco - 1].max_freq; - return clamp(rate, min_freq, max_freq); + req->rate = clamp(req->rate, min_freq, max_freq); + + return 0; } const struct clk_ops clk_alpha_pll_rivian_evo_ops = { @@ -2755,7 +2773,7 @@ const struct clk_ops clk_alpha_pll_rivian_evo_ops = { .disable = alpha_pll_lucid_5lpe_disable, .is_enabled = clk_trion_pll_is_enabled, .recalc_rate = clk_rivian_evo_pll_recalc_rate, - .round_rate = clk_rivian_evo_pll_round_rate, + .determine_rate = clk_rivian_evo_pll_determine_rate, }; EXPORT_SYMBOL_GPL(clk_alpha_pll_rivian_evo_ops); @@ -2964,7 +2982,7 @@ const struct clk_ops clk_alpha_pll_regera_ops = { .disable = clk_zonda_pll_disable, .is_enabled = clk_alpha_pll_is_enabled, .recalc_rate = clk_trion_pll_recalc_rate, - .round_rate = clk_alpha_pll_round_rate, + .determine_rate = clk_alpha_pll_determine_rate, .set_rate = clk_zonda_pll_set_rate, }; EXPORT_SYMBOL_GPL(clk_alpha_pll_regera_ops); @@ -3169,7 +3187,7 @@ const struct clk_ops clk_alpha_pll_slew_ops = { .enable = clk_alpha_pll_slew_enable, .disable = clk_alpha_pll_disable, .recalc_rate = clk_alpha_pll_recalc_rate, - .round_rate = clk_alpha_pll_round_rate, + .determine_rate = clk_alpha_pll_determine_rate, .set_rate = clk_alpha_pll_slew_set_rate, }; EXPORT_SYMBOL(clk_alpha_pll_slew_ops); diff --git a/drivers/clk/qcom/clk-alpha-pll.h b/drivers/clk/qcom/clk-alpha-pll.h index ff41aeab0ab9..0903a05b18cc 100644 --- a/drivers/clk/qcom/clk-alpha-pll.h +++ b/drivers/clk/qcom/clk-alpha-pll.h @@ -29,6 +29,7 @@ enum { CLK_ALPHA_PLL_TYPE_LUCID_OLE, CLK_ALPHA_PLL_TYPE_PONGO_ELU, CLK_ALPHA_PLL_TYPE_TAYCAN_ELU, + CLK_ALPHA_PLL_TYPE_TAYCAN_EKO_T = CLK_ALPHA_PLL_TYPE_TAYCAN_ELU, CLK_ALPHA_PLL_TYPE_RIVIAN_EVO, CLK_ALPHA_PLL_TYPE_DEFAULT_EVO, CLK_ALPHA_PLL_TYPE_BRAMMO_EVO, @@ -192,14 +193,17 @@ extern const struct clk_ops clk_alpha_pll_zonda_ops; extern const struct clk_ops clk_alpha_pll_lucid_evo_ops; #define clk_alpha_pll_taycan_elu_ops clk_alpha_pll_lucid_evo_ops +#define clk_alpha_pll_taycan_eko_t_ops clk_alpha_pll_lucid_evo_ops extern const struct clk_ops clk_alpha_pll_reset_lucid_evo_ops; #define clk_alpha_pll_reset_lucid_ole_ops clk_alpha_pll_reset_lucid_evo_ops extern const struct clk_ops clk_alpha_pll_fixed_lucid_evo_ops; #define clk_alpha_pll_fixed_lucid_ole_ops clk_alpha_pll_fixed_lucid_evo_ops #define clk_alpha_pll_fixed_taycan_elu_ops clk_alpha_pll_fixed_lucid_evo_ops +#define clk_alpha_pll_fixed_taycan_eko_t_ops clk_alpha_pll_fixed_lucid_evo_ops extern const struct clk_ops clk_alpha_pll_postdiv_lucid_evo_ops; #define clk_alpha_pll_postdiv_lucid_ole_ops clk_alpha_pll_postdiv_lucid_evo_ops #define clk_alpha_pll_postdiv_taycan_elu_ops clk_alpha_pll_postdiv_lucid_evo_ops +#define clk_alpha_pll_postdiv_taycan_eko_t_ops clk_alpha_pll_postdiv_lucid_evo_ops extern const struct clk_ops clk_alpha_pll_pongo_elu_ops; extern const struct clk_ops clk_alpha_pll_rivian_evo_ops; @@ -233,6 +237,8 @@ void clk_pongo_elu_pll_configure(struct clk_alpha_pll *pll, struct regmap *regma const struct alpha_pll_config *config); #define clk_taycan_elu_pll_configure(pll, regmap, config) \ clk_lucid_evo_pll_configure(pll, regmap, config) +#define clk_taycan_eko_t_pll_configure(pll, regmap, config) \ + clk_lucid_evo_pll_configure(pll, regmap, config) void clk_rivian_evo_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap, const struct alpha_pll_config *config); diff --git a/drivers/clk/qcom/clk-cbf-8996.c b/drivers/clk/qcom/clk-cbf-8996.c index ce4efcd995ea..0b40ed601f9a 100644 --- a/drivers/clk/qcom/clk-cbf-8996.c +++ b/drivers/clk/qcom/clk-cbf-8996.c @@ -212,7 +212,6 @@ static const struct regmap_config cbf_msm8996_regmap_config = { .reg_stride = 4, .val_bits = 32, .max_register = 0x10000, - .fast_io = true, .val_format_endian = REGMAP_ENDIAN_LITTLE, }; diff --git a/drivers/clk/qcom/clk-cpu-8996.c b/drivers/clk/qcom/clk-cpu-8996.c index 72689448a653..21d13c0841ed 100644 --- a/drivers/clk/qcom/clk-cpu-8996.c +++ b/drivers/clk/qcom/clk-cpu-8996.c @@ -411,7 +411,6 @@ static const struct regmap_config cpu_msm8996_regmap_config = { .reg_stride = 4, .val_bits = 32, .max_register = 0x80210, - .fast_io = true, .val_format_endian = REGMAP_ENDIAN_LITTLE, }; diff --git a/drivers/clk/qcom/clk-rcg.c b/drivers/clk/qcom/clk-rcg.c index 987141c91fe0..31f0650b48ba 100644 --- a/drivers/clk/qcom/clk-rcg.c +++ b/drivers/clk/qcom/clk-rcg.c @@ -423,7 +423,7 @@ static int _freq_tbl_determine_rate(struct clk_hw *hw, const struct freq_tbl *f, rate = tmp; } } else { - rate = clk_hw_get_rate(p); + rate = clk_hw_get_rate(p); } req->best_parent_hw = p; req->best_parent_rate = rate; diff --git a/drivers/clk/qcom/clk-rcg2.c b/drivers/clk/qcom/clk-rcg2.c index 8001fd9faf9d..e18cb8807d73 100644 --- a/drivers/clk/qcom/clk-rcg2.c +++ b/drivers/clk/qcom/clk-rcg2.c @@ -201,7 +201,7 @@ __clk_rcg2_recalc_rate(struct clk_hw *hw, unsigned long parent_rate, u32 cfg) regmap_read(rcg->clkr.regmap, RCG_M_OFFSET(rcg), &m); m &= mask; regmap_read(rcg->clkr.regmap, RCG_N_OFFSET(rcg), &n); - n = ~n; + n = ~n; n &= mask; n += m; mode = cfg & CFG_MODE_MASK; @@ -274,7 +274,7 @@ static int _freq_tbl_determine_rate(struct clk_hw *hw, const struct freq_tbl *f, rate = tmp; } } else { - rate = clk_hw_get_rate(p); + rate = clk_hw_get_rate(p); } req->best_parent_hw = p; req->best_parent_rate = rate; @@ -311,7 +311,7 @@ __clk_rcg2_select_conf(struct clk_hw *hw, const struct freq_multi_tbl *f, if (!p) continue; - parent_rate = clk_hw_get_rate(p); + parent_rate = clk_hw_get_rate(p); rate = calc_rate(parent_rate, conf->n, conf->m, conf->n, conf->pre_div); if (rate == req_rate) { @@ -382,7 +382,7 @@ static int _freq_tbl_fm_determine_rate(struct clk_hw *hw, const struct freq_mult rate = tmp; } } else { - rate = clk_hw_get_rate(p); + rate = clk_hw_get_rate(p); } req->best_parent_hw = p; diff --git a/drivers/clk/qcom/clk-regmap-divider.c b/drivers/clk/qcom/clk-regmap-divider.c index 63c9fca0d65d..4f5395f0ab6d 100644 --- a/drivers/clk/qcom/clk-regmap-divider.c +++ b/drivers/clk/qcom/clk-regmap-divider.c @@ -15,8 +15,8 @@ static inline struct clk_regmap_div *to_clk_regmap_div(struct clk_hw *hw) return container_of(to_clk_regmap(hw), struct clk_regmap_div, clkr); } -static long div_round_ro_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *prate) +static int div_ro_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { struct clk_regmap_div *divider = to_clk_regmap_div(hw); struct clk_regmap *clkr = ÷r->clkr; @@ -26,17 +26,24 @@ static long div_round_ro_rate(struct clk_hw *hw, unsigned long rate, val >>= divider->shift; val &= BIT(divider->width) - 1; - return divider_ro_round_rate(hw, rate, prate, NULL, divider->width, - CLK_DIVIDER_ROUND_CLOSEST, val); + req->rate = divider_ro_round_rate(hw, req->rate, + &req->best_parent_rate, NULL, + divider->width, + CLK_DIVIDER_ROUND_CLOSEST, val); + + return 0; } -static long div_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *prate) +static int div_determine_rate(struct clk_hw *hw, struct clk_rate_request *req) { struct clk_regmap_div *divider = to_clk_regmap_div(hw); - return divider_round_rate(hw, rate, prate, NULL, divider->width, - CLK_DIVIDER_ROUND_CLOSEST); + req->rate = divider_round_rate(hw, req->rate, &req->best_parent_rate, + NULL, + divider->width, + CLK_DIVIDER_ROUND_CLOSEST); + + return 0; } static int div_set_rate(struct clk_hw *hw, unsigned long rate, @@ -70,14 +77,14 @@ static unsigned long div_recalc_rate(struct clk_hw *hw, } const struct clk_ops clk_regmap_div_ops = { - .round_rate = div_round_rate, + .determine_rate = div_determine_rate, .set_rate = div_set_rate, .recalc_rate = div_recalc_rate, }; EXPORT_SYMBOL_GPL(clk_regmap_div_ops); const struct clk_ops clk_regmap_div_ro_ops = { - .round_rate = div_round_ro_rate, + .determine_rate = div_ro_determine_rate, .recalc_rate = div_recalc_rate, }; EXPORT_SYMBOL_GPL(clk_regmap_div_ro_ops); diff --git a/drivers/clk/qcom/clk-rpmh.c b/drivers/clk/qcom/clk-rpmh.c index 1496fb3de4be..63c38cb47bc4 100644 --- a/drivers/clk/qcom/clk-rpmh.c +++ b/drivers/clk/qcom/clk-rpmh.c @@ -87,7 +87,7 @@ static DEFINE_MUTEX(rpmh_clk_lock); .hw.init = &(struct clk_init_data){ \ .ops = &clk_rpmh_ops, \ .name = #_name, \ - .parent_data = &(const struct clk_parent_data){ \ + .parent_data = &(const struct clk_parent_data){ \ .fw_name = "xo", \ .name = "xo_board", \ }, \ @@ -105,7 +105,7 @@ static DEFINE_MUTEX(rpmh_clk_lock); .hw.init = &(struct clk_init_data){ \ .ops = &clk_rpmh_ops, \ .name = #_name "_ao", \ - .parent_data = &(const struct clk_parent_data){ \ + .parent_data = &(const struct clk_parent_data){ \ .fw_name = "xo", \ .name = "xo_board", \ }, \ @@ -182,7 +182,7 @@ static int clk_rpmh_send_aggregate_command(struct clk_rpmh *c) } c->last_sent_aggr_state = c->aggr_state; - c->peer->last_sent_aggr_state = c->last_sent_aggr_state; + c->peer->last_sent_aggr_state = c->last_sent_aggr_state; return 0; } @@ -390,6 +390,11 @@ DEFINE_CLK_RPMH_VRM(clk7, _a4, "clka7", 4); DEFINE_CLK_RPMH_VRM(div_clk1, _div2, "divclka1", 2); +DEFINE_CLK_RPMH_VRM(clk3, _a, "C3A_E0", 1); +DEFINE_CLK_RPMH_VRM(clk4, _a, "C4A_E0", 1); +DEFINE_CLK_RPMH_VRM(clk5, _a, "C5A_E0", 1); +DEFINE_CLK_RPMH_VRM(clk8, _a, "C8A_E0", 1); + DEFINE_CLK_RPMH_BCM(ce, "CE0"); DEFINE_CLK_RPMH_BCM(hwkm, "HK0"); DEFINE_CLK_RPMH_BCM(ipa, "IP0"); @@ -879,6 +884,22 @@ static const struct clk_rpmh_desc clk_rpmh_sm8750 = { .clka_optional = true, }; +static struct clk_hw *glymur_rpmh_clocks[] = { + [RPMH_CXO_CLK] = &clk_rpmh_bi_tcxo_div2.hw, + [RPMH_CXO_CLK_A] = &clk_rpmh_bi_tcxo_div2_ao.hw, + [RPMH_RF_CLK3] = &clk_rpmh_clk3_a.hw, + [RPMH_RF_CLK3_A] = &clk_rpmh_clk3_a_ao.hw, + [RPMH_RF_CLK4] = &clk_rpmh_clk4_a.hw, + [RPMH_RF_CLK4_A] = &clk_rpmh_clk4_a_ao.hw, + [RPMH_RF_CLK5] = &clk_rpmh_clk5_a.hw, + [RPMH_RF_CLK5_A] = &clk_rpmh_clk5_a_ao.hw, +}; + +static const struct clk_rpmh_desc clk_rpmh_glymur = { + .clks = glymur_rpmh_clocks, + .num_clks = ARRAY_SIZE(glymur_rpmh_clocks), +}; + static struct clk_hw *of_clk_rpmh_hw_get(struct of_phandle_args *clkspec, void *data) { @@ -968,6 +989,7 @@ static int clk_rpmh_probe(struct platform_device *pdev) } static const struct of_device_id clk_rpmh_match_table[] = { + { .compatible = "qcom,glymur-rpmh-clk", .data = &clk_rpmh_glymur}, { .compatible = "qcom,milos-rpmh-clk", .data = &clk_rpmh_milos}, { .compatible = "qcom,qcs615-rpmh-clk", .data = &clk_rpmh_qcs615}, { .compatible = "qcom,qdu1000-rpmh-clk", .data = &clk_rpmh_qdu1000}, diff --git a/drivers/clk/qcom/clk-smd-rpm.c b/drivers/clk/qcom/clk-smd-rpm.c index 3bf6df3884a5..103db984a40b 100644 --- a/drivers/clk/qcom/clk-smd-rpm.c +++ b/drivers/clk/qcom/clk-smd-rpm.c @@ -30,7 +30,7 @@ .hw.init = &(struct clk_init_data){ \ .ops = &clk_smd_rpm_ops, \ .name = #_name, \ - .parent_data = &(const struct clk_parent_data){ \ + .parent_data = &(const struct clk_parent_data){ \ .fw_name = "xo", \ .name = "xo_board", \ }, \ @@ -47,7 +47,7 @@ .hw.init = &(struct clk_init_data){ \ .ops = &clk_smd_rpm_ops, \ .name = #_active, \ - .parent_data = &(const struct clk_parent_data){ \ + .parent_data = &(const struct clk_parent_data){ \ .fw_name = "xo", \ .name = "xo_board", \ }, \ @@ -74,7 +74,7 @@ .hw.init = &(struct clk_init_data){ \ .ops = &clk_smd_rpm_branch_ops, \ .name = #_name, \ - .parent_data = &(const struct clk_parent_data){ \ + .parent_data = &(const struct clk_parent_data){ \ .fw_name = "xo", \ .name = "xo_board", \ }, \ @@ -92,7 +92,7 @@ .hw.init = &(struct clk_init_data){ \ .ops = &clk_smd_rpm_branch_ops, \ .name = #_active, \ - .parent_data = &(const struct clk_parent_data){ \ + .parent_data = &(const struct clk_parent_data){ \ .fw_name = "xo", \ .name = "xo_board", \ }, \ diff --git a/drivers/clk/qcom/common.c b/drivers/clk/qcom/common.c index 37c3008e6c1b..121591886774 100644 --- a/drivers/clk/qcom/common.c +++ b/drivers/clk/qcom/common.c @@ -277,8 +277,8 @@ static int qcom_cc_icc_register(struct device *dev, icd[i].slave_id = desc->icc_hws[i].slave_id; hws = &desc->clks[desc->icc_hws[i].clk_id]->hw; icd[i].clk = devm_clk_hw_get_clk(dev, hws, "icc"); - if (!icd[i].clk) - return dev_err_probe(dev, -ENOENT, + if (IS_ERR(icd[i].clk)) + return dev_err_probe(dev, PTR_ERR(icd[i].clk), "(%d) clock entry is null\n", i); icd[i].name = clk_hw_get_name(hws); } diff --git a/drivers/clk/qcom/dispcc-glymur.c b/drivers/clk/qcom/dispcc-glymur.c new file mode 100644 index 000000000000..5203fa6383f6 --- /dev/null +++ b/drivers/clk/qcom/dispcc-glymur.c @@ -0,0 +1,1982 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2025, Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#include <linux/clk-provider.h> +#include <linux/mod_devicetable.h> +#include <linux/module.h> +#include <linux/of.h> +#include <linux/platform_device.h> +#include <linux/pm_runtime.h> +#include <linux/regmap.h> + +#include <dt-bindings/clock/qcom,glymur-dispcc.h> + +#include "clk-alpha-pll.h" +#include "clk-branch.h" +#include "clk-pll.h" +#include "clk-rcg.h" +#include "clk-regmap.h" +#include "clk-regmap-divider.h" +#include "clk-regmap-mux.h" +#include "common.h" +#include "gdsc.h" +#include "reset.h" + +enum { + DT_BI_TCXO, + DT_SLEEP_CLK, + DT_DP0_PHY_PLL_LINK_CLK, + DT_DP0_PHY_PLL_VCO_DIV_CLK, + DT_DP1_PHY_PLL_LINK_CLK, + DT_DP1_PHY_PLL_VCO_DIV_CLK, + DT_DP2_PHY_PLL_LINK_CLK, + DT_DP2_PHY_PLL_VCO_DIV_CLK, + DT_DP3_PHY_PLL_LINK_CLK, + DT_DP3_PHY_PLL_VCO_DIV_CLK, + DT_DSI0_PHY_PLL_OUT_BYTECLK, + DT_DSI0_PHY_PLL_OUT_DSICLK, + DT_DSI1_PHY_PLL_OUT_BYTECLK, + DT_DSI1_PHY_PLL_OUT_DSICLK, + DT_STANDALONE_PHY_PLL0_LINK_CLK, + DT_STANDALONE_PHY_PLL0_VCO_DIV_CLK, + DT_STANDALONE_PHY_PLL1_LINK_CLK, + DT_STANDALONE_PHY_PLL1_VCO_DIV_CLK, +}; + +enum { + P_BI_TCXO, + P_SLEEP_CLK, + P_DISP_CC_PLL0_OUT_MAIN, + P_DISP_CC_PLL1_OUT_EVEN, + P_DISP_CC_PLL1_OUT_MAIN, + P_DP0_PHY_PLL_LINK_CLK, + P_DP0_PHY_PLL_VCO_DIV_CLK, + P_DP1_PHY_PLL_LINK_CLK, + P_DP1_PHY_PLL_VCO_DIV_CLK, + P_DP2_PHY_PLL_LINK_CLK, + P_DP2_PHY_PLL_VCO_DIV_CLK, + P_DP3_PHY_PLL_LINK_CLK, + P_DP3_PHY_PLL_VCO_DIV_CLK, + P_DSI0_PHY_PLL_OUT_BYTECLK, + P_DSI0_PHY_PLL_OUT_DSICLK, + P_DSI1_PHY_PLL_OUT_BYTECLK, + P_DSI1_PHY_PLL_OUT_DSICLK, + P_STANDALONE_PHY_PLL0_LINK_CLK, + P_STANDALONE_PHY_PLL0_VCO_DIV_CLK, + P_STANDALONE_PHY_PLL1_LINK_CLK, + P_STANDALONE_PHY_PLL1_VCO_DIV_CLK, +}; + +static const struct pll_vco taycan_eko_t_vco[] = { + { 249600000, 2500000000, 0 }, +}; + +/* 257.142858 MHz Configuration */ +static const struct alpha_pll_config disp_cc_pll0_config = { + .l = 0xd, + .alpha = 0x6492, + .config_ctl_val = 0x25c400e7, + .config_ctl_hi_val = 0x0a8060e0, + .config_ctl_hi1_val = 0xf51dea20, + .user_ctl_val = 0x00000008, + .user_ctl_hi_val = 0x00000002, +}; + +static struct clk_alpha_pll disp_cc_pll0 = { + .offset = 0x0, + .config = &disp_cc_pll0_config, + .vco_table = taycan_eko_t_vco, + .num_vco = ARRAY_SIZE(taycan_eko_t_vco), + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_TAYCAN_EKO_T], + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_pll0", + .parent_data = &(const struct clk_parent_data) { + .index = DT_BI_TCXO, + }, + .num_parents = 1, + .ops = &clk_alpha_pll_taycan_eko_t_ops, + }, + }, +}; + +/* 600.0 MHz Configuration */ +static const struct alpha_pll_config disp_cc_pll1_config = { + .l = 0x1f, + .alpha = 0x4000, + .config_ctl_val = 0x25c400e7, + .config_ctl_hi_val = 0x0a8060e0, + .config_ctl_hi1_val = 0xf51dea20, + .user_ctl_val = 0x00000008, + .user_ctl_hi_val = 0x00000002, +}; + +static struct clk_alpha_pll disp_cc_pll1 = { + .offset = 0x1000, + .config = &disp_cc_pll1_config, + .vco_table = taycan_eko_t_vco, + .num_vco = ARRAY_SIZE(taycan_eko_t_vco), + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_TAYCAN_EKO_T], + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_pll1", + .parent_data = &(const struct clk_parent_data) { + .index = DT_BI_TCXO, + }, + .num_parents = 1, + .ops = &clk_alpha_pll_taycan_eko_t_ops, + }, + }, +}; + +static const struct parent_map disp_cc_parent_map_0[] = { + { P_BI_TCXO, 0 }, + { P_STANDALONE_PHY_PLL0_VCO_DIV_CLK, 1 }, + { P_DP0_PHY_PLL_VCO_DIV_CLK, 2 }, + { P_DP3_PHY_PLL_VCO_DIV_CLK, 3 }, + { P_DP1_PHY_PLL_VCO_DIV_CLK, 4 }, + { P_STANDALONE_PHY_PLL1_VCO_DIV_CLK, 5 }, + { P_DP2_PHY_PLL_VCO_DIV_CLK, 6 }, +}; + +static const struct clk_parent_data disp_cc_parent_data_0[] = { + { .index = DT_BI_TCXO }, + { .index = DT_STANDALONE_PHY_PLL0_VCO_DIV_CLK }, + { .index = DT_DP0_PHY_PLL_VCO_DIV_CLK }, + { .index = DT_DP3_PHY_PLL_VCO_DIV_CLK }, + { .index = DT_DP1_PHY_PLL_VCO_DIV_CLK }, + { .index = DT_STANDALONE_PHY_PLL1_VCO_DIV_CLK }, + { .index = DT_DP2_PHY_PLL_VCO_DIV_CLK }, +}; + +static const struct parent_map disp_cc_parent_map_1[] = { + { P_BI_TCXO, 0 }, +}; + +static const struct clk_parent_data disp_cc_parent_data_1[] = { + { .index = DT_BI_TCXO }, +}; + +static const struct parent_map disp_cc_parent_map_2[] = { + { P_BI_TCXO, 0 }, + { P_DSI0_PHY_PLL_OUT_DSICLK, 1 }, + { P_DSI0_PHY_PLL_OUT_BYTECLK, 2 }, + { P_DSI1_PHY_PLL_OUT_DSICLK, 3 }, + { P_DSI1_PHY_PLL_OUT_BYTECLK, 4 }, +}; + +static const struct clk_parent_data disp_cc_parent_data_2[] = { + { .index = DT_BI_TCXO }, + { .index = DT_DSI0_PHY_PLL_OUT_DSICLK }, + { .index = DT_DSI0_PHY_PLL_OUT_BYTECLK }, + { .index = DT_DSI1_PHY_PLL_OUT_DSICLK }, + { .index = DT_DSI1_PHY_PLL_OUT_BYTECLK }, +}; + +static const struct parent_map disp_cc_parent_map_3[] = { + { P_BI_TCXO, 0 }, + { P_DP0_PHY_PLL_LINK_CLK, 1 }, + { P_DP1_PHY_PLL_LINK_CLK, 2 }, + { P_DP2_PHY_PLL_LINK_CLK, 3 }, + { P_DP3_PHY_PLL_LINK_CLK, 4 }, + { P_STANDALONE_PHY_PLL1_LINK_CLK, 5 }, + { P_STANDALONE_PHY_PLL0_LINK_CLK, 6 }, +}; + +static const struct clk_parent_data disp_cc_parent_data_3[] = { + { .index = DT_BI_TCXO }, + { .index = DT_DP0_PHY_PLL_LINK_CLK }, + { .index = DT_DP1_PHY_PLL_LINK_CLK }, + { .index = DT_DP2_PHY_PLL_LINK_CLK }, + { .index = DT_DP3_PHY_PLL_LINK_CLK }, + { .index = DT_STANDALONE_PHY_PLL1_LINK_CLK }, + { .index = DT_STANDALONE_PHY_PLL0_LINK_CLK }, +}; + +static const struct parent_map disp_cc_parent_map_4[] = { + { P_BI_TCXO, 0 }, + { P_DSI0_PHY_PLL_OUT_DSICLK, 1 }, + { P_DSI1_PHY_PLL_OUT_DSICLK, 3 }, +}; + +static const struct clk_parent_data disp_cc_parent_data_4[] = { + { .index = DT_BI_TCXO }, + { .index = DT_DSI0_PHY_PLL_OUT_DSICLK }, + { .index = DT_DSI1_PHY_PLL_OUT_DSICLK }, +}; + +static const struct parent_map disp_cc_parent_map_5[] = { + { P_BI_TCXO, 0 }, + { P_DSI0_PHY_PLL_OUT_BYTECLK, 2 }, + { P_DSI1_PHY_PLL_OUT_BYTECLK, 4 }, +}; + +static const struct clk_parent_data disp_cc_parent_data_5[] = { + { .index = DT_BI_TCXO }, + { .index = DT_DSI0_PHY_PLL_OUT_BYTECLK }, + { .index = DT_DSI1_PHY_PLL_OUT_BYTECLK }, +}; + +static const struct parent_map disp_cc_parent_map_6[] = { + { P_BI_TCXO, 0 }, + { P_DISP_CC_PLL1_OUT_MAIN, 4 }, + { P_DISP_CC_PLL1_OUT_EVEN, 6 }, +}; + +static const struct clk_parent_data disp_cc_parent_data_6[] = { + { .index = DT_BI_TCXO }, + { .hw = &disp_cc_pll1.clkr.hw }, + { .hw = &disp_cc_pll1.clkr.hw }, +}; + +static const struct parent_map disp_cc_parent_map_7[] = { + { P_BI_TCXO, 0 }, + { P_DISP_CC_PLL0_OUT_MAIN, 1 }, + { P_DISP_CC_PLL1_OUT_MAIN, 4 }, + { P_DISP_CC_PLL1_OUT_EVEN, 6 }, +}; + +static const struct clk_parent_data disp_cc_parent_data_7[] = { + { .index = DT_BI_TCXO }, + { .hw = &disp_cc_pll0.clkr.hw }, + { .hw = &disp_cc_pll1.clkr.hw }, + { .hw = &disp_cc_pll1.clkr.hw }, +}; + +static const struct parent_map disp_cc_parent_map_8[] = { + { P_BI_TCXO, 0 }, +}; + +static const struct clk_parent_data disp_cc_parent_data_8[] = { + { .index = DT_BI_TCXO }, +}; + +static const struct parent_map disp_cc_parent_map_9[] = { + { P_SLEEP_CLK, 0 }, +}; + +static const struct clk_parent_data disp_cc_parent_data_9[] = { + { .index = DT_SLEEP_CLK }, +}; + +static const struct freq_tbl ftbl_disp_cc_esync0_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + { } +}; + +static struct clk_rcg2 disp_cc_esync0_clk_src = { + .cmd_rcgr = 0x80c0, + .mnd_width = 16, + .hid_width = 5, + .parent_map = disp_cc_parent_map_4, + .freq_tbl = ftbl_disp_cc_esync0_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "disp_cc_esync0_clk_src", + .parent_data = disp_cc_parent_data_4, + .num_parents = ARRAY_SIZE(disp_cc_parent_data_4), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_rcg2 disp_cc_esync1_clk_src = { + .cmd_rcgr = 0x80d8, + .mnd_width = 16, + .hid_width = 5, + .parent_map = disp_cc_parent_map_4, + .freq_tbl = ftbl_disp_cc_esync0_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "disp_cc_esync1_clk_src", + .parent_data = disp_cc_parent_data_4, + .num_parents = ARRAY_SIZE(disp_cc_parent_data_4), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static const struct freq_tbl ftbl_disp_cc_mdss_ahb_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + F(37500000, P_DISP_CC_PLL1_OUT_MAIN, 16, 0, 0), + F(75000000, P_DISP_CC_PLL1_OUT_MAIN, 8, 0, 0), + { } +}; + +static struct clk_rcg2 disp_cc_mdss_ahb_clk_src = { + .cmd_rcgr = 0x8360, + .mnd_width = 0, + .hid_width = 5, + .parent_map = disp_cc_parent_map_6, + .freq_tbl = ftbl_disp_cc_mdss_ahb_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_ahb_clk_src", + .parent_data = disp_cc_parent_data_6, + .num_parents = ARRAY_SIZE(disp_cc_parent_data_6), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_rcg2 disp_cc_mdss_byte0_clk_src = { + .cmd_rcgr = 0x8180, + .mnd_width = 0, + .hid_width = 5, + .parent_map = disp_cc_parent_map_2, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_byte0_clk_src", + .parent_data = disp_cc_parent_data_2, + .num_parents = ARRAY_SIZE(disp_cc_parent_data_2), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_byte2_ops, + }, +}; + +static struct clk_rcg2 disp_cc_mdss_byte1_clk_src = { + .cmd_rcgr = 0x819c, + .mnd_width = 0, + .hid_width = 5, + .parent_map = disp_cc_parent_map_2, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_byte1_clk_src", + .parent_data = disp_cc_parent_data_2, + .num_parents = ARRAY_SIZE(disp_cc_parent_data_2), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_byte2_ops, + }, +}; + +static struct clk_rcg2 disp_cc_mdss_dptx0_aux_clk_src = { + .cmd_rcgr = 0x8234, + .mnd_width = 0, + .hid_width = 5, + .parent_map = disp_cc_parent_map_1, + .freq_tbl = ftbl_disp_cc_esync0_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_dptx0_aux_clk_src", + .parent_data = disp_cc_parent_data_1, + .num_parents = ARRAY_SIZE(disp_cc_parent_data_1), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_rcg2 disp_cc_mdss_dptx0_link_clk_src = { + .cmd_rcgr = 0x81e8, + .mnd_width = 0, + .hid_width = 5, + .parent_map = disp_cc_parent_map_3, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_dptx0_link_clk_src", + .parent_data = disp_cc_parent_data_3, + .num_parents = ARRAY_SIZE(disp_cc_parent_data_3), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_byte2_ops, + }, +}; + +static struct clk_rcg2 disp_cc_mdss_dptx0_pixel0_clk_src = { + .cmd_rcgr = 0x8204, + .mnd_width = 16, + .hid_width = 5, + .parent_map = disp_cc_parent_map_0, + .freq_tbl = ftbl_disp_cc_esync0_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_dptx0_pixel0_clk_src", + .parent_data = disp_cc_parent_data_0, + .num_parents = ARRAY_SIZE(disp_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_dp_ops, + }, +}; + +static struct clk_rcg2 disp_cc_mdss_dptx0_pixel1_clk_src = { + .cmd_rcgr = 0x821c, + .mnd_width = 16, + .hid_width = 5, + .parent_map = disp_cc_parent_map_0, + .freq_tbl = ftbl_disp_cc_esync0_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_dptx0_pixel1_clk_src", + .parent_data = disp_cc_parent_data_0, + .num_parents = ARRAY_SIZE(disp_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_dp_ops, + }, +}; + +static struct clk_rcg2 disp_cc_mdss_dptx1_aux_clk_src = { + .cmd_rcgr = 0x8298, + .mnd_width = 0, + .hid_width = 5, + .parent_map = disp_cc_parent_map_1, + .freq_tbl = ftbl_disp_cc_esync0_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_dptx1_aux_clk_src", + .parent_data = disp_cc_parent_data_1, + .num_parents = ARRAY_SIZE(disp_cc_parent_data_1), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_dp_ops, + }, +}; + +static struct clk_rcg2 disp_cc_mdss_dptx1_link_clk_src = { + .cmd_rcgr = 0x827c, + .mnd_width = 0, + .hid_width = 5, + .parent_map = disp_cc_parent_map_3, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_dptx1_link_clk_src", + .parent_data = disp_cc_parent_data_3, + .num_parents = ARRAY_SIZE(disp_cc_parent_data_3), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_byte2_ops, + }, +}; + +static struct clk_rcg2 disp_cc_mdss_dptx1_pixel0_clk_src = { + .cmd_rcgr = 0x824c, + .mnd_width = 16, + .hid_width = 5, + .parent_map = disp_cc_parent_map_0, + .freq_tbl = ftbl_disp_cc_esync0_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_dptx1_pixel0_clk_src", + .parent_data = disp_cc_parent_data_0, + .num_parents = ARRAY_SIZE(disp_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_dp_ops, + }, +}; + +static struct clk_rcg2 disp_cc_mdss_dptx1_pixel1_clk_src = { + .cmd_rcgr = 0x8264, + .mnd_width = 16, + .hid_width = 5, + .parent_map = disp_cc_parent_map_0, + .freq_tbl = ftbl_disp_cc_esync0_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_dptx1_pixel1_clk_src", + .parent_data = disp_cc_parent_data_0, + .num_parents = ARRAY_SIZE(disp_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_dp_ops, + }, +}; + +static struct clk_rcg2 disp_cc_mdss_dptx2_aux_clk_src = { + .cmd_rcgr = 0x82fc, + .mnd_width = 0, + .hid_width = 5, + .parent_map = disp_cc_parent_map_1, + .freq_tbl = ftbl_disp_cc_esync0_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_dptx2_aux_clk_src", + .parent_data = disp_cc_parent_data_1, + .num_parents = ARRAY_SIZE(disp_cc_parent_data_1), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_rcg2 disp_cc_mdss_dptx2_link_clk_src = { + .cmd_rcgr = 0x82b0, + .mnd_width = 0, + .hid_width = 5, + .parent_map = disp_cc_parent_map_3, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_dptx2_link_clk_src", + .parent_data = disp_cc_parent_data_3, + .num_parents = ARRAY_SIZE(disp_cc_parent_data_3), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_byte2_ops, + }, +}; + +static struct clk_rcg2 disp_cc_mdss_dptx2_pixel0_clk_src = { + .cmd_rcgr = 0x82cc, + .mnd_width = 16, + .hid_width = 5, + .parent_map = disp_cc_parent_map_0, + .freq_tbl = ftbl_disp_cc_esync0_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_dptx2_pixel0_clk_src", + .parent_data = disp_cc_parent_data_0, + .num_parents = ARRAY_SIZE(disp_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_dp_ops, + }, +}; + +static struct clk_rcg2 disp_cc_mdss_dptx2_pixel1_clk_src = { + .cmd_rcgr = 0x82e4, + .mnd_width = 16, + .hid_width = 5, + .parent_map = disp_cc_parent_map_0, + .freq_tbl = ftbl_disp_cc_esync0_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_dptx2_pixel1_clk_src", + .parent_data = disp_cc_parent_data_0, + .num_parents = ARRAY_SIZE(disp_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_dp_ops, + }, +}; + +static struct clk_rcg2 disp_cc_mdss_dptx3_aux_clk_src = { + .cmd_rcgr = 0x8348, + .mnd_width = 0, + .hid_width = 5, + .parent_map = disp_cc_parent_map_1, + .freq_tbl = ftbl_disp_cc_esync0_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_dptx3_aux_clk_src", + .parent_data = disp_cc_parent_data_1, + .num_parents = ARRAY_SIZE(disp_cc_parent_data_1), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_rcg2 disp_cc_mdss_dptx3_link_clk_src = { + .cmd_rcgr = 0x832c, + .mnd_width = 0, + .hid_width = 5, + .parent_map = disp_cc_parent_map_3, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_dptx3_link_clk_src", + .parent_data = disp_cc_parent_data_3, + .num_parents = ARRAY_SIZE(disp_cc_parent_data_3), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_byte2_ops, + }, +}; + +static struct clk_rcg2 disp_cc_mdss_dptx3_pixel0_clk_src = { + .cmd_rcgr = 0x8314, + .mnd_width = 16, + .hid_width = 5, + .parent_map = disp_cc_parent_map_0, + .freq_tbl = ftbl_disp_cc_esync0_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_dptx3_pixel0_clk_src", + .parent_data = disp_cc_parent_data_0, + .num_parents = ARRAY_SIZE(disp_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_dp_ops, + }, +}; + +static struct clk_rcg2 disp_cc_mdss_esc0_clk_src = { + .cmd_rcgr = 0x81b8, + .mnd_width = 0, + .hid_width = 5, + .parent_map = disp_cc_parent_map_5, + .freq_tbl = ftbl_disp_cc_esync0_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_esc0_clk_src", + .parent_data = disp_cc_parent_data_5, + .num_parents = ARRAY_SIZE(disp_cc_parent_data_5), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_rcg2 disp_cc_mdss_esc1_clk_src = { + .cmd_rcgr = 0x81d0, + .mnd_width = 0, + .hid_width = 5, + .parent_map = disp_cc_parent_map_5, + .freq_tbl = ftbl_disp_cc_esync0_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_esc1_clk_src", + .parent_data = disp_cc_parent_data_5, + .num_parents = ARRAY_SIZE(disp_cc_parent_data_5), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static const struct freq_tbl ftbl_disp_cc_mdss_mdp_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + F(85714286, P_DISP_CC_PLL0_OUT_MAIN, 3, 0, 0), + F(100000000, P_DISP_CC_PLL0_OUT_MAIN, 3, 0, 0), + F(150000000, P_DISP_CC_PLL0_OUT_MAIN, 3, 0, 0), + F(156000000, P_DISP_CC_PLL0_OUT_MAIN, 3, 0, 0), + F(205000000, P_DISP_CC_PLL0_OUT_MAIN, 3, 0, 0), + F(337000000, P_DISP_CC_PLL0_OUT_MAIN, 3, 0, 0), + F(417000000, P_DISP_CC_PLL0_OUT_MAIN, 3, 0, 0), + F(532000000, P_DISP_CC_PLL0_OUT_MAIN, 3, 0, 0), + F(600000000, P_DISP_CC_PLL0_OUT_MAIN, 3, 0, 0), + F(660000000, P_DISP_CC_PLL0_OUT_MAIN, 3, 0, 0), + F(717000000, P_DISP_CC_PLL0_OUT_MAIN, 3, 0, 0), + { } +}; + +static struct clk_rcg2 disp_cc_mdss_mdp_clk_src = { + .cmd_rcgr = 0x8150, + .mnd_width = 0, + .hid_width = 5, + .parent_map = disp_cc_parent_map_7, + .freq_tbl = ftbl_disp_cc_mdss_mdp_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_mdp_clk_src", + .parent_data = disp_cc_parent_data_7, + .num_parents = ARRAY_SIZE(disp_cc_parent_data_7), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_rcg2 disp_cc_mdss_pclk0_clk_src = { + .cmd_rcgr = 0x8108, + .mnd_width = 8, + .hid_width = 5, + .parent_map = disp_cc_parent_map_2, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_pclk0_clk_src", + .parent_data = disp_cc_parent_data_2, + .num_parents = ARRAY_SIZE(disp_cc_parent_data_2), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_pixel_ops, + }, +}; + +static struct clk_rcg2 disp_cc_mdss_pclk1_clk_src = { + .cmd_rcgr = 0x8120, + .mnd_width = 8, + .hid_width = 5, + .parent_map = disp_cc_parent_map_2, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_pclk1_clk_src", + .parent_data = disp_cc_parent_data_2, + .num_parents = ARRAY_SIZE(disp_cc_parent_data_2), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_pixel_ops, + }, +}; + +static struct clk_rcg2 disp_cc_mdss_pclk2_clk_src = { + .cmd_rcgr = 0x8138, + .mnd_width = 8, + .hid_width = 5, + .parent_map = disp_cc_parent_map_2, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_pclk2_clk_src", + .parent_data = disp_cc_parent_data_2, + .num_parents = ARRAY_SIZE(disp_cc_parent_data_2), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_pixel_ops, + }, +}; + +static struct clk_rcg2 disp_cc_mdss_vsync_clk_src = { + .cmd_rcgr = 0x8168, + .mnd_width = 0, + .hid_width = 5, + .parent_map = disp_cc_parent_map_1, + .freq_tbl = ftbl_disp_cc_esync0_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_vsync_clk_src", + .parent_data = disp_cc_parent_data_1, + .num_parents = ARRAY_SIZE(disp_cc_parent_data_1), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_rcg2 disp_cc_osc_clk_src = { + .cmd_rcgr = 0x80f0, + .mnd_width = 0, + .hid_width = 5, + .parent_map = disp_cc_parent_map_8, + .freq_tbl = ftbl_disp_cc_esync0_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "disp_cc_osc_clk_src", + .parent_data = disp_cc_parent_data_8, + .num_parents = ARRAY_SIZE(disp_cc_parent_data_8), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static const struct freq_tbl ftbl_disp_cc_sleep_clk_src[] = { + F(32000, P_SLEEP_CLK, 1, 0, 0), + { } +}; + +static struct clk_rcg2 disp_cc_sleep_clk_src = { + .cmd_rcgr = 0xe064, + .mnd_width = 0, + .hid_width = 5, + .parent_map = disp_cc_parent_map_9, + .freq_tbl = ftbl_disp_cc_sleep_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "disp_cc_sleep_clk_src", + .parent_data = disp_cc_parent_data_9, + .num_parents = ARRAY_SIZE(disp_cc_parent_data_9), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_rcg2 disp_cc_xo_clk_src = { + .cmd_rcgr = 0xe044, + .mnd_width = 0, + .hid_width = 5, + .parent_map = disp_cc_parent_map_1, + .freq_tbl = ftbl_disp_cc_esync0_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "disp_cc_xo_clk_src", + .parent_data = disp_cc_parent_data_1, + .num_parents = ARRAY_SIZE(disp_cc_parent_data_1), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_regmap_div disp_cc_mdss_byte0_div_clk_src = { + .reg = 0x8198, + .shift = 0, + .width = 4, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_byte0_div_clk_src", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_byte0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_regmap_div_ops, + }, +}; + +static struct clk_regmap_div disp_cc_mdss_byte1_div_clk_src = { + .reg = 0x81b4, + .shift = 0, + .width = 4, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_byte1_div_clk_src", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_byte1_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_regmap_div_ops, + }, +}; + +static struct clk_regmap_div disp_cc_mdss_dptx0_link_div_clk_src = { + .reg = 0x8200, + .shift = 0, + .width = 4, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_dptx0_link_div_clk_src", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_dptx0_link_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_regmap_div_ro_ops, + }, +}; + +static struct clk_regmap_div disp_cc_mdss_dptx0_link_dpin_div_clk_src = { + .reg = 0x838c, + .shift = 0, + .width = 4, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_dptx0_link_dpin_div_clk_src", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_dptx0_link_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_regmap_div_ro_ops, + }, +}; + +static struct clk_regmap_div disp_cc_mdss_dptx1_link_div_clk_src = { + .reg = 0x8294, + .shift = 0, + .width = 4, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_dptx1_link_div_clk_src", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_dptx1_link_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_regmap_div_ro_ops, + }, +}; + +static struct clk_regmap_div disp_cc_mdss_dptx1_link_dpin_div_clk_src = { + .reg = 0x8390, + .shift = 0, + .width = 4, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_dptx1_link_dpin_div_clk_src", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_dptx1_link_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_regmap_div_ro_ops, + }, +}; + +static struct clk_regmap_div disp_cc_mdss_dptx2_link_div_clk_src = { + .reg = 0x82c8, + .shift = 0, + .width = 4, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_dptx2_link_div_clk_src", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_dptx2_link_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_regmap_div_ro_ops, + }, +}; + +static struct clk_regmap_div disp_cc_mdss_dptx2_link_dpin_div_clk_src = { + .reg = 0x8394, + .shift = 0, + .width = 4, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_dptx2_link_dpin_div_clk_src", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_dptx2_link_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_regmap_div_ro_ops, + }, +}; + +static struct clk_regmap_div disp_cc_mdss_dptx3_link_div_clk_src = { + .reg = 0x8344, + .shift = 0, + .width = 4, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_dptx3_link_div_clk_src", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_dptx3_link_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_regmap_div_ro_ops, + }, +}; + +static struct clk_regmap_div disp_cc_mdss_dptx3_link_dpin_div_clk_src = { + .reg = 0x8398, + .shift = 0, + .width = 4, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_dptx3_link_dpin_div_clk_src", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_dptx3_link_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_regmap_div_ro_ops, + }, +}; + +static struct clk_branch disp_cc_esync0_clk = { + .halt_reg = 0x80b8, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x80b8, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_esync0_clk", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_esync0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_esync1_clk = { + .halt_reg = 0x80bc, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x80bc, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_esync1_clk", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_esync1_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_accu_shift_clk = { + .halt_reg = 0xe060, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0xe060, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_accu_shift_clk", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_xo_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_ahb1_clk = { + .halt_reg = 0xa028, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xa028, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_ahb1_clk", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_ahb_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_ahb_clk = { + .halt_reg = 0x80b0, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x80b0, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_ahb_clk", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_ahb_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_byte0_clk = { + .halt_reg = 0x8034, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8034, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_byte0_clk", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_byte0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_byte0_intf_clk = { + .halt_reg = 0x8038, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8038, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_byte0_intf_clk", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_byte0_div_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_byte1_clk = { + .halt_reg = 0x803c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x803c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_byte1_clk", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_byte1_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_byte1_intf_clk = { + .halt_reg = 0x8040, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8040, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_byte1_intf_clk", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_byte1_div_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_dptx0_aux_clk = { + .halt_reg = 0x8064, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8064, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_dptx0_aux_clk", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_dptx0_aux_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_dptx0_link_clk = { + .halt_reg = 0x804c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x804c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_dptx0_link_clk", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_dptx0_link_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_dptx0_link_dpin_clk = { + .halt_reg = 0x837c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x837c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_dptx0_link_dpin_clk", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_dptx0_link_dpin_div_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_dptx0_link_intf_clk = { + .halt_reg = 0x8054, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8054, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_dptx0_link_intf_clk", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_dptx0_link_div_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_dptx0_pixel0_clk = { + .halt_reg = 0x805c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x805c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_dptx0_pixel0_clk", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_dptx0_pixel0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_dptx0_pixel1_clk = { + .halt_reg = 0x8060, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8060, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_dptx0_pixel1_clk", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_dptx0_pixel1_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_dptx0_usb_router_link_intf_clk = { + .halt_reg = 0x8050, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8050, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_dptx0_usb_router_link_intf_clk", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_dptx0_link_div_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_dptx1_aux_clk = { + .halt_reg = 0x8080, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8080, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_dptx1_aux_clk", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_dptx1_aux_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_dptx1_link_clk = { + .halt_reg = 0x8070, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8070, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_dptx1_link_clk", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_dptx1_link_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_dptx1_link_dpin_clk = { + .halt_reg = 0x8380, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8380, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_dptx1_link_dpin_clk", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_dptx1_link_dpin_div_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_dptx1_link_intf_clk = { + .halt_reg = 0x8078, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8078, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_dptx1_link_intf_clk", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_dptx1_link_div_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_dptx1_pixel0_clk = { + .halt_reg = 0x8068, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8068, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_dptx1_pixel0_clk", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_dptx1_pixel0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_dptx1_pixel1_clk = { + .halt_reg = 0x806c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x806c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_dptx1_pixel1_clk", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_dptx1_pixel1_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_dptx1_usb_router_link_intf_clk = { + .halt_reg = 0x8074, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8074, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_dptx1_usb_router_link_intf_clk", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_dptx1_link_div_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_dptx2_aux_clk = { + .halt_reg = 0x8098, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8098, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_dptx2_aux_clk", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_dptx2_aux_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_dptx2_link_clk = { + .halt_reg = 0x808c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x808c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_dptx2_link_clk", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_dptx2_link_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_dptx2_link_dpin_clk = { + .halt_reg = 0x8384, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8384, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_dptx2_link_dpin_clk", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_dptx2_link_dpin_div_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_dptx2_link_intf_clk = { + .halt_reg = 0x8090, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8090, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_dptx2_link_intf_clk", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_dptx2_link_div_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_dptx2_pixel0_clk = { + .halt_reg = 0x8084, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8084, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_dptx2_pixel0_clk", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_dptx2_pixel0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_dptx2_pixel1_clk = { + .halt_reg = 0x8088, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8088, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_dptx2_pixel1_clk", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_dptx2_pixel1_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_dptx2_usb_router_link_intf_clk = { + .halt_reg = 0x8378, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8378, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_dptx2_usb_router_link_intf_clk", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_dptx2_link_div_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_dptx3_aux_clk = { + .halt_reg = 0x80a8, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x80a8, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_dptx3_aux_clk", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_dptx3_aux_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_dptx3_link_clk = { + .halt_reg = 0x80a0, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x80a0, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_dptx3_link_clk", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_dptx3_link_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_dptx3_link_dpin_clk = { + .halt_reg = 0x8388, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8388, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_dptx3_link_dpin_clk", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_dptx3_link_dpin_div_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_dptx3_link_intf_clk = { + .halt_reg = 0x80a4, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x80a4, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_dptx3_link_intf_clk", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_dptx3_link_div_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_dptx3_pixel0_clk = { + .halt_reg = 0x809c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x809c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_dptx3_pixel0_clk", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_dptx3_pixel0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_esc0_clk = { + .halt_reg = 0x8044, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8044, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_esc0_clk", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_esc0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_esc1_clk = { + .halt_reg = 0x8048, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8048, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_esc1_clk", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_esc1_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_mdp1_clk = { + .halt_reg = 0xa004, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xa004, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_mdp1_clk", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_mdp_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_mdp_clk = { + .halt_reg = 0x8010, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8010, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_mdp_clk", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_mdp_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_mdp_lut1_clk = { + .halt_reg = 0xa014, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0xa014, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_mdp_lut1_clk", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_mdp_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_mdp_lut_clk = { + .halt_reg = 0x8020, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x8020, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_mdp_lut_clk", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_mdp_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_non_gdsc_ahb_clk = { + .halt_reg = 0xc004, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0xc004, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_non_gdsc_ahb_clk", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_ahb_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_pclk0_clk = { + .halt_reg = 0x8004, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8004, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_pclk0_clk", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_pclk0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_pclk1_clk = { + .halt_reg = 0x8008, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8008, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_pclk1_clk", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_pclk1_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_pclk2_clk = { + .halt_reg = 0x800c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x800c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_pclk2_clk", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_pclk2_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_rscc_ahb_clk = { + .halt_reg = 0xc00c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xc00c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_rscc_ahb_clk", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_ahb_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_rscc_vsync_clk = { + .halt_reg = 0xc008, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xc008, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_rscc_vsync_clk", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_vsync_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_vsync1_clk = { + .halt_reg = 0xa024, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xa024, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_vsync1_clk", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_vsync_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_vsync_clk = { + .halt_reg = 0x8030, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8030, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_vsync_clk", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_vsync_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_osc_clk = { + .halt_reg = 0x80b4, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x80b4, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_osc_clk", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_osc_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct gdsc disp_cc_mdss_core_gdsc = { + .gdscr = 0x9000, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0xf, + .pd = { + .name = "disp_cc_mdss_core_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, + .flags = HW_CTRL | POLL_CFG_GDSCR | RETAIN_FF_ENABLE, +}; + +static struct gdsc disp_cc_mdss_core_int2_gdsc = { + .gdscr = 0xb000, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0xf, + .pd = { + .name = "disp_cc_mdss_core_int2_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, + .flags = HW_CTRL | POLL_CFG_GDSCR | RETAIN_FF_ENABLE, +}; + +static struct clk_regmap *disp_cc_glymur_clocks[] = { + [DISP_CC_ESYNC0_CLK] = &disp_cc_esync0_clk.clkr, + [DISP_CC_ESYNC0_CLK_SRC] = &disp_cc_esync0_clk_src.clkr, + [DISP_CC_ESYNC1_CLK] = &disp_cc_esync1_clk.clkr, + [DISP_CC_ESYNC1_CLK_SRC] = &disp_cc_esync1_clk_src.clkr, + [DISP_CC_MDSS_ACCU_SHIFT_CLK] = &disp_cc_mdss_accu_shift_clk.clkr, + [DISP_CC_MDSS_AHB1_CLK] = &disp_cc_mdss_ahb1_clk.clkr, + [DISP_CC_MDSS_AHB_CLK] = &disp_cc_mdss_ahb_clk.clkr, + [DISP_CC_MDSS_AHB_CLK_SRC] = &disp_cc_mdss_ahb_clk_src.clkr, + [DISP_CC_MDSS_BYTE0_CLK] = &disp_cc_mdss_byte0_clk.clkr, + [DISP_CC_MDSS_BYTE0_CLK_SRC] = &disp_cc_mdss_byte0_clk_src.clkr, + [DISP_CC_MDSS_BYTE0_DIV_CLK_SRC] = &disp_cc_mdss_byte0_div_clk_src.clkr, + [DISP_CC_MDSS_BYTE0_INTF_CLK] = &disp_cc_mdss_byte0_intf_clk.clkr, + [DISP_CC_MDSS_BYTE1_CLK] = &disp_cc_mdss_byte1_clk.clkr, + [DISP_CC_MDSS_BYTE1_CLK_SRC] = &disp_cc_mdss_byte1_clk_src.clkr, + [DISP_CC_MDSS_BYTE1_DIV_CLK_SRC] = &disp_cc_mdss_byte1_div_clk_src.clkr, + [DISP_CC_MDSS_BYTE1_INTF_CLK] = &disp_cc_mdss_byte1_intf_clk.clkr, + [DISP_CC_MDSS_DPTX0_AUX_CLK] = &disp_cc_mdss_dptx0_aux_clk.clkr, + [DISP_CC_MDSS_DPTX0_AUX_CLK_SRC] = &disp_cc_mdss_dptx0_aux_clk_src.clkr, + [DISP_CC_MDSS_DPTX0_LINK_CLK] = &disp_cc_mdss_dptx0_link_clk.clkr, + [DISP_CC_MDSS_DPTX0_LINK_CLK_SRC] = &disp_cc_mdss_dptx0_link_clk_src.clkr, + [DISP_CC_MDSS_DPTX0_LINK_DIV_CLK_SRC] = &disp_cc_mdss_dptx0_link_div_clk_src.clkr, + [DISP_CC_MDSS_DPTX0_LINK_DPIN_CLK] = &disp_cc_mdss_dptx0_link_dpin_clk.clkr, + [DISP_CC_MDSS_DPTX0_LINK_DPIN_DIV_CLK_SRC] = &disp_cc_mdss_dptx0_link_dpin_div_clk_src.clkr, + [DISP_CC_MDSS_DPTX0_LINK_INTF_CLK] = &disp_cc_mdss_dptx0_link_intf_clk.clkr, + [DISP_CC_MDSS_DPTX0_PIXEL0_CLK] = &disp_cc_mdss_dptx0_pixel0_clk.clkr, + [DISP_CC_MDSS_DPTX0_PIXEL0_CLK_SRC] = &disp_cc_mdss_dptx0_pixel0_clk_src.clkr, + [DISP_CC_MDSS_DPTX0_PIXEL1_CLK] = &disp_cc_mdss_dptx0_pixel1_clk.clkr, + [DISP_CC_MDSS_DPTX0_PIXEL1_CLK_SRC] = &disp_cc_mdss_dptx0_pixel1_clk_src.clkr, + [DISP_CC_MDSS_DPTX0_USB_ROUTER_LINK_INTF_CLK] = + &disp_cc_mdss_dptx0_usb_router_link_intf_clk.clkr, + [DISP_CC_MDSS_DPTX1_AUX_CLK] = &disp_cc_mdss_dptx1_aux_clk.clkr, + [DISP_CC_MDSS_DPTX1_AUX_CLK_SRC] = &disp_cc_mdss_dptx1_aux_clk_src.clkr, + [DISP_CC_MDSS_DPTX1_LINK_CLK] = &disp_cc_mdss_dptx1_link_clk.clkr, + [DISP_CC_MDSS_DPTX1_LINK_CLK_SRC] = &disp_cc_mdss_dptx1_link_clk_src.clkr, + [DISP_CC_MDSS_DPTX1_LINK_DIV_CLK_SRC] = &disp_cc_mdss_dptx1_link_div_clk_src.clkr, + [DISP_CC_MDSS_DPTX1_LINK_DPIN_CLK] = &disp_cc_mdss_dptx1_link_dpin_clk.clkr, + [DISP_CC_MDSS_DPTX1_LINK_DPIN_DIV_CLK_SRC] = &disp_cc_mdss_dptx1_link_dpin_div_clk_src.clkr, + [DISP_CC_MDSS_DPTX1_LINK_INTF_CLK] = &disp_cc_mdss_dptx1_link_intf_clk.clkr, + [DISP_CC_MDSS_DPTX1_PIXEL0_CLK] = &disp_cc_mdss_dptx1_pixel0_clk.clkr, + [DISP_CC_MDSS_DPTX1_PIXEL0_CLK_SRC] = &disp_cc_mdss_dptx1_pixel0_clk_src.clkr, + [DISP_CC_MDSS_DPTX1_PIXEL1_CLK] = &disp_cc_mdss_dptx1_pixel1_clk.clkr, + [DISP_CC_MDSS_DPTX1_PIXEL1_CLK_SRC] = &disp_cc_mdss_dptx1_pixel1_clk_src.clkr, + [DISP_CC_MDSS_DPTX1_USB_ROUTER_LINK_INTF_CLK] = + &disp_cc_mdss_dptx1_usb_router_link_intf_clk.clkr, + [DISP_CC_MDSS_DPTX2_AUX_CLK] = &disp_cc_mdss_dptx2_aux_clk.clkr, + [DISP_CC_MDSS_DPTX2_AUX_CLK_SRC] = &disp_cc_mdss_dptx2_aux_clk_src.clkr, + [DISP_CC_MDSS_DPTX2_LINK_CLK] = &disp_cc_mdss_dptx2_link_clk.clkr, + [DISP_CC_MDSS_DPTX2_LINK_CLK_SRC] = &disp_cc_mdss_dptx2_link_clk_src.clkr, + [DISP_CC_MDSS_DPTX2_LINK_DIV_CLK_SRC] = &disp_cc_mdss_dptx2_link_div_clk_src.clkr, + [DISP_CC_MDSS_DPTX2_LINK_DPIN_CLK] = &disp_cc_mdss_dptx2_link_dpin_clk.clkr, + [DISP_CC_MDSS_DPTX2_LINK_DPIN_DIV_CLK_SRC] = &disp_cc_mdss_dptx2_link_dpin_div_clk_src.clkr, + [DISP_CC_MDSS_DPTX2_LINK_INTF_CLK] = &disp_cc_mdss_dptx2_link_intf_clk.clkr, + [DISP_CC_MDSS_DPTX2_PIXEL0_CLK] = &disp_cc_mdss_dptx2_pixel0_clk.clkr, + [DISP_CC_MDSS_DPTX2_PIXEL0_CLK_SRC] = &disp_cc_mdss_dptx2_pixel0_clk_src.clkr, + [DISP_CC_MDSS_DPTX2_PIXEL1_CLK] = &disp_cc_mdss_dptx2_pixel1_clk.clkr, + [DISP_CC_MDSS_DPTX2_PIXEL1_CLK_SRC] = &disp_cc_mdss_dptx2_pixel1_clk_src.clkr, + [DISP_CC_MDSS_DPTX2_USB_ROUTER_LINK_INTF_CLK] = + &disp_cc_mdss_dptx2_usb_router_link_intf_clk.clkr, + [DISP_CC_MDSS_DPTX3_AUX_CLK] = &disp_cc_mdss_dptx3_aux_clk.clkr, + [DISP_CC_MDSS_DPTX3_AUX_CLK_SRC] = &disp_cc_mdss_dptx3_aux_clk_src.clkr, + [DISP_CC_MDSS_DPTX3_LINK_CLK] = &disp_cc_mdss_dptx3_link_clk.clkr, + [DISP_CC_MDSS_DPTX3_LINK_CLK_SRC] = &disp_cc_mdss_dptx3_link_clk_src.clkr, + [DISP_CC_MDSS_DPTX3_LINK_DIV_CLK_SRC] = &disp_cc_mdss_dptx3_link_div_clk_src.clkr, + [DISP_CC_MDSS_DPTX3_LINK_DPIN_CLK] = &disp_cc_mdss_dptx3_link_dpin_clk.clkr, + [DISP_CC_MDSS_DPTX3_LINK_DPIN_DIV_CLK_SRC] = &disp_cc_mdss_dptx3_link_dpin_div_clk_src.clkr, + [DISP_CC_MDSS_DPTX3_LINK_INTF_CLK] = &disp_cc_mdss_dptx3_link_intf_clk.clkr, + [DISP_CC_MDSS_DPTX3_PIXEL0_CLK] = &disp_cc_mdss_dptx3_pixel0_clk.clkr, + [DISP_CC_MDSS_DPTX3_PIXEL0_CLK_SRC] = &disp_cc_mdss_dptx3_pixel0_clk_src.clkr, + [DISP_CC_MDSS_ESC0_CLK] = &disp_cc_mdss_esc0_clk.clkr, + [DISP_CC_MDSS_ESC0_CLK_SRC] = &disp_cc_mdss_esc0_clk_src.clkr, + [DISP_CC_MDSS_ESC1_CLK] = &disp_cc_mdss_esc1_clk.clkr, + [DISP_CC_MDSS_ESC1_CLK_SRC] = &disp_cc_mdss_esc1_clk_src.clkr, + [DISP_CC_MDSS_MDP1_CLK] = &disp_cc_mdss_mdp1_clk.clkr, + [DISP_CC_MDSS_MDP_CLK] = &disp_cc_mdss_mdp_clk.clkr, + [DISP_CC_MDSS_MDP_CLK_SRC] = &disp_cc_mdss_mdp_clk_src.clkr, + [DISP_CC_MDSS_MDP_LUT1_CLK] = &disp_cc_mdss_mdp_lut1_clk.clkr, + [DISP_CC_MDSS_MDP_LUT_CLK] = &disp_cc_mdss_mdp_lut_clk.clkr, + [DISP_CC_MDSS_NON_GDSC_AHB_CLK] = &disp_cc_mdss_non_gdsc_ahb_clk.clkr, + [DISP_CC_MDSS_PCLK0_CLK] = &disp_cc_mdss_pclk0_clk.clkr, + [DISP_CC_MDSS_PCLK0_CLK_SRC] = &disp_cc_mdss_pclk0_clk_src.clkr, + [DISP_CC_MDSS_PCLK1_CLK] = &disp_cc_mdss_pclk1_clk.clkr, + [DISP_CC_MDSS_PCLK1_CLK_SRC] = &disp_cc_mdss_pclk1_clk_src.clkr, + [DISP_CC_MDSS_PCLK2_CLK] = &disp_cc_mdss_pclk2_clk.clkr, + [DISP_CC_MDSS_PCLK2_CLK_SRC] = &disp_cc_mdss_pclk2_clk_src.clkr, + [DISP_CC_MDSS_RSCC_AHB_CLK] = &disp_cc_mdss_rscc_ahb_clk.clkr, + [DISP_CC_MDSS_RSCC_VSYNC_CLK] = &disp_cc_mdss_rscc_vsync_clk.clkr, + [DISP_CC_MDSS_VSYNC1_CLK] = &disp_cc_mdss_vsync1_clk.clkr, + [DISP_CC_MDSS_VSYNC_CLK] = &disp_cc_mdss_vsync_clk.clkr, + [DISP_CC_MDSS_VSYNC_CLK_SRC] = &disp_cc_mdss_vsync_clk_src.clkr, + [DISP_CC_OSC_CLK] = &disp_cc_osc_clk.clkr, + [DISP_CC_OSC_CLK_SRC] = &disp_cc_osc_clk_src.clkr, + [DISP_CC_PLL0] = &disp_cc_pll0.clkr, + [DISP_CC_PLL1] = &disp_cc_pll1.clkr, + [DISP_CC_SLEEP_CLK_SRC] = &disp_cc_sleep_clk_src.clkr, + [DISP_CC_XO_CLK_SRC] = &disp_cc_xo_clk_src.clkr, +}; + +static struct gdsc *disp_cc_glymur_gdscs[] = { + [DISP_CC_MDSS_CORE_GDSC] = &disp_cc_mdss_core_gdsc, + [DISP_CC_MDSS_CORE_INT2_GDSC] = &disp_cc_mdss_core_int2_gdsc, +}; + +static const struct qcom_reset_map disp_cc_glymur_resets[] = { + [DISP_CC_MDSS_CORE_BCR] = { 0x8000 }, + [DISP_CC_MDSS_CORE_INT2_BCR] = { 0xa000 }, + [DISP_CC_MDSS_RSCC_BCR] = { 0xc000 }, +}; + +static struct clk_alpha_pll *disp_cc_glymur_plls[] = { + &disp_cc_pll0, + &disp_cc_pll1, +}; + +static u32 disp_cc_glymur_critical_cbcrs[] = { + 0xe07c, /* DISP_CC_SLEEP_CLK */ + 0xe05c, /* DISP_CC_XO_CLK */ +}; + +static const struct regmap_config disp_cc_glymur_regmap_config = { + .reg_bits = 32, + .reg_stride = 4, + .val_bits = 32, + .max_register = 0x11014, + .fast_io = true, +}; + +static struct qcom_cc_driver_data disp_cc_glymur_driver_data = { + .alpha_plls = disp_cc_glymur_plls, + .num_alpha_plls = ARRAY_SIZE(disp_cc_glymur_plls), + .clk_cbcrs = disp_cc_glymur_critical_cbcrs, + .num_clk_cbcrs = ARRAY_SIZE(disp_cc_glymur_critical_cbcrs), +}; + +static const struct qcom_cc_desc disp_cc_glymur_desc = { + .config = &disp_cc_glymur_regmap_config, + .clks = disp_cc_glymur_clocks, + .num_clks = ARRAY_SIZE(disp_cc_glymur_clocks), + .resets = disp_cc_glymur_resets, + .num_resets = ARRAY_SIZE(disp_cc_glymur_resets), + .gdscs = disp_cc_glymur_gdscs, + .num_gdscs = ARRAY_SIZE(disp_cc_glymur_gdscs), + .use_rpm = true, + .driver_data = &disp_cc_glymur_driver_data, +}; + +static const struct of_device_id disp_cc_glymur_match_table[] = { + { .compatible = "qcom,glymur-dispcc" }, + { } +}; +MODULE_DEVICE_TABLE(of, disp_cc_glymur_match_table); + +static int disp_cc_glymur_probe(struct platform_device *pdev) +{ + return qcom_cc_probe(pdev, &disp_cc_glymur_desc); +} + +static struct platform_driver disp_cc_glymur_driver = { + .probe = disp_cc_glymur_probe, + .driver = { + .name = "dispcc-glymur", + .of_match_table = disp_cc_glymur_match_table, + }, +}; + +module_platform_driver(disp_cc_glymur_driver); + +MODULE_DESCRIPTION("QTI DISPCC GLYMUR Driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/clk/qcom/dispcc-milos.c b/drivers/clk/qcom/dispcc-milos.c index 602d3a498d33..95b6dd89d9ae 100644 --- a/drivers/clk/qcom/dispcc-milos.c +++ b/drivers/clk/qcom/dispcc-milos.c @@ -937,7 +937,7 @@ static struct qcom_cc_driver_data disp_cc_milos_driver_data = { .clk_regs_configure = disp_cc_milos_clk_regs_configure, }; -static struct qcom_cc_desc disp_cc_milos_desc = { +static const struct qcom_cc_desc disp_cc_milos_desc = { .config = &disp_cc_milos_regmap_config, .clks = disp_cc_milos_clocks, .num_clks = ARRAY_SIZE(disp_cc_milos_clocks), diff --git a/drivers/clk/qcom/dispcc-sc7280.c b/drivers/clk/qcom/dispcc-sc7280.c index 8bdf57734a3d..465dc06c8712 100644 --- a/drivers/clk/qcom/dispcc-sc7280.c +++ b/drivers/clk/qcom/dispcc-sc7280.c @@ -17,6 +17,7 @@ #include "clk-regmap-divider.h" #include "common.h" #include "gdsc.h" +#include "reset.h" enum { P_BI_TCXO, @@ -847,6 +848,11 @@ static struct gdsc *disp_cc_sc7280_gdscs[] = { [DISP_CC_MDSS_CORE_GDSC] = &disp_cc_mdss_core_gdsc, }; +static const struct qcom_reset_map disp_cc_sc7280_resets[] = { + [DISP_CC_MDSS_CORE_BCR] = { 0x1000 }, + [DISP_CC_MDSS_RSCC_BCR] = { 0x2000 }, +}; + static const struct regmap_config disp_cc_sc7280_regmap_config = { .reg_bits = 32, .reg_stride = 4, @@ -861,6 +867,8 @@ static const struct qcom_cc_desc disp_cc_sc7280_desc = { .num_clks = ARRAY_SIZE(disp_cc_sc7280_clocks), .gdscs = disp_cc_sc7280_gdscs, .num_gdscs = ARRAY_SIZE(disp_cc_sc7280_gdscs), + .resets = disp_cc_sc7280_resets, + .num_resets = ARRAY_SIZE(disp_cc_sc7280_resets), }; static const struct of_device_id disp_cc_sc7280_match_table[] = { diff --git a/drivers/clk/qcom/gcc-glymur.c b/drivers/clk/qcom/gcc-glymur.c new file mode 100644 index 000000000000..62059120f972 --- /dev/null +++ b/drivers/clk/qcom/gcc-glymur.c @@ -0,0 +1,8616 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2025, Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#include <linux/clk-provider.h> +#include <linux/mod_devicetable.h> +#include <linux/module.h> +#include <linux/of.h> +#include <linux/platform_device.h> +#include <linux/regmap.h> + +#include <dt-bindings/clock/qcom,glymur-gcc.h> + +#include "clk-alpha-pll.h" +#include "clk-branch.h" +#include "clk-pll.h" +#include "clk-rcg.h" +#include "clk-regmap.h" +#include "clk-regmap-divider.h" +#include "clk-regmap-mux.h" +#include "clk-regmap-phy-mux.h" +#include "common.h" +#include "gdsc.h" +#include "reset.h" + +enum { + DT_BI_TCXO, + DT_BI_TCXO_AO, + DT_SLEEP_CLK, + DT_GCC_USB4_0_PHY_DP0_GMUX_CLK_SRC, + DT_GCC_USB4_0_PHY_DP1_GMUX_CLK_SRC, + DT_GCC_USB4_0_PHY_PCIE_PIPEGMUX_CLK_SRC, + DT_GCC_USB4_0_PHY_PIPEGMUX_CLK_SRC, + DT_GCC_USB4_0_PHY_SYS_PIPEGMUX_CLK_SRC, + DT_GCC_USB4_1_PHY_DP0_GMUX_2_CLK_SRC, + DT_GCC_USB4_1_PHY_DP1_GMUX_2_CLK_SRC, + DT_GCC_USB4_1_PHY_PCIE_PIPEGMUX_CLK_SRC, + DT_GCC_USB4_1_PHY_PIPEGMUX_CLK_SRC, + DT_GCC_USB4_1_PHY_SYS_PIPEGMUX_CLK_SRC, + DT_GCC_USB4_2_PHY_DP0_GMUX_CLK_SRC, + DT_GCC_USB4_2_PHY_DP1_GMUX_CLK_SRC, + DT_GCC_USB4_2_PHY_PCIE_PIPEGMUX_CLK_SRC, + DT_GCC_USB4_2_PHY_PIPEGMUX_CLK_SRC, + DT_GCC_USB4_2_PHY_SYS_PIPEGMUX_CLK_SRC, + DT_PCIE_3A_PIPE_CLK, + DT_PCIE_3B_PIPE_CLK, + DT_PCIE_4_PIPE_CLK, + DT_PCIE_5_PIPE_CLK, + DT_PCIE_6_PIPE_CLK, + DT_QUSB4PHY_0_GCC_USB4_RX0_CLK, + DT_QUSB4PHY_0_GCC_USB4_RX1_CLK, + DT_QUSB4PHY_1_GCC_USB4_RX0_CLK, + DT_QUSB4PHY_1_GCC_USB4_RX1_CLK, + DT_QUSB4PHY_2_GCC_USB4_RX0_CLK, + DT_QUSB4PHY_2_GCC_USB4_RX1_CLK, + DT_UFS_PHY_RX_SYMBOL_0_CLK, + DT_UFS_PHY_RX_SYMBOL_1_CLK, + DT_UFS_PHY_TX_SYMBOL_0_CLK, + DT_USB3_PHY_0_WRAPPER_GCC_USB30_PIPE_CLK, + DT_USB3_PHY_1_WRAPPER_GCC_USB30_PIPE_CLK, + DT_USB3_PHY_2_WRAPPER_GCC_USB30_PIPE_CLK, + DT_USB3_UNI_PHY_MP_GCC_USB30_PIPE_0_CLK, + DT_USB3_UNI_PHY_MP_GCC_USB30_PIPE_1_CLK, + DT_USB4_0_PHY_GCC_USB4_PCIE_PIPE_CLK, + DT_USB4_0_PHY_GCC_USB4RTR_MAX_PIPE_CLK, + DT_USB4_1_PHY_GCC_USB4_PCIE_PIPE_CLK, + DT_USB4_1_PHY_GCC_USB4RTR_MAX_PIPE_CLK, + DT_USB4_2_PHY_GCC_USB4_PCIE_PIPE_CLK, + DT_USB4_2_PHY_GCC_USB4RTR_MAX_PIPE_CLK, +}; + +enum { + P_BI_TCXO, + P_GCC_GPLL0_OUT_EVEN, + P_GCC_GPLL0_OUT_MAIN, + P_GCC_GPLL14_OUT_EVEN, + P_GCC_GPLL14_OUT_MAIN, + P_GCC_GPLL1_OUT_MAIN, + P_GCC_GPLL4_OUT_MAIN, + P_GCC_GPLL5_OUT_MAIN, + P_GCC_GPLL7_OUT_MAIN, + P_GCC_GPLL8_OUT_MAIN, + P_GCC_GPLL9_OUT_MAIN, + P_GCC_USB3_PRIM_PHY_PIPE_CLK_SRC, + P_GCC_USB3_SEC_PHY_PIPE_CLK_SRC, + P_GCC_USB3_TERT_PHY_PIPE_CLK_SRC, + P_GCC_USB4_0_PHY_DP0_GMUX_CLK_SRC, + P_GCC_USB4_0_PHY_DP1_GMUX_CLK_SRC, + P_GCC_USB4_0_PHY_PCIE_PIPEGMUX_CLK_SRC, + P_GCC_USB4_0_PHY_PIPEGMUX_CLK_SRC, + P_GCC_USB4_0_PHY_SYS_PIPEGMUX_CLK_SRC, + P_GCC_USB4_1_PHY_DP0_GMUX_2_CLK_SRC, + P_GCC_USB4_1_PHY_DP1_GMUX_2_CLK_SRC, + P_GCC_USB4_1_PHY_PCIE_PIPEGMUX_CLK_SRC, + P_GCC_USB4_1_PHY_PIPEGMUX_CLK_SRC, + P_GCC_USB4_1_PHY_PLL_PIPE_CLK_SRC, + P_GCC_USB4_1_PHY_SYS_PIPEGMUX_CLK_SRC, + P_GCC_USB4_2_PHY_DP0_GMUX_CLK_SRC, + P_GCC_USB4_2_PHY_DP1_GMUX_CLK_SRC, + P_GCC_USB4_2_PHY_PCIE_PIPEGMUX_CLK_SRC, + P_GCC_USB4_2_PHY_PIPEGMUX_CLK_SRC, + P_GCC_USB4_2_PHY_SYS_PIPEGMUX_CLK_SRC, + P_PCIE_3A_PIPE_CLK, + P_PCIE_3B_PIPE_CLK, + P_PCIE_4_PIPE_CLK, + P_PCIE_5_PIPE_CLK, + P_PCIE_6_PIPE_CLK, + P_QUSB4PHY_0_GCC_USB4_RX0_CLK, + P_QUSB4PHY_0_GCC_USB4_RX1_CLK, + P_QUSB4PHY_1_GCC_USB4_RX0_CLK, + P_QUSB4PHY_1_GCC_USB4_RX1_CLK, + P_QUSB4PHY_2_GCC_USB4_RX0_CLK, + P_QUSB4PHY_2_GCC_USB4_RX1_CLK, + P_SLEEP_CLK, + P_UFS_PHY_RX_SYMBOL_0_CLK, + P_UFS_PHY_RX_SYMBOL_1_CLK, + P_UFS_PHY_TX_SYMBOL_0_CLK, + P_USB3_PHY_0_WRAPPER_GCC_USB30_PIPE_CLK, + P_USB3_PHY_1_WRAPPER_GCC_USB30_PIPE_CLK, + P_USB3_PHY_2_WRAPPER_GCC_USB30_PIPE_CLK, + P_USB3_UNI_PHY_MP_GCC_USB30_PIPE_0_CLK, + P_USB3_UNI_PHY_MP_GCC_USB30_PIPE_1_CLK, + P_USB4_0_PHY_GCC_USB4_PCIE_PIPE_CLK, + P_USB4_0_PHY_GCC_USB4RTR_MAX_PIPE_CLK, + P_USB4_1_PHY_GCC_USB4_PCIE_PIPE_CLK, + P_USB4_1_PHY_GCC_USB4RTR_MAX_PIPE_CLK, + P_USB4_2_PHY_GCC_USB4_PCIE_PIPE_CLK, + P_USB4_2_PHY_GCC_USB4RTR_MAX_PIPE_CLK, +}; + +static struct clk_alpha_pll gcc_gpll0 = { + .offset = 0x0, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_TAYCAN_EKO_T], + .clkr = { + .enable_reg = 0x62040, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_gpll0", + .parent_data = &(const struct clk_parent_data) { + .index = DT_BI_TCXO, + }, + .num_parents = 1, + .ops = &clk_alpha_pll_fixed_taycan_eko_t_ops, + }, + }, +}; + +static const struct clk_div_table post_div_table_gcc_gpll0_out_even[] = { + { 0x1, 2 }, + { } +}; + +static struct clk_alpha_pll_postdiv gcc_gpll0_out_even = { + .offset = 0x0, + .post_div_shift = 10, + .post_div_table = post_div_table_gcc_gpll0_out_even, + .num_post_div = ARRAY_SIZE(post_div_table_gcc_gpll0_out_even), + .width = 4, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_TAYCAN_EKO_T], + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_gpll0_out_even", + .parent_hws = (const struct clk_hw*[]) { + &gcc_gpll0.clkr.hw, + }, + .num_parents = 1, + .ops = &clk_alpha_pll_postdiv_taycan_eko_t_ops, + }, +}; + +static struct clk_alpha_pll gcc_gpll1 = { + .offset = 0x1000, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_TAYCAN_EKO_T], + .clkr = { + .enable_reg = 0x62040, + .enable_mask = BIT(1), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_gpll1", + .parent_data = &(const struct clk_parent_data) { + .index = DT_BI_TCXO, + }, + .num_parents = 1, + .ops = &clk_alpha_pll_fixed_taycan_eko_t_ops, + }, + }, +}; + +static struct clk_alpha_pll gcc_gpll14 = { + .offset = 0xe000, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_TAYCAN_EKO_T], + .clkr = { + .enable_reg = 0x62040, + .enable_mask = BIT(14), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_gpll14", + .parent_data = &(const struct clk_parent_data) { + .index = DT_BI_TCXO, + }, + .num_parents = 1, + .ops = &clk_alpha_pll_fixed_taycan_eko_t_ops, + }, + }, +}; + +static const struct clk_div_table post_div_table_gcc_gpll14_out_even[] = { + { 0x1, 2 }, + { } +}; + +static struct clk_alpha_pll_postdiv gcc_gpll14_out_even = { + .offset = 0xe000, + .post_div_shift = 10, + .post_div_table = post_div_table_gcc_gpll14_out_even, + .num_post_div = ARRAY_SIZE(post_div_table_gcc_gpll14_out_even), + .width = 4, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_TAYCAN_EKO_T], + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_gpll14_out_even", + .parent_hws = (const struct clk_hw*[]) { + &gcc_gpll14.clkr.hw, + }, + .num_parents = 1, + .ops = &clk_alpha_pll_postdiv_taycan_eko_t_ops, + }, +}; + +static struct clk_alpha_pll gcc_gpll4 = { + .offset = 0x4000, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_TAYCAN_EKO_T], + .clkr = { + .enable_reg = 0x62040, + .enable_mask = BIT(4), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_gpll4", + .parent_data = &(const struct clk_parent_data) { + .index = DT_BI_TCXO, + }, + .num_parents = 1, + .ops = &clk_alpha_pll_fixed_taycan_eko_t_ops, + }, + }, +}; + +static struct clk_alpha_pll gcc_gpll5 = { + .offset = 0x5000, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_TAYCAN_EKO_T], + .clkr = { + .enable_reg = 0x62040, + .enable_mask = BIT(5), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_gpll5", + .parent_data = &(const struct clk_parent_data) { + .index = DT_BI_TCXO, + }, + .num_parents = 1, + .ops = &clk_alpha_pll_fixed_taycan_eko_t_ops, + }, + }, +}; + +static struct clk_alpha_pll gcc_gpll7 = { + .offset = 0x7000, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_TAYCAN_EKO_T], + .clkr = { + .enable_reg = 0x62040, + .enable_mask = BIT(7), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_gpll7", + .parent_data = &(const struct clk_parent_data) { + .index = DT_BI_TCXO, + }, + .num_parents = 1, + .ops = &clk_alpha_pll_fixed_taycan_eko_t_ops, + }, + }, +}; + +static struct clk_alpha_pll gcc_gpll8 = { + .offset = 0x8000, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_TAYCAN_EKO_T], + .clkr = { + .enable_reg = 0x62040, + .enable_mask = BIT(8), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_gpll8", + .parent_data = &(const struct clk_parent_data) { + .index = DT_BI_TCXO, + }, + .num_parents = 1, + .ops = &clk_alpha_pll_fixed_taycan_eko_t_ops, + }, + }, +}; + +static struct clk_alpha_pll gcc_gpll9 = { + .offset = 0x9000, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_TAYCAN_EKO_T], + .clkr = { + .enable_reg = 0x62040, + .enable_mask = BIT(9), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_gpll9", + .parent_data = &(const struct clk_parent_data) { + .index = DT_BI_TCXO, + }, + .num_parents = 1, + .ops = &clk_alpha_pll_fixed_taycan_eko_t_ops, + }, + }, +}; + +static struct clk_regmap_mux gcc_usb3_prim_phy_pipe_clk_src; +static struct clk_regmap_mux gcc_usb3_sec_phy_pipe_clk_src; +static struct clk_regmap_mux gcc_usb3_tert_phy_pipe_clk_src; + +static struct clk_rcg2 gcc_usb4_1_phy_pll_pipe_clk_src; + +static const struct parent_map gcc_parent_map_0[] = { + { P_BI_TCXO, 0 }, + { P_GCC_GPLL0_OUT_MAIN, 1 }, + { P_GCC_GPLL0_OUT_EVEN, 6 }, +}; + +static const struct clk_parent_data gcc_parent_data_0[] = { + { .index = DT_BI_TCXO }, + { .hw = &gcc_gpll0.clkr.hw }, + { .hw = &gcc_gpll0_out_even.clkr.hw }, +}; + +static const struct parent_map gcc_parent_map_1[] = { + { P_BI_TCXO, 0 }, + { P_GCC_GPLL0_OUT_MAIN, 1 }, + { P_GCC_GPLL1_OUT_MAIN, 4 }, + { P_GCC_GPLL0_OUT_EVEN, 6 }, +}; + +static const struct clk_parent_data gcc_parent_data_1[] = { + { .index = DT_BI_TCXO }, + { .hw = &gcc_gpll0.clkr.hw }, + { .hw = &gcc_gpll1.clkr.hw }, + { .hw = &gcc_gpll0_out_even.clkr.hw }, +}; + +static const struct parent_map gcc_parent_map_2[] = { + { P_BI_TCXO, 0 }, + { P_SLEEP_CLK, 5 }, +}; + +static const struct clk_parent_data gcc_parent_data_2[] = { + { .index = DT_BI_TCXO }, + { .index = DT_SLEEP_CLK }, +}; + +static const struct parent_map gcc_parent_map_3[] = { + { P_BI_TCXO, 0 }, + { P_GCC_GPLL0_OUT_MAIN, 1 }, + { P_GCC_GPLL1_OUT_MAIN, 4 }, + { P_GCC_GPLL4_OUT_MAIN, 5 }, + { P_GCC_GPLL0_OUT_EVEN, 6 }, +}; + +static const struct clk_parent_data gcc_parent_data_3[] = { + { .index = DT_BI_TCXO }, + { .hw = &gcc_gpll0.clkr.hw }, + { .hw = &gcc_gpll1.clkr.hw }, + { .hw = &gcc_gpll4.clkr.hw }, + { .hw = &gcc_gpll0_out_even.clkr.hw }, +}; + +static const struct parent_map gcc_parent_map_4[] = { + { P_BI_TCXO, 0 }, + { P_GCC_GPLL0_OUT_MAIN, 1 }, + { P_SLEEP_CLK, 5 }, + { P_GCC_GPLL0_OUT_EVEN, 6 }, +}; + +static const struct clk_parent_data gcc_parent_data_4[] = { + { .index = DT_BI_TCXO }, + { .hw = &gcc_gpll0.clkr.hw }, + { .index = DT_SLEEP_CLK }, + { .hw = &gcc_gpll0_out_even.clkr.hw }, +}; + +static const struct parent_map gcc_parent_map_5[] = { + { P_BI_TCXO, 0 }, +}; + +static const struct clk_parent_data gcc_parent_data_5[] = { + { .index = DT_BI_TCXO }, +}; + +static const struct parent_map gcc_parent_map_6[] = { + { P_BI_TCXO, 0 }, + { P_GCC_GPLL0_OUT_MAIN, 1 }, + { P_GCC_GPLL4_OUT_MAIN, 5 }, + { P_GCC_GPLL0_OUT_EVEN, 6 }, +}; + +static const struct clk_parent_data gcc_parent_data_6[] = { + { .index = DT_BI_TCXO }, + { .hw = &gcc_gpll0.clkr.hw }, + { .hw = &gcc_gpll4.clkr.hw }, + { .hw = &gcc_gpll0_out_even.clkr.hw }, +}; + +static const struct parent_map gcc_parent_map_7[] = { + { P_BI_TCXO, 0 }, + { P_GCC_GPLL14_OUT_MAIN, 1 }, + { P_GCC_GPLL14_OUT_EVEN, 6 }, +}; + +static const struct clk_parent_data gcc_parent_data_7[] = { + { .index = DT_BI_TCXO }, + { .hw = &gcc_gpll14.clkr.hw }, + { .hw = &gcc_gpll14_out_even.clkr.hw }, +}; + +static const struct parent_map gcc_parent_map_8[] = { + { P_BI_TCXO, 0 }, + { P_GCC_GPLL4_OUT_MAIN, 5 }, +}; + +static const struct clk_parent_data gcc_parent_data_8[] = { + { .index = DT_BI_TCXO }, + { .hw = &gcc_gpll4.clkr.hw }, +}; + +static const struct parent_map gcc_parent_map_9[] = { + { P_BI_TCXO, 0 }, + { P_GCC_GPLL0_OUT_MAIN, 1 }, + { P_GCC_GPLL8_OUT_MAIN, 2 }, + { P_GCC_GPLL0_OUT_EVEN, 6 }, +}; + +static const struct clk_parent_data gcc_parent_data_9[] = { + { .index = DT_BI_TCXO }, + { .hw = &gcc_gpll0.clkr.hw }, + { .hw = &gcc_gpll8.clkr.hw }, + { .hw = &gcc_gpll0_out_even.clkr.hw }, +}; + +static const struct parent_map gcc_parent_map_10[] = { + { P_BI_TCXO, 0 }, + { P_GCC_GPLL0_OUT_MAIN, 1 }, + { P_GCC_GPLL7_OUT_MAIN, 2 }, +}; + +static const struct clk_parent_data gcc_parent_data_10[] = { + { .index = DT_BI_TCXO }, + { .hw = &gcc_gpll0.clkr.hw }, + { .hw = &gcc_gpll7.clkr.hw }, +}; + +static const struct parent_map gcc_parent_map_11[] = { + { P_BI_TCXO, 0 }, + { P_GCC_GPLL0_OUT_MAIN, 1 }, + { P_GCC_GPLL7_OUT_MAIN, 2 }, + { P_GCC_GPLL8_OUT_MAIN, 3 }, + { P_SLEEP_CLK, 5 }, +}; + +static const struct clk_parent_data gcc_parent_data_11[] = { + { .index = DT_BI_TCXO }, + { .hw = &gcc_gpll0.clkr.hw }, + { .hw = &gcc_gpll7.clkr.hw }, + { .hw = &gcc_gpll8.clkr.hw }, + { .index = DT_SLEEP_CLK }, +}; + +static const struct parent_map gcc_parent_map_17[] = { + { P_BI_TCXO, 0 }, + { P_GCC_GPLL0_OUT_MAIN, 1 }, + { P_GCC_GPLL9_OUT_MAIN, 2 }, + { P_GCC_GPLL4_OUT_MAIN, 5 }, + { P_GCC_GPLL0_OUT_EVEN, 6 }, +}; + +static const struct clk_parent_data gcc_parent_data_17[] = { + { .index = DT_BI_TCXO }, + { .hw = &gcc_gpll0.clkr.hw }, + { .hw = &gcc_gpll9.clkr.hw }, + { .hw = &gcc_gpll4.clkr.hw }, + { .hw = &gcc_gpll0_out_even.clkr.hw }, +}; + +static const struct parent_map gcc_parent_map_18[] = { + { P_UFS_PHY_RX_SYMBOL_0_CLK, 0 }, + { P_BI_TCXO, 2 }, +}; + +static const struct clk_parent_data gcc_parent_data_18[] = { + { .index = DT_UFS_PHY_RX_SYMBOL_0_CLK }, + { .index = DT_BI_TCXO }, +}; + +static const struct parent_map gcc_parent_map_19[] = { + { P_UFS_PHY_RX_SYMBOL_1_CLK, 0 }, + { P_BI_TCXO, 2 }, +}; + +static const struct clk_parent_data gcc_parent_data_19[] = { + { .index = DT_UFS_PHY_RX_SYMBOL_1_CLK }, + { .index = DT_BI_TCXO }, +}; + +static const struct parent_map gcc_parent_map_20[] = { + { P_UFS_PHY_TX_SYMBOL_0_CLK, 0 }, + { P_BI_TCXO, 2 }, +}; + +static const struct clk_parent_data gcc_parent_data_20[] = { + { .index = DT_UFS_PHY_TX_SYMBOL_0_CLK }, + { .index = DT_BI_TCXO }, +}; + +static const struct parent_map gcc_parent_map_21[] = { + { P_GCC_USB3_PRIM_PHY_PIPE_CLK_SRC, 0 }, + { P_USB4_0_PHY_GCC_USB4RTR_MAX_PIPE_CLK, 1 }, + { P_GCC_USB4_0_PHY_PIPEGMUX_CLK_SRC, 3 }, +}; + +static const struct clk_parent_data gcc_parent_data_21[] = { + { .hw = &gcc_usb3_prim_phy_pipe_clk_src.clkr.hw }, + { .index = DT_USB4_0_PHY_GCC_USB4RTR_MAX_PIPE_CLK }, + { .index = DT_GCC_USB4_0_PHY_PIPEGMUX_CLK_SRC }, +}; + +static const struct parent_map gcc_parent_map_22[] = { + { P_GCC_USB3_SEC_PHY_PIPE_CLK_SRC, 0 }, + { P_USB4_1_PHY_GCC_USB4RTR_MAX_PIPE_CLK, 1 }, + { P_GCC_USB4_1_PHY_PLL_PIPE_CLK_SRC, 2 }, + { P_GCC_USB4_1_PHY_PIPEGMUX_CLK_SRC, 3 }, +}; + +static const struct clk_parent_data gcc_parent_data_22[] = { + { .hw = &gcc_usb3_sec_phy_pipe_clk_src.clkr.hw }, + { .index = DT_USB4_1_PHY_GCC_USB4RTR_MAX_PIPE_CLK }, + { .hw = &gcc_usb4_1_phy_pll_pipe_clk_src.clkr.hw }, + { .index = DT_GCC_USB4_1_PHY_PIPEGMUX_CLK_SRC }, +}; + +static const struct parent_map gcc_parent_map_23[] = { + { P_GCC_USB3_TERT_PHY_PIPE_CLK_SRC, 0 }, + { P_USB4_2_PHY_GCC_USB4RTR_MAX_PIPE_CLK, 1 }, + { P_GCC_USB4_2_PHY_PIPEGMUX_CLK_SRC, 3 }, +}; + +static const struct clk_parent_data gcc_parent_data_23[] = { + { .hw = &gcc_usb3_tert_phy_pipe_clk_src.clkr.hw }, + { .index = DT_USB4_2_PHY_GCC_USB4RTR_MAX_PIPE_CLK }, + { .index = DT_GCC_USB4_2_PHY_PIPEGMUX_CLK_SRC }, +}; + +static const struct parent_map gcc_parent_map_24[] = { + { P_USB3_UNI_PHY_MP_GCC_USB30_PIPE_0_CLK, 0 }, + { P_BI_TCXO, 2 }, +}; + +static const struct clk_parent_data gcc_parent_data_24[] = { + { .index = DT_USB3_UNI_PHY_MP_GCC_USB30_PIPE_0_CLK }, + { .index = DT_BI_TCXO }, +}; + +static const struct parent_map gcc_parent_map_25[] = { + { P_USB3_UNI_PHY_MP_GCC_USB30_PIPE_1_CLK, 0 }, + { P_BI_TCXO, 2 }, +}; + +static const struct clk_parent_data gcc_parent_data_25[] = { + { .index = DT_USB3_UNI_PHY_MP_GCC_USB30_PIPE_1_CLK }, + { .index = DT_BI_TCXO }, +}; + +static const struct parent_map gcc_parent_map_26[] = { + { P_USB3_PHY_0_WRAPPER_GCC_USB30_PIPE_CLK, 0 }, + { P_BI_TCXO, 2 }, +}; + +static const struct clk_parent_data gcc_parent_data_26[] = { + { .index = DT_USB3_PHY_0_WRAPPER_GCC_USB30_PIPE_CLK }, + { .index = DT_BI_TCXO }, +}; + +static const struct parent_map gcc_parent_map_27[] = { + { P_USB3_PHY_1_WRAPPER_GCC_USB30_PIPE_CLK, 0 }, + { P_BI_TCXO, 2 }, +}; + +static const struct clk_parent_data gcc_parent_data_27[] = { + { .index = DT_USB3_PHY_1_WRAPPER_GCC_USB30_PIPE_CLK }, + { .index = DT_BI_TCXO }, +}; + +static const struct parent_map gcc_parent_map_28[] = { + { P_USB3_PHY_2_WRAPPER_GCC_USB30_PIPE_CLK, 0 }, + { P_BI_TCXO, 2 }, +}; + +static const struct clk_parent_data gcc_parent_data_28[] = { + { .index = DT_USB3_PHY_2_WRAPPER_GCC_USB30_PIPE_CLK }, + { .index = DT_BI_TCXO }, +}; + +static const struct parent_map gcc_parent_map_29[] = { + { P_GCC_USB4_0_PHY_DP0_GMUX_CLK_SRC, 0 }, + { P_USB4_0_PHY_GCC_USB4RTR_MAX_PIPE_CLK, 2 }, +}; + +static const struct clk_parent_data gcc_parent_data_29[] = { + { .index = DT_GCC_USB4_0_PHY_DP0_GMUX_CLK_SRC }, + { .index = DT_USB4_0_PHY_GCC_USB4RTR_MAX_PIPE_CLK }, +}; + +static const struct parent_map gcc_parent_map_30[] = { + { P_GCC_USB4_0_PHY_DP1_GMUX_CLK_SRC, 0 }, + { P_USB4_0_PHY_GCC_USB4RTR_MAX_PIPE_CLK, 2 }, +}; + +static const struct clk_parent_data gcc_parent_data_30[] = { + { .index = DT_GCC_USB4_0_PHY_DP1_GMUX_CLK_SRC }, + { .index = DT_USB4_0_PHY_GCC_USB4RTR_MAX_PIPE_CLK }, +}; + +static const struct parent_map gcc_parent_map_31[] = { + { P_USB4_0_PHY_GCC_USB4_PCIE_PIPE_CLK, 0 }, + { P_BI_TCXO, 2 }, +}; + +static const struct clk_parent_data gcc_parent_data_31[] = { + { .index = DT_USB4_0_PHY_GCC_USB4_PCIE_PIPE_CLK }, + { .index = DT_BI_TCXO }, +}; + +static const struct parent_map gcc_parent_map_32[] = { + { P_BI_TCXO, 0 }, + { P_GCC_GPLL0_OUT_MAIN, 1 }, + { P_GCC_GPLL7_OUT_MAIN, 2 }, + { P_SLEEP_CLK, 5 }, +}; + +static const struct clk_parent_data gcc_parent_data_32[] = { + { .index = DT_BI_TCXO }, + { .hw = &gcc_gpll0.clkr.hw }, + { .hw = &gcc_gpll7.clkr.hw }, + { .index = DT_SLEEP_CLK }, +}; + +static const struct parent_map gcc_parent_map_33[] = { + { P_GCC_USB4_0_PHY_PCIE_PIPEGMUX_CLK_SRC, 0 }, + { P_USB4_0_PHY_GCC_USB4_PCIE_PIPE_CLK, 1 }, +}; + +static const struct clk_parent_data gcc_parent_data_33[] = { + { .index = DT_GCC_USB4_0_PHY_PCIE_PIPEGMUX_CLK_SRC }, + { .index = DT_USB4_0_PHY_GCC_USB4_PCIE_PIPE_CLK }, +}; + +static const struct parent_map gcc_parent_map_34[] = { + { P_QUSB4PHY_0_GCC_USB4_RX0_CLK, 0 }, + { P_BI_TCXO, 2 }, +}; + +static const struct clk_parent_data gcc_parent_data_34[] = { + { .index = DT_QUSB4PHY_0_GCC_USB4_RX0_CLK }, + { .index = DT_BI_TCXO }, +}; + +static const struct parent_map gcc_parent_map_35[] = { + { P_QUSB4PHY_0_GCC_USB4_RX1_CLK, 0 }, + { P_BI_TCXO, 2 }, +}; + +static const struct clk_parent_data gcc_parent_data_35[] = { + { .index = DT_QUSB4PHY_0_GCC_USB4_RX1_CLK }, + { .index = DT_BI_TCXO }, +}; + +static const struct parent_map gcc_parent_map_36[] = { + { P_GCC_USB4_0_PHY_SYS_PIPEGMUX_CLK_SRC, 0 }, + { P_USB4_0_PHY_GCC_USB4_PCIE_PIPE_CLK, 2 }, +}; + +static const struct clk_parent_data gcc_parent_data_36[] = { + { .index = DT_GCC_USB4_0_PHY_SYS_PIPEGMUX_CLK_SRC }, + { .index = DT_USB4_0_PHY_GCC_USB4_PCIE_PIPE_CLK }, +}; + +static const struct parent_map gcc_parent_map_37[] = { + { P_GCC_USB4_1_PHY_DP0_GMUX_2_CLK_SRC, 0 }, + { P_USB4_1_PHY_GCC_USB4RTR_MAX_PIPE_CLK, 2 }, +}; + +static const struct clk_parent_data gcc_parent_data_37[] = { + { .index = DT_GCC_USB4_1_PHY_DP0_GMUX_2_CLK_SRC }, + { .index = DT_USB4_1_PHY_GCC_USB4RTR_MAX_PIPE_CLK }, +}; + +static const struct parent_map gcc_parent_map_38[] = { + { P_GCC_USB4_1_PHY_DP1_GMUX_2_CLK_SRC, 0 }, + { P_USB4_1_PHY_GCC_USB4RTR_MAX_PIPE_CLK, 2 }, +}; + +static const struct clk_parent_data gcc_parent_data_38[] = { + { .index = DT_GCC_USB4_1_PHY_DP1_GMUX_2_CLK_SRC }, + { .index = DT_USB4_1_PHY_GCC_USB4RTR_MAX_PIPE_CLK }, +}; + +static const struct parent_map gcc_parent_map_39[] = { + { P_USB4_1_PHY_GCC_USB4_PCIE_PIPE_CLK, 0 }, + { P_BI_TCXO, 2 }, +}; + +static const struct clk_parent_data gcc_parent_data_39[] = { + { .index = DT_USB4_1_PHY_GCC_USB4_PCIE_PIPE_CLK }, + { .index = DT_BI_TCXO }, +}; + +static const struct parent_map gcc_parent_map_40[] = { + { P_GCC_USB4_1_PHY_PCIE_PIPEGMUX_CLK_SRC, 0 }, + { P_USB4_1_PHY_GCC_USB4_PCIE_PIPE_CLK, 1 }, +}; + +static const struct clk_parent_data gcc_parent_data_40[] = { + { .index = DT_GCC_USB4_1_PHY_PCIE_PIPEGMUX_CLK_SRC }, + { .index = DT_USB4_1_PHY_GCC_USB4_PCIE_PIPE_CLK }, +}; + +static const struct parent_map gcc_parent_map_41[] = { + { P_BI_TCXO, 0 }, + { P_GCC_GPLL0_OUT_MAIN, 1 }, + { P_GCC_GPLL5_OUT_MAIN, 3 }, + { P_GCC_GPLL0_OUT_EVEN, 6 }, +}; + +static const struct clk_parent_data gcc_parent_data_41[] = { + { .index = DT_BI_TCXO }, + { .hw = &gcc_gpll0.clkr.hw }, + { .hw = &gcc_gpll5.clkr.hw }, + { .hw = &gcc_gpll0_out_even.clkr.hw }, +}; + +static const struct parent_map gcc_parent_map_42[] = { + { P_QUSB4PHY_1_GCC_USB4_RX0_CLK, 0 }, + { P_BI_TCXO, 2 }, +}; + +static const struct clk_parent_data gcc_parent_data_42[] = { + { .index = DT_QUSB4PHY_1_GCC_USB4_RX0_CLK }, + { .index = DT_BI_TCXO }, +}; + +static const struct parent_map gcc_parent_map_43[] = { + { P_QUSB4PHY_1_GCC_USB4_RX1_CLK, 0 }, + { P_BI_TCXO, 2 }, +}; + +static const struct clk_parent_data gcc_parent_data_43[] = { + { .index = DT_QUSB4PHY_1_GCC_USB4_RX1_CLK }, + { .index = DT_BI_TCXO }, +}; + +static const struct parent_map gcc_parent_map_44[] = { + { P_GCC_USB4_1_PHY_SYS_PIPEGMUX_CLK_SRC, 0 }, + { P_USB4_1_PHY_GCC_USB4_PCIE_PIPE_CLK, 2 }, +}; + +static const struct clk_parent_data gcc_parent_data_44[] = { + { .index = DT_GCC_USB4_1_PHY_SYS_PIPEGMUX_CLK_SRC }, + { .index = DT_USB4_1_PHY_GCC_USB4_PCIE_PIPE_CLK }, +}; + +static const struct parent_map gcc_parent_map_45[] = { + { P_GCC_USB4_2_PHY_DP0_GMUX_CLK_SRC, 0 }, + { P_USB4_2_PHY_GCC_USB4RTR_MAX_PIPE_CLK, 2 }, +}; + +static const struct clk_parent_data gcc_parent_data_45[] = { + { .index = DT_GCC_USB4_2_PHY_DP0_GMUX_CLK_SRC }, + { .index = DT_USB4_2_PHY_GCC_USB4RTR_MAX_PIPE_CLK }, +}; + +static const struct parent_map gcc_parent_map_46[] = { + { P_GCC_USB4_2_PHY_DP1_GMUX_CLK_SRC, 0 }, + { P_USB4_2_PHY_GCC_USB4RTR_MAX_PIPE_CLK, 2 }, +}; + +static const struct clk_parent_data gcc_parent_data_46[] = { + { .index = DT_GCC_USB4_2_PHY_DP1_GMUX_CLK_SRC }, + { .index = DT_USB4_2_PHY_GCC_USB4RTR_MAX_PIPE_CLK }, +}; + +static const struct parent_map gcc_parent_map_47[] = { + { P_USB4_2_PHY_GCC_USB4_PCIE_PIPE_CLK, 0 }, + { P_BI_TCXO, 2 }, +}; + +static const struct clk_parent_data gcc_parent_data_47[] = { + { .index = DT_USB4_2_PHY_GCC_USB4_PCIE_PIPE_CLK }, + { .index = DT_BI_TCXO }, +}; + +static const struct parent_map gcc_parent_map_48[] = { + { P_GCC_USB4_2_PHY_PCIE_PIPEGMUX_CLK_SRC, 0 }, + { P_USB4_2_PHY_GCC_USB4_PCIE_PIPE_CLK, 1 }, +}; + +static const struct clk_parent_data gcc_parent_data_48[] = { + { .index = DT_GCC_USB4_2_PHY_PCIE_PIPEGMUX_CLK_SRC }, + { .index = DT_USB4_2_PHY_GCC_USB4_PCIE_PIPE_CLK }, +}; + +static const struct parent_map gcc_parent_map_49[] = { + { P_QUSB4PHY_2_GCC_USB4_RX0_CLK, 0 }, + { P_BI_TCXO, 2 }, +}; + +static const struct clk_parent_data gcc_parent_data_49[] = { + { .index = DT_QUSB4PHY_2_GCC_USB4_RX0_CLK }, + { .index = DT_BI_TCXO }, +}; + +static const struct parent_map gcc_parent_map_50[] = { + { P_QUSB4PHY_2_GCC_USB4_RX1_CLK, 0 }, + { P_BI_TCXO, 2 }, +}; + +static const struct clk_parent_data gcc_parent_data_50[] = { + { .index = DT_QUSB4PHY_2_GCC_USB4_RX1_CLK }, + { .index = DT_BI_TCXO }, +}; + +static const struct parent_map gcc_parent_map_51[] = { + { P_GCC_USB4_2_PHY_SYS_PIPEGMUX_CLK_SRC, 0 }, + { P_USB4_2_PHY_GCC_USB4_PCIE_PIPE_CLK, 2 }, +}; + +static const struct clk_parent_data gcc_parent_data_51[] = { + { .index = DT_GCC_USB4_2_PHY_SYS_PIPEGMUX_CLK_SRC }, + { .index = DT_USB4_2_PHY_GCC_USB4_PCIE_PIPE_CLK }, +}; + +static struct clk_regmap_phy_mux gcc_pcie_3a_pipe_clk_src = { + .reg = 0xdc088, + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "gcc_pcie_3a_pipe_clk_src", + .parent_data = &(const struct clk_parent_data){ + .index = DT_PCIE_3A_PIPE_CLK, + }, + .num_parents = 1, + .ops = &clk_regmap_phy_mux_ops, + }, + }, +}; + +static struct clk_regmap_phy_mux gcc_pcie_3b_pipe_clk_src = { + .reg = 0x941b4, + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "gcc_pcie_3b_pipe_clk_src", + .parent_data = &(const struct clk_parent_data){ + .index = DT_PCIE_3B_PIPE_CLK, + }, + .num_parents = 1, + .ops = &clk_regmap_phy_mux_ops, + }, + }, +}; + +static struct clk_regmap_phy_mux gcc_pcie_4_pipe_clk_src = { + .reg = 0x881a4, + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "gcc_pcie_4_pipe_clk_src", + .parent_data = &(const struct clk_parent_data){ + .index = DT_PCIE_4_PIPE_CLK, + }, + .num_parents = 1, + .ops = &clk_regmap_phy_mux_ops, + }, + }, +}; + +static struct clk_regmap_phy_mux gcc_pcie_5_pipe_clk_src = { + .reg = 0xc309c, + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "gcc_pcie_5_pipe_clk_src", + .parent_data = &(const struct clk_parent_data){ + .index = DT_PCIE_5_PIPE_CLK, + }, + .num_parents = 1, + .ops = &clk_regmap_phy_mux_ops, + }, + }, +}; + +static struct clk_regmap_phy_mux gcc_pcie_6_pipe_clk_src = { + .reg = 0x8a1a4, + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "gcc_pcie_6_pipe_clk_src", + .parent_data = &(const struct clk_parent_data){ + .index = DT_PCIE_6_PIPE_CLK, + }, + .num_parents = 1, + .ops = &clk_regmap_phy_mux_ops, + }, + }, +}; + +static struct clk_regmap_mux gcc_ufs_phy_rx_symbol_0_clk_src = { + .reg = 0x7706c, + .shift = 0, + .width = 2, + .parent_map = gcc_parent_map_18, + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "gcc_ufs_phy_rx_symbol_0_clk_src", + .parent_data = gcc_parent_data_18, + .num_parents = ARRAY_SIZE(gcc_parent_data_18), + .ops = &clk_regmap_mux_closest_ops, + }, + }, +}; + +static struct clk_regmap_mux gcc_ufs_phy_rx_symbol_1_clk_src = { + .reg = 0x770f0, + .shift = 0, + .width = 2, + .parent_map = gcc_parent_map_19, + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "gcc_ufs_phy_rx_symbol_1_clk_src", + .parent_data = gcc_parent_data_19, + .num_parents = ARRAY_SIZE(gcc_parent_data_19), + .ops = &clk_regmap_mux_closest_ops, + }, + }, +}; + +static struct clk_regmap_mux gcc_ufs_phy_tx_symbol_0_clk_src = { + .reg = 0x7705c, + .shift = 0, + .width = 2, + .parent_map = gcc_parent_map_20, + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "gcc_ufs_phy_tx_symbol_0_clk_src", + .parent_data = gcc_parent_data_20, + .num_parents = ARRAY_SIZE(gcc_parent_data_20), + .ops = &clk_regmap_mux_closest_ops, + }, + }, +}; + +static struct clk_regmap_mux gcc_usb34_prim_phy_pipe_clk_src = { + .reg = 0x2b0b8, + .shift = 0, + .width = 2, + .parent_map = gcc_parent_map_21, + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb34_prim_phy_pipe_clk_src", + .parent_data = gcc_parent_data_21, + .num_parents = ARRAY_SIZE(gcc_parent_data_21), + .ops = &clk_regmap_mux_closest_ops, + }, + }, +}; + +static struct clk_regmap_mux gcc_usb34_sec_phy_pipe_clk_src = { + .reg = 0x2d0c4, + .shift = 0, + .width = 2, + .parent_map = gcc_parent_map_22, + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb34_sec_phy_pipe_clk_src", + .parent_data = gcc_parent_data_22, + .num_parents = ARRAY_SIZE(gcc_parent_data_22), + .ops = &clk_regmap_mux_closest_ops, + }, + }, +}; + +static struct clk_regmap_mux gcc_usb34_tert_phy_pipe_clk_src = { + .reg = 0xe00bc, + .shift = 0, + .width = 2, + .parent_map = gcc_parent_map_23, + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb34_tert_phy_pipe_clk_src", + .parent_data = gcc_parent_data_23, + .num_parents = ARRAY_SIZE(gcc_parent_data_23), + .ops = &clk_regmap_mux_closest_ops, + }, + }, +}; + +static struct clk_regmap_mux gcc_usb3_mp_phy_pipe_0_clk_src = { + .reg = 0x9a07c, + .shift = 0, + .width = 2, + .parent_map = gcc_parent_map_24, + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb3_mp_phy_pipe_0_clk_src", + .parent_data = gcc_parent_data_24, + .num_parents = ARRAY_SIZE(gcc_parent_data_24), + .ops = &clk_regmap_mux_closest_ops, + }, + }, +}; + +static struct clk_regmap_mux gcc_usb3_mp_phy_pipe_1_clk_src = { + .reg = 0x9a084, + .shift = 0, + .width = 2, + .parent_map = gcc_parent_map_25, + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb3_mp_phy_pipe_1_clk_src", + .parent_data = gcc_parent_data_25, + .num_parents = ARRAY_SIZE(gcc_parent_data_25), + .ops = &clk_regmap_mux_closest_ops, + }, + }, +}; + +static struct clk_regmap_mux gcc_usb3_prim_phy_pipe_clk_src = { + .reg = 0x3f08c, + .shift = 0, + .width = 2, + .parent_map = gcc_parent_map_26, + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb3_prim_phy_pipe_clk_src", + .parent_data = gcc_parent_data_26, + .num_parents = ARRAY_SIZE(gcc_parent_data_26), + .ops = &clk_regmap_mux_closest_ops, + }, + }, +}; + +static struct clk_regmap_mux gcc_usb3_sec_phy_pipe_clk_src = { + .reg = 0xe207c, + .shift = 0, + .width = 2, + .parent_map = gcc_parent_map_27, + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb3_sec_phy_pipe_clk_src", + .parent_data = gcc_parent_data_27, + .num_parents = ARRAY_SIZE(gcc_parent_data_27), + .ops = &clk_regmap_mux_closest_ops, + }, + }, +}; + +static struct clk_regmap_mux gcc_usb3_tert_phy_pipe_clk_src = { + .reg = 0xe107c, + .shift = 0, + .width = 2, + .parent_map = gcc_parent_map_28, + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb3_tert_phy_pipe_clk_src", + .parent_data = gcc_parent_data_28, + .num_parents = ARRAY_SIZE(gcc_parent_data_28), + .ops = &clk_regmap_mux_closest_ops, + }, + }, +}; + +static struct clk_regmap_mux gcc_usb4_0_phy_dp0_clk_src = { + .reg = 0x2b080, + .shift = 0, + .width = 2, + .parent_map = gcc_parent_map_29, + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb4_0_phy_dp0_clk_src", + .parent_data = gcc_parent_data_29, + .num_parents = ARRAY_SIZE(gcc_parent_data_29), + .ops = &clk_regmap_mux_closest_ops, + }, + }, +}; + +static struct clk_regmap_mux gcc_usb4_0_phy_dp1_clk_src = { + .reg = 0x2b134, + .shift = 0, + .width = 2, + .parent_map = gcc_parent_map_30, + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb4_0_phy_dp1_clk_src", + .parent_data = gcc_parent_data_30, + .num_parents = ARRAY_SIZE(gcc_parent_data_30), + .ops = &clk_regmap_mux_closest_ops, + }, + }, +}; + +static struct clk_regmap_mux gcc_usb4_0_phy_p2rr2p_pipe_clk_src = { + .reg = 0x2b0f0, + .shift = 0, + .width = 2, + .parent_map = gcc_parent_map_31, + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb4_0_phy_p2rr2p_pipe_clk_src", + .parent_data = gcc_parent_data_31, + .num_parents = ARRAY_SIZE(gcc_parent_data_31), + .ops = &clk_regmap_mux_closest_ops, + }, + }, +}; + +static struct clk_regmap_mux gcc_usb4_0_phy_pcie_pipe_mux_clk_src = { + .reg = 0x2b120, + .shift = 0, + .width = 1, + .parent_map = gcc_parent_map_33, + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb4_0_phy_pcie_pipe_mux_clk_src", + .parent_data = gcc_parent_data_33, + .num_parents = ARRAY_SIZE(gcc_parent_data_33), + .ops = &clk_regmap_mux_closest_ops, + }, + }, +}; + +static struct clk_regmap_mux gcc_usb4_0_phy_rx0_clk_src = { + .reg = 0x2b0c0, + .shift = 0, + .width = 2, + .parent_map = gcc_parent_map_34, + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb4_0_phy_rx0_clk_src", + .parent_data = gcc_parent_data_34, + .num_parents = ARRAY_SIZE(gcc_parent_data_34), + .ops = &clk_regmap_mux_closest_ops, + }, + }, +}; + +static struct clk_regmap_mux gcc_usb4_0_phy_rx1_clk_src = { + .reg = 0x2b0d4, + .shift = 0, + .width = 2, + .parent_map = gcc_parent_map_35, + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb4_0_phy_rx1_clk_src", + .parent_data = gcc_parent_data_35, + .num_parents = ARRAY_SIZE(gcc_parent_data_35), + .ops = &clk_regmap_mux_closest_ops, + }, + }, +}; + +static struct clk_regmap_mux gcc_usb4_0_phy_sys_clk_src = { + .reg = 0x2b100, + .shift = 0, + .width = 2, + .parent_map = gcc_parent_map_36, + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb4_0_phy_sys_clk_src", + .parent_data = gcc_parent_data_36, + .num_parents = ARRAY_SIZE(gcc_parent_data_36), + .ops = &clk_regmap_mux_closest_ops, + }, + }, +}; + +static struct clk_regmap_mux gcc_usb4_1_phy_dp0_clk_src = { + .reg = 0x2d08c, + .shift = 0, + .width = 2, + .parent_map = gcc_parent_map_37, + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb4_1_phy_dp0_clk_src", + .parent_data = gcc_parent_data_37, + .num_parents = ARRAY_SIZE(gcc_parent_data_37), + .ops = &clk_regmap_mux_closest_ops, + }, + }, +}; + +static struct clk_regmap_mux gcc_usb4_1_phy_dp1_clk_src = { + .reg = 0x2d154, + .shift = 0, + .width = 2, + .parent_map = gcc_parent_map_38, + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb4_1_phy_dp1_clk_src", + .parent_data = gcc_parent_data_38, + .num_parents = ARRAY_SIZE(gcc_parent_data_38), + .ops = &clk_regmap_mux_closest_ops, + }, + }, +}; + +static struct clk_regmap_mux gcc_usb4_1_phy_p2rr2p_pipe_clk_src = { + .reg = 0x2d114, + .shift = 0, + .width = 2, + .parent_map = gcc_parent_map_39, + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb4_1_phy_p2rr2p_pipe_clk_src", + .parent_data = gcc_parent_data_39, + .num_parents = ARRAY_SIZE(gcc_parent_data_39), + .ops = &clk_regmap_mux_closest_ops, + }, + }, +}; + +static struct clk_regmap_mux gcc_usb4_1_phy_pcie_pipe_mux_clk_src = { + .reg = 0x2d140, + .shift = 0, + .width = 1, + .parent_map = gcc_parent_map_40, + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb4_1_phy_pcie_pipe_mux_clk_src", + .parent_data = gcc_parent_data_40, + .num_parents = ARRAY_SIZE(gcc_parent_data_40), + .ops = &clk_regmap_mux_closest_ops, + }, + }, +}; + +static struct clk_regmap_mux gcc_usb4_1_phy_rx0_clk_src = { + .reg = 0x2d0e4, + .shift = 0, + .width = 2, + .parent_map = gcc_parent_map_42, + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb4_1_phy_rx0_clk_src", + .parent_data = gcc_parent_data_42, + .num_parents = ARRAY_SIZE(gcc_parent_data_42), + .ops = &clk_regmap_mux_closest_ops, + }, + }, +}; + +static struct clk_regmap_mux gcc_usb4_1_phy_rx1_clk_src = { + .reg = 0x2d0f8, + .shift = 0, + .width = 2, + .parent_map = gcc_parent_map_43, + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb4_1_phy_rx1_clk_src", + .parent_data = gcc_parent_data_43, + .num_parents = ARRAY_SIZE(gcc_parent_data_43), + .ops = &clk_regmap_mux_closest_ops, + }, + }, +}; + +static struct clk_regmap_mux gcc_usb4_1_phy_sys_clk_src = { + .reg = 0x2d124, + .shift = 0, + .width = 2, + .parent_map = gcc_parent_map_44, + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb4_1_phy_sys_clk_src", + .parent_data = gcc_parent_data_44, + .num_parents = ARRAY_SIZE(gcc_parent_data_44), + .ops = &clk_regmap_mux_closest_ops, + }, + }, +}; + +static struct clk_regmap_mux gcc_usb4_2_phy_dp0_clk_src = { + .reg = 0xe0084, + .shift = 0, + .width = 2, + .parent_map = gcc_parent_map_45, + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb4_2_phy_dp0_clk_src", + .parent_data = gcc_parent_data_45, + .num_parents = ARRAY_SIZE(gcc_parent_data_45), + .ops = &clk_regmap_mux_closest_ops, + }, + }, +}; + +static struct clk_regmap_mux gcc_usb4_2_phy_dp1_clk_src = { + .reg = 0xe013c, + .shift = 0, + .width = 2, + .parent_map = gcc_parent_map_46, + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb4_2_phy_dp1_clk_src", + .parent_data = gcc_parent_data_46, + .num_parents = ARRAY_SIZE(gcc_parent_data_46), + .ops = &clk_regmap_mux_closest_ops, + }, + }, +}; + +static struct clk_regmap_mux gcc_usb4_2_phy_p2rr2p_pipe_clk_src = { + .reg = 0xe00f4, + .shift = 0, + .width = 2, + .parent_map = gcc_parent_map_47, + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb4_2_phy_p2rr2p_pipe_clk_src", + .parent_data = gcc_parent_data_47, + .num_parents = ARRAY_SIZE(gcc_parent_data_47), + .ops = &clk_regmap_mux_closest_ops, + }, + }, +}; + +static struct clk_regmap_mux gcc_usb4_2_phy_pcie_pipe_mux_clk_src = { + .reg = 0xe0124, + .shift = 0, + .width = 1, + .parent_map = gcc_parent_map_48, + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb4_2_phy_pcie_pipe_mux_clk_src", + .parent_data = gcc_parent_data_48, + .num_parents = ARRAY_SIZE(gcc_parent_data_48), + .ops = &clk_regmap_mux_closest_ops, + }, + }, +}; + +static struct clk_regmap_mux gcc_usb4_2_phy_rx0_clk_src = { + .reg = 0xe00c4, + .shift = 0, + .width = 2, + .parent_map = gcc_parent_map_49, + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb4_2_phy_rx0_clk_src", + .parent_data = gcc_parent_data_49, + .num_parents = ARRAY_SIZE(gcc_parent_data_49), + .ops = &clk_regmap_mux_closest_ops, + }, + }, +}; + +static struct clk_regmap_mux gcc_usb4_2_phy_rx1_clk_src = { + .reg = 0xe00d8, + .shift = 0, + .width = 2, + .parent_map = gcc_parent_map_50, + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb4_2_phy_rx1_clk_src", + .parent_data = gcc_parent_data_50, + .num_parents = ARRAY_SIZE(gcc_parent_data_50), + .ops = &clk_regmap_mux_closest_ops, + }, + }, +}; + +static struct clk_regmap_mux gcc_usb4_2_phy_sys_clk_src = { + .reg = 0xe0104, + .shift = 0, + .width = 2, + .parent_map = gcc_parent_map_51, + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb4_2_phy_sys_clk_src", + .parent_data = gcc_parent_data_51, + .num_parents = ARRAY_SIZE(gcc_parent_data_51), + .ops = &clk_regmap_mux_closest_ops, + }, + }, +}; + +static const struct freq_tbl ftbl_gcc_gp1_clk_src[] = { + F(50000000, P_GCC_GPLL0_OUT_EVEN, 6, 0, 0), + F(100000000, P_GCC_GPLL0_OUT_MAIN, 6, 0, 0), + F(200000000, P_GCC_GPLL0_OUT_MAIN, 3, 0, 0), + { } +}; + +static struct clk_rcg2 gcc_gp1_clk_src = { + .cmd_rcgr = 0x64004, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_4, + .freq_tbl = ftbl_gcc_gp1_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_gp1_clk_src", + .parent_data = gcc_parent_data_4, + .num_parents = ARRAY_SIZE(gcc_parent_data_4), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_no_init_park_ops, + }, +}; + +static struct clk_rcg2 gcc_gp2_clk_src = { + .cmd_rcgr = 0x92004, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_4, + .freq_tbl = ftbl_gcc_gp1_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_gp2_clk_src", + .parent_data = gcc_parent_data_4, + .num_parents = ARRAY_SIZE(gcc_parent_data_4), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_no_init_park_ops, + }, +}; + +static struct clk_rcg2 gcc_gp3_clk_src = { + .cmd_rcgr = 0x93004, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_4, + .freq_tbl = ftbl_gcc_gp1_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_gp3_clk_src", + .parent_data = gcc_parent_data_4, + .num_parents = ARRAY_SIZE(gcc_parent_data_4), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_no_init_park_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_pcie_0_aux_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + { } +}; + +static struct clk_rcg2 gcc_pcie_0_aux_clk_src = { + .cmd_rcgr = 0xc8168, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_2, + .freq_tbl = ftbl_gcc_pcie_0_aux_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_pcie_0_aux_clk_src", + .parent_data = gcc_parent_data_2, + .num_parents = ARRAY_SIZE(gcc_parent_data_2), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_no_init_park_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_pcie_0_phy_rchng_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + F(100000000, P_GCC_GPLL0_OUT_EVEN, 3, 0, 0), + { } +}; + +static struct clk_rcg2 gcc_pcie_0_phy_rchng_clk_src = { + .cmd_rcgr = 0xc803c, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_pcie_0_phy_rchng_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_pcie_0_phy_rchng_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_no_init_park_ops, + }, +}; + +static struct clk_rcg2 gcc_pcie_1_aux_clk_src = { + .cmd_rcgr = 0x2e168, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_2, + .freq_tbl = ftbl_gcc_pcie_0_aux_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_pcie_1_aux_clk_src", + .parent_data = gcc_parent_data_2, + .num_parents = ARRAY_SIZE(gcc_parent_data_2), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_no_init_park_ops, + }, +}; + +static struct clk_rcg2 gcc_pcie_1_phy_rchng_clk_src = { + .cmd_rcgr = 0x2e03c, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_pcie_0_phy_rchng_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_pcie_1_phy_rchng_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_no_init_park_ops, + }, +}; + +static struct clk_rcg2 gcc_pcie_2_aux_clk_src = { + .cmd_rcgr = 0xc0168, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_2, + .freq_tbl = ftbl_gcc_pcie_0_aux_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_pcie_2_aux_clk_src", + .parent_data = gcc_parent_data_2, + .num_parents = ARRAY_SIZE(gcc_parent_data_2), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_no_init_park_ops, + }, +}; + +static struct clk_rcg2 gcc_pcie_2_phy_rchng_clk_src = { + .cmd_rcgr = 0xc003c, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_pcie_0_phy_rchng_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_pcie_2_phy_rchng_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_no_init_park_ops, + }, +}; + +static struct clk_rcg2 gcc_pcie_3a_aux_clk_src = { + .cmd_rcgr = 0xdc08c, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_2, + .freq_tbl = ftbl_gcc_pcie_0_aux_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_pcie_3a_aux_clk_src", + .parent_data = gcc_parent_data_2, + .num_parents = ARRAY_SIZE(gcc_parent_data_2), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_no_init_park_ops, + }, +}; + +static struct clk_rcg2 gcc_pcie_3a_phy_rchng_clk_src = { + .cmd_rcgr = 0xdc070, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_pcie_0_phy_rchng_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_pcie_3a_phy_rchng_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_no_init_park_ops, + }, +}; + +static struct clk_rcg2 gcc_pcie_3b_aux_clk_src = { + .cmd_rcgr = 0x941b8, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_2, + .freq_tbl = ftbl_gcc_pcie_0_aux_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_pcie_3b_aux_clk_src", + .parent_data = gcc_parent_data_2, + .num_parents = ARRAY_SIZE(gcc_parent_data_2), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_no_init_park_ops, + }, +}; + +static struct clk_rcg2 gcc_pcie_3b_phy_rchng_clk_src = { + .cmd_rcgr = 0x94088, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_pcie_0_phy_rchng_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_pcie_3b_phy_rchng_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_no_init_park_ops, + }, +}; + +static struct clk_rcg2 gcc_pcie_4_aux_clk_src = { + .cmd_rcgr = 0x881a8, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_2, + .freq_tbl = ftbl_gcc_pcie_0_aux_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_pcie_4_aux_clk_src", + .parent_data = gcc_parent_data_2, + .num_parents = ARRAY_SIZE(gcc_parent_data_2), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_no_init_park_ops, + }, +}; + +static struct clk_rcg2 gcc_pcie_4_phy_rchng_clk_src = { + .cmd_rcgr = 0x88078, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_pcie_0_phy_rchng_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_pcie_4_phy_rchng_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_no_init_park_ops, + }, +}; + +static struct clk_rcg2 gcc_pcie_5_aux_clk_src = { + .cmd_rcgr = 0xc30a0, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_2, + .freq_tbl = ftbl_gcc_pcie_0_aux_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_pcie_5_aux_clk_src", + .parent_data = gcc_parent_data_2, + .num_parents = ARRAY_SIZE(gcc_parent_data_2), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_no_init_park_ops, + }, +}; + +static struct clk_rcg2 gcc_pcie_5_phy_rchng_clk_src = { + .cmd_rcgr = 0xc3084, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_pcie_0_phy_rchng_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_pcie_5_phy_rchng_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_no_init_park_ops, + }, +}; + +static struct clk_rcg2 gcc_pcie_6_aux_clk_src = { + .cmd_rcgr = 0x8a1a8, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_2, + .freq_tbl = ftbl_gcc_pcie_0_aux_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_pcie_6_aux_clk_src", + .parent_data = gcc_parent_data_2, + .num_parents = ARRAY_SIZE(gcc_parent_data_2), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_no_init_park_ops, + }, +}; + +static struct clk_rcg2 gcc_pcie_6_phy_rchng_clk_src = { + .cmd_rcgr = 0x8a078, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_pcie_0_phy_rchng_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_pcie_6_phy_rchng_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_no_init_park_ops, + }, +}; + +static struct clk_rcg2 gcc_pcie_phy_3a_aux_clk_src = { + .cmd_rcgr = 0x6c01c, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_2, + .freq_tbl = ftbl_gcc_pcie_0_aux_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_pcie_phy_3a_aux_clk_src", + .parent_data = gcc_parent_data_2, + .num_parents = ARRAY_SIZE(gcc_parent_data_2), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_no_init_park_ops, + }, +}; + +static struct clk_rcg2 gcc_pcie_phy_3b_aux_clk_src = { + .cmd_rcgr = 0x7501c, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_2, + .freq_tbl = ftbl_gcc_pcie_0_aux_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_pcie_phy_3b_aux_clk_src", + .parent_data = gcc_parent_data_2, + .num_parents = ARRAY_SIZE(gcc_parent_data_2), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_no_init_park_ops, + }, +}; + +static struct clk_rcg2 gcc_pcie_phy_4_aux_clk_src = { + .cmd_rcgr = 0xd3018, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_2, + .freq_tbl = ftbl_gcc_pcie_0_aux_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_pcie_phy_4_aux_clk_src", + .parent_data = gcc_parent_data_2, + .num_parents = ARRAY_SIZE(gcc_parent_data_2), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_no_init_park_ops, + }, +}; + +static struct clk_rcg2 gcc_pcie_phy_5_aux_clk_src = { + .cmd_rcgr = 0xd2018, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_2, + .freq_tbl = ftbl_gcc_pcie_0_aux_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_pcie_phy_5_aux_clk_src", + .parent_data = gcc_parent_data_2, + .num_parents = ARRAY_SIZE(gcc_parent_data_2), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_no_init_park_ops, + }, +}; + +static struct clk_rcg2 gcc_pcie_phy_6_aux_clk_src = { + .cmd_rcgr = 0xd4018, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_2, + .freq_tbl = ftbl_gcc_pcie_0_aux_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_pcie_phy_6_aux_clk_src", + .parent_data = gcc_parent_data_2, + .num_parents = ARRAY_SIZE(gcc_parent_data_2), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_no_init_park_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_pdm2_clk_src[] = { + F(60000000, P_GCC_GPLL0_OUT_MAIN, 10, 0, 0), + { } +}; + +static struct clk_rcg2 gcc_pdm2_clk_src = { + .cmd_rcgr = 0x33010, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_pdm2_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_pdm2_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_no_init_park_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_qupv3_oob_qspi_s0_clk_src[] = { + F(7372800, P_GCC_GPLL0_OUT_EVEN, 1, 384, 15625), + F(14745600, P_GCC_GPLL0_OUT_EVEN, 1, 768, 15625), + F(19200000, P_BI_TCXO, 1, 0, 0), + F(29491200, P_GCC_GPLL0_OUT_EVEN, 1, 1536, 15625), + F(32000000, P_GCC_GPLL0_OUT_EVEN, 1, 8, 75), + F(48000000, P_GCC_GPLL0_OUT_EVEN, 1, 4, 25), + F(64000000, P_GCC_GPLL0_OUT_EVEN, 1, 16, 75), + F(75000000, P_GCC_GPLL0_OUT_EVEN, 4, 0, 0), + F(80000000, P_GCC_GPLL0_OUT_EVEN, 1, 4, 15), + F(96000000, P_GCC_GPLL0_OUT_EVEN, 1, 8, 25), + F(100000000, P_GCC_GPLL0_OUT_MAIN, 6, 0, 0), + F(120000000, P_GCC_GPLL0_OUT_MAIN, 5, 0, 0), + F(150000000, P_GCC_GPLL0_OUT_EVEN, 2, 0, 0), + F(200000000, P_GCC_GPLL0_OUT_MAIN, 3, 0, 0), + F(403000000, P_GCC_GPLL4_OUT_MAIN, 2, 0, 0), + { } +}; + +static struct clk_init_data gcc_qupv3_oob_qspi_s0_clk_src_init = { + .name = "gcc_qupv3_oob_qspi_s0_clk_src", + .parent_data = gcc_parent_data_3, + .num_parents = ARRAY_SIZE(gcc_parent_data_3), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_no_init_park_ops, +}; + +static struct clk_rcg2 gcc_qupv3_oob_qspi_s0_clk_src = { + .cmd_rcgr = 0xe7044, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_3, + .freq_tbl = ftbl_gcc_qupv3_oob_qspi_s0_clk_src, + .clkr.hw.init = &gcc_qupv3_oob_qspi_s0_clk_src_init, +}; + +static const struct freq_tbl ftbl_gcc_qupv3_oob_qspi_s1_clk_src[] = { + F(7372800, P_GCC_GPLL0_OUT_EVEN, 1, 384, 15625), + F(14745600, P_GCC_GPLL0_OUT_EVEN, 1, 768, 15625), + F(19200000, P_BI_TCXO, 1, 0, 0), + F(29491200, P_GCC_GPLL0_OUT_EVEN, 1, 1536, 15625), + F(32000000, P_GCC_GPLL0_OUT_EVEN, 1, 8, 75), + F(48000000, P_GCC_GPLL0_OUT_EVEN, 1, 4, 25), + F(64000000, P_GCC_GPLL0_OUT_EVEN, 1, 16, 75), + F(75000000, P_GCC_GPLL0_OUT_EVEN, 4, 0, 0), + F(80000000, P_GCC_GPLL0_OUT_EVEN, 1, 4, 15), + F(96000000, P_GCC_GPLL0_OUT_EVEN, 1, 8, 25), + F(100000000, P_GCC_GPLL0_OUT_MAIN, 6, 0, 0), + F(120000000, P_GCC_GPLL0_OUT_MAIN, 5, 0, 0), + F(150000000, P_GCC_GPLL0_OUT_EVEN, 2, 0, 0), + F(200000000, P_GCC_GPLL0_OUT_MAIN, 3, 0, 0), + { } +}; + +static struct clk_init_data gcc_qupv3_oob_qspi_s1_clk_src_init = { + .name = "gcc_qupv3_oob_qspi_s1_clk_src", + .parent_data = gcc_parent_data_1, + .num_parents = ARRAY_SIZE(gcc_parent_data_1), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_no_init_park_ops, +}; + +static struct clk_rcg2 gcc_qupv3_oob_qspi_s1_clk_src = { + .cmd_rcgr = 0xe7170, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_1, + .freq_tbl = ftbl_gcc_qupv3_oob_qspi_s1_clk_src, + .clkr.hw.init = &gcc_qupv3_oob_qspi_s1_clk_src_init, +}; + +static struct clk_init_data gcc_qupv3_wrap0_qspi_s2_clk_src_init = { + .name = "gcc_qupv3_wrap0_qspi_s2_clk_src", + .parent_data = gcc_parent_data_1, + .num_parents = ARRAY_SIZE(gcc_parent_data_1), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_no_init_park_ops, +}; + +static struct clk_rcg2 gcc_qupv3_wrap0_qspi_s2_clk_src = { + .cmd_rcgr = 0x287a0, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_1, + .freq_tbl = ftbl_gcc_qupv3_oob_qspi_s1_clk_src, + .clkr.hw.init = &gcc_qupv3_wrap0_qspi_s2_clk_src_init, +}; + +static struct clk_init_data gcc_qupv3_wrap0_qspi_s3_clk_src_init = { + .name = "gcc_qupv3_wrap0_qspi_s3_clk_src", + .parent_data = gcc_parent_data_1, + .num_parents = ARRAY_SIZE(gcc_parent_data_1), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_no_init_park_ops, +}; + +static struct clk_rcg2 gcc_qupv3_wrap0_qspi_s3_clk_src = { + .cmd_rcgr = 0x288d0, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_1, + .freq_tbl = ftbl_gcc_qupv3_oob_qspi_s1_clk_src, + .clkr.hw.init = &gcc_qupv3_wrap0_qspi_s3_clk_src_init, +}; + +static struct clk_init_data gcc_qupv3_wrap0_qspi_s6_clk_src_init = { + .name = "gcc_qupv3_wrap0_qspi_s6_clk_src", + .parent_data = gcc_parent_data_1, + .num_parents = ARRAY_SIZE(gcc_parent_data_1), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_no_init_park_ops, +}; + +static struct clk_rcg2 gcc_qupv3_wrap0_qspi_s6_clk_src = { + .cmd_rcgr = 0x2866c, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_1, + .freq_tbl = ftbl_gcc_qupv3_oob_qspi_s1_clk_src, + .clkr.hw.init = &gcc_qupv3_wrap0_qspi_s6_clk_src_init, +}; + +static const struct freq_tbl ftbl_gcc_qupv3_wrap0_s0_clk_src[] = { + F(7372800, P_GCC_GPLL0_OUT_EVEN, 1, 384, 15625), + F(14745600, P_GCC_GPLL0_OUT_EVEN, 1, 768, 15625), + F(19200000, P_BI_TCXO, 1, 0, 0), + F(29491200, P_GCC_GPLL0_OUT_EVEN, 1, 1536, 15625), + F(32000000, P_GCC_GPLL0_OUT_EVEN, 1, 8, 75), + F(48000000, P_GCC_GPLL0_OUT_EVEN, 1, 4, 25), + F(64000000, P_GCC_GPLL0_OUT_EVEN, 1, 16, 75), + F(75000000, P_GCC_GPLL0_OUT_EVEN, 4, 0, 0), + F(80000000, P_GCC_GPLL0_OUT_EVEN, 1, 4, 15), + F(96000000, P_GCC_GPLL0_OUT_EVEN, 1, 8, 25), + F(100000000, P_GCC_GPLL0_OUT_MAIN, 6, 0, 0), + F(120000000, P_GCC_GPLL0_OUT_MAIN, 5, 0, 0), + { } +}; + +static struct clk_init_data gcc_qupv3_wrap0_s0_clk_src_init = { + .name = "gcc_qupv3_wrap0_s0_clk_src", + .parent_data = gcc_parent_data_1, + .num_parents = ARRAY_SIZE(gcc_parent_data_1), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_no_init_park_ops, +}; + +static struct clk_rcg2 gcc_qupv3_wrap0_s0_clk_src = { + .cmd_rcgr = 0x28014, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_1, + .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src, + .clkr.hw.init = &gcc_qupv3_wrap0_s0_clk_src_init, +}; + +static struct clk_init_data gcc_qupv3_wrap0_s1_clk_src_init = { + .name = "gcc_qupv3_wrap0_s1_clk_src", + .parent_data = gcc_parent_data_1, + .num_parents = ARRAY_SIZE(gcc_parent_data_1), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_no_init_park_ops, +}; + +static struct clk_rcg2 gcc_qupv3_wrap0_s1_clk_src = { + .cmd_rcgr = 0x28150, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_1, + .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src, + .clkr.hw.init = &gcc_qupv3_wrap0_s1_clk_src_init, +}; + +static const struct freq_tbl ftbl_gcc_qupv3_wrap0_s4_clk_src[] = { + F(7372800, P_GCC_GPLL0_OUT_EVEN, 1, 384, 15625), + F(14745600, P_GCC_GPLL0_OUT_EVEN, 1, 768, 15625), + F(19200000, P_BI_TCXO, 1, 0, 0), + F(29491200, P_GCC_GPLL0_OUT_EVEN, 1, 1536, 15625), + F(32000000, P_GCC_GPLL0_OUT_EVEN, 1, 8, 75), + F(48000000, P_GCC_GPLL0_OUT_EVEN, 1, 4, 25), + F(64000000, P_GCC_GPLL0_OUT_EVEN, 1, 16, 75), + F(75000000, P_GCC_GPLL0_OUT_EVEN, 4, 0, 0), + F(80000000, P_GCC_GPLL0_OUT_EVEN, 1, 4, 15), + F(96000000, P_GCC_GPLL0_OUT_EVEN, 1, 8, 25), + F(100000000, P_GCC_GPLL0_OUT_MAIN, 6, 0, 0), + { } +}; + +static struct clk_init_data gcc_qupv3_wrap0_s4_clk_src_init = { + .name = "gcc_qupv3_wrap0_s4_clk_src", + .parent_data = gcc_parent_data_1, + .num_parents = ARRAY_SIZE(gcc_parent_data_1), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_no_init_park_ops, +}; + +static struct clk_rcg2 gcc_qupv3_wrap0_s4_clk_src = { + .cmd_rcgr = 0x282b4, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_1, + .freq_tbl = ftbl_gcc_qupv3_wrap0_s4_clk_src, + .clkr.hw.init = &gcc_qupv3_wrap0_s4_clk_src_init, +}; + +static struct clk_init_data gcc_qupv3_wrap0_s5_clk_src_init = { + .name = "gcc_qupv3_wrap0_s5_clk_src", + .parent_data = gcc_parent_data_1, + .num_parents = ARRAY_SIZE(gcc_parent_data_1), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_no_init_park_ops, +}; + +static struct clk_rcg2 gcc_qupv3_wrap0_s5_clk_src = { + .cmd_rcgr = 0x283f0, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_1, + .freq_tbl = ftbl_gcc_qupv3_wrap0_s4_clk_src, + .clkr.hw.init = &gcc_qupv3_wrap0_s5_clk_src_init, +}; + +static struct clk_init_data gcc_qupv3_wrap0_s7_clk_src_init = { + .name = "gcc_qupv3_wrap0_s7_clk_src", + .parent_data = gcc_parent_data_1, + .num_parents = ARRAY_SIZE(gcc_parent_data_1), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_no_init_park_ops, +}; + +static struct clk_rcg2 gcc_qupv3_wrap0_s7_clk_src = { + .cmd_rcgr = 0x28540, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_1, + .freq_tbl = ftbl_gcc_qupv3_wrap0_s4_clk_src, + .clkr.hw.init = &gcc_qupv3_wrap0_s7_clk_src_init, +}; + +static struct clk_init_data gcc_qupv3_wrap1_qspi_s2_clk_src_init = { + .name = "gcc_qupv3_wrap1_qspi_s2_clk_src", + .parent_data = gcc_parent_data_1, + .num_parents = ARRAY_SIZE(gcc_parent_data_1), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_no_init_park_ops, +}; + +static struct clk_rcg2 gcc_qupv3_wrap1_qspi_s2_clk_src = { + .cmd_rcgr = 0xb37a0, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_1, + .freq_tbl = ftbl_gcc_qupv3_oob_qspi_s1_clk_src, + .clkr.hw.init = &gcc_qupv3_wrap1_qspi_s2_clk_src_init, +}; + +static struct clk_init_data gcc_qupv3_wrap1_qspi_s3_clk_src_init = { + .name = "gcc_qupv3_wrap1_qspi_s3_clk_src", + .parent_data = gcc_parent_data_1, + .num_parents = ARRAY_SIZE(gcc_parent_data_1), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_no_init_park_ops, +}; + +static struct clk_rcg2 gcc_qupv3_wrap1_qspi_s3_clk_src = { + .cmd_rcgr = 0xb38d0, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_1, + .freq_tbl = ftbl_gcc_qupv3_oob_qspi_s1_clk_src, + .clkr.hw.init = &gcc_qupv3_wrap1_qspi_s3_clk_src_init, +}; + +static struct clk_init_data gcc_qupv3_wrap1_qspi_s6_clk_src_init = { + .name = "gcc_qupv3_wrap1_qspi_s6_clk_src", + .parent_data = gcc_parent_data_1, + .num_parents = ARRAY_SIZE(gcc_parent_data_1), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_no_init_park_ops, +}; + +static struct clk_rcg2 gcc_qupv3_wrap1_qspi_s6_clk_src = { + .cmd_rcgr = 0xb366c, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_1, + .freq_tbl = ftbl_gcc_qupv3_oob_qspi_s1_clk_src, + .clkr.hw.init = &gcc_qupv3_wrap1_qspi_s6_clk_src_init, +}; + +static struct clk_init_data gcc_qupv3_wrap1_s0_clk_src_init = { + .name = "gcc_qupv3_wrap1_s0_clk_src", + .parent_data = gcc_parent_data_1, + .num_parents = ARRAY_SIZE(gcc_parent_data_1), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_no_init_park_ops, +}; + +static struct clk_rcg2 gcc_qupv3_wrap1_s0_clk_src = { + .cmd_rcgr = 0xb3014, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_1, + .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src, + .clkr.hw.init = &gcc_qupv3_wrap1_s0_clk_src_init, +}; + +static struct clk_init_data gcc_qupv3_wrap1_s1_clk_src_init = { + .name = "gcc_qupv3_wrap1_s1_clk_src", + .parent_data = gcc_parent_data_1, + .num_parents = ARRAY_SIZE(gcc_parent_data_1), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_no_init_park_ops, +}; + +static struct clk_rcg2 gcc_qupv3_wrap1_s1_clk_src = { + .cmd_rcgr = 0xb3150, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_1, + .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src, + .clkr.hw.init = &gcc_qupv3_wrap1_s1_clk_src_init, +}; + +static struct clk_init_data gcc_qupv3_wrap1_s4_clk_src_init = { + .name = "gcc_qupv3_wrap1_s4_clk_src", + .parent_data = gcc_parent_data_1, + .num_parents = ARRAY_SIZE(gcc_parent_data_1), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_no_init_park_ops, +}; + +static struct clk_rcg2 gcc_qupv3_wrap1_s4_clk_src = { + .cmd_rcgr = 0xb32b4, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_1, + .freq_tbl = ftbl_gcc_qupv3_wrap0_s4_clk_src, + .clkr.hw.init = &gcc_qupv3_wrap1_s4_clk_src_init, +}; + +static struct clk_init_data gcc_qupv3_wrap1_s5_clk_src_init = { + .name = "gcc_qupv3_wrap1_s5_clk_src", + .parent_data = gcc_parent_data_1, + .num_parents = ARRAY_SIZE(gcc_parent_data_1), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_no_init_park_ops, +}; + +static struct clk_rcg2 gcc_qupv3_wrap1_s5_clk_src = { + .cmd_rcgr = 0xb33f0, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_1, + .freq_tbl = ftbl_gcc_qupv3_wrap0_s4_clk_src, + .clkr.hw.init = &gcc_qupv3_wrap1_s5_clk_src_init, +}; + +static struct clk_init_data gcc_qupv3_wrap1_s7_clk_src_init = { + .name = "gcc_qupv3_wrap1_s7_clk_src", + .parent_data = gcc_parent_data_1, + .num_parents = ARRAY_SIZE(gcc_parent_data_1), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_no_init_park_ops, +}; + +static struct clk_rcg2 gcc_qupv3_wrap1_s7_clk_src = { + .cmd_rcgr = 0xb3540, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_1, + .freq_tbl = ftbl_gcc_qupv3_wrap0_s4_clk_src, + .clkr.hw.init = &gcc_qupv3_wrap1_s7_clk_src_init, +}; + +static struct clk_init_data gcc_qupv3_wrap2_qspi_s2_clk_src_init = { + .name = "gcc_qupv3_wrap2_qspi_s2_clk_src", + .parent_data = gcc_parent_data_1, + .num_parents = ARRAY_SIZE(gcc_parent_data_1), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_no_init_park_ops, +}; + +static struct clk_rcg2 gcc_qupv3_wrap2_qspi_s2_clk_src = { + .cmd_rcgr = 0xb47a0, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_1, + .freq_tbl = ftbl_gcc_qupv3_oob_qspi_s1_clk_src, + .clkr.hw.init = &gcc_qupv3_wrap2_qspi_s2_clk_src_init, +}; + +static struct clk_init_data gcc_qupv3_wrap2_qspi_s3_clk_src_init = { + .name = "gcc_qupv3_wrap2_qspi_s3_clk_src", + .parent_data = gcc_parent_data_1, + .num_parents = ARRAY_SIZE(gcc_parent_data_1), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_no_init_park_ops, +}; + +static struct clk_rcg2 gcc_qupv3_wrap2_qspi_s3_clk_src = { + .cmd_rcgr = 0xb48d0, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_1, + .freq_tbl = ftbl_gcc_qupv3_oob_qspi_s1_clk_src, + .clkr.hw.init = &gcc_qupv3_wrap2_qspi_s3_clk_src_init, +}; + +static struct clk_init_data gcc_qupv3_wrap2_qspi_s6_clk_src_init = { + .name = "gcc_qupv3_wrap2_qspi_s6_clk_src", + .parent_data = gcc_parent_data_1, + .num_parents = ARRAY_SIZE(gcc_parent_data_1), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_no_init_park_ops, +}; + +static struct clk_rcg2 gcc_qupv3_wrap2_qspi_s6_clk_src = { + .cmd_rcgr = 0xb466c, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_1, + .freq_tbl = ftbl_gcc_qupv3_oob_qspi_s1_clk_src, + .clkr.hw.init = &gcc_qupv3_wrap2_qspi_s6_clk_src_init, +}; + +static struct clk_init_data gcc_qupv3_wrap2_s0_clk_src_init = { + .name = "gcc_qupv3_wrap2_s0_clk_src", + .parent_data = gcc_parent_data_1, + .num_parents = ARRAY_SIZE(gcc_parent_data_1), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_no_init_park_ops, +}; + +static struct clk_rcg2 gcc_qupv3_wrap2_s0_clk_src = { + .cmd_rcgr = 0xb4014, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_1, + .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src, + .clkr.hw.init = &gcc_qupv3_wrap2_s0_clk_src_init, +}; + +static struct clk_init_data gcc_qupv3_wrap2_s1_clk_src_init = { + .name = "gcc_qupv3_wrap2_s1_clk_src", + .parent_data = gcc_parent_data_1, + .num_parents = ARRAY_SIZE(gcc_parent_data_1), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_no_init_park_ops, +}; + +static struct clk_rcg2 gcc_qupv3_wrap2_s1_clk_src = { + .cmd_rcgr = 0xb4150, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_1, + .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src, + .clkr.hw.init = &gcc_qupv3_wrap2_s1_clk_src_init, +}; + +static struct clk_init_data gcc_qupv3_wrap2_s4_clk_src_init = { + .name = "gcc_qupv3_wrap2_s4_clk_src", + .parent_data = gcc_parent_data_1, + .num_parents = ARRAY_SIZE(gcc_parent_data_1), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_no_init_park_ops, +}; + +static struct clk_rcg2 gcc_qupv3_wrap2_s4_clk_src = { + .cmd_rcgr = 0xb42b4, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_1, + .freq_tbl = ftbl_gcc_qupv3_wrap0_s4_clk_src, + .clkr.hw.init = &gcc_qupv3_wrap2_s4_clk_src_init, +}; + +static struct clk_init_data gcc_qupv3_wrap2_s5_clk_src_init = { + .name = "gcc_qupv3_wrap2_s5_clk_src", + .parent_data = gcc_parent_data_1, + .num_parents = ARRAY_SIZE(gcc_parent_data_1), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_no_init_park_ops, +}; + +static struct clk_rcg2 gcc_qupv3_wrap2_s5_clk_src = { + .cmd_rcgr = 0xb43f0, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_1, + .freq_tbl = ftbl_gcc_qupv3_wrap0_s4_clk_src, + .clkr.hw.init = &gcc_qupv3_wrap2_s5_clk_src_init, +}; + +static struct clk_init_data gcc_qupv3_wrap2_s7_clk_src_init = { + .name = "gcc_qupv3_wrap2_s7_clk_src", + .parent_data = gcc_parent_data_1, + .num_parents = ARRAY_SIZE(gcc_parent_data_1), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_no_init_park_ops, +}; + +static struct clk_rcg2 gcc_qupv3_wrap2_s7_clk_src = { + .cmd_rcgr = 0xb4540, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_1, + .freq_tbl = ftbl_gcc_qupv3_wrap0_s4_clk_src, + .clkr.hw.init = &gcc_qupv3_wrap2_s7_clk_src_init, +}; + +static const struct freq_tbl ftbl_gcc_sdcc2_apps_clk_src[] = { + F(400000, P_BI_TCXO, 12, 1, 4), + F(25000000, P_GCC_GPLL0_OUT_EVEN, 12, 0, 0), + F(50000000, P_GCC_GPLL0_OUT_EVEN, 6, 0, 0), + F(100000000, P_GCC_GPLL0_OUT_EVEN, 3, 0, 0), + F(202000000, P_GCC_GPLL9_OUT_MAIN, 4, 0, 0), + { } +}; + +static struct clk_rcg2 gcc_sdcc2_apps_clk_src = { + .cmd_rcgr = 0xb001c, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_parent_map_17, + .freq_tbl = ftbl_gcc_sdcc2_apps_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_sdcc2_apps_clk_src", + .parent_data = gcc_parent_data_17, + .num_parents = ARRAY_SIZE(gcc_parent_data_17), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_floor_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_sdcc4_apps_clk_src[] = { + F(400000, P_BI_TCXO, 12, 1, 4), + F(25000000, P_GCC_GPLL0_OUT_EVEN, 12, 0, 0), + F(75000000, P_GCC_GPLL0_OUT_MAIN, 8, 0, 0), + { } +}; + +static struct clk_rcg2 gcc_sdcc4_apps_clk_src = { + .cmd_rcgr = 0xdf01c, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_parent_map_3, + .freq_tbl = ftbl_gcc_sdcc4_apps_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_sdcc4_apps_clk_src", + .parent_data = gcc_parent_data_3, + .num_parents = ARRAY_SIZE(gcc_parent_data_3), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_floor_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_ufs_phy_axi_clk_src[] = { + F(25000000, P_GCC_GPLL0_OUT_EVEN, 12, 0, 0), + F(100000000, P_GCC_GPLL0_OUT_EVEN, 3, 0, 0), + F(201500000, P_GCC_GPLL4_OUT_MAIN, 4, 0, 0), + F(403000000, P_GCC_GPLL4_OUT_MAIN, 2, 0, 0), + { } +}; + +static struct clk_rcg2 gcc_ufs_phy_axi_clk_src = { + .cmd_rcgr = 0x77038, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_parent_map_6, + .freq_tbl = ftbl_gcc_ufs_phy_axi_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_ufs_phy_axi_clk_src", + .parent_data = gcc_parent_data_6, + .num_parents = ARRAY_SIZE(gcc_parent_data_6), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_no_init_park_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_ufs_phy_ice_core_clk_src[] = { + F(100000000, P_GCC_GPLL0_OUT_EVEN, 3, 0, 0), + F(201500000, P_GCC_GPLL4_OUT_MAIN, 4, 0, 0), + F(403000000, P_GCC_GPLL4_OUT_MAIN, 2, 0, 0), + { } +}; + +static struct clk_rcg2 gcc_ufs_phy_ice_core_clk_src = { + .cmd_rcgr = 0x77090, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_6, + .freq_tbl = ftbl_gcc_ufs_phy_ice_core_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_ufs_phy_ice_core_clk_src", + .parent_data = gcc_parent_data_6, + .num_parents = ARRAY_SIZE(gcc_parent_data_6), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_no_init_park_ops, + }, +}; + +static struct clk_rcg2 gcc_ufs_phy_phy_aux_clk_src = { + .cmd_rcgr = 0x770c4, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_5, + .freq_tbl = ftbl_gcc_pcie_0_aux_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_ufs_phy_phy_aux_clk_src", + .parent_data = gcc_parent_data_5, + .num_parents = ARRAY_SIZE(gcc_parent_data_5), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_no_init_park_ops, + }, +}; + +static struct clk_rcg2 gcc_ufs_phy_unipro_core_clk_src = { + .cmd_rcgr = 0x770a8, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_6, + .freq_tbl = ftbl_gcc_ufs_phy_ice_core_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_ufs_phy_unipro_core_clk_src", + .parent_data = gcc_parent_data_6, + .num_parents = ARRAY_SIZE(gcc_parent_data_6), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_no_init_park_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_usb20_master_clk_src[] = { + F(60000000, P_GCC_GPLL14_OUT_MAIN, 10, 0, 0), + F(120000000, P_GCC_GPLL14_OUT_MAIN, 5, 0, 0), + { } +}; + +static struct clk_rcg2 gcc_usb20_master_clk_src = { + .cmd_rcgr = 0xbc030, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_parent_map_7, + .freq_tbl = ftbl_gcc_usb20_master_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_usb20_master_clk_src", + .parent_data = gcc_parent_data_7, + .num_parents = ARRAY_SIZE(gcc_parent_data_7), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_no_init_park_ops, + }, +}; + +static struct clk_rcg2 gcc_usb20_mock_utmi_clk_src = { + .cmd_rcgr = 0xbc048, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_7, + .freq_tbl = ftbl_gcc_pcie_0_aux_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_usb20_mock_utmi_clk_src", + .parent_data = gcc_parent_data_7, + .num_parents = ARRAY_SIZE(gcc_parent_data_7), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_no_init_park_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_usb30_mp_master_clk_src[] = { + F(66666667, P_GCC_GPLL0_OUT_EVEN, 4.5, 0, 0), + F(133333333, P_GCC_GPLL0_OUT_MAIN, 4.5, 0, 0), + F(200000000, P_GCC_GPLL0_OUT_MAIN, 3, 0, 0), + F(240000000, P_GCC_GPLL0_OUT_MAIN, 2.5, 0, 0), + { } +}; + +static struct clk_rcg2 gcc_usb30_mp_master_clk_src = { + .cmd_rcgr = 0x9a03c, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_usb30_mp_master_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_usb30_mp_master_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_no_init_park_ops, + }, +}; + +static struct clk_rcg2 gcc_usb30_mp_mock_utmi_clk_src = { + .cmd_rcgr = 0x9a054, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_pcie_0_aux_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_usb30_mp_mock_utmi_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_no_init_park_ops, + }, +}; + +static struct clk_rcg2 gcc_usb30_prim_master_clk_src = { + .cmd_rcgr = 0x3f04c, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_usb30_mp_master_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_usb30_prim_master_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_no_init_park_ops, + }, +}; + +static struct clk_rcg2 gcc_usb30_prim_mock_utmi_clk_src = { + .cmd_rcgr = 0x3f064, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_pcie_0_aux_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_usb30_prim_mock_utmi_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_no_init_park_ops, + }, +}; + +static struct clk_rcg2 gcc_usb30_sec_master_clk_src = { + .cmd_rcgr = 0xe203c, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_usb30_mp_master_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_usb30_sec_master_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_no_init_park_ops, + }, +}; + +static struct clk_rcg2 gcc_usb30_sec_mock_utmi_clk_src = { + .cmd_rcgr = 0xe2054, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_pcie_0_aux_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_usb30_sec_mock_utmi_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_no_init_park_ops, + }, +}; + +static struct clk_rcg2 gcc_usb30_tert_master_clk_src = { + .cmd_rcgr = 0xe103c, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_usb30_mp_master_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_usb30_tert_master_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_no_init_park_ops, + }, +}; + +static struct clk_rcg2 gcc_usb30_tert_mock_utmi_clk_src = { + .cmd_rcgr = 0xe1054, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_pcie_0_aux_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_usb30_tert_mock_utmi_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_no_init_park_ops, + }, +}; + +static struct clk_rcg2 gcc_usb3_mp_phy_aux_clk_src = { + .cmd_rcgr = 0x9a088, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_8, + .freq_tbl = ftbl_gcc_pcie_0_aux_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_usb3_mp_phy_aux_clk_src", + .parent_data = gcc_parent_data_8, + .num_parents = ARRAY_SIZE(gcc_parent_data_8), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_no_init_park_ops, + }, +}; + +static struct clk_rcg2 gcc_usb3_prim_phy_aux_clk_src = { + .cmd_rcgr = 0x3f090, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_8, + .freq_tbl = ftbl_gcc_pcie_0_aux_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_usb3_prim_phy_aux_clk_src", + .parent_data = gcc_parent_data_8, + .num_parents = ARRAY_SIZE(gcc_parent_data_8), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_no_init_park_ops, + }, +}; + +static struct clk_rcg2 gcc_usb3_sec_phy_aux_clk_src = { + .cmd_rcgr = 0xe2080, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_8, + .freq_tbl = ftbl_gcc_pcie_0_aux_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_usb3_sec_phy_aux_clk_src", + .parent_data = gcc_parent_data_8, + .num_parents = ARRAY_SIZE(gcc_parent_data_8), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_no_init_park_ops, + }, +}; + +static struct clk_rcg2 gcc_usb3_tert_phy_aux_clk_src = { + .cmd_rcgr = 0xe1080, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_8, + .freq_tbl = ftbl_gcc_pcie_0_aux_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_usb3_tert_phy_aux_clk_src", + .parent_data = gcc_parent_data_8, + .num_parents = ARRAY_SIZE(gcc_parent_data_8), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_no_init_park_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_usb4_0_master_clk_src[] = { + F(85714286, P_GCC_GPLL0_OUT_EVEN, 3.5, 0, 0), + F(177666750, P_GCC_GPLL8_OUT_MAIN, 4, 0, 0), + F(355333500, P_GCC_GPLL8_OUT_MAIN, 2, 0, 0), + { } +}; + +static struct clk_rcg2 gcc_usb4_0_master_clk_src = { + .cmd_rcgr = 0x2b02c, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_parent_map_9, + .freq_tbl = ftbl_gcc_usb4_0_master_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_usb4_0_master_clk_src", + .parent_data = gcc_parent_data_9, + .num_parents = ARRAY_SIZE(gcc_parent_data_9), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_no_init_park_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_usb4_0_phy_pcie_pipe_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + F(125000000, P_GCC_GPLL7_OUT_MAIN, 4, 0, 0), + F(250000000, P_GCC_GPLL7_OUT_MAIN, 2, 0, 0), + { } +}; + +static struct clk_rcg2 gcc_usb4_0_phy_pcie_pipe_clk_src = { + .cmd_rcgr = 0x2b104, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_32, + .freq_tbl = ftbl_gcc_usb4_0_phy_pcie_pipe_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_usb4_0_phy_pcie_pipe_clk_src", + .parent_data = gcc_parent_data_32, + .num_parents = ARRAY_SIZE(gcc_parent_data_32), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_no_init_park_ops, + }, +}; + +static struct clk_rcg2 gcc_usb4_0_sb_if_clk_src = { + .cmd_rcgr = 0x2b0a0, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_5, + .freq_tbl = ftbl_gcc_pcie_0_aux_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_usb4_0_sb_if_clk_src", + .parent_data = gcc_parent_data_5, + .num_parents = ARRAY_SIZE(gcc_parent_data_5), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_no_init_park_ops, + }, +}; + +static struct clk_rcg2 gcc_usb4_0_tmu_clk_src = { + .cmd_rcgr = 0x2b084, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_10, + .freq_tbl = ftbl_gcc_usb4_0_phy_pcie_pipe_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_usb4_0_tmu_clk_src", + .parent_data = gcc_parent_data_10, + .num_parents = ARRAY_SIZE(gcc_parent_data_10), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_no_init_park_ops, + }, +}; + +static struct clk_rcg2 gcc_usb4_1_master_clk_src = { + .cmd_rcgr = 0x2d02c, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_parent_map_9, + .freq_tbl = ftbl_gcc_usb4_0_master_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_usb4_1_master_clk_src", + .parent_data = gcc_parent_data_9, + .num_parents = ARRAY_SIZE(gcc_parent_data_9), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_no_init_park_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_usb4_1_phy_pcie_pipe_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + F(177666750, P_GCC_GPLL8_OUT_MAIN, 4, 0, 0), + F(355333500, P_GCC_GPLL8_OUT_MAIN, 2, 0, 0), + { } +}; + +static struct clk_rcg2 gcc_usb4_1_phy_pcie_pipe_clk_src = { + .cmd_rcgr = 0x2d128, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_11, + .freq_tbl = ftbl_gcc_usb4_1_phy_pcie_pipe_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_usb4_1_phy_pcie_pipe_clk_src", + .parent_data = gcc_parent_data_11, + .num_parents = ARRAY_SIZE(gcc_parent_data_11), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_no_init_park_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_usb4_1_phy_pll_pipe_clk_src[] = { + F(100000000, P_GCC_GPLL0_OUT_EVEN, 3, 0, 0), + F(311000000, P_GCC_GPLL5_OUT_MAIN, 3, 0, 0), + { } +}; + +static struct clk_rcg2 gcc_usb4_1_phy_pll_pipe_clk_src = { + .cmd_rcgr = 0x2d0c8, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_41, + .freq_tbl = ftbl_gcc_usb4_1_phy_pll_pipe_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_usb4_1_phy_pll_pipe_clk_src", + .parent_data = gcc_parent_data_41, + .num_parents = ARRAY_SIZE(gcc_parent_data_41), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_no_init_park_ops, + }, +}; + +static struct clk_rcg2 gcc_usb4_1_sb_if_clk_src = { + .cmd_rcgr = 0x2d0ac, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_5, + .freq_tbl = ftbl_gcc_pcie_0_aux_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_usb4_1_sb_if_clk_src", + .parent_data = gcc_parent_data_5, + .num_parents = ARRAY_SIZE(gcc_parent_data_5), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_no_init_park_ops, + }, +}; + +static struct clk_rcg2 gcc_usb4_1_tmu_clk_src = { + .cmd_rcgr = 0x2d090, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_10, + .freq_tbl = ftbl_gcc_usb4_0_phy_pcie_pipe_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_usb4_1_tmu_clk_src", + .parent_data = gcc_parent_data_10, + .num_parents = ARRAY_SIZE(gcc_parent_data_10), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_no_init_park_ops, + }, +}; + +static struct clk_rcg2 gcc_usb4_2_master_clk_src = { + .cmd_rcgr = 0xe002c, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_parent_map_9, + .freq_tbl = ftbl_gcc_usb4_0_master_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_usb4_2_master_clk_src", + .parent_data = gcc_parent_data_9, + .num_parents = ARRAY_SIZE(gcc_parent_data_9), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_no_init_park_ops, + }, +}; + +static struct clk_rcg2 gcc_usb4_2_phy_pcie_pipe_clk_src = { + .cmd_rcgr = 0xe0108, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_11, + .freq_tbl = ftbl_gcc_usb4_0_phy_pcie_pipe_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_usb4_2_phy_pcie_pipe_clk_src", + .parent_data = gcc_parent_data_11, + .num_parents = ARRAY_SIZE(gcc_parent_data_11), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_no_init_park_ops, + }, +}; + +static struct clk_rcg2 gcc_usb4_2_sb_if_clk_src = { + .cmd_rcgr = 0xe00a4, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_5, + .freq_tbl = ftbl_gcc_pcie_0_aux_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_usb4_2_sb_if_clk_src", + .parent_data = gcc_parent_data_5, + .num_parents = ARRAY_SIZE(gcc_parent_data_5), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_no_init_park_ops, + }, +}; + +static struct clk_rcg2 gcc_usb4_2_tmu_clk_src = { + .cmd_rcgr = 0xe0088, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_10, + .freq_tbl = ftbl_gcc_usb4_0_phy_pcie_pipe_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_usb4_2_tmu_clk_src", + .parent_data = gcc_parent_data_10, + .num_parents = ARRAY_SIZE(gcc_parent_data_10), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_no_init_park_ops, + }, +}; + +static struct clk_regmap_div gcc_pcie_3b_pipe_div_clk_src = { + .reg = 0x94070, + .shift = 0, + .width = 4, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_pcie_3b_pipe_div_clk_src", + .parent_hws = (const struct clk_hw*[]) { + &gcc_pcie_3b_pipe_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_regmap_div_ro_ops, + }, +}; + +static struct clk_regmap_div gcc_pcie_4_pipe_div_clk_src = { + .reg = 0x88060, + .shift = 0, + .width = 4, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_pcie_4_pipe_div_clk_src", + .parent_hws = (const struct clk_hw*[]) { + &gcc_pcie_4_pipe_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_regmap_div_ro_ops, + }, +}; + +static struct clk_regmap_div gcc_pcie_5_pipe_div_clk_src = { + .reg = 0xc306c, + .shift = 0, + .width = 4, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_pcie_5_pipe_div_clk_src", + .parent_hws = (const struct clk_hw*[]) { + &gcc_pcie_5_pipe_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_regmap_div_ro_ops, + }, +}; + +static struct clk_regmap_div gcc_pcie_6_pipe_div_clk_src = { + .reg = 0x8a060, + .shift = 0, + .width = 4, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_pcie_6_pipe_div_clk_src", + .parent_hws = (const struct clk_hw*[]) { + &gcc_pcie_6_pipe_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_regmap_div_ro_ops, + }, +}; + +static struct clk_regmap_div gcc_qupv3_oob_s0_clk_src = { + .reg = 0xe7024, + .shift = 0, + .width = 4, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_oob_s0_clk_src", + .parent_hws = (const struct clk_hw*[]) { + &gcc_qupv3_oob_qspi_s0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_regmap_div_ro_ops, + }, +}; + +static struct clk_regmap_div gcc_qupv3_oob_s1_clk_src = { + .reg = 0xe7038, + .shift = 0, + .width = 4, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_oob_s1_clk_src", + .parent_hws = (const struct clk_hw*[]) { + &gcc_qupv3_oob_qspi_s1_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_regmap_div_ro_ops, + }, +}; + +static struct clk_regmap_div gcc_qupv3_wrap0_s2_clk_src = { + .reg = 0x2828c, + .shift = 0, + .width = 4, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap0_s2_clk_src", + .parent_hws = (const struct clk_hw*[]) { + &gcc_qupv3_wrap0_qspi_s2_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_regmap_div_ro_ops, + }, +}; + +static struct clk_regmap_div gcc_qupv3_wrap0_s3_clk_src = { + .reg = 0x282a0, + .shift = 0, + .width = 4, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap0_s3_clk_src", + .parent_hws = (const struct clk_hw*[]) { + &gcc_qupv3_wrap0_qspi_s3_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_regmap_div_ro_ops, + }, +}; + +static struct clk_regmap_div gcc_qupv3_wrap0_s6_clk_src = { + .reg = 0x2852c, + .shift = 0, + .width = 4, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap0_s6_clk_src", + .parent_hws = (const struct clk_hw*[]) { + &gcc_qupv3_wrap0_qspi_s6_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_regmap_div_ro_ops, + }, +}; + +static struct clk_regmap_div gcc_qupv3_wrap1_s2_clk_src = { + .reg = 0xb328c, + .shift = 0, + .width = 4, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap1_s2_clk_src", + .parent_hws = (const struct clk_hw*[]) { + &gcc_qupv3_wrap1_qspi_s2_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_regmap_div_ro_ops, + }, +}; + +static struct clk_regmap_div gcc_qupv3_wrap1_s3_clk_src = { + .reg = 0xb32a0, + .shift = 0, + .width = 4, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap1_s3_clk_src", + .parent_hws = (const struct clk_hw*[]) { + &gcc_qupv3_wrap1_qspi_s3_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_regmap_div_ro_ops, + }, +}; + +static struct clk_regmap_div gcc_qupv3_wrap1_s6_clk_src = { + .reg = 0xb352c, + .shift = 0, + .width = 4, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap1_s6_clk_src", + .parent_hws = (const struct clk_hw*[]) { + &gcc_qupv3_wrap1_qspi_s6_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_regmap_div_ro_ops, + }, +}; + +static struct clk_regmap_div gcc_qupv3_wrap2_s2_clk_src = { + .reg = 0xb428c, + .shift = 0, + .width = 4, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap2_s2_clk_src", + .parent_hws = (const struct clk_hw*[]) { + &gcc_qupv3_wrap2_qspi_s2_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_regmap_div_ro_ops, + }, +}; + +static struct clk_regmap_div gcc_qupv3_wrap2_s3_clk_src = { + .reg = 0xb42a0, + .shift = 0, + .width = 4, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap2_s3_clk_src", + .parent_hws = (const struct clk_hw*[]) { + &gcc_qupv3_wrap2_qspi_s3_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_regmap_div_ro_ops, + }, +}; + +static struct clk_regmap_div gcc_qupv3_wrap2_s6_clk_src = { + .reg = 0xb452c, + .shift = 0, + .width = 4, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap2_s6_clk_src", + .parent_hws = (const struct clk_hw*[]) { + &gcc_qupv3_wrap2_qspi_s6_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_regmap_div_ro_ops, + }, +}; + +static struct clk_regmap_div gcc_usb20_mock_utmi_postdiv_clk_src = { + .reg = 0xbc174, + .shift = 0, + .width = 4, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_usb20_mock_utmi_postdiv_clk_src", + .parent_hws = (const struct clk_hw*[]) { + &gcc_usb20_mock_utmi_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_regmap_div_ro_ops, + }, +}; + +static struct clk_regmap_div gcc_usb30_mp_mock_utmi_postdiv_clk_src = { + .reg = 0x9a06c, + .shift = 0, + .width = 4, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_usb30_mp_mock_utmi_postdiv_clk_src", + .parent_hws = (const struct clk_hw*[]) { + &gcc_usb30_mp_mock_utmi_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_regmap_div_ro_ops, + }, +}; + +static struct clk_regmap_div gcc_usb30_prim_mock_utmi_postdiv_clk_src = { + .reg = 0x3f07c, + .shift = 0, + .width = 4, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_usb30_prim_mock_utmi_postdiv_clk_src", + .parent_hws = (const struct clk_hw*[]) { + &gcc_usb30_prim_mock_utmi_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_regmap_div_ro_ops, + }, +}; + +static struct clk_regmap_div gcc_usb30_sec_mock_utmi_postdiv_clk_src = { + .reg = 0xe206c, + .shift = 0, + .width = 4, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_usb30_sec_mock_utmi_postdiv_clk_src", + .parent_hws = (const struct clk_hw*[]) { + &gcc_usb30_sec_mock_utmi_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_regmap_div_ro_ops, + }, +}; + +static struct clk_regmap_div gcc_usb30_tert_mock_utmi_postdiv_clk_src = { + .reg = 0xe106c, + .shift = 0, + .width = 4, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_usb30_tert_mock_utmi_postdiv_clk_src", + .parent_hws = (const struct clk_hw*[]) { + &gcc_usb30_tert_mock_utmi_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_regmap_div_ro_ops, + }, +}; + +static struct clk_branch gcc_aggre_noc_pcie_3a_west_sf_axi_clk = { + .halt_reg = 0xdc0bc, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x62008, + .enable_mask = BIT(27), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_aggre_noc_pcie_3a_west_sf_axi_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_aggre_noc_pcie_3b_west_sf_axi_clk = { + .halt_reg = 0x941ec, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x62008, + .enable_mask = BIT(28), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_aggre_noc_pcie_3b_west_sf_axi_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_aggre_noc_pcie_4_west_sf_axi_clk = { + .halt_reg = 0x881d0, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x62008, + .enable_mask = BIT(29), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_aggre_noc_pcie_4_west_sf_axi_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_aggre_noc_pcie_5_east_sf_axi_clk = { + .halt_reg = 0xc30d0, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x62008, + .enable_mask = BIT(30), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_aggre_noc_pcie_5_east_sf_axi_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_aggre_noc_pcie_6_west_sf_axi_clk = { + .halt_reg = 0x8a1d0, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x62008, + .enable_mask = BIT(31), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_aggre_noc_pcie_6_west_sf_axi_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_aggre_ufs_phy_axi_clk = { + .halt_reg = 0x77000, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x77000, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x77000, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_aggre_ufs_phy_axi_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_ufs_phy_axi_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_aggre_usb2_prim_axi_clk = { + .halt_reg = 0xbc17c, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0xbc17c, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0xbc17c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_aggre_usb2_prim_axi_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_usb20_master_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_aggre_usb3_mp_axi_clk = { + .halt_reg = 0x9a004, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x9a004, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x9a004, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_aggre_usb3_mp_axi_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_usb30_mp_master_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_aggre_usb3_prim_axi_clk = { + .halt_reg = 0x3f00c, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x3f00c, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x3f00c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_aggre_usb3_prim_axi_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_usb30_prim_master_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_aggre_usb3_sec_axi_clk = { + .halt_reg = 0xe2004, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0xe2004, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0xe2004, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_aggre_usb3_sec_axi_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_usb30_sec_master_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_aggre_usb3_tert_axi_clk = { + .halt_reg = 0xe1004, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0xe1004, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0xe1004, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_aggre_usb3_tert_axi_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_usb30_tert_master_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_aggre_usb4_0_axi_clk = { + .halt_reg = 0x2b000, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x2b000, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x2b000, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_aggre_usb4_0_axi_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_usb4_0_master_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_aggre_usb4_1_axi_clk = { + .halt_reg = 0x2d000, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x2d000, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x2d000, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_aggre_usb4_1_axi_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_usb4_1_master_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_aggre_usb4_2_axi_clk = { + .halt_reg = 0xe0000, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0xe0000, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0xe0000, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_aggre_usb4_2_axi_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_usb4_2_master_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_av1e_ahb_clk = { + .halt_reg = 0x9b02c, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x9b02c, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x9b02c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_av1e_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_av1e_axi_clk = { + .halt_reg = 0x9b030, + .halt_check = BRANCH_HALT_SKIP, + .hwcg_reg = 0x9b030, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x9b030, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_av1e_axi_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_av1e_xo_clk = { + .halt_reg = 0x9b044, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x9b044, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_av1e_xo_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_boot_rom_ahb_clk = { + .halt_reg = 0x34038, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x34038, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x62020, + .enable_mask = BIT(27), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_boot_rom_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_camera_hf_axi_clk = { + .halt_reg = 0x26014, + .halt_check = BRANCH_HALT_SKIP, + .hwcg_reg = 0x26014, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x26014, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_camera_hf_axi_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_camera_sf_axi_clk = { + .halt_reg = 0x26028, + .halt_check = BRANCH_HALT_SKIP, + .hwcg_reg = 0x26028, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x26028, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_camera_sf_axi_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_cfg_noc_pcie_anoc_ahb_clk = { + .halt_reg = 0x82004, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x82004, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x62008, + .enable_mask = BIT(19), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_cfg_noc_pcie_anoc_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_cfg_noc_pcie_anoc_south_ahb_clk = { + .halt_reg = 0xba2ec, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0xba2ec, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x62008, + .enable_mask = BIT(16), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_cfg_noc_pcie_anoc_south_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_cfg_noc_usb2_prim_axi_clk = { + .halt_reg = 0xbc178, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0xbc178, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0xbc178, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_cfg_noc_usb2_prim_axi_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_usb20_master_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_cfg_noc_usb3_mp_axi_clk = { + .halt_reg = 0x9a000, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x9a000, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x9a000, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_cfg_noc_usb3_mp_axi_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_usb30_mp_master_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_cfg_noc_usb3_prim_axi_clk = { + .halt_reg = 0x3f000, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x3f000, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x3f000, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_cfg_noc_usb3_prim_axi_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_usb30_prim_master_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_cfg_noc_usb3_sec_axi_clk = { + .halt_reg = 0xe2000, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0xe2000, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0xe2000, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_cfg_noc_usb3_sec_axi_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_usb30_sec_master_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_cfg_noc_usb3_tert_axi_clk = { + .halt_reg = 0xe1000, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0xe1000, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0xe1000, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_cfg_noc_usb3_tert_axi_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_usb30_tert_master_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_cfg_noc_usb_anoc_ahb_clk = { + .halt_reg = 0x3f004, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x3f004, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x62008, + .enable_mask = BIT(17), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_cfg_noc_usb_anoc_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_cfg_noc_usb_anoc_south_ahb_clk = { + .halt_reg = 0x3f008, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x3f008, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x62008, + .enable_mask = BIT(18), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_cfg_noc_usb_anoc_south_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_disp_hf_axi_clk = { + .halt_reg = 0x27008, + .halt_check = BRANCH_HALT_SKIP, + .clkr = { + .enable_reg = 0x27008, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_disp_hf_axi_clk", + .ops = &clk_branch2_ops, + .flags = CLK_IS_CRITICAL, + }, + }, +}; + +static struct clk_branch gcc_eva_ahb_clk = { + .halt_reg = 0x9b004, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x9b004, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x9b004, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_eva_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_eva_axi0_clk = { + .halt_reg = 0x9b008, + .halt_check = BRANCH_HALT_SKIP, + .hwcg_reg = 0x9b008, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x9b008, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_eva_axi0_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_eva_axi0c_clk = { + .halt_reg = 0x9b01c, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x9b01c, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x9b01c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_eva_axi0c_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_eva_xo_clk = { + .halt_reg = 0x9b024, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x9b024, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_eva_xo_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_gp1_clk = { + .halt_reg = 0x64000, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x64000, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_gp1_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_gp1_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_gp2_clk = { + .halt_reg = 0x92000, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x92000, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_gp2_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_gp2_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_gp3_clk = { + .halt_reg = 0x93000, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x93000, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_gp3_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_gp3_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_gpu_gemnoc_gfx_clk = { + .halt_reg = 0x71010, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x71010, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x71010, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_gpu_gemnoc_gfx_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_gpu_gpll0_clk_src = { + .halt_reg = 0x71024, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x71024, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x62038, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_gpu_gpll0_clk_src", + .parent_hws = (const struct clk_hw*[]) { + &gcc_gpll0.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_gpu_gpll0_div_clk_src = { + .halt_reg = 0x7102c, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x7102c, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x62038, + .enable_mask = BIT(1), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_gpu_gpll0_div_clk_src", + .parent_hws = (const struct clk_hw*[]) { + &gcc_gpll0_out_even.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcie_0_aux_clk = { + .halt_reg = 0xc8018, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x62010, + .enable_mask = BIT(25), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_pcie_0_aux_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_pcie_0_aux_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcie_0_cfg_ahb_clk = { + .halt_reg = 0xba4a8, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0xba4a8, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x62010, + .enable_mask = BIT(24), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_pcie_0_cfg_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcie_0_mstr_axi_clk = { + .halt_reg = 0xba498, + .halt_check = BRANCH_HALT_SKIP, + .hwcg_reg = 0xba498, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x62010, + .enable_mask = BIT(23), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_pcie_0_mstr_axi_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcie_0_phy_rchng_clk = { + .halt_reg = 0xc8038, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x62010, + .enable_mask = BIT(27), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_pcie_0_phy_rchng_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_pcie_0_phy_rchng_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcie_0_pipe_clk = { + .halt_reg = 0xc8028, + .halt_check = BRANCH_HALT_SKIP, + .clkr = { + .enable_reg = 0x62010, + .enable_mask = BIT(26), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_pcie_0_pipe_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_usb4_0_phy_pcie_pipe_mux_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcie_0_slv_axi_clk = { + .halt_reg = 0xba488, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0xba488, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x62010, + .enable_mask = BIT(22), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_pcie_0_slv_axi_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcie_0_slv_q2a_axi_clk = { + .halt_reg = 0xba484, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x62010, + .enable_mask = BIT(21), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_pcie_0_slv_q2a_axi_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcie_1_aux_clk = { + .halt_reg = 0x2e018, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x62010, + .enable_mask = BIT(18), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_pcie_1_aux_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_pcie_1_aux_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcie_1_cfg_ahb_clk = { + .halt_reg = 0xba480, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0xba480, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x62010, + .enable_mask = BIT(17), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_pcie_1_cfg_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcie_1_mstr_axi_clk = { + .halt_reg = 0xba470, + .halt_check = BRANCH_HALT_SKIP, + .hwcg_reg = 0xba470, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x62010, + .enable_mask = BIT(16), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_pcie_1_mstr_axi_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcie_1_phy_rchng_clk = { + .halt_reg = 0x2e038, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x62010, + .enable_mask = BIT(20), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_pcie_1_phy_rchng_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_pcie_1_phy_rchng_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcie_1_pipe_clk = { + .halt_reg = 0x2e028, + .halt_check = BRANCH_HALT_SKIP, + .clkr = { + .enable_reg = 0x62010, + .enable_mask = BIT(19), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_pcie_1_pipe_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_usb4_1_phy_pcie_pipe_mux_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcie_1_slv_axi_clk = { + .halt_reg = 0xba460, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0xba460, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x62010, + .enable_mask = BIT(15), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_pcie_1_slv_axi_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcie_1_slv_q2a_axi_clk = { + .halt_reg = 0xba45c, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x62010, + .enable_mask = BIT(14), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_pcie_1_slv_q2a_axi_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcie_2_aux_clk = { + .halt_reg = 0xc0018, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x62018, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_pcie_2_aux_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_pcie_2_aux_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcie_2_cfg_ahb_clk = { + .halt_reg = 0xba4d0, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0xba4d0, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x62010, + .enable_mask = BIT(31), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_pcie_2_cfg_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcie_2_mstr_axi_clk = { + .halt_reg = 0xba4c0, + .halt_check = BRANCH_HALT_SKIP, + .hwcg_reg = 0xba4c0, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x62010, + .enable_mask = BIT(30), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_pcie_2_mstr_axi_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcie_2_phy_rchng_clk = { + .halt_reg = 0xc0038, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x62018, + .enable_mask = BIT(2), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_pcie_2_phy_rchng_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_pcie_2_phy_rchng_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcie_2_pipe_clk = { + .halt_reg = 0xc0028, + .halt_check = BRANCH_HALT_SKIP, + .clkr = { + .enable_reg = 0x62018, + .enable_mask = BIT(1), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_pcie_2_pipe_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_usb4_2_phy_pcie_pipe_mux_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcie_2_slv_axi_clk = { + .halt_reg = 0xba4b0, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0xba4b0, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x62010, + .enable_mask = BIT(29), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_pcie_2_slv_axi_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcie_2_slv_q2a_axi_clk = { + .halt_reg = 0xba4ac, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x62010, + .enable_mask = BIT(28), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_pcie_2_slv_q2a_axi_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcie_3a_aux_clk = { + .halt_reg = 0xdc04c, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0xdc04c, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x62028, + .enable_mask = BIT(16), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_pcie_3a_aux_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_pcie_3a_aux_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcie_3a_cfg_ahb_clk = { + .halt_reg = 0xba4f0, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0xba4f0, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x62028, + .enable_mask = BIT(15), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_pcie_3a_cfg_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcie_3a_mstr_axi_clk = { + .halt_reg = 0xdc038, + .halt_check = BRANCH_HALT_SKIP, + .hwcg_reg = 0xdc038, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x62028, + .enable_mask = BIT(14), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_pcie_3a_mstr_axi_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcie_3a_phy_rchng_clk = { + .halt_reg = 0xdc06c, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0xdc06c, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x62028, + .enable_mask = BIT(18), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_pcie_3a_phy_rchng_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_pcie_3a_phy_rchng_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcie_3a_pipe_clk = { + .halt_reg = 0xdc05c, + .halt_check = BRANCH_HALT_SKIP, + .hwcg_reg = 0xdc05c, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x62028, + .enable_mask = BIT(17), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_pcie_3a_pipe_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_pcie_3a_pipe_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcie_3a_slv_axi_clk = { + .halt_reg = 0xdc024, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0xdc024, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x62028, + .enable_mask = BIT(13), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_pcie_3a_slv_axi_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcie_3a_slv_q2a_axi_clk = { + .halt_reg = 0xdc01c, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0xdc01c, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x62028, + .enable_mask = BIT(12), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_pcie_3a_slv_q2a_axi_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcie_3b_aux_clk = { + .halt_reg = 0x94050, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x62028, + .enable_mask = BIT(25), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_pcie_3b_aux_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_pcie_3b_aux_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcie_3b_cfg_ahb_clk = { + .halt_reg = 0xba4f4, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0xba4f4, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x62028, + .enable_mask = BIT(24), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_pcie_3b_cfg_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcie_3b_mstr_axi_clk = { + .halt_reg = 0x94038, + .halt_check = BRANCH_HALT_SKIP, + .hwcg_reg = 0x94038, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x62028, + .enable_mask = BIT(23), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_pcie_3b_mstr_axi_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcie_3b_phy_rchng_clk = { + .halt_reg = 0x94084, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x62028, + .enable_mask = BIT(28), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_pcie_3b_phy_rchng_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_pcie_3b_phy_rchng_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcie_3b_pipe_clk = { + .halt_reg = 0x94060, + .halt_check = BRANCH_HALT_SKIP, + .clkr = { + .enable_reg = 0x62028, + .enable_mask = BIT(26), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_pcie_3b_pipe_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_pcie_3b_pipe_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcie_3b_pipe_div2_clk = { + .halt_reg = 0x94074, + .halt_check = BRANCH_HALT_SKIP, + .clkr = { + .enable_reg = 0x62028, + .enable_mask = BIT(27), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_pcie_3b_pipe_div2_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_pcie_3b_pipe_div_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcie_3b_slv_axi_clk = { + .halt_reg = 0x94024, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x94024, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x62028, + .enable_mask = BIT(22), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_pcie_3b_slv_axi_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcie_3b_slv_q2a_axi_clk = { + .halt_reg = 0x9401c, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x62028, + .enable_mask = BIT(21), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_pcie_3b_slv_q2a_axi_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcie_4_aux_clk = { + .halt_reg = 0x88040, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x62030, + .enable_mask = BIT(17), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_pcie_4_aux_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_pcie_4_aux_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcie_4_cfg_ahb_clk = { + .halt_reg = 0xba4fc, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0xba4fc, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x62030, + .enable_mask = BIT(16), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_pcie_4_cfg_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcie_4_mstr_axi_clk = { + .halt_reg = 0x88030, + .halt_check = BRANCH_HALT_SKIP, + .hwcg_reg = 0x88030, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x62030, + .enable_mask = BIT(15), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_pcie_4_mstr_axi_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcie_4_phy_rchng_clk = { + .halt_reg = 0x88074, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x62030, + .enable_mask = BIT(20), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_pcie_4_phy_rchng_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_pcie_4_phy_rchng_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcie_4_pipe_clk = { + .halt_reg = 0x88050, + .halt_check = BRANCH_HALT_SKIP, + .clkr = { + .enable_reg = 0x62030, + .enable_mask = BIT(18), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_pcie_4_pipe_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_pcie_4_pipe_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcie_4_pipe_div2_clk = { + .halt_reg = 0x88064, + .halt_check = BRANCH_HALT_SKIP, + .clkr = { + .enable_reg = 0x62030, + .enable_mask = BIT(19), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_pcie_4_pipe_div2_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_pcie_4_pipe_div_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcie_4_slv_axi_clk = { + .halt_reg = 0x88020, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x88020, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x62030, + .enable_mask = BIT(14), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_pcie_4_slv_axi_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcie_4_slv_q2a_axi_clk = { + .halt_reg = 0x8801c, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x62030, + .enable_mask = BIT(13), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_pcie_4_slv_q2a_axi_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcie_5_aux_clk = { + .halt_reg = 0xc304c, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x62030, + .enable_mask = BIT(5), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_pcie_5_aux_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_pcie_5_aux_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcie_5_cfg_ahb_clk = { + .halt_reg = 0xba4f8, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0xba4f8, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x62030, + .enable_mask = BIT(4), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_pcie_5_cfg_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcie_5_mstr_axi_clk = { + .halt_reg = 0xc3038, + .halt_check = BRANCH_HALT_SKIP, + .hwcg_reg = 0xc3038, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x62030, + .enable_mask = BIT(3), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_pcie_5_mstr_axi_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcie_5_phy_rchng_clk = { + .halt_reg = 0xc3080, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x62030, + .enable_mask = BIT(8), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_pcie_5_phy_rchng_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_pcie_5_phy_rchng_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcie_5_pipe_clk = { + .halt_reg = 0xc305c, + .halt_check = BRANCH_HALT_SKIP, + .clkr = { + .enable_reg = 0x62030, + .enable_mask = BIT(6), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_pcie_5_pipe_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_pcie_5_pipe_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcie_5_pipe_div2_clk = { + .halt_reg = 0xc3070, + .halt_check = BRANCH_HALT_SKIP, + .clkr = { + .enable_reg = 0x62030, + .enable_mask = BIT(7), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_pcie_5_pipe_div2_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_pcie_5_pipe_div_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcie_5_slv_axi_clk = { + .halt_reg = 0xc3024, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0xc3024, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x62030, + .enable_mask = BIT(2), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_pcie_5_slv_axi_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcie_5_slv_q2a_axi_clk = { + .halt_reg = 0xc301c, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x62030, + .enable_mask = BIT(1), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_pcie_5_slv_q2a_axi_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcie_6_aux_clk = { + .halt_reg = 0x8a040, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x62030, + .enable_mask = BIT(27), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_pcie_6_aux_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_pcie_6_aux_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcie_6_cfg_ahb_clk = { + .halt_reg = 0xba500, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0xba500, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x62030, + .enable_mask = BIT(26), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_pcie_6_cfg_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcie_6_mstr_axi_clk = { + .halt_reg = 0x8a030, + .halt_check = BRANCH_HALT_SKIP, + .hwcg_reg = 0x8a030, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x62030, + .enable_mask = BIT(25), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_pcie_6_mstr_axi_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcie_6_phy_rchng_clk = { + .halt_reg = 0x8a074, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x62030, + .enable_mask = BIT(30), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_pcie_6_phy_rchng_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_pcie_6_phy_rchng_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcie_6_pipe_clk = { + .halt_reg = 0x8a050, + .halt_check = BRANCH_HALT_SKIP, + .clkr = { + .enable_reg = 0x62030, + .enable_mask = BIT(28), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_pcie_6_pipe_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_pcie_6_pipe_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcie_6_pipe_div2_clk = { + .halt_reg = 0x8a064, + .halt_check = BRANCH_HALT_SKIP, + .clkr = { + .enable_reg = 0x62030, + .enable_mask = BIT(29), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_pcie_6_pipe_div2_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_pcie_6_pipe_div_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcie_6_slv_axi_clk = { + .halt_reg = 0x8a020, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x8a020, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x62030, + .enable_mask = BIT(24), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_pcie_6_slv_axi_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcie_6_slv_q2a_axi_clk = { + .halt_reg = 0x8a01c, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x62030, + .enable_mask = BIT(23), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_pcie_6_slv_q2a_axi_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcie_noc_pwrctl_clk = { + .halt_reg = 0xba2ac, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x62008, + .enable_mask = BIT(7), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_pcie_noc_pwrctl_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcie_noc_qosgen_extref_clk = { + .halt_reg = 0xba2a8, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x62008, + .enable_mask = BIT(6), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_pcie_noc_qosgen_extref_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcie_noc_sf_center_clk = { + .halt_reg = 0xba2b0, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0xba2b0, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x62008, + .enable_mask = BIT(8), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_pcie_noc_sf_center_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcie_noc_slave_sf_east_clk = { + .halt_reg = 0xba2b8, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0xba2b8, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x62008, + .enable_mask = BIT(9), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_pcie_noc_slave_sf_east_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcie_noc_slave_sf_west_clk = { + .halt_reg = 0xba2c0, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0xba2c0, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x62008, + .enable_mask = BIT(10), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_pcie_noc_slave_sf_west_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcie_noc_tsctr_clk = { + .halt_reg = 0xba2a4, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0xba2a4, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x62008, + .enable_mask = BIT(5), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_pcie_noc_tsctr_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcie_phy_3a_aux_clk = { + .halt_reg = 0x6c038, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x6c038, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x62028, + .enable_mask = BIT(19), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_pcie_phy_3a_aux_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_pcie_phy_3a_aux_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcie_phy_3b_aux_clk = { + .halt_reg = 0x75034, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x62028, + .enable_mask = BIT(31), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_pcie_phy_3b_aux_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_pcie_phy_3b_aux_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcie_phy_4_aux_clk = { + .halt_reg = 0xd3030, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x62030, + .enable_mask = BIT(21), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_pcie_phy_4_aux_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_pcie_phy_4_aux_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcie_phy_5_aux_clk = { + .halt_reg = 0xd2030, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x62030, + .enable_mask = BIT(11), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_pcie_phy_5_aux_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_pcie_phy_5_aux_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcie_phy_6_aux_clk = { + .halt_reg = 0xd4030, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x62030, + .enable_mask = BIT(31), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_pcie_phy_6_aux_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_pcie_phy_6_aux_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcie_rscc_cfg_ahb_clk = { + .halt_reg = 0xb8004, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0xb8004, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x62038, + .enable_mask = BIT(2), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_pcie_rscc_cfg_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcie_rscc_xo_clk = { + .halt_reg = 0xb8008, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x62038, + .enable_mask = BIT(3), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_pcie_rscc_xo_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pdm2_clk = { + .halt_reg = 0x3300c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x3300c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_pdm2_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_pdm2_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pdm_ahb_clk = { + .halt_reg = 0x33004, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x33004, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x33004, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_pdm_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pdm_xo4_clk = { + .halt_reg = 0x33008, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x33008, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_pdm_xo4_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qmip_av1e_ahb_clk = { + .halt_reg = 0x9b048, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x9b048, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x9b048, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qmip_av1e_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qmip_camera_cmd_ahb_clk = { + .halt_reg = 0x26010, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x26010, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x26010, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qmip_camera_cmd_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qmip_camera_nrt_ahb_clk = { + .halt_reg = 0x26008, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x26008, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x26008, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qmip_camera_nrt_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qmip_camera_rt_ahb_clk = { + .halt_reg = 0x2600c, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x2600c, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x2600c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qmip_camera_rt_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qmip_gpu_ahb_clk = { + .halt_reg = 0x71008, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x71008, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x71008, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qmip_gpu_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qmip_pcie_3a_ahb_clk = { + .halt_reg = 0xdc018, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0xdc018, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x62028, + .enable_mask = BIT(11), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qmip_pcie_3a_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qmip_pcie_3b_ahb_clk = { + .halt_reg = 0x94018, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x94018, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x62028, + .enable_mask = BIT(20), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qmip_pcie_3b_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qmip_pcie_4_ahb_clk = { + .halt_reg = 0x88018, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x88018, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x62030, + .enable_mask = BIT(12), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qmip_pcie_4_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qmip_pcie_5_ahb_clk = { + .halt_reg = 0xc3018, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0xc3018, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x62030, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qmip_pcie_5_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qmip_pcie_6_ahb_clk = { + .halt_reg = 0x8a018, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x8a018, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x62030, + .enable_mask = BIT(22), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qmip_pcie_6_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qmip_video_cv_cpu_ahb_clk = { + .halt_reg = 0x32018, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x32018, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x32018, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qmip_video_cv_cpu_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qmip_video_cvp_ahb_clk = { + .halt_reg = 0x32008, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x32008, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x32008, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qmip_video_cvp_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qmip_video_v_cpu_ahb_clk = { + .halt_reg = 0x32014, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x32014, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x32014, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qmip_video_v_cpu_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qmip_video_vcodec1_ahb_clk = { + .halt_reg = 0x32010, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x32010, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x32010, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qmip_video_vcodec1_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qmip_video_vcodec_ahb_clk = { + .halt_reg = 0x3200c, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x3200c, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x3200c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qmip_video_vcodec_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_oob_core_2x_clk = { + .halt_reg = 0xc5040, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x62018, + .enable_mask = BIT(5), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_oob_core_2x_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_oob_core_clk = { + .halt_reg = 0xc502c, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x62018, + .enable_mask = BIT(4), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_oob_core_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_oob_m_ahb_clk = { + .halt_reg = 0xe7004, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0xe7004, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0xe7004, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_oob_m_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_oob_qspi_s0_clk = { + .halt_reg = 0xe7040, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x62018, + .enable_mask = BIT(9), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_oob_qspi_s0_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_qupv3_oob_qspi_s0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_oob_qspi_s1_clk = { + .halt_reg = 0xe729c, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x62018, + .enable_mask = BIT(10), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_oob_qspi_s1_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_qupv3_oob_qspi_s1_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_oob_s0_clk = { + .halt_reg = 0xe7014, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x62018, + .enable_mask = BIT(6), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_oob_s0_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_qupv3_oob_s0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_oob_s1_clk = { + .halt_reg = 0xe7028, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x62018, + .enable_mask = BIT(7), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_oob_s1_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_qupv3_oob_s1_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_oob_s_ahb_clk = { + .halt_reg = 0xc5028, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0xc5028, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x62018, + .enable_mask = BIT(3), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_oob_s_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_oob_tcxo_clk = { + .halt_reg = 0xe703c, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x62018, + .enable_mask = BIT(8), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_oob_tcxo_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap0_core_2x_clk = { + .halt_reg = 0xc5448, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x62020, + .enable_mask = BIT(12), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap0_core_2x_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap0_core_clk = { + .halt_reg = 0xc5434, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x62020, + .enable_mask = BIT(11), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap0_core_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap0_qspi_s2_clk = { + .halt_reg = 0x2879c, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x62020, + .enable_mask = BIT(22), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap0_qspi_s2_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_qupv3_wrap0_qspi_s2_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap0_qspi_s3_clk = { + .halt_reg = 0x288cc, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x62020, + .enable_mask = BIT(23), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap0_qspi_s3_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_qupv3_wrap0_qspi_s3_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap0_qspi_s6_clk = { + .halt_reg = 0x28798, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x62020, + .enable_mask = BIT(21), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap0_qspi_s6_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_qupv3_wrap0_qspi_s6_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap0_s0_clk = { + .halt_reg = 0x28004, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x62020, + .enable_mask = BIT(13), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap0_s0_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_qupv3_wrap0_s0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap0_s1_clk = { + .halt_reg = 0x28140, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x62020, + .enable_mask = BIT(14), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap0_s1_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_qupv3_wrap0_s1_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap0_s2_clk = { + .halt_reg = 0x2827c, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x62020, + .enable_mask = BIT(15), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap0_s2_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_qupv3_wrap0_s2_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap0_s3_clk = { + .halt_reg = 0x28290, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x62020, + .enable_mask = BIT(16), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap0_s3_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_qupv3_wrap0_s3_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap0_s4_clk = { + .halt_reg = 0x282a4, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x62020, + .enable_mask = BIT(17), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap0_s4_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_qupv3_wrap0_s4_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap0_s5_clk = { + .halt_reg = 0x283e0, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x62020, + .enable_mask = BIT(18), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap0_s5_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_qupv3_wrap0_s5_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap0_s6_clk = { + .halt_reg = 0x2851c, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x62020, + .enable_mask = BIT(19), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap0_s6_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_qupv3_wrap0_s6_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap0_s7_clk = { + .halt_reg = 0x28530, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x62020, + .enable_mask = BIT(20), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap0_s7_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_qupv3_wrap0_s7_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap1_core_2x_clk = { + .halt_reg = 0xc5198, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x62018, + .enable_mask = BIT(14), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap1_core_2x_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap1_core_clk = { + .halt_reg = 0xc5184, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x62018, + .enable_mask = BIT(13), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap1_core_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap1_qspi_s2_clk = { + .halt_reg = 0xb379c, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x62018, + .enable_mask = BIT(24), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap1_qspi_s2_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_qupv3_wrap1_qspi_s2_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap1_qspi_s3_clk = { + .halt_reg = 0xb38cc, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x62018, + .enable_mask = BIT(25), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap1_qspi_s3_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_qupv3_wrap1_qspi_s3_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap1_qspi_s6_clk = { + .halt_reg = 0xb3798, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x62018, + .enable_mask = BIT(23), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap1_qspi_s6_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_qupv3_wrap1_qspi_s6_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap1_s0_clk = { + .halt_reg = 0xb3004, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x62018, + .enable_mask = BIT(15), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap1_s0_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_qupv3_wrap1_s0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap1_s1_clk = { + .halt_reg = 0xb3140, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x62018, + .enable_mask = BIT(16), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap1_s1_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_qupv3_wrap1_s1_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap1_s2_clk = { + .halt_reg = 0xb327c, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x62018, + .enable_mask = BIT(17), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap1_s2_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_qupv3_wrap1_s2_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap1_s3_clk = { + .halt_reg = 0xb3290, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x62018, + .enable_mask = BIT(18), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap1_s3_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_qupv3_wrap1_s3_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap1_s4_clk = { + .halt_reg = 0xb32a4, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x62018, + .enable_mask = BIT(19), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap1_s4_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_qupv3_wrap1_s4_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap1_s5_clk = { + .halt_reg = 0xb33e0, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x62018, + .enable_mask = BIT(20), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap1_s5_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_qupv3_wrap1_s5_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap1_s6_clk = { + .halt_reg = 0xb351c, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x62018, + .enable_mask = BIT(21), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap1_s6_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_qupv3_wrap1_s6_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap1_s7_clk = { + .halt_reg = 0xb3530, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x62018, + .enable_mask = BIT(22), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap1_s7_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_qupv3_wrap1_s7_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap2_core_2x_clk = { + .halt_reg = 0xc52f0, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x62018, + .enable_mask = BIT(29), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap2_core_2x_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap2_core_clk = { + .halt_reg = 0xc52dc, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x62018, + .enable_mask = BIT(28), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap2_core_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap2_qspi_s2_clk = { + .halt_reg = 0xb479c, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x62020, + .enable_mask = BIT(7), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap2_qspi_s2_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_qupv3_wrap2_qspi_s2_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap2_qspi_s3_clk = { + .halt_reg = 0xb48cc, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x62020, + .enable_mask = BIT(8), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap2_qspi_s3_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_qupv3_wrap2_qspi_s3_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap2_qspi_s6_clk = { + .halt_reg = 0xb4798, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x62020, + .enable_mask = BIT(6), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap2_qspi_s6_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_qupv3_wrap2_qspi_s6_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap2_s0_clk = { + .halt_reg = 0xb4004, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x62018, + .enable_mask = BIT(30), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap2_s0_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_qupv3_wrap2_s0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap2_s1_clk = { + .halt_reg = 0xb4140, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x62018, + .enable_mask = BIT(31), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap2_s1_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_qupv3_wrap2_s1_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap2_s2_clk = { + .halt_reg = 0xb427c, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x62020, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap2_s2_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_qupv3_wrap2_s2_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap2_s3_clk = { + .halt_reg = 0xb4290, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x62020, + .enable_mask = BIT(1), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap2_s3_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_qupv3_wrap2_s3_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap2_s4_clk = { + .halt_reg = 0xb42a4, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x62020, + .enable_mask = BIT(2), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap2_s4_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_qupv3_wrap2_s4_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap2_s5_clk = { + .halt_reg = 0xb43e0, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x62020, + .enable_mask = BIT(3), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap2_s5_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_qupv3_wrap2_s5_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap2_s6_clk = { + .halt_reg = 0xb451c, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x62020, + .enable_mask = BIT(4), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap2_s6_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_qupv3_wrap2_s6_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap2_s7_clk = { + .halt_reg = 0xb4530, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x62020, + .enable_mask = BIT(5), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap2_s7_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_qupv3_wrap2_s7_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap_0_m_ahb_clk = { + .halt_reg = 0xc542c, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0xc542c, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x62020, + .enable_mask = BIT(9), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap_0_m_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap_0_s_ahb_clk = { + .halt_reg = 0xc5430, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0xc5430, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x62020, + .enable_mask = BIT(10), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap_0_s_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap_1_m_ahb_clk = { + .halt_reg = 0xc517c, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0xc517c, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x62018, + .enable_mask = BIT(11), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap_1_m_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap_1_s_ahb_clk = { + .halt_reg = 0xc5180, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0xc5180, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x62018, + .enable_mask = BIT(12), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap_1_s_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap_2_m_ahb_clk = { + .halt_reg = 0xc52d4, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0xc52d4, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x62018, + .enable_mask = BIT(26), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap_2_m_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap_2_s_ahb_clk = { + .halt_reg = 0xc52d8, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0xc52d8, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x62018, + .enable_mask = BIT(27), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap_2_s_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_sdcc2_ahb_clk = { + .halt_reg = 0xb0014, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xb0014, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_sdcc2_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_sdcc2_apps_clk = { + .halt_reg = 0xb0004, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xb0004, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_sdcc2_apps_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_sdcc2_apps_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_sdcc4_ahb_clk = { + .halt_reg = 0xdf014, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xdf014, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_sdcc4_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_sdcc4_apps_clk = { + .halt_reg = 0xdf004, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xdf004, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_sdcc4_apps_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_sdcc4_apps_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_ufs_phy_ahb_clk = { + .halt_reg = 0xba504, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0xba504, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0xba504, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_ufs_phy_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_ufs_phy_axi_clk = { + .halt_reg = 0x7701c, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x7701c, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x7701c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_ufs_phy_axi_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_ufs_phy_axi_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_ufs_phy_ice_core_clk = { + .halt_reg = 0x77080, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x77080, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x77080, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_ufs_phy_ice_core_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_ufs_phy_ice_core_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_ufs_phy_phy_aux_clk = { + .halt_reg = 0x770c0, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x770c0, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x770c0, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_ufs_phy_phy_aux_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_ufs_phy_phy_aux_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_ufs_phy_rx_symbol_0_clk = { + .halt_reg = 0x77034, + .halt_check = BRANCH_HALT_DELAY, + .clkr = { + .enable_reg = 0x77034, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_ufs_phy_rx_symbol_0_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_ufs_phy_rx_symbol_0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_ufs_phy_rx_symbol_1_clk = { + .halt_reg = 0x770dc, + .halt_check = BRANCH_HALT_DELAY, + .clkr = { + .enable_reg = 0x770dc, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_ufs_phy_rx_symbol_1_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_ufs_phy_rx_symbol_1_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_ufs_phy_tx_symbol_0_clk = { + .halt_reg = 0x77030, + .halt_check = BRANCH_HALT_DELAY, + .clkr = { + .enable_reg = 0x77030, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_ufs_phy_tx_symbol_0_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_ufs_phy_tx_symbol_0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_ufs_phy_unipro_core_clk = { + .halt_reg = 0x77070, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x77070, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x77070, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_ufs_phy_unipro_core_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_ufs_phy_unipro_core_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb20_master_clk = { + .halt_reg = 0xbc018, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xbc018, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb20_master_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_usb20_master_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb20_mock_utmi_clk = { + .halt_reg = 0xbc02c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xbc02c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb20_mock_utmi_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_usb20_mock_utmi_postdiv_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb20_sleep_clk = { + .halt_reg = 0xbc028, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xbc028, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb20_sleep_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb30_mp_master_clk = { + .halt_reg = 0x9a024, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x9a024, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb30_mp_master_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_usb30_mp_master_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb30_mp_mock_utmi_clk = { + .halt_reg = 0x9a038, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x9a038, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb30_mp_mock_utmi_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_usb30_mp_mock_utmi_postdiv_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb30_mp_sleep_clk = { + .halt_reg = 0x9a034, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x9a034, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb30_mp_sleep_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb30_prim_master_clk = { + .halt_reg = 0x3f030, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x3f030, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb30_prim_master_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_usb30_prim_master_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb30_prim_mock_utmi_clk = { + .halt_reg = 0x3f048, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x3f048, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb30_prim_mock_utmi_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_usb30_prim_mock_utmi_postdiv_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb30_prim_sleep_clk = { + .halt_reg = 0x3f044, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x3f044, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb30_prim_sleep_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb30_sec_master_clk = { + .halt_reg = 0xe2024, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xe2024, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb30_sec_master_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_usb30_sec_master_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb30_sec_mock_utmi_clk = { + .halt_reg = 0xe2038, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xe2038, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb30_sec_mock_utmi_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_usb30_sec_mock_utmi_postdiv_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb30_sec_sleep_clk = { + .halt_reg = 0xe2034, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xe2034, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb30_sec_sleep_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb30_tert_master_clk = { + .halt_reg = 0xe1024, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xe1024, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb30_tert_master_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_usb30_tert_master_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb30_tert_mock_utmi_clk = { + .halt_reg = 0xe1038, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xe1038, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb30_tert_mock_utmi_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_usb30_tert_mock_utmi_postdiv_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb30_tert_sleep_clk = { + .halt_reg = 0xe1034, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xe1034, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb30_tert_sleep_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb3_mp_phy_aux_clk = { + .halt_reg = 0x9a070, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x9a070, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb3_mp_phy_aux_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_usb3_mp_phy_aux_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb3_mp_phy_com_aux_clk = { + .halt_reg = 0x9a074, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x9a074, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb3_mp_phy_com_aux_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_usb3_mp_phy_aux_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb3_mp_phy_pipe_0_clk = { + .halt_reg = 0x9a078, + .halt_check = BRANCH_HALT_SKIP, + .clkr = { + .enable_reg = 0x9a078, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb3_mp_phy_pipe_0_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_usb3_mp_phy_pipe_0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb3_mp_phy_pipe_1_clk = { + .halt_reg = 0x9a080, + .halt_check = BRANCH_HALT_SKIP, + .clkr = { + .enable_reg = 0x9a080, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb3_mp_phy_pipe_1_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_usb3_mp_phy_pipe_1_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb3_prim_phy_aux_clk = { + .halt_reg = 0x3f080, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x3f080, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb3_prim_phy_aux_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_usb3_prim_phy_aux_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb3_prim_phy_com_aux_clk = { + .halt_reg = 0x3f084, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x3f084, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb3_prim_phy_com_aux_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_usb3_prim_phy_aux_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb3_prim_phy_pipe_clk = { + .halt_reg = 0x3f088, + .halt_check = BRANCH_HALT_DELAY, + .hwcg_reg = 0x3f088, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x3f088, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb3_prim_phy_pipe_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_usb34_prim_phy_pipe_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb3_sec_phy_aux_clk = { + .halt_reg = 0xe2070, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xe2070, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb3_sec_phy_aux_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_usb3_sec_phy_aux_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb3_sec_phy_com_aux_clk = { + .halt_reg = 0xe2074, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xe2074, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb3_sec_phy_com_aux_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_usb3_sec_phy_aux_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb3_sec_phy_pipe_clk = { + .halt_reg = 0xe2078, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0xe2078, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0xe2078, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb3_sec_phy_pipe_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_usb34_sec_phy_pipe_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb3_tert_phy_aux_clk = { + .halt_reg = 0xe1070, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xe1070, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb3_tert_phy_aux_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_usb3_tert_phy_aux_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb3_tert_phy_com_aux_clk = { + .halt_reg = 0xe1074, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xe1074, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb3_tert_phy_com_aux_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_usb3_tert_phy_aux_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb3_tert_phy_pipe_clk = { + .halt_reg = 0xe1078, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0xe1078, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0xe1078, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb3_tert_phy_pipe_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_usb34_tert_phy_pipe_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb4_0_cfg_ahb_clk = { + .halt_reg = 0xba450, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0xba450, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0xba450, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb4_0_cfg_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb4_0_dp0_clk = { + .halt_reg = 0x2b070, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x2b070, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb4_0_dp0_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_usb4_0_phy_dp0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb4_0_dp1_clk = { + .halt_reg = 0x2b124, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x2b124, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb4_0_dp1_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_usb4_0_phy_dp1_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb4_0_master_clk = { + .halt_reg = 0x2b01c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x2b01c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb4_0_master_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_usb4_0_master_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb4_0_phy_p2rr2p_pipe_clk = { + .halt_reg = 0x2b0f4, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x2b0f4, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb4_0_phy_p2rr2p_pipe_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_usb4_0_phy_p2rr2p_pipe_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb4_0_phy_pcie_pipe_clk = { + .halt_reg = 0x2b04c, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x62010, + .enable_mask = BIT(11), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb4_0_phy_pcie_pipe_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_usb4_0_phy_pcie_pipe_mux_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb4_0_phy_rx0_clk = { + .halt_reg = 0x2b0c4, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x2b0c4, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb4_0_phy_rx0_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_usb4_0_phy_rx0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb4_0_phy_rx1_clk = { + .halt_reg = 0x2b0d8, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x2b0d8, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb4_0_phy_rx1_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_usb4_0_phy_rx1_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb4_0_phy_usb_pipe_clk = { + .halt_reg = 0x2b0bc, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x2b0bc, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x2b0bc, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb4_0_phy_usb_pipe_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_usb34_prim_phy_pipe_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb4_0_sb_if_clk = { + .halt_reg = 0x2b048, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x2b048, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb4_0_sb_if_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_usb4_0_sb_if_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb4_0_sys_clk = { + .halt_reg = 0x2b05c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x2b05c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb4_0_sys_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_usb4_0_phy_sys_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb4_0_tmu_clk = { + .halt_reg = 0x2b09c, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x2b09c, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x2b09c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb4_0_tmu_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_usb4_0_tmu_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb4_0_uc_hrr_clk = { + .halt_reg = 0x2b06c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x2b06c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb4_0_uc_hrr_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_usb4_0_phy_sys_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb4_1_cfg_ahb_clk = { + .halt_reg = 0xba454, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0xba454, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0xba454, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb4_1_cfg_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb4_1_dp0_clk = { + .halt_reg = 0x2d07c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x2d07c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb4_1_dp0_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_usb4_1_phy_dp0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb4_1_dp1_clk = { + .halt_reg = 0x2d144, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x2d144, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb4_1_dp1_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_usb4_1_phy_dp1_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb4_1_master_clk = { + .halt_reg = 0x2d01c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x2d01c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb4_1_master_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_usb4_1_master_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb4_1_phy_p2rr2p_pipe_clk = { + .halt_reg = 0x2d118, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x2d118, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb4_1_phy_p2rr2p_pipe_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_usb4_1_phy_p2rr2p_pipe_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb4_1_phy_pcie_pipe_clk = { + .halt_reg = 0x2d04c, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x62010, + .enable_mask = BIT(12), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb4_1_phy_pcie_pipe_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_usb4_1_phy_pcie_pipe_mux_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb4_1_phy_rx0_clk = { + .halt_reg = 0x2d0e8, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x2d0e8, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb4_1_phy_rx0_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_usb4_1_phy_rx0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb4_1_phy_rx1_clk = { + .halt_reg = 0x2d0fc, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x2d0fc, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb4_1_phy_rx1_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_usb4_1_phy_rx1_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb4_1_phy_usb_pipe_clk = { + .halt_reg = 0x2d0e0, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x2d0e0, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x2d0e0, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb4_1_phy_usb_pipe_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_usb34_sec_phy_pipe_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb4_1_sb_if_clk = { + .halt_reg = 0x2d048, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x2d048, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb4_1_sb_if_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_usb4_1_sb_if_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb4_1_sys_clk = { + .halt_reg = 0x2d05c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x2d05c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb4_1_sys_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_usb4_1_phy_sys_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb4_1_tmu_clk = { + .halt_reg = 0x2d0a8, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x2d0a8, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x2d0a8, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb4_1_tmu_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_usb4_1_tmu_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb4_1_uc_hrr_clk = { + .halt_reg = 0x2d06c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x2d06c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb4_1_uc_hrr_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_usb4_1_phy_sys_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb4_2_cfg_ahb_clk = { + .halt_reg = 0xba458, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0xba458, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0xba458, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb4_2_cfg_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb4_2_dp0_clk = { + .halt_reg = 0xe0070, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xe0070, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb4_2_dp0_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_usb4_2_phy_dp0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb4_2_dp1_clk = { + .halt_reg = 0xe0128, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xe0128, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb4_2_dp1_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_usb4_2_phy_dp1_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb4_2_master_clk = { + .halt_reg = 0xe001c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xe001c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb4_2_master_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_usb4_2_master_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb4_2_phy_p2rr2p_pipe_clk = { + .halt_reg = 0xe00f8, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xe00f8, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb4_2_phy_p2rr2p_pipe_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_usb4_2_phy_p2rr2p_pipe_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb4_2_phy_pcie_pipe_clk = { + .halt_reg = 0xe004c, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x62010, + .enable_mask = BIT(13), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb4_2_phy_pcie_pipe_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_usb4_2_phy_pcie_pipe_mux_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb4_2_phy_rx0_clk = { + .halt_reg = 0xe00c8, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xe00c8, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb4_2_phy_rx0_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_usb4_2_phy_rx0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb4_2_phy_rx1_clk = { + .halt_reg = 0xe00dc, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xe00dc, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb4_2_phy_rx1_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_usb4_2_phy_rx1_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb4_2_phy_usb_pipe_clk = { + .halt_reg = 0xe00c0, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0xe00c0, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0xe00c0, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb4_2_phy_usb_pipe_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_usb34_tert_phy_pipe_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb4_2_sb_if_clk = { + .halt_reg = 0xe0048, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xe0048, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb4_2_sb_if_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_usb4_2_sb_if_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb4_2_sys_clk = { + .halt_reg = 0xe005c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xe005c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb4_2_sys_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_usb4_2_phy_sys_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb4_2_tmu_clk = { + .halt_reg = 0xe00a0, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0xe00a0, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0xe00a0, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb4_2_tmu_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_usb4_2_tmu_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb4_2_uc_hrr_clk = { + .halt_reg = 0xe006c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xe006c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb4_2_uc_hrr_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_usb4_2_phy_sys_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_video_axi0_clk = { + .halt_reg = 0x3201c, + .halt_check = BRANCH_HALT_SKIP, + .hwcg_reg = 0x3201c, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x3201c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_video_axi0_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_video_axi0c_clk = { + .halt_reg = 0x32030, + .halt_check = BRANCH_HALT_SKIP, + .hwcg_reg = 0x32030, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x32030, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_video_axi0c_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_video_axi1_clk = { + .halt_reg = 0x32044, + .halt_check = BRANCH_HALT_SKIP, + .hwcg_reg = 0x32044, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x32044, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_video_axi1_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct gdsc gcc_pcie_0_tunnel_gdsc = { + .gdscr = 0xc8004, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0xf, + .pd = { + .name = "gcc_pcie_0_tunnel_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, + .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE | VOTABLE, +}; + +static struct gdsc gcc_pcie_1_tunnel_gdsc = { + .gdscr = 0x2e004, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0xf, + .pd = { + .name = "gcc_pcie_1_tunnel_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, + .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE | VOTABLE, +}; + +static struct gdsc gcc_pcie_2_tunnel_gdsc = { + .gdscr = 0xc0004, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0xf, + .pd = { + .name = "gcc_pcie_2_tunnel_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, + .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE | VOTABLE, +}; + +static struct gdsc gcc_pcie_3a_gdsc = { + .gdscr = 0xdc004, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0xf, + .pd = { + .name = "gcc_pcie_3a_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, + .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE | VOTABLE, +}; + +static struct gdsc gcc_pcie_3a_phy_gdsc = { + .gdscr = 0x6c004, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0x2, + .pd = { + .name = "gcc_pcie_3a_phy_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, + .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE | VOTABLE, +}; + +static struct gdsc gcc_pcie_3b_gdsc = { + .gdscr = 0x94004, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0xf, + .pd = { + .name = "gcc_pcie_3b_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, + .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE | VOTABLE, +}; + +static struct gdsc gcc_pcie_3b_phy_gdsc = { + .gdscr = 0x75004, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0x2, + .pd = { + .name = "gcc_pcie_3b_phy_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, + .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE | VOTABLE, +}; + +static struct gdsc gcc_pcie_4_gdsc = { + .gdscr = 0x88004, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0xf, + .pd = { + .name = "gcc_pcie_4_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, + .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE | VOTABLE, +}; + +static struct gdsc gcc_pcie_4_phy_gdsc = { + .gdscr = 0xd3004, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0x2, + .pd = { + .name = "gcc_pcie_4_phy_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, + .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE | VOTABLE, +}; + +static struct gdsc gcc_pcie_5_gdsc = { + .gdscr = 0xc3004, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0xf, + .pd = { + .name = "gcc_pcie_5_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, + .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE | VOTABLE, +}; + +static struct gdsc gcc_pcie_5_phy_gdsc = { + .gdscr = 0xd2004, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0x2, + .pd = { + .name = "gcc_pcie_5_phy_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, + .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE | VOTABLE, +}; + +static struct gdsc gcc_pcie_6_gdsc = { + .gdscr = 0x8a004, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0xf, + .pd = { + .name = "gcc_pcie_6_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, + .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE | VOTABLE, +}; + +static struct gdsc gcc_pcie_6_phy_gdsc = { + .gdscr = 0xd4004, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0x2, + .pd = { + .name = "gcc_pcie_6_phy_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, + .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE | VOTABLE, +}; + +static struct gdsc gcc_ufs_phy_gdsc = { + .gdscr = 0x77008, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0xf, + .pd = { + .name = "gcc_ufs_phy_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, + .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE, +}; + +static struct gdsc gcc_usb20_prim_gdsc = { + .gdscr = 0xbc004, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0xf, + .pd = { + .name = "gcc_usb20_prim_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, + .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE, +}; + +static struct gdsc gcc_usb30_mp_gdsc = { + .gdscr = 0x9a010, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0xf, + .pd = { + .name = "gcc_usb30_mp_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, + .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE, +}; + +static struct gdsc gcc_usb30_prim_gdsc = { + .gdscr = 0x3f01c, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0xf, + .pd = { + .name = "gcc_usb30_prim_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, + .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE, +}; + +static struct gdsc gcc_usb30_sec_gdsc = { + .gdscr = 0xe2010, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0xf, + .pd = { + .name = "gcc_usb30_sec_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, + .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE, +}; + +static struct gdsc gcc_usb30_tert_gdsc = { + .gdscr = 0xe1010, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0xf, + .pd = { + .name = "gcc_usb30_tert_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, + .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE, +}; + +static struct gdsc gcc_usb3_mp_ss0_phy_gdsc = { + .gdscr = 0x5400c, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0x2, + .pd = { + .name = "gcc_usb3_mp_ss0_phy_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, + .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE, +}; + +static struct gdsc gcc_usb3_mp_ss1_phy_gdsc = { + .gdscr = 0x5402c, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0x2, + .pd = { + .name = "gcc_usb3_mp_ss1_phy_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, + .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE, +}; + +static struct gdsc gcc_usb4_0_gdsc = { + .gdscr = 0x2b008, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0xf, + .pd = { + .name = "gcc_usb4_0_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, + .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE, +}; + +static struct gdsc gcc_usb4_1_gdsc = { + .gdscr = 0x2d008, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0xf, + .pd = { + .name = "gcc_usb4_1_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, + .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE, +}; + +static struct gdsc gcc_usb4_2_gdsc = { + .gdscr = 0xe0008, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0xf, + .pd = { + .name = "gcc_usb4_2_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, + .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE, +}; + +static struct gdsc gcc_usb_0_phy_gdsc = { + .gdscr = 0xdb024, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0x2, + .pd = { + .name = "gcc_usb_0_phy_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, + .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE, +}; + +static struct gdsc gcc_usb_1_phy_gdsc = { + .gdscr = 0x2c024, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0x2, + .pd = { + .name = "gcc_usb_1_phy_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, + .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE, +}; + +static struct gdsc gcc_usb_2_phy_gdsc = { + .gdscr = 0xbe024, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0x2, + .pd = { + .name = "gcc_usb_2_phy_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, + .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE, +}; + +static struct clk_regmap *gcc_glymur_clocks[] = { + [GCC_AGGRE_NOC_PCIE_3A_WEST_SF_AXI_CLK] = &gcc_aggre_noc_pcie_3a_west_sf_axi_clk.clkr, + [GCC_AGGRE_NOC_PCIE_3B_WEST_SF_AXI_CLK] = &gcc_aggre_noc_pcie_3b_west_sf_axi_clk.clkr, + [GCC_AGGRE_NOC_PCIE_4_WEST_SF_AXI_CLK] = &gcc_aggre_noc_pcie_4_west_sf_axi_clk.clkr, + [GCC_AGGRE_NOC_PCIE_5_EAST_SF_AXI_CLK] = &gcc_aggre_noc_pcie_5_east_sf_axi_clk.clkr, + [GCC_AGGRE_NOC_PCIE_6_WEST_SF_AXI_CLK] = &gcc_aggre_noc_pcie_6_west_sf_axi_clk.clkr, + [GCC_AGGRE_UFS_PHY_AXI_CLK] = &gcc_aggre_ufs_phy_axi_clk.clkr, + [GCC_AGGRE_USB2_PRIM_AXI_CLK] = &gcc_aggre_usb2_prim_axi_clk.clkr, + [GCC_AGGRE_USB3_MP_AXI_CLK] = &gcc_aggre_usb3_mp_axi_clk.clkr, + [GCC_AGGRE_USB3_PRIM_AXI_CLK] = &gcc_aggre_usb3_prim_axi_clk.clkr, + [GCC_AGGRE_USB3_SEC_AXI_CLK] = &gcc_aggre_usb3_sec_axi_clk.clkr, + [GCC_AGGRE_USB3_TERT_AXI_CLK] = &gcc_aggre_usb3_tert_axi_clk.clkr, + [GCC_AGGRE_USB4_0_AXI_CLK] = &gcc_aggre_usb4_0_axi_clk.clkr, + [GCC_AGGRE_USB4_1_AXI_CLK] = &gcc_aggre_usb4_1_axi_clk.clkr, + [GCC_AGGRE_USB4_2_AXI_CLK] = &gcc_aggre_usb4_2_axi_clk.clkr, + [GCC_AV1E_AHB_CLK] = &gcc_av1e_ahb_clk.clkr, + [GCC_AV1E_AXI_CLK] = &gcc_av1e_axi_clk.clkr, + [GCC_AV1E_XO_CLK] = &gcc_av1e_xo_clk.clkr, + [GCC_BOOT_ROM_AHB_CLK] = &gcc_boot_rom_ahb_clk.clkr, + [GCC_CAMERA_HF_AXI_CLK] = &gcc_camera_hf_axi_clk.clkr, + [GCC_CAMERA_SF_AXI_CLK] = &gcc_camera_sf_axi_clk.clkr, + [GCC_CFG_NOC_PCIE_ANOC_AHB_CLK] = &gcc_cfg_noc_pcie_anoc_ahb_clk.clkr, + [GCC_CFG_NOC_PCIE_ANOC_SOUTH_AHB_CLK] = &gcc_cfg_noc_pcie_anoc_south_ahb_clk.clkr, + [GCC_CFG_NOC_USB2_PRIM_AXI_CLK] = &gcc_cfg_noc_usb2_prim_axi_clk.clkr, + [GCC_CFG_NOC_USB3_MP_AXI_CLK] = &gcc_cfg_noc_usb3_mp_axi_clk.clkr, + [GCC_CFG_NOC_USB3_PRIM_AXI_CLK] = &gcc_cfg_noc_usb3_prim_axi_clk.clkr, + [GCC_CFG_NOC_USB3_SEC_AXI_CLK] = &gcc_cfg_noc_usb3_sec_axi_clk.clkr, + [GCC_CFG_NOC_USB3_TERT_AXI_CLK] = &gcc_cfg_noc_usb3_tert_axi_clk.clkr, + [GCC_CFG_NOC_USB_ANOC_AHB_CLK] = &gcc_cfg_noc_usb_anoc_ahb_clk.clkr, + [GCC_CFG_NOC_USB_ANOC_SOUTH_AHB_CLK] = &gcc_cfg_noc_usb_anoc_south_ahb_clk.clkr, + [GCC_DISP_HF_AXI_CLK] = &gcc_disp_hf_axi_clk.clkr, + [GCC_EVA_AHB_CLK] = &gcc_eva_ahb_clk.clkr, + [GCC_EVA_AXI0_CLK] = &gcc_eva_axi0_clk.clkr, + [GCC_EVA_AXI0C_CLK] = &gcc_eva_axi0c_clk.clkr, + [GCC_EVA_XO_CLK] = &gcc_eva_xo_clk.clkr, + [GCC_GP1_CLK] = &gcc_gp1_clk.clkr, + [GCC_GP1_CLK_SRC] = &gcc_gp1_clk_src.clkr, + [GCC_GP2_CLK] = &gcc_gp2_clk.clkr, + [GCC_GP2_CLK_SRC] = &gcc_gp2_clk_src.clkr, + [GCC_GP3_CLK] = &gcc_gp3_clk.clkr, + [GCC_GP3_CLK_SRC] = &gcc_gp3_clk_src.clkr, + [GCC_GPLL0] = &gcc_gpll0.clkr, + [GCC_GPLL0_OUT_EVEN] = &gcc_gpll0_out_even.clkr, + [GCC_GPLL1] = &gcc_gpll1.clkr, + [GCC_GPLL14] = &gcc_gpll14.clkr, + [GCC_GPLL14_OUT_EVEN] = &gcc_gpll14_out_even.clkr, + [GCC_GPLL4] = &gcc_gpll4.clkr, + [GCC_GPLL5] = &gcc_gpll5.clkr, + [GCC_GPLL7] = &gcc_gpll7.clkr, + [GCC_GPLL8] = &gcc_gpll8.clkr, + [GCC_GPLL9] = &gcc_gpll9.clkr, + [GCC_GPU_GEMNOC_GFX_CLK] = &gcc_gpu_gemnoc_gfx_clk.clkr, + [GCC_GPU_GPLL0_CLK_SRC] = &gcc_gpu_gpll0_clk_src.clkr, + [GCC_GPU_GPLL0_DIV_CLK_SRC] = &gcc_gpu_gpll0_div_clk_src.clkr, + [GCC_PCIE_0_AUX_CLK] = &gcc_pcie_0_aux_clk.clkr, + [GCC_PCIE_0_AUX_CLK_SRC] = &gcc_pcie_0_aux_clk_src.clkr, + [GCC_PCIE_0_CFG_AHB_CLK] = &gcc_pcie_0_cfg_ahb_clk.clkr, + [GCC_PCIE_0_MSTR_AXI_CLK] = &gcc_pcie_0_mstr_axi_clk.clkr, + [GCC_PCIE_0_PHY_RCHNG_CLK] = &gcc_pcie_0_phy_rchng_clk.clkr, + [GCC_PCIE_0_PHY_RCHNG_CLK_SRC] = &gcc_pcie_0_phy_rchng_clk_src.clkr, + [GCC_PCIE_0_PIPE_CLK] = &gcc_pcie_0_pipe_clk.clkr, + [GCC_PCIE_0_SLV_AXI_CLK] = &gcc_pcie_0_slv_axi_clk.clkr, + [GCC_PCIE_0_SLV_Q2A_AXI_CLK] = &gcc_pcie_0_slv_q2a_axi_clk.clkr, + [GCC_PCIE_1_AUX_CLK] = &gcc_pcie_1_aux_clk.clkr, + [GCC_PCIE_1_AUX_CLK_SRC] = &gcc_pcie_1_aux_clk_src.clkr, + [GCC_PCIE_1_CFG_AHB_CLK] = &gcc_pcie_1_cfg_ahb_clk.clkr, + [GCC_PCIE_1_MSTR_AXI_CLK] = &gcc_pcie_1_mstr_axi_clk.clkr, + [GCC_PCIE_1_PHY_RCHNG_CLK] = &gcc_pcie_1_phy_rchng_clk.clkr, + [GCC_PCIE_1_PHY_RCHNG_CLK_SRC] = &gcc_pcie_1_phy_rchng_clk_src.clkr, + [GCC_PCIE_1_PIPE_CLK] = &gcc_pcie_1_pipe_clk.clkr, + [GCC_PCIE_1_SLV_AXI_CLK] = &gcc_pcie_1_slv_axi_clk.clkr, + [GCC_PCIE_1_SLV_Q2A_AXI_CLK] = &gcc_pcie_1_slv_q2a_axi_clk.clkr, + [GCC_PCIE_2_AUX_CLK] = &gcc_pcie_2_aux_clk.clkr, + [GCC_PCIE_2_AUX_CLK_SRC] = &gcc_pcie_2_aux_clk_src.clkr, + [GCC_PCIE_2_CFG_AHB_CLK] = &gcc_pcie_2_cfg_ahb_clk.clkr, + [GCC_PCIE_2_MSTR_AXI_CLK] = &gcc_pcie_2_mstr_axi_clk.clkr, + [GCC_PCIE_2_PHY_RCHNG_CLK] = &gcc_pcie_2_phy_rchng_clk.clkr, + [GCC_PCIE_2_PHY_RCHNG_CLK_SRC] = &gcc_pcie_2_phy_rchng_clk_src.clkr, + [GCC_PCIE_2_PIPE_CLK] = &gcc_pcie_2_pipe_clk.clkr, + [GCC_PCIE_2_SLV_AXI_CLK] = &gcc_pcie_2_slv_axi_clk.clkr, + [GCC_PCIE_2_SLV_Q2A_AXI_CLK] = &gcc_pcie_2_slv_q2a_axi_clk.clkr, + [GCC_PCIE_3A_AUX_CLK] = &gcc_pcie_3a_aux_clk.clkr, + [GCC_PCIE_3A_AUX_CLK_SRC] = &gcc_pcie_3a_aux_clk_src.clkr, + [GCC_PCIE_3A_CFG_AHB_CLK] = &gcc_pcie_3a_cfg_ahb_clk.clkr, + [GCC_PCIE_3A_MSTR_AXI_CLK] = &gcc_pcie_3a_mstr_axi_clk.clkr, + [GCC_PCIE_3A_PHY_RCHNG_CLK] = &gcc_pcie_3a_phy_rchng_clk.clkr, + [GCC_PCIE_3A_PHY_RCHNG_CLK_SRC] = &gcc_pcie_3a_phy_rchng_clk_src.clkr, + [GCC_PCIE_3A_PIPE_CLK] = &gcc_pcie_3a_pipe_clk.clkr, + [GCC_PCIE_3A_PIPE_CLK_SRC] = &gcc_pcie_3a_pipe_clk_src.clkr, + [GCC_PCIE_3A_SLV_AXI_CLK] = &gcc_pcie_3a_slv_axi_clk.clkr, + [GCC_PCIE_3A_SLV_Q2A_AXI_CLK] = &gcc_pcie_3a_slv_q2a_axi_clk.clkr, + [GCC_PCIE_3B_AUX_CLK] = &gcc_pcie_3b_aux_clk.clkr, + [GCC_PCIE_3B_AUX_CLK_SRC] = &gcc_pcie_3b_aux_clk_src.clkr, + [GCC_PCIE_3B_CFG_AHB_CLK] = &gcc_pcie_3b_cfg_ahb_clk.clkr, + [GCC_PCIE_3B_MSTR_AXI_CLK] = &gcc_pcie_3b_mstr_axi_clk.clkr, + [GCC_PCIE_3B_PHY_RCHNG_CLK] = &gcc_pcie_3b_phy_rchng_clk.clkr, + [GCC_PCIE_3B_PHY_RCHNG_CLK_SRC] = &gcc_pcie_3b_phy_rchng_clk_src.clkr, + [GCC_PCIE_3B_PIPE_CLK] = &gcc_pcie_3b_pipe_clk.clkr, + [GCC_PCIE_3B_PIPE_CLK_SRC] = &gcc_pcie_3b_pipe_clk_src.clkr, + [GCC_PCIE_3B_PIPE_DIV2_CLK] = &gcc_pcie_3b_pipe_div2_clk.clkr, + [GCC_PCIE_3B_PIPE_DIV_CLK_SRC] = &gcc_pcie_3b_pipe_div_clk_src.clkr, + [GCC_PCIE_3B_SLV_AXI_CLK] = &gcc_pcie_3b_slv_axi_clk.clkr, + [GCC_PCIE_3B_SLV_Q2A_AXI_CLK] = &gcc_pcie_3b_slv_q2a_axi_clk.clkr, + [GCC_PCIE_4_AUX_CLK] = &gcc_pcie_4_aux_clk.clkr, + [GCC_PCIE_4_AUX_CLK_SRC] = &gcc_pcie_4_aux_clk_src.clkr, + [GCC_PCIE_4_CFG_AHB_CLK] = &gcc_pcie_4_cfg_ahb_clk.clkr, + [GCC_PCIE_4_MSTR_AXI_CLK] = &gcc_pcie_4_mstr_axi_clk.clkr, + [GCC_PCIE_4_PHY_RCHNG_CLK] = &gcc_pcie_4_phy_rchng_clk.clkr, + [GCC_PCIE_4_PHY_RCHNG_CLK_SRC] = &gcc_pcie_4_phy_rchng_clk_src.clkr, + [GCC_PCIE_4_PIPE_CLK] = &gcc_pcie_4_pipe_clk.clkr, + [GCC_PCIE_4_PIPE_CLK_SRC] = &gcc_pcie_4_pipe_clk_src.clkr, + [GCC_PCIE_4_PIPE_DIV2_CLK] = &gcc_pcie_4_pipe_div2_clk.clkr, + [GCC_PCIE_4_PIPE_DIV_CLK_SRC] = &gcc_pcie_4_pipe_div_clk_src.clkr, + [GCC_PCIE_4_SLV_AXI_CLK] = &gcc_pcie_4_slv_axi_clk.clkr, + [GCC_PCIE_4_SLV_Q2A_AXI_CLK] = &gcc_pcie_4_slv_q2a_axi_clk.clkr, + [GCC_PCIE_5_AUX_CLK] = &gcc_pcie_5_aux_clk.clkr, + [GCC_PCIE_5_AUX_CLK_SRC] = &gcc_pcie_5_aux_clk_src.clkr, + [GCC_PCIE_5_CFG_AHB_CLK] = &gcc_pcie_5_cfg_ahb_clk.clkr, + [GCC_PCIE_5_MSTR_AXI_CLK] = &gcc_pcie_5_mstr_axi_clk.clkr, + [GCC_PCIE_5_PHY_RCHNG_CLK] = &gcc_pcie_5_phy_rchng_clk.clkr, + [GCC_PCIE_5_PHY_RCHNG_CLK_SRC] = &gcc_pcie_5_phy_rchng_clk_src.clkr, + [GCC_PCIE_5_PIPE_CLK] = &gcc_pcie_5_pipe_clk.clkr, + [GCC_PCIE_5_PIPE_CLK_SRC] = &gcc_pcie_5_pipe_clk_src.clkr, + [GCC_PCIE_5_PIPE_DIV2_CLK] = &gcc_pcie_5_pipe_div2_clk.clkr, + [GCC_PCIE_5_PIPE_DIV_CLK_SRC] = &gcc_pcie_5_pipe_div_clk_src.clkr, + [GCC_PCIE_5_SLV_AXI_CLK] = &gcc_pcie_5_slv_axi_clk.clkr, + [GCC_PCIE_5_SLV_Q2A_AXI_CLK] = &gcc_pcie_5_slv_q2a_axi_clk.clkr, + [GCC_PCIE_6_AUX_CLK] = &gcc_pcie_6_aux_clk.clkr, + [GCC_PCIE_6_AUX_CLK_SRC] = &gcc_pcie_6_aux_clk_src.clkr, + [GCC_PCIE_6_CFG_AHB_CLK] = &gcc_pcie_6_cfg_ahb_clk.clkr, + [GCC_PCIE_6_MSTR_AXI_CLK] = &gcc_pcie_6_mstr_axi_clk.clkr, + [GCC_PCIE_6_PHY_RCHNG_CLK] = &gcc_pcie_6_phy_rchng_clk.clkr, + [GCC_PCIE_6_PHY_RCHNG_CLK_SRC] = &gcc_pcie_6_phy_rchng_clk_src.clkr, + [GCC_PCIE_6_PIPE_CLK] = &gcc_pcie_6_pipe_clk.clkr, + [GCC_PCIE_6_PIPE_CLK_SRC] = &gcc_pcie_6_pipe_clk_src.clkr, + [GCC_PCIE_6_PIPE_DIV2_CLK] = &gcc_pcie_6_pipe_div2_clk.clkr, + [GCC_PCIE_6_PIPE_DIV_CLK_SRC] = &gcc_pcie_6_pipe_div_clk_src.clkr, + [GCC_PCIE_6_SLV_AXI_CLK] = &gcc_pcie_6_slv_axi_clk.clkr, + [GCC_PCIE_6_SLV_Q2A_AXI_CLK] = &gcc_pcie_6_slv_q2a_axi_clk.clkr, + [GCC_PCIE_NOC_PWRCTL_CLK] = &gcc_pcie_noc_pwrctl_clk.clkr, + [GCC_PCIE_NOC_QOSGEN_EXTREF_CLK] = &gcc_pcie_noc_qosgen_extref_clk.clkr, + [GCC_PCIE_NOC_SF_CENTER_CLK] = &gcc_pcie_noc_sf_center_clk.clkr, + [GCC_PCIE_NOC_SLAVE_SF_EAST_CLK] = &gcc_pcie_noc_slave_sf_east_clk.clkr, + [GCC_PCIE_NOC_SLAVE_SF_WEST_CLK] = &gcc_pcie_noc_slave_sf_west_clk.clkr, + [GCC_PCIE_NOC_TSCTR_CLK] = &gcc_pcie_noc_tsctr_clk.clkr, + [GCC_PCIE_PHY_3A_AUX_CLK] = &gcc_pcie_phy_3a_aux_clk.clkr, + [GCC_PCIE_PHY_3A_AUX_CLK_SRC] = &gcc_pcie_phy_3a_aux_clk_src.clkr, + [GCC_PCIE_PHY_3B_AUX_CLK] = &gcc_pcie_phy_3b_aux_clk.clkr, + [GCC_PCIE_PHY_3B_AUX_CLK_SRC] = &gcc_pcie_phy_3b_aux_clk_src.clkr, + [GCC_PCIE_PHY_4_AUX_CLK] = &gcc_pcie_phy_4_aux_clk.clkr, + [GCC_PCIE_PHY_4_AUX_CLK_SRC] = &gcc_pcie_phy_4_aux_clk_src.clkr, + [GCC_PCIE_PHY_5_AUX_CLK] = &gcc_pcie_phy_5_aux_clk.clkr, + [GCC_PCIE_PHY_5_AUX_CLK_SRC] = &gcc_pcie_phy_5_aux_clk_src.clkr, + [GCC_PCIE_PHY_6_AUX_CLK] = &gcc_pcie_phy_6_aux_clk.clkr, + [GCC_PCIE_PHY_6_AUX_CLK_SRC] = &gcc_pcie_phy_6_aux_clk_src.clkr, + [GCC_PCIE_RSCC_CFG_AHB_CLK] = &gcc_pcie_rscc_cfg_ahb_clk.clkr, + [GCC_PCIE_RSCC_XO_CLK] = &gcc_pcie_rscc_xo_clk.clkr, + [GCC_PDM2_CLK] = &gcc_pdm2_clk.clkr, + [GCC_PDM2_CLK_SRC] = &gcc_pdm2_clk_src.clkr, + [GCC_PDM_AHB_CLK] = &gcc_pdm_ahb_clk.clkr, + [GCC_PDM_XO4_CLK] = &gcc_pdm_xo4_clk.clkr, + [GCC_QMIP_AV1E_AHB_CLK] = &gcc_qmip_av1e_ahb_clk.clkr, + [GCC_QMIP_CAMERA_CMD_AHB_CLK] = &gcc_qmip_camera_cmd_ahb_clk.clkr, + [GCC_QMIP_CAMERA_NRT_AHB_CLK] = &gcc_qmip_camera_nrt_ahb_clk.clkr, + [GCC_QMIP_CAMERA_RT_AHB_CLK] = &gcc_qmip_camera_rt_ahb_clk.clkr, + [GCC_QMIP_GPU_AHB_CLK] = &gcc_qmip_gpu_ahb_clk.clkr, + [GCC_QMIP_PCIE_3A_AHB_CLK] = &gcc_qmip_pcie_3a_ahb_clk.clkr, + [GCC_QMIP_PCIE_3B_AHB_CLK] = &gcc_qmip_pcie_3b_ahb_clk.clkr, + [GCC_QMIP_PCIE_4_AHB_CLK] = &gcc_qmip_pcie_4_ahb_clk.clkr, + [GCC_QMIP_PCIE_5_AHB_CLK] = &gcc_qmip_pcie_5_ahb_clk.clkr, + [GCC_QMIP_PCIE_6_AHB_CLK] = &gcc_qmip_pcie_6_ahb_clk.clkr, + [GCC_QMIP_VIDEO_CV_CPU_AHB_CLK] = &gcc_qmip_video_cv_cpu_ahb_clk.clkr, + [GCC_QMIP_VIDEO_CVP_AHB_CLK] = &gcc_qmip_video_cvp_ahb_clk.clkr, + [GCC_QMIP_VIDEO_V_CPU_AHB_CLK] = &gcc_qmip_video_v_cpu_ahb_clk.clkr, + [GCC_QMIP_VIDEO_VCODEC1_AHB_CLK] = &gcc_qmip_video_vcodec1_ahb_clk.clkr, + [GCC_QMIP_VIDEO_VCODEC_AHB_CLK] = &gcc_qmip_video_vcodec_ahb_clk.clkr, + [GCC_QUPV3_OOB_CORE_2X_CLK] = &gcc_qupv3_oob_core_2x_clk.clkr, + [GCC_QUPV3_OOB_CORE_CLK] = &gcc_qupv3_oob_core_clk.clkr, + [GCC_QUPV3_OOB_M_AHB_CLK] = &gcc_qupv3_oob_m_ahb_clk.clkr, + [GCC_QUPV3_OOB_QSPI_S0_CLK] = &gcc_qupv3_oob_qspi_s0_clk.clkr, + [GCC_QUPV3_OOB_QSPI_S0_CLK_SRC] = &gcc_qupv3_oob_qspi_s0_clk_src.clkr, + [GCC_QUPV3_OOB_QSPI_S1_CLK] = &gcc_qupv3_oob_qspi_s1_clk.clkr, + [GCC_QUPV3_OOB_QSPI_S1_CLK_SRC] = &gcc_qupv3_oob_qspi_s1_clk_src.clkr, + [GCC_QUPV3_OOB_S0_CLK] = &gcc_qupv3_oob_s0_clk.clkr, + [GCC_QUPV3_OOB_S0_CLK_SRC] = &gcc_qupv3_oob_s0_clk_src.clkr, + [GCC_QUPV3_OOB_S1_CLK] = &gcc_qupv3_oob_s1_clk.clkr, + [GCC_QUPV3_OOB_S1_CLK_SRC] = &gcc_qupv3_oob_s1_clk_src.clkr, + [GCC_QUPV3_OOB_S_AHB_CLK] = &gcc_qupv3_oob_s_ahb_clk.clkr, + [GCC_QUPV3_OOB_TCXO_CLK] = &gcc_qupv3_oob_tcxo_clk.clkr, + [GCC_QUPV3_WRAP0_CORE_2X_CLK] = &gcc_qupv3_wrap0_core_2x_clk.clkr, + [GCC_QUPV3_WRAP0_CORE_CLK] = &gcc_qupv3_wrap0_core_clk.clkr, + [GCC_QUPV3_WRAP0_QSPI_S2_CLK] = &gcc_qupv3_wrap0_qspi_s2_clk.clkr, + [GCC_QUPV3_WRAP0_QSPI_S2_CLK_SRC] = &gcc_qupv3_wrap0_qspi_s2_clk_src.clkr, + [GCC_QUPV3_WRAP0_QSPI_S3_CLK] = &gcc_qupv3_wrap0_qspi_s3_clk.clkr, + [GCC_QUPV3_WRAP0_QSPI_S3_CLK_SRC] = &gcc_qupv3_wrap0_qspi_s3_clk_src.clkr, + [GCC_QUPV3_WRAP0_QSPI_S6_CLK] = &gcc_qupv3_wrap0_qspi_s6_clk.clkr, + [GCC_QUPV3_WRAP0_QSPI_S6_CLK_SRC] = &gcc_qupv3_wrap0_qspi_s6_clk_src.clkr, + [GCC_QUPV3_WRAP0_S0_CLK] = &gcc_qupv3_wrap0_s0_clk.clkr, + [GCC_QUPV3_WRAP0_S0_CLK_SRC] = &gcc_qupv3_wrap0_s0_clk_src.clkr, + [GCC_QUPV3_WRAP0_S1_CLK] = &gcc_qupv3_wrap0_s1_clk.clkr, + [GCC_QUPV3_WRAP0_S1_CLK_SRC] = &gcc_qupv3_wrap0_s1_clk_src.clkr, + [GCC_QUPV3_WRAP0_S2_CLK] = &gcc_qupv3_wrap0_s2_clk.clkr, + [GCC_QUPV3_WRAP0_S2_CLK_SRC] = &gcc_qupv3_wrap0_s2_clk_src.clkr, + [GCC_QUPV3_WRAP0_S3_CLK] = &gcc_qupv3_wrap0_s3_clk.clkr, + [GCC_QUPV3_WRAP0_S3_CLK_SRC] = &gcc_qupv3_wrap0_s3_clk_src.clkr, + [GCC_QUPV3_WRAP0_S4_CLK] = &gcc_qupv3_wrap0_s4_clk.clkr, + [GCC_QUPV3_WRAP0_S4_CLK_SRC] = &gcc_qupv3_wrap0_s4_clk_src.clkr, + [GCC_QUPV3_WRAP0_S5_CLK] = &gcc_qupv3_wrap0_s5_clk.clkr, + [GCC_QUPV3_WRAP0_S5_CLK_SRC] = &gcc_qupv3_wrap0_s5_clk_src.clkr, + [GCC_QUPV3_WRAP0_S6_CLK] = &gcc_qupv3_wrap0_s6_clk.clkr, + [GCC_QUPV3_WRAP0_S6_CLK_SRC] = &gcc_qupv3_wrap0_s6_clk_src.clkr, + [GCC_QUPV3_WRAP0_S7_CLK] = &gcc_qupv3_wrap0_s7_clk.clkr, + [GCC_QUPV3_WRAP0_S7_CLK_SRC] = &gcc_qupv3_wrap0_s7_clk_src.clkr, + [GCC_QUPV3_WRAP1_CORE_2X_CLK] = &gcc_qupv3_wrap1_core_2x_clk.clkr, + [GCC_QUPV3_WRAP1_CORE_CLK] = &gcc_qupv3_wrap1_core_clk.clkr, + [GCC_QUPV3_WRAP1_QSPI_S2_CLK] = &gcc_qupv3_wrap1_qspi_s2_clk.clkr, + [GCC_QUPV3_WRAP1_QSPI_S2_CLK_SRC] = &gcc_qupv3_wrap1_qspi_s2_clk_src.clkr, + [GCC_QUPV3_WRAP1_QSPI_S3_CLK] = &gcc_qupv3_wrap1_qspi_s3_clk.clkr, + [GCC_QUPV3_WRAP1_QSPI_S3_CLK_SRC] = &gcc_qupv3_wrap1_qspi_s3_clk_src.clkr, + [GCC_QUPV3_WRAP1_QSPI_S6_CLK] = &gcc_qupv3_wrap1_qspi_s6_clk.clkr, + [GCC_QUPV3_WRAP1_QSPI_S6_CLK_SRC] = &gcc_qupv3_wrap1_qspi_s6_clk_src.clkr, + [GCC_QUPV3_WRAP1_S0_CLK] = &gcc_qupv3_wrap1_s0_clk.clkr, + [GCC_QUPV3_WRAP1_S0_CLK_SRC] = &gcc_qupv3_wrap1_s0_clk_src.clkr, + [GCC_QUPV3_WRAP1_S1_CLK] = &gcc_qupv3_wrap1_s1_clk.clkr, + [GCC_QUPV3_WRAP1_S1_CLK_SRC] = &gcc_qupv3_wrap1_s1_clk_src.clkr, + [GCC_QUPV3_WRAP1_S2_CLK] = &gcc_qupv3_wrap1_s2_clk.clkr, + [GCC_QUPV3_WRAP1_S2_CLK_SRC] = &gcc_qupv3_wrap1_s2_clk_src.clkr, + [GCC_QUPV3_WRAP1_S3_CLK] = &gcc_qupv3_wrap1_s3_clk.clkr, + [GCC_QUPV3_WRAP1_S3_CLK_SRC] = &gcc_qupv3_wrap1_s3_clk_src.clkr, + [GCC_QUPV3_WRAP1_S4_CLK] = &gcc_qupv3_wrap1_s4_clk.clkr, + [GCC_QUPV3_WRAP1_S4_CLK_SRC] = &gcc_qupv3_wrap1_s4_clk_src.clkr, + [GCC_QUPV3_WRAP1_S5_CLK] = &gcc_qupv3_wrap1_s5_clk.clkr, + [GCC_QUPV3_WRAP1_S5_CLK_SRC] = &gcc_qupv3_wrap1_s5_clk_src.clkr, + [GCC_QUPV3_WRAP1_S6_CLK] = &gcc_qupv3_wrap1_s6_clk.clkr, + [GCC_QUPV3_WRAP1_S6_CLK_SRC] = &gcc_qupv3_wrap1_s6_clk_src.clkr, + [GCC_QUPV3_WRAP1_S7_CLK] = &gcc_qupv3_wrap1_s7_clk.clkr, + [GCC_QUPV3_WRAP1_S7_CLK_SRC] = &gcc_qupv3_wrap1_s7_clk_src.clkr, + [GCC_QUPV3_WRAP2_CORE_2X_CLK] = &gcc_qupv3_wrap2_core_2x_clk.clkr, + [GCC_QUPV3_WRAP2_CORE_CLK] = &gcc_qupv3_wrap2_core_clk.clkr, + [GCC_QUPV3_WRAP2_QSPI_S2_CLK] = &gcc_qupv3_wrap2_qspi_s2_clk.clkr, + [GCC_QUPV3_WRAP2_QSPI_S2_CLK_SRC] = &gcc_qupv3_wrap2_qspi_s2_clk_src.clkr, + [GCC_QUPV3_WRAP2_QSPI_S3_CLK] = &gcc_qupv3_wrap2_qspi_s3_clk.clkr, + [GCC_QUPV3_WRAP2_QSPI_S3_CLK_SRC] = &gcc_qupv3_wrap2_qspi_s3_clk_src.clkr, + [GCC_QUPV3_WRAP2_QSPI_S6_CLK] = &gcc_qupv3_wrap2_qspi_s6_clk.clkr, + [GCC_QUPV3_WRAP2_QSPI_S6_CLK_SRC] = &gcc_qupv3_wrap2_qspi_s6_clk_src.clkr, + [GCC_QUPV3_WRAP2_S0_CLK] = &gcc_qupv3_wrap2_s0_clk.clkr, + [GCC_QUPV3_WRAP2_S0_CLK_SRC] = &gcc_qupv3_wrap2_s0_clk_src.clkr, + [GCC_QUPV3_WRAP2_S1_CLK] = &gcc_qupv3_wrap2_s1_clk.clkr, + [GCC_QUPV3_WRAP2_S1_CLK_SRC] = &gcc_qupv3_wrap2_s1_clk_src.clkr, + [GCC_QUPV3_WRAP2_S2_CLK] = &gcc_qupv3_wrap2_s2_clk.clkr, + [GCC_QUPV3_WRAP2_S2_CLK_SRC] = &gcc_qupv3_wrap2_s2_clk_src.clkr, + [GCC_QUPV3_WRAP2_S3_CLK] = &gcc_qupv3_wrap2_s3_clk.clkr, + [GCC_QUPV3_WRAP2_S3_CLK_SRC] = &gcc_qupv3_wrap2_s3_clk_src.clkr, + [GCC_QUPV3_WRAP2_S4_CLK] = &gcc_qupv3_wrap2_s4_clk.clkr, + [GCC_QUPV3_WRAP2_S4_CLK_SRC] = &gcc_qupv3_wrap2_s4_clk_src.clkr, + [GCC_QUPV3_WRAP2_S5_CLK] = &gcc_qupv3_wrap2_s5_clk.clkr, + [GCC_QUPV3_WRAP2_S5_CLK_SRC] = &gcc_qupv3_wrap2_s5_clk_src.clkr, + [GCC_QUPV3_WRAP2_S6_CLK] = &gcc_qupv3_wrap2_s6_clk.clkr, + [GCC_QUPV3_WRAP2_S6_CLK_SRC] = &gcc_qupv3_wrap2_s6_clk_src.clkr, + [GCC_QUPV3_WRAP2_S7_CLK] = &gcc_qupv3_wrap2_s7_clk.clkr, + [GCC_QUPV3_WRAP2_S7_CLK_SRC] = &gcc_qupv3_wrap2_s7_clk_src.clkr, + [GCC_QUPV3_WRAP_0_M_AHB_CLK] = &gcc_qupv3_wrap_0_m_ahb_clk.clkr, + [GCC_QUPV3_WRAP_0_S_AHB_CLK] = &gcc_qupv3_wrap_0_s_ahb_clk.clkr, + [GCC_QUPV3_WRAP_1_M_AHB_CLK] = &gcc_qupv3_wrap_1_m_ahb_clk.clkr, + [GCC_QUPV3_WRAP_1_S_AHB_CLK] = &gcc_qupv3_wrap_1_s_ahb_clk.clkr, + [GCC_QUPV3_WRAP_2_M_AHB_CLK] = &gcc_qupv3_wrap_2_m_ahb_clk.clkr, + [GCC_QUPV3_WRAP_2_S_AHB_CLK] = &gcc_qupv3_wrap_2_s_ahb_clk.clkr, + [GCC_SDCC2_AHB_CLK] = &gcc_sdcc2_ahb_clk.clkr, + [GCC_SDCC2_APPS_CLK] = &gcc_sdcc2_apps_clk.clkr, + [GCC_SDCC2_APPS_CLK_SRC] = &gcc_sdcc2_apps_clk_src.clkr, + [GCC_SDCC4_AHB_CLK] = &gcc_sdcc4_ahb_clk.clkr, + [GCC_SDCC4_APPS_CLK] = &gcc_sdcc4_apps_clk.clkr, + [GCC_SDCC4_APPS_CLK_SRC] = &gcc_sdcc4_apps_clk_src.clkr, + [GCC_UFS_PHY_AHB_CLK] = &gcc_ufs_phy_ahb_clk.clkr, + [GCC_UFS_PHY_AXI_CLK] = &gcc_ufs_phy_axi_clk.clkr, + [GCC_UFS_PHY_AXI_CLK_SRC] = &gcc_ufs_phy_axi_clk_src.clkr, + [GCC_UFS_PHY_ICE_CORE_CLK] = &gcc_ufs_phy_ice_core_clk.clkr, + [GCC_UFS_PHY_ICE_CORE_CLK_SRC] = &gcc_ufs_phy_ice_core_clk_src.clkr, + [GCC_UFS_PHY_PHY_AUX_CLK] = &gcc_ufs_phy_phy_aux_clk.clkr, + [GCC_UFS_PHY_PHY_AUX_CLK_SRC] = &gcc_ufs_phy_phy_aux_clk_src.clkr, + [GCC_UFS_PHY_RX_SYMBOL_0_CLK] = &gcc_ufs_phy_rx_symbol_0_clk.clkr, + [GCC_UFS_PHY_RX_SYMBOL_0_CLK_SRC] = &gcc_ufs_phy_rx_symbol_0_clk_src.clkr, + [GCC_UFS_PHY_RX_SYMBOL_1_CLK] = &gcc_ufs_phy_rx_symbol_1_clk.clkr, + [GCC_UFS_PHY_RX_SYMBOL_1_CLK_SRC] = &gcc_ufs_phy_rx_symbol_1_clk_src.clkr, + [GCC_UFS_PHY_TX_SYMBOL_0_CLK] = &gcc_ufs_phy_tx_symbol_0_clk.clkr, + [GCC_UFS_PHY_TX_SYMBOL_0_CLK_SRC] = &gcc_ufs_phy_tx_symbol_0_clk_src.clkr, + [GCC_UFS_PHY_UNIPRO_CORE_CLK] = &gcc_ufs_phy_unipro_core_clk.clkr, + [GCC_UFS_PHY_UNIPRO_CORE_CLK_SRC] = &gcc_ufs_phy_unipro_core_clk_src.clkr, + [GCC_USB20_MASTER_CLK] = &gcc_usb20_master_clk.clkr, + [GCC_USB20_MASTER_CLK_SRC] = &gcc_usb20_master_clk_src.clkr, + [GCC_USB20_MOCK_UTMI_CLK] = &gcc_usb20_mock_utmi_clk.clkr, + [GCC_USB20_MOCK_UTMI_CLK_SRC] = &gcc_usb20_mock_utmi_clk_src.clkr, + [GCC_USB20_MOCK_UTMI_POSTDIV_CLK_SRC] = &gcc_usb20_mock_utmi_postdiv_clk_src.clkr, + [GCC_USB20_SLEEP_CLK] = &gcc_usb20_sleep_clk.clkr, + [GCC_USB30_MP_MASTER_CLK] = &gcc_usb30_mp_master_clk.clkr, + [GCC_USB30_MP_MASTER_CLK_SRC] = &gcc_usb30_mp_master_clk_src.clkr, + [GCC_USB30_MP_MOCK_UTMI_CLK] = &gcc_usb30_mp_mock_utmi_clk.clkr, + [GCC_USB30_MP_MOCK_UTMI_CLK_SRC] = &gcc_usb30_mp_mock_utmi_clk_src.clkr, + [GCC_USB30_MP_MOCK_UTMI_POSTDIV_CLK_SRC] = &gcc_usb30_mp_mock_utmi_postdiv_clk_src.clkr, + [GCC_USB30_MP_SLEEP_CLK] = &gcc_usb30_mp_sleep_clk.clkr, + [GCC_USB30_PRIM_MASTER_CLK] = &gcc_usb30_prim_master_clk.clkr, + [GCC_USB30_PRIM_MASTER_CLK_SRC] = &gcc_usb30_prim_master_clk_src.clkr, + [GCC_USB30_PRIM_MOCK_UTMI_CLK] = &gcc_usb30_prim_mock_utmi_clk.clkr, + [GCC_USB30_PRIM_MOCK_UTMI_CLK_SRC] = &gcc_usb30_prim_mock_utmi_clk_src.clkr, + [GCC_USB30_PRIM_MOCK_UTMI_POSTDIV_CLK_SRC] = &gcc_usb30_prim_mock_utmi_postdiv_clk_src.clkr, + [GCC_USB30_PRIM_SLEEP_CLK] = &gcc_usb30_prim_sleep_clk.clkr, + [GCC_USB30_SEC_MASTER_CLK] = &gcc_usb30_sec_master_clk.clkr, + [GCC_USB30_SEC_MASTER_CLK_SRC] = &gcc_usb30_sec_master_clk_src.clkr, + [GCC_USB30_SEC_MOCK_UTMI_CLK] = &gcc_usb30_sec_mock_utmi_clk.clkr, + [GCC_USB30_SEC_MOCK_UTMI_CLK_SRC] = &gcc_usb30_sec_mock_utmi_clk_src.clkr, + [GCC_USB30_SEC_MOCK_UTMI_POSTDIV_CLK_SRC] = &gcc_usb30_sec_mock_utmi_postdiv_clk_src.clkr, + [GCC_USB30_SEC_SLEEP_CLK] = &gcc_usb30_sec_sleep_clk.clkr, + [GCC_USB30_TERT_MASTER_CLK] = &gcc_usb30_tert_master_clk.clkr, + [GCC_USB30_TERT_MASTER_CLK_SRC] = &gcc_usb30_tert_master_clk_src.clkr, + [GCC_USB30_TERT_MOCK_UTMI_CLK] = &gcc_usb30_tert_mock_utmi_clk.clkr, + [GCC_USB30_TERT_MOCK_UTMI_CLK_SRC] = &gcc_usb30_tert_mock_utmi_clk_src.clkr, + [GCC_USB30_TERT_MOCK_UTMI_POSTDIV_CLK_SRC] = &gcc_usb30_tert_mock_utmi_postdiv_clk_src.clkr, + [GCC_USB30_TERT_SLEEP_CLK] = &gcc_usb30_tert_sleep_clk.clkr, + [GCC_USB34_PRIM_PHY_PIPE_CLK_SRC] = &gcc_usb34_prim_phy_pipe_clk_src.clkr, + [GCC_USB34_SEC_PHY_PIPE_CLK_SRC] = &gcc_usb34_sec_phy_pipe_clk_src.clkr, + [GCC_USB34_TERT_PHY_PIPE_CLK_SRC] = &gcc_usb34_tert_phy_pipe_clk_src.clkr, + [GCC_USB3_MP_PHY_AUX_CLK] = &gcc_usb3_mp_phy_aux_clk.clkr, + [GCC_USB3_MP_PHY_AUX_CLK_SRC] = &gcc_usb3_mp_phy_aux_clk_src.clkr, + [GCC_USB3_MP_PHY_COM_AUX_CLK] = &gcc_usb3_mp_phy_com_aux_clk.clkr, + [GCC_USB3_MP_PHY_PIPE_0_CLK] = &gcc_usb3_mp_phy_pipe_0_clk.clkr, + [GCC_USB3_MP_PHY_PIPE_0_CLK_SRC] = &gcc_usb3_mp_phy_pipe_0_clk_src.clkr, + [GCC_USB3_MP_PHY_PIPE_1_CLK] = &gcc_usb3_mp_phy_pipe_1_clk.clkr, + [GCC_USB3_MP_PHY_PIPE_1_CLK_SRC] = &gcc_usb3_mp_phy_pipe_1_clk_src.clkr, + [GCC_USB3_PRIM_PHY_AUX_CLK] = &gcc_usb3_prim_phy_aux_clk.clkr, + [GCC_USB3_PRIM_PHY_AUX_CLK_SRC] = &gcc_usb3_prim_phy_aux_clk_src.clkr, + [GCC_USB3_PRIM_PHY_COM_AUX_CLK] = &gcc_usb3_prim_phy_com_aux_clk.clkr, + [GCC_USB3_PRIM_PHY_PIPE_CLK] = &gcc_usb3_prim_phy_pipe_clk.clkr, + [GCC_USB3_PRIM_PHY_PIPE_CLK_SRC] = &gcc_usb3_prim_phy_pipe_clk_src.clkr, + [GCC_USB3_SEC_PHY_AUX_CLK] = &gcc_usb3_sec_phy_aux_clk.clkr, + [GCC_USB3_SEC_PHY_AUX_CLK_SRC] = &gcc_usb3_sec_phy_aux_clk_src.clkr, + [GCC_USB3_SEC_PHY_COM_AUX_CLK] = &gcc_usb3_sec_phy_com_aux_clk.clkr, + [GCC_USB3_SEC_PHY_PIPE_CLK] = &gcc_usb3_sec_phy_pipe_clk.clkr, + [GCC_USB3_SEC_PHY_PIPE_CLK_SRC] = &gcc_usb3_sec_phy_pipe_clk_src.clkr, + [GCC_USB3_TERT_PHY_AUX_CLK] = &gcc_usb3_tert_phy_aux_clk.clkr, + [GCC_USB3_TERT_PHY_AUX_CLK_SRC] = &gcc_usb3_tert_phy_aux_clk_src.clkr, + [GCC_USB3_TERT_PHY_COM_AUX_CLK] = &gcc_usb3_tert_phy_com_aux_clk.clkr, + [GCC_USB3_TERT_PHY_PIPE_CLK] = &gcc_usb3_tert_phy_pipe_clk.clkr, + [GCC_USB3_TERT_PHY_PIPE_CLK_SRC] = &gcc_usb3_tert_phy_pipe_clk_src.clkr, + [GCC_USB4_0_CFG_AHB_CLK] = &gcc_usb4_0_cfg_ahb_clk.clkr, + [GCC_USB4_0_DP0_CLK] = &gcc_usb4_0_dp0_clk.clkr, + [GCC_USB4_0_DP1_CLK] = &gcc_usb4_0_dp1_clk.clkr, + [GCC_USB4_0_MASTER_CLK] = &gcc_usb4_0_master_clk.clkr, + [GCC_USB4_0_MASTER_CLK_SRC] = &gcc_usb4_0_master_clk_src.clkr, + [GCC_USB4_0_PHY_DP0_CLK_SRC] = &gcc_usb4_0_phy_dp0_clk_src.clkr, + [GCC_USB4_0_PHY_DP1_CLK_SRC] = &gcc_usb4_0_phy_dp1_clk_src.clkr, + [GCC_USB4_0_PHY_P2RR2P_PIPE_CLK] = &gcc_usb4_0_phy_p2rr2p_pipe_clk.clkr, + [GCC_USB4_0_PHY_P2RR2P_PIPE_CLK_SRC] = &gcc_usb4_0_phy_p2rr2p_pipe_clk_src.clkr, + [GCC_USB4_0_PHY_PCIE_PIPE_CLK] = &gcc_usb4_0_phy_pcie_pipe_clk.clkr, + [GCC_USB4_0_PHY_PCIE_PIPE_CLK_SRC] = &gcc_usb4_0_phy_pcie_pipe_clk_src.clkr, + [GCC_USB4_0_PHY_PCIE_PIPE_MUX_CLK_SRC] = &gcc_usb4_0_phy_pcie_pipe_mux_clk_src.clkr, + [GCC_USB4_0_PHY_RX0_CLK] = &gcc_usb4_0_phy_rx0_clk.clkr, + [GCC_USB4_0_PHY_RX0_CLK_SRC] = &gcc_usb4_0_phy_rx0_clk_src.clkr, + [GCC_USB4_0_PHY_RX1_CLK] = &gcc_usb4_0_phy_rx1_clk.clkr, + [GCC_USB4_0_PHY_RX1_CLK_SRC] = &gcc_usb4_0_phy_rx1_clk_src.clkr, + [GCC_USB4_0_PHY_SYS_CLK_SRC] = &gcc_usb4_0_phy_sys_clk_src.clkr, + [GCC_USB4_0_PHY_USB_PIPE_CLK] = &gcc_usb4_0_phy_usb_pipe_clk.clkr, + [GCC_USB4_0_SB_IF_CLK] = &gcc_usb4_0_sb_if_clk.clkr, + [GCC_USB4_0_SB_IF_CLK_SRC] = &gcc_usb4_0_sb_if_clk_src.clkr, + [GCC_USB4_0_SYS_CLK] = &gcc_usb4_0_sys_clk.clkr, + [GCC_USB4_0_TMU_CLK] = &gcc_usb4_0_tmu_clk.clkr, + [GCC_USB4_0_TMU_CLK_SRC] = &gcc_usb4_0_tmu_clk_src.clkr, + [GCC_USB4_0_UC_HRR_CLK] = &gcc_usb4_0_uc_hrr_clk.clkr, + [GCC_USB4_1_CFG_AHB_CLK] = &gcc_usb4_1_cfg_ahb_clk.clkr, + [GCC_USB4_1_DP0_CLK] = &gcc_usb4_1_dp0_clk.clkr, + [GCC_USB4_1_DP1_CLK] = &gcc_usb4_1_dp1_clk.clkr, + [GCC_USB4_1_MASTER_CLK] = &gcc_usb4_1_master_clk.clkr, + [GCC_USB4_1_MASTER_CLK_SRC] = &gcc_usb4_1_master_clk_src.clkr, + [GCC_USB4_1_PHY_DP0_CLK_SRC] = &gcc_usb4_1_phy_dp0_clk_src.clkr, + [GCC_USB4_1_PHY_DP1_CLK_SRC] = &gcc_usb4_1_phy_dp1_clk_src.clkr, + [GCC_USB4_1_PHY_P2RR2P_PIPE_CLK] = &gcc_usb4_1_phy_p2rr2p_pipe_clk.clkr, + [GCC_USB4_1_PHY_P2RR2P_PIPE_CLK_SRC] = &gcc_usb4_1_phy_p2rr2p_pipe_clk_src.clkr, + [GCC_USB4_1_PHY_PCIE_PIPE_CLK] = &gcc_usb4_1_phy_pcie_pipe_clk.clkr, + [GCC_USB4_1_PHY_PCIE_PIPE_CLK_SRC] = &gcc_usb4_1_phy_pcie_pipe_clk_src.clkr, + [GCC_USB4_1_PHY_PCIE_PIPE_MUX_CLK_SRC] = &gcc_usb4_1_phy_pcie_pipe_mux_clk_src.clkr, + [GCC_USB4_1_PHY_PLL_PIPE_CLK_SRC] = &gcc_usb4_1_phy_pll_pipe_clk_src.clkr, + [GCC_USB4_1_PHY_RX0_CLK] = &gcc_usb4_1_phy_rx0_clk.clkr, + [GCC_USB4_1_PHY_RX0_CLK_SRC] = &gcc_usb4_1_phy_rx0_clk_src.clkr, + [GCC_USB4_1_PHY_RX1_CLK] = &gcc_usb4_1_phy_rx1_clk.clkr, + [GCC_USB4_1_PHY_RX1_CLK_SRC] = &gcc_usb4_1_phy_rx1_clk_src.clkr, + [GCC_USB4_1_PHY_SYS_CLK_SRC] = &gcc_usb4_1_phy_sys_clk_src.clkr, + [GCC_USB4_1_PHY_USB_PIPE_CLK] = &gcc_usb4_1_phy_usb_pipe_clk.clkr, + [GCC_USB4_1_SB_IF_CLK] = &gcc_usb4_1_sb_if_clk.clkr, + [GCC_USB4_1_SB_IF_CLK_SRC] = &gcc_usb4_1_sb_if_clk_src.clkr, + [GCC_USB4_1_SYS_CLK] = &gcc_usb4_1_sys_clk.clkr, + [GCC_USB4_1_TMU_CLK] = &gcc_usb4_1_tmu_clk.clkr, + [GCC_USB4_1_TMU_CLK_SRC] = &gcc_usb4_1_tmu_clk_src.clkr, + [GCC_USB4_1_UC_HRR_CLK] = &gcc_usb4_1_uc_hrr_clk.clkr, + [GCC_USB4_2_CFG_AHB_CLK] = &gcc_usb4_2_cfg_ahb_clk.clkr, + [GCC_USB4_2_DP0_CLK] = &gcc_usb4_2_dp0_clk.clkr, + [GCC_USB4_2_DP1_CLK] = &gcc_usb4_2_dp1_clk.clkr, + [GCC_USB4_2_MASTER_CLK] = &gcc_usb4_2_master_clk.clkr, + [GCC_USB4_2_MASTER_CLK_SRC] = &gcc_usb4_2_master_clk_src.clkr, + [GCC_USB4_2_PHY_DP0_CLK_SRC] = &gcc_usb4_2_phy_dp0_clk_src.clkr, + [GCC_USB4_2_PHY_DP1_CLK_SRC] = &gcc_usb4_2_phy_dp1_clk_src.clkr, + [GCC_USB4_2_PHY_P2RR2P_PIPE_CLK] = &gcc_usb4_2_phy_p2rr2p_pipe_clk.clkr, + [GCC_USB4_2_PHY_P2RR2P_PIPE_CLK_SRC] = &gcc_usb4_2_phy_p2rr2p_pipe_clk_src.clkr, + [GCC_USB4_2_PHY_PCIE_PIPE_CLK] = &gcc_usb4_2_phy_pcie_pipe_clk.clkr, + [GCC_USB4_2_PHY_PCIE_PIPE_CLK_SRC] = &gcc_usb4_2_phy_pcie_pipe_clk_src.clkr, + [GCC_USB4_2_PHY_PCIE_PIPE_MUX_CLK_SRC] = &gcc_usb4_2_phy_pcie_pipe_mux_clk_src.clkr, + [GCC_USB4_2_PHY_RX0_CLK] = &gcc_usb4_2_phy_rx0_clk.clkr, + [GCC_USB4_2_PHY_RX0_CLK_SRC] = &gcc_usb4_2_phy_rx0_clk_src.clkr, + [GCC_USB4_2_PHY_RX1_CLK] = &gcc_usb4_2_phy_rx1_clk.clkr, + [GCC_USB4_2_PHY_RX1_CLK_SRC] = &gcc_usb4_2_phy_rx1_clk_src.clkr, + [GCC_USB4_2_PHY_SYS_CLK_SRC] = &gcc_usb4_2_phy_sys_clk_src.clkr, + [GCC_USB4_2_PHY_USB_PIPE_CLK] = &gcc_usb4_2_phy_usb_pipe_clk.clkr, + [GCC_USB4_2_SB_IF_CLK] = &gcc_usb4_2_sb_if_clk.clkr, + [GCC_USB4_2_SB_IF_CLK_SRC] = &gcc_usb4_2_sb_if_clk_src.clkr, + [GCC_USB4_2_SYS_CLK] = &gcc_usb4_2_sys_clk.clkr, + [GCC_USB4_2_TMU_CLK] = &gcc_usb4_2_tmu_clk.clkr, + [GCC_USB4_2_TMU_CLK_SRC] = &gcc_usb4_2_tmu_clk_src.clkr, + [GCC_USB4_2_UC_HRR_CLK] = &gcc_usb4_2_uc_hrr_clk.clkr, + [GCC_VIDEO_AXI0_CLK] = &gcc_video_axi0_clk.clkr, + [GCC_VIDEO_AXI0C_CLK] = &gcc_video_axi0c_clk.clkr, + [GCC_VIDEO_AXI1_CLK] = &gcc_video_axi1_clk.clkr, +}; + +static struct gdsc *gcc_glymur_gdscs[] = { + [GCC_PCIE_0_TUNNEL_GDSC] = &gcc_pcie_0_tunnel_gdsc, + [GCC_PCIE_1_TUNNEL_GDSC] = &gcc_pcie_1_tunnel_gdsc, + [GCC_PCIE_2_TUNNEL_GDSC] = &gcc_pcie_2_tunnel_gdsc, + [GCC_PCIE_3A_GDSC] = &gcc_pcie_3a_gdsc, + [GCC_PCIE_3A_PHY_GDSC] = &gcc_pcie_3a_phy_gdsc, + [GCC_PCIE_3B_GDSC] = &gcc_pcie_3b_gdsc, + [GCC_PCIE_3B_PHY_GDSC] = &gcc_pcie_3b_phy_gdsc, + [GCC_PCIE_4_GDSC] = &gcc_pcie_4_gdsc, + [GCC_PCIE_4_PHY_GDSC] = &gcc_pcie_4_phy_gdsc, + [GCC_PCIE_5_GDSC] = &gcc_pcie_5_gdsc, + [GCC_PCIE_5_PHY_GDSC] = &gcc_pcie_5_phy_gdsc, + [GCC_PCIE_6_GDSC] = &gcc_pcie_6_gdsc, + [GCC_PCIE_6_PHY_GDSC] = &gcc_pcie_6_phy_gdsc, + [GCC_UFS_PHY_GDSC] = &gcc_ufs_phy_gdsc, + [GCC_USB20_PRIM_GDSC] = &gcc_usb20_prim_gdsc, + [GCC_USB30_MP_GDSC] = &gcc_usb30_mp_gdsc, + [GCC_USB30_PRIM_GDSC] = &gcc_usb30_prim_gdsc, + [GCC_USB30_SEC_GDSC] = &gcc_usb30_sec_gdsc, + [GCC_USB30_TERT_GDSC] = &gcc_usb30_tert_gdsc, + [GCC_USB3_MP_SS0_PHY_GDSC] = &gcc_usb3_mp_ss0_phy_gdsc, + [GCC_USB3_MP_SS1_PHY_GDSC] = &gcc_usb3_mp_ss1_phy_gdsc, + [GCC_USB4_0_GDSC] = &gcc_usb4_0_gdsc, + [GCC_USB4_1_GDSC] = &gcc_usb4_1_gdsc, + [GCC_USB4_2_GDSC] = &gcc_usb4_2_gdsc, + [GCC_USB_0_PHY_GDSC] = &gcc_usb_0_phy_gdsc, + [GCC_USB_1_PHY_GDSC] = &gcc_usb_1_phy_gdsc, + [GCC_USB_2_PHY_GDSC] = &gcc_usb_2_phy_gdsc, +}; + +static const struct qcom_reset_map gcc_glymur_resets[] = { + [GCC_AV1E_BCR] = { 0x9b028 }, + [GCC_CAMERA_BCR] = { 0x26000 }, + [GCC_DISPLAY_BCR] = { 0x27000 }, + [GCC_EVA_BCR] = { 0x9b000 }, + [GCC_GPU_BCR] = { 0x71000 }, + [GCC_PCIE_0_LINK_DOWN_BCR] = { 0xbc2d0 }, + [GCC_PCIE_0_NOCSR_COM_PHY_BCR] = { 0xbc2dc }, + [GCC_PCIE_0_PHY_BCR] = { 0xbc2d8 }, + [GCC_PCIE_0_PHY_NOCSR_COM_PHY_BCR] = { 0xbc2e0 }, + [GCC_PCIE_0_TUNNEL_BCR] = { 0xc8000 }, + [GCC_PCIE_1_LINK_DOWN_BCR] = { 0x7f018 }, + [GCC_PCIE_1_NOCSR_COM_PHY_BCR] = { 0x7f024 }, + [GCC_PCIE_1_PHY_BCR] = { 0x7f020 }, + [GCC_PCIE_1_PHY_NOCSR_COM_PHY_BCR] = { 0x7f028 }, + [GCC_PCIE_1_TUNNEL_BCR] = { 0x2e000 }, + [GCC_PCIE_2_LINK_DOWN_BCR] = { 0x281d0 }, + [GCC_PCIE_2_NOCSR_COM_PHY_BCR] = { 0x281dc }, + [GCC_PCIE_2_PHY_BCR] = { 0x281d8 }, + [GCC_PCIE_2_PHY_NOCSR_COM_PHY_BCR] = { 0x281e0 }, + [GCC_PCIE_2_TUNNEL_BCR] = { 0xc0000 }, + [GCC_PCIE_3A_BCR] = { 0xdc000 }, + [GCC_PCIE_3A_LINK_DOWN_BCR] = { 0x7b0a0 }, + [GCC_PCIE_3A_NOCSR_COM_PHY_BCR] = { 0x7b0ac }, + [GCC_PCIE_3A_PHY_BCR] = { 0x6c000 }, + [GCC_PCIE_3A_PHY_NOCSR_COM_PHY_BCR] = { 0x7b0b0 }, + [GCC_PCIE_3B_BCR] = { 0x94000 }, + [GCC_PCIE_3B_LINK_DOWN_BCR] = { 0x7a0c0 }, + [GCC_PCIE_3B_NOCSR_COM_PHY_BCR] = { 0x7a0cc }, + [GCC_PCIE_3B_PHY_BCR] = { 0x75000 }, + [GCC_PCIE_3B_PHY_NOCSR_COM_PHY_BCR] = { 0x7a0c8 }, + [GCC_PCIE_4_BCR] = { 0x88000 }, + [GCC_PCIE_4_LINK_DOWN_BCR] = { 0x980c0 }, + [GCC_PCIE_4_NOCSR_COM_PHY_BCR] = { 0x980cc }, + [GCC_PCIE_4_PHY_BCR] = { 0xd3000 }, + [GCC_PCIE_4_PHY_NOCSR_COM_PHY_BCR] = { 0x980d0 }, + [GCC_PCIE_5_BCR] = { 0xc3000 }, + [GCC_PCIE_5_LINK_DOWN_BCR] = { 0x850c0 }, + [GCC_PCIE_5_NOCSR_COM_PHY_BCR] = { 0x850cc }, + [GCC_PCIE_5_PHY_BCR] = { 0xd2000 }, + [GCC_PCIE_5_PHY_NOCSR_COM_PHY_BCR] = { 0x850d0 }, + [GCC_PCIE_6_BCR] = { 0x8a000 }, + [GCC_PCIE_6_LINK_DOWN_BCR] = { 0x3a0b0 }, + [GCC_PCIE_6_NOCSR_COM_PHY_BCR] = { 0x3a0bc }, + [GCC_PCIE_6_PHY_BCR] = { 0xd4000 }, + [GCC_PCIE_6_PHY_NOCSR_COM_PHY_BCR] = { 0x3a0c0 }, + [GCC_PCIE_NOC_BCR] = { 0xba294 }, + [GCC_PCIE_PHY_BCR] = { 0x6f000 }, + [GCC_PCIE_PHY_CFG_AHB_BCR] = { 0x7f00c }, + [GCC_PCIE_PHY_COM_BCR] = { 0x7f010 }, + [GCC_PCIE_RSCC_BCR] = { 0xb8000 }, + [GCC_PDM_BCR] = { 0x33000 }, + [GCC_QUPV3_WRAPPER_0_BCR] = { 0x28000 }, + [GCC_QUPV3_WRAPPER_1_BCR] = { 0xb3000 }, + [GCC_QUPV3_WRAPPER_2_BCR] = { 0xb4000 }, + [GCC_QUPV3_WRAPPER_OOB_BCR] = { 0xe7000 }, + [GCC_QUSB2PHY_HS0_MP_BCR] = { 0xca000 }, + [GCC_QUSB2PHY_HS1_MP_BCR] = { 0xe6000 }, + [GCC_QUSB2PHY_PRIM_BCR] = { 0xad024 }, + [GCC_QUSB2PHY_SEC_BCR] = { 0xae000 }, + [GCC_QUSB2PHY_TERT_BCR] = { 0xc9000 }, + [GCC_QUSB2PHY_USB20_HS_BCR] = { 0xe9000 }, + [GCC_SDCC2_BCR] = { 0xb0000 }, + [GCC_SDCC4_BCR] = { 0xdf000 }, + [GCC_TCSR_PCIE_BCR] = { 0x281e4 }, + [GCC_UFS_PHY_BCR] = { 0x77004 }, + [GCC_USB20_PRIM_BCR] = { 0xbc000 }, + [GCC_USB30_MP_BCR] = { 0x9a00c }, + [GCC_USB30_PRIM_BCR] = { 0x3f018 }, + [GCC_USB30_SEC_BCR] = { 0xe200c }, + [GCC_USB30_TERT_BCR] = { 0xe100c }, + [GCC_USB3_MP_SS0_PHY_BCR] = { 0x54008 }, + [GCC_USB3_MP_SS1_PHY_BCR] = { 0x54028 }, + [GCC_USB3_PHY_PRIM_BCR] = { 0xdb000 }, + [GCC_USB3_PHY_SEC_BCR] = { 0x2c000 }, + [GCC_USB3_PHY_TERT_BCR] = { 0xbe000 }, + [GCC_USB3_UNIPHY_MP0_BCR] = { 0x54000 }, + [GCC_USB3_UNIPHY_MP1_BCR] = { 0x54020 }, + [GCC_USB3PHY_PHY_PRIM_BCR] = { 0xdb004 }, + [GCC_USB3PHY_PHY_SEC_BCR] = { 0x2c004 }, + [GCC_USB3PHY_PHY_TERT_BCR] = { 0xbe004 }, + [GCC_USB3UNIPHY_PHY_MP0_BCR] = { 0x54004 }, + [GCC_USB3UNIPHY_PHY_MP1_BCR] = { 0x54024 }, + [GCC_USB4_0_BCR] = { 0x2b004 }, + [GCC_USB4_0_DP0_PHY_PRIM_BCR] = { 0xdb010 }, + [GCC_USB4_1_BCR] = { 0x2d004 }, + [GCC_USB4_2_BCR] = { 0xe0004 }, + [GCC_USB_0_PHY_BCR] = { 0xdb020 }, + [GCC_USB_1_PHY_BCR] = { 0x2c020 }, + [GCC_USB_2_PHY_BCR] = { 0xbe020 }, + [GCC_VIDEO_AXI0_CLK_ARES] = { 0x3201c, 2 }, + [GCC_VIDEO_AXI1_CLK_ARES] = { 0x32044, 2 }, + [GCC_VIDEO_BCR] = { 0x32000 }, +}; + +static const struct clk_rcg_dfs_data gcc_dfs_clocks[] = { + DEFINE_RCG_DFS(gcc_qupv3_oob_qspi_s0_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_oob_qspi_s1_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap0_qspi_s2_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap0_qspi_s3_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap0_qspi_s6_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap0_s0_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap0_s1_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap0_s4_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap0_s5_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap0_s7_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap1_qspi_s2_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap1_qspi_s3_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap1_qspi_s6_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap1_s0_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap1_s1_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap1_s4_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap1_s5_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap1_s7_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap2_qspi_s2_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap2_qspi_s3_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap2_qspi_s6_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap2_s0_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap2_s1_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap2_s4_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap2_s5_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap2_s7_clk_src), +}; + +static u32 gcc_glymur_critical_cbcrs[] = { + 0x26004, /* GCC_CAMERA_AHB_CLK */ + 0x26040, /* GCC_CAMERA_XO_CLK */ + 0x27004, /* GCC_DISP_AHB_CLK */ + 0x71004, /* GCC_GPU_CFG_AHB_CLK */ + 0x32004, /* GCC_VIDEO_AHB_CLK */ + 0x32058, /* GCC_VIDEO_XO_CLK */ +}; + +static const struct regmap_config gcc_glymur_regmap_config = { + .reg_bits = 32, + .reg_stride = 4, + .val_bits = 32, + .max_register = 0x1f8ff0, + .fast_io = true, +}; + +static void clk_glymur_regs_configure(struct device *dev, struct regmap *regmap) +{ + /* FORCE_MEM_CORE_ON for ufs phy ice core clocks */ + qcom_branch_set_force_mem_core(regmap, gcc_ufs_phy_ice_core_clk, true); +} + +static struct qcom_cc_driver_data gcc_glymur_driver_data = { + .clk_cbcrs = gcc_glymur_critical_cbcrs, + .num_clk_cbcrs = ARRAY_SIZE(gcc_glymur_critical_cbcrs), + .dfs_rcgs = gcc_dfs_clocks, + .num_dfs_rcgs = ARRAY_SIZE(gcc_dfs_clocks), + .clk_regs_configure = clk_glymur_regs_configure, +}; + +static const struct qcom_cc_desc gcc_glymur_desc = { + .config = &gcc_glymur_regmap_config, + .clks = gcc_glymur_clocks, + .num_clks = ARRAY_SIZE(gcc_glymur_clocks), + .resets = gcc_glymur_resets, + .num_resets = ARRAY_SIZE(gcc_glymur_resets), + .gdscs = gcc_glymur_gdscs, + .num_gdscs = ARRAY_SIZE(gcc_glymur_gdscs), + .driver_data = &gcc_glymur_driver_data, +}; + +static const struct of_device_id gcc_glymur_match_table[] = { + { .compatible = "qcom,glymur-gcc" }, + { } +}; +MODULE_DEVICE_TABLE(of, gcc_glymur_match_table); + +static int gcc_glymur_probe(struct platform_device *pdev) +{ + return qcom_cc_probe(pdev, &gcc_glymur_desc); +} + +static struct platform_driver gcc_glymur_driver = { + .probe = gcc_glymur_probe, + .driver = { + .name = "gcc-glymur", + .of_match_table = gcc_glymur_match_table, + }, +}; + +static int __init gcc_glymur_init(void) +{ + return platform_driver_register(&gcc_glymur_driver); +} +subsys_initcall(gcc_glymur_init); + +static void __exit gcc_glymur_exit(void) +{ + platform_driver_unregister(&gcc_glymur_driver); +} +module_exit(gcc_glymur_exit); + +MODULE_DESCRIPTION("QTI GCC GLYMUR Driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/clk/qcom/gcc-ipq6018.c b/drivers/clk/qcom/gcc-ipq6018.c index d861191b0c85..d4fc491a18b2 100644 --- a/drivers/clk/qcom/gcc-ipq6018.c +++ b/drivers/clk/qcom/gcc-ipq6018.c @@ -511,15 +511,23 @@ static struct clk_rcg2 apss_ahb_clk_src = { }, }; -static const struct freq_tbl ftbl_nss_port5_rx_clk_src[] = { - F(24000000, P_XO, 1, 0, 0), - F(25000000, P_UNIPHY1_RX, 12.5, 0, 0), - F(25000000, P_UNIPHY0_RX, 5, 0, 0), - F(78125000, P_UNIPHY1_RX, 4, 0, 0), - F(125000000, P_UNIPHY1_RX, 2.5, 0, 0), - F(125000000, P_UNIPHY0_RX, 1, 0, 0), - F(156250000, P_UNIPHY1_RX, 2, 0, 0), - F(312500000, P_UNIPHY1_RX, 1, 0, 0), +static const struct freq_conf ftbl_nss_port5_rx_clk_src_25[] = { + C(P_UNIPHY1_RX, 12.5, 0, 0), + C(P_UNIPHY0_RX, 5, 0, 0), +}; + +static const struct freq_conf ftbl_nss_port5_rx_clk_src_125[] = { + C(P_UNIPHY1_RX, 2.5, 0, 0), + C(P_UNIPHY0_RX, 1, 0, 0), +}; + +static const struct freq_multi_tbl ftbl_nss_port5_rx_clk_src[] = { + FMS(24000000, P_XO, 1, 0, 0), + FM(25000000, ftbl_nss_port5_rx_clk_src_25), + FMS(78125000, P_UNIPHY1_RX, 4, 0, 0), + FM(125000000, ftbl_nss_port5_rx_clk_src_125), + FMS(156250000, P_UNIPHY1_RX, 2, 0, 0), + FMS(312500000, P_UNIPHY1_RX, 1, 0, 0), { } }; @@ -547,26 +555,34 @@ gcc_xo_uniphy0_rx_tx_uniphy1_rx_tx_ubi32_bias_map[] = { static struct clk_rcg2 nss_port5_rx_clk_src = { .cmd_rcgr = 0x68060, - .freq_tbl = ftbl_nss_port5_rx_clk_src, + .freq_multi_tbl = ftbl_nss_port5_rx_clk_src, .hid_width = 5, .parent_map = gcc_xo_uniphy0_rx_tx_uniphy1_rx_tx_ubi32_bias_map, .clkr.hw.init = &(struct clk_init_data){ .name = "nss_port5_rx_clk_src", .parent_data = gcc_xo_uniphy0_rx_tx_uniphy1_rx_tx_ubi32_bias, .num_parents = 7, - .ops = &clk_rcg2_ops, + .ops = &clk_rcg2_fm_ops, }, }; -static const struct freq_tbl ftbl_nss_port5_tx_clk_src[] = { - F(24000000, P_XO, 1, 0, 0), - F(25000000, P_UNIPHY1_TX, 12.5, 0, 0), - F(25000000, P_UNIPHY0_TX, 5, 0, 0), - F(78125000, P_UNIPHY1_TX, 4, 0, 0), - F(125000000, P_UNIPHY1_TX, 2.5, 0, 0), - F(125000000, P_UNIPHY0_TX, 1, 0, 0), - F(156250000, P_UNIPHY1_TX, 2, 0, 0), - F(312500000, P_UNIPHY1_TX, 1, 0, 0), +static const struct freq_conf ftbl_nss_port5_tx_clk_src_25[] = { + C(P_UNIPHY1_TX, 12.5, 0, 0), + C(P_UNIPHY0_TX, 5, 0, 0), +}; + +static const struct freq_conf ftbl_nss_port5_tx_clk_src_125[] = { + C(P_UNIPHY1_TX, 2.5, 0, 0), + C(P_UNIPHY0_TX, 1, 0, 0), +}; + +static const struct freq_multi_tbl ftbl_nss_port5_tx_clk_src[] = { + FMS(24000000, P_XO, 1, 0, 0), + FM(25000000, ftbl_nss_port5_tx_clk_src_25), + FMS(78125000, P_UNIPHY1_TX, 4, 0, 0), + FM(125000000, ftbl_nss_port5_tx_clk_src_125), + FMS(156250000, P_UNIPHY1_TX, 2, 0, 0), + FMS(312500000, P_UNIPHY1_TX, 1, 0, 0), { } }; @@ -594,14 +610,14 @@ gcc_xo_uniphy0_tx_rx_uniphy1_tx_rx_ubi32_bias_map[] = { static struct clk_rcg2 nss_port5_tx_clk_src = { .cmd_rcgr = 0x68068, - .freq_tbl = ftbl_nss_port5_tx_clk_src, + .freq_multi_tbl = ftbl_nss_port5_tx_clk_src, .hid_width = 5, .parent_map = gcc_xo_uniphy0_tx_rx_uniphy1_tx_rx_ubi32_bias_map, .clkr.hw.init = &(struct clk_init_data){ .name = "nss_port5_tx_clk_src", .parent_data = gcc_xo_uniphy0_tx_rx_uniphy1_tx_rx_ubi32_bias, .num_parents = 7, - .ops = &clk_rcg2_ops, + .ops = &clk_rcg2_fm_ops, }, }; diff --git a/drivers/clk/qcom/gcc-msm8917.c b/drivers/clk/qcom/gcc-msm8917.c index 3e2a2ae2ee6e..0a1aa623cd49 100644 --- a/drivers/clk/qcom/gcc-msm8917.c +++ b/drivers/clk/qcom/gcc-msm8917.c @@ -37,6 +37,8 @@ enum { DT_SLEEP_CLK, DT_DSI0PLL, DT_DSI0PLL_BYTE, + DT_DSI1PLL, + DT_DSI1PLL_BYTE, }; enum { @@ -48,6 +50,8 @@ enum { P_GPLL6, P_DSI0PLL, P_DSI0PLL_BYTE, + P_DSI1PLL, + P_DSI1PLL_BYTE, }; static struct clk_alpha_pll gpll0_sleep_clk_src = { @@ -102,7 +106,11 @@ static const struct pll_vco gpll3_p_vco[] = { { 700000000, 1400000000, 0 }, }; -static const struct alpha_pll_config gpll3_early_config = { +static const struct pll_vco gpll3_p_vco_msm8937[] = { + { 525000000, 1066000000, 0 }, +}; + +static struct alpha_pll_config gpll3_early_config = { .l = 63, .config_ctl_val = 0x4001055b, .early_output_mask = 0, @@ -273,6 +281,19 @@ static const struct freq_tbl ftbl_blsp_i2c_apps_clk_src[] = { { } }; +static struct clk_rcg2 blsp1_qup1_i2c_apps_clk_src = { + .cmd_rcgr = 0x0200c, + .hid_width = 5, + .freq_tbl = ftbl_blsp_i2c_apps_clk_src, + .parent_map = gcc_xo_gpll0_map, + .clkr.hw.init = &(struct clk_init_data){ + .name = "blsp1_qup1_i2c_apps_clk_src", + .parent_data = gcc_xo_gpll0_data, + .num_parents = ARRAY_SIZE(gcc_xo_gpll0_data), + .ops = &clk_rcg2_ops, + }, +}; + static struct clk_rcg2 blsp1_qup2_i2c_apps_clk_src = { .cmd_rcgr = 0x03000, .hid_width = 5, @@ -351,6 +372,19 @@ static struct clk_rcg2 blsp2_qup3_i2c_apps_clk_src = { } }; +static struct clk_rcg2 blsp2_qup4_i2c_apps_clk_src = { + .cmd_rcgr = 0x18000, + .hid_width = 5, + .freq_tbl = ftbl_blsp_i2c_apps_clk_src, + .parent_map = gcc_xo_gpll0_map, + .clkr.hw.init = &(struct clk_init_data){ + .name = "blsp2_qup4_i2c_apps_clk_src", + .parent_data = gcc_xo_gpll0_data, + .num_parents = ARRAY_SIZE(gcc_xo_gpll0_data), + .ops = &clk_rcg2_ops, + }, +}; + static const struct freq_tbl ftbl_blsp_spi_apps_clk_src[] = { F(960000, P_XO, 10, 1, 2), F(4800000, P_XO, 4, 0, 0), @@ -362,6 +396,20 @@ static const struct freq_tbl ftbl_blsp_spi_apps_clk_src[] = { { } }; +static struct clk_rcg2 blsp1_qup1_spi_apps_clk_src = { + .cmd_rcgr = 0x02024, + .mnd_width = 8, + .hid_width = 5, + .freq_tbl = ftbl_blsp_spi_apps_clk_src, + .parent_map = gcc_xo_gpll0_map, + .clkr.hw.init = &(struct clk_init_data){ + .name = "blsp1_qup1_spi_apps_clk_src", + .parent_data = gcc_xo_gpll0_data, + .num_parents = ARRAY_SIZE(gcc_xo_gpll0_data), + .ops = &clk_rcg2_ops, + }, +}; + static struct clk_rcg2 blsp1_qup2_spi_apps_clk_src = { .cmd_rcgr = 0x03014, .hid_width = 5, @@ -446,6 +494,20 @@ static struct clk_rcg2 blsp2_qup3_spi_apps_clk_src = { } }; +static struct clk_rcg2 blsp2_qup4_spi_apps_clk_src = { + .cmd_rcgr = 0x18024, + .mnd_width = 8, + .hid_width = 5, + .freq_tbl = ftbl_blsp_spi_apps_clk_src, + .parent_map = gcc_xo_gpll0_map, + .clkr.hw.init = &(struct clk_init_data){ + .name = "blsp2_qup4_spi_apps_clk_src", + .parent_data = gcc_xo_gpll0_data, + .num_parents = ARRAY_SIZE(gcc_xo_gpll0_data), + .ops = &clk_rcg2_ops, + }, +}; + static const struct freq_tbl ftbl_blsp_uart_apps_clk_src[] = { F(3686400, P_GPLL0, 1, 72, 15625), F(7372800, P_GPLL0, 1, 144, 15625), @@ -525,11 +587,19 @@ static struct clk_rcg2 blsp2_uart2_apps_clk_src = { static const struct parent_map gcc_byte0_map[] = { { P_XO, 0 }, { P_DSI0PLL_BYTE, 1 }, + { P_DSI1PLL_BYTE, 3 }, +}; + +static const struct parent_map gcc_byte1_map[] = { + { P_XO, 0 }, + { P_DSI0PLL_BYTE, 3 }, + { P_DSI1PLL_BYTE, 1 }, }; static const struct clk_parent_data gcc_byte_data[] = { { .index = DT_XO }, { .index = DT_DSI0PLL_BYTE }, + { .index = DT_DSI1PLL_BYTE }, }; static struct clk_rcg2 byte0_clk_src = { @@ -545,6 +615,19 @@ static struct clk_rcg2 byte0_clk_src = { } }; +static struct clk_rcg2 byte1_clk_src = { + .cmd_rcgr = 0x4d0b0, + .hid_width = 5, + .parent_map = gcc_byte1_map, + .clkr.hw.init = &(struct clk_init_data){ + .name = "byte1_clk_src", + .parent_data = gcc_byte_data, + .num_parents = ARRAY_SIZE(gcc_byte_data), + .ops = &clk_byte2_ops, + .flags = CLK_SET_RATE_PARENT, + }, +}; + static const struct freq_tbl ftbl_camss_gp_clk_src[] = { F(100000000, P_GPLL0, 8, 0, 0), F(160000000, P_GPLL0, 5, 0, 0), @@ -642,6 +725,17 @@ static const struct freq_tbl ftbl_cpp_clk_src[] = { { } }; +static const struct freq_tbl ftbl_cpp_clk_src_msm8937[] = { + F(133330000, P_GPLL0, 6, 0, 0), + F(160000000, P_GPLL0, 5, 0, 0), + F(200000000, P_GPLL0, 5, 0, 0), + F(266666667, P_GPLL0, 3, 0, 0), + F(308570000, P_GPLL6, 3.5, 0, 0), + F(320000000, P_GPLL0, 2.5, 0, 0), + F(360000000, P_GPLL6, 3, 0, 0), + { } +}; + static struct clk_rcg2 cpp_clk_src = { .cmd_rcgr = 0x58018, .hid_width = 5, @@ -655,6 +749,13 @@ static struct clk_rcg2 cpp_clk_src = { } }; +static struct clk_init_data vcodec0_clk_src_init_msm8937 = { + .name = "vcodec0_clk_src", + .parent_data = gcc_cpp_data, + .num_parents = ARRAY_SIZE(gcc_cpp_data), + .ops = &clk_rcg2_ops, +}; + static const struct freq_tbl ftbl_crypto_clk_src[] = { F(50000000, P_GPLL0, 16, 0, 0), F(80000000, P_GPLL0, 10, 0, 0), @@ -730,6 +831,13 @@ static const struct freq_tbl ftbl_csi_phytimer_clk_src[] = { { } }; +static const struct freq_tbl ftbl_csi_phytimer_clk_src_msm8937[] = { + F(100000000, P_GPLL0, 8, 0, 0), + F(160000000, P_GPLL0, 5, 0, 0), + F(200000000, P_GPLL0, 4, 0, 0), + { } +}; + static struct clk_rcg2 csi0phytimer_clk_src = { .cmd_rcgr = 0x4e000, .hid_width = 5, @@ -774,6 +882,19 @@ static struct clk_rcg2 esc0_clk_src = { } }; +static struct clk_rcg2 esc1_clk_src = { + .cmd_rcgr = 0x4d0a8, + .hid_width = 5, + .freq_tbl = ftbl_esc0_1_clk_src, + .parent_map = gcc_xo_gpll0_out_aux_map, + .clkr.hw.init = &(struct clk_init_data){ + .name = "esc1_clk_src", + .parent_data = gcc_xo_gpll0_data, + .num_parents = ARRAY_SIZE(gcc_xo_gpll0_data), + .ops = &clk_rcg2_ops, + }, +}; + static const struct parent_map gcc_gfx3d_map[] = { { P_XO, 0 }, { P_GPLL0, 1 }, @@ -817,6 +938,25 @@ static const struct freq_tbl ftbl_gfx3d_clk_src[] = { { } }; +static const struct freq_tbl ftbl_gfx3d_clk_src_msm8937[] = { + F(19200000, P_XO, 1, 0, 0), + F(50000000, P_GPLL0, 16, 0, 0), + F(80000000, P_GPLL0, 10, 0, 0), + F(100000000, P_GPLL0, 8, 0, 0), + F(160000000, P_GPLL0, 5, 0, 0), + F(200000000, P_GPLL0, 4, 0, 0), + F(216000000, P_GPLL6, 5, 0, 0), + F(228570000, P_GPLL0, 3.5, 0, 0), + F(240000000, P_GPLL6, 4.5, 0, 0), + F(266670000, P_GPLL0, 3, 0, 0), + F(300000000, P_GPLL3, 1, 0, 0), + F(320000000, P_GPLL0, 2.5, 0, 0), + F(375000000, P_GPLL3, 1, 0, 0), + F(400000000, P_GPLL0, 2, 0, 0), + F(450000000, P_GPLL3, 1, 0, 0), + { } +}; + static struct clk_rcg2 gfx3d_clk_src = { .cmd_rcgr = 0x59000, .hid_width = 5, @@ -973,21 +1113,29 @@ static struct clk_rcg2 mdp_clk_src = { } }; -static const struct parent_map gcc_pclk_map[] = { +static const struct parent_map gcc_pclk0_map[] = { { P_XO, 0 }, { P_DSI0PLL, 1 }, + { P_DSI1PLL, 3 }, +}; + +static const struct parent_map gcc_pclk1_map[] = { + { P_XO, 0 }, + { P_DSI0PLL, 3 }, + { P_DSI1PLL, 1 }, }; static const struct clk_parent_data gcc_pclk_data[] = { { .index = DT_XO }, { .index = DT_DSI0PLL }, + { .index = DT_DSI1PLL }, }; static struct clk_rcg2 pclk0_clk_src = { .cmd_rcgr = 0x4d000, .hid_width = 5, .mnd_width = 8, - .parent_map = gcc_pclk_map, + .parent_map = gcc_pclk0_map, .clkr.hw.init = &(struct clk_init_data) { .name = "pclk0_clk_src", .parent_data = gcc_pclk_data, @@ -997,6 +1145,20 @@ static struct clk_rcg2 pclk0_clk_src = { } }; +static struct clk_rcg2 pclk1_clk_src = { + .cmd_rcgr = 0x4d0b8, + .hid_width = 5, + .mnd_width = 8, + .parent_map = gcc_pclk1_map, + .clkr.hw.init = &(struct clk_init_data){ + .name = "pclk1_clk_src", + .parent_data = gcc_pclk_data, + .num_parents = ARRAY_SIZE(gcc_pclk_data), + .ops = &clk_pixel_ops, + .flags = CLK_SET_RATE_PARENT, + }, +}; + static const struct freq_tbl ftbl_pdm2_clk_src[] = { F(64000000, P_GPLL0, 12.5, 0, 0), { } @@ -1108,6 +1270,14 @@ static const struct freq_tbl ftbl_usb_hs_system_clk_src[] = { { } }; +static const struct freq_tbl ftbl_usb_hs_system_clk_src_msm8937[] = { + F(57142857, P_GPLL0, 14, 0, 0), + F(100000000, P_GPLL0, 8, 0, 0), + F(133333333, P_GPLL0, 6, 0, 0), + F(177777778, P_GPLL0, 4.5, 0, 0), + { } +}; + static struct clk_rcg2 usb_hs_system_clk_src = { .cmd_rcgr = 0x41010, .hid_width = 5, @@ -1132,6 +1302,15 @@ static const struct freq_tbl ftbl_vcodec0_clk_src[] = { { } }; +static const struct freq_tbl ftbl_vcodec0_clk_src_msm8937[] = { + F(166150000, P_GPLL6, 6.5, 0, 0), + F(240000000, P_GPLL6, 4.5, 0, 0), + F(308571428, P_GPLL6, 3.5, 0, 0), + F(320000000, P_GPLL0, 2.5, 0, 0), + F(360000000, P_GPLL6, 3, 0, 0), + { } +}; + static struct clk_rcg2 vcodec0_clk_src = { .cmd_rcgr = 0x4c000, .hid_width = 5, @@ -1160,6 +1339,23 @@ static const struct freq_tbl ftbl_vfe_clk_src[] = { { } }; +static const struct freq_tbl ftbl_vfe_clk_src_msm8937[] = { + F(50000000, P_GPLL0, 16, 0, 0), + F(80000000, P_GPLL0, 10, 0, 0), + F(100000000, P_GPLL0, 8, 0, 0), + F(133333333, P_GPLL0, 6, 0, 0), + F(160000000, P_GPLL0, 5, 0, 0), + F(177777778, P_GPLL0, 4.5, 0, 0), + F(200000000, P_GPLL0, 4, 0, 0), + F(266666667, P_GPLL0, 3, 0, 0), + F(308571428, P_GPLL6, 3.5, 0, 0), + F(320000000, P_GPLL0, 2.5, 0, 0), + F(360000000, P_GPLL6, 3, 0, 0), + F(400000000, P_GPLL0, 2, 0, 0), + F(432000000, P_GPLL6, 2.5, 0, 0), + { } +}; + static struct clk_rcg2 vfe0_clk_src = { .cmd_rcgr = 0x58000, .hid_width = 5, @@ -1269,6 +1465,24 @@ static struct clk_branch gcc_blsp2_ahb_clk = { } }; +static struct clk_branch gcc_blsp1_qup1_i2c_apps_clk = { + .halt_reg = 0x02008, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x02008, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_blsp1_qup1_i2c_apps_clk", + .parent_hws = (const struct clk_hw*[]){ + &blsp1_qup1_i2c_apps_clk_src.clkr.hw, + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + static struct clk_branch gcc_blsp1_qup2_i2c_apps_clk = { .halt_reg = 0x03010, .halt_check = BRANCH_HALT, @@ -1377,6 +1591,42 @@ static struct clk_branch gcc_blsp2_qup3_i2c_apps_clk = { } }; +static struct clk_branch gcc_blsp2_qup4_i2c_apps_clk = { + .halt_reg = 0x18020, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x18020, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_blsp2_qup4_i2c_apps_clk", + .parent_hws = (const struct clk_hw*[]){ + &blsp2_qup4_i2c_apps_clk_src.clkr.hw, + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_branch gcc_blsp1_qup1_spi_apps_clk = { + .halt_reg = 0x02004, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x02004, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_blsp1_qup1_spi_apps_clk", + .parent_hws = (const struct clk_hw*[]){ + &blsp1_qup1_spi_apps_clk_src.clkr.hw, + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + static struct clk_branch gcc_blsp1_qup2_spi_apps_clk = { .halt_reg = 0x0300c, .halt_check = BRANCH_HALT, @@ -1485,6 +1735,24 @@ static struct clk_branch gcc_blsp2_qup3_spi_apps_clk = { } }; +static struct clk_branch gcc_blsp2_qup4_spi_apps_clk = { + .halt_reg = 0x1801c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x1801c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_blsp2_qup4_spi_apps_clk", + .parent_hws = (const struct clk_hw*[]){ + &blsp2_qup4_spi_apps_clk_src.clkr.hw, + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + static struct clk_branch gcc_blsp1_uart1_apps_clk = { .halt_reg = 0x0203c, .halt_check = BRANCH_HALT, @@ -2521,6 +2789,24 @@ static struct clk_branch gcc_mdss_byte0_clk = { } }; +static struct clk_branch gcc_mdss_byte1_clk = { + .halt_reg = 0x4d0a0, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x4d0a0, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_mdss_byte1_clk", + .parent_hws = (const struct clk_hw*[]){ + &byte1_clk_src.clkr.hw, + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + static struct clk_branch gcc_mdss_esc0_clk = { .halt_reg = 0x4d098, .halt_check = BRANCH_HALT, @@ -2539,6 +2825,24 @@ static struct clk_branch gcc_mdss_esc0_clk = { } }; +static struct clk_branch gcc_mdss_esc1_clk = { + .halt_reg = 0x4d09c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x4d09c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_mdss_esc1_clk", + .parent_hws = (const struct clk_hw*[]){ + &esc1_clk_src.clkr.hw, + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + static struct clk_branch gcc_mdss_mdp_clk = { .halt_reg = 0x4d088, .halt_check = BRANCH_HALT, @@ -2575,6 +2879,24 @@ static struct clk_branch gcc_mdss_pclk0_clk = { } }; +static struct clk_branch gcc_mdss_pclk1_clk = { + .halt_reg = 0x4d0a4, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x4d0a4, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_mdss_pclk1_clk", + .parent_hws = (const struct clk_hw*[]){ + &pclk1_clk_src.clkr.hw, + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + static struct clk_branch gcc_mdss_vsync_clk = { .halt_reg = 0x4d090, .halt_check = BRANCH_HALT, @@ -2632,6 +2954,24 @@ static struct clk_branch gcc_oxili_ahb_clk = { } }; +static struct clk_branch gcc_oxili_aon_clk = { + .halt_reg = 0x5904c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x5904c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_oxili_aon_clk", + .parent_hws = (const struct clk_hw*[]){ + &gfx3d_clk_src.clkr.hw, + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + static struct clk_branch gcc_oxili_gfx3d_clk = { .halt_reg = 0x59020, .halt_check = BRANCH_HALT, @@ -2650,6 +2990,19 @@ static struct clk_branch gcc_oxili_gfx3d_clk = { } }; +static struct clk_branch gcc_oxili_timer_clk = { + .halt_reg = 0x59040, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x59040, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_oxili_timer_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + static struct clk_branch gcc_pdm2_clk = { .halt_reg = 0x4400c, .halt_check = BRANCH_HALT, @@ -3027,6 +3380,28 @@ static struct gdsc oxili_gx_gdsc = { .flags = CLAMP_IO, }; +static struct gdsc oxili_gx_gdsc_msm8937 = { + .gdscr = 0x5901c, + .clamp_io_ctrl = 0x5b00c, + .cxcs = (unsigned int []){ 0x59000 }, + .cxc_count = 1, + .pd = { + .name = "oxili_gx_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, + .flags = CLAMP_IO, +}; + +static struct gdsc oxili_cx_gdsc = { + .gdscr = 0x59044, + .cxcs = (unsigned int []){ 0x59020 }, + .cxc_count = 1, + .pd = { + .name = "oxili_cx_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, +}; + static struct gdsc cpp_gdsc = { .gdscr = 0x58078, .cxcs = (unsigned int []){ 0x5803c, 0x58064 }, @@ -3207,6 +3582,188 @@ static struct clk_regmap *gcc_msm8917_clocks[] = { [GCC_VFE_TBU_CLK] = &gcc_vfe_tbu_clk.clkr, }; +static struct clk_regmap *gcc_msm8937_clocks[] = { + [GPLL0] = &gpll0.clkr, + [GPLL0_EARLY] = &gpll0_early.clkr, + [GPLL0_SLEEP_CLK_SRC] = &gpll0_sleep_clk_src.clkr, + [GPLL3] = &gpll3.clkr, + [GPLL3_EARLY] = &gpll3_early.clkr, + [GPLL4] = &gpll4.clkr, + [GPLL4_EARLY] = &gpll4_early.clkr, + [GPLL6] = &gpll6, + [GPLL6_EARLY] = &gpll6_early.clkr, + [APSS_AHB_CLK_SRC] = &apss_ahb_clk_src.clkr, + [MSM8937_BLSP1_QUP1_I2C_APPS_CLK_SRC] = &blsp1_qup1_i2c_apps_clk_src.clkr, + [MSM8937_BLSP1_QUP1_SPI_APPS_CLK_SRC] = &blsp1_qup1_spi_apps_clk_src.clkr, + [BLSP1_QUP2_I2C_APPS_CLK_SRC] = &blsp1_qup2_i2c_apps_clk_src.clkr, + [BLSP1_QUP2_SPI_APPS_CLK_SRC] = &blsp1_qup2_spi_apps_clk_src.clkr, + [BLSP1_QUP3_I2C_APPS_CLK_SRC] = &blsp1_qup3_i2c_apps_clk_src.clkr, + [BLSP1_QUP3_SPI_APPS_CLK_SRC] = &blsp1_qup3_spi_apps_clk_src.clkr, + [BLSP1_QUP4_I2C_APPS_CLK_SRC] = &blsp1_qup4_i2c_apps_clk_src.clkr, + [BLSP1_QUP4_SPI_APPS_CLK_SRC] = &blsp1_qup4_spi_apps_clk_src.clkr, + [BLSP1_UART1_APPS_CLK_SRC] = &blsp1_uart1_apps_clk_src.clkr, + [BLSP1_UART2_APPS_CLK_SRC] = &blsp1_uart2_apps_clk_src.clkr, + [BLSP2_QUP1_I2C_APPS_CLK_SRC] = &blsp2_qup1_i2c_apps_clk_src.clkr, + [BLSP2_QUP1_SPI_APPS_CLK_SRC] = &blsp2_qup1_spi_apps_clk_src.clkr, + [BLSP2_QUP2_I2C_APPS_CLK_SRC] = &blsp2_qup2_i2c_apps_clk_src.clkr, + [BLSP2_QUP2_SPI_APPS_CLK_SRC] = &blsp2_qup2_spi_apps_clk_src.clkr, + [BLSP2_QUP3_I2C_APPS_CLK_SRC] = &blsp2_qup3_i2c_apps_clk_src.clkr, + [BLSP2_QUP3_SPI_APPS_CLK_SRC] = &blsp2_qup3_spi_apps_clk_src.clkr, + [MSM8937_BLSP2_QUP4_I2C_APPS_CLK_SRC] = &blsp2_qup4_i2c_apps_clk_src.clkr, + [MSM8937_BLSP2_QUP4_SPI_APPS_CLK_SRC] = &blsp2_qup4_spi_apps_clk_src.clkr, + [BLSP2_UART1_APPS_CLK_SRC] = &blsp2_uart1_apps_clk_src.clkr, + [BLSP2_UART2_APPS_CLK_SRC] = &blsp2_uart2_apps_clk_src.clkr, + [BYTE0_CLK_SRC] = &byte0_clk_src.clkr, + [MSM8937_BYTE1_CLK_SRC] = &byte1_clk_src.clkr, + [CAMSS_GP0_CLK_SRC] = &camss_gp0_clk_src.clkr, + [CAMSS_GP1_CLK_SRC] = &camss_gp1_clk_src.clkr, + [CAMSS_TOP_AHB_CLK_SRC] = &camss_top_ahb_clk_src.clkr, + [CCI_CLK_SRC] = &cci_clk_src.clkr, + [CPP_CLK_SRC] = &cpp_clk_src.clkr, + [CRYPTO_CLK_SRC] = &crypto_clk_src.clkr, + [CSI0PHYTIMER_CLK_SRC] = &csi0phytimer_clk_src.clkr, + [CSI0_CLK_SRC] = &csi0_clk_src.clkr, + [CSI1PHYTIMER_CLK_SRC] = &csi1phytimer_clk_src.clkr, + [CSI1_CLK_SRC] = &csi1_clk_src.clkr, + [CSI2_CLK_SRC] = &csi2_clk_src.clkr, + [ESC0_CLK_SRC] = &esc0_clk_src.clkr, + [MSM8937_ESC1_CLK_SRC] = &esc1_clk_src.clkr, + [GFX3D_CLK_SRC] = &gfx3d_clk_src.clkr, + [GP1_CLK_SRC] = &gp1_clk_src.clkr, + [GP2_CLK_SRC] = &gp2_clk_src.clkr, + [GP3_CLK_SRC] = &gp3_clk_src.clkr, + [JPEG0_CLK_SRC] = &jpeg0_clk_src.clkr, + [MCLK0_CLK_SRC] = &mclk0_clk_src.clkr, + [MCLK1_CLK_SRC] = &mclk1_clk_src.clkr, + [MCLK2_CLK_SRC] = &mclk2_clk_src.clkr, + [MDP_CLK_SRC] = &mdp_clk_src.clkr, + [PCLK0_CLK_SRC] = &pclk0_clk_src.clkr, + [MSM8937_PCLK1_CLK_SRC] = &pclk1_clk_src.clkr, + [PDM2_CLK_SRC] = &pdm2_clk_src.clkr, + [SDCC1_APPS_CLK_SRC] = &sdcc1_apps_clk_src.clkr, + [SDCC1_ICE_CORE_CLK_SRC] = &sdcc1_ice_core_clk_src.clkr, + [SDCC2_APPS_CLK_SRC] = &sdcc2_apps_clk_src.clkr, + [USB_HS_SYSTEM_CLK_SRC] = &usb_hs_system_clk_src.clkr, + [VCODEC0_CLK_SRC] = &vcodec0_clk_src.clkr, + [VFE0_CLK_SRC] = &vfe0_clk_src.clkr, + [VFE1_CLK_SRC] = &vfe1_clk_src.clkr, + [VSYNC_CLK_SRC] = &vsync_clk_src.clkr, + [GCC_APSS_TCU_CLK] = &gcc_apss_tcu_clk.clkr, + [GCC_BIMC_GFX_CLK] = &gcc_bimc_gfx_clk.clkr, + [GCC_BIMC_GPU_CLK] = &gcc_bimc_gpu_clk.clkr, + [GCC_BLSP1_AHB_CLK] = &gcc_blsp1_ahb_clk.clkr, + [MSM8937_GCC_BLSP1_QUP1_I2C_APPS_CLK] = &gcc_blsp1_qup1_i2c_apps_clk.clkr, + [MSM8937_GCC_BLSP1_QUP1_SPI_APPS_CLK] = &gcc_blsp1_qup1_spi_apps_clk.clkr, + [GCC_BLSP1_QUP2_I2C_APPS_CLK] = &gcc_blsp1_qup2_i2c_apps_clk.clkr, + [GCC_BLSP1_QUP2_SPI_APPS_CLK] = &gcc_blsp1_qup2_spi_apps_clk.clkr, + [GCC_BLSP1_QUP3_I2C_APPS_CLK] = &gcc_blsp1_qup3_i2c_apps_clk.clkr, + [GCC_BLSP1_QUP3_SPI_APPS_CLK] = &gcc_blsp1_qup3_spi_apps_clk.clkr, + [GCC_BLSP1_QUP4_I2C_APPS_CLK] = &gcc_blsp1_qup4_i2c_apps_clk.clkr, + [GCC_BLSP1_QUP4_SPI_APPS_CLK] = &gcc_blsp1_qup4_spi_apps_clk.clkr, + [GCC_BLSP1_UART1_APPS_CLK] = &gcc_blsp1_uart1_apps_clk.clkr, + [GCC_BLSP1_UART2_APPS_CLK] = &gcc_blsp1_uart2_apps_clk.clkr, + [GCC_BLSP2_AHB_CLK] = &gcc_blsp2_ahb_clk.clkr, + [GCC_BLSP2_QUP1_I2C_APPS_CLK] = &gcc_blsp2_qup1_i2c_apps_clk.clkr, + [GCC_BLSP2_QUP1_SPI_APPS_CLK] = &gcc_blsp2_qup1_spi_apps_clk.clkr, + [GCC_BLSP2_QUP2_I2C_APPS_CLK] = &gcc_blsp2_qup2_i2c_apps_clk.clkr, + [GCC_BLSP2_QUP2_SPI_APPS_CLK] = &gcc_blsp2_qup2_spi_apps_clk.clkr, + [GCC_BLSP2_QUP3_I2C_APPS_CLK] = &gcc_blsp2_qup3_i2c_apps_clk.clkr, + [GCC_BLSP2_QUP3_SPI_APPS_CLK] = &gcc_blsp2_qup3_spi_apps_clk.clkr, + [MSM8937_GCC_BLSP2_QUP4_I2C_APPS_CLK] = &gcc_blsp2_qup4_i2c_apps_clk.clkr, + [MSM8937_GCC_BLSP2_QUP4_SPI_APPS_CLK] = &gcc_blsp2_qup4_spi_apps_clk.clkr, + [GCC_BLSP2_UART1_APPS_CLK] = &gcc_blsp2_uart1_apps_clk.clkr, + [GCC_BLSP2_UART2_APPS_CLK] = &gcc_blsp2_uart2_apps_clk.clkr, + [GCC_BOOT_ROM_AHB_CLK] = &gcc_boot_rom_ahb_clk.clkr, + [GCC_CAMSS_AHB_CLK] = &gcc_camss_ahb_clk.clkr, + [GCC_CAMSS_CCI_AHB_CLK] = &gcc_camss_cci_ahb_clk.clkr, + [GCC_CAMSS_CCI_CLK] = &gcc_camss_cci_clk.clkr, + [GCC_CAMSS_CPP_AHB_CLK] = &gcc_camss_cpp_ahb_clk.clkr, + [GCC_CAMSS_CPP_CLK] = &gcc_camss_cpp_clk.clkr, + [GCC_CAMSS_CSI0PHYTIMER_CLK] = &gcc_camss_csi0phytimer_clk.clkr, + [GCC_CAMSS_CSI0PHY_CLK] = &gcc_camss_csi0phy_clk.clkr, + [GCC_CAMSS_CSI0PIX_CLK] = &gcc_camss_csi0pix_clk.clkr, + [GCC_CAMSS_CSI0RDI_CLK] = &gcc_camss_csi0rdi_clk.clkr, + [GCC_CAMSS_CSI0_AHB_CLK] = &gcc_camss_csi0_ahb_clk.clkr, + [GCC_CAMSS_CSI0_CLK] = &gcc_camss_csi0_clk.clkr, + [GCC_CAMSS_CSI1PHYTIMER_CLK] = &gcc_camss_csi1phytimer_clk.clkr, + [GCC_CAMSS_CSI1PHY_CLK] = &gcc_camss_csi1phy_clk.clkr, + [GCC_CAMSS_CSI1PIX_CLK] = &gcc_camss_csi1pix_clk.clkr, + [GCC_CAMSS_CSI1RDI_CLK] = &gcc_camss_csi1rdi_clk.clkr, + [GCC_CAMSS_CSI1_AHB_CLK] = &gcc_camss_csi1_ahb_clk.clkr, + [GCC_CAMSS_CSI1_CLK] = &gcc_camss_csi1_clk.clkr, + [GCC_CAMSS_CSI2PHY_CLK] = &gcc_camss_csi2phy_clk.clkr, + [GCC_CAMSS_CSI2PIX_CLK] = &gcc_camss_csi2pix_clk.clkr, + [GCC_CAMSS_CSI2RDI_CLK] = &gcc_camss_csi2rdi_clk.clkr, + [GCC_CAMSS_CSI2_AHB_CLK] = &gcc_camss_csi2_ahb_clk.clkr, + [GCC_CAMSS_CSI2_CLK] = &gcc_camss_csi2_clk.clkr, + [GCC_CAMSS_CSI_VFE0_CLK] = &gcc_camss_csi_vfe0_clk.clkr, + [GCC_CAMSS_CSI_VFE1_CLK] = &gcc_camss_csi_vfe1_clk.clkr, + [GCC_CAMSS_GP0_CLK] = &gcc_camss_gp0_clk.clkr, + [GCC_CAMSS_GP1_CLK] = &gcc_camss_gp1_clk.clkr, + [GCC_CAMSS_ISPIF_AHB_CLK] = &gcc_camss_ispif_ahb_clk.clkr, + [GCC_CAMSS_JPEG0_CLK] = &gcc_camss_jpeg0_clk.clkr, + [GCC_CAMSS_JPEG_AHB_CLK] = &gcc_camss_jpeg_ahb_clk.clkr, + [GCC_CAMSS_JPEG_AXI_CLK] = &gcc_camss_jpeg_axi_clk.clkr, + [GCC_CAMSS_MCLK0_CLK] = &gcc_camss_mclk0_clk.clkr, + [GCC_CAMSS_MCLK1_CLK] = &gcc_camss_mclk1_clk.clkr, + [GCC_CAMSS_MCLK2_CLK] = &gcc_camss_mclk2_clk.clkr, + [GCC_CAMSS_MICRO_AHB_CLK] = &gcc_camss_micro_ahb_clk.clkr, + [GCC_CAMSS_TOP_AHB_CLK] = &gcc_camss_top_ahb_clk.clkr, + [GCC_CAMSS_VFE0_AHB_CLK] = &gcc_camss_vfe0_ahb_clk.clkr, + [GCC_CAMSS_VFE0_AXI_CLK] = &gcc_camss_vfe0_axi_clk.clkr, + [GCC_CAMSS_VFE0_CLK] = &gcc_camss_vfe0_clk.clkr, + [GCC_CAMSS_VFE1_AHB_CLK] = &gcc_camss_vfe1_ahb_clk.clkr, + [GCC_CAMSS_VFE1_AXI_CLK] = &gcc_camss_vfe1_axi_clk.clkr, + [GCC_CAMSS_VFE1_CLK] = &gcc_camss_vfe1_clk.clkr, + [GCC_CPP_TBU_CLK] = &gcc_cpp_tbu_clk.clkr, + [GCC_CRYPTO_AHB_CLK] = &gcc_crypto_ahb_clk.clkr, + [GCC_CRYPTO_AXI_CLK] = &gcc_crypto_axi_clk.clkr, + [GCC_CRYPTO_CLK] = &gcc_crypto_clk.clkr, + [GCC_DCC_CLK] = &gcc_dcc_clk.clkr, + [GCC_GP1_CLK] = &gcc_gp1_clk.clkr, + [GCC_GP2_CLK] = &gcc_gp2_clk.clkr, + [GCC_GP3_CLK] = &gcc_gp3_clk.clkr, + [GCC_JPEG_TBU_CLK] = &gcc_jpeg_tbu_clk.clkr, + [GCC_MDP_TBU_CLK] = &gcc_mdp_tbu_clk.clkr, + [GCC_MDSS_AHB_CLK] = &gcc_mdss_ahb_clk.clkr, + [GCC_MDSS_AXI_CLK] = &gcc_mdss_axi_clk.clkr, + [GCC_MDSS_BYTE0_CLK] = &gcc_mdss_byte0_clk.clkr, + [MSM8937_GCC_MDSS_BYTE1_CLK] = &gcc_mdss_byte1_clk.clkr, + [GCC_MDSS_ESC0_CLK] = &gcc_mdss_esc0_clk.clkr, + [MSM8937_GCC_MDSS_ESC1_CLK] = &gcc_mdss_esc1_clk.clkr, + [GCC_MDSS_MDP_CLK] = &gcc_mdss_mdp_clk.clkr, + [GCC_MDSS_PCLK0_CLK] = &gcc_mdss_pclk0_clk.clkr, + [MSM8937_GCC_MDSS_PCLK1_CLK] = &gcc_mdss_pclk1_clk.clkr, + [GCC_MDSS_VSYNC_CLK] = &gcc_mdss_vsync_clk.clkr, + [GCC_MSS_CFG_AHB_CLK] = &gcc_mss_cfg_ahb_clk.clkr, + [GCC_MSS_Q6_BIMC_AXI_CLK] = &gcc_mss_q6_bimc_axi_clk.clkr, + [GCC_OXILI_AHB_CLK] = &gcc_oxili_ahb_clk.clkr, + [MSM8937_GCC_OXILI_AON_CLK] = &gcc_oxili_aon_clk.clkr, + [GCC_OXILI_GFX3D_CLK] = &gcc_oxili_gfx3d_clk.clkr, + [MSM8937_GCC_OXILI_TIMER_CLK] = &gcc_oxili_timer_clk.clkr, + [GCC_PDM2_CLK] = &gcc_pdm2_clk.clkr, + [GCC_PDM_AHB_CLK] = &gcc_pdm_ahb_clk.clkr, + [GCC_PRNG_AHB_CLK] = &gcc_prng_ahb_clk.clkr, + [GCC_QDSS_DAP_CLK] = &gcc_qdss_dap_clk.clkr, + [GCC_SDCC1_AHB_CLK] = &gcc_sdcc1_ahb_clk.clkr, + [GCC_SDCC1_APPS_CLK] = &gcc_sdcc1_apps_clk.clkr, + [GCC_SDCC1_ICE_CORE_CLK] = &gcc_sdcc1_ice_core_clk.clkr, + [GCC_SDCC2_AHB_CLK] = &gcc_sdcc2_ahb_clk.clkr, + [GCC_SDCC2_APPS_CLK] = &gcc_sdcc2_apps_clk.clkr, + [GCC_SMMU_CFG_CLK] = &gcc_smmu_cfg_clk.clkr, + [GCC_USB2A_PHY_SLEEP_CLK] = &gcc_usb2a_phy_sleep_clk.clkr, + [GCC_USB_HS_AHB_CLK] = &gcc_usb_hs_ahb_clk.clkr, + [GCC_USB_HS_PHY_CFG_AHB_CLK] = &gcc_usb_hs_phy_cfg_ahb_clk.clkr, + [GCC_USB_HS_SYSTEM_CLK] = &gcc_usb_hs_system_clk.clkr, + [GCC_VENUS0_AHB_CLK] = &gcc_venus0_ahb_clk.clkr, + [GCC_VENUS0_AXI_CLK] = &gcc_venus0_axi_clk.clkr, + [GCC_VENUS0_CORE0_VCODEC0_CLK] = &gcc_venus0_core0_vcodec0_clk.clkr, + [GCC_VENUS0_VCODEC0_CLK] = &gcc_venus0_vcodec0_clk.clkr, + [GCC_VENUS_TBU_CLK] = &gcc_venus_tbu_clk.clkr, + [GCC_VFE1_TBU_CLK] = &gcc_vfe1_tbu_clk.clkr, + [GCC_VFE_TBU_CLK] = &gcc_vfe_tbu_clk.clkr, +}; + static const struct qcom_reset_map gcc_msm8917_resets[] = { [GCC_CAMSS_MICRO_BCR] = { 0x56008 }, [GCC_MSS_BCR] = { 0x71000 }, @@ -3234,6 +3791,18 @@ static struct gdsc *gcc_msm8917_gdscs[] = { [VFE1_GDSC] = &vfe1_gdsc, }; +static struct gdsc *gcc_msm8937_gdscs[] = { + [CPP_GDSC] = &cpp_gdsc, + [JPEG_GDSC] = &jpeg_gdsc, + [MDSS_GDSC] = &mdss_gdsc, + [OXILI_GX_GDSC] = &oxili_gx_gdsc_msm8937, + [MSM8937_OXILI_CX_GDSC] = &oxili_cx_gdsc, + [VENUS_CORE0_GDSC] = &venus_core0_gdsc, + [VENUS_GDSC] = &venus_gdsc, + [VFE0_GDSC] = &vfe0_gdsc, + [VFE1_GDSC] = &vfe1_gdsc, +}; + static const struct qcom_cc_desc gcc_msm8917_desc = { .config = &gcc_msm8917_regmap_config, .clks = gcc_msm8917_clocks, @@ -3254,6 +3823,41 @@ static const struct qcom_cc_desc gcc_qm215_desc = { .num_gdscs = ARRAY_SIZE(gcc_msm8917_gdscs), }; +static const struct qcom_cc_desc gcc_msm8937_desc = { + .config = &gcc_msm8917_regmap_config, + .clks = gcc_msm8937_clocks, + .num_clks = ARRAY_SIZE(gcc_msm8937_clocks), + .resets = gcc_msm8917_resets, + .num_resets = ARRAY_SIZE(gcc_msm8917_resets), + .gdscs = gcc_msm8937_gdscs, + .num_gdscs = ARRAY_SIZE(gcc_msm8937_gdscs), +}; + +static void msm8937_clock_override(void) +{ + /* GPLL3 750MHz configuration */ + gpll3_early_config.l = 47; + gpll3_early.vco_table = gpll3_p_vco_msm8937; + gpll3_early.num_vco = ARRAY_SIZE(gpll3_p_vco_msm8937); + + /* + * Set below clocks for use specific msm8937 parent map. + */ + vcodec0_clk_src.parent_map = gcc_cpp_map; + vcodec0_clk_src.clkr.hw.init = &vcodec0_clk_src_init_msm8937; + + /* + * Set below clocks for use specific msm8937 freq table. + */ + vfe0_clk_src.freq_tbl = ftbl_vfe_clk_src_msm8937; + vfe1_clk_src.freq_tbl = ftbl_vfe_clk_src_msm8937; + cpp_clk_src.freq_tbl = ftbl_cpp_clk_src_msm8937; + vcodec0_clk_src.freq_tbl = ftbl_vcodec0_clk_src_msm8937; + csi0phytimer_clk_src.freq_tbl = ftbl_csi_phytimer_clk_src_msm8937; + csi1phytimer_clk_src.freq_tbl = ftbl_csi_phytimer_clk_src_msm8937; + usb_hs_system_clk_src.freq_tbl = ftbl_usb_hs_system_clk_src_msm8937; +} + static int gcc_msm8917_probe(struct platform_device *pdev) { struct regmap *regmap; @@ -3261,8 +3865,12 @@ static int gcc_msm8917_probe(struct platform_device *pdev) gcc_desc = of_device_get_match_data(&pdev->dev); - if (gcc_desc == &gcc_qm215_desc) + if (gcc_desc == &gcc_qm215_desc) { gfx3d_clk_src.parent_map = gcc_gfx3d_map_qm215; + } else if (gcc_desc == &gcc_msm8937_desc) { + msm8937_clock_override(); + gfx3d_clk_src.freq_tbl = ftbl_gfx3d_clk_src_msm8937; + } regmap = qcom_cc_map(pdev, gcc_desc); if (IS_ERR(regmap)) @@ -3276,6 +3884,7 @@ static int gcc_msm8917_probe(struct platform_device *pdev) static const struct of_device_id gcc_msm8917_match_table[] = { { .compatible = "qcom,gcc-msm8917", .data = &gcc_msm8917_desc }, { .compatible = "qcom,gcc-qm215", .data = &gcc_qm215_desc }, + { .compatible = "qcom,gcc-msm8937", .data = &gcc_msm8937_desc }, {}, }; MODULE_DEVICE_TABLE(of, gcc_msm8917_match_table); diff --git a/drivers/clk/qcom/gcc-qcs404.c b/drivers/clk/qcom/gcc-qcs404.c index 5ca003c9bfba..efc75a3814ab 100644 --- a/drivers/clk/qcom/gcc-qcs404.c +++ b/drivers/clk/qcom/gcc-qcs404.c @@ -2754,7 +2754,7 @@ static struct clk_regmap *gcc_qcs404_clocks[] = { [GCC_DCC_CLK] = &gcc_dcc_clk.clkr, [GCC_DCC_XO_CLK] = &gcc_dcc_xo_clk.clkr, [GCC_WCSS_Q6_AHB_CLK] = &gcc_wdsp_q6ss_ahbs_clk.clkr, - [GCC_WCSS_Q6_AXIM_CLK] = &gcc_wdsp_q6ss_axim_clk.clkr, + [GCC_WCSS_Q6_AXIM_CLK] = &gcc_wdsp_q6ss_axim_clk.clkr, }; diff --git a/drivers/clk/qcom/gcc-sc8280xp.c b/drivers/clk/qcom/gcc-sc8280xp.c index f27d0003f427..b683795475e3 100644 --- a/drivers/clk/qcom/gcc-sc8280xp.c +++ b/drivers/clk/qcom/gcc-sc8280xp.c @@ -6775,10 +6775,6 @@ static struct gdsc pcie_1_tunnel_gdsc = { .flags = VOTABLE | RETAIN_FF_ENABLE, }; -/* - * The Qualcomm PCIe driver does not yet implement suspend so to keep the - * PCIe power domains always-on for now. - */ static struct gdsc pcie_2a_gdsc = { .gdscr = 0x9d004, .collapse_ctrl = 0x52128, diff --git a/drivers/clk/qcom/gcc-sdm660.c b/drivers/clk/qcom/gcc-sdm660.c index 01a76f1b5b4c..20253a06a583 100644 --- a/drivers/clk/qcom/gcc-sdm660.c +++ b/drivers/clk/qcom/gcc-sdm660.c @@ -2247,6 +2247,45 @@ static struct clk_branch gcc_usb_phy_cfg_ahb2phy_clk = { }, }; +static struct clk_branch hlos1_vote_lpass_adsp_smmu_clk = { + .halt_reg = 0x7d014, + .halt_check = BRANCH_VOTED, + .clkr = { + .enable_reg = 0x7d014, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "hlos1_vote_lpass_adsp_smmu_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch hlos1_vote_turing_adsp_smmu_clk = { + .halt_reg = 0x7d048, + .halt_check = BRANCH_VOTED, + .clkr = { + .enable_reg = 0x7d048, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "hlos1_vote_turing_adsp_smmu_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch hlos2_vote_turing_adsp_smmu_clk = { + .halt_reg = 0x7e048, + .halt_check = BRANCH_VOTED, + .clkr = { + .enable_reg = 0x7e048, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "hlos2_vote_turing_adsp_smmu_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + static struct gdsc ufs_gdsc = { .gdscr = 0x75004, .gds_hw_ctrl = 0x0, @@ -2277,6 +2316,33 @@ static struct gdsc pcie_0_gdsc = { .flags = VOTABLE, }; +static struct gdsc hlos1_vote_turing_adsp_gdsc = { + .gdscr = 0x7d04c, + .pd = { + .name = "hlos1_vote_turing_adsp_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, + .flags = VOTABLE, +}; + +static struct gdsc hlos2_vote_turing_adsp_gdsc = { + .gdscr = 0x7e04c, + .pd = { + .name = "hlos2_vote_turing_adsp_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, + .flags = VOTABLE, +}; + +static struct gdsc hlos1_vote_lpass_adsp_gdsc = { + .gdscr = 0x7d034, + .pd = { + .name = "hlos1_vote_lpass_adsp_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, + .flags = VOTABLE, +}; + static struct clk_hw *gcc_sdm660_hws[] = { &xo.hw, &gpll0_early_div.hw, @@ -2409,12 +2475,18 @@ static struct clk_regmap *gcc_sdm660_clocks[] = { [USB30_MASTER_CLK_SRC] = &usb30_master_clk_src.clkr, [USB30_MOCK_UTMI_CLK_SRC] = &usb30_mock_utmi_clk_src.clkr, [USB3_PHY_AUX_CLK_SRC] = &usb3_phy_aux_clk_src.clkr, + [GCC_HLOS1_VOTE_LPASS_ADSP_SMMU_CLK] = &hlos1_vote_lpass_adsp_smmu_clk.clkr, + [GCC_HLOS1_VOTE_TURING_ADSP_SMMU_CLK] = &hlos1_vote_turing_adsp_smmu_clk.clkr, + [GCC_HLOS2_VOTE_TURING_ADSP_SMMU_CLK] = &hlos2_vote_turing_adsp_smmu_clk.clkr, }; static struct gdsc *gcc_sdm660_gdscs[] = { [UFS_GDSC] = &ufs_gdsc, [USB_30_GDSC] = &usb_30_gdsc, [PCIE_0_GDSC] = &pcie_0_gdsc, + [HLOS1_VOTE_TURING_ADSP_GDSC] = &hlos1_vote_turing_adsp_gdsc, + [HLOS2_VOTE_TURING_ADSP_GDSC] = &hlos2_vote_turing_adsp_gdsc, + [HLOS1_VOTE_LPASS_ADSP_GDSC] = &hlos1_vote_lpass_adsp_gdsc, }; static const struct qcom_reset_map gcc_sdm660_resets[] = { diff --git a/drivers/clk/qcom/gpucc-sa8775p.c b/drivers/clk/qcom/gpucc-sa8775p.c index 78cad622cb5a..25dcc5912f99 100644 --- a/drivers/clk/qcom/gpucc-sa8775p.c +++ b/drivers/clk/qcom/gpucc-sa8775p.c @@ -365,7 +365,7 @@ static struct clk_branch gpu_cc_cx_gmu_clk = { &gpu_cc_gmu_clk_src.clkr.hw, }, .num_parents = 1, - .flags = CLK_SET_RATE_PARENT, + .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_aon_ops, }, }, @@ -414,7 +414,7 @@ static struct clk_branch gpu_cc_cxo_clk = { &gpu_cc_xo_clk_src.clkr.hw, }, .num_parents = 1, - .flags = CLK_SET_RATE_PARENT, + .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, }, }, @@ -499,7 +499,7 @@ static struct clk_branch gpu_cc_hub_cx_int_clk = { &gpu_cc_hub_cx_int_div_clk_src.clkr.hw, }, .num_parents = 1, - .flags = CLK_SET_RATE_PARENT, + .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_aon_ops, }, }, diff --git a/drivers/clk/qcom/gpucc-sc7180.c b/drivers/clk/qcom/gpucc-sc7180.c index a7bf44544b95..97287488e05a 100644 --- a/drivers/clk/qcom/gpucc-sc7180.c +++ b/drivers/clk/qcom/gpucc-sc7180.c @@ -42,7 +42,7 @@ static struct clk_alpha_pll gpu_cc_pll1 = { .clkr = { .hw.init = &(struct clk_init_data){ .name = "gpu_cc_pll1", - .parent_data = &(const struct clk_parent_data){ + .parent_data = &(const struct clk_parent_data){ .fw_name = "bi_tcxo", }, .num_parents = 1, diff --git a/drivers/clk/qcom/gpucc-sm6350.c b/drivers/clk/qcom/gpucc-sm6350.c index ee89c42413f8..efbee1518dd3 100644 --- a/drivers/clk/qcom/gpucc-sm6350.c +++ b/drivers/clk/qcom/gpucc-sm6350.c @@ -67,7 +67,7 @@ static struct clk_alpha_pll gpu_cc_pll0 = { .clkr = { .hw.init = &(struct clk_init_data){ .name = "gpu_cc_pll0", - .parent_data = &(const struct clk_parent_data){ + .parent_data = &(const struct clk_parent_data){ .index = DT_BI_TCXO, .fw_name = "bi_tcxo", }, @@ -111,7 +111,7 @@ static struct clk_alpha_pll gpu_cc_pll1 = { .clkr = { .hw.init = &(struct clk_init_data){ .name = "gpu_cc_pll1", - .parent_data = &(const struct clk_parent_data){ + .parent_data = &(const struct clk_parent_data){ .index = DT_BI_TCXO, .fw_name = "bi_tcxo", }, diff --git a/drivers/clk/qcom/gpucc-sm8150.c b/drivers/clk/qcom/gpucc-sm8150.c index 7ce91208c0bc..5701031c17f3 100644 --- a/drivers/clk/qcom/gpucc-sm8150.c +++ b/drivers/clk/qcom/gpucc-sm8150.c @@ -53,7 +53,7 @@ static struct clk_alpha_pll gpu_cc_pll1 = { .clkr = { .hw.init = &(struct clk_init_data){ .name = "gpu_cc_pll1", - .parent_data = &(const struct clk_parent_data){ + .parent_data = &(const struct clk_parent_data){ .fw_name = "bi_tcxo", }, .num_parents = 1, diff --git a/drivers/clk/qcom/gpucc-sm8250.c b/drivers/clk/qcom/gpucc-sm8250.c index ca0a1681d352..eee3208640cd 100644 --- a/drivers/clk/qcom/gpucc-sm8250.c +++ b/drivers/clk/qcom/gpucc-sm8250.c @@ -56,7 +56,7 @@ static struct clk_alpha_pll gpu_cc_pll1 = { .clkr = { .hw.init = &(struct clk_init_data){ .name = "gpu_cc_pll1", - .parent_data = &(const struct clk_parent_data){ + .parent_data = &(const struct clk_parent_data){ .fw_name = "bi_tcxo", }, .num_parents = 1, diff --git a/drivers/clk/qcom/hfpll.c b/drivers/clk/qcom/hfpll.c index b0b0cb074b4a..385964196185 100644 --- a/drivers/clk/qcom/hfpll.c +++ b/drivers/clk/qcom/hfpll.c @@ -99,7 +99,6 @@ static const struct regmap_config hfpll_regmap_config = { .reg_stride = 4, .val_bits = 32, .max_register = 0x30, - .fast_io = true, }; static int qcom_hfpll_probe(struct platform_device *pdev) diff --git a/drivers/clk/qcom/ipq-cmn-pll.c b/drivers/clk/qcom/ipq-cmn-pll.c index b3d7169c63e5..dafbf5732048 100644 --- a/drivers/clk/qcom/ipq-cmn-pll.c +++ b/drivers/clk/qcom/ipq-cmn-pll.c @@ -108,7 +108,6 @@ static const struct regmap_config ipq_cmn_pll_regmap_config = { .reg_stride = 4, .val_bits = 32, .max_register = 0x7fc, - .fast_io = true, }; static const struct cmn_pll_fixed_output_clk ipq5018_output_clks[] = { diff --git a/drivers/clk/qcom/lpassaudiocc-sc7280.c b/drivers/clk/qcom/lpassaudiocc-sc7280.c index 3ff123bffa11..7e2172969289 100644 --- a/drivers/clk/qcom/lpassaudiocc-sc7280.c +++ b/drivers/clk/qcom/lpassaudiocc-sc7280.c @@ -709,8 +709,8 @@ static const struct qcom_cc_desc lpass_audio_cc_sc7280_desc = { }; static const struct qcom_reset_map lpass_audio_cc_sc7280_resets[] = { - [LPASS_AUDIO_SWR_RX_CGCR] = { 0xa0, 1 }, - [LPASS_AUDIO_SWR_TX_CGCR] = { 0xa8, 1 }, + [LPASS_AUDIO_SWR_RX_CGCR] = { 0xa0, 1 }, + [LPASS_AUDIO_SWR_TX_CGCR] = { 0xa8, 1 }, [LPASS_AUDIO_SWR_WSA_CGCR] = { 0xb0, 1 }, }; diff --git a/drivers/clk/qcom/lpasscc-sc8280xp.c b/drivers/clk/qcom/lpasscc-sc8280xp.c index 9fd9498d7dc8..ff839788c40e 100644 --- a/drivers/clk/qcom/lpasscc-sc8280xp.c +++ b/drivers/clk/qcom/lpasscc-sc8280xp.c @@ -18,9 +18,9 @@ #include "reset.h" static const struct qcom_reset_map lpass_audiocc_sc8280xp_resets[] = { - [LPASS_AUDIO_SWR_RX_CGCR] = { 0xa0, 1 }, + [LPASS_AUDIO_SWR_RX_CGCR] = { 0xa0, 1 }, [LPASS_AUDIO_SWR_WSA_CGCR] = { 0xb0, 1 }, - [LPASS_AUDIO_SWR_WSA2_CGCR] = { 0xd8, 1 }, + [LPASS_AUDIO_SWR_WSA2_CGCR] = { 0xd8, 1 }, }; static const struct regmap_config lpass_audiocc_sc8280xp_regmap_config = { diff --git a/drivers/clk/qcom/lpasscc-sm6115.c b/drivers/clk/qcom/lpasscc-sm6115.c index 8ffdab71b948..ac6d219233b4 100644 --- a/drivers/clk/qcom/lpasscc-sm6115.c +++ b/drivers/clk/qcom/lpasscc-sm6115.c @@ -17,7 +17,7 @@ #include "reset.h" static const struct qcom_reset_map lpass_audiocc_sm6115_resets[] = { - [LPASS_AUDIO_SWR_RX_CGCR] = { .reg = 0x98, .bit = 1, .udelay = 500 }, + [LPASS_AUDIO_SWR_RX_CGCR] = { .reg = 0x98, .bit = 1, .udelay = 500 }, }; static struct regmap_config lpass_audiocc_sm6115_regmap_config = { diff --git a/drivers/clk/qcom/lpasscorecc-sc7180.c b/drivers/clk/qcom/lpasscorecc-sc7180.c index 5937b071533b..5174bd3dcdc5 100644 --- a/drivers/clk/qcom/lpasscorecc-sc7180.c +++ b/drivers/clk/qcom/lpasscorecc-sc7180.c @@ -42,7 +42,7 @@ static const struct alpha_pll_config lpass_lpaaudio_dig_pll_config = { }; static const u8 clk_alpha_pll_regs_offset[][PLL_OFF_MAX_REGS] = { - [CLK_ALPHA_PLL_TYPE_FABIA] = { + [CLK_ALPHA_PLL_TYPE_FABIA] = { [PLL_OFF_L_VAL] = 0x04, [PLL_OFF_CAL_L_VAL] = 0x8, [PLL_OFF_USER_CTL] = 0x0c, diff --git a/drivers/clk/qcom/mmcc-sdm660.c b/drivers/clk/qcom/mmcc-sdm660.c index e69fc65b13da..b723c536dfb6 100644 --- a/drivers/clk/qcom/mmcc-sdm660.c +++ b/drivers/clk/qcom/mmcc-sdm660.c @@ -74,7 +74,7 @@ static struct clk_alpha_pll mmpll0 = { }, }; -static struct clk_alpha_pll mmpll6 = { +static struct clk_alpha_pll mmpll6 = { .offset = 0xf0, .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT], .clkr = { diff --git a/drivers/clk/qcom/nsscc-ipq9574.c b/drivers/clk/qcom/nsscc-ipq9574.c index 64c6b05ff066..c8b11b04a7c2 100644 --- a/drivers/clk/qcom/nsscc-ipq9574.c +++ b/drivers/clk/qcom/nsscc-ipq9574.c @@ -3016,7 +3016,7 @@ static const struct qcom_reset_map nss_cc_ipq9574_resets[] = { [NSSPORT4_RESET] = { .reg = 0x28a24, .bitmask = GENMASK(5, 4) }, [NSSPORT5_RESET] = { .reg = 0x28a24, .bitmask = GENMASK(3, 2) }, [NSSPORT6_RESET] = { .reg = 0x28a24, .bitmask = GENMASK(1, 0) }, - [EDMA_HW_RESET] = { .reg = 0x28a08, .bitmask = GENMASK(16, 15) }, + [EDMA_HW_RESET] = { .reg = 0x28a08, .bitmask = GENMASK(16, 15) }, }; static const struct regmap_config nss_cc_ipq9574_regmap_config = { diff --git a/drivers/clk/qcom/tcsrcc-glymur.c b/drivers/clk/qcom/tcsrcc-glymur.c new file mode 100644 index 000000000000..c1f8b6d10b7f --- /dev/null +++ b/drivers/clk/qcom/tcsrcc-glymur.c @@ -0,0 +1,313 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2025, Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#include <linux/clk-provider.h> +#include <linux/mod_devicetable.h> +#include <linux/module.h> +#include <linux/of.h> +#include <linux/platform_device.h> +#include <linux/regmap.h> + +#include <dt-bindings/clock/qcom,glymur-tcsr.h> + +#include "clk-alpha-pll.h" +#include "clk-branch.h" +#include "clk-pll.h" +#include "clk-rcg.h" +#include "clk-regmap.h" +#include "clk-regmap-divider.h" +#include "clk-regmap-mux.h" +#include "common.h" +#include "gdsc.h" +#include "reset.h" + +enum { + DT_BI_TCXO_PAD, +}; + +static struct clk_branch tcsr_edp_clkref_en = { + .halt_reg = 0x1c, + .halt_check = BRANCH_HALT_DELAY, + .clkr = { + .enable_reg = 0x1c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "tcsr_edp_clkref_en", + .parent_data = &(const struct clk_parent_data){ + .index = DT_BI_TCXO_PAD, + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch tcsr_pcie_1_clkref_en = { + .halt_reg = 0x4, + .halt_check = BRANCH_HALT_DELAY, + .clkr = { + .enable_reg = 0x4, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "tcsr_pcie_1_clkref_en", + .parent_data = &(const struct clk_parent_data){ + .index = DT_BI_TCXO_PAD, + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch tcsr_pcie_2_clkref_en = { + .halt_reg = 0x8, + .halt_check = BRANCH_HALT_DELAY, + .clkr = { + .enable_reg = 0x8, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "tcsr_pcie_2_clkref_en", + .parent_data = &(const struct clk_parent_data){ + .index = DT_BI_TCXO_PAD, + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch tcsr_pcie_3_clkref_en = { + .halt_reg = 0x10, + .halt_check = BRANCH_HALT_DELAY, + .clkr = { + .enable_reg = 0x10, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "tcsr_pcie_3_clkref_en", + .parent_data = &(const struct clk_parent_data){ + .index = DT_BI_TCXO_PAD, + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch tcsr_pcie_4_clkref_en = { + .halt_reg = 0x14, + .halt_check = BRANCH_HALT_DELAY, + .clkr = { + .enable_reg = 0x14, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "tcsr_pcie_4_clkref_en", + .parent_data = &(const struct clk_parent_data){ + .index = DT_BI_TCXO_PAD, + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch tcsr_usb2_1_clkref_en = { + .halt_reg = 0x28, + .halt_check = BRANCH_HALT_DELAY, + .clkr = { + .enable_reg = 0x28, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "tcsr_usb2_1_clkref_en", + .parent_data = &(const struct clk_parent_data){ + .index = DT_BI_TCXO_PAD, + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch tcsr_usb2_2_clkref_en = { + .halt_reg = 0x2c, + .halt_check = BRANCH_HALT_DELAY, + .clkr = { + .enable_reg = 0x2c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "tcsr_usb2_2_clkref_en", + .parent_data = &(const struct clk_parent_data){ + .index = DT_BI_TCXO_PAD, + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch tcsr_usb2_3_clkref_en = { + .halt_reg = 0x30, + .halt_check = BRANCH_HALT_DELAY, + .clkr = { + .enable_reg = 0x30, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "tcsr_usb2_3_clkref_en", + .parent_data = &(const struct clk_parent_data){ + .index = DT_BI_TCXO_PAD, + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch tcsr_usb2_4_clkref_en = { + .halt_reg = 0x44, + .halt_check = BRANCH_HALT_DELAY, + .clkr = { + .enable_reg = 0x44, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "tcsr_usb2_4_clkref_en", + .parent_data = &(const struct clk_parent_data){ + .index = DT_BI_TCXO_PAD, + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch tcsr_usb3_0_clkref_en = { + .halt_reg = 0x20, + .halt_check = BRANCH_HALT_DELAY, + .clkr = { + .enable_reg = 0x20, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "tcsr_usb3_0_clkref_en", + .parent_data = &(const struct clk_parent_data){ + .index = DT_BI_TCXO_PAD, + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch tcsr_usb3_1_clkref_en = { + .halt_reg = 0x24, + .halt_check = BRANCH_HALT_DELAY, + .clkr = { + .enable_reg = 0x24, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "tcsr_usb3_1_clkref_en", + .parent_data = &(const struct clk_parent_data){ + .index = DT_BI_TCXO_PAD, + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch tcsr_usb4_1_clkref_en = { + .halt_reg = 0x0, + .halt_check = BRANCH_HALT_DELAY, + .clkr = { + .enable_reg = 0x0, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "tcsr_usb4_1_clkref_en", + .parent_data = &(const struct clk_parent_data){ + .index = DT_BI_TCXO_PAD, + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch tcsr_usb4_2_clkref_en = { + .halt_reg = 0x18, + .halt_check = BRANCH_HALT_DELAY, + .clkr = { + .enable_reg = 0x18, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "tcsr_usb4_2_clkref_en", + .parent_data = &(const struct clk_parent_data){ + .index = DT_BI_TCXO_PAD, + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_regmap *tcsr_cc_glymur_clocks[] = { + [TCSR_EDP_CLKREF_EN] = &tcsr_edp_clkref_en.clkr, + [TCSR_PCIE_1_CLKREF_EN] = &tcsr_pcie_1_clkref_en.clkr, + [TCSR_PCIE_2_CLKREF_EN] = &tcsr_pcie_2_clkref_en.clkr, + [TCSR_PCIE_3_CLKREF_EN] = &tcsr_pcie_3_clkref_en.clkr, + [TCSR_PCIE_4_CLKREF_EN] = &tcsr_pcie_4_clkref_en.clkr, + [TCSR_USB2_1_CLKREF_EN] = &tcsr_usb2_1_clkref_en.clkr, + [TCSR_USB2_2_CLKREF_EN] = &tcsr_usb2_2_clkref_en.clkr, + [TCSR_USB2_3_CLKREF_EN] = &tcsr_usb2_3_clkref_en.clkr, + [TCSR_USB2_4_CLKREF_EN] = &tcsr_usb2_4_clkref_en.clkr, + [TCSR_USB3_0_CLKREF_EN] = &tcsr_usb3_0_clkref_en.clkr, + [TCSR_USB3_1_CLKREF_EN] = &tcsr_usb3_1_clkref_en.clkr, + [TCSR_USB4_1_CLKREF_EN] = &tcsr_usb4_1_clkref_en.clkr, + [TCSR_USB4_2_CLKREF_EN] = &tcsr_usb4_2_clkref_en.clkr, +}; + +static const struct regmap_config tcsr_cc_glymur_regmap_config = { + .reg_bits = 32, + .reg_stride = 4, + .val_bits = 32, + .max_register = 0x44, + .fast_io = true, +}; + +static const struct qcom_cc_desc tcsr_cc_glymur_desc = { + .config = &tcsr_cc_glymur_regmap_config, + .clks = tcsr_cc_glymur_clocks, + .num_clks = ARRAY_SIZE(tcsr_cc_glymur_clocks), +}; + +static const struct of_device_id tcsr_cc_glymur_match_table[] = { + { .compatible = "qcom,glymur-tcsr" }, + { } +}; +MODULE_DEVICE_TABLE(of, tcsr_cc_glymur_match_table); + +static int tcsr_cc_glymur_probe(struct platform_device *pdev) +{ + return qcom_cc_probe(pdev, &tcsr_cc_glymur_desc); +} + +static struct platform_driver tcsr_cc_glymur_driver = { + .probe = tcsr_cc_glymur_probe, + .driver = { + .name = "tcsrcc-glymur", + .of_match_table = tcsr_cc_glymur_match_table, + }, +}; + +static int __init tcsr_cc_glymur_init(void) +{ + return platform_driver_register(&tcsr_cc_glymur_driver); +} +subsys_initcall(tcsr_cc_glymur_init); + +static void __exit tcsr_cc_glymur_exit(void) +{ + platform_driver_unregister(&tcsr_cc_glymur_driver); +} +module_exit(tcsr_cc_glymur_exit); + +MODULE_DESCRIPTION("QTI TCSRCC GLYMUR Driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/clk/qcom/tcsrcc-x1e80100.c b/drivers/clk/qcom/tcsrcc-x1e80100.c index ff61769a0807..a367e1f55622 100644 --- a/drivers/clk/qcom/tcsrcc-x1e80100.c +++ b/drivers/clk/qcom/tcsrcc-x1e80100.c @@ -29,6 +29,10 @@ static struct clk_branch tcsr_edp_clkref_en = { .enable_mask = BIT(0), .hw.init = &(const struct clk_init_data) { .name = "tcsr_edp_clkref_en", + .parent_data = &(const struct clk_parent_data){ + .index = DT_BI_TCXO_PAD, + }, + .num_parents = 1, .ops = &clk_branch2_ops, }, }, diff --git a/drivers/clk/qcom/videocc-milos.c b/drivers/clk/qcom/videocc-milos.c index 998301e0ba88..acc9df295d4f 100644 --- a/drivers/clk/qcom/videocc-milos.c +++ b/drivers/clk/qcom/videocc-milos.c @@ -366,7 +366,7 @@ static struct qcom_cc_driver_data video_cc_milos_driver_data = { .num_clk_cbcrs = ARRAY_SIZE(video_cc_milos_critical_cbcrs), }; -static struct qcom_cc_desc video_cc_milos_desc = { +static const struct qcom_cc_desc video_cc_milos_desc = { .config = &video_cc_milos_regmap_config, .clks = video_cc_milos_clocks, .num_clks = ARRAY_SIZE(video_cc_milos_clocks), diff --git a/drivers/clk/renesas/r9a07g043-cpg.c b/drivers/clk/renesas/r9a07g043-cpg.c index 02dc5cecfd8d..33e9a1223c72 100644 --- a/drivers/clk/renesas/r9a07g043-cpg.c +++ b/drivers/clk/renesas/r9a07g043-cpg.c @@ -164,143 +164,143 @@ static const struct cpg_core_clk r9a07g043_core_clks[] __initconst = { static const struct rzg2l_mod_clk r9a07g043_mod_clks[] = { #ifdef CONFIG_ARM64 DEF_MOD("gic", R9A07G043_GIC600_GICCLK, R9A07G043_CLK_P1, - 0x514, 0, 0), + 0x514, 0, MSTOP(BUS_REG1, BIT(7))), DEF_MOD("ia55_pclk", R9A07G043_IA55_PCLK, R9A07G043_CLK_P2, - 0x518, 0, 0), + 0x518, 0, MSTOP(BUS_PERI_CPU, BIT(13))), DEF_MOD("ia55_clk", R9A07G043_IA55_CLK, R9A07G043_CLK_P1, - 0x518, 1, 0), + 0x518, 1, MSTOP(BUS_PERI_CPU, BIT(13))), #endif #ifdef CONFIG_RISCV DEF_MOD("iax45_pclk", R9A07G043_IAX45_PCLK, R9A07G043_CLK_P2, - 0x518, 0, 0), + 0x518, 0, MSTOP(BUS_PERI_CPU, BIT(13))), DEF_MOD("iax45_clk", R9A07G043_IAX45_CLK, R9A07G043_CLK_P1, - 0x518, 1, 0), + 0x518, 1, MSTOP(BUS_PERI_CPU, BIT(13))), #endif DEF_MOD("dmac_aclk", R9A07G043_DMAC_ACLK, R9A07G043_CLK_P1, - 0x52c, 0, 0), + 0x52c, 0, MSTOP(BUS_REG1, BIT(2))), DEF_MOD("dmac_pclk", R9A07G043_DMAC_PCLK, CLK_P1_DIV2, - 0x52c, 1, 0), + 0x52c, 1, MSTOP(BUS_REG1, BIT(3))), DEF_MOD("ostm0_pclk", R9A07G043_OSTM0_PCLK, R9A07G043_CLK_P0, - 0x534, 0, 0), + 0x534, 0, MSTOP(BUS_REG0, BIT(4))), DEF_MOD("ostm1_pclk", R9A07G043_OSTM1_PCLK, R9A07G043_CLK_P0, - 0x534, 1, 0), + 0x534, 1, MSTOP(BUS_REG0, BIT(5))), DEF_MOD("ostm2_pclk", R9A07G043_OSTM2_PCLK, R9A07G043_CLK_P0, - 0x534, 2, 0), + 0x534, 2, MSTOP(BUS_REG0, BIT(6))), DEF_MOD("mtu_x_mck", R9A07G043_MTU_X_MCK_MTU3, R9A07G043_CLK_P0, - 0x538, 0, 0), + 0x538, 0, MSTOP(BUS_MCPU1, BIT(2))), DEF_MOD("wdt0_pclk", R9A07G043_WDT0_PCLK, R9A07G043_CLK_P0, - 0x548, 0, 0), + 0x548, 0, MSTOP(BUS_REG0, BIT(2))), DEF_MOD("wdt0_clk", R9A07G043_WDT0_CLK, R9A07G043_OSCCLK, - 0x548, 1, 0), + 0x548, 1, MSTOP(BUS_REG0, BIT(2))), DEF_MOD("spi_clk2", R9A07G043_SPI_CLK2, R9A07G043_CLK_SPI1, - 0x550, 0, 0), + 0x550, 0, MSTOP(BUS_MCPU1, BIT(1))), DEF_MOD("spi_clk", R9A07G043_SPI_CLK, R9A07G043_CLK_SPI0, - 0x550, 1, 0), + 0x550, 1, MSTOP(BUS_MCPU1, BIT(1))), DEF_MOD("sdhi0_imclk", R9A07G043_SDHI0_IMCLK, CLK_SD0_DIV4, - 0x554, 0, 0), + 0x554, 0, MSTOP(BUS_PERI_COM, BIT(0))), DEF_MOD("sdhi0_imclk2", R9A07G043_SDHI0_IMCLK2, CLK_SD0_DIV4, - 0x554, 1, 0), + 0x554, 1, MSTOP(BUS_PERI_COM, BIT(0))), DEF_MOD("sdhi0_clk_hs", R9A07G043_SDHI0_CLK_HS, R9A07G043_CLK_SD0, - 0x554, 2, 0), + 0x554, 2, MSTOP(BUS_PERI_COM, BIT(0))), DEF_MOD("sdhi0_aclk", R9A07G043_SDHI0_ACLK, R9A07G043_CLK_P1, - 0x554, 3, 0), + 0x554, 3, MSTOP(BUS_PERI_COM, BIT(0))), DEF_MOD("sdhi1_imclk", R9A07G043_SDHI1_IMCLK, CLK_SD1_DIV4, - 0x554, 4, 0), + 0x554, 4, MSTOP(BUS_PERI_COM, BIT(1))), DEF_MOD("sdhi1_imclk2", R9A07G043_SDHI1_IMCLK2, CLK_SD1_DIV4, - 0x554, 5, 0), + 0x554, 5, MSTOP(BUS_PERI_COM, BIT(1))), DEF_MOD("sdhi1_clk_hs", R9A07G043_SDHI1_CLK_HS, R9A07G043_CLK_SD1, - 0x554, 6, 0), + 0x554, 6, MSTOP(BUS_PERI_COM, BIT(1))), DEF_MOD("sdhi1_aclk", R9A07G043_SDHI1_ACLK, R9A07G043_CLK_P1, - 0x554, 7, 0), + 0x554, 7, MSTOP(BUS_PERI_COM, BIT(1))), #ifdef CONFIG_ARM64 - DEF_MOD("cru_sysclk", R9A07G043_CRU_SYSCLK, CLK_M2_DIV2, - 0x564, 0, 0), - DEF_MOD("cru_vclk", R9A07G043_CRU_VCLK, R9A07G043_CLK_M2, - 0x564, 1, 0), - DEF_MOD("cru_pclk", R9A07G043_CRU_PCLK, R9A07G043_CLK_ZT, - 0x564, 2, 0), - DEF_MOD("cru_aclk", R9A07G043_CRU_ACLK, R9A07G043_CLK_M0, - 0x564, 3, 0), + DEF_MOD("cru_sysclk", R9A07G043_CRU_SYSCLK, CLK_M2_DIV2, + 0x564, 0, MSTOP(BUS_PERI_VIDEO, BIT(3))), + DEF_MOD("cru_vclk", R9A07G043_CRU_VCLK, R9A07G043_CLK_M2, + 0x564, 1, MSTOP(BUS_PERI_VIDEO, BIT(3))), + DEF_MOD("cru_pclk", R9A07G043_CRU_PCLK, R9A07G043_CLK_ZT, + 0x564, 2, MSTOP(BUS_PERI_VIDEO, BIT(3))), + DEF_MOD("cru_aclk", R9A07G043_CRU_ACLK, R9A07G043_CLK_M0, + 0x564, 3, MSTOP(BUS_PERI_VIDEO, BIT(3))), DEF_COUPLED("lcdc_clk_a", R9A07G043_LCDC_CLK_A, R9A07G043_CLK_M0, - 0x56c, 0, 0), + 0x56c, 0, MSTOP(BUS_PERI_VIDEO, GENMASK(8, 7))), DEF_COUPLED("lcdc_clk_p", R9A07G043_LCDC_CLK_P, R9A07G043_CLK_ZT, - 0x56c, 0, 0), + 0x56c, 0, MSTOP(BUS_PERI_VIDEO, GENMASK(8, 7))), DEF_MOD("lcdc_clk_d", R9A07G043_LCDC_CLK_D, R9A07G043_CLK_M3, - 0x56c, 1, 0), + 0x56c, 1, MSTOP(BUS_PERI_VIDEO, BIT(9))), #endif DEF_MOD("ssi0_pclk", R9A07G043_SSI0_PCLK2, R9A07G043_CLK_P0, - 0x570, 0, 0), + 0x570, 0, MSTOP(BUS_MCPU1, BIT(10))), DEF_MOD("ssi0_sfr", R9A07G043_SSI0_PCLK_SFR, R9A07G043_CLK_P0, - 0x570, 1, 0), + 0x570, 1, MSTOP(BUS_MCPU1, BIT(10))), DEF_MOD("ssi1_pclk", R9A07G043_SSI1_PCLK2, R9A07G043_CLK_P0, - 0x570, 2, 0), + 0x570, 2, MSTOP(BUS_MCPU1, BIT(11))), DEF_MOD("ssi1_sfr", R9A07G043_SSI1_PCLK_SFR, R9A07G043_CLK_P0, - 0x570, 3, 0), + 0x570, 3, MSTOP(BUS_MCPU1, BIT(11))), DEF_MOD("ssi2_pclk", R9A07G043_SSI2_PCLK2, R9A07G043_CLK_P0, - 0x570, 4, 0), + 0x570, 4, MSTOP(BUS_MCPU1, BIT(12))), DEF_MOD("ssi2_sfr", R9A07G043_SSI2_PCLK_SFR, R9A07G043_CLK_P0, - 0x570, 5, 0), + 0x570, 5, MSTOP(BUS_MCPU1, BIT(12))), DEF_MOD("ssi3_pclk", R9A07G043_SSI3_PCLK2, R9A07G043_CLK_P0, - 0x570, 6, 0), + 0x570, 6, MSTOP(BUS_MCPU1, BIT(13))), DEF_MOD("ssi3_sfr", R9A07G043_SSI3_PCLK_SFR, R9A07G043_CLK_P0, - 0x570, 7, 0), + 0x570, 7, MSTOP(BUS_MCPU1, BIT(13))), DEF_MOD("usb0_host", R9A07G043_USB_U2H0_HCLK, R9A07G043_CLK_P1, - 0x578, 0, 0), + 0x578, 0, MSTOP(BUS_PERI_COM, BIT(5))), DEF_MOD("usb1_host", R9A07G043_USB_U2H1_HCLK, R9A07G043_CLK_P1, - 0x578, 1, 0), + 0x578, 1, MSTOP(BUS_PERI_COM, BIT(7))), DEF_MOD("usb0_func", R9A07G043_USB_U2P_EXR_CPUCLK, R9A07G043_CLK_P1, - 0x578, 2, 0), + 0x578, 2, MSTOP(BUS_PERI_COM, BIT(6))), DEF_MOD("usb_pclk", R9A07G043_USB_PCLK, R9A07G043_CLK_P1, - 0x578, 3, 0), + 0x578, 3, MSTOP(BUS_PERI_COM, BIT(4))), DEF_COUPLED("eth0_axi", R9A07G043_ETH0_CLK_AXI, R9A07G043_CLK_M0, - 0x57c, 0, 0), + 0x57c, 0, MSTOP(BUS_PERI_COM, BIT(2))), DEF_COUPLED("eth0_chi", R9A07G043_ETH0_CLK_CHI, R9A07G043_CLK_ZT, - 0x57c, 0, 0), + 0x57c, 0, MSTOP(BUS_PERI_COM, BIT(2))), DEF_COUPLED("eth1_axi", R9A07G043_ETH1_CLK_AXI, R9A07G043_CLK_M0, - 0x57c, 1, 0), + 0x57c, 1, MSTOP(BUS_PERI_COM, BIT(3))), DEF_COUPLED("eth1_chi", R9A07G043_ETH1_CLK_CHI, R9A07G043_CLK_ZT, - 0x57c, 1, 0), + 0x57c, 1, MSTOP(BUS_PERI_COM, BIT(3))), DEF_MOD("i2c0", R9A07G043_I2C0_PCLK, R9A07G043_CLK_P0, - 0x580, 0, 0), + 0x580, 0, MSTOP(BUS_MCPU2, BIT(10))), DEF_MOD("i2c1", R9A07G043_I2C1_PCLK, R9A07G043_CLK_P0, - 0x580, 1, 0), + 0x580, 1, MSTOP(BUS_MCPU2, BIT(11))), DEF_MOD("i2c2", R9A07G043_I2C2_PCLK, R9A07G043_CLK_P0, - 0x580, 2, 0), + 0x580, 2, MSTOP(BUS_MCPU2, BIT(12))), DEF_MOD("i2c3", R9A07G043_I2C3_PCLK, R9A07G043_CLK_P0, - 0x580, 3, 0), + 0x580, 3, MSTOP(BUS_MCPU2, BIT(13))), DEF_MOD("scif0", R9A07G043_SCIF0_CLK_PCK, R9A07G043_CLK_P0, - 0x584, 0, 0), + 0x584, 0, MSTOP(BUS_MCPU2, BIT(1))), DEF_MOD("scif1", R9A07G043_SCIF1_CLK_PCK, R9A07G043_CLK_P0, - 0x584, 1, 0), + 0x584, 1, MSTOP(BUS_MCPU2, BIT(2))), DEF_MOD("scif2", R9A07G043_SCIF2_CLK_PCK, R9A07G043_CLK_P0, - 0x584, 2, 0), + 0x584, 2, MSTOP(BUS_MCPU2, BIT(3))), DEF_MOD("scif3", R9A07G043_SCIF3_CLK_PCK, R9A07G043_CLK_P0, - 0x584, 3, 0), + 0x584, 3, MSTOP(BUS_MCPU2, BIT(4))), DEF_MOD("scif4", R9A07G043_SCIF4_CLK_PCK, R9A07G043_CLK_P0, - 0x584, 4, 0), + 0x584, 4, MSTOP(BUS_MCPU2, BIT(5))), DEF_MOD("sci0", R9A07G043_SCI0_CLKP, R9A07G043_CLK_P0, - 0x588, 0, 0), + 0x588, 0, MSTOP(BUS_MCPU2, BIT(7))), DEF_MOD("sci1", R9A07G043_SCI1_CLKP, R9A07G043_CLK_P0, - 0x588, 1, 0), + 0x588, 1, MSTOP(BUS_MCPU2, BIT(8))), DEF_MOD("rspi0", R9A07G043_RSPI0_CLKB, R9A07G043_CLK_P0, - 0x590, 0, 0), + 0x590, 0, MSTOP(BUS_MCPU1, BIT(14))), DEF_MOD("rspi1", R9A07G043_RSPI1_CLKB, R9A07G043_CLK_P0, - 0x590, 1, 0), + 0x590, 1, MSTOP(BUS_MCPU1, BIT(15))), DEF_MOD("rspi2", R9A07G043_RSPI2_CLKB, R9A07G043_CLK_P0, - 0x590, 2, 0), + 0x590, 2, MSTOP(BUS_MCPU2, BIT(0))), DEF_MOD("canfd", R9A07G043_CANFD_PCLK, R9A07G043_CLK_P0, - 0x594, 0, 0), + 0x594, 0, MSTOP(BUS_MCPU2, BIT(9))), DEF_MOD("gpio", R9A07G043_GPIO_HCLK, R9A07G043_OSCCLK, - 0x598, 0, 0), + 0x598, 0, MSTOP(BUS_PERI_CPU, BIT(6))), DEF_MOD("adc_adclk", R9A07G043_ADC_ADCLK, R9A07G043_CLK_TSU, - 0x5a8, 0, 0), + 0x5a8, 0, MSTOP(BUS_MCPU2, BIT(14))), DEF_MOD("adc_pclk", R9A07G043_ADC_PCLK, R9A07G043_CLK_P0, - 0x5a8, 1, 0), + 0x5a8, 1, MSTOP(BUS_MCPU2, BIT(14))), DEF_MOD("tsu_pclk", R9A07G043_TSU_PCLK, R9A07G043_CLK_TSU, - 0x5ac, 0, 0), + 0x5ac, 0, MSTOP(BUS_MCPU2, BIT(15))), #ifdef CONFIG_RISCV DEF_MOD("nceplic_aclk", R9A07G043_NCEPLIC_ACLK, R9A07G043_CLK_P1, - 0x608, 0, 0), + 0x608, 0, MSTOP(BUS_REG1, BIT(7))), #endif }; diff --git a/drivers/clk/renesas/r9a07g044-cpg.c b/drivers/clk/renesas/r9a07g044-cpg.c index c851d4eeebbe..0dd264877b9a 100644 --- a/drivers/clk/renesas/r9a07g044-cpg.c +++ b/drivers/clk/renesas/r9a07g044-cpg.c @@ -242,163 +242,163 @@ static const struct { } mod_clks = { .common = { DEF_MOD("gic", R9A07G044_GIC600_GICCLK, R9A07G044_CLK_P1, - 0x514, 0, 0), + 0x514, 0, MSTOP(BUS_REG1, BIT(7))), DEF_MOD("ia55_pclk", R9A07G044_IA55_PCLK, R9A07G044_CLK_P2, - 0x518, 0, 0), + 0x518, 0, MSTOP(BUS_PERI_CPU, BIT(13))), DEF_MOD("ia55_clk", R9A07G044_IA55_CLK, R9A07G044_CLK_P1, - 0x518, 1, 0), + 0x518, 1, MSTOP(BUS_PERI_CPU, BIT(13))), DEF_MOD("dmac_aclk", R9A07G044_DMAC_ACLK, R9A07G044_CLK_P1, - 0x52c, 0, 0), + 0x52c, 0, MSTOP(BUS_REG1, BIT(2))), DEF_MOD("dmac_pclk", R9A07G044_DMAC_PCLK, CLK_P1_DIV2, - 0x52c, 1, 0), + 0x52c, 1, MSTOP(BUS_REG1, BIT(3))), DEF_MOD("ostm0_pclk", R9A07G044_OSTM0_PCLK, R9A07G044_CLK_P0, - 0x534, 0, 0), + 0x534, 0, MSTOP(BUS_REG0, BIT(4))), DEF_MOD("ostm1_pclk", R9A07G044_OSTM1_PCLK, R9A07G044_CLK_P0, - 0x534, 1, 0), + 0x534, 1, MSTOP(BUS_REG0, BIT(5))), DEF_MOD("ostm2_pclk", R9A07G044_OSTM2_PCLK, R9A07G044_CLK_P0, - 0x534, 2, 0), + 0x534, 2, MSTOP(BUS_REG0, BIT(6))), DEF_MOD("mtu_x_mck", R9A07G044_MTU_X_MCK_MTU3, R9A07G044_CLK_P0, - 0x538, 0, 0), + 0x538, 0, MSTOP(BUS_MCPU1, BIT(2))), DEF_MOD("gpt_pclk", R9A07G044_GPT_PCLK, R9A07G044_CLK_P0, - 0x540, 0, 0), + 0x540, 0, MSTOP(BUS_MCPU1, BIT(4))), DEF_MOD("poeg_a_clkp", R9A07G044_POEG_A_CLKP, R9A07G044_CLK_P0, - 0x544, 0, 0), + 0x544, 0, MSTOP(BUS_MCPU1, BIT(5))), DEF_MOD("poeg_b_clkp", R9A07G044_POEG_B_CLKP, R9A07G044_CLK_P0, - 0x544, 1, 0), + 0x544, 1, MSTOP(BUS_MCPU1, BIT(6))), DEF_MOD("poeg_c_clkp", R9A07G044_POEG_C_CLKP, R9A07G044_CLK_P0, - 0x544, 2, 0), + 0x544, 2, MSTOP(BUS_MCPU1, BIT(7))), DEF_MOD("poeg_d_clkp", R9A07G044_POEG_D_CLKP, R9A07G044_CLK_P0, - 0x544, 3, 0), + 0x544, 3, MSTOP(BUS_MCPU1, BIT(8))), DEF_MOD("wdt0_pclk", R9A07G044_WDT0_PCLK, R9A07G044_CLK_P0, - 0x548, 0, 0), + 0x548, 0, MSTOP(BUS_REG0, BIT(2))), DEF_MOD("wdt0_clk", R9A07G044_WDT0_CLK, R9A07G044_OSCCLK, - 0x548, 1, 0), + 0x548, 1, MSTOP(BUS_REG0, BIT(2))), DEF_MOD("wdt1_pclk", R9A07G044_WDT1_PCLK, R9A07G044_CLK_P0, - 0x548, 2, 0), + 0x548, 2, MSTOP(BUS_REG0, BIT(3))), DEF_MOD("wdt1_clk", R9A07G044_WDT1_CLK, R9A07G044_OSCCLK, - 0x548, 3, 0), + 0x548, 3, MSTOP(BUS_REG0, BIT(3))), DEF_MOD("spi_clk2", R9A07G044_SPI_CLK2, R9A07G044_CLK_SPI1, - 0x550, 0, 0), + 0x550, 0, MSTOP(BUS_MCPU1, BIT(1))), DEF_MOD("spi_clk", R9A07G044_SPI_CLK, R9A07G044_CLK_SPI0, - 0x550, 1, 0), + 0x550, 1, MSTOP(BUS_MCPU1, BIT(1))), DEF_MOD("sdhi0_imclk", R9A07G044_SDHI0_IMCLK, CLK_SD0_DIV4, - 0x554, 0, 0), + 0x554, 0, MSTOP(BUS_PERI_COM, BIT(0))), DEF_MOD("sdhi0_imclk2", R9A07G044_SDHI0_IMCLK2, CLK_SD0_DIV4, - 0x554, 1, 0), + 0x554, 1, MSTOP(BUS_PERI_COM, BIT(0))), DEF_MOD("sdhi0_clk_hs", R9A07G044_SDHI0_CLK_HS, R9A07G044_CLK_SD0, - 0x554, 2, 0), + 0x554, 2, MSTOP(BUS_PERI_COM, BIT(0))), DEF_MOD("sdhi0_aclk", R9A07G044_SDHI0_ACLK, R9A07G044_CLK_P1, - 0x554, 3, 0), + 0x554, 3, MSTOP(BUS_PERI_COM, BIT(0))), DEF_MOD("sdhi1_imclk", R9A07G044_SDHI1_IMCLK, CLK_SD1_DIV4, - 0x554, 4, 0), + 0x554, 4, MSTOP(BUS_PERI_COM, BIT(1))), DEF_MOD("sdhi1_imclk2", R9A07G044_SDHI1_IMCLK2, CLK_SD1_DIV4, - 0x554, 5, 0), + 0x554, 5, MSTOP(BUS_PERI_COM, BIT(1))), DEF_MOD("sdhi1_clk_hs", R9A07G044_SDHI1_CLK_HS, R9A07G044_CLK_SD1, - 0x554, 6, 0), + 0x554, 6, MSTOP(BUS_PERI_COM, BIT(1))), DEF_MOD("sdhi1_aclk", R9A07G044_SDHI1_ACLK, R9A07G044_CLK_P1, - 0x554, 7, 0), + 0x554, 7, MSTOP(BUS_PERI_COM, BIT(1))), DEF_MOD("gpu_clk", R9A07G044_GPU_CLK, R9A07G044_CLK_G, - 0x558, 0, 0), + 0x558, 0, MSTOP(BUS_REG1, BIT(4))), DEF_MOD("gpu_axi_clk", R9A07G044_GPU_AXI_CLK, R9A07G044_CLK_P1, 0x558, 1, 0), DEF_MOD("gpu_ace_clk", R9A07G044_GPU_ACE_CLK, R9A07G044_CLK_P1, 0x558, 2, 0), - DEF_MOD("cru_sysclk", R9A07G044_CRU_SYSCLK, CLK_M2_DIV2, - 0x564, 0, 0), - DEF_MOD("cru_vclk", R9A07G044_CRU_VCLK, R9A07G044_CLK_M2, - 0x564, 1, 0), - DEF_MOD("cru_pclk", R9A07G044_CRU_PCLK, R9A07G044_CLK_ZT, - 0x564, 2, 0), - DEF_MOD("cru_aclk", R9A07G044_CRU_ACLK, R9A07G044_CLK_M0, - 0x564, 3, 0), + DEF_MOD("cru_sysclk", R9A07G044_CRU_SYSCLK, CLK_M2_DIV2, + 0x564, 0, MSTOP(BUS_PERI_VIDEO, BIT(3))), + DEF_MOD("cru_vclk", R9A07G044_CRU_VCLK, R9A07G044_CLK_M2, + 0x564, 1, MSTOP(BUS_PERI_VIDEO, BIT(3))), + DEF_MOD("cru_pclk", R9A07G044_CRU_PCLK, R9A07G044_CLK_ZT, + 0x564, 2, MSTOP(BUS_PERI_VIDEO, BIT(3))), + DEF_MOD("cru_aclk", R9A07G044_CRU_ACLK, R9A07G044_CLK_M0, + 0x564, 3, MSTOP(BUS_PERI_VIDEO, BIT(3))), DEF_MOD("dsi_pll_clk", R9A07G044_MIPI_DSI_PLLCLK, R9A07G044_CLK_M1, - 0x568, 0, 0), + 0x568, 0, MSTOP(BUS_PERI_VIDEO, GENMASK(6, 5))), DEF_MOD("dsi_sys_clk", R9A07G044_MIPI_DSI_SYSCLK, CLK_M2_DIV2, - 0x568, 1, 0), + 0x568, 1, MSTOP(BUS_PERI_VIDEO, GENMASK(6, 5))), DEF_MOD("dsi_aclk", R9A07G044_MIPI_DSI_ACLK, R9A07G044_CLK_P1, - 0x568, 2, 0), + 0x568, 2, MSTOP(BUS_PERI_VIDEO, GENMASK(6, 5))), DEF_MOD("dsi_pclk", R9A07G044_MIPI_DSI_PCLK, R9A07G044_CLK_P2, - 0x568, 3, 0), + 0x568, 3, MSTOP(BUS_PERI_VIDEO, GENMASK(6, 5))), DEF_MOD("dsi_vclk", R9A07G044_MIPI_DSI_VCLK, R9A07G044_CLK_M3, - 0x568, 4, 0), + 0x568, 4, MSTOP(BUS_PERI_VIDEO, GENMASK(6, 5))), DEF_MOD("dsi_lpclk", R9A07G044_MIPI_DSI_LPCLK, R9A07G044_CLK_M4, - 0x568, 5, 0), + 0x568, 5, MSTOP(BUS_PERI_VIDEO, GENMASK(6, 5))), DEF_COUPLED("lcdc_a", R9A07G044_LCDC_CLK_A, R9A07G044_CLK_M0, - 0x56c, 0, 0), + 0x56c, 0, MSTOP(BUS_PERI_VIDEO, GENMASK(8, 7))), DEF_COUPLED("lcdc_p", R9A07G044_LCDC_CLK_P, R9A07G044_CLK_ZT, - 0x56c, 0, 0), + 0x56c, 0, MSTOP(BUS_PERI_VIDEO, GENMASK(8, 7))), DEF_MOD("lcdc_clk_d", R9A07G044_LCDC_CLK_D, R9A07G044_CLK_M3, - 0x56c, 1, 0), + 0x56c, 1, MSTOP(BUS_PERI_VIDEO, BIT(9))), DEF_MOD("ssi0_pclk", R9A07G044_SSI0_PCLK2, R9A07G044_CLK_P0, - 0x570, 0, 0), + 0x570, 0, MSTOP(BUS_MCPU1, BIT(10))), DEF_MOD("ssi0_sfr", R9A07G044_SSI0_PCLK_SFR, R9A07G044_CLK_P0, - 0x570, 1, 0), + 0x570, 1, MSTOP(BUS_MCPU1, BIT(10))), DEF_MOD("ssi1_pclk", R9A07G044_SSI1_PCLK2, R9A07G044_CLK_P0, - 0x570, 2, 0), + 0x570, 2, MSTOP(BUS_MCPU1, BIT(11))), DEF_MOD("ssi1_sfr", R9A07G044_SSI1_PCLK_SFR, R9A07G044_CLK_P0, - 0x570, 3, 0), + 0x570, 3, MSTOP(BUS_MCPU1, BIT(11))), DEF_MOD("ssi2_pclk", R9A07G044_SSI2_PCLK2, R9A07G044_CLK_P0, - 0x570, 4, 0), + 0x570, 4, MSTOP(BUS_MCPU1, BIT(12))), DEF_MOD("ssi2_sfr", R9A07G044_SSI2_PCLK_SFR, R9A07G044_CLK_P0, - 0x570, 5, 0), + 0x570, 5, MSTOP(BUS_MCPU1, BIT(12))), DEF_MOD("ssi3_pclk", R9A07G044_SSI3_PCLK2, R9A07G044_CLK_P0, - 0x570, 6, 0), + 0x570, 6, MSTOP(BUS_MCPU1, BIT(13))), DEF_MOD("ssi3_sfr", R9A07G044_SSI3_PCLK_SFR, R9A07G044_CLK_P0, - 0x570, 7, 0), + 0x570, 7, MSTOP(BUS_MCPU1, BIT(13))), DEF_MOD("usb0_host", R9A07G044_USB_U2H0_HCLK, R9A07G044_CLK_P1, - 0x578, 0, 0), + 0x578, 0, MSTOP(BUS_PERI_COM, BIT(5))), DEF_MOD("usb1_host", R9A07G044_USB_U2H1_HCLK, R9A07G044_CLK_P1, - 0x578, 1, 0), + 0x578, 1, MSTOP(BUS_PERI_COM, BIT(7))), DEF_MOD("usb0_func", R9A07G044_USB_U2P_EXR_CPUCLK, R9A07G044_CLK_P1, - 0x578, 2, 0), + 0x578, 2, MSTOP(BUS_PERI_COM, BIT(6))), DEF_MOD("usb_pclk", R9A07G044_USB_PCLK, R9A07G044_CLK_P1, - 0x578, 3, 0), + 0x578, 3, MSTOP(BUS_PERI_COM, BIT(4))), DEF_COUPLED("eth0_axi", R9A07G044_ETH0_CLK_AXI, R9A07G044_CLK_M0, - 0x57c, 0, 0), + 0x57c, 0, MSTOP(BUS_PERI_COM, BIT(2))), DEF_COUPLED("eth0_chi", R9A07G044_ETH0_CLK_CHI, R9A07G044_CLK_ZT, - 0x57c, 0, 0), + 0x57c, 0, MSTOP(BUS_PERI_COM, BIT(2))), DEF_COUPLED("eth1_axi", R9A07G044_ETH1_CLK_AXI, R9A07G044_CLK_M0, - 0x57c, 1, 0), + 0x57c, 1, MSTOP(BUS_PERI_COM, BIT(3))), DEF_COUPLED("eth1_chi", R9A07G044_ETH1_CLK_CHI, R9A07G044_CLK_ZT, - 0x57c, 1, 0), + 0x57c, 1, MSTOP(BUS_PERI_COM, BIT(3))), DEF_MOD("i2c0", R9A07G044_I2C0_PCLK, R9A07G044_CLK_P0, - 0x580, 0, 0), + 0x580, 0, MSTOP(BUS_MCPU2, BIT(10))), DEF_MOD("i2c1", R9A07G044_I2C1_PCLK, R9A07G044_CLK_P0, - 0x580, 1, 0), + 0x580, 1, MSTOP(BUS_MCPU2, BIT(11))), DEF_MOD("i2c2", R9A07G044_I2C2_PCLK, R9A07G044_CLK_P0, - 0x580, 2, 0), + 0x580, 2, MSTOP(BUS_MCPU2, BIT(12))), DEF_MOD("i2c3", R9A07G044_I2C3_PCLK, R9A07G044_CLK_P0, - 0x580, 3, 0), + 0x580, 3, MSTOP(BUS_MCPU2, BIT(13))), DEF_MOD("scif0", R9A07G044_SCIF0_CLK_PCK, R9A07G044_CLK_P0, - 0x584, 0, 0), + 0x584, 0, MSTOP(BUS_MCPU2, BIT(1))), DEF_MOD("scif1", R9A07G044_SCIF1_CLK_PCK, R9A07G044_CLK_P0, - 0x584, 1, 0), + 0x584, 1, MSTOP(BUS_MCPU2, BIT(2))), DEF_MOD("scif2", R9A07G044_SCIF2_CLK_PCK, R9A07G044_CLK_P0, - 0x584, 2, 0), + 0x584, 2, MSTOP(BUS_MCPU2, BIT(3))), DEF_MOD("scif3", R9A07G044_SCIF3_CLK_PCK, R9A07G044_CLK_P0, - 0x584, 3, 0), + 0x584, 3, MSTOP(BUS_MCPU2, BIT(4))), DEF_MOD("scif4", R9A07G044_SCIF4_CLK_PCK, R9A07G044_CLK_P0, - 0x584, 4, 0), + 0x584, 4, MSTOP(BUS_MCPU2, BIT(5))), DEF_MOD("sci0", R9A07G044_SCI0_CLKP, R9A07G044_CLK_P0, - 0x588, 0, 0), + 0x588, 0, MSTOP(BUS_MCPU2, BIT(7))), DEF_MOD("sci1", R9A07G044_SCI1_CLKP, R9A07G044_CLK_P0, - 0x588, 1, 0), + 0x588, 1, MSTOP(BUS_MCPU2, BIT(8))), DEF_MOD("rspi0", R9A07G044_RSPI0_CLKB, R9A07G044_CLK_P0, - 0x590, 0, 0), + 0x590, 0, MSTOP(BUS_MCPU1, BIT(14))), DEF_MOD("rspi1", R9A07G044_RSPI1_CLKB, R9A07G044_CLK_P0, - 0x590, 1, 0), + 0x590, 1, MSTOP(BUS_MCPU1, BIT(15))), DEF_MOD("rspi2", R9A07G044_RSPI2_CLKB, R9A07G044_CLK_P0, - 0x590, 2, 0), + 0x590, 2, MSTOP(BUS_MCPU2, BIT(0))), DEF_MOD("canfd", R9A07G044_CANFD_PCLK, R9A07G044_CLK_P0, - 0x594, 0, 0), + 0x594, 0, MSTOP(BUS_MCPU2, BIT(9))), DEF_MOD("gpio", R9A07G044_GPIO_HCLK, R9A07G044_OSCCLK, - 0x598, 0, 0), + 0x598, 0, MSTOP(BUS_PERI_CPU, BIT(6))), DEF_MOD("adc_adclk", R9A07G044_ADC_ADCLK, R9A07G044_CLK_TSU, - 0x5a8, 0, 0), + 0x5a8, 0, MSTOP(BUS_MCPU2, BIT(14))), DEF_MOD("adc_pclk", R9A07G044_ADC_PCLK, R9A07G044_CLK_P0, - 0x5a8, 1, 0), + 0x5a8, 1, MSTOP(BUS_MCPU2, BIT(14))), DEF_MOD("tsu_pclk", R9A07G044_TSU_PCLK, R9A07G044_CLK_TSU, - 0x5ac, 0, 0), + 0x5ac, 0, MSTOP(BUS_MCPU2, BIT(15))), }, #ifdef CONFIG_CLK_R9A07G054 .drp = { diff --git a/drivers/clk/renesas/r9a08g045-cpg.c b/drivers/clk/renesas/r9a08g045-cpg.c index ed0661997928..79e7b19c7882 100644 --- a/drivers/clk/renesas/r9a08g045-cpg.c +++ b/drivers/clk/renesas/r9a08g045-cpg.c @@ -183,6 +183,7 @@ static const struct cpg_core_clk r9a08g045_core_clks[] __initconst = { DEF_G3S_DIV("P3", R9A08G045_CLK_P3, CLK_PLL3_DIV2_4, DIVPL3C, G3S_DIVPL3C_STS, dtable_1_32, 0, 0, 0, NULL), DEF_FIXED("P3_DIV2", CLK_P3_DIV2, R9A08G045_CLK_P3, 1, 2), + DEF_FIXED("P5", R9A08G045_CLK_P5, CLK_PLL2_DIV2, 1, 4), DEF_FIXED("ZT", R9A08G045_CLK_ZT, CLK_PLL3_DIV2_8, 1, 1), DEF_FIXED("S0", R9A08G045_CLK_S0, CLK_SEL_PLL4, 1, 2), DEF_FIXED("OSC", R9A08G045_OSCCLK, CLK_EXTAL, 1, 1), @@ -284,13 +285,22 @@ static const struct rzg2l_mod_clk r9a08g045_mod_clks[] = { MSTOP(BUS_MCPU2, BIT(5))), DEF_MOD("scif5_clk_pck", R9A08G045_SCIF5_CLK_PCK, R9A08G045_CLK_P0, 0x584, 5, MSTOP(BUS_MCPU3, BIT(4))), - DEF_MOD("gpio_hclk", R9A08G045_GPIO_HCLK, R9A08G045_OSCCLK, 0x598, 0, 0), + DEF_MOD("gpio_hclk", R9A08G045_GPIO_HCLK, R9A08G045_OSCCLK, 0x598, 0, + MSTOP(BUS_PERI_CPU, BIT(6))), DEF_MOD("adc_adclk", R9A08G045_ADC_ADCLK, R9A08G045_CLK_TSU, 0x5a8, 0, MSTOP(BUS_MCPU2, BIT(14))), DEF_MOD("adc_pclk", R9A08G045_ADC_PCLK, R9A08G045_CLK_TSU, 0x5a8, 1, MSTOP(BUS_MCPU2, BIT(14))), DEF_MOD("tsu_pclk", R9A08G045_TSU_PCLK, R9A08G045_CLK_TSU, 0x5ac, 0, MSTOP(BUS_MCPU2, BIT(15))), + DEF_MOD("pci_aclk", R9A08G045_PCI_ACLK, R9A08G045_CLK_M0, 0x608, 0, + MSTOP(BUS_PERI_COM, BIT(10))), + DEF_MOD("pci_clkl1pm", R9A08G045_PCI_CLKL1PM, R9A08G045_CLK_ZT, 0x608, 1, + MSTOP(BUS_PERI_COM, BIT(10))), + DEF_MOD("i3c_pclk", R9A08G045_I3C_PCLK, R9A08G045_CLK_TSU, 0x610, 0, + MSTOP(BUS_MCPU3, BIT(10))), + DEF_MOD("i3c_tclk", R9A08G045_I3C_TCLK, R9A08G045_CLK_P5, 0x610, 1, + MSTOP(BUS_MCPU3, BIT(10))), DEF_MOD("vbat_bclk", R9A08G045_VBAT_BCLK, R9A08G045_OSCCLK, 0x614, 0, MSTOP(BUS_MCPU3, GENMASK(8, 7))), }; @@ -331,6 +341,15 @@ static const struct rzg2l_reset r9a08g045_resets[] = { DEF_RST(R9A08G045_ADC_PRESETN, 0x8a8, 0), DEF_RST(R9A08G045_ADC_ADRST_N, 0x8a8, 1), DEF_RST(R9A08G045_TSU_PRESETN, 0x8ac, 0), + DEF_RST(R9A08G045_PCI_ARESETN, 0x908, 0), + DEF_RST(R9A08G045_PCI_RST_B, 0x908, 1), + DEF_RST(R9A08G045_PCI_RST_GP_B, 0x908, 2), + DEF_RST(R9A08G045_PCI_RST_PS_B, 0x908, 3), + DEF_RST(R9A08G045_PCI_RST_RSM_B, 0x908, 4), + DEF_RST(R9A08G045_PCI_RST_CFG_B, 0x908, 5), + DEF_RST(R9A08G045_PCI_RST_LOAD_B, 0x908, 6), + DEF_RST(R9A08G045_I3C_TRESETN, 0x910, 0), + DEF_RST(R9A08G045_I3C_PRESETN, 0x910, 1), DEF_RST(R9A08G045_VBAT_BRESETN, 0x914, 0), }; @@ -342,6 +361,10 @@ static const unsigned int r9a08g045_crit_mod_clks[] __initconst = { MOD_CLK_BASE + R9A08G045_VBAT_BCLK, }; +static const unsigned int r9a08g045_no_pm_mod_clks[] = { + MOD_CLK_BASE + R9A08G045_PCI_CLKL1PM, +}; + const struct rzg2l_cpg_info r9a08g045_cpg_info = { /* Core Clocks */ .core_clks = r9a08g045_core_clks, @@ -358,6 +381,10 @@ const struct rzg2l_cpg_info r9a08g045_cpg_info = { .num_mod_clks = ARRAY_SIZE(r9a08g045_mod_clks), .num_hw_mod_clks = R9A08G045_VBAT_BCLK + 1, + /* No PM modules Clocks */ + .no_pm_mod_clks = r9a08g045_no_pm_mod_clks, + .num_no_pm_mod_clks = ARRAY_SIZE(r9a08g045_no_pm_mod_clks), + /* Resets */ .resets = r9a08g045_resets, .num_resets = R9A08G045_VBAT_BRESETN + 1, /* Last reset ID + 1 */ diff --git a/drivers/clk/renesas/r9a09g047-cpg.c b/drivers/clk/renesas/r9a09g047-cpg.c index 26e2be7667eb..ef115f9ec0e6 100644 --- a/drivers/clk/renesas/r9a09g047-cpg.c +++ b/drivers/clk/renesas/r9a09g047-cpg.c @@ -16,7 +16,7 @@ enum clk_ids { /* Core Clock Outputs exported to DT */ - LAST_DT_CORE_CLK = R9A09G047_GBETH_1_CLK_PTP_REF_I, + LAST_DT_CORE_CLK = R9A09G047_USB3_0_CLKCORE, /* External Input Clocks */ CLK_AUDIO_EXTAL, @@ -48,6 +48,8 @@ enum clk_ids { CLK_PLLDTY_ACPU_DIV2, CLK_PLLDTY_ACPU_DIV4, CLK_PLLDTY_DIV8, + CLK_PLLDTY_RCPU, + CLK_PLLDTY_RCPU_DIV4, CLK_PLLETH_DIV_250_FIX, CLK_PLLETH_DIV_125_FIX, CLK_CSDIV_PLLETH_GBE0, @@ -157,6 +159,8 @@ static const struct cpg_core_clk r9a09g047_core_clks[] __initconst = { DEF_SMUX(".smux2_gbe1_txclk", CLK_SMUX2_GBE1_TXCLK, SSEL1_SELCTL0, smux2_gbe1_txclk), DEF_SMUX(".smux2_gbe1_rxclk", CLK_SMUX2_GBE1_RXCLK, SSEL1_SELCTL1, smux2_gbe1_rxclk), DEF_FIXED(".plldty_div16", CLK_PLLDTY_DIV16, CLK_PLLDTY, 1, 16), + DEF_DDIV(".plldty_rcpu", CLK_PLLDTY_RCPU, CLK_PLLDTY, CDDIV3_DIVCTL2, dtable_2_64), + DEF_FIXED(".plldty_rcpu_div4", CLK_PLLDTY_RCPU_DIV4, CLK_PLLDTY_RCPU, 1, 4), DEF_DDIV(".pllvdo_cru0", CLK_PLLVDO_CRU0, CLK_PLLVDO, CDDIV3_DIVCTL3, dtable_2_4), DEF_DDIV(".pllvdo_gpu", CLK_PLLVDO_GPU, CLK_PLLVDO, CDDIV3_DIVCTL1, dtable_2_64), @@ -177,13 +181,29 @@ static const struct cpg_core_clk r9a09g047_core_clks[] __initconst = { CLK_PLLETH_DIV_125_FIX, 1, 1), DEF_FIXED("gbeth_1_clk_ptp_ref_i", R9A09G047_GBETH_1_CLK_PTP_REF_I, CLK_PLLETH_DIV_125_FIX, 1, 1), + DEF_FIXED("usb3_0_ref_alt_clk_p", R9A09G047_USB3_0_REF_ALT_CLK_P, CLK_QEXTAL, 1, 1), + DEF_FIXED("usb3_0_core_clk", R9A09G047_USB3_0_CLKCORE, CLK_QEXTAL, 1, 1), }; static const struct rzv2h_mod_clk r9a09g047_mod_clks[] __initconst = { + DEF_MOD("dmac_0_aclk", CLK_PLLCM33_GEAR, 0, 0, 0, 0, + BUS_MSTOP(5, BIT(9))), + DEF_MOD("dmac_1_aclk", CLK_PLLDTY_ACPU_DIV2, 0, 1, 0, 1, + BUS_MSTOP(3, BIT(2))), + DEF_MOD("dmac_2_aclk", CLK_PLLDTY_ACPU_DIV2, 0, 2, 0, 2, + BUS_MSTOP(3, BIT(3))), + DEF_MOD("dmac_3_aclk", CLK_PLLDTY_RCPU_DIV4, 0, 3, 0, 3, + BUS_MSTOP(10, BIT(11))), + DEF_MOD("dmac_4_aclk", CLK_PLLDTY_RCPU_DIV4, 0, 4, 0, 4, + BUS_MSTOP(10, BIT(12))), DEF_MOD_CRITICAL("icu_0_pclk_i", CLK_PLLCM33_DIV16, 0, 5, 0, 5, BUS_MSTOP_NONE), DEF_MOD_CRITICAL("gic_0_gicclk", CLK_PLLDTY_ACPU_DIV4, 1, 3, 0, 19, BUS_MSTOP(3, BIT(5))), + DEF_MOD("gpt_0_pclk_sfr", CLK_PLLCLN_DIV8, 3, 1, 1, 17, + BUS_MSTOP(6, BIT(11))), + DEF_MOD("gpt_1_pclk_sfr", CLK_PLLCLN_DIV8, 3, 2, 1, 18, + BUS_MSTOP(6, BIT(12))), DEF_MOD("wdt_1_clkp", CLK_PLLCLN_DIV16, 4, 13, 2, 13, BUS_MSTOP(1, BIT(0))), DEF_MOD("wdt_1_clk_loco", CLK_QEXTAL, 4, 14, 2, 14, @@ -258,6 +278,10 @@ static const struct rzv2h_mod_clk r9a09g047_mod_clks[] __initconst = { BUS_MSTOP(8, BIT(4))), DEF_MOD("sdhi_2_aclk", CLK_PLLDTY_ACPU_DIV4, 10, 14, 5, 14, BUS_MSTOP(8, BIT(4))), + DEF_MOD("usb3_0_aclk", CLK_PLLDTY_DIV8, 10, 15, 5, 15, + BUS_MSTOP(7, BIT(12))), + DEF_MOD("usb3_0_pclk_usbtst", CLK_PLLDTY_ACPU_DIV4, 11, 0, 5, 16, + BUS_MSTOP(7, BIT(14))), DEF_MOD_MUX_EXTERNAL("gbeth_0_clk_tx_i", CLK_SMUX2_GBE0_TXCLK, 11, 8, 5, 24, BUS_MSTOP(8, BIT(5)), 1), DEF_MOD_MUX_EXTERNAL("gbeth_0_clk_rx_i", CLK_SMUX2_GBE0_RXCLK, 11, 9, 5, 25, @@ -300,9 +324,18 @@ static const struct rzv2h_mod_clk r9a09g047_mod_clks[] __initconst = { static const struct rzv2h_reset r9a09g047_resets[] __initconst = { DEF_RST(3, 0, 1, 1), /* SYS_0_PRESETN */ + DEF_RST(3, 1, 1, 2), /* DMAC_0_ARESETN */ + DEF_RST(3, 2, 1, 3), /* DMAC_1_ARESETN */ + DEF_RST(3, 3, 1, 4), /* DMAC_2_ARESETN */ + DEF_RST(3, 4, 1, 5), /* DMAC_3_ARESETN */ + DEF_RST(3, 5, 1, 6), /* DMAC_4_ARESETN */ DEF_RST(3, 6, 1, 7), /* ICU_0_PRESETN_I */ DEF_RST(3, 8, 1, 9), /* GIC_0_GICRESET_N */ DEF_RST(3, 9, 1, 10), /* GIC_0_DBG_GICRESET_N */ + DEF_RST(5, 9, 2, 10), /* GPT_0_RST_P_REG */ + DEF_RST(5, 10, 2, 11), /* GPT_0_RST_S_REG */ + DEF_RST(5, 11, 2, 12), /* GPT_1_RST_P_REG */ + DEF_RST(5, 12, 2, 13), /* GPT_1_RST_S_REG */ DEF_RST(7, 6, 3, 7), /* WDT_1_RESET */ DEF_RST(7, 7, 3, 8), /* WDT_2_RESET */ DEF_RST(7, 8, 3, 9), /* WDT_3_RESET */ @@ -325,6 +358,7 @@ static const struct rzv2h_reset r9a09g047_resets[] __initconst = { DEF_RST(10, 7, 4, 24), /* SDHI_0_IXRST */ DEF_RST(10, 8, 4, 25), /* SDHI_1_IXRST */ DEF_RST(10, 9, 4, 26), /* SDHI_2_IXRST */ + DEF_RST(10, 10, 4, 27), /* USB3_0_ARESETN */ DEF_RST(11, 0, 5, 1), /* GBETH_0_ARESETN_I */ DEF_RST(11, 1, 5, 2), /* GBETH_1_ARESETN_I */ DEF_RST(12, 5, 5, 22), /* CRU_0_PRESETN */ diff --git a/drivers/clk/renesas/r9a09g056-cpg.c b/drivers/clk/renesas/r9a09g056-cpg.c index 437af86f49dd..55f056359dd7 100644 --- a/drivers/clk/renesas/r9a09g056-cpg.c +++ b/drivers/clk/renesas/r9a09g056-cpg.c @@ -36,10 +36,10 @@ enum clk_ids { CLK_PLLCM33_DIV4, CLK_PLLCM33_DIV5, CLK_PLLCM33_DIV16, + CLK_PLLCM33_GEAR, CLK_SMUX2_XSPI_CLK0, CLK_SMUX2_XSPI_CLK1, CLK_PLLCM33_XSPI, - CLK_PLLCM33_GEAR, CLK_PLLCLN_DIV2, CLK_PLLCLN_DIV8, CLK_PLLCLN_DIV16, @@ -120,11 +120,11 @@ static const struct cpg_core_clk r9a09g056_core_clks[] __initconst = { DEF_FIXED(".pllcm33_div4", CLK_PLLCM33_DIV4, CLK_PLLCM33, 1, 4), DEF_FIXED(".pllcm33_div5", CLK_PLLCM33_DIV5, CLK_PLLCM33, 1, 5), DEF_FIXED(".pllcm33_div16", CLK_PLLCM33_DIV16, CLK_PLLCM33, 1, 16), + DEF_DDIV(".pllcm33_gear", CLK_PLLCM33_GEAR, CLK_PLLCM33_DIV4, CDDIV0_DIVCTL1, dtable_2_64), DEF_SMUX(".smux2_xspi_clk0", CLK_SMUX2_XSPI_CLK0, SSEL1_SELCTL2, smux2_xspi_clk0), DEF_SMUX(".smux2_xspi_clk1", CLK_SMUX2_XSPI_CLK1, SSEL1_SELCTL3, smux2_xspi_clk1), DEF_CSDIV(".pllcm33_xspi", CLK_PLLCM33_XSPI, CLK_SMUX2_XSPI_CLK1, CSDIV0_DIVCTL3, dtable_2_16), - DEF_DDIV(".pllcm33_gear", CLK_PLLCM33_GEAR, CLK_PLLCM33_DIV4, CDDIV0_DIVCTL1, dtable_2_64), DEF_FIXED(".pllcln_div2", CLK_PLLCLN_DIV2, CLK_PLLCLN, 1, 2), DEF_FIXED(".pllcln_div8", CLK_PLLCLN_DIV8, CLK_PLLCLN, 1, 8), @@ -205,6 +205,12 @@ static const struct rzv2h_mod_clk r9a09g056_mod_clks[] __initconst = { BUS_MSTOP(5, BIT(13))), DEF_MOD("scif_0_clk_pck", CLK_PLLCM33_DIV16, 8, 15, 4, 15, BUS_MSTOP(3, BIT(14))), + DEF_MOD("i3c_0_pclkrw", CLK_PLLCLN_DIV16, 9, 0, 4, 16, + BUS_MSTOP(10, BIT(15))), + DEF_MOD("i3c_0_pclk", CLK_PLLCLN_DIV16, 9, 1, 4, 17, + BUS_MSTOP(10, BIT(15))), + DEF_MOD("i3c_0_tclk", CLK_PLLCLN_DIV8, 9, 2, 4, 18, + BUS_MSTOP(10, BIT(15))), DEF_MOD("riic_8_ckm", CLK_PLLCM33_DIV16, 9, 3, 4, 19, BUS_MSTOP(3, BIT(13))), DEF_MOD("riic_0_ckm", CLK_PLLCLN_DIV16, 9, 4, 4, 20, @@ -308,6 +314,8 @@ static const struct rzv2h_reset r9a09g056_resets[] __initconst = { DEF_RST(7, 7, 3, 8), /* WDT_2_RESET */ DEF_RST(7, 8, 3, 9), /* WDT_3_RESET */ DEF_RST(9, 5, 4, 6), /* SCIF_0_RST_SYSTEM_N */ + DEF_RST(9, 6, 4, 7), /* I3C_0_PRESETN */ + DEF_RST(9, 7, 4, 8), /* I3C_0_TRESETN */ DEF_RST(9, 8, 4, 9), /* RIIC_0_MRST */ DEF_RST(9, 9, 4, 10), /* RIIC_1_MRST */ DEF_RST(9, 10, 4, 11), /* RIIC_2_MRST */ @@ -317,8 +325,8 @@ static const struct rzv2h_reset r9a09g056_resets[] __initconst = { DEF_RST(9, 14, 4, 15), /* RIIC_6_MRST */ DEF_RST(9, 15, 4, 16), /* RIIC_7_MRST */ DEF_RST(10, 0, 4, 17), /* RIIC_8_MRST */ - DEF_RST(10, 3, 4, 20), /* SPI_HRESETN */ - DEF_RST(10, 4, 4, 21), /* SPI_ARESETN */ + DEF_RST(10, 3, 4, 20), /* SPI_HRESETN */ + DEF_RST(10, 4, 4, 21), /* SPI_ARESETN */ DEF_RST(10, 7, 4, 24), /* SDHI_0_IXRST */ DEF_RST(10, 8, 4, 25), /* SDHI_1_IXRST */ DEF_RST(10, 9, 4, 26), /* SDHI_2_IXRST */ diff --git a/drivers/clk/renesas/r9a09g057-cpg.c b/drivers/clk/renesas/r9a09g057-cpg.c index f7de69a93de1..6389c4b6a523 100644 --- a/drivers/clk/renesas/r9a09g057-cpg.c +++ b/drivers/clk/renesas/r9a09g057-cpg.c @@ -134,9 +134,8 @@ static const struct cpg_core_clk r9a09g057_core_clks[] __initconst = { DEF_FIXED(".pllcm33_div3", CLK_PLLCM33_DIV3, CLK_PLLCM33, 1, 3), DEF_FIXED(".pllcm33_div4", CLK_PLLCM33_DIV4, CLK_PLLCM33, 1, 4), DEF_FIXED(".pllcm33_div5", CLK_PLLCM33_DIV5, CLK_PLLCM33, 1, 5), - DEF_DDIV(".pllcm33_gear", CLK_PLLCM33_GEAR, - CLK_PLLCM33_DIV4, CDDIV0_DIVCTL1, dtable_2_64), DEF_FIXED(".pllcm33_div16", CLK_PLLCM33_DIV16, CLK_PLLCM33, 1, 16), + DEF_DDIV(".pllcm33_gear", CLK_PLLCM33_GEAR, CLK_PLLCM33_DIV4, CDDIV0_DIVCTL1, dtable_2_64), DEF_SMUX(".smux2_xspi_clk0", CLK_SMUX2_XSPI_CLK0, SSEL1_SELCTL2, smux2_xspi_clk0), DEF_SMUX(".smux2_xspi_clk1", CLK_SMUX2_XSPI_CLK1, SSEL1_SELCTL3, smux2_xspi_clk1), DEF_CSDIV(".pllcm33_xspi", CLK_PLLCM33_XSPI, CLK_SMUX2_XSPI_CLK1, CSDIV0_DIVCTL3, @@ -260,6 +259,12 @@ static const struct rzv2h_mod_clk r9a09g057_mod_clks[] __initconst = { BUS_MSTOP(11, BIT(2))), DEF_MOD("scif_0_clk_pck", CLK_PLLCM33_DIV16, 8, 15, 4, 15, BUS_MSTOP(3, BIT(14))), + DEF_MOD("i3c_0_pclkrw", CLK_PLLCLN_DIV16, 9, 0, 4, 16, + BUS_MSTOP(10, BIT(15))), + DEF_MOD("i3c_0_pclk", CLK_PLLCLN_DIV16, 9, 1, 4, 17, + BUS_MSTOP(10, BIT(15))), + DEF_MOD("i3c_0_tclk", CLK_PLLCLN_DIV8, 9, 2, 4, 18, + BUS_MSTOP(10, BIT(15))), DEF_MOD("riic_8_ckm", CLK_PLLCM33_DIV16, 9, 3, 4, 19, BUS_MSTOP(3, BIT(13))), DEF_MOD("riic_0_ckm", CLK_PLLCLN_DIV16, 9, 4, 4, 20, @@ -403,6 +408,8 @@ static const struct rzv2h_reset r9a09g057_resets[] __initconst = { DEF_RST(7, 15, 3, 16), /* RSPI_2_PRESETN */ DEF_RST(8, 0, 3, 17), /* RSPI_2_TRESETN */ DEF_RST(9, 5, 4, 6), /* SCIF_0_RST_SYSTEM_N */ + DEF_RST(9, 6, 4, 7), /* I3C_0_PRESETN */ + DEF_RST(9, 7, 4, 8), /* I3C_0_TRESETN */ DEF_RST(9, 8, 4, 9), /* RIIC_0_MRST */ DEF_RST(9, 9, 4, 10), /* RIIC_1_MRST */ DEF_RST(9, 10, 4, 11), /* RIIC_2_MRST */ diff --git a/drivers/clk/renesas/r9a09g077-cpg.c b/drivers/clk/renesas/r9a09g077-cpg.c index c920d6a9707f..af3ef6d58c87 100644 --- a/drivers/clk/renesas/r9a09g077-cpg.c +++ b/drivers/clk/renesas/r9a09g077-cpg.c @@ -46,8 +46,13 @@ #define DIVCA55C2 CONF_PACK(SCKCR2, 10, 1) #define DIVCA55C3 CONF_PACK(SCKCR2, 11, 1) #define DIVCA55S CONF_PACK(SCKCR2, 12, 1) +#define DIVSCI5ASYNC CONF_PACK(SCKCR2, 18, 2) #define DIVSCI0ASYNC CONF_PACK(SCKCR3, 6, 2) +#define DIVSCI1ASYNC CONF_PACK(SCKCR3, 8, 2) +#define DIVSCI2ASYNC CONF_PACK(SCKCR3, 10, 2) +#define DIVSCI3ASYNC CONF_PACK(SCKCR3, 12, 2) +#define DIVSCI4ASYNC CONF_PACK(SCKCR3, 14, 2) #define SEL_PLL CONF_PACK(SCKCR, 22, 1) @@ -67,7 +72,7 @@ enum rzt2h_clk_types { enum clk_ids { /* Core Clock Outputs exported to DT */ - LAST_DT_CORE_CLK = R9A09G077_SDHI_CLKHS, + LAST_DT_CORE_CLK = R9A09G077_ETCLKE, /* External Input Clocks */ CLK_EXTAL, @@ -84,6 +89,11 @@ enum clk_ids { CLK_SEL_CLK_PLL4, CLK_PLL4D1, CLK_SCI0ASYNC, + CLK_SCI1ASYNC, + CLK_SCI2ASYNC, + CLK_SCI3ASYNC, + CLK_SCI4ASYNC, + CLK_SCI5ASYNC, /* Module Clocks */ MOD_CLK_BASE, @@ -133,6 +143,16 @@ static const struct cpg_core_clk r9a09g077_core_clks[] __initconst = { DEF_FIXED(".pll4d1", CLK_PLL4D1, CLK_SEL_CLK_PLL4, 1, 1), DEF_DIV(".sci0async", CLK_SCI0ASYNC, CLK_PLL4D1, DIVSCI0ASYNC, dtable_24_25_30_32), + DEF_DIV(".sci1async", CLK_SCI1ASYNC, CLK_PLL4D1, DIVSCI1ASYNC, + dtable_24_25_30_32), + DEF_DIV(".sci2async", CLK_SCI2ASYNC, CLK_PLL4D1, DIVSCI2ASYNC, + dtable_24_25_30_32), + DEF_DIV(".sci3async", CLK_SCI3ASYNC, CLK_PLL4D1, DIVSCI3ASYNC, + dtable_24_25_30_32), + DEF_DIV(".sci4async", CLK_SCI4ASYNC, CLK_PLL4D1, DIVSCI4ASYNC, + dtable_24_25_30_32), + DEF_DIV(".sci5async", CLK_SCI5ASYNC, CLK_PLL4D1, DIVSCI5ASYNC, + dtable_24_25_30_32), /* Core output clk */ DEF_DIV("CA55C0", R9A09G077_CLK_CA55C0, CLK_SEL_CLK_PLL0, DIVCA55C0, @@ -146,16 +166,35 @@ static const struct cpg_core_clk r9a09g077_core_clks[] __initconst = { DEF_DIV("CA55S", R9A09G077_CLK_CA55S, CLK_SEL_CLK_PLL0, DIVCA55S, dtable_1_2), DEF_FIXED("PCLKGPTL", R9A09G077_CLK_PCLKGPTL, CLK_SEL_CLK_PLL1, 2, 1), + DEF_FIXED("PCLKH", R9A09G077_CLK_PCLKH, CLK_SEL_CLK_PLL1, 4, 1), DEF_FIXED("PCLKM", R9A09G077_CLK_PCLKM, CLK_SEL_CLK_PLL1, 8, 1), DEF_FIXED("PCLKL", R9A09G077_CLK_PCLKL, CLK_SEL_CLK_PLL1, 16, 1), + DEF_FIXED("PCLKAH", R9A09G077_CLK_PCLKAH, CLK_PLL4D1, 6, 1), DEF_FIXED("PCLKAM", R9A09G077_CLK_PCLKAM, CLK_PLL4D1, 12, 1), DEF_FIXED("SDHI_CLKHS", R9A09G077_SDHI_CLKHS, CLK_SEL_CLK_PLL2, 1, 1), + DEF_FIXED("USB_CLK", R9A09G077_USB_CLK, CLK_PLL4D1, 48, 1), + DEF_FIXED("ETCLKA", R9A09G077_ETCLKA, CLK_SEL_CLK_PLL1, 5, 1), + DEF_FIXED("ETCLKB", R9A09G077_ETCLKB, CLK_SEL_CLK_PLL1, 8, 1), + DEF_FIXED("ETCLKC", R9A09G077_ETCLKC, CLK_SEL_CLK_PLL1, 10, 1), + DEF_FIXED("ETCLKD", R9A09G077_ETCLKD, CLK_SEL_CLK_PLL1, 20, 1), + DEF_FIXED("ETCLKE", R9A09G077_ETCLKE, CLK_SEL_CLK_PLL1, 40, 1), }; static const struct mssr_mod_clk r9a09g077_mod_clks[] __initconst = { DEF_MOD("sci0fck", 8, CLK_SCI0ASYNC), + DEF_MOD("sci1fck", 9, CLK_SCI1ASYNC), + DEF_MOD("sci2fck", 10, CLK_SCI2ASYNC), + DEF_MOD("sci3fck", 11, CLK_SCI3ASYNC), + DEF_MOD("sci4fck", 12, CLK_SCI4ASYNC), DEF_MOD("iic0", 100, R9A09G077_CLK_PCLKL), DEF_MOD("iic1", 101, R9A09G077_CLK_PCLKL), + DEF_MOD("gmac0", 400, R9A09G077_CLK_PCLKM), + DEF_MOD("ethsw", 401, R9A09G077_CLK_PCLKM), + DEF_MOD("ethss", 403, R9A09G077_CLK_PCLKM), + DEF_MOD("usb", 408, R9A09G077_CLK_PCLKAM), + DEF_MOD("gmac1", 416, R9A09G077_CLK_PCLKAM), + DEF_MOD("gmac2", 417, R9A09G077_CLK_PCLKAM), + DEF_MOD("sci5fck", 600, CLK_SCI5ASYNC), DEF_MOD("iic2", 601, R9A09G077_CLK_PCLKL), DEF_MOD("sdhi0", 1212, R9A09G077_CLK_PCLKAM), DEF_MOD("sdhi1", 1213, R9A09G077_CLK_PCLKAM), diff --git a/drivers/clk/renesas/renesas-cpg-mssr.c b/drivers/clk/renesas/renesas-cpg-mssr.c index 5ff6ee1f7d4b..de1cf7ba45b7 100644 --- a/drivers/clk/renesas/renesas-cpg-mssr.c +++ b/drivers/clk/renesas/renesas-cpg-mssr.c @@ -1082,6 +1082,7 @@ static int __init cpg_mssr_reserved_init(struct cpg_mssr_priv *priv, of_for_each_phandle(&it, rc, node, "clocks", "#clock-cells", -1) { int idx; + unsigned int *new_ids; if (it.node != priv->np) continue; @@ -1092,11 +1093,13 @@ static int __init cpg_mssr_reserved_init(struct cpg_mssr_priv *priv, if (args[0] != CPG_MOD) continue; - ids = krealloc_array(ids, (num + 1), sizeof(*ids), GFP_KERNEL); - if (!ids) { + new_ids = krealloc_array(ids, (num + 1), sizeof(*ids), GFP_KERNEL); + if (!new_ids) { of_node_put(it.node); + kfree(ids); return -ENOMEM; } + ids = new_ids; if (priv->reg_layout == CLK_REG_LAYOUT_RZ_A) idx = MOD_CLK_PACK_10(args[1]); /* for DEF_MOD_STB() */ diff --git a/drivers/clk/renesas/rzg2l-cpg.c b/drivers/clk/renesas/rzg2l-cpg.c index 187233302818..07909e80bae2 100644 --- a/drivers/clk/renesas/rzg2l-cpg.c +++ b/drivers/clk/renesas/rzg2l-cpg.c @@ -824,11 +824,10 @@ static unsigned long rzg2l_cpg_sipll5_recalc_rate(struct clk_hw *hw, return pll5_rate; } -static long rzg2l_cpg_sipll5_round_rate(struct clk_hw *hw, - unsigned long rate, - unsigned long *parent_rate) +static int rzg2l_cpg_sipll5_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { - return rate; + return 0; } static int rzg2l_cpg_sipll5_set_rate(struct clk_hw *hw, @@ -902,7 +901,7 @@ static int rzg2l_cpg_sipll5_set_rate(struct clk_hw *hw, static const struct clk_ops rzg2l_cpg_sipll5_ops = { .recalc_rate = rzg2l_cpg_sipll5_recalc_rate, - .round_rate = rzg2l_cpg_sipll5_round_rate, + .determine_rate = rzg2l_cpg_sipll5_determine_rate, .set_rate = rzg2l_cpg_sipll5_set_rate, }; @@ -1639,8 +1638,8 @@ fail: #define rcdev_to_priv(x) container_of(x, struct rzg2l_cpg_priv, rcdev) -static int rzg2l_cpg_assert(struct reset_controller_dev *rcdev, - unsigned long id) +static int __rzg2l_cpg_assert(struct reset_controller_dev *rcdev, + unsigned long id, bool assert) { struct rzg2l_cpg_priv *priv = rcdev_to_priv(rcdev); const struct rzg2l_cpg_info *info = priv->info; @@ -1648,9 +1647,13 @@ static int rzg2l_cpg_assert(struct reset_controller_dev *rcdev, u32 mask = BIT(info->resets[id].bit); s8 monbit = info->resets[id].monbit; u32 value = mask << 16; + int ret; - dev_dbg(rcdev->dev, "assert id:%ld offset:0x%x\n", id, CLK_RST_R(reg)); + dev_dbg(rcdev->dev, "%s id:%ld offset:0x%x\n", + assert ? "assert" : "deassert", id, CLK_RST_R(reg)); + if (!assert) + value |= mask; writel(value, priv->base + CLK_RST_R(reg)); if (info->has_clk_mon_regs) { @@ -1664,38 +1667,26 @@ static int rzg2l_cpg_assert(struct reset_controller_dev *rcdev, return 0; } - return readl_poll_timeout_atomic(priv->base + reg, value, - value & mask, 10, 200); + ret = readl_poll_timeout_atomic(priv->base + reg, value, + assert == !!(value & mask), 10, 200); + if (ret && !assert) { + value = mask << 16; + writel(value, priv->base + CLK_RST_R(info->resets[id].off)); + } + + return ret; +} + +static int rzg2l_cpg_assert(struct reset_controller_dev *rcdev, + unsigned long id) +{ + return __rzg2l_cpg_assert(rcdev, id, true); } static int rzg2l_cpg_deassert(struct reset_controller_dev *rcdev, unsigned long id) { - struct rzg2l_cpg_priv *priv = rcdev_to_priv(rcdev); - const struct rzg2l_cpg_info *info = priv->info; - unsigned int reg = info->resets[id].off; - u32 mask = BIT(info->resets[id].bit); - s8 monbit = info->resets[id].monbit; - u32 value = (mask << 16) | mask; - - dev_dbg(rcdev->dev, "deassert id:%ld offset:0x%x\n", id, - CLK_RST_R(reg)); - - writel(value, priv->base + CLK_RST_R(reg)); - - if (info->has_clk_mon_regs) { - reg = CLK_MRST_R(reg); - } else if (monbit >= 0) { - reg = CPG_RST_MON; - mask = BIT(monbit); - } else { - /* Wait for at least one cycle of the RCLK clock (@ ca. 32 kHz) */ - udelay(35); - return 0; - } - - return readl_poll_timeout_atomic(priv->base + reg, value, - !(value & mask), 10, 200); + return __rzg2l_cpg_assert(rcdev, id, false); } static int rzg2l_cpg_reset(struct reset_controller_dev *rcdev, diff --git a/drivers/clk/renesas/rzg2l-cpg.h b/drivers/clk/renesas/rzg2l-cpg.h index 0a71c5ec24b6..55e815be16c8 100644 --- a/drivers/clk/renesas/rzg2l-cpg.h +++ b/drivers/clk/renesas/rzg2l-cpg.h @@ -34,6 +34,7 @@ #define CPG_BUS_PERI_COM_MSTOP (0xB6C) #define CPG_BUS_PERI_CPU_MSTOP (0xB70) #define CPG_BUS_PERI_DDR_MSTOP (0xB74) +#define CPG_BUS_PERI_VIDEO_MSTOP (0xB78) #define CPG_BUS_REG0_MSTOP (0xB7C) #define CPG_BUS_REG1_MSTOP (0xB80) #define CPG_BUS_TZCDDR_MSTOP (0xB84) diff --git a/drivers/clk/renesas/rzv2h-cpg.c b/drivers/clk/renesas/rzv2h-cpg.c index f468afbb54e2..2197d1d2453a 100644 --- a/drivers/clk/renesas/rzv2h-cpg.c +++ b/drivers/clk/renesas/rzv2h-cpg.c @@ -294,15 +294,6 @@ static unsigned long rzv2h_ddiv_recalc_rate(struct clk_hw *hw, divider->flags, divider->width); } -static long rzv2h_ddiv_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *prate) -{ - struct clk_divider *divider = to_clk_divider(hw); - - return divider_round_rate(hw, rate, prate, divider->table, - divider->width, divider->flags); -} - static int rzv2h_ddiv_determine_rate(struct clk_hw *hw, struct clk_rate_request *req) { @@ -359,7 +350,6 @@ ddiv_timeout: static const struct clk_ops rzv2h_ddiv_clk_divider_ops = { .recalc_rate = rzv2h_ddiv_recalc_rate, - .round_rate = rzv2h_ddiv_round_rate, .determine_rate = rzv2h_ddiv_determine_rate, .set_rate = rzv2h_ddiv_set_rate, }; @@ -864,6 +854,7 @@ static int __rzv2h_cpg_assert(struct reset_controller_dev *rcdev, u32 mask = BIT(priv->resets[id].reset_bit); u8 monbit = priv->resets[id].mon_bit; u32 value = mask << 16; + int ret; dev_dbg(rcdev->dev, "%s id:%ld offset:0x%x\n", assert ? "assert" : "deassert", id, reg); @@ -875,9 +866,14 @@ static int __rzv2h_cpg_assert(struct reset_controller_dev *rcdev, reg = GET_RST_MON_OFFSET(priv->resets[id].mon_index); mask = BIT(monbit); - return readl_poll_timeout_atomic(priv->base + reg, value, - assert ? (value & mask) : !(value & mask), - 10, 200); + ret = readl_poll_timeout_atomic(priv->base + reg, value, + assert == !!(value & mask), 10, 200); + if (ret && !assert) { + value = mask << 16; + writel(value, priv->base + GET_RST_OFFSET(priv->resets[id].reset_index)); + } + + return ret; } static int rzv2h_cpg_assert(struct reset_controller_dev *rcdev, diff --git a/drivers/clk/rockchip/clk-ddr.c b/drivers/clk/rockchip/clk-ddr.c index 86718c54e56b..8866a65982a0 100644 --- a/drivers/clk/rockchip/clk-ddr.c +++ b/drivers/clk/rockchip/clk-ddr.c @@ -55,17 +55,18 @@ rockchip_ddrclk_sip_recalc_rate(struct clk_hw *hw, return res.a0; } -static long rockchip_ddrclk_sip_round_rate(struct clk_hw *hw, - unsigned long rate, - unsigned long *prate) +static int rockchip_ddrclk_sip_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { struct arm_smccc_res res; - arm_smccc_smc(ROCKCHIP_SIP_DRAM_FREQ, rate, 0, + arm_smccc_smc(ROCKCHIP_SIP_DRAM_FREQ, req->rate, 0, ROCKCHIP_SIP_CONFIG_DRAM_ROUND_RATE, 0, 0, 0, 0, &res); - return res.a0; + req->rate = res.a0; + + return 0; } static u8 rockchip_ddrclk_get_parent(struct clk_hw *hw) @@ -83,7 +84,7 @@ static u8 rockchip_ddrclk_get_parent(struct clk_hw *hw) static const struct clk_ops rockchip_ddrclk_sip_ops = { .recalc_rate = rockchip_ddrclk_sip_recalc_rate, .set_rate = rockchip_ddrclk_sip_set_rate, - .round_rate = rockchip_ddrclk_sip_round_rate, + .determine_rate = rockchip_ddrclk_sip_determine_rate, .get_parent = rockchip_ddrclk_get_parent, }; diff --git a/drivers/clk/rockchip/clk-half-divider.c b/drivers/clk/rockchip/clk-half-divider.c index 64f7faad2148..fbc018e8afa4 100644 --- a/drivers/clk/rockchip/clk-half-divider.c +++ b/drivers/clk/rockchip/clk-half-divider.c @@ -92,17 +92,19 @@ static int clk_half_divider_bestdiv(struct clk_hw *hw, unsigned long rate, return bestdiv; } -static long clk_half_divider_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *prate) +static int clk_half_divider_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { struct clk_divider *divider = to_clk_divider(hw); int div; - div = clk_half_divider_bestdiv(hw, rate, prate, + div = clk_half_divider_bestdiv(hw, req->rate, &req->best_parent_rate, divider->width, divider->flags); - return DIV_ROUND_UP_ULL(((u64)*prate * 2), div * 2 + 3); + req->rate = DIV_ROUND_UP_ULL(((u64)req->best_parent_rate * 2), div * 2 + 3); + + return 0; } static int clk_half_divider_set_rate(struct clk_hw *hw, unsigned long rate, @@ -141,7 +143,7 @@ static int clk_half_divider_set_rate(struct clk_hw *hw, unsigned long rate, static const struct clk_ops clk_half_divider_ops = { .recalc_rate = clk_half_divider_recalc_rate, - .round_rate = clk_half_divider_round_rate, + .determine_rate = clk_half_divider_determine_rate, .set_rate = clk_half_divider_set_rate, }; diff --git a/drivers/clk/rockchip/clk-pll.c b/drivers/clk/rockchip/clk-pll.c index c9d599c31923..86dba3826a77 100644 --- a/drivers/clk/rockchip/clk-pll.c +++ b/drivers/clk/rockchip/clk-pll.c @@ -61,8 +61,8 @@ static const struct rockchip_pll_rate_table *rockchip_get_pll_settings( return NULL; } -static long rockchip_pll_round_rate(struct clk_hw *hw, - unsigned long drate, unsigned long *prate) +static int rockchip_pll_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw); const struct rockchip_pll_rate_table *rate_table = pll->rate_table; @@ -70,12 +70,17 @@ static long rockchip_pll_round_rate(struct clk_hw *hw, /* Assuming rate_table is in descending order */ for (i = 0; i < pll->rate_count; i++) { - if (drate >= rate_table[i].rate) - return rate_table[i].rate; + if (req->rate >= rate_table[i].rate) { + req->rate = rate_table[i].rate; + + return 0; + } } /* return minimum supported value */ - return rate_table[i - 1].rate; + req->rate = rate_table[i - 1].rate; + + return 0; } /* @@ -352,7 +357,7 @@ static const struct clk_ops rockchip_rk3036_pll_clk_norate_ops = { static const struct clk_ops rockchip_rk3036_pll_clk_ops = { .recalc_rate = rockchip_rk3036_pll_recalc_rate, - .round_rate = rockchip_pll_round_rate, + .determine_rate = rockchip_pll_determine_rate, .set_rate = rockchip_rk3036_pll_set_rate, .enable = rockchip_rk3036_pll_enable, .disable = rockchip_rk3036_pll_disable, @@ -571,7 +576,7 @@ static const struct clk_ops rockchip_rk3066_pll_clk_norate_ops = { static const struct clk_ops rockchip_rk3066_pll_clk_ops = { .recalc_rate = rockchip_rk3066_pll_recalc_rate, - .round_rate = rockchip_pll_round_rate, + .determine_rate = rockchip_pll_determine_rate, .set_rate = rockchip_rk3066_pll_set_rate, .enable = rockchip_rk3066_pll_enable, .disable = rockchip_rk3066_pll_disable, @@ -836,7 +841,7 @@ static const struct clk_ops rockchip_rk3399_pll_clk_norate_ops = { static const struct clk_ops rockchip_rk3399_pll_clk_ops = { .recalc_rate = rockchip_rk3399_pll_recalc_rate, - .round_rate = rockchip_pll_round_rate, + .determine_rate = rockchip_pll_determine_rate, .set_rate = rockchip_rk3399_pll_set_rate, .enable = rockchip_rk3399_pll_enable, .disable = rockchip_rk3399_pll_disable, @@ -1036,7 +1041,7 @@ static const struct clk_ops rockchip_rk3588_pll_clk_norate_ops = { static const struct clk_ops rockchip_rk3588_pll_clk_ops = { .recalc_rate = rockchip_rk3588_pll_recalc_rate, - .round_rate = rockchip_pll_round_rate, + .determine_rate = rockchip_pll_determine_rate, .set_rate = rockchip_rk3588_pll_set_rate, .enable = rockchip_rk3588_pll_enable, .disable = rockchip_rk3588_pll_disable, diff --git a/drivers/clk/rockchip/clk-rk3368.c b/drivers/clk/rockchip/clk-rk3368.c index 04391e4e2874..95e6996adbae 100644 --- a/drivers/clk/rockchip/clk-rk3368.c +++ b/drivers/clk/rockchip/clk-rk3368.c @@ -526,7 +526,7 @@ static struct rockchip_clk_branch rk3368_clk_branches[] __initdata = { GATE(ACLK_PERI, "aclk_peri", "aclk_peri_src", CLK_IGNORE_UNUSED, RK3368_CLKGATE_CON(3), 1, GFLAGS), - GATE(0, "sclk_mipidsi_24m", "xin24m", 0, RK3368_CLKGATE_CON(4), 14, GFLAGS), + GATE(SCLK_MIPIDSI_24M, "sclk_mipidsi_24m", "xin24m", 0, RK3368_CLKGATE_CON(4), 14, GFLAGS), /* * Clock-Architecture Diagram 4 diff --git a/drivers/clk/samsung/Makefile b/drivers/clk/samsung/Makefile index b77fe288e4bb..ef464f434740 100644 --- a/drivers/clk/samsung/Makefile +++ b/drivers/clk/samsung/Makefile @@ -13,6 +13,7 @@ obj-$(CONFIG_EXYNOS_5260_COMMON_CLK) += clk-exynos5260.o obj-$(CONFIG_EXYNOS_5410_COMMON_CLK) += clk-exynos5410.o obj-$(CONFIG_EXYNOS_5420_COMMON_CLK) += clk-exynos5420.o obj-$(CONFIG_EXYNOS_5420_COMMON_CLK) += clk-exynos5-subcmu.o +obj-$(CONFIG_EXYNOS_ARM64_COMMON_CLK) += clk-artpec8.o obj-$(CONFIG_EXYNOS_ARM64_COMMON_CLK) += clk-exynos5433.o obj-$(CONFIG_EXYNOS_AUDSS_CLK_CON) += clk-exynos-audss.o obj-$(CONFIG_EXYNOS_CLKOUT) += clk-exynos-clkout.o diff --git a/drivers/clk/samsung/clk-artpec8.c b/drivers/clk/samsung/clk-artpec8.c new file mode 100644 index 000000000000..0ea7c8b58674 --- /dev/null +++ b/drivers/clk/samsung/clk-artpec8.c @@ -0,0 +1,1044 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2025 Samsung Electronics Co., Ltd. + * https://www.samsung.com + * Copyright (c) 2025 Axis Communications AB. + * https://www.axis.com + * + * Common Clock Framework support for ARTPEC-8 SoC. + */ + +#include <linux/clk-provider.h> +#include <linux/platform_device.h> +#include <dt-bindings/clock/axis,artpec8-clk.h> + +#include "clk.h" +#include "clk-exynos-arm64.h" + +/* NOTE: Must be equal to the last clock ID increased by one */ +#define CMU_CMU_NR_CLK (CLK_DOUT_CMU_VPP_CORE + 1) +#define CMU_BUS_NR_CLK (CLK_DOUT_BUS_PCLK + 1) +#define CMU_CORE_NR_CLK (CLK_DOUT_CORE_PCLK + 1) +#define CMU_CPUCL_NR_CLK (CLK_GOUT_CPUCL_CSSYS_IPCLKPORT_ATCLK + 1) +#define CMU_FSYS_NR_CLK (CLK_GOUT_FSYS_QSPI_IPCLKPORT_SSI_CLK + 1) +#define CMU_IMEM_NR_CLK (CLK_GOUT_IMEM_PCLK_TMU0_APBIF + 1) +#define CMU_PERI_NR_CLK (CLK_GOUT_PERI_DMA4DSIM_IPCLKPORT_CLK_AXI_CLK + 1) + +/* Register Offset definitions for CMU_CMU (0x12400000) */ +#define PLL_LOCKTIME_PLL_AUDIO 0x0000 +#define PLL_LOCKTIME_PLL_SHARED0 0x0004 +#define PLL_LOCKTIME_PLL_SHARED1 0x0008 +#define PLL_CON0_PLL_AUDIO 0x0100 +#define PLL_CON0_PLL_SHARED0 0x0120 +#define PLL_CON0_PLL_SHARED1 0x0140 +#define CLK_CON_MUX_CLKCMU_2D 0x1000 +#define CLK_CON_MUX_CLKCMU_3D 0x1004 +#define CLK_CON_MUX_CLKCMU_BUS 0x1008 +#define CLK_CON_MUX_CLKCMU_BUS_DLP 0x100c +#define CLK_CON_MUX_CLKCMU_CDC_CORE 0x1010 +#define CLK_CON_MUX_CLKCMU_FSYS_SCAN0 0x1014 +#define CLK_CON_MUX_CLKCMU_FSYS_SCAN1 0x1018 +#define CLK_CON_MUX_CLKCMU_IMEM_JPEG 0x101c +#define CLK_CON_MUX_CLKCMU_PERI_DISP 0x1020 +#define CLK_CON_MUX_CLKCMU_CORE_BUS 0x1024 +#define CLK_CON_MUX_CLKCMU_CORE_DLP 0x1028 +#define CLK_CON_MUX_CLKCMU_CPUCL_SWITCH 0x1030 +#define CLK_CON_MUX_CLKCMU_DLP_CORE 0x1034 +#define CLK_CON_MUX_CLKCMU_FSYS_BUS 0x1038 +#define CLK_CON_MUX_CLKCMU_FSYS_IP 0x103c +#define CLK_CON_MUX_CLKCMU_IMEM_ACLK 0x1054 +#define CLK_CON_MUX_CLKCMU_MIF_BUSP 0x1080 +#define CLK_CON_MUX_CLKCMU_MIF_SWITCH 0x1084 +#define CLK_CON_MUX_CLKCMU_PERI_IP 0x1088 +#define CLK_CON_MUX_CLKCMU_RSP_CORE 0x108c +#define CLK_CON_MUX_CLKCMU_TRFM_CORE 0x1090 +#define CLK_CON_MUX_CLKCMU_VCA_ACE 0x1094 +#define CLK_CON_MUX_CLKCMU_VCA_OD 0x1098 +#define CLK_CON_MUX_CLKCMU_VIO_CORE 0x109c +#define CLK_CON_MUX_CLKCMU_VIP0_CORE 0x10a0 +#define CLK_CON_MUX_CLKCMU_VIP1_CORE 0x10a4 +#define CLK_CON_MUX_CLKCMU_VPP_CORE 0x10a8 + +#define CLK_CON_DIV_CLKCMU_BUS 0x1800 +#define CLK_CON_DIV_CLKCMU_BUS_DLP 0x1804 +#define CLK_CON_DIV_CLKCMU_CDC_CORE 0x1808 +#define CLK_CON_DIV_CLKCMU_FSYS_SCAN0 0x180c +#define CLK_CON_DIV_CLKCMU_FSYS_SCAN1 0x1810 +#define CLK_CON_DIV_CLKCMU_IMEM_JPEG 0x1814 +#define CLK_CON_DIV_CLKCMU_MIF_SWITCH 0x1818 +#define CLK_CON_DIV_CLKCMU_CORE_DLP 0x181c +#define CLK_CON_DIV_CLKCMU_CORE_MAIN 0x1820 +#define CLK_CON_DIV_CLKCMU_PERI_DISP 0x1824 +#define CLK_CON_DIV_CLKCMU_CPUCL_SWITCH 0x1828 +#define CLK_CON_DIV_CLKCMU_DLP_CORE 0x182c +#define CLK_CON_DIV_CLKCMU_FSYS_BUS 0x1830 +#define CLK_CON_DIV_CLKCMU_FSYS_IP 0x1834 +#define CLK_CON_DIV_CLKCMU_VIO_AUDIO 0x1838 +#define CLK_CON_DIV_CLKCMU_GPU_2D 0x1848 +#define CLK_CON_DIV_CLKCMU_GPU_3D 0x184c +#define CLK_CON_DIV_CLKCMU_IMEM_ACLK 0x1854 +#define CLK_CON_DIV_CLKCMU_MIF_BUSP 0x1884 +#define CLK_CON_DIV_CLKCMU_PERI_AUDIO 0x1890 +#define CLK_CON_DIV_CLKCMU_PERI_IP 0x1894 +#define CLK_CON_DIV_CLKCMU_RSP_CORE 0x1898 +#define CLK_CON_DIV_CLKCMU_TRFM_CORE 0x189c +#define CLK_CON_DIV_CLKCMU_VCA_ACE 0x18a0 +#define CLK_CON_DIV_CLKCMU_VCA_OD 0x18a4 +#define CLK_CON_DIV_CLKCMU_VIO_CORE 0x18ac +#define CLK_CON_DIV_CLKCMU_VIP0_CORE 0x18b0 +#define CLK_CON_DIV_CLKCMU_VIP1_CORE 0x18b4 +#define CLK_CON_DIV_CLKCMU_VPP_CORE 0x18b8 +#define CLK_CON_DIV_PLL_SHARED0_DIV2 0x18bc +#define CLK_CON_DIV_PLL_SHARED0_DIV3 0x18c0 +#define CLK_CON_DIV_PLL_SHARED0_DIV4 0x18c4 +#define CLK_CON_DIV_PLL_SHARED1_DIV2 0x18c8 +#define CLK_CON_DIV_PLL_SHARED1_DIV3 0x18cc +#define CLK_CON_DIV_PLL_SHARED1_DIV4 0x18d0 + +static const unsigned long cmu_cmu_clk_regs[] __initconst = { + PLL_LOCKTIME_PLL_AUDIO, + PLL_LOCKTIME_PLL_SHARED0, + PLL_LOCKTIME_PLL_SHARED1, + PLL_CON0_PLL_AUDIO, + PLL_CON0_PLL_SHARED0, + PLL_CON0_PLL_SHARED1, + CLK_CON_MUX_CLKCMU_2D, + CLK_CON_MUX_CLKCMU_3D, + CLK_CON_MUX_CLKCMU_BUS, + CLK_CON_MUX_CLKCMU_BUS_DLP, + CLK_CON_MUX_CLKCMU_CDC_CORE, + CLK_CON_MUX_CLKCMU_FSYS_SCAN0, + CLK_CON_MUX_CLKCMU_FSYS_SCAN1, + CLK_CON_MUX_CLKCMU_IMEM_JPEG, + CLK_CON_MUX_CLKCMU_PERI_DISP, + CLK_CON_MUX_CLKCMU_CORE_BUS, + CLK_CON_MUX_CLKCMU_CORE_DLP, + CLK_CON_MUX_CLKCMU_CPUCL_SWITCH, + CLK_CON_MUX_CLKCMU_DLP_CORE, + CLK_CON_MUX_CLKCMU_FSYS_BUS, + CLK_CON_MUX_CLKCMU_FSYS_IP, + CLK_CON_MUX_CLKCMU_IMEM_ACLK, + CLK_CON_MUX_CLKCMU_MIF_BUSP, + CLK_CON_MUX_CLKCMU_MIF_SWITCH, + CLK_CON_MUX_CLKCMU_PERI_IP, + CLK_CON_MUX_CLKCMU_RSP_CORE, + CLK_CON_MUX_CLKCMU_TRFM_CORE, + CLK_CON_MUX_CLKCMU_VCA_ACE, + CLK_CON_MUX_CLKCMU_VCA_OD, + CLK_CON_MUX_CLKCMU_VIO_CORE, + CLK_CON_MUX_CLKCMU_VIP0_CORE, + CLK_CON_MUX_CLKCMU_VIP1_CORE, + CLK_CON_MUX_CLKCMU_VPP_CORE, + CLK_CON_DIV_CLKCMU_BUS, + CLK_CON_DIV_CLKCMU_BUS_DLP, + CLK_CON_DIV_CLKCMU_CDC_CORE, + CLK_CON_DIV_CLKCMU_FSYS_SCAN0, + CLK_CON_DIV_CLKCMU_FSYS_SCAN1, + CLK_CON_DIV_CLKCMU_IMEM_JPEG, + CLK_CON_DIV_CLKCMU_MIF_SWITCH, + CLK_CON_DIV_CLKCMU_CORE_DLP, + CLK_CON_DIV_CLKCMU_CORE_MAIN, + CLK_CON_DIV_CLKCMU_PERI_DISP, + CLK_CON_DIV_CLKCMU_CPUCL_SWITCH, + CLK_CON_DIV_CLKCMU_DLP_CORE, + CLK_CON_DIV_CLKCMU_FSYS_BUS, + CLK_CON_DIV_CLKCMU_FSYS_IP, + CLK_CON_DIV_CLKCMU_VIO_AUDIO, + CLK_CON_DIV_CLKCMU_GPU_2D, + CLK_CON_DIV_CLKCMU_GPU_3D, + CLK_CON_DIV_CLKCMU_IMEM_ACLK, + CLK_CON_DIV_CLKCMU_MIF_BUSP, + CLK_CON_DIV_CLKCMU_PERI_AUDIO, + CLK_CON_DIV_CLKCMU_PERI_IP, + CLK_CON_DIV_CLKCMU_RSP_CORE, + CLK_CON_DIV_CLKCMU_TRFM_CORE, + CLK_CON_DIV_CLKCMU_VCA_ACE, + CLK_CON_DIV_CLKCMU_VCA_OD, + CLK_CON_DIV_CLKCMU_VIO_CORE, + CLK_CON_DIV_CLKCMU_VIP0_CORE, + CLK_CON_DIV_CLKCMU_VIP1_CORE, + CLK_CON_DIV_CLKCMU_VPP_CORE, + CLK_CON_DIV_PLL_SHARED0_DIV2, + CLK_CON_DIV_PLL_SHARED0_DIV3, + CLK_CON_DIV_PLL_SHARED0_DIV4, + CLK_CON_DIV_PLL_SHARED1_DIV2, + CLK_CON_DIV_PLL_SHARED1_DIV3, + CLK_CON_DIV_PLL_SHARED1_DIV4, +}; + +static const struct samsung_pll_rate_table artpec8_pll_audio_rates[] __initconst = { + PLL_36XX_RATE(25 * MHZ, 589823913U, 47, 1, 1, 12184), + PLL_36XX_RATE(25 * MHZ, 393215942U, 47, 3, 0, 12184), + PLL_36XX_RATE(25 * MHZ, 294911956U, 47, 1, 2, 12184), + PLL_36XX_RATE(25 * MHZ, 100000000U, 32, 2, 2, 0), + PLL_36XX_RATE(25 * MHZ, 98303985U, 47, 3, 2, 12184), + PLL_36XX_RATE(25 * MHZ, 49151992U, 47, 3, 3, 12184), +}; + +static const struct samsung_pll_clock cmu_cmu_pll_clks[] __initconst = { + PLL(pll_1017x, CLK_FOUT_SHARED0_PLL, "fout_pll_shared0", "fin_pll", + PLL_LOCKTIME_PLL_SHARED0, PLL_CON0_PLL_SHARED0, NULL), + PLL(pll_1017x, CLK_FOUT_SHARED1_PLL, "fout_pll_shared1", "fin_pll", + PLL_LOCKTIME_PLL_SHARED1, PLL_CON0_PLL_SHARED1, NULL), + PLL(pll_1031x, CLK_FOUT_AUDIO_PLL, "fout_pll_audio", "fin_pll", + PLL_LOCKTIME_PLL_AUDIO, PLL_CON0_PLL_AUDIO, artpec8_pll_audio_rates), +}; + +PNAME(mout_clkcmu_bus_bus_p) = { "dout_pll_shared1_div2", "dout_pll_shared0_div3", + "dout_pll_shared1_div3", "dout_pll_shared1_div4" }; +PNAME(mout_clkcmu_bus_dlp_p) = { "dout_pll_shared0_div2", "dout_pll_shared0_div4", + "dout_pll_shared1_div2", "dout_pll_shared1_div4" }; +PNAME(mout_clkcmu_core_bus_p) = { "dout_pll_shared1_div2", "dout_pll_shared0_div3", + "dout_pll_shared0_div4", "dout_pll_shared1_div3" }; +PNAME(mout_clkcmu_core_dlp_p) = { "dout_pll_shared0_div2", "dout_pll_shared1_div2", + "dout_pll_shared0_div3", "dout_pll_shared1_div3" }; +PNAME(mout_clkcmu_cpucl_switch_p) = { "dout_pll_shared0_div2", "dout_pll_shared1_div2", + "dout_pll_shared0_div3", "dout_pll_shared1_div3" }; +PNAME(mout_clkcmu_fsys_bus_p) = { "dout_pll_shared1_div2", "dout_pll_shared0_div2", + "dout_pll_shared1_div4", "dout_pll_shared1_div3" }; +PNAME(mout_clkcmu_fsys_ip_p) = { "dout_pll_shared0_div2", "dout_pll_shared1_div3", + "dout_pll_shared1_div2", "dout_pll_shared0_div3" }; +PNAME(mout_clkcmu_fsys_scan0_p) = { "dout_pll_shared0_div4", "dout_pll_shared1_div4" }; +PNAME(mout_clkcmu_fsys_scan1_p) = { "dout_pll_shared0_div4", "dout_pll_shared1_div4" }; +PNAME(mout_clkcmu_imem_imem_p) = { "dout_pll_shared1_div4", "dout_pll_shared0_div3", + "dout_pll_shared1_div3", "dout_pll_shared1_div2" }; +PNAME(mout_clkcmu_imem_jpeg_p) = { "dout_pll_shared0_div2", "dout_pll_shared0_div3", + "dout_pll_shared1_div2", "dout_pll_shared1_div3" }; +PNAME(mout_clkcmu_cdc_core_p) = { "dout_pll_shared1_div2", "dout_pll_shared0_div3", + "dout_pll_shared1_div3", "dout_pll_shared1_div4" }; +PNAME(mout_clkcmu_dlp_core_p) = { "dout_pll_shared0_div2", "dout_pll_shared1_div2", + "dout_pll_shared0_div3", "dout_pll_shared1_div3" }; +PNAME(mout_clkcmu_3d_p) = { "dout_pll_shared0_div2", "dout_pll_shared1_div2", + "dout_pll_shared0_div3", "dout_pll_shared1_div3" }; +PNAME(mout_clkcmu_2d_p) = { "dout_pll_shared0_div2", "dout_pll_shared1_div2", + "dout_pll_shared0_div3", "dout_pll_shared1_div3" }; +PNAME(mout_clkcmu_mif_switch_p) = { "dout_pll_shared0", "dout_pll_shared1", + "dout_pll_shared0_div2", "dout_pll_shared0_div3" }; +PNAME(mout_clkcmu_mif_busp_p) = { "dout_pll_shared0_div3", "dout_pll_shared1_div4", + "dout_pll_shared0_div4", "dout_pll_shared0_div2" }; +PNAME(mout_clkcmu_peri_disp_p) = { "dout_pll_shared1_div2", "dout_pll_shared0_div2", + "dout_pll_shared1_div4", "dout_pll_shared1_div3" }; +PNAME(mout_clkcmu_peri_ip_p) = { "dout_pll_shared1_div2", "dout_pll_shared0_div4", + "dout_pll_shared1_div4", "dout_pll_shared0_div2" }; +PNAME(mout_clkcmu_rsp_core_p) = { "dout_pll_shared1_div2", "dout_pll_shared0_div3", + "dout_pll_shared1_div3", "dout_pll_shared1_div4" }; +PNAME(mout_clkcmu_trfm_core_p) = { "dout_pll_shared1_div2", "dout_pll_shared0_div3", + "dout_pll_shared1_div3", "dout_pll_shared1_div4" }; +PNAME(mout_clkcmu_vca_ace_p) = { "dout_pll_shared1_div2", "dout_pll_shared0_div3", + "dout_pll_shared1_div3", "dout_pll_shared1_div4" }; +PNAME(mout_clkcmu_vca_od_p) = { "dout_pll_shared1_div2", "dout_pll_shared0_div3", + "dout_pll_shared1_div3", "dout_pll_shared1_div4" }; +PNAME(mout_clkcmu_vio_core_p) = { "dout_pll_shared0_div3", "dout_pll_shared0_div2", + "dout_pll_shared1_div2", "dout_pll_shared1_div3" }; +PNAME(mout_clkcmu_vip0_core_p) = { "dout_pll_shared1_div2", "dout_pll_shared0_div3", + "dout_pll_shared1_div3", "dout_pll_shared1_div4" }; +PNAME(mout_clkcmu_vip1_core_p) = { "dout_pll_shared1_div2", "dout_pll_shared0_div3", + "dout_pll_shared1_div3", "dout_pll_shared1_div4" }; +PNAME(mout_clkcmu_vpp_core_p) = { "dout_pll_shared1_div2", "dout_pll_shared0_div3", + "dout_pll_shared1_div3", "dout_pll_shared1_div4" }; +PNAME(mout_clkcmu_pll_shared0_p) = { "fin_pll", "fout_pll_shared0" }; +PNAME(mout_clkcmu_pll_shared1_p) = { "fin_pll", "fout_pll_shared1" }; +PNAME(mout_clkcmu_pll_audio_p) = { "fin_pll", "fout_pll_audio" }; + +static const struct samsung_fixed_factor_clock cmu_fixed_factor_clks[] __initconst = { + FFACTOR(CLK_DOUT_CMU_OTP, "dout_clkcmu_otp", "fin_pll", 1, 8, 0), +}; + +static const struct samsung_mux_clock cmu_cmu_mux_clks[] __initconst = { + MUX(0, "mout_clkcmu_pll_shared0", mout_clkcmu_pll_shared0_p, PLL_CON0_PLL_SHARED0, 4, 1), + MUX(0, "mout_clkcmu_pll_shared1", mout_clkcmu_pll_shared1_p, PLL_CON0_PLL_SHARED1, 4, 1), + MUX(0, "mout_clkcmu_pll_audio", mout_clkcmu_pll_audio_p, PLL_CON0_PLL_AUDIO, 4, 1), + MUX(0, "mout_clkcmu_bus_bus", mout_clkcmu_bus_bus_p, CLK_CON_MUX_CLKCMU_BUS, 0, 2), + MUX(0, "mout_clkcmu_bus_dlp", mout_clkcmu_bus_dlp_p, CLK_CON_MUX_CLKCMU_BUS_DLP, 0, 2), + MUX(0, "mout_clkcmu_core_bus", mout_clkcmu_core_bus_p, CLK_CON_MUX_CLKCMU_CORE_BUS, 0, 2), + MUX(0, "mout_clkcmu_core_dlp", mout_clkcmu_core_dlp_p, CLK_CON_MUX_CLKCMU_CORE_DLP, 0, 2), + MUX(0, "mout_clkcmu_cpucl_switch", mout_clkcmu_cpucl_switch_p, + CLK_CON_MUX_CLKCMU_CPUCL_SWITCH, 0, 3), + MUX(0, "mout_clkcmu_fsys_bus", mout_clkcmu_fsys_bus_p, CLK_CON_MUX_CLKCMU_FSYS_BUS, 0, 2), + MUX(0, "mout_clkcmu_fsys_ip", mout_clkcmu_fsys_ip_p, CLK_CON_MUX_CLKCMU_FSYS_IP, 0, 2), + MUX(0, "mout_clkcmu_fsys_scan0", mout_clkcmu_fsys_scan0_p, + CLK_CON_MUX_CLKCMU_FSYS_SCAN0, 0, 1), + MUX(0, "mout_clkcmu_fsys_scan1", mout_clkcmu_fsys_scan1_p, + CLK_CON_MUX_CLKCMU_FSYS_SCAN1, 0, 1), + MUX(0, "mout_clkcmu_imem_imem", mout_clkcmu_imem_imem_p, + CLK_CON_MUX_CLKCMU_IMEM_ACLK, 0, 2), + MUX(0, "mout_clkcmu_imem_jpeg", mout_clkcmu_imem_jpeg_p, + CLK_CON_MUX_CLKCMU_IMEM_JPEG, 0, 2), + nMUX(0, "mout_clkcmu_cdc_core", mout_clkcmu_cdc_core_p, CLK_CON_MUX_CLKCMU_CDC_CORE, 0, 2), + nMUX(0, "mout_clkcmu_dlp_core", mout_clkcmu_dlp_core_p, CLK_CON_MUX_CLKCMU_DLP_CORE, 0, 2), + MUX(0, "mout_clkcmu_3d", mout_clkcmu_3d_p, CLK_CON_MUX_CLKCMU_3D, 0, 2), + MUX(0, "mout_clkcmu_2d", mout_clkcmu_2d_p, CLK_CON_MUX_CLKCMU_2D, 0, 2), + MUX(0, "mout_clkcmu_mif_switch", mout_clkcmu_mif_switch_p, + CLK_CON_MUX_CLKCMU_MIF_SWITCH, 0, 2), + MUX(0, "mout_clkcmu_mif_busp", mout_clkcmu_mif_busp_p, CLK_CON_MUX_CLKCMU_MIF_BUSP, 0, 2), + MUX(0, "mout_clkcmu_peri_disp", mout_clkcmu_peri_disp_p, + CLK_CON_MUX_CLKCMU_PERI_DISP, 0, 2), + MUX(0, "mout_clkcmu_peri_ip", mout_clkcmu_peri_ip_p, CLK_CON_MUX_CLKCMU_PERI_IP, 0, 2), + MUX(0, "mout_clkcmu_rsp_core", mout_clkcmu_rsp_core_p, CLK_CON_MUX_CLKCMU_RSP_CORE, 0, 2), + nMUX(0, "mout_clkcmu_trfm_core", mout_clkcmu_trfm_core_p, + CLK_CON_MUX_CLKCMU_TRFM_CORE, 0, 2), + MUX(0, "mout_clkcmu_vca_ace", mout_clkcmu_vca_ace_p, CLK_CON_MUX_CLKCMU_VCA_ACE, 0, 2), + MUX(0, "mout_clkcmu_vca_od", mout_clkcmu_vca_od_p, CLK_CON_MUX_CLKCMU_VCA_OD, 0, 2), + MUX(0, "mout_clkcmu_vio_core", mout_clkcmu_vio_core_p, CLK_CON_MUX_CLKCMU_VIO_CORE, 0, 2), + nMUX(0, "mout_clkcmu_vip0_core", mout_clkcmu_vip0_core_p, + CLK_CON_MUX_CLKCMU_VIP0_CORE, 0, 2), + nMUX(0, "mout_clkcmu_vip1_core", mout_clkcmu_vip1_core_p, + CLK_CON_MUX_CLKCMU_VIP1_CORE, 0, 2), + nMUX(0, "mout_clkcmu_vpp_core", mout_clkcmu_vpp_core_p, CLK_CON_MUX_CLKCMU_VPP_CORE, 0, 2), +}; + +static const struct samsung_div_clock cmu_cmu_div_clks[] __initconst = { + DIV(CLK_DOUT_SHARED0_DIV2, "dout_pll_shared0_div2", + "mout_clkcmu_pll_shared0", CLK_CON_DIV_PLL_SHARED0_DIV2, 0, 1), + DIV(CLK_DOUT_SHARED0_DIV3, "dout_pll_shared0_div3", + "mout_clkcmu_pll_shared0", CLK_CON_DIV_PLL_SHARED0_DIV3, 0, 2), + DIV(CLK_DOUT_SHARED0_DIV4, "dout_pll_shared0_div4", + "dout_pll_shared0_div2", CLK_CON_DIV_PLL_SHARED0_DIV4, 0, 1), + DIV(CLK_DOUT_SHARED1_DIV2, "dout_pll_shared1_div2", + "mout_clkcmu_pll_shared1", CLK_CON_DIV_PLL_SHARED1_DIV2, 0, 1), + DIV(CLK_DOUT_SHARED1_DIV3, "dout_pll_shared1_div3", + "mout_clkcmu_pll_shared1", CLK_CON_DIV_PLL_SHARED1_DIV3, 0, 2), + DIV(CLK_DOUT_SHARED1_DIV4, "dout_pll_shared1_div4", + "dout_pll_shared1_div2", CLK_CON_DIV_PLL_SHARED1_DIV4, 0, 1), + DIV(CLK_DOUT_CMU_BUS, "dout_clkcmu_bus", + "mout_clkcmu_bus_bus", CLK_CON_DIV_CLKCMU_BUS, 0, 4), + DIV(CLK_DOUT_CMU_BUS_DLP, "dout_clkcmu_bus_dlp", + "mout_clkcmu_bus_dlp", CLK_CON_DIV_CLKCMU_BUS_DLP, 0, 4), + DIV(CLK_DOUT_CMU_CORE_MAIN, "dout_clkcmu_core_main", + "mout_clkcmu_core_bus", CLK_CON_DIV_CLKCMU_CORE_MAIN, 0, 4), + DIV(CLK_DOUT_CMU_CORE_DLP, "dout_clkcmu_core_dlp", + "mout_clkcmu_core_dlp", CLK_CON_DIV_CLKCMU_CORE_DLP, 0, 4), + DIV(CLK_DOUT_CMU_CPUCL_SWITCH, "dout_clkcmu_cpucl_switch", + "mout_clkcmu_cpucl_switch", CLK_CON_DIV_CLKCMU_CPUCL_SWITCH, 0, 3), + DIV(CLK_DOUT_CMU_FSYS_BUS, "dout_clkcmu_fsys_bus", + "mout_clkcmu_fsys_bus", CLK_CON_DIV_CLKCMU_FSYS_BUS, 0, 4), + DIV(CLK_DOUT_CMU_FSYS_IP, "dout_clkcmu_fsys_ip", + "mout_clkcmu_fsys_ip", CLK_CON_DIV_CLKCMU_FSYS_IP, 0, 9), + DIV(CLK_DOUT_CMU_FSYS_SCAN0, "dout_clkcmu_fsys_scan0", + "mout_clkcmu_fsys_scan0", CLK_CON_DIV_CLKCMU_FSYS_SCAN0, 0, 4), + DIV(CLK_DOUT_CMU_FSYS_SCAN1, "dout_clkcmu_fsys_scan1", + "mout_clkcmu_fsys_scan1", CLK_CON_DIV_CLKCMU_FSYS_SCAN1, 0, 4), + DIV(CLK_DOUT_CMU_IMEM_ACLK, "dout_clkcmu_imem_aclk", + "mout_clkcmu_imem_imem", CLK_CON_DIV_CLKCMU_IMEM_ACLK, 0, 4), + DIV(CLK_DOUT_CMU_IMEM_JPEG, "dout_clkcmu_imem_jpeg", + "mout_clkcmu_imem_jpeg", CLK_CON_DIV_CLKCMU_IMEM_JPEG, 0, 4), + DIV_F(CLK_DOUT_CMU_CDC_CORE, "dout_clkcmu_cdc_core", + "mout_clkcmu_cdc_core", CLK_CON_DIV_CLKCMU_CDC_CORE, 0, 4, CLK_SET_RATE_PARENT, 0), + DIV_F(CLK_DOUT_CMU_DLP_CORE, "dout_clkcmu_dlp_core", + "mout_clkcmu_dlp_core", CLK_CON_DIV_CLKCMU_DLP_CORE, 0, 4, CLK_SET_RATE_PARENT, 0), + DIV(CLK_DOUT_CMU_GPU_3D, "dout_clkcmu_gpu_3d", + "mout_clkcmu_3d", CLK_CON_DIV_CLKCMU_GPU_3D, 0, 3), + DIV(CLK_DOUT_CMU_GPU_2D, "dout_clkcmu_gpu_2d", + "mout_clkcmu_2d", CLK_CON_DIV_CLKCMU_GPU_2D, 0, 4), + DIV(CLK_DOUT_CMU_MIF_SWITCH, "dout_clkcmu_mif_switch", + "mout_clkcmu_mif_switch", CLK_CON_DIV_CLKCMU_MIF_SWITCH, 0, 4), + DIV(CLK_DOUT_CMU_MIF_BUSP, "dout_clkcmu_mif_busp", + "mout_clkcmu_mif_busp", CLK_CON_DIV_CLKCMU_MIF_BUSP, 0, 3), + DIV(CLK_DOUT_CMU_PERI_DISP, "dout_clkcmu_peri_disp", + "mout_clkcmu_peri_disp", CLK_CON_DIV_CLKCMU_PERI_DISP, 0, 4), + DIV(CLK_DOUT_CMU_PERI_IP, "dout_clkcmu_peri_ip", + "mout_clkcmu_peri_ip", CLK_CON_DIV_CLKCMU_PERI_IP, 0, 4), + DIV(CLK_DOUT_CMU_PERI_AUDIO, "dout_clkcmu_peri_audio", + "mout_clkcmu_pll_audio", CLK_CON_DIV_CLKCMU_PERI_AUDIO, 0, 4), + DIV(CLK_DOUT_CMU_RSP_CORE, "dout_clkcmu_rsp_core", + "mout_clkcmu_rsp_core", CLK_CON_DIV_CLKCMU_RSP_CORE, 0, 4), + DIV_F(CLK_DOUT_CMU_TRFM_CORE, "dout_clkcmu_trfm_core", + "mout_clkcmu_trfm_core", CLK_CON_DIV_CLKCMU_TRFM_CORE, 0, 4, CLK_SET_RATE_PARENT, 0), + DIV(CLK_DOUT_CMU_VCA_ACE, "dout_clkcmu_vca_ace", + "mout_clkcmu_vca_ace", CLK_CON_DIV_CLKCMU_VCA_ACE, 0, 4), + DIV(CLK_DOUT_CMU_VCA_OD, "dout_clkcmu_vca_od", + "mout_clkcmu_vca_od", CLK_CON_DIV_CLKCMU_VCA_OD, 0, 4), + DIV(CLK_DOUT_CMU_VIO_CORE, "dout_clkcmu_vio_core", + "mout_clkcmu_vio_core", CLK_CON_DIV_CLKCMU_VIO_CORE, 0, 4), + DIV(CLK_DOUT_CMU_VIO_AUDIO, "dout_clkcmu_vio_audio", + "mout_clkcmu_pll_audio", CLK_CON_DIV_CLKCMU_VIO_AUDIO, 0, 4), + DIV_F(CLK_DOUT_CMU_VIP0_CORE, "dout_clkcmu_vip0_core", + "mout_clkcmu_vip0_core", CLK_CON_DIV_CLKCMU_VIP0_CORE, 0, 4, CLK_SET_RATE_PARENT, 0), + DIV_F(CLK_DOUT_CMU_VIP1_CORE, "dout_clkcmu_vip1_core", + "mout_clkcmu_vip1_core", CLK_CON_DIV_CLKCMU_VIP1_CORE, 0, 4, CLK_SET_RATE_PARENT, 0), + DIV_F(CLK_DOUT_CMU_VPP_CORE, "dout_clkcmu_vpp_core", + "mout_clkcmu_vpp_core", CLK_CON_DIV_CLKCMU_VPP_CORE, 0, 4, CLK_SET_RATE_PARENT, 0), +}; + +static const struct samsung_cmu_info cmu_cmu_info __initconst = { + .pll_clks = cmu_cmu_pll_clks, + .nr_pll_clks = ARRAY_SIZE(cmu_cmu_pll_clks), + .fixed_factor_clks = cmu_fixed_factor_clks, + .nr_fixed_factor_clks = ARRAY_SIZE(cmu_fixed_factor_clks), + .mux_clks = cmu_cmu_mux_clks, + .nr_mux_clks = ARRAY_SIZE(cmu_cmu_mux_clks), + .div_clks = cmu_cmu_div_clks, + .nr_div_clks = ARRAY_SIZE(cmu_cmu_div_clks), + .nr_clk_ids = CMU_CMU_NR_CLK, + .clk_regs = cmu_cmu_clk_regs, + .nr_clk_regs = ARRAY_SIZE(cmu_cmu_clk_regs), +}; + +/* Register Offset definitions for CMU_BUS (0x12c10000) */ +#define PLL_CON0_MUX_CLK_BUS_ACLK_USER 0x0100 +#define PLL_CON0_MUX_CLK_BUS_DLP_USER 0x0120 +#define CLK_CON_DIV_CLK_BUS_PCLK 0x1800 + +static const unsigned long cmu_bus_clk_regs[] __initconst = { + PLL_CON0_MUX_CLK_BUS_ACLK_USER, + PLL_CON0_MUX_CLK_BUS_DLP_USER, + CLK_CON_DIV_CLK_BUS_PCLK, +}; + +PNAME(mout_clk_bus_aclk_user_p) = { "fin_pll", "dout_clkcmu_bus" }; +PNAME(mout_clk_bus_dlp_user_p) = { "fin_pll", "dout_clkcmu_bus_dlp" }; + +static const struct samsung_mux_clock cmu_bus_mux_clks[] __initconst = { + MUX(CLK_MOUT_BUS_ACLK_USER, "mout_clk_bus_aclk_user", + mout_clk_bus_aclk_user_p, PLL_CON0_MUX_CLK_BUS_ACLK_USER, 4, 1), + MUX(CLK_MOUT_BUS_DLP_USER, "mout_clk_bus_dlp_user", + mout_clk_bus_dlp_user_p, PLL_CON0_MUX_CLK_BUS_DLP_USER, 4, 1), +}; + +static const struct samsung_div_clock cmu_bus_div_clks[] __initconst = { + DIV(CLK_DOUT_BUS_PCLK, "dout_clk_bus_pclk", "mout_clk_bus_aclk_user", + CLK_CON_DIV_CLK_BUS_PCLK, 0, 4), +}; + +static const struct samsung_cmu_info cmu_bus_info __initconst = { + .mux_clks = cmu_bus_mux_clks, + .nr_mux_clks = ARRAY_SIZE(cmu_bus_mux_clks), + .div_clks = cmu_bus_div_clks, + .nr_div_clks = ARRAY_SIZE(cmu_bus_div_clks), + .nr_clk_ids = CMU_BUS_NR_CLK, + .clk_regs = cmu_bus_clk_regs, + .nr_clk_regs = ARRAY_SIZE(cmu_bus_clk_regs), +}; + +/* Register Offset definitions for CMU_CORE (0x12410000) */ +#define PLL_CON0_MUX_CLK_CORE_ACLK_USER 0x0100 +#define PLL_CON0_MUX_CLK_CORE_DLP_USER 0x0120 +#define CLK_CON_DIV_CLK_CORE_PCLK 0x1800 + +static const unsigned long cmu_core_clk_regs[] __initconst = { + PLL_CON0_MUX_CLK_CORE_ACLK_USER, + PLL_CON0_MUX_CLK_CORE_DLP_USER, + CLK_CON_DIV_CLK_CORE_PCLK, +}; + +PNAME(mout_clk_core_aclk_user_p) = { "fin_pll", "dout_clkcmu_core_main" }; +PNAME(mout_clk_core_dlp_user_p) = { "fin_pll", "dout_clkcmu_core_dlp" }; + +static const struct samsung_mux_clock cmu_core_mux_clks[] __initconst = { + MUX(CLK_MOUT_CORE_ACLK_USER, "mout_clk_core_aclk_user", + mout_clk_core_aclk_user_p, PLL_CON0_MUX_CLK_CORE_ACLK_USER, 4, 1), + MUX(CLK_MOUT_CORE_DLP_USER, "mout_clk_core_dlp_user", + mout_clk_core_dlp_user_p, PLL_CON0_MUX_CLK_CORE_DLP_USER, 4, 1), +}; + +static const struct samsung_div_clock cmu_core_div_clks[] __initconst = { + DIV(CLK_DOUT_CORE_PCLK, "dout_clk_core_pclk", + "mout_clk_core_aclk_user", CLK_CON_DIV_CLK_CORE_PCLK, 0, 4), +}; + +static const struct samsung_cmu_info cmu_core_info __initconst = { + .mux_clks = cmu_core_mux_clks, + .nr_mux_clks = ARRAY_SIZE(cmu_core_mux_clks), + .div_clks = cmu_core_div_clks, + .nr_div_clks = ARRAY_SIZE(cmu_core_div_clks), + .nr_clk_ids = CMU_CORE_NR_CLK, + .clk_regs = cmu_core_clk_regs, + .nr_clk_regs = ARRAY_SIZE(cmu_core_clk_regs), +}; + +/* Register Offset definitions for CMU_CPUCL (0x11410000) */ +#define PLL_LOCKTIME_PLL_CPUCL 0x0000 +#define PLL_CON0_MUX_CLKCMU_CPUCL_SWITCH_USER 0x0120 +#define PLL_CON0_PLL_CPUCL 0x0140 +#define CLK_CON_MUX_CLK_CPUCL_PLL 0x1000 +#define CLK_CON_DIV_CLK_CLUSTER_ACLK 0x1800 +#define CLK_CON_DIV_CLK_CLUSTER_CNTCLK 0x1804 +#define CLK_CON_DIV_CLK_CLUSTER_PCLKDBG 0x1808 +#define CLK_CON_DIV_CLK_CPUCL_CMUREF 0x180c +#define CLK_CON_DIV_CLK_CPUCL_PCLK 0x1814 +#define CLK_CON_DIV_CLK_CLUSTER_ATCLK 0x1818 +#define CLK_CON_DIV_CLK_CPUCL_DBG 0x181c +#define CLK_CON_DIV_CLK_CPUCL_PCLKDBG 0x1820 +#define CLK_CON_GAT_CLK_CLUSTER_CPU 0x2008 +#define CLK_CON_GAT_CLK_CPUCL_SHORTSTOP 0x200c +#define CLK_CON_DMYQCH_CON_CSSYS_QCH 0x3008 + +static const unsigned long cmu_cpucl_clk_regs[] __initconst = { + PLL_LOCKTIME_PLL_CPUCL, + PLL_CON0_MUX_CLKCMU_CPUCL_SWITCH_USER, + PLL_CON0_PLL_CPUCL, + CLK_CON_MUX_CLK_CPUCL_PLL, + CLK_CON_DIV_CLK_CLUSTER_ACLK, + CLK_CON_DIV_CLK_CLUSTER_CNTCLK, + CLK_CON_DIV_CLK_CLUSTER_PCLKDBG, + CLK_CON_DIV_CLK_CPUCL_CMUREF, + CLK_CON_DIV_CLK_CPUCL_PCLK, + CLK_CON_DIV_CLK_CLUSTER_ATCLK, + CLK_CON_DIV_CLK_CPUCL_DBG, + CLK_CON_DIV_CLK_CPUCL_PCLKDBG, + CLK_CON_GAT_CLK_CLUSTER_CPU, + CLK_CON_GAT_CLK_CPUCL_SHORTSTOP, + CLK_CON_DMYQCH_CON_CSSYS_QCH, +}; + +static const struct samsung_pll_clock cmu_cpucl_pll_clks[] __initconst = { + PLL(pll_1017x, CLK_FOUT_CPUCL_PLL, "fout_pll_cpucl", "fin_pll", + PLL_LOCKTIME_PLL_CPUCL, PLL_CON0_PLL_CPUCL, NULL), +}; + +PNAME(mout_clkcmu_cpucl_switch_user_p) = { "fin_pll", "dout_clkcmu_cpucl_switch" }; +PNAME(mout_pll_cpucl_p) = { "fin_pll", "fout_pll_cpucl" }; +PNAME(mout_clk_cpucl_pll_p) = { "mout_pll_cpucl", "mout_clkcmu_cpucl_switch_user" }; + +static const struct samsung_mux_clock cmu_cpucl_mux_clks[] __initconst = { + MUX_F(0, "mout_pll_cpucl", mout_pll_cpucl_p, PLL_CON0_PLL_CPUCL, 4, 1, + CLK_SET_RATE_PARENT | CLK_RECALC_NEW_RATES, 0), + MUX(CLK_MOUT_CPUCL_SWITCH_USER, "mout_clkcmu_cpucl_switch_user", + mout_clkcmu_cpucl_switch_user_p, PLL_CON0_MUX_CLKCMU_CPUCL_SWITCH_USER, 4, 1), + MUX_F(CLK_MOUT_CPUCL_PLL, "mout_clk_cpucl_pll", mout_clk_cpucl_pll_p, + CLK_CON_MUX_CLK_CPUCL_PLL, 0, 1, CLK_SET_RATE_PARENT, 0), +}; + +static const struct samsung_fixed_factor_clock cpucl_ffactor_clks[] __initconst = { + FFACTOR(CLK_DOUT_CPUCL_CPU, "dout_clk_cpucl_cpu", + "mout_clk_cpucl_pll", 1, 1, CLK_SET_RATE_PARENT), +}; + +static const struct samsung_div_clock cmu_cpucl_div_clks[] __initconst = { + DIV(CLK_DOUT_CPUCL_CLUSTER_ACLK, "dout_clk_cluster_aclk", + "dout_clk_cpucl_cpu", CLK_CON_DIV_CLK_CLUSTER_ACLK, 0, 4), + DIV(CLK_DOUT_CPUCL_CLUSTER_PCLKDBG, "dout_clk_cluster_pclkdbg", + "dout_clk_cpucl_cpu", CLK_CON_DIV_CLK_CLUSTER_PCLKDBG, 0, 4), + DIV(CLK_DOUT_CPUCL_CLUSTER_CNTCLK, "dout_clk_cluster_cntclk", + "dout_clk_cpucl_cpu", CLK_CON_DIV_CLK_CLUSTER_CNTCLK, 0, 4), + DIV(CLK_DOUT_CPUCL_CLUSTER_ATCLK, "dout_clk_cluster_atclk", + "dout_clk_cpucl_cpu", CLK_CON_DIV_CLK_CLUSTER_ATCLK, 0, 4), + DIV(CLK_DOUT_CPUCL_PCLK, "dout_clk_cpucl_pclk", + "dout_clk_cpucl_cpu", CLK_CON_DIV_CLK_CPUCL_PCLK, 0, 4), + DIV(CLK_DOUT_CPUCL_CMUREF, "dout_clk_cpucl_cmuref", + "dout_clk_cpucl_cpu", CLK_CON_DIV_CLK_CPUCL_CMUREF, 0, 3), + DIV(CLK_DOUT_CPUCL_DBG, "dout_clk_cpucl_dbg", + "dout_clk_cpucl_cpu", CLK_CON_DIV_CLK_CPUCL_DBG, 0, 4), + DIV(CLK_DOUT_CPUCL_PCLKDBG, "dout_clk_cpucl_pclkdbg", + "dout_clk_cpucl_dbg", CLK_CON_DIV_CLK_CPUCL_PCLKDBG, 0, 4), +}; + +static const struct samsung_gate_clock cmu_cpucl_gate_clks[] __initconst = { + GATE(CLK_GOUT_CPUCL_CLUSTER_CPU, "clk_con_gat_clk_cluster_cpu", + "clk_con_gat_clk_cpucl_shortstop", CLK_CON_GAT_CLK_CLUSTER_CPU, 21, + CLK_SET_RATE_PARENT | CLK_IS_CRITICAL, 0), + GATE(CLK_GOUT_CPUCL_SHORTSTOP, "clk_con_gat_clk_cpucl_shortstop", + "dout_clk_cpucl_cpu", CLK_CON_GAT_CLK_CPUCL_SHORTSTOP, 21, + CLK_SET_RATE_PARENT | CLK_IS_CRITICAL, 0), + GATE(CLK_GOUT_CPUCL_CSSYS_IPCLKPORT_PCLKDBG, "cssys_ipclkport_pclkdbg", + "dout_clk_cpucl_pclkdbg", CLK_CON_DMYQCH_CON_CSSYS_QCH, 1, + CLK_SET_RATE_PARENT | CLK_IS_CRITICAL, 0), + GATE(CLK_GOUT_CPUCL_CSSYS_IPCLKPORT_ATCLK, "cssys_ipclkport_atclk", + "dout_clk_cpucl_dbg", CLK_CON_DMYQCH_CON_CSSYS_QCH, 1, + CLK_SET_RATE_PARENT | CLK_IS_CRITICAL, 0), +}; + +static const struct samsung_cmu_info cmu_cpucl_info __initconst = { + .pll_clks = cmu_cpucl_pll_clks, + .nr_pll_clks = ARRAY_SIZE(cmu_cpucl_pll_clks), + .fixed_factor_clks = cpucl_ffactor_clks, + .nr_fixed_factor_clks = ARRAY_SIZE(cpucl_ffactor_clks), + .mux_clks = cmu_cpucl_mux_clks, + .nr_mux_clks = ARRAY_SIZE(cmu_cpucl_mux_clks), + .div_clks = cmu_cpucl_div_clks, + .nr_div_clks = ARRAY_SIZE(cmu_cpucl_div_clks), + .gate_clks = cmu_cpucl_gate_clks, + .nr_gate_clks = ARRAY_SIZE(cmu_cpucl_gate_clks), + .nr_clk_ids = CMU_CPUCL_NR_CLK, + .clk_regs = cmu_cpucl_clk_regs, + .nr_clk_regs = ARRAY_SIZE(cmu_cpucl_clk_regs), +}; + +/* Register Offset definitions for CMU_FSYS (0x16c10000) */ +#define PLL_LOCKTIME_PLL_FSYS 0x0004 +#define PLL_CON0_MUX_CLK_FSYS_BUS_USER 0x0120 +#define PLL_CON0_MUX_CLK_FSYS_MMC_USER 0x0140 +#define PLL_CON0_MUX_CLK_FSYS_SCAN0_USER 0x0160 +#define PLL_CON0_MUX_CLK_FSYS_SCAN1_USER 0x0180 +#define PLL_CON0_PLL_FSYS 0x01c0 +#define CLK_CON_DIV_CLK_FSYS_ADC 0x1804 +#define CLK_CON_DIV_CLK_FSYS_BUS300 0x1808 +#define CLK_CON_DIV_CLK_FSYS_BUS_QSPI 0x180c +#define CLK_CON_DIV_CLK_FSYS_EQOS_25 0x1810 +#define CLK_CON_DIV_CLK_FSYS_EQOS_2P5 0x1814 +#define CLK_CON_DIV_CLK_FSYS_EQOS_500 0x1818 +#define CLK_CON_DIV_CLK_FSYS_EQOS_INT125 0x181c +#define CLK_CON_DIV_CLK_FSYS_MMC_CARD0 0x1820 +#define CLK_CON_DIV_CLK_FSYS_MMC_CARD1 0x1824 +#define CLK_CON_DIV_CLK_FSYS_OTP_MEM 0x1828 +#define CLK_CON_DIV_CLK_FSYS_PCIE_PHY_REFCLK_SYSPLL 0x182c +#define CLK_CON_DIV_CLK_FSYS_QSPI 0x1830 +#define CLK_CON_DIV_CLK_FSYS_SCLK_UART 0x1834 +#define CLK_CON_DIV_CLK_FSYS_SFMC_NAND 0x1838 +#define CLK_CON_DIV_SCAN_CLK_FSYS_125 0x183c +#define CLK_CON_DIV_SCAN_CLK_FSYS_MMC 0x1840 +#define CLK_CON_DIV_SCAN_CLK_FSYS_PCIE_PIPE 0x1844 +#define CLK_CON_FSYS_I2C0_IPCLKPORT_I_PCLK 0x2044 +#define CLK_CON_FSYS_I2C1_IPCLKPORT_I_PCLK 0x2048 +#define CLK_CON_FSYS_UART0_IPCLKPORT_I_PCLK 0x204c +#define CLK_CON_FSYS_UART0_IPCLKPORT_I_SCLK_UART 0x2050 +#define CLK_CON_MMC0_IPCLKPORT_I_ACLK 0x2070 +#define CLK_CON_MMC1_IPCLKPORT_I_ACLK 0x2078 +#define CLK_CON_DWC_PCIE_CTL_INST_0_DBI_ACLK_UG 0x208c +#define CLK_CON_DWC_PCIE_CTL_INST_0_MSTR_ACLK_UG 0x2090 +#define CLK_CON_DWC_PCIE_CTL_INST_0_SLV_ACLK_UG 0x2094 +#define CLK_CON_PWM_IPCLKPORT_I_PCLK_S0 0x20a0 +#define CLK_CON_USB20DRD_IPCLKPORT_ACLK_PHYCTRL_20 0x20bc +#define CLK_CON_USB20DRD_IPCLKPORT_BUS_CLK_EARLY 0x20c0 +#define CLK_CON_XHB_AHBBR_IPCLKPORT_CLK 0x20c4 +#define CLK_CON_XHB_USB_IPCLKPORT_CLK 0x20cc +#define CLK_CON_BUS_P_FSYS_IPCLKPORT_QSPICLK 0x201c +#define CLK_CON_DMYQCH_CON_EQOS_TOP_QCH 0x3008 +#define CLK_CON_DMYQCH_CON_MMC0_QCH 0x300c +#define CLK_CON_DMYQCH_CON_MMC1_QCH 0x3010 +#define CLK_CON_DMYQCH_CON_PCIE_TOP_QCH 0x3018 +#define CLK_CON_DMYQCH_CON_PCIE_TOP_QCH_REF 0x301c +#define CLK_CON_DMYQCH_CON_QSPI_QCH 0x3020 +#define CLK_CON_DMYQCH_CON_SFMC_QCH 0x3024 + +static const unsigned long cmu_fsys_clk_regs[] __initconst = { + PLL_LOCKTIME_PLL_FSYS, + PLL_CON0_MUX_CLK_FSYS_BUS_USER, + PLL_CON0_MUX_CLK_FSYS_MMC_USER, + PLL_CON0_MUX_CLK_FSYS_SCAN0_USER, + PLL_CON0_MUX_CLK_FSYS_SCAN1_USER, + PLL_CON0_PLL_FSYS, + CLK_CON_DIV_CLK_FSYS_ADC, + CLK_CON_DIV_CLK_FSYS_BUS300, + CLK_CON_DIV_CLK_FSYS_BUS_QSPI, + CLK_CON_DIV_CLK_FSYS_EQOS_25, + CLK_CON_DIV_CLK_FSYS_EQOS_2P5, + CLK_CON_DIV_CLK_FSYS_EQOS_500, + CLK_CON_DIV_CLK_FSYS_EQOS_INT125, + CLK_CON_DIV_CLK_FSYS_MMC_CARD0, + CLK_CON_DIV_CLK_FSYS_MMC_CARD1, + CLK_CON_DIV_CLK_FSYS_OTP_MEM, + CLK_CON_DIV_CLK_FSYS_PCIE_PHY_REFCLK_SYSPLL, + CLK_CON_DIV_CLK_FSYS_QSPI, + CLK_CON_DIV_CLK_FSYS_SCLK_UART, + CLK_CON_DIV_CLK_FSYS_SFMC_NAND, + CLK_CON_DIV_SCAN_CLK_FSYS_125, + CLK_CON_DIV_SCAN_CLK_FSYS_MMC, + CLK_CON_DIV_SCAN_CLK_FSYS_PCIE_PIPE, + CLK_CON_FSYS_I2C0_IPCLKPORT_I_PCLK, + CLK_CON_FSYS_I2C1_IPCLKPORT_I_PCLK, + CLK_CON_FSYS_UART0_IPCLKPORT_I_PCLK, + CLK_CON_FSYS_UART0_IPCLKPORT_I_SCLK_UART, + CLK_CON_MMC0_IPCLKPORT_I_ACLK, + CLK_CON_MMC1_IPCLKPORT_I_ACLK, + CLK_CON_DWC_PCIE_CTL_INST_0_DBI_ACLK_UG, + CLK_CON_DWC_PCIE_CTL_INST_0_MSTR_ACLK_UG, + CLK_CON_DWC_PCIE_CTL_INST_0_SLV_ACLK_UG, + CLK_CON_PWM_IPCLKPORT_I_PCLK_S0, + CLK_CON_USB20DRD_IPCLKPORT_ACLK_PHYCTRL_20, + CLK_CON_USB20DRD_IPCLKPORT_BUS_CLK_EARLY, + CLK_CON_XHB_AHBBR_IPCLKPORT_CLK, + CLK_CON_XHB_USB_IPCLKPORT_CLK, + CLK_CON_BUS_P_FSYS_IPCLKPORT_QSPICLK, + CLK_CON_DMYQCH_CON_EQOS_TOP_QCH, + CLK_CON_DMYQCH_CON_MMC0_QCH, + CLK_CON_DMYQCH_CON_MMC1_QCH, + CLK_CON_DMYQCH_CON_PCIE_TOP_QCH, + CLK_CON_DMYQCH_CON_PCIE_TOP_QCH_REF, + CLK_CON_DMYQCH_CON_QSPI_QCH, + CLK_CON_DMYQCH_CON_SFMC_QCH, +}; + +static const struct samsung_pll_clock cmu_fsys_pll_clks[] __initconst = { + PLL(pll_1017x, CLK_FOUT_FSYS_PLL, "fout_pll_fsys", "fin_pll", + PLL_LOCKTIME_PLL_FSYS, PLL_CON0_PLL_FSYS, NULL), +}; + +PNAME(mout_fsys_scan0_user_p) = { "fin_pll", "dout_clkcmu_fsys_scan0" }; +PNAME(mout_fsys_scan1_user_p) = { "fin_pll", "dout_clkcmu_fsys_scan1" }; +PNAME(mout_fsys_bus_user_p) = { "fin_pll", "dout_clkcmu_fsys_bus" }; +PNAME(mout_fsys_mmc_user_p) = { "fin_pll", "dout_clkcmu_fsys_ip" }; +PNAME(mout_fsys_pll_fsys_p) = { "fin_pll", "fout_pll_fsys" }; + +static const struct samsung_mux_clock cmu_fsys_mux_clks[] __initconst = { + MUX(0, "mout_clk_pll_fsys", mout_fsys_pll_fsys_p, PLL_CON0_PLL_FSYS, 4, 1), + MUX(CLK_MOUT_FSYS_SCAN0_USER, "mout_fsys_scan0_user", + mout_fsys_scan0_user_p, PLL_CON0_MUX_CLK_FSYS_SCAN0_USER, 4, 1), + MUX(CLK_MOUT_FSYS_SCAN1_USER, "mout_fsys_scan1_user", + mout_fsys_scan1_user_p, PLL_CON0_MUX_CLK_FSYS_SCAN1_USER, 4, 1), + MUX(CLK_MOUT_FSYS_BUS_USER, "mout_fsys_bus_user", + mout_fsys_bus_user_p, PLL_CON0_MUX_CLK_FSYS_BUS_USER, 4, 1), + MUX(CLK_MOUT_FSYS_MMC_USER, "mout_fsys_mmc_user", + mout_fsys_mmc_user_p, PLL_CON0_MUX_CLK_FSYS_MMC_USER, 4, 1), +}; + +static const struct samsung_div_clock cmu_fsys_div_clks[] __initconst = { + DIV(CLK_DOUT_FSYS_PCIE_PIPE, "dout_fsys_pcie_pipe", "mout_clk_pll_fsys", + CLK_CON_DIV_SCAN_CLK_FSYS_PCIE_PIPE, 0, 4), + DIV(CLK_DOUT_FSYS_ADC, "dout_fsys_adc", "mout_clk_pll_fsys", + CLK_CON_DIV_CLK_FSYS_ADC, 0, 7), + DIV(CLK_DOUT_FSYS_PCIE_PHY_REFCLK_SYSPLL, "dout_fsys_pcie_phy_refclk_syspll", + "mout_clk_pll_fsys", CLK_CON_DIV_CLK_FSYS_PCIE_PHY_REFCLK_SYSPLL, 0, 8), + DIV(CLK_DOUT_FSYS_QSPI, "dout_fsys_qspi", "mout_fsys_mmc_user", + CLK_CON_DIV_CLK_FSYS_QSPI, 0, 4), + DIV(CLK_DOUT_FSYS_EQOS_INT125, "dout_fsys_eqos_int125", "mout_clk_pll_fsys", + CLK_CON_DIV_CLK_FSYS_EQOS_INT125, 0, 4), + DIV(CLK_DOUT_FSYS_OTP_MEM, "dout_fsys_otp_mem", "fin_pll", + CLK_CON_DIV_CLK_FSYS_OTP_MEM, 0, 9), + DIV(CLK_DOUT_FSYS_SCLK_UART, "dout_fsys_sclk_uart", "mout_clk_pll_fsys", + CLK_CON_DIV_CLK_FSYS_SCLK_UART, 0, 10), + DIV(CLK_DOUT_FSYS_SFMC_NAND, "dout_fsys_sfmc_nand", "mout_fsys_mmc_user", + CLK_CON_DIV_CLK_FSYS_SFMC_NAND, 0, 4), + DIV(CLK_DOUT_SCAN_CLK_FSYS_125, "dout_scan_clk_fsys_125", "mout_clk_pll_fsys", + CLK_CON_DIV_SCAN_CLK_FSYS_125, 0, 4), + DIV(CLK_DOUT_FSYS_SCAN_CLK_MMC, "dout_scan_clk_fsys_mmc", "fout_pll_fsys", + CLK_CON_DIV_SCAN_CLK_FSYS_MMC, 0, 4), + DIV(CLK_DOUT_FSYS_EQOS_25, "dout_fsys_eqos_25", "dout_fsys_eqos_int125", + CLK_CON_DIV_CLK_FSYS_EQOS_25, 0, 4), + DIV_F(CLK_DOUT_FSYS_EQOS_2p5, "dout_fsys_eqos_2p5", "dout_fsys_eqos_25", + CLK_CON_DIV_CLK_FSYS_EQOS_2P5, 0, 4, CLK_SET_RATE_PARENT, 0), + DIV(0, "dout_fsys_eqos_500", "mout_clk_pll_fsys", + CLK_CON_DIV_CLK_FSYS_EQOS_500, 0, 4), + DIV(CLK_DOUT_FSYS_BUS300, "dout_fsys_bus300", "mout_fsys_bus_user", + CLK_CON_DIV_CLK_FSYS_BUS300, 0, 4), + DIV(CLK_DOUT_FSYS_BUS_QSPI, "dout_fsys_bus_qspi", "mout_fsys_mmc_user", + CLK_CON_DIV_CLK_FSYS_BUS_QSPI, 0, 4), + DIV(CLK_DOUT_FSYS_MMC_CARD0, "dout_fsys_mmc_card0", "mout_fsys_mmc_user", + CLK_CON_DIV_CLK_FSYS_MMC_CARD0, 0, 10), + DIV(CLK_DOUT_FSYS_MMC_CARD1, "dout_fsys_mmc_card1", "mout_fsys_mmc_user", + CLK_CON_DIV_CLK_FSYS_MMC_CARD1, 0, 10), +}; + +static const struct samsung_gate_clock cmu_fsys_gate_clks[] __initconst = { + GATE(CLK_GOUT_FSYS_PCIE_PHY_REFCLK_IN, "pcie_sub_ctrl_inst_0_phy_refclk_in", + "dout_fsys_pcie_phy_refclk_syspll", CLK_CON_DMYQCH_CON_PCIE_TOP_QCH_REF, 1, + CLK_SET_RATE_PARENT, 0), + GATE(CLK_GOUT_FSYS_EQOS_TOP_IPCLKPORT_I_RGMII_TXCLK_2P5, + "eqos_top_ipclkport_i_rgmii_txclk_2p5", + "dout_fsys_eqos_2p5", CLK_CON_DMYQCH_CON_EQOS_TOP_QCH, 1, CLK_SET_RATE_PARENT, 0), + GATE(CLK_GOUT_FSYS_EQOS_TOP_IPCLKPORT_ACLK_I, "eqos_top_ipclkport_aclk_i", + "dout_fsys_bus300", CLK_CON_DMYQCH_CON_EQOS_TOP_QCH, 1, CLK_SET_RATE_PARENT, 0), + GATE(CLK_GOUT_FSYS_EQOS_TOP_IPCLKPORT_CLK_CSR_I, "eqos_top_ipclkport_clk_csr_i", + "dout_fsys_bus300", CLK_CON_DMYQCH_CON_EQOS_TOP_QCH, 1, CLK_SET_RATE_PARENT, 0), + GATE(CLK_GOUT_FSYS_PIPE_PAL_INST_0_I_APB_PCLK, "pipe_pal_inst_0_i_apb_pclk", + "dout_fsys_bus300", CLK_CON_DMYQCH_CON_PCIE_TOP_QCH, 1, CLK_SET_RATE_PARENT, 0), + GATE(CLK_GOUT_FSYS_QSPI_IPCLKPORT_HCLK, "qspi_ipclkport_hclk", + "dout_fsys_bus_qspi", CLK_CON_DMYQCH_CON_QSPI_QCH, 1, CLK_SET_RATE_PARENT, 0), + GATE(CLK_GOUT_FSYS_QSPI_IPCLKPORT_SSI_CLK, "qspi_ipclkport_ssi_clk", + "dout_fsys_qspi", CLK_CON_DMYQCH_CON_QSPI_QCH, 1, CLK_SET_RATE_PARENT, 0), + GATE(CLK_GOUT_FSYS_MMC0_IPCLKPORT_SDCLKIN, "mmc0_ipclkport_sdclkin", + "dout_fsys_mmc_card0", CLK_CON_DMYQCH_CON_MMC0_QCH, 1, CLK_SET_RATE_PARENT, 0), + GATE(CLK_GOUT_FSYS_MMC1_IPCLKPORT_SDCLKIN, "mmc1_ipclkport_sdclkin", + "dout_fsys_mmc_card1", CLK_CON_DMYQCH_CON_MMC1_QCH, 1, CLK_SET_RATE_PARENT, 0), + GATE(CLK_GOUT_FSYS_SFMC_IPCLKPORT_I_ACLK_NAND, "sfmc_ipclkport_i_aclk_nand", + "dout_fsys_sfmc_nand", CLK_CON_DMYQCH_CON_SFMC_QCH, 1, CLK_SET_RATE_PARENT, 0), + GATE(CLK_GOUT_FSYS_UART0_SCLK_UART, "uart0_sclk", "dout_fsys_sclk_uart", + CLK_CON_FSYS_UART0_IPCLKPORT_I_SCLK_UART, 21, + CLK_SET_RATE_PARENT | CLK_IS_CRITICAL, 0), + GATE(CLK_GOUT_FSYS_DWC_PCIE_CTL_INST_0_MSTR_ACLK_UG, "dwc_pcie_ctl_inst_0_mstr_aclk_ug", + "mout_fsys_bus_user", CLK_CON_DWC_PCIE_CTL_INST_0_MSTR_ACLK_UG, 21, + CLK_SET_RATE_PARENT | CLK_IS_CRITICAL, 0), + GATE(CLK_GOUT_FSYS_DWC_PCIE_CTL_INXT_0_SLV_ACLK_UG, "dwc_pcie_ctl_inst_0_slv_aclk_ug", + "mout_fsys_bus_user", CLK_CON_DWC_PCIE_CTL_INST_0_SLV_ACLK_UG, 21, + CLK_SET_RATE_PARENT | CLK_IS_CRITICAL, 0), + GATE(CLK_GOUT_FSYS_I2C0_IPCLKPORT_I_PCLK, "fsys_i2c0_ipclkport_i_pclk", "dout_fsys_bus300", + CLK_CON_FSYS_I2C0_IPCLKPORT_I_PCLK, 21, CLK_SET_RATE_PARENT | CLK_IS_CRITICAL, 0), + GATE(CLK_GOUT_FSYS_I2C1_IPCLKPORT_I_PCLK, "fsys_i2c1_ipclkport_i_pclk", "dout_fsys_bus300", + CLK_CON_FSYS_I2C1_IPCLKPORT_I_PCLK, 21, CLK_SET_RATE_PARENT | CLK_IS_CRITICAL, 0), + GATE(CLK_GOUT_FSYS_UART0_PCLK, "uart0_pclk", "dout_fsys_bus300", + CLK_CON_FSYS_UART0_IPCLKPORT_I_PCLK, 21, CLK_SET_RATE_PARENT | CLK_IS_CRITICAL, 0), + GATE(CLK_GOUT_FSYS_MMC0_IPCLKPORT_I_ACLK, "mmc0_ipclkport_i_aclk", "dout_fsys_bus300", + CLK_CON_MMC0_IPCLKPORT_I_ACLK, 21, CLK_SET_RATE_PARENT | CLK_IS_CRITICAL, 0), + GATE(CLK_GOUT_FSYS_MMC1_IPCLKPORT_I_ACLK, "mmc1_ipclkport_i_aclk", "dout_fsys_bus300", + CLK_CON_MMC1_IPCLKPORT_I_ACLK, 21, CLK_SET_RATE_PARENT | CLK_IS_CRITICAL, 0), + GATE(CLK_GOUT_FSYS_DWC_PCIE_CTL_INST_0_DBI_ACLK_UG, "dwc_pcie_ctl_inst_0_dbi_aclk_ug", + "dout_fsys_bus300", CLK_CON_DWC_PCIE_CTL_INST_0_DBI_ACLK_UG, 21, + CLK_SET_RATE_PARENT | CLK_IS_CRITICAL, 0), + GATE(CLK_GOUT_FSYS_PWM_IPCLKPORT_I_PCLK_S0, "pwm_ipclkport_i_pclk_s0", "dout_fsys_bus300", + CLK_CON_PWM_IPCLKPORT_I_PCLK_S0, 21, CLK_SET_RATE_PARENT | CLK_IS_CRITICAL, 0), + GATE(CLK_GOUT_FSYS_USB20DRD_IPCLKPORT_ACLK_PHYCTRL_20, "usb20drd_ipclkport_aclk_phyctrl_20", + "dout_fsys_bus300", CLK_CON_USB20DRD_IPCLKPORT_ACLK_PHYCTRL_20, 21, + CLK_SET_RATE_PARENT | CLK_IS_CRITICAL, 0), + GATE(CLK_GOUT_FSYS_USB20DRD_IPCLKPORT_BUS_CLK_EARLY, "usb20drd_ipclkport_bus_clk_early", + "dout_fsys_bus300", CLK_CON_USB20DRD_IPCLKPORT_BUS_CLK_EARLY, 21, + CLK_SET_RATE_PARENT | CLK_IS_CRITICAL, 0), + GATE(CLK_GOUT_FSYS_XHB_AHBBR_IPCLKPORT_CLK, "xhb_ahbbr_ipclkport_clk", "dout_fsys_bus300", + CLK_CON_XHB_AHBBR_IPCLKPORT_CLK, 21, CLK_SET_RATE_PARENT | CLK_IS_CRITICAL, 0), + GATE(CLK_GOUT_FSYS_XHB_USB_IPCLKPORT_CLK, "xhb_usb_ipclkport_clk", "dout_fsys_bus300", + CLK_CON_XHB_USB_IPCLKPORT_CLK, 21, CLK_SET_RATE_PARENT | CLK_IS_CRITICAL, 0), + GATE(CLK_GOUT_FSYS_BUS_QSPI, "bus_p_fsys_ipclkport_qspiclk", "dout_fsys_bus_qspi", + CLK_CON_BUS_P_FSYS_IPCLKPORT_QSPICLK, 21, CLK_SET_RATE_PARENT | CLK_IS_CRITICAL, 0), +}; + +static const struct samsung_cmu_info cmu_fsys_info __initconst = { + .pll_clks = cmu_fsys_pll_clks, + .nr_pll_clks = ARRAY_SIZE(cmu_fsys_pll_clks), + .mux_clks = cmu_fsys_mux_clks, + .nr_mux_clks = ARRAY_SIZE(cmu_fsys_mux_clks), + .div_clks = cmu_fsys_div_clks, + .nr_div_clks = ARRAY_SIZE(cmu_fsys_div_clks), + .gate_clks = cmu_fsys_gate_clks, + .nr_gate_clks = ARRAY_SIZE(cmu_fsys_gate_clks), + .nr_clk_ids = CMU_FSYS_NR_CLK, + .clk_regs = cmu_fsys_clk_regs, + .nr_clk_regs = ARRAY_SIZE(cmu_fsys_clk_regs), +}; + +/* Register Offset definitions for CMU_IMEM (0x10010000) */ +#define PLL_CON0_MUX_CLK_IMEM_ACLK_USER 0x0100 +#define PLL_CON0_MUX_CLK_IMEM_JPEG_USER 0x0120 +#define CLK_CON_MUX_CLK_IMEM_GIC_CA53 0x1000 +#define CLK_CON_MUX_CLK_IMEM_GIC_CA5 0x1008 +#define CLK_CON_MCT_IPCLKPORT_PCLK 0x2038 +#define CLK_CON_SFRIF_TMU_IMEM_IPCLKPORT_PCLK 0x2044 + +static const unsigned long cmu_imem_clk_regs[] __initconst = { + PLL_CON0_MUX_CLK_IMEM_ACLK_USER, + PLL_CON0_MUX_CLK_IMEM_JPEG_USER, + CLK_CON_MUX_CLK_IMEM_GIC_CA53, + CLK_CON_MUX_CLK_IMEM_GIC_CA5, + CLK_CON_MCT_IPCLKPORT_PCLK, + CLK_CON_SFRIF_TMU_IMEM_IPCLKPORT_PCLK, +}; + +PNAME(mout_imem_aclk_user_p) = { "fin_pll", "dout_clkcmu_imem_aclk" }; +PNAME(mout_imem_gic_ca53_p) = { "mout_imem_aclk_user", "fin_pll" }; +PNAME(mout_imem_gic_ca5_p) = { "mout_imem_aclk_user", "fin_pll" }; +PNAME(mout_imem_jpeg_user_p) = { "fin_pll", "dout_clkcmu_imem_jpeg" }; + +static const struct samsung_mux_clock cmu_imem_mux_clks[] __initconst = { + MUX(CLK_MOUT_IMEM_ACLK_USER, "mout_imem_aclk_user", + mout_imem_aclk_user_p, PLL_CON0_MUX_CLK_IMEM_ACLK_USER, 4, 1), + MUX(CLK_MOUT_IMEM_GIC_CA53, "mout_imem_gic_ca53", + mout_imem_gic_ca53_p, CLK_CON_MUX_CLK_IMEM_GIC_CA53, 0, 1), + MUX(CLK_MOUT_IMEM_GIC_CA5, "mout_imem_gic_ca5", + mout_imem_gic_ca5_p, CLK_CON_MUX_CLK_IMEM_GIC_CA5, 0, 1), + MUX(CLK_MOUT_IMEM_JPEG_USER, "mout_imem_jpeg_user", + mout_imem_jpeg_user_p, PLL_CON0_MUX_CLK_IMEM_JPEG_USER, 4, 1), +}; + +static const struct samsung_gate_clock cmu_imem_gate_clks[] __initconst = { + GATE(CLK_GOUT_IMEM_MCT_PCLK, "mct_pclk", "mout_imem_aclk_user", + CLK_CON_MCT_IPCLKPORT_PCLK, 21, CLK_SET_RATE_PARENT | CLK_IS_CRITICAL, 0), + GATE(CLK_GOUT_IMEM_PCLK_TMU0_APBIF, "sfrif_tmu_imem_ipclkport_pclk", "mout_imem_aclk_user", + CLK_CON_SFRIF_TMU_IMEM_IPCLKPORT_PCLK, 21, CLK_SET_RATE_PARENT | CLK_IS_CRITICAL, 0), +}; + +static const struct samsung_cmu_info cmu_imem_info __initconst = { + .mux_clks = cmu_imem_mux_clks, + .nr_mux_clks = ARRAY_SIZE(cmu_imem_mux_clks), + .gate_clks = cmu_imem_gate_clks, + .nr_gate_clks = ARRAY_SIZE(cmu_imem_gate_clks), + .nr_clk_ids = CMU_IMEM_NR_CLK, + .clk_regs = cmu_imem_clk_regs, + .nr_clk_regs = ARRAY_SIZE(cmu_imem_clk_regs), +}; + +static void __init artpec8_clk_cmu_imem_init(struct device_node *np) +{ + samsung_cmu_register_one(np, &cmu_imem_info); +} + +CLK_OF_DECLARE(artpec8_clk_cmu_imem, "axis,artpec8-cmu-imem", artpec8_clk_cmu_imem_init); + +/* Register Offset definitions for CMU_PERI (0x16410000) */ +#define PLL_CON0_MUX_CLK_PERI_AUDIO_USER 0x0100 +#define PLL_CON0_MUX_CLK_PERI_DISP_USER 0x0120 +#define PLL_CON0_MUX_CLK_PERI_IP_USER 0x0140 +#define CLK_CON_MUX_CLK_PERI_I2S0 0x1000 +#define CLK_CON_MUX_CLK_PERI_I2S1 0x1004 +#define CLK_CON_DIV_CLK_PERI_DSIM 0x1800 +#define CLK_CON_DIV_CLK_PERI_I2S0 0x1804 +#define CLK_CON_DIV_CLK_PERI_I2S1 0x1808 +#define CLK_CON_DIV_CLK_PERI_PCLK 0x180c +#define CLK_CON_DIV_CLK_PERI_SPI 0x1810 +#define CLK_CON_DIV_CLK_PERI_UART1 0x1814 +#define CLK_CON_DIV_CLK_PERI_UART2 0x1818 +#define CLK_CON_APB_ASYNC_DSIM_IPCLKPORT_PCLKS 0x2004 +#define CLK_CON_PERI_I2C2_IPCLKPORT_I_PCLK 0x2030 +#define CLK_CON_PERI_I2C3_IPCLKPORT_I_PCLK 0x2034 +#define CLK_CON_PERI_SPI0_IPCLKPORT_I_PCLK 0x2048 +#define CLK_CON_PERI_SPI0_IPCLKPORT_I_SCLK_SPI 0x204c +#define CLK_CON_PERI_UART1_IPCLKPORT_I_PCLK 0x2050 +#define CLK_CON_PERI_UART1_IPCLKPORT_I_SCLK_UART 0x2054 +#define CLK_CON_PERI_UART2_IPCLKPORT_I_PCLK 0x2058 +#define CLK_CON_PERI_UART2_IPCLKPORT_I_SCLK_UART 0x205c +#define CLK_CON_DMYQCH_CON_AUDIO_OUT_QCH 0x3000 +#define CLK_CON_DMYQCH_CON_DMA4DSIM_QCH 0x3004 +#define CLK_CON_DMYQCH_CON_PERI_I2SSC0_QCH 0x3008 +#define CLK_CON_DMYQCH_CON_PERI_I2SSC1_QCH 0x300c + +static const unsigned long cmu_peri_clk_regs[] __initconst = { + PLL_CON0_MUX_CLK_PERI_AUDIO_USER, + PLL_CON0_MUX_CLK_PERI_DISP_USER, + PLL_CON0_MUX_CLK_PERI_IP_USER, + CLK_CON_MUX_CLK_PERI_I2S0, + CLK_CON_MUX_CLK_PERI_I2S1, + CLK_CON_DIV_CLK_PERI_DSIM, + CLK_CON_DIV_CLK_PERI_I2S0, + CLK_CON_DIV_CLK_PERI_I2S1, + CLK_CON_DIV_CLK_PERI_PCLK, + CLK_CON_DIV_CLK_PERI_SPI, + CLK_CON_DIV_CLK_PERI_UART1, + CLK_CON_DIV_CLK_PERI_UART2, + CLK_CON_APB_ASYNC_DSIM_IPCLKPORT_PCLKS, + CLK_CON_PERI_I2C2_IPCLKPORT_I_PCLK, + CLK_CON_PERI_I2C3_IPCLKPORT_I_PCLK, + CLK_CON_PERI_SPI0_IPCLKPORT_I_PCLK, + CLK_CON_PERI_SPI0_IPCLKPORT_I_SCLK_SPI, + CLK_CON_PERI_UART1_IPCLKPORT_I_PCLK, + CLK_CON_PERI_UART1_IPCLKPORT_I_SCLK_UART, + CLK_CON_PERI_UART2_IPCLKPORT_I_PCLK, + CLK_CON_PERI_UART2_IPCLKPORT_I_SCLK_UART, + CLK_CON_DMYQCH_CON_AUDIO_OUT_QCH, + CLK_CON_DMYQCH_CON_DMA4DSIM_QCH, + CLK_CON_DMYQCH_CON_PERI_I2SSC0_QCH, + CLK_CON_DMYQCH_CON_PERI_I2SSC1_QCH, +}; + +static const struct samsung_fixed_rate_clock peri_fixed_clks[] __initconst = { + FRATE(0, "clk_peri_audio", NULL, 0, 100000000), +}; + +PNAME(mout_peri_ip_user_p) = { "fin_pll", "dout_clkcmu_peri_ip" }; +PNAME(mout_peri_audio_user_p) = { "fin_pll", "dout_clkcmu_peri_audio" }; +PNAME(mout_peri_disp_user_p) = { "fin_pll", "dout_clkcmu_peri_disp" }; +PNAME(mout_peri_i2s0_p) = { "dout_peri_i2s0", "clk_peri_audio" }; +PNAME(mout_peri_i2s1_p) = { "dout_peri_i2s1", "clk_peri_audio" }; + +static const struct samsung_mux_clock cmu_peri_mux_clks[] __initconst = { + MUX(CLK_MOUT_PERI_IP_USER, "mout_peri_ip_user", mout_peri_ip_user_p, + PLL_CON0_MUX_CLK_PERI_IP_USER, 4, 1), + MUX(CLK_MOUT_PERI_AUDIO_USER, "mout_peri_audio_user", + mout_peri_audio_user_p, PLL_CON0_MUX_CLK_PERI_AUDIO_USER, 4, 1), + MUX(CLK_MOUT_PERI_DISP_USER, "mout_peri_disp_user", mout_peri_disp_user_p, + PLL_CON0_MUX_CLK_PERI_DISP_USER, 4, 1), + MUX(CLK_MOUT_PERI_I2S0, "mout_peri_i2s0", mout_peri_i2s0_p, + CLK_CON_MUX_CLK_PERI_I2S0, 0, 1), + MUX(CLK_MOUT_PERI_I2S1, "mout_peri_i2s1", mout_peri_i2s1_p, + CLK_CON_MUX_CLK_PERI_I2S1, 0, 1), +}; + +static const struct samsung_div_clock cmu_peri_div_clks[] __initconst = { + DIV(CLK_DOUT_PERI_SPI, "dout_peri_spi", "mout_peri_ip_user", + CLK_CON_DIV_CLK_PERI_SPI, 0, 10), + DIV(CLK_DOUT_PERI_UART1, "dout_peri_uart1", "mout_peri_ip_user", + CLK_CON_DIV_CLK_PERI_UART1, 0, 10), + DIV(CLK_DOUT_PERI_UART2, "dout_peri_uart2", "mout_peri_ip_user", + CLK_CON_DIV_CLK_PERI_UART2, 0, 10), + DIV(CLK_DOUT_PERI_PCLK, "dout_peri_pclk", "mout_peri_ip_user", + CLK_CON_DIV_CLK_PERI_PCLK, 0, 4), + DIV(CLK_DOUT_PERI_I2S0, "dout_peri_i2s0", "mout_peri_audio_user", + CLK_CON_DIV_CLK_PERI_I2S0, 0, 4), + DIV(CLK_DOUT_PERI_I2S1, "dout_peri_i2s1", "mout_peri_audio_user", + CLK_CON_DIV_CLK_PERI_I2S1, 0, 4), + DIV(CLK_DOUT_PERI_DSIM, "dout_peri_dsim", "mout_peri_disp_user", + CLK_CON_DIV_CLK_PERI_DSIM, 0, 4), +}; + +static const struct samsung_gate_clock cmu_peri_gate_clks[] __initconst = { + GATE(CLK_GOUT_PERI_DMA4DSIM_IPCLKPORT_CLK_APB_CLK, "dma4dsim_ipclkport_clk_apb_clk", + "dout_peri_pclk", CLK_CON_DMYQCH_CON_DMA4DSIM_QCH, 1, CLK_SET_RATE_PARENT, 0), + GATE(CLK_GOUT_PERI_I2SSC0_IPCLKPORT_CLK_HST, "i2ssc0_ipclkport_clk_hst", "dout_peri_pclk", + CLK_CON_DMYQCH_CON_PERI_I2SSC0_QCH, 1, CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, 0), + GATE(CLK_GOUT_PERI_I2SSC1_IPCLKPORT_CLK_HST, "i2ssc1_ipclkport_clk_hst", "dout_peri_pclk", + CLK_CON_DMYQCH_CON_PERI_I2SSC1_QCH, 1, CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, 0), + GATE(CLK_GOUT_PERI_AUDIO_OUT_IPCLKPORT_CLK, "audio_out_ipclkport_clk", + "mout_peri_audio_user", CLK_CON_DMYQCH_CON_AUDIO_OUT_QCH, 1, CLK_SET_RATE_PARENT, 0), + GATE(CLK_GOUT_PERI_I2SSC0_IPCLKPORT_CLK, "peri_i2ssc0_ipclkport_clk", "mout_peri_i2s0", + CLK_CON_DMYQCH_CON_PERI_I2SSC0_QCH, 1, CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, 0), + GATE(CLK_GOUT_PERI_I2SSC1_IPCLKPORT_CLK, "peri_i2ssc1_ipclkport_clk", "mout_peri_i2s1", + CLK_CON_DMYQCH_CON_PERI_I2SSC1_QCH, 1, CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, 0), + GATE(CLK_GOUT_PERI_DMA4DSIM_IPCLKPORT_CLK_AXI_CLK, "dma4dsim_ipclkport_clk_axi_clk", + "mout_peri_disp_user", CLK_CON_DMYQCH_CON_DMA4DSIM_QCH, 1, CLK_SET_RATE_PARENT, 0), + GATE(CLK_GOUT_PERI_SPI0_SCLK_SPI, "peri_spi0_ipclkport_i_sclk_spi", "dout_peri_spi", + CLK_CON_PERI_SPI0_IPCLKPORT_I_SCLK_SPI, 21, CLK_SET_RATE_PARENT | CLK_IS_CRITICAL, 0), + GATE(CLK_GOUT_PERI_UART1_SCLK_UART, "uart1_sclk", "dout_peri_uart1", + CLK_CON_PERI_UART1_IPCLKPORT_I_SCLK_UART, 21, + CLK_SET_RATE_PARENT | CLK_IS_CRITICAL, 0), + GATE(CLK_GOUT_PERI_UART2_SCLK_UART, "uart2_sclk", "dout_peri_uart2", + CLK_CON_PERI_UART2_IPCLKPORT_I_SCLK_UART, 21, + CLK_SET_RATE_PARENT | CLK_IS_CRITICAL, 0), + GATE(CLK_GOUT_PERI_APB_ASYNC_DSIM_IPCLKPORT_PCLKS, "apb_async_dsim_ipclkport_pclks", + "dout_peri_pclk", CLK_CON_APB_ASYNC_DSIM_IPCLKPORT_PCLKS, 21, + CLK_SET_RATE_PARENT | CLK_IS_CRITICAL, 0), + GATE(CLK_GOUT_PERI_I2C2_IPCLKPORT_I_PCLK, "peri_i2c2_ipclkport_i_pclk", "dout_peri_pclk", + CLK_CON_PERI_I2C2_IPCLKPORT_I_PCLK, 21, CLK_SET_RATE_PARENT | CLK_IS_CRITICAL, 0), + GATE(CLK_GOUT_PERI_I2C3_IPCLKPORT_I_PCLK, "peri_i2c3_ipclkport_i_pclk", "dout_peri_pclk", + CLK_CON_PERI_I2C3_IPCLKPORT_I_PCLK, 21, CLK_SET_RATE_PARENT | CLK_IS_CRITICAL, 0), + GATE(CLK_GOUT_PERI_SPI0_PCLK, "peri_spi0_ipclkport_i_pclk", "dout_peri_pclk", + CLK_CON_PERI_SPI0_IPCLKPORT_I_PCLK, 21, CLK_SET_RATE_PARENT | CLK_IS_CRITICAL, 0), + GATE(CLK_GOUT_PERI_UART1_PCLK, "uart1_pclk", "dout_peri_pclk", + CLK_CON_PERI_UART1_IPCLKPORT_I_PCLK, 21, CLK_SET_RATE_PARENT | CLK_IS_CRITICAL, 0), + GATE(CLK_GOUT_PERI_UART2_PCLK, "uart2_pclk", "dout_peri_pclk", + CLK_CON_PERI_UART2_IPCLKPORT_I_PCLK, 21, CLK_SET_RATE_PARENT | CLK_IS_CRITICAL, 0), +}; + +static const struct samsung_cmu_info cmu_peri_info __initconst = { + .mux_clks = cmu_peri_mux_clks, + .nr_mux_clks = ARRAY_SIZE(cmu_peri_mux_clks), + .div_clks = cmu_peri_div_clks, + .nr_div_clks = ARRAY_SIZE(cmu_peri_div_clks), + .gate_clks = cmu_peri_gate_clks, + .nr_gate_clks = ARRAY_SIZE(cmu_peri_gate_clks), + .fixed_clks = peri_fixed_clks, + .nr_fixed_clks = ARRAY_SIZE(peri_fixed_clks), + .nr_clk_ids = CMU_PERI_NR_CLK, + .clk_regs = cmu_peri_clk_regs, + .nr_clk_regs = ARRAY_SIZE(cmu_peri_clk_regs), +}; + +/** + * artpec8_cmu_probe - Probe function for ARTPEC platform clocks + * @pdev: Pointer to platform device + * + * Configure clock hierarchy for clock domains of ARTPEC platform + */ +static int __init artpec8_cmu_probe(struct platform_device *pdev) +{ + const struct samsung_cmu_info *info; + struct device *dev = &pdev->dev; + + info = of_device_get_match_data(dev); + exynos_arm64_register_cmu(dev, dev->of_node, info); + + return 0; +} + +static const struct of_device_id artpec8_cmu_of_match[] = { + { + .compatible = "axis,artpec8-cmu-cmu", + .data = &cmu_cmu_info, + }, { + .compatible = "axis,artpec8-cmu-bus", + .data = &cmu_bus_info, + }, { + .compatible = "axis,artpec8-cmu-core", + .data = &cmu_core_info, + }, { + .compatible = "axis,artpec8-cmu-cpucl", + .data = &cmu_cpucl_info, + }, { + .compatible = "axis,artpec8-cmu-fsys", + .data = &cmu_fsys_info, + }, { + .compatible = "axis,artpec8-cmu-peri", + .data = &cmu_peri_info, + }, { + }, +}; + +static struct platform_driver artpec8_cmu_driver __refdata = { + .driver = { + .name = "artpec8-cmu", + .of_match_table = artpec8_cmu_of_match, + .suppress_bind_attrs = true, + }, + .probe = artpec8_cmu_probe, +}; + +static int __init artpec8_cmu_init(void) +{ + return platform_driver_register(&artpec8_cmu_driver); +} +core_initcall(artpec8_cmu_init); diff --git a/drivers/clk/samsung/clk-cpu.c b/drivers/clk/samsung/clk-cpu.c index 4e1ebd8a30b1..300f8d5d3c48 100644 --- a/drivers/clk/samsung/clk-cpu.c +++ b/drivers/clk/samsung/clk-cpu.c @@ -567,12 +567,14 @@ static int exynos850_cpuclk_post_rate_change(struct clk_notifier_data *ndata, /* -------------------------------------------------------------------------- */ /* Common round rate callback usable for all types of CPU clocks */ -static long exynos_cpuclk_round_rate(struct clk_hw *hw, unsigned long drate, - unsigned long *prate) +static int exynos_cpuclk_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { struct clk_hw *parent = clk_hw_get_parent(hw); - *prate = clk_hw_round_rate(parent, drate); - return *prate; + req->best_parent_rate = clk_hw_round_rate(parent, req->rate); + req->rate = req->best_parent_rate; + + return 0; } /* Common recalc rate callback usable for all types of CPU clocks */ @@ -591,7 +593,7 @@ static unsigned long exynos_cpuclk_recalc_rate(struct clk_hw *hw, static const struct clk_ops exynos_cpuclk_clk_ops = { .recalc_rate = exynos_cpuclk_recalc_rate, - .round_rate = exynos_cpuclk_round_rate, + .determine_rate = exynos_cpuclk_determine_rate, }; /* diff --git a/drivers/clk/samsung/clk-exynos990.c b/drivers/clk/samsung/clk-exynos990.c index 8d3f193d2b4d..6277dd557fab 100644 --- a/drivers/clk/samsung/clk-exynos990.c +++ b/drivers/clk/samsung/clk-exynos990.c @@ -17,8 +17,10 @@ #include "clk-pll.h" /* NOTE: Must be equal to the last clock ID increased by one */ -#define CLKS_NR_TOP (CLK_GOUT_CMU_VRA_BUS + 1) -#define CLKS_NR_HSI0 (CLK_GOUT_HSI0_XIU_D_HSI0_ACLK + 1) +#define CLKS_NR_TOP (CLK_DOUT_CMU_CLK_CMUREF + 1) +#define CLKS_NR_HSI0 (CLK_GOUT_HSI0_LHS_ACEL_D_HSI0_CLK + 1) +#define CLKS_NR_PERIC0 (CLK_GOUT_PERIC0_SYSREG_PCLK + 1) +#define CLKS_NR_PERIC1 (CLK_GOUT_PERIC1_XIU_P_ACLK + 1) #define CLKS_NR_PERIS (CLK_GOUT_PERIS_OTP_CON_TOP_OSCCLK + 1) /* ---- CMU_TOP ------------------------------------------------------------- */ @@ -45,6 +47,7 @@ #define PLL_CON3_PLL_SHARED3 0x024c #define PLL_CON0_PLL_SHARED4 0x0280 #define PLL_CON3_PLL_SHARED4 0x028c +#define CLK_CON_MUX_CLKCMU_DPU_BUS 0x1000 #define CLK_CON_MUX_MUX_CLKCMU_APM_BUS 0x1004 #define CLK_CON_MUX_MUX_CLKCMU_AUD_CPU 0x1008 #define CLK_CON_MUX_MUX_CLKCMU_BUS0_BUS 0x100c @@ -103,6 +106,8 @@ #define CLK_CON_MUX_MUX_CLKCMU_SSP_BUS 0x10e0 #define CLK_CON_MUX_MUX_CLKCMU_TNR_BUS 0x10e4 #define CLK_CON_MUX_MUX_CLKCMU_VRA_BUS 0x10e8 +#define CLK_CON_MUX_MUX_CLK_CMU_CMUREF 0x10f0 +#define CLK_CON_MUX_MUX_CMU_CMUREF 0x10f4 #define CLK_CON_DIV_CLKCMU_APM_BUS 0x1800 #define CLK_CON_DIV_CLKCMU_AUD_CPU 0x1804 #define CLK_CON_DIV_CLKCMU_BUS0_BUS 0x1808 @@ -162,6 +167,7 @@ #define CLK_CON_DIV_CLKCMU_VRA_BUS 0x18e0 #define CLK_CON_DIV_DIV_CLKCMU_DPU 0x18e8 #define CLK_CON_DIV_DIV_CLKCMU_DPU_ALT 0x18ec +#define CLK_CON_DIV_DIV_CLK_CMU_CMUREF 0x18f0 #define CLK_CON_DIV_PLL_SHARED0_DIV2 0x18f4 #define CLK_CON_DIV_PLL_SHARED0_DIV3 0x18f8 #define CLK_CON_DIV_PLL_SHARED0_DIV4 0x18fc @@ -239,13 +245,21 @@ static const unsigned long top_clk_regs[] __initconst = { PLL_LOCKTIME_PLL_SHARED2, PLL_LOCKTIME_PLL_SHARED3, PLL_LOCKTIME_PLL_SHARED4, + PLL_CON0_PLL_G3D, PLL_CON3_PLL_G3D, + PLL_CON0_PLL_MMC, PLL_CON3_PLL_MMC, + PLL_CON0_PLL_SHARED0, PLL_CON3_PLL_SHARED0, + PLL_CON0_PLL_SHARED1, PLL_CON3_PLL_SHARED1, + PLL_CON0_PLL_SHARED2, PLL_CON3_PLL_SHARED2, + PLL_CON0_PLL_SHARED3, PLL_CON3_PLL_SHARED3, + PLL_CON0_PLL_SHARED4, PLL_CON3_PLL_SHARED4, + CLK_CON_MUX_CLKCMU_DPU_BUS, CLK_CON_MUX_MUX_CLKCMU_APM_BUS, CLK_CON_MUX_MUX_CLKCMU_AUD_CPU, CLK_CON_MUX_MUX_CLKCMU_BUS0_BUS, @@ -304,6 +318,8 @@ static const unsigned long top_clk_regs[] __initconst = { CLK_CON_MUX_MUX_CLKCMU_SSP_BUS, CLK_CON_MUX_MUX_CLKCMU_TNR_BUS, CLK_CON_MUX_MUX_CLKCMU_VRA_BUS, + CLK_CON_MUX_MUX_CLK_CMU_CMUREF, + CLK_CON_MUX_MUX_CMU_CMUREF, CLK_CON_DIV_CLKCMU_APM_BUS, CLK_CON_DIV_CLKCMU_AUD_CPU, CLK_CON_DIV_CLKCMU_BUS0_BUS, @@ -363,6 +379,7 @@ static const unsigned long top_clk_regs[] __initconst = { CLK_CON_DIV_CLKCMU_VRA_BUS, CLK_CON_DIV_DIV_CLKCMU_DPU, CLK_CON_DIV_DIV_CLKCMU_DPU_ALT, + CLK_CON_DIV_DIV_CLK_CMU_CMUREF, CLK_CON_DIV_PLL_SHARED0_DIV2, CLK_CON_DIV_PLL_SHARED0_DIV3, CLK_CON_DIV_PLL_SHARED0_DIV4, @@ -458,6 +475,8 @@ PNAME(mout_pll_shared3_p) = { "oscclk", "fout_shared3_pll" }; PNAME(mout_pll_shared4_p) = { "oscclk", "fout_shared4_pll" }; PNAME(mout_pll_mmc_p) = { "oscclk", "fout_mmc_pll" }; PNAME(mout_pll_g3d_p) = { "oscclk", "fout_g3d_pll" }; +PNAME(mout_cmu_dpu_bus_p) = { "dout_cmu_dpu", + "dout_cmu_dpu_alt" }; PNAME(mout_cmu_apm_bus_p) = { "dout_cmu_shared0_div2", "dout_cmu_shared2_div2" }; PNAME(mout_cmu_aud_cpu_p) = { "dout_cmu_shared0_div2", @@ -672,6 +691,12 @@ PNAME(mout_cmu_vra_bus_p) = { "dout_cmu_shared0_div3", "dout_cmu_shared4_div2", "dout_cmu_shared0_div4", "dout_cmu_shared4_div3" }; +PNAME(mout_cmu_cmuref_p) = { "oscclk", + "dout_cmu_clk_cmuref" }; +PNAME(mout_cmu_clk_cmuref_p) = { "dout_cmu_shared0_div4", + "dout_cmu_shared1_div4", + "dout_cmu_shared2_div2", + "oscclk" }; /* * Register name to clock name mangling strategy used in this file @@ -689,19 +714,21 @@ PNAME(mout_cmu_vra_bus_p) = { "dout_cmu_shared0_div3", static const struct samsung_mux_clock top_mux_clks[] __initconst = { MUX(CLK_MOUT_PLL_SHARED0, "mout_pll_shared0", mout_pll_shared0_p, - PLL_CON3_PLL_SHARED0, 4, 1), + PLL_CON0_PLL_SHARED0, 4, 1), MUX(CLK_MOUT_PLL_SHARED1, "mout_pll_shared1", mout_pll_shared1_p, - PLL_CON3_PLL_SHARED1, 4, 1), + PLL_CON0_PLL_SHARED1, 4, 1), MUX(CLK_MOUT_PLL_SHARED2, "mout_pll_shared2", mout_pll_shared2_p, - PLL_CON3_PLL_SHARED2, 4, 1), + PLL_CON0_PLL_SHARED2, 4, 1), MUX(CLK_MOUT_PLL_SHARED3, "mout_pll_shared3", mout_pll_shared3_p, - PLL_CON3_PLL_SHARED3, 4, 1), + PLL_CON0_PLL_SHARED3, 4, 1), MUX(CLK_MOUT_PLL_SHARED4, "mout_pll_shared4", mout_pll_shared4_p, PLL_CON0_PLL_SHARED4, 4, 1), MUX(CLK_MOUT_PLL_MMC, "mout_pll_mmc", mout_pll_mmc_p, PLL_CON0_PLL_MMC, 4, 1), MUX(CLK_MOUT_PLL_G3D, "mout_pll_g3d", mout_pll_g3d_p, PLL_CON0_PLL_G3D, 4, 1), + MUX(CLK_MOUT_CMU_DPU_BUS, "mout_cmu_dpu_bus", + mout_cmu_dpu_bus_p, CLK_CON_MUX_CLKCMU_DPU_BUS, 0, 1), MUX(CLK_MOUT_CMU_APM_BUS, "mout_cmu_apm_bus", mout_cmu_apm_bus_p, CLK_CON_MUX_MUX_CLKCMU_APM_BUS, 0, 1), MUX(CLK_MOUT_CMU_AUD_CPU, "mout_cmu_aud_cpu", @@ -759,11 +786,11 @@ static const struct samsung_mux_clock top_mux_clks[] __initconst = { MUX(CLK_MOUT_CMU_DPU_ALT, "mout_cmu_dpu_alt", mout_cmu_dpu_alt_p, CLK_CON_MUX_MUX_CLKCMU_DPU_ALT, 0, 2), MUX(CLK_MOUT_CMU_DSP_BUS, "mout_cmu_dsp_bus", - mout_cmu_dsp_bus_p, CLK_CON_MUX_MUX_CLKCMU_DSP_BUS, 0, 2), + mout_cmu_dsp_bus_p, CLK_CON_MUX_MUX_CLKCMU_DSP_BUS, 0, 3), MUX(CLK_MOUT_CMU_G2D_G2D, "mout_cmu_g2d_g2d", mout_cmu_g2d_g2d_p, CLK_CON_MUX_MUX_CLKCMU_G2D_G2D, 0, 2), MUX(CLK_MOUT_CMU_G2D_MSCL, "mout_cmu_g2d_mscl", - mout_cmu_g2d_mscl_p, CLK_CON_MUX_MUX_CLKCMU_G2D_MSCL, 0, 1), + mout_cmu_g2d_mscl_p, CLK_CON_MUX_MUX_CLKCMU_G2D_MSCL, 0, 2), MUX(CLK_MOUT_CMU_HPM, "mout_cmu_hpm", mout_cmu_hpm_p, CLK_CON_MUX_MUX_CLKCMU_HPM, 0, 2), MUX(CLK_MOUT_CMU_HSI0_BUS, "mout_cmu_hsi0_bus", @@ -775,7 +802,7 @@ static const struct samsung_mux_clock top_mux_clks[] __initconst = { 0, 2), MUX(CLK_MOUT_CMU_HSI0_USBDP_DEBUG, "mout_cmu_hsi0_usbdp_debug", mout_cmu_hsi0_usbdp_debug_p, - CLK_CON_MUX_MUX_CLKCMU_HSI0_USBDP_DEBUG, 0, 2), + CLK_CON_MUX_MUX_CLKCMU_HSI0_USBDP_DEBUG, 0, 1), MUX(CLK_MOUT_CMU_HSI1_BUS, "mout_cmu_hsi1_bus", mout_cmu_hsi1_bus_p, CLK_CON_MUX_MUX_CLKCMU_HSI1_BUS, 0, 3), MUX(CLK_MOUT_CMU_HSI1_MMC_CARD, "mout_cmu_hsi1_mmc_card", @@ -788,7 +815,7 @@ static const struct samsung_mux_clock top_mux_clks[] __initconst = { 0, 2), MUX(CLK_MOUT_CMU_HSI1_UFS_EMBD, "mout_cmu_hsi1_ufs_embd", mout_cmu_hsi1_ufs_embd_p, CLK_CON_MUX_MUX_CLKCMU_HSI1_UFS_EMBD, - 0, 1), + 0, 2), MUX(CLK_MOUT_CMU_HSI2_BUS, "mout_cmu_hsi2_bus", mout_cmu_hsi2_bus_p, CLK_CON_MUX_MUX_CLKCMU_HSI2_BUS, 0, 1), MUX(CLK_MOUT_CMU_HSI2_PCIE, "mout_cmu_hsi2_pcie", @@ -830,6 +857,10 @@ static const struct samsung_mux_clock top_mux_clks[] __initconst = { mout_cmu_tnr_bus_p, CLK_CON_MUX_MUX_CLKCMU_TNR_BUS, 0, 3), MUX(CLK_MOUT_CMU_VRA_BUS, "mout_cmu_vra_bus", mout_cmu_vra_bus_p, CLK_CON_MUX_MUX_CLKCMU_VRA_BUS, 0, 2), + MUX(CLK_MOUT_CMU_CMUREF, "mout_cmu_cmuref", + mout_cmu_cmuref_p, CLK_CON_MUX_MUX_CMU_CMUREF, 0, 1), + MUX(CLK_MOUT_CMU_CLK_CMUREF, "mout_cmu_clk_cmuref", + mout_cmu_clk_cmuref_p, CLK_CON_MUX_MUX_CLK_CMU_CMUREF, 0, 2), }; static const struct samsung_div_clock top_div_clks[] __initconst = { @@ -862,7 +893,7 @@ static const struct samsung_div_clock top_div_clks[] __initconst = { CLK_CON_DIV_PLL_SHARED4_DIV4, 0, 1), DIV(CLK_DOUT_CMU_APM_BUS, "dout_cmu_apm_bus", "gout_cmu_apm_bus", - CLK_CON_DIV_CLKCMU_APM_BUS, 0, 3), + CLK_CON_DIV_CLKCMU_APM_BUS, 0, 2), DIV(CLK_DOUT_CMU_AUD_CPU, "dout_cmu_aud_cpu", "gout_cmu_aud_cpu", CLK_CON_DIV_CLKCMU_AUD_CPU, 0, 3), DIV(CLK_DOUT_CMU_BUS0_BUS, "dout_cmu_bus0_bus", "gout_cmu_bus0_bus", @@ -887,9 +918,9 @@ static const struct samsung_div_clock top_div_clks[] __initconst = { CLK_CON_DIV_CLKCMU_CMU_BOOST, 0, 2), DIV(CLK_DOUT_CMU_CORE_BUS, "dout_cmu_core_bus", "gout_cmu_core_bus", CLK_CON_DIV_CLKCMU_CORE_BUS, 0, 4), - DIV(CLK_DOUT_CMU_CPUCL0_DBG_BUS, "dout_cmu_cpucl0_debug", + DIV(CLK_DOUT_CMU_CPUCL0_DBG_BUS, "dout_cmu_cpucl0_dbg_bus", "gout_cmu_cpucl0_dbg_bus", CLK_CON_DIV_CLKCMU_CPUCL0_DBG_BUS, - 0, 3), + 0, 4), DIV(CLK_DOUT_CMU_CPUCL0_SWITCH, "dout_cmu_cpucl0_switch", "gout_cmu_cpucl0_switch", CLK_CON_DIV_CLKCMU_CPUCL0_SWITCH, 0, 3), DIV(CLK_DOUT_CMU_CPUCL1_SWITCH, "dout_cmu_cpucl1_switch", @@ -924,16 +955,11 @@ static const struct samsung_div_clock top_div_clks[] __initconst = { CLK_CON_DIV_CLKCMU_HSI0_DPGTC, 0, 3), DIV(CLK_DOUT_CMU_HSI0_USB31DRD, "dout_cmu_hsi0_usb31drd", "gout_cmu_hsi0_usb31drd", CLK_CON_DIV_CLKCMU_HSI0_USB31DRD, 0, 4), - DIV(CLK_DOUT_CMU_HSI0_USBDP_DEBUG, "dout_cmu_hsi0_usbdp_debug", - "gout_cmu_hsi0_usbdp_debug", CLK_CON_DIV_CLKCMU_HSI0_USBDP_DEBUG, - 0, 4), DIV(CLK_DOUT_CMU_HSI1_BUS, "dout_cmu_hsi1_bus", "gout_cmu_hsi1_bus", CLK_CON_DIV_CLKCMU_HSI1_BUS, 0, 3), DIV(CLK_DOUT_CMU_HSI1_MMC_CARD, "dout_cmu_hsi1_mmc_card", "gout_cmu_hsi1_mmc_card", CLK_CON_DIV_CLKCMU_HSI1_MMC_CARD, 0, 9), - DIV(CLK_DOUT_CMU_HSI1_PCIE, "dout_cmu_hsi1_pcie", "gout_cmu_hsi1_pcie", - CLK_CON_DIV_CLKCMU_HSI1_PCIE, 0, 7), DIV(CLK_DOUT_CMU_HSI1_UFS_CARD, "dout_cmu_hsi1_ufs_card", "gout_cmu_hsi1_ufs_card", CLK_CON_DIV_CLKCMU_HSI1_UFS_CARD, 0, 3), @@ -942,8 +968,6 @@ static const struct samsung_div_clock top_div_clks[] __initconst = { 0, 3), DIV(CLK_DOUT_CMU_HSI2_BUS, "dout_cmu_hsi2_bus", "gout_cmu_hsi2_bus", CLK_CON_DIV_CLKCMU_HSI2_BUS, 0, 4), - DIV(CLK_DOUT_CMU_HSI2_PCIE, "dout_cmu_hsi2_pcie", "gout_cmu_hsi2_pcie", - CLK_CON_DIV_CLKCMU_HSI2_PCIE, 0, 7), DIV(CLK_DOUT_CMU_IPP_BUS, "dout_cmu_ipp_bus", "gout_cmu_ipp_bus", CLK_CON_DIV_CLKCMU_IPP_BUS, 0, 4), DIV(CLK_DOUT_CMU_ITP_BUS, "dout_cmu_itp_bus", "gout_cmu_itp_bus", @@ -979,8 +1003,22 @@ static const struct samsung_div_clock top_div_clks[] __initconst = { CLK_CON_DIV_CLKCMU_TNR_BUS, 0, 4), DIV(CLK_DOUT_CMU_VRA_BUS, "dout_cmu_vra_bus", "gout_cmu_vra_bus", CLK_CON_DIV_CLKCMU_VRA_BUS, 0, 4), - DIV(CLK_DOUT_CMU_DPU, "dout_cmu_clkcmu_dpu", "gout_cmu_dpu", - CLK_CON_DIV_DIV_CLKCMU_DPU, 0, 4), + DIV(CLK_DOUT_CMU_DPU, "dout_cmu_dpu", "gout_cmu_dpu", + CLK_CON_DIV_DIV_CLKCMU_DPU, 0, 3), + DIV(CLK_DOUT_CMU_DPU_ALT, "dout_cmu_dpu_alt", "gout_cmu_dpu_bus", + CLK_CON_DIV_DIV_CLKCMU_DPU_ALT, 0, 4), + DIV(CLK_DOUT_CMU_CLK_CMUREF, "dout_cmu_clk_cmuref", "mout_cmu_clk_cmuref", + CLK_CON_DIV_DIV_CLK_CMU_CMUREF, 0, 2), +}; + +static const struct samsung_fixed_factor_clock cmu_top_ffactor[] __initconst = { + FFACTOR(CLK_DOUT_CMU_HSI1_PCIE, "dout_cmu_hsi1_pcie", + "gout_cmu_hsi1_pcie", 1, 8, 0), + FFACTOR(CLK_DOUT_CMU_OTP, "dout_cmu_otp", "oscclk", 1, 8, 0), + FFACTOR(CLK_DOUT_CMU_HSI0_USBDP_DEBUG, "dout_cmu_hsi0_usbdp_debug", + "gout_cmu_hsi0_usbdp_debug", 1, 8, 0), + FFACTOR(CLK_DOUT_CMU_HSI2_PCIE, "dout_cmu_hsi2_pcie", + "gout_cmu_hsi2_pcie", 1, 8, 0), }; static const struct samsung_gate_clock top_gate_clks[] __initconst = { @@ -1126,6 +1164,8 @@ static const struct samsung_cmu_info top_cmu_info __initconst = { .nr_mux_clks = ARRAY_SIZE(top_mux_clks), .div_clks = top_div_clks, .nr_div_clks = ARRAY_SIZE(top_div_clks), + .fixed_factor_clks = cmu_top_ffactor, + .nr_fixed_factor_clks = ARRAY_SIZE(cmu_top_ffactor), .gate_clks = top_gate_clks, .nr_gate_clks = ARRAY_SIZE(top_gate_clks), .nr_clk_ids = CLKS_NR_TOP, @@ -1186,6 +1226,8 @@ static const unsigned long hsi0_clk_regs[] __initconst = { CLK_CON_GAT_GOUT_BLK_HSI0_UID_SYSMMU_USB_IPCLKPORT_CLK_S2, CLK_CON_GAT_GOUT_BLK_HSI0_UID_SYSREG_HSI0_IPCLKPORT_PCLK, CLK_CON_GAT_GOUT_BLK_HSI0_UID_USB31DRD_IPCLKPORT_ACLK_PHYCTRL, + CLK_CON_GAT_GOUT_BLK_HSI0_UID_USB31DRD_IPCLKPORT_I_USB31DRD_REF_CLK_40, + CLK_CON_GAT_GOUT_BLK_HSI0_UID_USB31DRD_IPCLKPORT_I_USBDPPHY_REF_SOC_PLL, CLK_CON_GAT_GOUT_BLK_HSI0_UID_USB31DRD_IPCLKPORT_I_USBDPPHY_SCL_APB_PCLK, CLK_CON_GAT_GOUT_BLK_HSI0_UID_USB31DRD_IPCLKPORT_I_USBPCS_APB_CLK, CLK_CON_GAT_GOUT_BLK_HSI0_UID_USB31DRD_IPCLKPORT_BUS_CLK_EARLY, @@ -1294,6 +1336,10 @@ static const struct samsung_gate_clock hsi0_gate_clks[] __initconst = { "gout_hsi0_xiu_d_hsi0_aclk", "mout_hsi0_bus_user", CLK_CON_GAT_GOUT_BLK_HSI0_UID_XIU_D_HSI0_IPCLKPORT_ACLK, 21, CLK_IGNORE_UNUSED, 0), + GATE(CLK_GOUT_HSI0_LHS_ACEL_D_HSI0_CLK, + "gout_hsi0_lhs_acel_d_hsi0_clk", "mout_hsi0_bus_user", + CLK_CON_GAT_GOUT_BLK_HSI0_UID_LHS_ACEL_D_HSI0_IPCLKPORT_I_CLK, + 21, CLK_IS_CRITICAL, 0), }; static const struct samsung_cmu_info hsi0_cmu_info __initconst = { @@ -1307,6 +1353,1150 @@ static const struct samsung_cmu_info hsi0_cmu_info __initconst = { .clk_name = "bus", }; +/* ---- CMU_PERIC0 --------------------------------------------------------- */ + +/* Register Offset definitions for CMU_PERIC0 (0x10400000) */ +#define PLL_CON0_MUX_CLKCMU_PERIC0_BUS_USER 0x0600 +#define PLL_CON1_MUX_CLKCMU_PERIC0_BUS_USER 0x0604 +#define PLL_CON0_MUX_CLKCMU_PERIC0_UART_DBG 0x0610 +#define PLL_CON1_MUX_CLKCMU_PERIC0_UART_DBG 0x0614 +#define PLL_CON0_MUX_CLKCMU_PERIC0_USI00_USI_USER 0x0620 +#define PLL_CON1_MUX_CLKCMU_PERIC0_USI00_USI_USER 0x0624 +#define PLL_CON0_MUX_CLKCMU_PERIC0_USI01_USI_USER 0x0630 +#define PLL_CON1_MUX_CLKCMU_PERIC0_USI01_USI_USER 0x0634 +#define PLL_CON0_MUX_CLKCMU_PERIC0_USI02_USI_USER 0x0640 +#define PLL_CON1_MUX_CLKCMU_PERIC0_USI02_USI_USER 0x0644 +#define PLL_CON0_MUX_CLKCMU_PERIC0_USI03_USI_USER 0x0650 +#define PLL_CON1_MUX_CLKCMU_PERIC0_USI03_USI_USER 0x0654 +#define PLL_CON0_MUX_CLKCMU_PERIC0_USI04_USI_USER 0x0660 +#define PLL_CON1_MUX_CLKCMU_PERIC0_USI04_USI_USER 0x0664 +#define PLL_CON0_MUX_CLKCMU_PERIC0_USI05_USI_USER 0x0670 +#define PLL_CON1_MUX_CLKCMU_PERIC0_USI05_USI_USER 0x0674 +#define PLL_CON0_MUX_CLKCMU_PERIC0_USI13_USI_USER 0x0680 +#define PLL_CON1_MUX_CLKCMU_PERIC0_USI13_USI_USER 0x0684 +#define PLL_CON0_MUX_CLKCMU_PERIC0_USI14_USI_USER 0x0690 +#define PLL_CON1_MUX_CLKCMU_PERIC0_USI14_USI_USER 0x0694 +#define PLL_CON0_MUX_CLKCMU_PERIC0_USI15_USI_USER 0x06a0 +#define PLL_CON1_MUX_CLKCMU_PERIC0_USI15_USI_USER 0x06a4 +#define PLL_CON0_MUX_CLKCMU_PERIC0_USI_I2C_USER 0x06b0 +#define PLL_CON1_MUX_CLKCMU_PERIC0_USI_I2C_USER 0x06b4 +#define CLK_CON_DIV_DIV_CLK_PERIC0_UART_DBG 0x1800 +#define CLK_CON_DIV_DIV_CLK_PERIC0_USI00_USI 0x1804 +#define CLK_CON_DIV_DIV_CLK_PERIC0_USI01_USI 0x1808 +#define CLK_CON_DIV_DIV_CLK_PERIC0_USI02_USI 0x180c +#define CLK_CON_DIV_DIV_CLK_PERIC0_USI03_USI 0x1810 +#define CLK_CON_DIV_DIV_CLK_PERIC0_USI04_USI 0x1814 +#define CLK_CON_DIV_DIV_CLK_PERIC0_USI05_USI 0x1818 +#define CLK_CON_DIV_DIV_CLK_PERIC0_USI13_USI 0x181c +#define CLK_CON_DIV_DIV_CLK_PERIC0_USI14_USI 0x1820 +#define CLK_CON_DIV_DIV_CLK_PERIC0_USI15_USI 0x1824 +#define CLK_CON_DIV_DIV_CLK_PERIC0_USI_I2C 0x1828 +#define CLK_CON_GAT_CLK_BLK_PERIC0_UID_PERIC0_CMU_PERIC0_IPCLKPORT_PCLK 0x2004 +#define CLK_CON_GAT_CLK_BLK_PERIC0_UID_RSTNSYNC_CLK_PERIC0_OSCCLK_IPCLKPORT_CLK 0x2008 +#define CLK_CON_GAT_GOUT_BLK_PERIC0_UID_D_TZPC_PERIC0_IPCLKPORT_PCLK 0x200c +#define CLK_CON_GAT_GOUT_BLK_PERIC0_UID_GPIO_PERIC0_IPCLKPORT_PCLK 0x2010 +#define CLK_CON_GAT_GOUT_BLK_PERIC0_UID_LHM_AXI_P_PERIC0_IPCLKPORT_I_CLK 0x2014 +#define CLK_CON_GAT_GOUT_BLK_PERIC0_UID_PERIC0_TOP0_IPCLKPORT_IPCLK_10 0x2018 +#define CLK_CON_GAT_GOUT_BLK_PERIC0_UID_PERIC0_TOP0_IPCLKPORT_IPCLK_11 0x201c +#define CLK_CON_GAT_GOUT_BLK_PERIC0_UID_PERIC0_TOP0_IPCLKPORT_IPCLK_12 0x2020 +#define CLK_CON_GAT_GOUT_BLK_PERIC0_UID_PERIC0_TOP0_IPCLKPORT_IPCLK_13 0x2024 +#define CLK_CON_GAT_GOUT_BLK_PERIC0_UID_PERIC0_TOP0_IPCLKPORT_IPCLK_14 0x2028 +#define CLK_CON_GAT_GOUT_BLK_PERIC0_UID_PERIC0_TOP0_IPCLKPORT_IPCLK_15 0x202c +#define CLK_CON_GAT_GOUT_BLK_PERIC0_UID_PERIC0_TOP0_IPCLKPORT_IPCLK_4 0x2030 +#define CLK_CON_GAT_GOUT_BLK_PERIC0_UID_PERIC0_TOP0_IPCLKPORT_IPCLK_5 0x2034 +#define CLK_CON_GAT_GOUT_BLK_PERIC0_UID_PERIC0_TOP0_IPCLKPORT_IPCLK_6 0x2038 +#define CLK_CON_GAT_GOUT_BLK_PERIC0_UID_PERIC0_TOP0_IPCLKPORT_IPCLK_7 0x203c +#define CLK_CON_GAT_GOUT_BLK_PERIC0_UID_PERIC0_TOP0_IPCLKPORT_IPCLK_8 0x2040 +#define CLK_CON_GAT_GOUT_BLK_PERIC0_UID_PERIC0_TOP0_IPCLKPORT_IPCLK_9 0x2044 +#define CLK_CON_GAT_GOUT_BLK_PERIC0_UID_PERIC0_TOP0_IPCLKPORT_PCLK_10 0x2048 +#define CLK_CON_GAT_GOUT_BLK_PERIC0_UID_PERIC0_TOP0_IPCLKPORT_PCLK_11 0x204c +#define CLK_CON_GAT_GOUT_BLK_PERIC0_UID_PERIC0_TOP0_IPCLKPORT_PCLK_12 0x2050 +#define CLK_CON_GAT_GOUT_BLK_PERIC0_UID_PERIC0_TOP0_IPCLKPORT_PCLK_13 0x2054 +#define CLK_CON_GAT_GOUT_BLK_PERIC0_UID_PERIC0_TOP0_IPCLKPORT_PCLK_14 0x2058 +#define CLK_CON_GAT_GOUT_BLK_PERIC0_UID_PERIC0_TOP0_IPCLKPORT_PCLK_15 0x205c +#define CLK_CON_GAT_GOUT_BLK_PERIC0_UID_PERIC0_TOP0_IPCLKPORT_PCLK_4 0x2060 +#define CLK_CON_GAT_GOUT_BLK_PERIC0_UID_PERIC0_TOP0_IPCLKPORT_PCLK_5 0x2064 +#define CLK_CON_GAT_GOUT_BLK_PERIC0_UID_PERIC0_TOP0_IPCLKPORT_PCLK_6 0x2068 +#define CLK_CON_GAT_GOUT_BLK_PERIC0_UID_PERIC0_TOP0_IPCLKPORT_PCLK_7 0x206c +#define CLK_CON_GAT_GOUT_BLK_PERIC0_UID_PERIC0_TOP0_IPCLKPORT_PCLK_8 0x2070 +#define CLK_CON_GAT_GOUT_BLK_PERIC0_UID_PERIC0_TOP0_IPCLKPORT_PCLK_9 0x2074 +#define CLK_CON_GAT_GOUT_BLK_PERIC0_UID_PERIC0_TOP1_IPCLKPORT_IPCLK_0 0x2078 +#define CLK_CON_GAT_GOUT_BLK_PERIC0_UID_PERIC0_TOP1_IPCLKPORT_IPCLK_3 0x207c +#define CLK_CON_GAT_GOUT_BLK_PERIC0_UID_PERIC0_TOP1_IPCLKPORT_IPCLK_4 0x2080 +#define CLK_CON_GAT_GOUT_BLK_PERIC0_UID_PERIC0_TOP1_IPCLKPORT_IPCLK_5 0x2084 +#define CLK_CON_GAT_GOUT_BLK_PERIC0_UID_PERIC0_TOP1_IPCLKPORT_IPCLK_6 0x2088 +#define CLK_CON_GAT_GOUT_BLK_PERIC0_UID_PERIC0_TOP1_IPCLKPORT_IPCLK_7 0x208c +#define CLK_CON_GAT_GOUT_BLK_PERIC0_UID_PERIC0_TOP1_IPCLKPORT_IPCLK_8 0x2090 +#define CLK_CON_GAT_GOUT_BLK_PERIC0_UID_PERIC0_TOP1_IPCLKPORT_PCLK_0 0x2094 +#define CLK_CON_GAT_GOUT_BLK_PERIC0_UID_PERIC0_TOP1_IPCLKPORT_PCLK_15 0x2098 +#define CLK_CON_GAT_GOUT_BLK_PERIC0_UID_PERIC0_TOP1_IPCLKPORT_PCLK_3 0x209c +#define CLK_CON_GAT_GOUT_BLK_PERIC0_UID_PERIC0_TOP1_IPCLKPORT_PCLK_4 0x20a0 +#define CLK_CON_GAT_GOUT_BLK_PERIC0_UID_PERIC0_TOP1_IPCLKPORT_PCLK_5 0x20a4 +#define CLK_CON_GAT_GOUT_BLK_PERIC0_UID_PERIC0_TOP1_IPCLKPORT_PCLK_6 0x20a8 +#define CLK_CON_GAT_GOUT_BLK_PERIC0_UID_PERIC0_TOP1_IPCLKPORT_PCLK_7 0x20ac +#define CLK_CON_GAT_GOUT_BLK_PERIC0_UID_PERIC0_TOP1_IPCLKPORT_PCLK_8 0x20b0 +#define CLK_CON_GAT_GOUT_BLK_PERIC0_UID_RSTNSYNC_CLK_PERIC0_BUSP_IPCLKPORT_CLK 0x20b4 +#define CLK_CON_GAT_GOUT_BLK_PERIC0_UID_RSTNSYNC_CLK_PERIC0_UART_DBG_IPCLKPORT_CLK 0x20b8 +#define CLK_CON_GAT_GOUT_BLK_PERIC0_UID_RSTNSYNC_CLK_PERIC0_USI00_USI_IPCLKPORT_CLK 0x20bc +#define CLK_CON_GAT_GOUT_BLK_PERIC0_UID_RSTNSYNC_CLK_PERIC0_USI01_USI_IPCLKPORT_CLK 0x20c0 +#define CLK_CON_GAT_GOUT_BLK_PERIC0_UID_RSTNSYNC_CLK_PERIC0_USI02_USI_IPCLKPORT_CLK 0x20c4 +#define CLK_CON_GAT_GOUT_BLK_PERIC0_UID_RSTNSYNC_CLK_PERIC0_USI03_USI_IPCLKPORT_CLK 0x20c8 +#define CLK_CON_GAT_GOUT_BLK_PERIC0_UID_RSTNSYNC_CLK_PERIC0_USI04_USI_IPCLKPORT_CLK 0x20cc +#define CLK_CON_GAT_GOUT_BLK_PERIC0_UID_RSTNSYNC_CLK_PERIC0_USI05_USI_IPCLKPORT_CLK 0x20d0 +#define CLK_CON_GAT_GOUT_BLK_PERIC0_UID_RSTNSYNC_CLK_PERIC0_USI13_USI_IPCLKPORT_CLK 0x20d4 +#define CLK_CON_GAT_GOUT_BLK_PERIC0_UID_RSTNSYNC_CLK_PERIC0_USI14_USI_IPCLKPORT_CLK 0x20d8 +#define CLK_CON_GAT_GOUT_BLK_PERIC0_UID_RSTNSYNC_CLK_PERIC0_USI15_USI_IPCLKPORT_CLK 0x20dc +#define CLK_CON_GAT_GOUT_BLK_PERIC0_UID_RSTNSYNC_CLK_PERIC0_USI_I2C_IPCLKPORT_CLK 0x20e0 +#define CLK_CON_GAT_GOUT_BLK_PERIC0_UID_SYSREG_PERIC0_IPCLKPORT_PCLK 0x20e4 + +static const unsigned long peric0_clk_regs[] __initconst = { + PLL_CON0_MUX_CLKCMU_PERIC0_BUS_USER, + PLL_CON1_MUX_CLKCMU_PERIC0_BUS_USER, + PLL_CON0_MUX_CLKCMU_PERIC0_UART_DBG, + PLL_CON1_MUX_CLKCMU_PERIC0_UART_DBG, + PLL_CON0_MUX_CLKCMU_PERIC0_USI00_USI_USER, + PLL_CON1_MUX_CLKCMU_PERIC0_USI00_USI_USER, + PLL_CON0_MUX_CLKCMU_PERIC0_USI01_USI_USER, + PLL_CON1_MUX_CLKCMU_PERIC0_USI01_USI_USER, + PLL_CON0_MUX_CLKCMU_PERIC0_USI02_USI_USER, + PLL_CON1_MUX_CLKCMU_PERIC0_USI02_USI_USER, + PLL_CON0_MUX_CLKCMU_PERIC0_USI03_USI_USER, + PLL_CON1_MUX_CLKCMU_PERIC0_USI03_USI_USER, + PLL_CON0_MUX_CLKCMU_PERIC0_USI04_USI_USER, + PLL_CON1_MUX_CLKCMU_PERIC0_USI04_USI_USER, + PLL_CON0_MUX_CLKCMU_PERIC0_USI05_USI_USER, + PLL_CON1_MUX_CLKCMU_PERIC0_USI05_USI_USER, + PLL_CON0_MUX_CLKCMU_PERIC0_USI13_USI_USER, + PLL_CON1_MUX_CLKCMU_PERIC0_USI13_USI_USER, + PLL_CON0_MUX_CLKCMU_PERIC0_USI14_USI_USER, + PLL_CON1_MUX_CLKCMU_PERIC0_USI14_USI_USER, + PLL_CON0_MUX_CLKCMU_PERIC0_USI15_USI_USER, + PLL_CON1_MUX_CLKCMU_PERIC0_USI15_USI_USER, + PLL_CON0_MUX_CLKCMU_PERIC0_USI_I2C_USER, + PLL_CON1_MUX_CLKCMU_PERIC0_USI_I2C_USER, + CLK_CON_DIV_DIV_CLK_PERIC0_UART_DBG, + CLK_CON_DIV_DIV_CLK_PERIC0_USI00_USI, + CLK_CON_DIV_DIV_CLK_PERIC0_USI01_USI, + CLK_CON_DIV_DIV_CLK_PERIC0_USI02_USI, + CLK_CON_DIV_DIV_CLK_PERIC0_USI03_USI, + CLK_CON_DIV_DIV_CLK_PERIC0_USI04_USI, + CLK_CON_DIV_DIV_CLK_PERIC0_USI05_USI, + CLK_CON_DIV_DIV_CLK_PERIC0_USI13_USI, + CLK_CON_DIV_DIV_CLK_PERIC0_USI14_USI, + CLK_CON_DIV_DIV_CLK_PERIC0_USI15_USI, + CLK_CON_DIV_DIV_CLK_PERIC0_USI_I2C, + CLK_CON_GAT_CLK_BLK_PERIC0_UID_PERIC0_CMU_PERIC0_IPCLKPORT_PCLK, + CLK_CON_GAT_CLK_BLK_PERIC0_UID_RSTNSYNC_CLK_PERIC0_OSCCLK_IPCLKPORT_CLK, + CLK_CON_GAT_GOUT_BLK_PERIC0_UID_D_TZPC_PERIC0_IPCLKPORT_PCLK, + CLK_CON_GAT_GOUT_BLK_PERIC0_UID_GPIO_PERIC0_IPCLKPORT_PCLK, + CLK_CON_GAT_GOUT_BLK_PERIC0_UID_LHM_AXI_P_PERIC0_IPCLKPORT_I_CLK, + CLK_CON_GAT_GOUT_BLK_PERIC0_UID_PERIC0_TOP0_IPCLKPORT_IPCLK_10, + CLK_CON_GAT_GOUT_BLK_PERIC0_UID_PERIC0_TOP0_IPCLKPORT_IPCLK_11, + CLK_CON_GAT_GOUT_BLK_PERIC0_UID_PERIC0_TOP0_IPCLKPORT_IPCLK_12, + CLK_CON_GAT_GOUT_BLK_PERIC0_UID_PERIC0_TOP0_IPCLKPORT_IPCLK_13, + CLK_CON_GAT_GOUT_BLK_PERIC0_UID_PERIC0_TOP0_IPCLKPORT_IPCLK_14, + CLK_CON_GAT_GOUT_BLK_PERIC0_UID_PERIC0_TOP0_IPCLKPORT_IPCLK_15, + CLK_CON_GAT_GOUT_BLK_PERIC0_UID_PERIC0_TOP0_IPCLKPORT_IPCLK_4, + CLK_CON_GAT_GOUT_BLK_PERIC0_UID_PERIC0_TOP0_IPCLKPORT_IPCLK_5, + CLK_CON_GAT_GOUT_BLK_PERIC0_UID_PERIC0_TOP0_IPCLKPORT_IPCLK_6, + CLK_CON_GAT_GOUT_BLK_PERIC0_UID_PERIC0_TOP0_IPCLKPORT_IPCLK_7, + CLK_CON_GAT_GOUT_BLK_PERIC0_UID_PERIC0_TOP0_IPCLKPORT_IPCLK_8, + CLK_CON_GAT_GOUT_BLK_PERIC0_UID_PERIC0_TOP0_IPCLKPORT_IPCLK_9, + CLK_CON_GAT_GOUT_BLK_PERIC0_UID_PERIC0_TOP0_IPCLKPORT_PCLK_10, + CLK_CON_GAT_GOUT_BLK_PERIC0_UID_PERIC0_TOP0_IPCLKPORT_PCLK_11, + CLK_CON_GAT_GOUT_BLK_PERIC0_UID_PERIC0_TOP0_IPCLKPORT_PCLK_12, + CLK_CON_GAT_GOUT_BLK_PERIC0_UID_PERIC0_TOP0_IPCLKPORT_PCLK_13, + CLK_CON_GAT_GOUT_BLK_PERIC0_UID_PERIC0_TOP0_IPCLKPORT_PCLK_14, + CLK_CON_GAT_GOUT_BLK_PERIC0_UID_PERIC0_TOP0_IPCLKPORT_PCLK_15, + CLK_CON_GAT_GOUT_BLK_PERIC0_UID_PERIC0_TOP0_IPCLKPORT_PCLK_4, + CLK_CON_GAT_GOUT_BLK_PERIC0_UID_PERIC0_TOP0_IPCLKPORT_PCLK_5, + CLK_CON_GAT_GOUT_BLK_PERIC0_UID_PERIC0_TOP0_IPCLKPORT_PCLK_6, + CLK_CON_GAT_GOUT_BLK_PERIC0_UID_PERIC0_TOP0_IPCLKPORT_PCLK_7, + CLK_CON_GAT_GOUT_BLK_PERIC0_UID_PERIC0_TOP0_IPCLKPORT_PCLK_8, + CLK_CON_GAT_GOUT_BLK_PERIC0_UID_PERIC0_TOP0_IPCLKPORT_PCLK_9, + CLK_CON_GAT_GOUT_BLK_PERIC0_UID_PERIC0_TOP1_IPCLKPORT_IPCLK_0, + CLK_CON_GAT_GOUT_BLK_PERIC0_UID_PERIC0_TOP1_IPCLKPORT_IPCLK_3, + CLK_CON_GAT_GOUT_BLK_PERIC0_UID_PERIC0_TOP1_IPCLKPORT_IPCLK_4, + CLK_CON_GAT_GOUT_BLK_PERIC0_UID_PERIC0_TOP1_IPCLKPORT_IPCLK_5, + CLK_CON_GAT_GOUT_BLK_PERIC0_UID_PERIC0_TOP1_IPCLKPORT_IPCLK_6, + CLK_CON_GAT_GOUT_BLK_PERIC0_UID_PERIC0_TOP1_IPCLKPORT_IPCLK_7, + CLK_CON_GAT_GOUT_BLK_PERIC0_UID_PERIC0_TOP1_IPCLKPORT_IPCLK_8, + CLK_CON_GAT_GOUT_BLK_PERIC0_UID_PERIC0_TOP1_IPCLKPORT_PCLK_0, + CLK_CON_GAT_GOUT_BLK_PERIC0_UID_PERIC0_TOP1_IPCLKPORT_PCLK_15, + CLK_CON_GAT_GOUT_BLK_PERIC0_UID_PERIC0_TOP1_IPCLKPORT_PCLK_3, + CLK_CON_GAT_GOUT_BLK_PERIC0_UID_PERIC0_TOP1_IPCLKPORT_PCLK_4, + CLK_CON_GAT_GOUT_BLK_PERIC0_UID_PERIC0_TOP1_IPCLKPORT_PCLK_5, + CLK_CON_GAT_GOUT_BLK_PERIC0_UID_PERIC0_TOP1_IPCLKPORT_PCLK_6, + CLK_CON_GAT_GOUT_BLK_PERIC0_UID_PERIC0_TOP1_IPCLKPORT_PCLK_7, + CLK_CON_GAT_GOUT_BLK_PERIC0_UID_PERIC0_TOP1_IPCLKPORT_PCLK_8, + CLK_CON_GAT_GOUT_BLK_PERIC0_UID_RSTNSYNC_CLK_PERIC0_BUSP_IPCLKPORT_CLK, + CLK_CON_GAT_GOUT_BLK_PERIC0_UID_RSTNSYNC_CLK_PERIC0_UART_DBG_IPCLKPORT_CLK, + CLK_CON_GAT_GOUT_BLK_PERIC0_UID_RSTNSYNC_CLK_PERIC0_USI00_USI_IPCLKPORT_CLK, + CLK_CON_GAT_GOUT_BLK_PERIC0_UID_RSTNSYNC_CLK_PERIC0_USI01_USI_IPCLKPORT_CLK, + CLK_CON_GAT_GOUT_BLK_PERIC0_UID_RSTNSYNC_CLK_PERIC0_USI02_USI_IPCLKPORT_CLK, + CLK_CON_GAT_GOUT_BLK_PERIC0_UID_RSTNSYNC_CLK_PERIC0_USI03_USI_IPCLKPORT_CLK, + CLK_CON_GAT_GOUT_BLK_PERIC0_UID_RSTNSYNC_CLK_PERIC0_USI04_USI_IPCLKPORT_CLK, + CLK_CON_GAT_GOUT_BLK_PERIC0_UID_RSTNSYNC_CLK_PERIC0_USI05_USI_IPCLKPORT_CLK, + CLK_CON_GAT_GOUT_BLK_PERIC0_UID_RSTNSYNC_CLK_PERIC0_USI13_USI_IPCLKPORT_CLK, + CLK_CON_GAT_GOUT_BLK_PERIC0_UID_RSTNSYNC_CLK_PERIC0_USI14_USI_IPCLKPORT_CLK, + CLK_CON_GAT_GOUT_BLK_PERIC0_UID_RSTNSYNC_CLK_PERIC0_USI15_USI_IPCLKPORT_CLK, + CLK_CON_GAT_GOUT_BLK_PERIC0_UID_RSTNSYNC_CLK_PERIC0_USI_I2C_IPCLKPORT_CLK, + CLK_CON_GAT_GOUT_BLK_PERIC0_UID_SYSREG_PERIC0_IPCLKPORT_PCLK, +}; + +/* Parent clock list for CMU_PERIC0 muxes */ +PNAME(mout_peric0_bus_user_p) = { "oscclk", "dout_cmu_peric0_bus" }; +PNAME(mout_peric0_uart_dbg_p) = { "oscclk", "dout_cmu_peric0_ip" }; +PNAME(mout_peric0_usi00_user_p) = { "oscclk", "dout_cmu_peric0_ip" }; +PNAME(mout_peric0_usi01_user_p) = { "oscclk", "dout_cmu_peric0_ip" }; +PNAME(mout_peric0_usi02_user_p) = { "oscclk", "dout_cmu_peric0_ip" }; +PNAME(mout_peric0_usi03_user_p) = { "oscclk", "dout_cmu_peric0_ip" }; +PNAME(mout_peric0_usi04_user_p) = { "oscclk", "dout_cmu_peric0_ip" }; +PNAME(mout_peric0_usi05_user_p) = { "oscclk", "dout_cmu_peric0_ip" }; +PNAME(mout_peric0_usi13_user_p) = { "oscclk", "dout_cmu_peric0_ip" }; +PNAME(mout_peric0_usi14_user_p) = { "oscclk", "dout_cmu_peric0_ip" }; +PNAME(mout_peric0_usi15_user_p) = { "oscclk", "dout_cmu_peric0_ip" }; +PNAME(mout_peric0_usi_i2c_user_p) = { "oscclk", "dout_cmu_peric0_ip" }; + +static const struct samsung_mux_clock peric0_mux_clks[] __initconst = { + MUX(CLK_MOUT_PERIC0_BUS_USER, "mout_peric0_bus_user", + mout_peric0_bus_user_p, PLL_CON0_MUX_CLKCMU_PERIC0_BUS_USER, + 4, 1), + MUX(CLK_MOUT_PERIC0_UART_DBG, "mout_peric0_uart_dbg", + mout_peric0_uart_dbg_p, PLL_CON0_MUX_CLKCMU_PERIC0_UART_DBG, + 4, 1), + MUX(CLK_MOUT_PERIC0_USI00_USI_USER, "mout_peric0_usi00_usi_user", + mout_peric0_usi00_user_p, PLL_CON0_MUX_CLKCMU_PERIC0_USI00_USI_USER, + 4, 1), + MUX(CLK_MOUT_PERIC0_USI01_USI_USER, "mout_peric0_usi01_usi_user", + mout_peric0_usi01_user_p, PLL_CON0_MUX_CLKCMU_PERIC0_USI01_USI_USER, + 4, 1), + MUX(CLK_MOUT_PERIC0_USI02_USI_USER, "mout_peric0_usi02_usi_user", + mout_peric0_usi02_user_p, PLL_CON0_MUX_CLKCMU_PERIC0_USI02_USI_USER, + 4, 1), + MUX(CLK_MOUT_PERIC0_USI03_USI_USER, "mout_peric0_usi03_usi_user", + mout_peric0_usi03_user_p, PLL_CON0_MUX_CLKCMU_PERIC0_USI03_USI_USER, + 4, 1), + MUX(CLK_MOUT_PERIC0_USI04_USI_USER, "mout_peric0_usi04_usi_user", + mout_peric0_usi04_user_p, PLL_CON0_MUX_CLKCMU_PERIC0_USI04_USI_USER, + 4, 1), + MUX(CLK_MOUT_PERIC0_USI05_USI_USER, "mout_peric0_usi05_usi_user", + mout_peric0_usi05_user_p, PLL_CON0_MUX_CLKCMU_PERIC0_USI05_USI_USER, + 4, 1), + MUX(CLK_MOUT_PERIC0_USI13_USI_USER, "mout_peric0_usi13_usi_user", + mout_peric0_usi13_user_p, PLL_CON0_MUX_CLKCMU_PERIC0_USI13_USI_USER, + 4, 1), + MUX(CLK_MOUT_PERIC0_USI14_USI_USER, "mout_peric0_usi14_usi_user", + mout_peric0_usi14_user_p, PLL_CON0_MUX_CLKCMU_PERIC0_USI14_USI_USER, + 4, 1), + MUX(CLK_MOUT_PERIC0_USI15_USI_USER, "mout_peric0_usi15_usi_user", + mout_peric0_usi15_user_p, PLL_CON0_MUX_CLKCMU_PERIC0_USI15_USI_USER, + 4, 1), + MUX(CLK_MOUT_PERIC0_USI_I2C_USER, "mout_peric0_usi_i2c_user", + mout_peric0_usi_i2c_user_p, PLL_CON0_MUX_CLKCMU_PERIC0_USI_I2C_USER, + 4, 1), +}; + +static const struct samsung_div_clock peric0_div_clks[] __initconst = { + DIV(CLK_DOUT_PERIC0_UART_DBG, "dout_peric0_uart_dbg", + "mout_peric0_uart_dbg", + CLK_CON_DIV_DIV_CLK_PERIC0_UART_DBG, + 0, 4), + DIV(CLK_DOUT_PERIC0_USI00_USI, "dout_peric0_usi00_usi", + "mout_peric0_usi00_usi_user", + CLK_CON_DIV_DIV_CLK_PERIC0_USI00_USI, + 0, 4), + DIV(CLK_DOUT_PERIC0_USI01_USI, "dout_peric0_usi01_usi", + "mout_peric0_usi01_usi_user", + CLK_CON_DIV_DIV_CLK_PERIC0_USI01_USI, + 0, 4), + DIV(CLK_DOUT_PERIC0_USI02_USI, "dout_peric0_usi02_usi", + "mout_peric0_usi02_usi_user", + CLK_CON_DIV_DIV_CLK_PERIC0_USI02_USI, + 0, 4), + DIV(CLK_DOUT_PERIC0_USI03_USI, "dout_peric0_usi03_usi", + "mout_peric0_usi03_usi_user", + CLK_CON_DIV_DIV_CLK_PERIC0_USI03_USI, + 0, 4), + DIV(CLK_DOUT_PERIC0_USI04_USI, "dout_peric0_usi04_usi", + "mout_peric0_usi04_usi_user", + CLK_CON_DIV_DIV_CLK_PERIC0_USI04_USI, + 0, 4), + DIV(CLK_DOUT_PERIC0_USI05_USI, "dout_peric0_usi05_usi", + "mout_peric0_usi05_usi_user", + CLK_CON_DIV_DIV_CLK_PERIC0_USI05_USI, + 0, 4), + DIV(CLK_DOUT_PERIC0_USI13_USI, "dout_peric0_usi13_usi", + "mout_peric0_usi13_usi_user", + CLK_CON_DIV_DIV_CLK_PERIC0_USI13_USI, + 0, 4), + DIV(CLK_DOUT_PERIC0_USI14_USI, "dout_peric0_usi14_usi", + "mout_peric0_usi14_usi_user", + CLK_CON_DIV_DIV_CLK_PERIC0_USI14_USI, + 0, 4), + DIV(CLK_DOUT_PERIC0_USI15_USI, "dout_peric0_usi15_usi", + "mout_peric0_usi15_usi_user", + CLK_CON_DIV_DIV_CLK_PERIC0_USI15_USI, + 0, 4), + DIV(CLK_DOUT_PERIC0_USI_I2C, "dout_peric0_usi_i2c", + "mout_peric0_usi_i2c_user", + CLK_CON_DIV_DIV_CLK_PERIC0_USI_I2C, + 0, 4), +}; + +static const struct samsung_gate_clock peric0_gate_clks[] __initconst = { + GATE(CLK_GOUT_PERIC0_CMU_PCLK, "gout_peric0_cmu_pclk", + "mout_peric0_bus_user", + CLK_CON_GAT_CLK_BLK_PERIC0_UID_PERIC0_CMU_PERIC0_IPCLKPORT_PCLK, + 21, CLK_IS_CRITICAL, 0), + GATE(CLK_GOUT_PERIC0_OSCCLK_CLK, "gout_peric0_oscclk_clk", + "oscclk", + CLK_CON_GAT_CLK_BLK_PERIC0_UID_RSTNSYNC_CLK_PERIC0_OSCCLK_IPCLKPORT_CLK, + 21, 0, 0), + GATE(CLK_GOUT_PERIC0_D_TZPC_PCLK, "gout_peric0_d_tpzc_pclk", + "mout_peric0_bus_user", + CLK_CON_GAT_GOUT_BLK_PERIC0_UID_D_TZPC_PERIC0_IPCLKPORT_PCLK, + 21, 0, 0), + GATE(CLK_GOUT_PERIC0_GPIO_PCLK, "gout_peric0_gpio_pclk", + "mout_peric0_bus_user", + CLK_CON_GAT_GOUT_BLK_PERIC0_UID_GPIO_PERIC0_IPCLKPORT_PCLK, + 21, CLK_IGNORE_UNUSED, 0), + GATE(CLK_GOUT_PERIC0_LHM_AXI_P_CLK, "gout_peric0_lhm_axi_p_clk", + "mout_peric0_bus_user", + CLK_CON_GAT_GOUT_BLK_PERIC0_UID_LHM_AXI_P_PERIC0_IPCLKPORT_I_CLK, + 21, CLK_IS_CRITICAL, 0), + GATE(CLK_GOUT_PERIC0_TOP0_IPCLK_10, "gout_peric0_top0_ipclk_10", + "dout_peric0_usi_i2c", + CLK_CON_GAT_GOUT_BLK_PERIC0_UID_PERIC0_TOP0_IPCLKPORT_IPCLK_10, + 21, 0, 0), + GATE(CLK_GOUT_PERIC0_TOP0_IPCLK_11, "gout_peric0_top0_ipclk_11", + "dout_peric0_usi03_usi", + CLK_CON_GAT_GOUT_BLK_PERIC0_UID_PERIC0_TOP0_IPCLKPORT_IPCLK_11, + 21, 0, 0), + GATE(CLK_GOUT_PERIC0_TOP0_IPCLK_12, "gout_peric0_top0_ipclk_12", + "dout_peric0_usi_i2c", + CLK_CON_GAT_GOUT_BLK_PERIC0_UID_PERIC0_TOP0_IPCLKPORT_IPCLK_12, + 21, 0, 0), + GATE(CLK_GOUT_PERIC0_TOP0_IPCLK_13, "gout_peric0_top0_ipclk_13", + "dout_peric0_usi04_usi", + CLK_CON_GAT_GOUT_BLK_PERIC0_UID_PERIC0_TOP0_IPCLKPORT_IPCLK_13, + 21, 0, 0), + GATE(CLK_GOUT_PERIC0_TOP0_IPCLK_14, "gout_peric0_top0_ipclk_14", + "dout_peric0_usi_i2c", + CLK_CON_GAT_GOUT_BLK_PERIC0_UID_PERIC0_TOP0_IPCLKPORT_IPCLK_14, + 21, 0, 0), + GATE(CLK_GOUT_PERIC0_TOP0_IPCLK_15, "gout_peric0_top0_ipclk_15", + "dout_peric0_usi05_usi", + CLK_CON_GAT_GOUT_BLK_PERIC0_UID_PERIC0_TOP0_IPCLKPORT_IPCLK_15, + 21, 0, 0), + GATE(CLK_GOUT_PERIC0_TOP0_IPCLK_4, "gout_peric0_top0_ipclk_4", + "dout_peric0_uart_dbg", + CLK_CON_GAT_GOUT_BLK_PERIC0_UID_PERIC0_TOP0_IPCLKPORT_IPCLK_4, + 21, 0, 0), + GATE(CLK_GOUT_PERIC0_TOP0_IPCLK_5, "gout_peric0_top0_ipclk_5", + "dout_peric0_usi00_usi", + CLK_CON_GAT_GOUT_BLK_PERIC0_UID_PERIC0_TOP0_IPCLKPORT_IPCLK_5, + 21, 0, 0), + GATE(CLK_GOUT_PERIC0_TOP0_IPCLK_6, "gout_peric0_top0_ipclk_6", + "dout_peric0_usi_i2c", + CLK_CON_GAT_GOUT_BLK_PERIC0_UID_PERIC0_TOP0_IPCLKPORT_IPCLK_6, + 21, 0, 0), + GATE(CLK_GOUT_PERIC0_TOP0_IPCLK_7, "gout_peric0_top0_ipclk_7", + "dout_peric0_usi01_usi", + CLK_CON_GAT_GOUT_BLK_PERIC0_UID_PERIC0_TOP0_IPCLKPORT_IPCLK_7, + 21, 0, 0), + GATE(CLK_GOUT_PERIC0_TOP0_IPCLK_8, "gout_peric0_top0_ipclk_8", + "dout_peric0_usi_i2c", + CLK_CON_GAT_GOUT_BLK_PERIC0_UID_PERIC0_TOP0_IPCLKPORT_IPCLK_8, + 21, 0, 0), + GATE(CLK_GOUT_PERIC0_TOP0_IPCLK_9, "gout_peric0_top0_ipclk_9", + "dout_peric0_usi02_usi", + CLK_CON_GAT_GOUT_BLK_PERIC0_UID_PERIC0_TOP0_IPCLKPORT_IPCLK_9, + 21, 0, 0), + GATE(CLK_GOUT_PERIC0_TOP0_PCLK_10, "gout_peric0_top0_pclk_10", + "mout_peric0_bus_user", + CLK_CON_GAT_GOUT_BLK_PERIC0_UID_PERIC0_TOP0_IPCLKPORT_PCLK_10, + 21, 0, 0), + GATE(CLK_GOUT_PERIC0_TOP0_PCLK_11, "gout_peric0_top0_pclk_11", + "mout_peric0_bus_user", + CLK_CON_GAT_GOUT_BLK_PERIC0_UID_PERIC0_TOP0_IPCLKPORT_PCLK_11, + 21, 0, 0), + GATE(CLK_GOUT_PERIC0_TOP0_PCLK_12, "gout_peric0_top0_pclk_12", + "mout_peric0_bus_user", + CLK_CON_GAT_GOUT_BLK_PERIC0_UID_PERIC0_TOP0_IPCLKPORT_PCLK_12, + 21, 0, 0), + GATE(CLK_GOUT_PERIC0_TOP0_PCLK_13, "gout_peric0_top0_pclk_13", + "mout_peric0_bus_user", + CLK_CON_GAT_GOUT_BLK_PERIC0_UID_PERIC0_TOP0_IPCLKPORT_PCLK_13, + 21, 0, 0), + GATE(CLK_GOUT_PERIC0_TOP0_PCLK_14, "gout_peric0_top0_pclk_14", + "mout_peric0_bus_user", + CLK_CON_GAT_GOUT_BLK_PERIC0_UID_PERIC0_TOP0_IPCLKPORT_PCLK_14, + 21, 0, 0), + GATE(CLK_GOUT_PERIC0_TOP0_PCLK_15, "gout_peric0_top0_pclk_15", + "mout_peric0_bus_user", + CLK_CON_GAT_GOUT_BLK_PERIC0_UID_PERIC0_TOP0_IPCLKPORT_PCLK_15, + 21, 0, 0), + GATE(CLK_GOUT_PERIC0_TOP0_PCLK_4, "gout_peric0_top0_pclk_4", + "mout_peric0_bus_user", + CLK_CON_GAT_GOUT_BLK_PERIC0_UID_PERIC0_TOP0_IPCLKPORT_PCLK_4, + 21, 0, 0), + GATE(CLK_GOUT_PERIC0_TOP0_PCLK_5, "gout_peric0_top0_pclk_5", + "mout_peric0_bus_user", + CLK_CON_GAT_GOUT_BLK_PERIC0_UID_PERIC0_TOP0_IPCLKPORT_PCLK_5, + 21, 0, 0), + GATE(CLK_GOUT_PERIC0_TOP0_PCLK_6, "gout_peric0_top0_pclk_6", + "mout_peric0_bus_user", + CLK_CON_GAT_GOUT_BLK_PERIC0_UID_PERIC0_TOP0_IPCLKPORT_PCLK_6, + 21, 0, 0), + GATE(CLK_GOUT_PERIC0_TOP0_PCLK_7, "gout_peric0_top0_pclk_7", + "mout_peric0_bus_user", + CLK_CON_GAT_GOUT_BLK_PERIC0_UID_PERIC0_TOP0_IPCLKPORT_PCLK_7, + 21, 0, 0), + GATE(CLK_GOUT_PERIC0_TOP0_PCLK_8, "gout_peric0_top0_pclk_8", + "mout_peric0_bus_user", + CLK_CON_GAT_GOUT_BLK_PERIC0_UID_PERIC0_TOP0_IPCLKPORT_PCLK_8, + 21, 0, 0), + GATE(CLK_GOUT_PERIC0_TOP0_PCLK_9, "gout_peric0_top0_pclk_9", + "mout_peric0_bus_user", + CLK_CON_GAT_GOUT_BLK_PERIC0_UID_PERIC0_TOP0_IPCLKPORT_PCLK_9, + 21, 0, 0), + GATE(CLK_GOUT_PERIC0_TOP1_IPCLK_0, "gout_peric0_top1_ipclk_0", + "dout_peric0_usi_i2c", + CLK_CON_GAT_GOUT_BLK_PERIC0_UID_PERIC0_TOP1_IPCLKPORT_IPCLK_0, + 21, 0, 0), + GATE(CLK_GOUT_PERIC0_TOP1_IPCLK_3, "gout_peric0_top1_ipclk_3", + "dout_peric0_usi13_usi", + CLK_CON_GAT_GOUT_BLK_PERIC0_UID_PERIC0_TOP1_IPCLKPORT_IPCLK_3, + 21, 0, 0), + GATE(CLK_GOUT_PERIC0_TOP1_IPCLK_4, "gout_peric0_top1_ipclk_4", + "dout_peric0_usi_i2c", + CLK_CON_GAT_GOUT_BLK_PERIC0_UID_PERIC0_TOP1_IPCLKPORT_IPCLK_4, + 21, 0, 0), + GATE(CLK_GOUT_PERIC0_TOP1_IPCLK_5, "gout_peric0_top1_ipclk_5", + "dout_peric0_usi14_usi", + CLK_CON_GAT_GOUT_BLK_PERIC0_UID_PERIC0_TOP1_IPCLKPORT_IPCLK_5, + 21, 0, 0), + GATE(CLK_GOUT_PERIC0_TOP1_IPCLK_6, "gout_peric0_top1_ipclk_6", + "dout_peric0_usi_i2c", + CLK_CON_GAT_GOUT_BLK_PERIC0_UID_PERIC0_TOP1_IPCLKPORT_IPCLK_6, + 21, 0, 0), + GATE(CLK_GOUT_PERIC0_TOP1_IPCLK_7, "gout_peric0_top1_ipclk_7", + "dout_peric0_usi15_usi", + CLK_CON_GAT_GOUT_BLK_PERIC0_UID_PERIC0_TOP1_IPCLKPORT_IPCLK_7, + 21, 0, 0), + GATE(CLK_GOUT_PERIC0_TOP1_IPCLK_8, "gout_peric0_top1_ipclk_8", + "dout_peric0_usi_i2c", + CLK_CON_GAT_GOUT_BLK_PERIC0_UID_PERIC0_TOP1_IPCLKPORT_IPCLK_8, + 21, 0, 0), + GATE(CLK_GOUT_PERIC0_TOP1_PCLK_0, "gout_peric0_top1_pclk_0", + "mout_peric0_bus_user", + CLK_CON_GAT_GOUT_BLK_PERIC0_UID_PERIC0_TOP1_IPCLKPORT_PCLK_0, + 21, 0, 0), + GATE(CLK_GOUT_PERIC0_TOP1_PCLK_15, "gout_peric0_top1_pclk_15", + "mout_peric0_bus_user", + CLK_CON_GAT_GOUT_BLK_PERIC0_UID_PERIC0_TOP1_IPCLKPORT_PCLK_15, + 21, 0, 0), + GATE(CLK_GOUT_PERIC0_TOP1_PCLK_3, "gout_peric0_top1_pclk_3", + "mout_peric0_bus_user", + CLK_CON_GAT_GOUT_BLK_PERIC0_UID_PERIC0_TOP1_IPCLKPORT_PCLK_3, + 21, 0, 0), + GATE(CLK_GOUT_PERIC0_TOP1_PCLK_4, "gout_peric0_top1_pclk_4", + "mout_peric0_bus_user", + CLK_CON_GAT_GOUT_BLK_PERIC0_UID_PERIC0_TOP1_IPCLKPORT_PCLK_4, + 21, 0, 0), + GATE(CLK_GOUT_PERIC0_TOP1_PCLK_5, "gout_peric0_top1_pclk_5", + "mout_peric0_bus_user", + CLK_CON_GAT_GOUT_BLK_PERIC0_UID_PERIC0_TOP1_IPCLKPORT_PCLK_5, + 21, 0, 0), + GATE(CLK_GOUT_PERIC0_TOP1_PCLK_6, "gout_peric0_top1_pclk_6", + "mout_peric0_bus_user", + CLK_CON_GAT_GOUT_BLK_PERIC0_UID_PERIC0_TOP1_IPCLKPORT_PCLK_6, + 21, 0, 0), + GATE(CLK_GOUT_PERIC0_TOP1_PCLK_7, "gout_peric0_top1_pclk_7", + "mout_peric0_bus_user", + CLK_CON_GAT_GOUT_BLK_PERIC0_UID_PERIC0_TOP1_IPCLKPORT_PCLK_7, + 21, 0, 0), + GATE(CLK_GOUT_PERIC0_TOP1_PCLK_8, "gout_peric0_top1_pclk_8", + "mout_peric0_bus_user", + CLK_CON_GAT_GOUT_BLK_PERIC0_UID_PERIC0_TOP1_IPCLKPORT_PCLK_8, + 21, 0, 0), + GATE(CLK_GOUT_PERIC0_BUSP_CLK, "gout_peric0_busp_clk", + "mout_peric0_bus_user", + CLK_CON_GAT_GOUT_BLK_PERIC0_UID_RSTNSYNC_CLK_PERIC0_BUSP_IPCLKPORT_CLK, + 21, 0, 0), + GATE(CLK_GOUT_PERIC0_UART_DBG_CLK, "gout_peric0_uart_dbg_clk", + "dout_peric0_uart_dbg", + CLK_CON_GAT_GOUT_BLK_PERIC0_UID_RSTNSYNC_CLK_PERIC0_UART_DBG_IPCLKPORT_CLK, + 21, 0, 0), + GATE(CLK_GOUT_PERIC0_USI00_USI_CLK, "gout_peric0_usi00_usi_clk", + "dout_peric0_usi00_usi", + CLK_CON_GAT_GOUT_BLK_PERIC0_UID_RSTNSYNC_CLK_PERIC0_USI00_USI_IPCLKPORT_CLK, + 21, 0, 0), + GATE(CLK_GOUT_PERIC0_USI01_USI_CLK, "gout_peric0_usi01_usi_clk", + "dout_peric0_usi01_usi", + CLK_CON_GAT_GOUT_BLK_PERIC0_UID_RSTNSYNC_CLK_PERIC0_USI01_USI_IPCLKPORT_CLK, + 21, 0, 0), + GATE(CLK_GOUT_PERIC0_USI02_USI_CLK, "gout_peric0_usi02_usi_clk", + "dout_peric0_usi02_usi", + CLK_CON_GAT_GOUT_BLK_PERIC0_UID_RSTNSYNC_CLK_PERIC0_USI02_USI_IPCLKPORT_CLK, + 21, 0, 0), + GATE(CLK_GOUT_PERIC0_USI03_USI_CLK, "gout_peric0_usi03_usi_clk", + "dout_peric0_usi03_usi", + CLK_CON_GAT_GOUT_BLK_PERIC0_UID_RSTNSYNC_CLK_PERIC0_USI03_USI_IPCLKPORT_CLK, + 21, 0, 0), + GATE(CLK_GOUT_PERIC0_USI04_USI_CLK, "gout_peric0_usi04_usi_clk", + "dout_peric0_usi04_usi", + CLK_CON_GAT_GOUT_BLK_PERIC0_UID_RSTNSYNC_CLK_PERIC0_USI04_USI_IPCLKPORT_CLK, + 21, 0, 0), + GATE(CLK_GOUT_PERIC0_USI05_USI_CLK, "gout_peric0_usi05_usi_clk", + "dout_peric0_usi05_usi", + CLK_CON_GAT_GOUT_BLK_PERIC0_UID_RSTNSYNC_CLK_PERIC0_USI05_USI_IPCLKPORT_CLK, + 21, 0, 0), + GATE(CLK_GOUT_PERIC0_USI13_USI_CLK, "gout_peric0_usi13_usi_clk", + "dout_peric0_usi13_usi", + CLK_CON_GAT_GOUT_BLK_PERIC0_UID_RSTNSYNC_CLK_PERIC0_USI13_USI_IPCLKPORT_CLK, + 21, 0, 0), + GATE(CLK_GOUT_PERIC0_USI14_USI_CLK, "gout_peric0_usi14_usi_clk", + "dout_peric0_usi14_usi", + CLK_CON_GAT_GOUT_BLK_PERIC0_UID_RSTNSYNC_CLK_PERIC0_USI14_USI_IPCLKPORT_CLK, + 21, 0, 0), + GATE(CLK_GOUT_PERIC0_USI15_USI_CLK, "gout_peric0_usi15_usi_clk", + "dout_peric0_usi15_usi", + CLK_CON_GAT_GOUT_BLK_PERIC0_UID_RSTNSYNC_CLK_PERIC0_USI15_USI_IPCLKPORT_CLK, + 21, 0, 0), + GATE(CLK_GOUT_PERIC0_USI_I2C_CLK, "gout_peric0_usi_i2c_clk", + "dout_peric0_usi_i2c", + CLK_CON_GAT_GOUT_BLK_PERIC0_UID_RSTNSYNC_CLK_PERIC0_USI_I2C_IPCLKPORT_CLK, + 21, 0, 0), + GATE(CLK_GOUT_PERIC0_SYSREG_PCLK, "gout_peric0_sysreg_pclk", + "mout_peric0_bus_user", + CLK_CON_GAT_GOUT_BLK_PERIC0_UID_SYSREG_PERIC0_IPCLKPORT_PCLK, + 21, 0, 0) +}; + +static const struct samsung_cmu_info peric0_cmu_info __initconst = { + .mux_clks = peric0_mux_clks, + .nr_mux_clks = ARRAY_SIZE(peric0_mux_clks), + .div_clks = peric0_div_clks, + .nr_div_clks = ARRAY_SIZE(peric0_div_clks), + .gate_clks = peric0_gate_clks, + .nr_gate_clks = ARRAY_SIZE(peric0_gate_clks), + .nr_clk_ids = CLKS_NR_PERIC0, + .clk_regs = peric0_clk_regs, + .nr_clk_regs = ARRAY_SIZE(peric0_clk_regs), + .clk_name = "bus", +}; + +/* ---- CMU_PERIC1 --------------------------------------------------------- */ + +/* Register Offset definitions for CMU_PERIC1 (0x10700000) */ +#define PLL_CON0_MUX_CLKCMU_PERIC1_BUS_USER 0x0600 +#define PLL_CON1_MUX_CLKCMU_PERIC1_BUS_USER 0x0604 +#define PLL_CON0_MUX_CLKCMU_PERIC1_UART_BT_USER 0x0610 +#define PLL_CON1_MUX_CLKCMU_PERIC1_UART_BT_USER 0x0614 +#define PLL_CON0_MUX_CLKCMU_PERIC1_USI06_USI_USER 0x0620 +#define PLL_CON1_MUX_CLKCMU_PERIC1_USI06_USI_USER 0x0624 +#define PLL_CON0_MUX_CLKCMU_PERIC1_USI07_USI_USER 0x0630 +#define PLL_CON1_MUX_CLKCMU_PERIC1_USI07_USI_USER 0x0634 +#define PLL_CON0_MUX_CLKCMU_PERIC1_USI08_USI_USER 0x0640 +#define PLL_CON1_MUX_CLKCMU_PERIC1_USI08_USI_USER 0x0644 +#define PLL_CON0_MUX_CLKCMU_PERIC1_USI09_USI_USER 0x0650 +#define PLL_CON1_MUX_CLKCMU_PERIC1_USI09_USI_USER 0x0654 +#define PLL_CON0_MUX_CLKCMU_PERIC1_USI10_USI_USER 0x0660 +#define PLL_CON1_MUX_CLKCMU_PERIC1_USI10_USI_USER 0x0664 +#define PLL_CON0_MUX_CLKCMU_PERIC1_USI11_USI_USER 0x0670 +#define PLL_CON1_MUX_CLKCMU_PERIC1_USI11_USI_USER 0x0674 +#define PLL_CON0_MUX_CLKCMU_PERIC1_USI12_USI_USER 0x0680 +#define PLL_CON1_MUX_CLKCMU_PERIC1_USI12_USI_USER 0x0684 +#define PLL_CON0_MUX_CLKCMU_PERIC1_USI16_USI_USER 0x0690 +#define PLL_CON1_MUX_CLKCMU_PERIC1_USI16_USI_USER 0x0694 +#define PLL_CON0_MUX_CLKCMU_PERIC1_USI17_USI_USER 0x06a0 +#define PLL_CON1_MUX_CLKCMU_PERIC1_USI17_USI_USER 0x06a4 +#define PLL_CON0_MUX_CLKCMU_PERIC1_USI18_USI_USER 0x06b0 +#define PLL_CON1_MUX_CLKCMU_PERIC1_USI18_USI_USER 0x06b4 +#define PLL_CON0_MUX_CLKCMU_PERIC1_USI_I2C_USER 0x06c0 +#define PLL_CON1_MUX_CLKCMU_PERIC1_USI_I2C_USER 0x06c4 +#define CLK_CON_DIV_DIV_CLK_PERIC1_UART_BT 0x1800 +#define CLK_CON_DIV_DIV_CLK_PERIC1_USI06_USI 0x1804 +#define CLK_CON_DIV_DIV_CLK_PERIC1_USI07_USI 0x1808 +#define CLK_CON_DIV_DIV_CLK_PERIC1_USI08_USI 0x180c +#define CLK_CON_DIV_DIV_CLK_PERIC1_USI09_USI 0x1810 +#define CLK_CON_DIV_DIV_CLK_PERIC1_USI10_USI 0x1814 +#define CLK_CON_DIV_DIV_CLK_PERIC1_USI11_USI 0x1818 +#define CLK_CON_DIV_DIV_CLK_PERIC1_USI12_USI 0x181c +#define CLK_CON_DIV_DIV_CLK_PERIC1_USI16_USI 0x1820 +#define CLK_CON_DIV_DIV_CLK_PERIC1_USI17_USI 0x1824 +#define CLK_CON_DIV_DIV_CLK_PERIC1_USI18_USI 0x1828 +#define CLK_CON_DIV_DIV_CLK_PERIC1_USI_I2C 0x182c +#define CLK_CON_GAT_CLK_BLK_PERIC1_UID_PERIC1_CMU_PERIC1_IPCLKPORT_PCLK 0x2004 +#define CLK_CON_GAT_CLK_BLK_PERIC1_UID_RSTNSYNC_CLK_PERIC1_UART_BT_IPCLKPORT_CLK 0x2008 +#define CLK_CON_GAT_CLK_BLK_PERIC1_UID_RSTNSYNC_CLK_PERIC1_USI12_USI_IPCLKPORT_CLK 0x200c +#define CLK_CON_GAT_CLK_BLK_PERIC1_UID_RSTNSYNC_CLK_PERIC1_USI18_USI_IPCLKPORT_CLK 0x2010 +#define CLK_CON_GAT_GOUT_BLK_PERIC1_UID_D_TZPC_PERIC1_IPCLKPORT_PCLK 0x2014 +#define CLK_CON_GAT_GOUT_BLK_PERIC1_UID_GPIO_PERIC1_IPCLKPORT_PCLK 0x2018 +#define CLK_CON_GAT_GOUT_BLK_PERIC1_UID_LHM_AXI_P_CSISPERIC1_IPCLKPORT_I_CLK 0x201c +#define CLK_CON_GAT_GOUT_BLK_PERIC1_UID_LHM_AXI_P_PERIC1_IPCLKPORT_I_CLK 0x2020 +#define CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP0_IPCLKPORT_IPCLK_10 0x2024 +#define CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP0_IPCLKPORT_IPCLK_11 0x2028 +#define CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP0_IPCLKPORT_IPCLK_12 0x202c +#define CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP0_IPCLKPORT_IPCLK_13 0x2030 +#define CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP0_IPCLKPORT_IPCLK_14 0x2034 +#define CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP0_IPCLKPORT_IPCLK_15 0x2038 +#define CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP0_IPCLKPORT_IPCLK_4 0x203c +#define CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP0_IPCLKPORT_PCLK_10 0x2040 +#define CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP0_IPCLKPORT_PCLK_11 0x2044 +#define CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP0_IPCLKPORT_PCLK_12 0x2048 +#define CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP0_IPCLKPORT_PCLK_13 0x204c +#define CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP0_IPCLKPORT_PCLK_14 0x2050 +#define CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP0_IPCLKPORT_PCLK_15 0x2054 +#define CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP0_IPCLKPORT_PCLK_4 0x2058 +#define CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP1_IPCLKPORT_IPCLK_0 0x205c +#define CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP1_IPCLKPORT_IPCLK_1 0x2060 +#define CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP1_IPCLKPORT_IPCLK_10 0x2064 +#define CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP1_IPCLKPORT_IPCLK_12 0x206c +#define CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP1_IPCLKPORT_IPCLK_13 0x2070 +#define CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP1_IPCLKPORT_IPCLK_14 0x2074 +#define CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP1_IPCLKPORT_IPCLK_15 0x2078 +#define CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP1_IPCLKPORT_IPCLK_2 0x207c +#define CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP1_IPCLKPORT_IPCLK_3 0x2080 +#define CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP1_IPCLKPORT_IPCLK_4 0x2084 +#define CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP1_IPCLKPORT_IPCLK_5 0x2088 +#define CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP1_IPCLKPORT_IPCLK_6 0x208c +#define CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP1_IPCLKPORT_IPCLK_7 0x2090 +#define CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP1_IPCLKPORT_IPCLK_9 0x2098 +#define CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP1_IPCLKPORT_PCLK_0 0x209c +#define CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP1_IPCLKPORT_PCLK_1 0x20a0 +#define CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP1_IPCLKPORT_PCLK_10 0x20a4 +#define CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP1_IPCLKPORT_PCLK_12 0x20ac +#define CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP1_IPCLKPORT_PCLK_13 0x20b0 +#define CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP1_IPCLKPORT_PCLK_14 0x20b4 +#define CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP1_IPCLKPORT_PCLK_15 0x20b8 +#define CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP1_IPCLKPORT_PCLK_2 0x20bc +#define CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP1_IPCLKPORT_PCLK_3 0x20c0 +#define CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP1_IPCLKPORT_PCLK_4 0x20c4 +#define CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP1_IPCLKPORT_PCLK_5 0x20c8 +#define CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP1_IPCLKPORT_PCLK_6 0x20cc +#define CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP1_IPCLKPORT_PCLK_7 0x20d0 +#define CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP1_IPCLKPORT_PCLK_9 0x20d8 +#define CLK_CON_GAT_GOUT_BLK_PERIC1_UID_RSTNSYNC_CLK_PERIC1_BUSP_IPCLKPORT_CLK 0x20dc +#define CLK_CON_GAT_GOUT_BLK_PERIC1_UID_RSTNSYNC_CLK_PERIC1_OSCCLK_IPCLKPORT_CLK 0x20e0 +#define CLK_CON_GAT_GOUT_BLK_PERIC1_UID_RSTNSYNC_CLK_PERIC1_USI06_USI_IPCLKPORT_CLK 0x20e4 +#define CLK_CON_GAT_GOUT_BLK_PERIC1_UID_RSTNSYNC_CLK_PERIC1_USI07_USI_IPCLKPORT_CLK 0x20e8 +#define CLK_CON_GAT_GOUT_BLK_PERIC1_UID_RSTNSYNC_CLK_PERIC1_USI08_USI_IPCLKPORT_CLK 0x20ec +#define CLK_CON_GAT_GOUT_BLK_PERIC1_UID_RSTNSYNC_CLK_PERIC1_USI09_USI_IPCLKPORT_CLK 0x20f0 +#define CLK_CON_GAT_GOUT_BLK_PERIC1_UID_RSTNSYNC_CLK_PERIC1_USI10_USI_IPCLKPORT_CLK 0x20f4 +#define CLK_CON_GAT_GOUT_BLK_PERIC1_UID_RSTNSYNC_CLK_PERIC1_USI11_USI_IPCLKPORT_CLK 0x20f8 +#define CLK_CON_GAT_GOUT_BLK_PERIC1_UID_RSTNSYNC_CLK_PERIC1_USI16_USI_IPCLKPORT_CLK 0x20fc +#define CLK_CON_GAT_GOUT_BLK_PERIC1_UID_RSTNSYNC_CLK_PERIC1_USI17_USI_IPCLKPORT_CLK 0x2100 +#define CLK_CON_GAT_GOUT_BLK_PERIC1_UID_RSTNSYNC_CLK_PERIC1_USI_I2C_IPCLKPORT_CLK 0x2104 +#define CLK_CON_GAT_GOUT_BLK_PERIC1_UID_SYSREG_PERIC1_IPCLKPORT_PCLK 0x2108 +#define CLK_CON_GAT_GOUT_BLK_PERIC1_UID_USI16_I3C_IPCLKPORT_I_PCLK 0x210c +#define CLK_CON_GAT_GOUT_BLK_PERIC1_UID_USI16_I3C_IPCLKPORT_I_SCLK 0x2110 +#define CLK_CON_GAT_GOUT_BLK_PERIC1_UID_USI17_I3C_IPCLKPORT_I_PCLK 0x2114 +#define CLK_CON_GAT_GOUT_BLK_PERIC1_UID_USI17_I3C_IPCLKPORT_I_SCLK 0x2118 +#define CLK_CON_GAT_GOUT_BLK_PERIC1_UID_XIU_P_PERIC1_IPCLKPORT_ACLK 0x211c + +static const unsigned long peric1_clk_regs[] __initconst = { + PLL_CON0_MUX_CLKCMU_PERIC1_BUS_USER, + PLL_CON1_MUX_CLKCMU_PERIC1_BUS_USER, + PLL_CON0_MUX_CLKCMU_PERIC1_UART_BT_USER, + PLL_CON1_MUX_CLKCMU_PERIC1_UART_BT_USER, + PLL_CON0_MUX_CLKCMU_PERIC1_USI06_USI_USER, + PLL_CON1_MUX_CLKCMU_PERIC1_USI06_USI_USER, + PLL_CON0_MUX_CLKCMU_PERIC1_USI07_USI_USER, + PLL_CON1_MUX_CLKCMU_PERIC1_USI07_USI_USER, + PLL_CON0_MUX_CLKCMU_PERIC1_USI08_USI_USER, + PLL_CON1_MUX_CLKCMU_PERIC1_USI08_USI_USER, + PLL_CON0_MUX_CLKCMU_PERIC1_USI09_USI_USER, + PLL_CON1_MUX_CLKCMU_PERIC1_USI09_USI_USER, + PLL_CON0_MUX_CLKCMU_PERIC1_USI10_USI_USER, + PLL_CON1_MUX_CLKCMU_PERIC1_USI10_USI_USER, + PLL_CON0_MUX_CLKCMU_PERIC1_USI11_USI_USER, + PLL_CON1_MUX_CLKCMU_PERIC1_USI11_USI_USER, + PLL_CON0_MUX_CLKCMU_PERIC1_USI12_USI_USER, + PLL_CON1_MUX_CLKCMU_PERIC1_USI12_USI_USER, + PLL_CON0_MUX_CLKCMU_PERIC1_USI16_USI_USER, + PLL_CON1_MUX_CLKCMU_PERIC1_USI16_USI_USER, + PLL_CON0_MUX_CLKCMU_PERIC1_USI17_USI_USER, + PLL_CON1_MUX_CLKCMU_PERIC1_USI17_USI_USER, + PLL_CON0_MUX_CLKCMU_PERIC1_USI18_USI_USER, + PLL_CON1_MUX_CLKCMU_PERIC1_USI18_USI_USER, + PLL_CON0_MUX_CLKCMU_PERIC1_USI_I2C_USER, + PLL_CON1_MUX_CLKCMU_PERIC1_USI_I2C_USER, + CLK_CON_DIV_DIV_CLK_PERIC1_UART_BT, + CLK_CON_DIV_DIV_CLK_PERIC1_USI06_USI, + CLK_CON_DIV_DIV_CLK_PERIC1_USI07_USI, + CLK_CON_DIV_DIV_CLK_PERIC1_USI08_USI, + CLK_CON_DIV_DIV_CLK_PERIC1_USI09_USI, + CLK_CON_DIV_DIV_CLK_PERIC1_USI10_USI, + CLK_CON_DIV_DIV_CLK_PERIC1_USI11_USI, + CLK_CON_DIV_DIV_CLK_PERIC1_USI12_USI, + CLK_CON_DIV_DIV_CLK_PERIC1_USI16_USI, + CLK_CON_DIV_DIV_CLK_PERIC1_USI17_USI, + CLK_CON_DIV_DIV_CLK_PERIC1_USI18_USI, + CLK_CON_DIV_DIV_CLK_PERIC1_USI_I2C, + CLK_CON_GAT_CLK_BLK_PERIC1_UID_PERIC1_CMU_PERIC1_IPCLKPORT_PCLK, + CLK_CON_GAT_CLK_BLK_PERIC1_UID_RSTNSYNC_CLK_PERIC1_UART_BT_IPCLKPORT_CLK, + CLK_CON_GAT_CLK_BLK_PERIC1_UID_RSTNSYNC_CLK_PERIC1_USI12_USI_IPCLKPORT_CLK, + CLK_CON_GAT_CLK_BLK_PERIC1_UID_RSTNSYNC_CLK_PERIC1_USI18_USI_IPCLKPORT_CLK, + CLK_CON_GAT_GOUT_BLK_PERIC1_UID_D_TZPC_PERIC1_IPCLKPORT_PCLK, + CLK_CON_GAT_GOUT_BLK_PERIC1_UID_GPIO_PERIC1_IPCLKPORT_PCLK, + CLK_CON_GAT_GOUT_BLK_PERIC1_UID_LHM_AXI_P_CSISPERIC1_IPCLKPORT_I_CLK, + CLK_CON_GAT_GOUT_BLK_PERIC1_UID_LHM_AXI_P_PERIC1_IPCLKPORT_I_CLK, + CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP0_IPCLKPORT_IPCLK_10, + CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP0_IPCLKPORT_IPCLK_11, + CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP0_IPCLKPORT_IPCLK_12, + CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP0_IPCLKPORT_IPCLK_13, + CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP0_IPCLKPORT_IPCLK_14, + CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP0_IPCLKPORT_IPCLK_15, + CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP0_IPCLKPORT_IPCLK_4, + CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP0_IPCLKPORT_PCLK_10, + CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP0_IPCLKPORT_PCLK_11, + CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP0_IPCLKPORT_PCLK_12, + CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP0_IPCLKPORT_PCLK_13, + CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP0_IPCLKPORT_PCLK_14, + CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP0_IPCLKPORT_PCLK_15, + CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP0_IPCLKPORT_PCLK_4, + CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP1_IPCLKPORT_IPCLK_0, + CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP1_IPCLKPORT_IPCLK_1, + CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP1_IPCLKPORT_IPCLK_10, + CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP1_IPCLKPORT_IPCLK_12, + CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP1_IPCLKPORT_IPCLK_13, + CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP1_IPCLKPORT_IPCLK_14, + CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP1_IPCLKPORT_IPCLK_15, + CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP1_IPCLKPORT_IPCLK_2, + CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP1_IPCLKPORT_IPCLK_3, + CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP1_IPCLKPORT_IPCLK_4, + CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP1_IPCLKPORT_IPCLK_5, + CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP1_IPCLKPORT_IPCLK_6, + CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP1_IPCLKPORT_IPCLK_7, + CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP1_IPCLKPORT_IPCLK_9, + CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP1_IPCLKPORT_PCLK_0, + CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP1_IPCLKPORT_PCLK_1, + CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP1_IPCLKPORT_PCLK_10, + CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP1_IPCLKPORT_PCLK_12, + CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP1_IPCLKPORT_PCLK_13, + CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP1_IPCLKPORT_PCLK_14, + CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP1_IPCLKPORT_PCLK_15, + CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP1_IPCLKPORT_PCLK_2, + CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP1_IPCLKPORT_PCLK_3, + CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP1_IPCLKPORT_PCLK_4, + CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP1_IPCLKPORT_PCLK_5, + CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP1_IPCLKPORT_PCLK_6, + CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP1_IPCLKPORT_PCLK_7, + CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP1_IPCLKPORT_PCLK_9, + CLK_CON_GAT_GOUT_BLK_PERIC1_UID_RSTNSYNC_CLK_PERIC1_BUSP_IPCLKPORT_CLK, + CLK_CON_GAT_GOUT_BLK_PERIC1_UID_RSTNSYNC_CLK_PERIC1_OSCCLK_IPCLKPORT_CLK, + CLK_CON_GAT_GOUT_BLK_PERIC1_UID_RSTNSYNC_CLK_PERIC1_USI06_USI_IPCLKPORT_CLK, + CLK_CON_GAT_GOUT_BLK_PERIC1_UID_RSTNSYNC_CLK_PERIC1_USI07_USI_IPCLKPORT_CLK, + CLK_CON_GAT_GOUT_BLK_PERIC1_UID_RSTNSYNC_CLK_PERIC1_USI08_USI_IPCLKPORT_CLK, + CLK_CON_GAT_GOUT_BLK_PERIC1_UID_RSTNSYNC_CLK_PERIC1_USI09_USI_IPCLKPORT_CLK, + CLK_CON_GAT_GOUT_BLK_PERIC1_UID_RSTNSYNC_CLK_PERIC1_USI10_USI_IPCLKPORT_CLK, + CLK_CON_GAT_GOUT_BLK_PERIC1_UID_RSTNSYNC_CLK_PERIC1_USI11_USI_IPCLKPORT_CLK, + CLK_CON_GAT_GOUT_BLK_PERIC1_UID_RSTNSYNC_CLK_PERIC1_USI16_USI_IPCLKPORT_CLK, + CLK_CON_GAT_GOUT_BLK_PERIC1_UID_RSTNSYNC_CLK_PERIC1_USI17_USI_IPCLKPORT_CLK, + CLK_CON_GAT_GOUT_BLK_PERIC1_UID_RSTNSYNC_CLK_PERIC1_USI_I2C_IPCLKPORT_CLK, + CLK_CON_GAT_GOUT_BLK_PERIC1_UID_SYSREG_PERIC1_IPCLKPORT_PCLK, + CLK_CON_GAT_GOUT_BLK_PERIC1_UID_USI16_I3C_IPCLKPORT_I_PCLK, + CLK_CON_GAT_GOUT_BLK_PERIC1_UID_USI16_I3C_IPCLKPORT_I_SCLK, + CLK_CON_GAT_GOUT_BLK_PERIC1_UID_USI17_I3C_IPCLKPORT_I_PCLK, + CLK_CON_GAT_GOUT_BLK_PERIC1_UID_USI17_I3C_IPCLKPORT_I_SCLK, + CLK_CON_GAT_GOUT_BLK_PERIC1_UID_XIU_P_PERIC1_IPCLKPORT_ACLK, +}; + +/* Parent clock list for CMU_PERIC1 muxes */ +PNAME(mout_peric1_bus_user_p) = { "oscclk", "dout_cmu_peric1_bus" }; +PNAME(mout_peric1_uart_bt_user_p) = { "oscclk", "dout_cmu_peric1_ip" }; +PNAME(mout_peric1_usi06_user_p) = { "oscclk", "dout_cmu_peric1_ip" }; +PNAME(mout_peric1_usi07_user_p) = { "oscclk", "dout_cmu_peric1_ip" }; +PNAME(mout_peric1_usi08_user_p) = { "oscclk", "dout_cmu_peric1_ip" }; +PNAME(mout_peric1_usi09_user_p) = { "oscclk", "dout_cmu_peric1_ip" }; +PNAME(mout_peric1_usi10_user_p) = { "oscclk", "dout_cmu_peric1_ip" }; +PNAME(mout_peric1_usi11_user_p) = { "oscclk", "dout_cmu_peric1_ip" }; +PNAME(mout_peric1_usi12_user_p) = { "oscclk", "dout_cmu_peric1_ip" }; +PNAME(mout_peric1_usi18_user_p) = { "oscclk", "dout_cmu_peric1_ip" }; +PNAME(mout_peric1_usi16_user_p) = { "oscclk", "dout_cmu_peric1_ip" }; +PNAME(mout_peric1_usi17_user_p) = { "oscclk", "dout_cmu_peric1_ip" }; +PNAME(mout_peric1_usi_i2c_user_p) = { "oscclk", "dout_cmu_peric1_ip" }; + +static const struct samsung_mux_clock peric1_mux_clks[] __initconst = { + MUX(CLK_MOUT_PERIC1_BUS_USER, "mout_peric1_bus_user", + mout_peric1_bus_user_p, PLL_CON0_MUX_CLKCMU_PERIC1_BUS_USER, + 4, 1), + MUX(CLK_MOUT_PERIC1_UART_BT_USER, "mout_peric1_uart_bt_user", + mout_peric1_uart_bt_user_p, PLL_CON0_MUX_CLKCMU_PERIC1_UART_BT_USER, + 4, 1), + MUX(CLK_MOUT_PERIC1_USI06_USI_USER, "mout_peric1_usi06_usi_user", + mout_peric1_usi06_user_p, PLL_CON0_MUX_CLKCMU_PERIC1_USI06_USI_USER, + 4, 1), + MUX(CLK_MOUT_PERIC1_USI07_USI_USER, "mout_peric1_usi07_usi_user", + mout_peric1_usi07_user_p, PLL_CON0_MUX_CLKCMU_PERIC1_USI07_USI_USER, + 4, 1), + MUX(CLK_MOUT_PERIC1_USI08_USI_USER, "mout_peric1_usi08_usi_user", + mout_peric1_usi08_user_p, PLL_CON0_MUX_CLKCMU_PERIC1_USI08_USI_USER, + 4, 1), + MUX(CLK_MOUT_PERIC1_USI09_USI_USER, "mout_peric1_usi09_usi_user", + mout_peric1_usi09_user_p, PLL_CON0_MUX_CLKCMU_PERIC1_USI09_USI_USER, + 4, 1), + MUX(CLK_MOUT_PERIC1_USI10_USI_USER, "mout_peric1_usi10_usi_user", + mout_peric1_usi10_user_p, PLL_CON0_MUX_CLKCMU_PERIC1_USI10_USI_USER, + 4, 1), + MUX(CLK_MOUT_PERIC1_USI11_USI_USER, "mout_peric1_usi11_usi_user", + mout_peric1_usi11_user_p, PLL_CON0_MUX_CLKCMU_PERIC1_USI11_USI_USER, + 4, 1), + MUX(CLK_MOUT_PERIC1_USI12_USI_USER, "mout_peric1_usi12_usi_user", + mout_peric1_usi12_user_p, PLL_CON0_MUX_CLKCMU_PERIC1_USI12_USI_USER, + 4, 1), + MUX(CLK_MOUT_PERIC1_USI18_USI_USER, "mout_peric1_usi18_usi_user", + mout_peric1_usi18_user_p, PLL_CON0_MUX_CLKCMU_PERIC1_USI18_USI_USER, + 4, 1), + MUX(CLK_MOUT_PERIC1_USI16_USI_USER, "mout_peric1_usi16_usi_user", + mout_peric1_usi16_user_p, PLL_CON0_MUX_CLKCMU_PERIC1_USI16_USI_USER, + 4, 1), + MUX(CLK_MOUT_PERIC1_USI17_USI_USER, "mout_peric1_usi17_usi_user", + mout_peric1_usi17_user_p, PLL_CON0_MUX_CLKCMU_PERIC1_USI17_USI_USER, + 4, 1), + MUX(CLK_MOUT_PERIC1_USI_I2C_USER, "mout_peric1_usi_i2c_user", + mout_peric1_usi_i2c_user_p, PLL_CON0_MUX_CLKCMU_PERIC1_USI_I2C_USER, + 4, 1), +}; + +static const struct samsung_div_clock peric1_div_clks[] __initconst = { + DIV(CLK_DOUT_PERIC1_UART_BT, "dout_peric1_uart_bt", + "mout_peric1_uart_bt_user", + CLK_CON_DIV_DIV_CLK_PERIC1_UART_BT, + 0, 4), + DIV(CLK_DOUT_PERIC1_USI06_USI, "dout_peric1_usi06_usi", + "mout_peric1_usi06_usi_user", + CLK_CON_DIV_DIV_CLK_PERIC1_USI06_USI, + 0, 4), + DIV(CLK_DOUT_PERIC1_USI07_USI, "dout_peric1_usi07_usi", + "mout_peric1_usi07_usi_user", + CLK_CON_DIV_DIV_CLK_PERIC1_USI07_USI, + 0, 4), + DIV(CLK_DOUT_PERIC1_USI08_USI, "dout_peric1_usi08_usi", + "mout_peric1_usi08_usi_user", + CLK_CON_DIV_DIV_CLK_PERIC1_USI08_USI, + 0, 4), + DIV(CLK_DOUT_PERIC1_USI18_USI, "dout_peric1_usi18_usi", + "mout_peric1_usi18_usi_user", + CLK_CON_DIV_DIV_CLK_PERIC1_USI18_USI, + 0, 4), + DIV(CLK_DOUT_PERIC1_USI12_USI, "dout_peric1_usi12_usi", + "mout_peric1_usi12_usi_user", + CLK_CON_DIV_DIV_CLK_PERIC1_USI12_USI, + 0, 4), + DIV(CLK_DOUT_PERIC1_USI09_USI, "dout_peric1_usi09_usi", + "mout_peric1_usi09_usi_user", + CLK_CON_DIV_DIV_CLK_PERIC1_USI09_USI, + 0, 4), + DIV(CLK_DOUT_PERIC1_USI10_USI, "dout_peric1_usi10_usi", + "mout_peric1_usi10_usi_user", + CLK_CON_DIV_DIV_CLK_PERIC1_USI10_USI, + 0, 4), + DIV(CLK_DOUT_PERIC1_USI11_USI, "dout_peric1_usi11_usi", + "mout_peric1_usi11_usi_user", + CLK_CON_DIV_DIV_CLK_PERIC1_USI11_USI, + 0, 4), + DIV(CLK_DOUT_PERIC1_USI16_USI, "dout_peric1_usi16_usi", + "mout_peric1_usi16_usi_user", + CLK_CON_DIV_DIV_CLK_PERIC1_USI16_USI, + 0, 4), + DIV(CLK_DOUT_PERIC1_USI17_USI, "dout_peric1_usi17_usi", + "mout_peric1_usi17_usi_user", + CLK_CON_DIV_DIV_CLK_PERIC1_USI17_USI, + 0, 4), + DIV(CLK_DOUT_PERIC1_USI_I2C, "dout_peric1_usi_i2c", + "mout_peric1_usi_i2c_user", + CLK_CON_DIV_DIV_CLK_PERIC1_USI_I2C, + 0, 4), +}; + +static const struct samsung_gate_clock peric1_gate_clks[] __initconst = { + GATE(CLK_GOUT_PERIC1_CMU_PCLK, "gout_peric1_cmu_pclk", + "mout_peric1_bus_user", + CLK_CON_GAT_CLK_BLK_PERIC1_UID_PERIC1_CMU_PERIC1_IPCLKPORT_PCLK, + 21, CLK_IS_CRITICAL, 0), + GATE(CLK_GOUT_PERIC1_UART_BT_CLK, "gout_peric1_uart_bt_clk", + "dout_peric1_uart_bt", + CLK_CON_GAT_CLK_BLK_PERIC1_UID_RSTNSYNC_CLK_PERIC1_UART_BT_IPCLKPORT_CLK, + 21, 0, 0), + GATE(CLK_GOUT_PERIC1_USI12_USI_CLK, "gout_peric1_usi12_usi_clk", + "dout_peric1_usi12_usi", + CLK_CON_GAT_CLK_BLK_PERIC1_UID_RSTNSYNC_CLK_PERIC1_USI12_USI_IPCLKPORT_CLK, + 21, 0, 0), + GATE(CLK_GOUT_PERIC1_USI18_USI_CLK, "gout_peric1_usi18_usi_clk", + "dout_peric1_usi18_usi", + CLK_CON_GAT_CLK_BLK_PERIC1_UID_RSTNSYNC_CLK_PERIC1_USI18_USI_IPCLKPORT_CLK, + 21, 0, 0), + GATE(CLK_GOUT_PERIC1_D_TZPC_PCLK, "gout_peric1_d_tzpc_pclk", + "dout_peric1_bus_user", + CLK_CON_GAT_GOUT_BLK_PERIC1_UID_D_TZPC_PERIC1_IPCLKPORT_PCLK, + 21, 0, 0), + GATE(CLK_GOUT_PERIC1_GPIO_PCLK, "gout_peric1_gpio_pclk", + "mout_peric1_bus_user", + CLK_CON_GAT_GOUT_BLK_PERIC1_UID_GPIO_PERIC1_IPCLKPORT_PCLK, + 21, CLK_IGNORE_UNUSED, 0), + GATE(CLK_GOUT_PERIC1_LHM_AXI_P_CSIS_CLK, "gout_peric1_lhm_axi_p_csis_clk", + "mout_peric1_bus_user", + CLK_CON_GAT_GOUT_BLK_PERIC1_UID_LHM_AXI_P_CSISPERIC1_IPCLKPORT_I_CLK, + 21, 0, 0), + GATE(CLK_GOUT_PERIC1_LHM_AXI_P_CLK, "gout_peric1_lhm_axi_p_clk", + "mout_peric1_bus_user", + CLK_CON_GAT_GOUT_BLK_PERIC1_UID_LHM_AXI_P_PERIC1_IPCLKPORT_I_CLK, + 21, CLK_IS_CRITICAL, 0), + GATE(CLK_GOUT_PERIC1_TOP0_IPCLK_10, "gout_peric1_top0_ipclk_10", + "dout_peric1_usi06_usi", + CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP0_IPCLKPORT_IPCLK_10, + 21, 0, 0), + GATE(CLK_GOUT_PERIC1_TOP0_IPCLK_11, "gout_peric1_top0_ipclk_11", + "dout_peric1_usi_i2c", + CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP0_IPCLKPORT_IPCLK_11, + 21, 0, 0), + GATE(CLK_GOUT_PERIC1_TOP0_IPCLK_12, "gout_peric1_top0_ipclk_12", + "dout_peric1_usi07_usi", + CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP0_IPCLKPORT_IPCLK_12, + 21, 0, 0), + GATE(CLK_GOUT_PERIC1_TOP0_IPCLK_13, "gout_peric1_top0_ipclk_13", + "dout_peric1_usi_i2c", + CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP0_IPCLKPORT_IPCLK_13, + 21, 0, 0), + GATE(CLK_GOUT_PERIC1_TOP0_IPCLK_14, "gout_peric1_top0_ipclk_14", + "dout_peric1_usi08_usi", + CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP0_IPCLKPORT_IPCLK_14, + 21, 0, 0), + GATE(CLK_GOUT_PERIC1_TOP0_IPCLK_15, "gout_peric1_top0_ipclk_15", + "dout_peric1_usi_i2c", + CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP0_IPCLKPORT_IPCLK_15, + 21, 0, 0), + GATE(CLK_GOUT_PERIC1_TOP0_IPCLK_4, "gout_peric1_top0_ipclk_4", + "dout_peric1_uart_bt", + CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP0_IPCLKPORT_IPCLK_4, + 21, 0, 0), + GATE(CLK_GOUT_PERIC1_TOP0_PCLK_10, "gout_peric1_top0_pclk_10", + "mout_peric1_bus_user", + CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP0_IPCLKPORT_PCLK_10, + 21, 0, 0), + GATE(CLK_GOUT_PERIC1_TOP0_PCLK_11, "gout_peric1_top0_pclk_11", + "mout_peric1_bus_user", + CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP0_IPCLKPORT_PCLK_11, + 21, 0, 0), + GATE(CLK_GOUT_PERIC1_TOP0_PCLK_12, "gout_peric1_top0_pclk_12", + "mout_peric1_bus_user", + CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP0_IPCLKPORT_PCLK_12, + 21, 0, 0), + GATE(CLK_GOUT_PERIC1_TOP0_PCLK_13, "gout_peric1_top0_pclk_13", + "mout_peric1_bus_user", + CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP0_IPCLKPORT_PCLK_13, + 21, 0, 0), + GATE(CLK_GOUT_PERIC1_TOP0_PCLK_14, "gout_peric1_top0_pclk_14", + "mout_peric1_bus_user", + CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP0_IPCLKPORT_PCLK_14, + 21, 0, 0), + GATE(CLK_GOUT_PERIC1_TOP0_PCLK_15, "gout_peric1_top0_pclk_15", + "mout_peric1_bus_user", + CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP0_IPCLKPORT_PCLK_15, + 21, 0, 0), + GATE(CLK_GOUT_PERIC1_TOP0_PCLK_4, "gout_peric1_top0_pclk_4", + "mout_peric1_bus_user", + CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP0_IPCLKPORT_PCLK_4, + 21, 0, 0), + GATE(CLK_GOUT_PERIC1_TOP1_IPCLK_0, "gout_peric1_top1_ipclk_0", + "dout_peric1_usi09_usi", + CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP1_IPCLKPORT_IPCLK_0, + 21, 0, 0), + GATE(CLK_GOUT_PERIC1_TOP1_IPCLK_1, "gout_peric1_top1_ipclk_1", + "dout_peric1_usi_i2c", + CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP1_IPCLKPORT_IPCLK_1, + 21, 0, 0), + GATE(CLK_GOUT_PERIC1_TOP1_IPCLK_10, "gout_peric1_top1_ipclk_10", + "dout_peric1_usi_i2c", + CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP1_IPCLKPORT_IPCLK_10, + 21, 0, 0), + GATE(CLK_GOUT_PERIC1_TOP1_IPCLK_12, "gout_peric1_top1_ipclk_12", + "dout_peric1_usi12_usi", + CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP1_IPCLKPORT_IPCLK_12, + 21, 0, 0), + GATE(CLK_GOUT_PERIC1_TOP1_IPCLK_13, "gout_peric1_top1_ipclk_13", + "dout_peric1_usi_i2c", + CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP1_IPCLKPORT_IPCLK_13, + 21, 0, 0), + GATE(CLK_GOUT_PERIC1_TOP1_IPCLK_14, "gout_peric1_top1_ipclk_14", + "dout_peric1_usi18_usi", + CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP1_IPCLKPORT_IPCLK_14, + 21, 0, 0), + GATE(CLK_GOUT_PERIC1_TOP1_IPCLK_15, "gout_peric1_top1_ipclk_15", + "dout_peric1_usi_i2c", + CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP1_IPCLKPORT_IPCLK_15, + 21, 0, 0), + GATE(CLK_GOUT_PERIC1_TOP1_IPCLK_2, "gout_peric1_top1_ipclk_2", + "dout_peric1_usi10_usi", + CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP1_IPCLKPORT_IPCLK_2, + 21, 0, 0), + GATE(CLK_GOUT_PERIC1_TOP1_IPCLK_3, "gout_peric1_top1_ipclk_3", + "dout_peric1_usi_i2c", + CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP1_IPCLKPORT_IPCLK_3, + 21, 0, 0), + GATE(CLK_GOUT_PERIC1_TOP1_IPCLK_4, "gout_peric1_top1_ipclk_4", + "dout_peric1_usi11_usi", + CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP1_IPCLKPORT_IPCLK_4, + 21, 0, 0), + GATE(CLK_GOUT_PERIC1_TOP1_IPCLK_5, "gout_peric1_top1_ipclk_5", + "dout_peric1_usi_i2c", + CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP1_IPCLKPORT_IPCLK_5, + 21, 0, 0), + GATE(CLK_GOUT_PERIC1_TOP1_IPCLK_6, "gout_peric1_top1_ipclk_6", + "dout_peric1_usi16_usi", + CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP1_IPCLKPORT_IPCLK_6, + 21, 0, 0), + GATE(CLK_GOUT_PERIC1_TOP1_IPCLK_7, "gout_peric1_top1_ipclk_7", + "dout_peric1_usi_i2c", + CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP1_IPCLKPORT_IPCLK_7, + 21, 0, 0), + GATE(CLK_GOUT_PERIC1_TOP1_IPCLK_9, "gout_peric1_top1_ipclk_9", + "dout_peric1_usi17_usi", + CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP1_IPCLKPORT_IPCLK_9, + 21, 0, 0), + GATE(CLK_GOUT_PERIC1_TOP1_PCLK_0, "gout_peric1_top1_pclk_0", + "mout_peric1_bus_user", + CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP1_IPCLKPORT_PCLK_0, + 21, 0, 0), + GATE(CLK_GOUT_PERIC1_TOP1_PCLK_1, "gout_peric1_top1_pclk_1", + "mout_peric1_bus_user", + CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP1_IPCLKPORT_PCLK_1, + 21, 0, 0), + GATE(CLK_GOUT_PERIC1_TOP1_PCLK_10, "gout_peric1_top1_pclk_10", + "dout_peric1_bus_user", + CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP1_IPCLKPORT_PCLK_10, + 21, 0, 0), + GATE(CLK_GOUT_PERIC1_TOP1_PCLK_12, "gout_peric1_top1_pclk_12", + "dout_peric1_bus_user", + CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP1_IPCLKPORT_PCLK_12, + 21, 0, 0), + GATE(CLK_GOUT_PERIC1_TOP1_PCLK_13, "gout_peric1_top1_pclk_13", + "mout_peric1_bus_user", + CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP1_IPCLKPORT_PCLK_13, + 21, 0, 0), + GATE(CLK_GOUT_PERIC1_TOP1_PCLK_14, "gout_peric1_top1_pclk_14", + "mout_peric1_bus_user", + CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP1_IPCLKPORT_PCLK_14, + 21, 0, 0), + GATE(CLK_GOUT_PERIC1_TOP1_PCLK_15, "gout_peric1_top1_pclk_15", + "mout_peric1_bus_user", + CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP1_IPCLKPORT_PCLK_15, + 21, 0, 0), + GATE(CLK_GOUT_PERIC1_TOP1_PCLK_2, "gout_peric1_top1_pclk_2", + "mout_peric1_bus_user", + CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP1_IPCLKPORT_PCLK_2, + 21, 0, 0), + GATE(CLK_GOUT_PERIC1_TOP1_PCLK_3, "gout_peric1_top1_pclk_3", + "mout_peric1_bus_user", + CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP1_IPCLKPORT_PCLK_3, + 21, 0, 0), + GATE(CLK_GOUT_PERIC1_TOP1_PCLK_4, "gout_peric1_top1_pclk_4", + "mout_peric1_bus_user", + CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP1_IPCLKPORT_PCLK_4, + 21, 0, 0), + GATE(CLK_GOUT_PERIC1_TOP1_PCLK_5, "gout_peric1_top1_pclk_5", + "mout_peric1_bus_user", + CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP1_IPCLKPORT_PCLK_5, + 21, 0, 0), + GATE(CLK_GOUT_PERIC1_TOP1_PCLK_6, "gout_peric1_top1_pclk_6", + "mout_peric1_bus_user", + CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP1_IPCLKPORT_PCLK_6, + 21, 0, 0), + GATE(CLK_GOUT_PERIC1_TOP1_PCLK_7, "gout_peric1_top1_pclk_7", + "mout_peric1_bus_user", + CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP1_IPCLKPORT_PCLK_7, + 21, 0, 0), + GATE(CLK_GOUT_PERIC1_TOP1_PCLK_9, "gout_peric1_top1_pclk_9", + "dout_peric1_bus_user", + CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP1_IPCLKPORT_PCLK_9, + 21, 0, 0), + GATE(CLK_GOUT_PERIC1_BUSP_CLK, "gout_peric1_busp_clk", + "mout_peric1_bus_user", + CLK_CON_GAT_GOUT_BLK_PERIC1_UID_RSTNSYNC_CLK_PERIC1_BUSP_IPCLKPORT_CLK, + 21, 0, 0), + GATE(CLK_GOUT_PERIC1_OSCCLK_CLK, "gout_peric1_oscclk_clk", + "oscclk", + CLK_CON_GAT_GOUT_BLK_PERIC1_UID_RSTNSYNC_CLK_PERIC1_OSCCLK_IPCLKPORT_CLK, + 21, 0, 0), + GATE(CLK_GOUT_PERIC1_USI06_USI_CLK, "gout_peric1_usi06_usi_clk", + "dout_peric1_usi06_usi", + CLK_CON_GAT_GOUT_BLK_PERIC1_UID_RSTNSYNC_CLK_PERIC1_USI06_USI_IPCLKPORT_CLK, + 21, 0, 0), + GATE(CLK_GOUT_PERIC1_USI07_USI_CLK, "gout_peric1_usi07_usi_clk", + "dout_peric1_usi07_usi", + CLK_CON_GAT_GOUT_BLK_PERIC1_UID_RSTNSYNC_CLK_PERIC1_USI07_USI_IPCLKPORT_CLK, + 21, 0, 0), + GATE(CLK_GOUT_PERIC1_USI08_USI_CLK, "gout_peric1_usi08_usi_clk", + "dout_peric1_usi08_usi", + CLK_CON_GAT_GOUT_BLK_PERIC1_UID_RSTNSYNC_CLK_PERIC1_USI08_USI_IPCLKPORT_CLK, + 21, 0, 0), + GATE(CLK_GOUT_PERIC1_USI09_USI_CLK, "gout_peric1_usi09_usi_clk", + "dout_peric1_usi09_usi", + CLK_CON_GAT_GOUT_BLK_PERIC1_UID_RSTNSYNC_CLK_PERIC1_USI09_USI_IPCLKPORT_CLK, + 21, 0, 0), + GATE(CLK_GOUT_PERIC1_USI10_USI_CLK, "gout_peric1_usi10_usi_clk", + "dout_peric1_usi10_usi", + CLK_CON_GAT_GOUT_BLK_PERIC1_UID_RSTNSYNC_CLK_PERIC1_USI10_USI_IPCLKPORT_CLK, + 21, 0, 0), + GATE(CLK_GOUT_PERIC1_USI11_USI_CLK, "gout_peric1_usi11_usi_clk", + "dout_peric1_usi11_usi", + CLK_CON_GAT_GOUT_BLK_PERIC1_UID_RSTNSYNC_CLK_PERIC1_USI11_USI_IPCLKPORT_CLK, + 21, 0, 0), + GATE(CLK_GOUT_PERIC1_USI16_USI_CLK, "gout_peric1_usi16_usi_clk", + "dout_peric1_usi16_usi", + CLK_CON_GAT_GOUT_BLK_PERIC1_UID_RSTNSYNC_CLK_PERIC1_USI16_USI_IPCLKPORT_CLK, + 21, 0, 0), + GATE(CLK_GOUT_PERIC1_USI17_USI_CLK, "gout_peric1_usi17_usi_clk", + "dout_peric1_usi17_usi", + CLK_CON_GAT_GOUT_BLK_PERIC1_UID_RSTNSYNC_CLK_PERIC1_USI17_USI_IPCLKPORT_CLK, + 21, 0, 0), + GATE(CLK_GOUT_PERIC1_USI_I2C_CLK, "gout_peric1_usi_i2c_clk", + "dout_peric1_usi_i2c", + CLK_CON_GAT_GOUT_BLK_PERIC1_UID_RSTNSYNC_CLK_PERIC1_USI_I2C_IPCLKPORT_CLK, + 21, 0, 0), + GATE(CLK_GOUT_PERIC1_SYSREG_PCLK, "gout_peric1_sysreg_pclk", + "mout_peric1_bus_user", + CLK_CON_GAT_GOUT_BLK_PERIC1_UID_SYSREG_PERIC1_IPCLKPORT_PCLK, + 21, 0, 0), + GATE(CLK_GOUT_PERIC1_USI16_I3C_PCLK, "gout_peric1_usi16_i3c_pclk", + "mout_peric1_bus_user", + CLK_CON_GAT_GOUT_BLK_PERIC1_UID_USI16_I3C_IPCLKPORT_I_PCLK, + 21, 0, 0), + GATE(CLK_GOUT_PERIC1_USI16_I3C_SCLK, "gout_peric1_usi16_i3c_sclk", + "dout_peric1_usi_i2c", + CLK_CON_GAT_GOUT_BLK_PERIC1_UID_USI16_I3C_IPCLKPORT_I_SCLK, + 21, 0, 0), + GATE(CLK_GOUT_PERIC1_USI17_I3C_PCLK, "gout_peric1_usi17_i3c_pclk", + "dout_peric1_bus_user", + CLK_CON_GAT_GOUT_BLK_PERIC1_UID_USI17_I3C_IPCLKPORT_I_PCLK, + 21, 0, 0), + GATE(CLK_GOUT_PERIC1_USI17_I3C_SCLK, "gout_peric1_usi17_i3c_sclk", + "dout_peric1_usi_i2c", + CLK_CON_GAT_GOUT_BLK_PERIC1_UID_USI17_I3C_IPCLKPORT_I_SCLK, + 21, 0, 0), + GATE(CLK_GOUT_PERIC1_XIU_P_ACLK, "gout_peric1_xiu_p_aclk", + "mout_peric1_bus_user", + CLK_CON_GAT_GOUT_BLK_PERIC1_UID_XIU_P_PERIC1_IPCLKPORT_ACLK, + 21, CLK_IGNORE_UNUSED, 0), +}; + +static const struct samsung_cmu_info peric1_cmu_info __initconst = { + .mux_clks = peric1_mux_clks, + .nr_mux_clks = ARRAY_SIZE(peric1_mux_clks), + .div_clks = peric1_div_clks, + .nr_div_clks = ARRAY_SIZE(peric1_div_clks), + .gate_clks = peric1_gate_clks, + .nr_gate_clks = ARRAY_SIZE(peric1_gate_clks), + .nr_clk_ids = CLKS_NR_PERIC1, + .clk_regs = peric1_clk_regs, + .nr_clk_regs = ARRAY_SIZE(peric1_clk_regs), + .clk_name = "bus", +}; + /* ---- CMU_PERIS ----------------------------------------------------------- */ /* Register Offset definitions for CMU_PERIS (0x10020000) */ @@ -1500,6 +2690,12 @@ static const struct of_device_id exynos990_cmu_of_match[] = { { .compatible = "samsung,exynos990-cmu-hsi0", .data = &hsi0_cmu_info, + }, { + .compatible = "samsung,exynos990-cmu-peric0", + .data = &peric0_cmu_info, + }, { + .compatible = "samsung,exynos990-cmu-peric1", + .data = &peric1_cmu_info, }, { }, }; diff --git a/drivers/clk/samsung/clk-fsd.c b/drivers/clk/samsung/clk-fsd.c index 594931334574..4124d65e3d18 100644 --- a/drivers/clk/samsung/clk-fsd.c +++ b/drivers/clk/samsung/clk-fsd.c @@ -89,7 +89,7 @@ #define CLKS_NR_FSYS1 (PCIE_LINK1_IPCLKPORT_SLV_ACLK + 1) #define CLKS_NR_IMEM (IMEM_TMU_GT_IPCLKPORT_I_CLK_TS + 1) #define CLKS_NR_MFC (MFC_MFC_IPCLKPORT_ACLK + 1) -#define CLKS_NR_CAM_CSI (CAM_CSI2_3_IPCLKPORT_I_ACLK + 1) +#define CLKS_NR_CAM_CSI (CAM_CSI2_3_IPCLKPORT_I_PCLK + 1) static const unsigned long cmu_clk_regs[] __initconst = { PLL_LOCKTIME_PLL_SHARED0, @@ -1646,7 +1646,7 @@ static const struct samsung_pll_rate_table pll_cam_csi_rate_table[] __initconst }; static const struct samsung_pll_clock cam_csi_pll_clks[] __initconst = { - PLL(pll_142xx, 0, "fout_pll_cam_csi", "fin_pll", + PLL(pll_142xx, CAM_CSI_PLL, "fout_pll_cam_csi", "fin_pll", PLL_LOCKTIME_PLL_CAM_CSI, PLL_CON0_PLL_CAM_CSI, pll_cam_csi_rate_table), }; @@ -1682,51 +1682,51 @@ static const struct samsung_gate_clock cam_csi_gate_clks[] __initconst = { GAT_CAM_CSI_BUS_D_CAM_CSI_IPCLKPORT_CLK__SYSTEM__NOC, 21, CLK_IGNORE_UNUSED, 0), GATE(CAM_CSI0_0_IPCLKPORT_I_ACLK, "cam_csi0_0_ipclkport_i_aclk", "dout_cam_csi0_aclk", GAT_CAM_CSI0_0_IPCLKPORT_I_ACLK, 21, CLK_IGNORE_UNUSED, 0), - GATE(0, "cam_csi0_0_ipclkport_i_pclk", "dout_cam_csi_busp", + GATE(CAM_CSI0_0_IPCLKPORT_I_PCLK, "cam_csi0_0_ipclkport_i_pclk", "dout_cam_csi_busp", GAT_CAM_CSI0_0_IPCLKPORT_I_PCLK, 21, CLK_IGNORE_UNUSED, 0), GATE(CAM_CSI0_1_IPCLKPORT_I_ACLK, "cam_csi0_1_ipclkport_i_aclk", "dout_cam_csi0_aclk", GAT_CAM_CSI0_1_IPCLKPORT_I_ACLK, 21, CLK_IGNORE_UNUSED, 0), - GATE(0, "cam_csi0_1_ipclkport_i_pclk", "dout_cam_csi_busp", + GATE(CAM_CSI0_1_IPCLKPORT_I_PCLK, "cam_csi0_1_ipclkport_i_pclk", "dout_cam_csi_busp", GAT_CAM_CSI0_1_IPCLKPORT_I_PCLK, 21, CLK_IGNORE_UNUSED, 0), GATE(CAM_CSI0_2_IPCLKPORT_I_ACLK, "cam_csi0_2_ipclkport_i_aclk", "dout_cam_csi0_aclk", GAT_CAM_CSI0_2_IPCLKPORT_I_ACLK, 21, CLK_IGNORE_UNUSED, 0), - GATE(0, "cam_csi0_2_ipclkport_i_pclk", "dout_cam_csi_busp", + GATE(CAM_CSI0_2_IPCLKPORT_I_PCLK, "cam_csi0_2_ipclkport_i_pclk", "dout_cam_csi_busp", GAT_CAM_CSI0_2_IPCLKPORT_I_PCLK, 21, CLK_IGNORE_UNUSED, 0), GATE(CAM_CSI0_3_IPCLKPORT_I_ACLK, "cam_csi0_3_ipclkport_i_aclk", "dout_cam_csi0_aclk", GAT_CAM_CSI0_3_IPCLKPORT_I_ACLK, 21, CLK_IGNORE_UNUSED, 0), - GATE(0, "cam_csi0_3_ipclkport_i_pclk", "dout_cam_csi_busp", + GATE(CAM_CSI0_3_IPCLKPORT_I_PCLK, "cam_csi0_3_ipclkport_i_pclk", "dout_cam_csi_busp", GAT_CAM_CSI0_3_IPCLKPORT_I_PCLK, 21, CLK_IGNORE_UNUSED, 0), GATE(CAM_CSI1_0_IPCLKPORT_I_ACLK, "cam_csi1_0_ipclkport_i_aclk", "dout_cam_csi1_aclk", GAT_CAM_CSI1_0_IPCLKPORT_I_ACLK, 21, CLK_IGNORE_UNUSED, 0), - GATE(0, "cam_csi1_0_ipclkport_i_pclk", "dout_cam_csi_busp", + GATE(CAM_CSI1_0_IPCLKPORT_I_PCLK, "cam_csi1_0_ipclkport_i_pclk", "dout_cam_csi_busp", GAT_CAM_CSI1_0_IPCLKPORT_I_PCLK, 21, CLK_IGNORE_UNUSED, 0), GATE(CAM_CSI1_1_IPCLKPORT_I_ACLK, "cam_csi1_1_ipclkport_i_aclk", "dout_cam_csi1_aclk", GAT_CAM_CSI1_1_IPCLKPORT_I_ACLK, 21, CLK_IGNORE_UNUSED, 0), - GATE(0, "cam_csi1_1_ipclkport_i_pclk", "dout_cam_csi_busp", + GATE(CAM_CSI1_1_IPCLKPORT_I_PCLK, "cam_csi1_1_ipclkport_i_pclk", "dout_cam_csi_busp", GAT_CAM_CSI1_1_IPCLKPORT_I_PCLK, 21, CLK_IGNORE_UNUSED, 0), GATE(CAM_CSI1_2_IPCLKPORT_I_ACLK, "cam_csi1_2_ipclkport_i_aclk", "dout_cam_csi1_aclk", GAT_CAM_CSI1_2_IPCLKPORT_I_ACLK, 21, CLK_IGNORE_UNUSED, 0), - GATE(0, "cam_csi1_2_ipclkport_i_pclk", "dout_cam_csi_busp", + GATE(CAM_CSI1_2_IPCLKPORT_I_PCLK, "cam_csi1_2_ipclkport_i_pclk", "dout_cam_csi_busp", GAT_CAM_CSI1_2_IPCLKPORT_I_PCLK, 21, CLK_IGNORE_UNUSED, 0), GATE(CAM_CSI1_3_IPCLKPORT_I_ACLK, "cam_csi1_3_ipclkport_i_aclk", "dout_cam_csi1_aclk", GAT_CAM_CSI1_3_IPCLKPORT_I_ACLK, 21, CLK_IGNORE_UNUSED, 0), - GATE(0, "cam_csi1_3_ipclkport_i_pclk", "dout_cam_csi_busp", + GATE(CAM_CSI1_3_IPCLKPORT_I_PCLK, "cam_csi1_3_ipclkport_i_pclk", "dout_cam_csi_busp", GAT_CAM_CSI1_3_IPCLKPORT_I_PCLK, 21, CLK_IGNORE_UNUSED, 0), GATE(CAM_CSI2_0_IPCLKPORT_I_ACLK, "cam_csi2_0_ipclkport_i_aclk", "dout_cam_csi2_aclk", GAT_CAM_CSI2_0_IPCLKPORT_I_ACLK, 21, CLK_IGNORE_UNUSED, 0), - GATE(0, "cam_csi2_0_ipclkport_i_pclk", "dout_cam_csi_busp", + GATE(CAM_CSI2_0_IPCLKPORT_I_PCLK, "cam_csi2_0_ipclkport_i_pclk", "dout_cam_csi_busp", GAT_CAM_CSI2_0_IPCLKPORT_I_PCLK, 21, CLK_IGNORE_UNUSED, 0), GATE(CAM_CSI2_1_IPCLKPORT_I_ACLK, "cam_csi2_1_ipclkport_i_aclk", "dout_cam_csi2_aclk", GAT_CAM_CSI2_1_IPCLKPORT_I_ACLK, 21, CLK_IGNORE_UNUSED, 0), - GATE(0, "cam_csi2_1_ipclkport_i_pclk", "dout_cam_csi_busp", + GATE(CAM_CSI2_1_IPCLKPORT_I_PCLK, "cam_csi2_1_ipclkport_i_pclk", "dout_cam_csi_busp", GAT_CAM_CSI2_1_IPCLKPORT_I_PCLK, 21, CLK_IGNORE_UNUSED, 0), GATE(CAM_CSI2_2_IPCLKPORT_I_ACLK, "cam_csi2_2_ipclkport_i_aclk", "dout_cam_csi2_aclk", GAT_CAM_CSI2_2_IPCLKPORT_I_ACLK, 21, CLK_IGNORE_UNUSED, 0), - GATE(0, "cam_csi2_2_ipclkport_i_pclk", "dout_cam_csi_busp", + GATE(CAM_CSI2_2_IPCLKPORT_I_PCLK, "cam_csi2_2_ipclkport_i_pclk", "dout_cam_csi_busp", GAT_CAM_CSI2_2_IPCLKPORT_I_PCLK, 21, CLK_IGNORE_UNUSED, 0), GATE(CAM_CSI2_3_IPCLKPORT_I_ACLK, "cam_csi2_3_ipclkport_i_aclk", "dout_cam_csi2_aclk", GAT_CAM_CSI2_3_IPCLKPORT_I_ACLK, 21, CLK_IGNORE_UNUSED, 0), - GATE(0, "cam_csi2_3_ipclkport_i_pclk", "dout_cam_csi_busp", + GATE(CAM_CSI2_3_IPCLKPORT_I_PCLK, "cam_csi2_3_ipclkport_i_pclk", "dout_cam_csi_busp", GAT_CAM_CSI2_3_IPCLKPORT_I_PCLK, 21, CLK_IGNORE_UNUSED, 0), GATE(0, "cam_ns_brdg_cam_csi_ipclkport_clk__psoc_cam_csi__clk_cam_csi_d", "dout_cam_csi_busd", diff --git a/drivers/clk/samsung/clk-pll.c b/drivers/clk/samsung/clk-pll.c index e4faf02b631e..7bea7be1d7e4 100644 --- a/drivers/clk/samsung/clk-pll.c +++ b/drivers/clk/samsung/clk-pll.c @@ -49,8 +49,8 @@ static const struct samsung_pll_rate_table *samsung_get_pll_settings( return NULL; } -static long samsung_pll_round_rate(struct clk_hw *hw, - unsigned long drate, unsigned long *prate) +static int samsung_pll_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { struct samsung_clk_pll *pll = to_clk_pll(hw); const struct samsung_pll_rate_table *rate_table = pll->rate_table; @@ -58,12 +58,17 @@ static long samsung_pll_round_rate(struct clk_hw *hw, /* Assuming rate_table is in descending order */ for (i = 0; i < pll->rate_count; i++) { - if (drate >= rate_table[i].rate) - return rate_table[i].rate; + if (req->rate >= rate_table[i].rate) { + req->rate = rate_table[i].rate; + + return 0; + } } /* return minimum supported value */ - return rate_table[i - 1].rate; + req->rate = rate_table[i - 1].rate; + + return 0; } static bool pll_early_timeout = true; @@ -273,7 +278,7 @@ static int samsung_pll35xx_set_rate(struct clk_hw *hw, unsigned long drate, } /* Set PLL lock time. */ - if (pll->type == pll_142xx) + if (pll->type == pll_142xx || pll->type == pll_1017x) writel_relaxed(rate->pdiv * PLL142XX_LOCK_FACTOR, pll->lock_reg); else @@ -298,7 +303,7 @@ static int samsung_pll35xx_set_rate(struct clk_hw *hw, unsigned long drate, static const struct clk_ops samsung_pll35xx_clk_ops = { .recalc_rate = samsung_pll35xx_recalc_rate, - .round_rate = samsung_pll_round_rate, + .determine_rate = samsung_pll_determine_rate, .set_rate = samsung_pll35xx_set_rate, .enable = samsung_pll3xxx_enable, .disable = samsung_pll3xxx_disable, @@ -411,7 +416,7 @@ static int samsung_pll36xx_set_rate(struct clk_hw *hw, unsigned long drate, static const struct clk_ops samsung_pll36xx_clk_ops = { .recalc_rate = samsung_pll36xx_recalc_rate, .set_rate = samsung_pll36xx_set_rate, - .round_rate = samsung_pll_round_rate, + .determine_rate = samsung_pll_determine_rate, .enable = samsung_pll3xxx_enable, .disable = samsung_pll3xxx_disable, }; @@ -514,7 +519,7 @@ static int samsung_pll0822x_set_rate(struct clk_hw *hw, unsigned long drate, static const struct clk_ops samsung_pll0822x_clk_ops = { .recalc_rate = samsung_pll0822x_recalc_rate, - .round_rate = samsung_pll_round_rate, + .determine_rate = samsung_pll_determine_rate, .set_rate = samsung_pll0822x_set_rate, .enable = samsung_pll3xxx_enable, .disable = samsung_pll3xxx_disable, @@ -612,7 +617,7 @@ static int samsung_pll0831x_set_rate(struct clk_hw *hw, unsigned long drate, static const struct clk_ops samsung_pll0831x_clk_ops = { .recalc_rate = samsung_pll0831x_recalc_rate, .set_rate = samsung_pll0831x_set_rate, - .round_rate = samsung_pll_round_rate, + .determine_rate = samsung_pll_determine_rate, .enable = samsung_pll3xxx_enable, .disable = samsung_pll3xxx_disable, }; @@ -735,7 +740,7 @@ static int samsung_pll45xx_set_rate(struct clk_hw *hw, unsigned long drate, static const struct clk_ops samsung_pll45xx_clk_ops = { .recalc_rate = samsung_pll45xx_recalc_rate, - .round_rate = samsung_pll_round_rate, + .determine_rate = samsung_pll_determine_rate, .set_rate = samsung_pll45xx_set_rate, }; @@ -880,7 +885,7 @@ static int samsung_pll46xx_set_rate(struct clk_hw *hw, unsigned long drate, static const struct clk_ops samsung_pll46xx_clk_ops = { .recalc_rate = samsung_pll46xx_recalc_rate, - .round_rate = samsung_pll_round_rate, + .determine_rate = samsung_pll_determine_rate, .set_rate = samsung_pll46xx_set_rate, }; @@ -1093,7 +1098,7 @@ static int samsung_pll2550xx_set_rate(struct clk_hw *hw, unsigned long drate, static const struct clk_ops samsung_pll2550xx_clk_ops = { .recalc_rate = samsung_pll2550xx_recalc_rate, - .round_rate = samsung_pll_round_rate, + .determine_rate = samsung_pll_determine_rate, .set_rate = samsung_pll2550xx_set_rate, }; @@ -1185,7 +1190,7 @@ static int samsung_pll2650x_set_rate(struct clk_hw *hw, unsigned long drate, static const struct clk_ops samsung_pll2650x_clk_ops = { .recalc_rate = samsung_pll2650x_recalc_rate, - .round_rate = samsung_pll_round_rate, + .determine_rate = samsung_pll_determine_rate, .set_rate = samsung_pll2650x_set_rate, }; @@ -1277,7 +1282,7 @@ static int samsung_pll2650xx_set_rate(struct clk_hw *hw, unsigned long drate, static const struct clk_ops samsung_pll2650xx_clk_ops = { .recalc_rate = samsung_pll2650xx_recalc_rate, .set_rate = samsung_pll2650xx_set_rate, - .round_rate = samsung_pll_round_rate, + .determine_rate = samsung_pll_determine_rate, }; static const struct clk_ops samsung_pll2650xx_clk_min_ops = { @@ -1325,6 +1330,125 @@ static const struct clk_ops samsung_pll531x_clk_ops = { .recalc_rate = samsung_pll531x_recalc_rate, }; +/* + * PLL1031x Clock Type + */ +#define PLL1031X_LOCK_FACTOR (500) + +#define PLL1031X_MDIV_MASK (0x3ff) +#define PLL1031X_PDIV_MASK (0x3f) +#define PLL1031X_SDIV_MASK (0x7) +#define PLL1031X_MDIV_SHIFT (16) +#define PLL1031X_PDIV_SHIFT (8) +#define PLL1031X_SDIV_SHIFT (0) + +#define PLL1031X_KDIV_MASK (0xffff) +#define PLL1031X_KDIV_SHIFT (0) +#define PLL1031X_MFR_MASK (0x3f) +#define PLL1031X_MRR_MASK (0x1f) +#define PLL1031X_MFR_SHIFT (16) +#define PLL1031X_MRR_SHIFT (24) + +static unsigned long samsung_pll1031x_recalc_rate(struct clk_hw *hw, + unsigned long parent_rate) +{ + struct samsung_clk_pll *pll = to_clk_pll(hw); + u32 mdiv, pdiv, sdiv, kdiv, pll_con0, pll_con3; + u64 fvco = parent_rate; + + pll_con0 = readl_relaxed(pll->con_reg); + pll_con3 = readl_relaxed(pll->con_reg + 0xc); + mdiv = (pll_con0 >> PLL1031X_MDIV_SHIFT) & PLL1031X_MDIV_MASK; + pdiv = (pll_con0 >> PLL1031X_PDIV_SHIFT) & PLL1031X_PDIV_MASK; + sdiv = (pll_con0 >> PLL1031X_SDIV_SHIFT) & PLL1031X_SDIV_MASK; + kdiv = (pll_con3 & PLL1031X_KDIV_MASK); + + fvco *= (mdiv << PLL1031X_MDIV_SHIFT) + kdiv; + do_div(fvco, (pdiv << sdiv)); + fvco >>= PLL1031X_MDIV_SHIFT; + + return (unsigned long)fvco; +} + +static bool samsung_pll1031x_mpk_change(u32 pll_con0, u32 pll_con3, + const struct samsung_pll_rate_table *rate) +{ + u32 old_mdiv, old_pdiv, old_kdiv; + + old_mdiv = (pll_con0 >> PLL1031X_MDIV_SHIFT) & PLL1031X_MDIV_MASK; + old_pdiv = (pll_con0 >> PLL1031X_PDIV_SHIFT) & PLL1031X_PDIV_MASK; + old_kdiv = (pll_con3 >> PLL1031X_KDIV_SHIFT) & PLL1031X_KDIV_MASK; + + return (old_mdiv != rate->mdiv || old_pdiv != rate->pdiv || + old_kdiv != rate->kdiv); +} + +static int samsung_pll1031x_set_rate(struct clk_hw *hw, unsigned long drate, + unsigned long prate) +{ + struct samsung_clk_pll *pll = to_clk_pll(hw); + const struct samsung_pll_rate_table *rate; + u32 con0, con3; + + /* Get required rate settings from table */ + rate = samsung_get_pll_settings(pll, drate); + if (!rate) { + pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__, + drate, clk_hw_get_name(hw)); + return -EINVAL; + } + + con0 = readl_relaxed(pll->con_reg); + con3 = readl_relaxed(pll->con_reg + 0xc); + + if (!(samsung_pll1031x_mpk_change(con0, con3, rate))) { + /* If only s change, change just s value only */ + con0 &= ~(PLL1031X_SDIV_MASK << PLL1031X_SDIV_SHIFT); + con0 |= rate->sdiv << PLL1031X_SDIV_SHIFT; + writel_relaxed(con0, pll->con_reg); + + return 0; + } + + /* Set PLL lock time. */ + writel_relaxed(rate->pdiv * PLL1031X_LOCK_FACTOR, pll->lock_reg); + + /* Set PLL M, P, and S values. */ + con0 &= ~((PLL1031X_MDIV_MASK << PLL1031X_MDIV_SHIFT) | + (PLL1031X_PDIV_MASK << PLL1031X_PDIV_SHIFT) | + (PLL1031X_SDIV_MASK << PLL1031X_SDIV_SHIFT)); + + con0 |= (rate->mdiv << PLL1031X_MDIV_SHIFT) | + (rate->pdiv << PLL1031X_PDIV_SHIFT) | + (rate->sdiv << PLL1031X_SDIV_SHIFT); + + /* Set PLL K, MFR and MRR values. */ + con3 = readl_relaxed(pll->con_reg + 0xc); + con3 &= ~((PLL1031X_KDIV_MASK << PLL1031X_KDIV_SHIFT) | + (PLL1031X_MFR_MASK << PLL1031X_MFR_SHIFT) | + (PLL1031X_MRR_MASK << PLL1031X_MRR_SHIFT)); + con3 |= (rate->kdiv << PLL1031X_KDIV_SHIFT) | + (rate->mfr << PLL1031X_MFR_SHIFT) | + (rate->mrr << PLL1031X_MRR_SHIFT); + + /* Write configuration to PLL */ + writel_relaxed(con0, pll->con_reg); + writel_relaxed(con3, pll->con_reg + 0xc); + + /* Wait for PLL lock if the PLL is enabled */ + return samsung_pll_lock_wait(pll, BIT(pll->lock_offs)); +} + +static const struct clk_ops samsung_pll1031x_clk_ops = { + .recalc_rate = samsung_pll1031x_recalc_rate, + .determine_rate = samsung_pll_determine_rate, + .set_rate = samsung_pll1031x_set_rate, +}; + +static const struct clk_ops samsung_pll1031x_clk_min_ops = { + .recalc_rate = samsung_pll1031x_recalc_rate, +}; + static void __init _samsung_clk_register_pll(struct samsung_clk_provider *ctx, const struct samsung_pll_clock *pll_clk) { @@ -1373,6 +1497,7 @@ static void __init _samsung_clk_register_pll(struct samsung_clk_provider *ctx, case pll_1451x: case pll_1452x: case pll_142xx: + case pll_1017x: pll->enable_offs = PLL35XX_ENABLE_SHIFT; pll->lock_offs = PLL35XX_LOCK_STAT_SHIFT; if (!pll->rate_table) @@ -1468,6 +1593,12 @@ static void __init _samsung_clk_register_pll(struct samsung_clk_provider *ctx, case pll_4311: init.ops = &samsung_pll531x_clk_ops; break; + case pll_1031x: + if (!pll->rate_table) + init.ops = &samsung_pll1031x_clk_min_ops; + else + init.ops = &samsung_pll1031x_clk_ops; + break; default: pr_warn("%s: Unknown pll type for pll clk %s\n", __func__, pll_clk->name); diff --git a/drivers/clk/samsung/clk-pll.h b/drivers/clk/samsung/clk-pll.h index e9a5f8e0e0a3..6c8bb7f26da5 100644 --- a/drivers/clk/samsung/clk-pll.h +++ b/drivers/clk/samsung/clk-pll.h @@ -49,6 +49,8 @@ enum samsung_pll_type { pll_0718x, pll_0732x, pll_4311, + pll_1017x, + pll_1031x, }; #define PLL_RATE(_fin, _m, _p, _s, _k, _ks) \ diff --git a/drivers/clk/sifive/fu540-prci.h b/drivers/clk/sifive/fu540-prci.h index e0173324f3c5..d45193c210b4 100644 --- a/drivers/clk/sifive/fu540-prci.h +++ b/drivers/clk/sifive/fu540-prci.h @@ -49,7 +49,7 @@ static struct __prci_wrpll_data sifive_fu540_prci_gemgxlpll_data = { static const struct clk_ops sifive_fu540_prci_wrpll_clk_ops = { .set_rate = sifive_prci_wrpll_set_rate, - .round_rate = sifive_prci_wrpll_round_rate, + .determine_rate = sifive_prci_wrpll_determine_rate, .recalc_rate = sifive_prci_wrpll_recalc_rate, .enable = sifive_prci_clock_enable, .disable = sifive_prci_clock_disable, diff --git a/drivers/clk/sifive/fu740-prci.h b/drivers/clk/sifive/fu740-prci.h index f31cd30fc395..c605a899d97d 100644 --- a/drivers/clk/sifive/fu740-prci.h +++ b/drivers/clk/sifive/fu740-prci.h @@ -55,7 +55,7 @@ static struct __prci_wrpll_data sifive_fu740_prci_cltxpll_data = { static const struct clk_ops sifive_fu740_prci_wrpll_clk_ops = { .set_rate = sifive_prci_wrpll_set_rate, - .round_rate = sifive_prci_wrpll_round_rate, + .determine_rate = sifive_prci_wrpll_determine_rate, .recalc_rate = sifive_prci_wrpll_recalc_rate, .enable = sifive_prci_clock_enable, .disable = sifive_prci_clock_disable, diff --git a/drivers/clk/sifive/sifive-prci.c b/drivers/clk/sifive/sifive-prci.c index caba0400f8a2..4d1cc7adb2b3 100644 --- a/drivers/clk/sifive/sifive-prci.c +++ b/drivers/clk/sifive/sifive-prci.c @@ -183,9 +183,8 @@ unsigned long sifive_prci_wrpll_recalc_rate(struct clk_hw *hw, return wrpll_calc_output_rate(&pwd->c, parent_rate); } -long sifive_prci_wrpll_round_rate(struct clk_hw *hw, - unsigned long rate, - unsigned long *parent_rate) +int sifive_prci_wrpll_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { struct __prci_clock *pc = clk_hw_to_prci_clock(hw); struct __prci_wrpll_data *pwd = pc->pwd; @@ -193,9 +192,11 @@ long sifive_prci_wrpll_round_rate(struct clk_hw *hw, memcpy(&c, &pwd->c, sizeof(c)); - wrpll_configure_for_rate(&c, rate, *parent_rate); + wrpll_configure_for_rate(&c, req->rate, req->best_parent_rate); - return wrpll_calc_output_rate(&c, *parent_rate); + req->rate = wrpll_calc_output_rate(&c, req->best_parent_rate); + + return 0; } int sifive_prci_wrpll_set_rate(struct clk_hw *hw, diff --git a/drivers/clk/sifive/sifive-prci.h b/drivers/clk/sifive/sifive-prci.h index 91658a88af4e..d74b2bddd08a 100644 --- a/drivers/clk/sifive/sifive-prci.h +++ b/drivers/clk/sifive/sifive-prci.h @@ -291,8 +291,8 @@ void sifive_prci_hfpclkpllsel_use_hfclk(struct __prci_data *pd); void sifive_prci_hfpclkpllsel_use_hfpclkpll(struct __prci_data *pd); /* Linux clock framework integration */ -long sifive_prci_wrpll_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *parent_rate); +int sifive_prci_wrpll_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req); int sifive_prci_wrpll_set_rate(struct clk_hw *hw, unsigned long rate, unsigned long parent_rate); int sifive_clk_is_enabled(struct clk_hw *hw); diff --git a/drivers/clk/sophgo/clk-cv18xx-ip.c b/drivers/clk/sophgo/clk-cv18xx-ip.c index b186e64d4813..c2b58faf0938 100644 --- a/drivers/clk/sophgo/clk-cv18xx-ip.c +++ b/drivers/clk/sophgo/clk-cv18xx-ip.c @@ -45,10 +45,12 @@ static unsigned long gate_recalc_rate(struct clk_hw *hw, return parent_rate; } -static long gate_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *parent_rate) +static int gate_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { - return *parent_rate; + req->rate = req->best_parent_rate; + + return 0; } static int gate_set_rate(struct clk_hw *hw, unsigned long rate, @@ -63,7 +65,7 @@ const struct clk_ops cv1800_clk_gate_ops = { .is_enabled = gate_is_enabled, .recalc_rate = gate_recalc_rate, - .round_rate = gate_round_rate, + .determine_rate = gate_determine_rate, .set_rate = gate_set_rate, }; diff --git a/drivers/clk/sophgo/clk-sg2042-clkgen.c b/drivers/clk/sophgo/clk-sg2042-clkgen.c index 9e61288d34f3..683661b71787 100644 --- a/drivers/clk/sophgo/clk-sg2042-clkgen.c +++ b/drivers/clk/sophgo/clk-sg2042-clkgen.c @@ -176,9 +176,8 @@ static unsigned long sg2042_clk_divider_recalc_rate(struct clk_hw *hw, return ret_rate; } -static long sg2042_clk_divider_round_rate(struct clk_hw *hw, - unsigned long rate, - unsigned long *prate) +static int sg2042_clk_divider_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { struct sg2042_divider_clock *divider = to_sg2042_clk_divider(hw); unsigned long ret_rate; @@ -192,15 +191,17 @@ static long sg2042_clk_divider_round_rate(struct clk_hw *hw, bestdiv = readl(divider->reg) >> divider->shift; bestdiv &= clk_div_mask(divider->width); } - ret_rate = DIV_ROUND_UP_ULL((u64)*prate, bestdiv); + ret_rate = DIV_ROUND_UP_ULL((u64)req->best_parent_rate, bestdiv); } else { - ret_rate = divider_round_rate(hw, rate, prate, NULL, + ret_rate = divider_round_rate(hw, req->rate, &req->best_parent_rate, NULL, divider->width, divider->div_flags); } pr_debug("--> %s: divider_round_rate: val = %ld\n", clk_hw_get_name(hw), ret_rate); - return ret_rate; + req->rate = ret_rate; + + return 0; } static int sg2042_clk_divider_set_rate(struct clk_hw *hw, @@ -258,13 +259,13 @@ static int sg2042_clk_divider_set_rate(struct clk_hw *hw, static const struct clk_ops sg2042_clk_divider_ops = { .recalc_rate = sg2042_clk_divider_recalc_rate, - .round_rate = sg2042_clk_divider_round_rate, + .determine_rate = sg2042_clk_divider_determine_rate, .set_rate = sg2042_clk_divider_set_rate, }; static const struct clk_ops sg2042_clk_divider_ro_ops = { .recalc_rate = sg2042_clk_divider_recalc_rate, - .round_rate = sg2042_clk_divider_round_rate, + .determine_rate = sg2042_clk_divider_determine_rate, }; /* diff --git a/drivers/clk/sophgo/clk-sg2042-pll.c b/drivers/clk/sophgo/clk-sg2042-pll.c index e5fb0bb7ac4f..110b6ee06fe4 100644 --- a/drivers/clk/sophgo/clk-sg2042-pll.c +++ b/drivers/clk/sophgo/clk-sg2042-pll.c @@ -346,37 +346,30 @@ static unsigned long sg2042_clk_pll_recalc_rate(struct clk_hw *hw, return rate; } -static long sg2042_clk_pll_round_rate(struct clk_hw *hw, - unsigned long req_rate, - unsigned long *prate) +static int sg2042_clk_pll_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { struct sg2042_pll_ctrl pctrl_table; unsigned int value; long proper_rate; int ret; - ret = sg2042_get_pll_ctl_setting(&pctrl_table, req_rate, *prate); + ret = sg2042_get_pll_ctl_setting(&pctrl_table, + min(req->rate, req->max_rate), + req->best_parent_rate); if (ret) { proper_rate = 0; goto out; } value = sg2042_pll_ctrl_encode(&pctrl_table); - proper_rate = (long)sg2042_pll_recalc_rate(value, *prate); + proper_rate = (long)sg2042_pll_recalc_rate(value, req->best_parent_rate); out: - pr_debug("--> %s: pll_round_rate: val = %ld\n", + pr_debug("--> %s: pll_determine_rate: val = %ld\n", clk_hw_get_name(hw), proper_rate); - return proper_rate; -} + req->rate = proper_rate; -static int sg2042_clk_pll_determine_rate(struct clk_hw *hw, - struct clk_rate_request *req) -{ - req->rate = sg2042_clk_pll_round_rate(hw, min(req->rate, req->max_rate), - &req->best_parent_rate); - pr_debug("--> %s: pll_determine_rate: val = %ld\n", - clk_hw_get_name(hw), req->rate); return 0; } @@ -417,14 +410,13 @@ out: static const struct clk_ops sg2042_clk_pll_ops = { .recalc_rate = sg2042_clk_pll_recalc_rate, - .round_rate = sg2042_clk_pll_round_rate, .determine_rate = sg2042_clk_pll_determine_rate, .set_rate = sg2042_clk_pll_set_rate, }; static const struct clk_ops sg2042_clk_pll_ro_ops = { .recalc_rate = sg2042_clk_pll_recalc_rate, - .round_rate = sg2042_clk_pll_round_rate, + .determine_rate = sg2042_clk_pll_determine_rate, }; /* diff --git a/drivers/clk/spacemit/ccu-k1.c b/drivers/clk/spacemit/ccu-k1.c index 65e6de030717..f5a9fe6ba185 100644 --- a/drivers/clk/spacemit/ccu-k1.c +++ b/drivers/clk/spacemit/ccu-k1.c @@ -136,13 +136,33 @@ CCU_GATE_DEFINE(pll1_d3_819p2, CCU_PARENT_HW(pll1_d3), MPMU_ACGR, BIT(14), 0); CCU_GATE_DEFINE(pll1_d2_1228p8, CCU_PARENT_HW(pll1_d2), MPMU_ACGR, BIT(16), 0); CCU_GATE_DEFINE(slow_uart, CCU_PARENT_NAME(osc), MPMU_ACGR, BIT(1), CLK_IGNORE_UNUSED); -CCU_DDN_DEFINE(slow_uart1_14p74, pll1_d16_153p6, MPMU_SUCCR, 16, 13, 0, 13, 0); -CCU_DDN_DEFINE(slow_uart2_48, pll1_d4_614p4, MPMU_SUCCR_1, 16, 13, 0, 13, 0); +CCU_DDN_DEFINE(slow_uart1_14p74, pll1_d16_153p6, MPMU_SUCCR, 16, 13, 0, 13, 2, 0); +CCU_DDN_DEFINE(slow_uart2_48, pll1_d4_614p4, MPMU_SUCCR_1, 16, 13, 0, 13, 2, 0); CCU_GATE_DEFINE(wdt_clk, CCU_PARENT_HW(pll1_d96_25p6), MPMU_WDTPCR, BIT(1), 0); -CCU_FACTOR_GATE_DEFINE(i2s_sysclk, CCU_PARENT_HW(pll1_d16_153p6), MPMU_ISCCR, BIT(31), 50, 1); -CCU_FACTOR_GATE_DEFINE(i2s_bclk, CCU_PARENT_HW(i2s_sysclk), MPMU_ISCCR, BIT(29), 1, 1); +CCU_FACTOR_DEFINE(i2s_153p6, CCU_PARENT_HW(pll1_d8_307p2), 2, 1); + +static const struct clk_parent_data i2s_153p6_base_parents[] = { + CCU_PARENT_HW(i2s_153p6), + CCU_PARENT_HW(pll1_d8_307p2), +}; +CCU_MUX_DEFINE(i2s_153p6_base, i2s_153p6_base_parents, MPMU_FCCR, 29, 1, 0); + +static const struct clk_parent_data i2s_sysclk_src_parents[] = { + CCU_PARENT_HW(pll1_d96_25p6), + CCU_PARENT_HW(i2s_153p6_base) +}; +CCU_MUX_GATE_DEFINE(i2s_sysclk_src, i2s_sysclk_src_parents, MPMU_ISCCR, 30, 1, BIT(31), 0); + +CCU_DDN_DEFINE(i2s_sysclk, i2s_sysclk_src, MPMU_ISCCR, 0, 15, 15, 12, 1, 0); + +CCU_FACTOR_DEFINE(i2s_bclk_factor, CCU_PARENT_HW(i2s_sysclk), 2, 1); +/* + * Divider of i2s_bclk always implies a 1/2 factor, which is + * described by i2s_bclk_factor. + */ +CCU_DIV_GATE_DEFINE(i2s_bclk, CCU_PARENT_HW(i2s_bclk_factor), MPMU_ISCCR, 27, 2, BIT(29), 0); static const struct clk_parent_data apb_parents[] = { CCU_PARENT_HW(pll1_d96_25p6), @@ -247,7 +267,14 @@ CCU_GATE_DEFINE(aib_clk, CCU_PARENT_NAME(vctcxo_24m), APBC_AIB_CLK_RST, BIT(1), CCU_GATE_DEFINE(onewire_clk, CCU_PARENT_NAME(vctcxo_24m), APBC_ONEWIRE_CLK_RST, BIT(1), 0); -static const struct clk_parent_data sspa_parents[] = { +/* + * When i2s_bclk is selected as the parent clock of sspa, + * the hardware requires bit3 to be set + */ +CCU_GATE_DEFINE(sspa0_i2s_bclk, CCU_PARENT_HW(i2s_bclk), APBC_SSPA0_CLK_RST, BIT(3), 0); +CCU_GATE_DEFINE(sspa1_i2s_bclk, CCU_PARENT_HW(i2s_bclk), APBC_SSPA1_CLK_RST, BIT(3), 0); + +static const struct clk_parent_data sspa0_parents[] = { CCU_PARENT_HW(pll1_d384_6p4), CCU_PARENT_HW(pll1_d192_12p8), CCU_PARENT_HW(pll1_d96_25p6), @@ -255,10 +282,22 @@ static const struct clk_parent_data sspa_parents[] = { CCU_PARENT_HW(pll1_d768_3p2), CCU_PARENT_HW(pll1_d1536_1p6), CCU_PARENT_HW(pll1_d3072_0p8), - CCU_PARENT_HW(i2s_bclk), + CCU_PARENT_HW(sspa0_i2s_bclk), }; -CCU_MUX_GATE_DEFINE(sspa0_clk, sspa_parents, APBC_SSPA0_CLK_RST, 4, 3, BIT(1), 0); -CCU_MUX_GATE_DEFINE(sspa1_clk, sspa_parents, APBC_SSPA1_CLK_RST, 4, 3, BIT(1), 0); +CCU_MUX_GATE_DEFINE(sspa0_clk, sspa0_parents, APBC_SSPA0_CLK_RST, 4, 3, BIT(1), 0); + +static const struct clk_parent_data sspa1_parents[] = { + CCU_PARENT_HW(pll1_d384_6p4), + CCU_PARENT_HW(pll1_d192_12p8), + CCU_PARENT_HW(pll1_d96_25p6), + CCU_PARENT_HW(pll1_d48_51p2), + CCU_PARENT_HW(pll1_d768_3p2), + CCU_PARENT_HW(pll1_d1536_1p6), + CCU_PARENT_HW(pll1_d3072_0p8), + CCU_PARENT_HW(sspa1_i2s_bclk), +}; +CCU_MUX_GATE_DEFINE(sspa1_clk, sspa1_parents, APBC_SSPA1_CLK_RST, 4, 3, BIT(1), 0); + CCU_GATE_DEFINE(dro_clk, CCU_PARENT_HW(apb_clk), APBC_DRO_CLK_RST, BIT(1), 0); CCU_GATE_DEFINE(ir_clk, CCU_PARENT_HW(apb_clk), APBC_IR_CLK_RST, BIT(1), 0); CCU_GATE_DEFINE(tsen_clk, CCU_PARENT_HW(apb_clk), APBC_TSEN_CLK_RST, BIT(1), 0); @@ -756,6 +795,10 @@ static struct clk_hw *k1_ccu_mpmu_hws[] = { [CLK_I2S_BCLK] = &i2s_bclk.common.hw, [CLK_APB] = &apb_clk.common.hw, [CLK_WDT_BUS] = &wdt_bus_clk.common.hw, + [CLK_I2S_153P6] = &i2s_153p6.common.hw, + [CLK_I2S_153P6_BASE] = &i2s_153p6_base.common.hw, + [CLK_I2S_SYSCLK_SRC] = &i2s_sysclk_src.common.hw, + [CLK_I2S_BCLK_FACTOR] = &i2s_bclk_factor.common.hw, }; static const struct spacemit_ccu_data k1_ccu_mpmu_data = { @@ -865,6 +908,8 @@ static struct clk_hw *k1_ccu_apbc_hws[] = { [CLK_SSPA1_BUS] = &sspa1_bus_clk.common.hw, [CLK_TSEN_BUS] = &tsen_bus_clk.common.hw, [CLK_IPC_AP2AUD_BUS] = &ipc_ap2aud_bus_clk.common.hw, + [CLK_SSPA0_I2S_BCLK] = &sspa0_i2s_bclk.common.hw, + [CLK_SSPA1_I2S_BCLK] = &sspa1_i2s_bclk.common.hw, }; static const struct spacemit_ccu_data k1_ccu_apbc_data = { diff --git a/drivers/clk/spacemit/ccu_ddn.c b/drivers/clk/spacemit/ccu_ddn.c index be311b045698..5b16e273bee5 100644 --- a/drivers/clk/spacemit/ccu_ddn.c +++ b/drivers/clk/spacemit/ccu_ddn.c @@ -22,30 +22,33 @@ #include "ccu_ddn.h" -static unsigned long ccu_ddn_calc_rate(unsigned long prate, - unsigned long num, unsigned long den) +static unsigned long ccu_ddn_calc_rate(unsigned long prate, unsigned long num, + unsigned long den, unsigned int pre_div) { - return prate * den / 2 / num; + return prate * den / pre_div / num; } static unsigned long ccu_ddn_calc_best_rate(struct ccu_ddn *ddn, unsigned long rate, unsigned long prate, unsigned long *num, unsigned long *den) { - rational_best_approximation(rate, prate / 2, + rational_best_approximation(rate, prate / ddn->pre_div, ddn->den_mask >> ddn->den_shift, ddn->num_mask >> ddn->num_shift, den, num); - return ccu_ddn_calc_rate(prate, *num, *den); + return ccu_ddn_calc_rate(prate, *num, *den, ddn->pre_div); } -static long ccu_ddn_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *prate) +static int ccu_ddn_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { struct ccu_ddn *ddn = hw_to_ccu_ddn(hw); unsigned long num, den; - return ccu_ddn_calc_best_rate(ddn, rate, *prate, &num, &den); + req->rate = ccu_ddn_calc_best_rate(ddn, req->rate, + req->best_parent_rate, &num, &den); + + return 0; } static unsigned long ccu_ddn_recalc_rate(struct clk_hw *hw, unsigned long prate) @@ -58,7 +61,7 @@ static unsigned long ccu_ddn_recalc_rate(struct clk_hw *hw, unsigned long prate) num = (val & ddn->num_mask) >> ddn->num_shift; den = (val & ddn->den_mask) >> ddn->den_shift; - return ccu_ddn_calc_rate(prate, num, den); + return ccu_ddn_calc_rate(prate, num, den, ddn->pre_div); } static int ccu_ddn_set_rate(struct clk_hw *hw, unsigned long rate, @@ -78,6 +81,6 @@ static int ccu_ddn_set_rate(struct clk_hw *hw, unsigned long rate, const struct clk_ops spacemit_ccu_ddn_ops = { .recalc_rate = ccu_ddn_recalc_rate, - .round_rate = ccu_ddn_round_rate, + .determine_rate = ccu_ddn_determine_rate, .set_rate = ccu_ddn_set_rate, }; diff --git a/drivers/clk/spacemit/ccu_ddn.h b/drivers/clk/spacemit/ccu_ddn.h index a52fabe77d62..4838414a8e8d 100644 --- a/drivers/clk/spacemit/ccu_ddn.h +++ b/drivers/clk/spacemit/ccu_ddn.h @@ -18,13 +18,14 @@ struct ccu_ddn { unsigned int num_shift; unsigned int den_mask; unsigned int den_shift; + unsigned int pre_div; }; #define CCU_DDN_INIT(_name, _parent, _flags) \ CLK_HW_INIT_HW(#_name, &_parent.common.hw, &spacemit_ccu_ddn_ops, _flags) #define CCU_DDN_DEFINE(_name, _parent, _reg_ctrl, _num_shift, _num_width, \ - _den_shift, _den_width, _flags) \ + _den_shift, _den_width, _pre_div, _flags) \ static struct ccu_ddn _name = { \ .common = { \ .reg_ctrl = _reg_ctrl, \ @@ -33,7 +34,8 @@ static struct ccu_ddn _name = { \ .num_mask = GENMASK(_num_shift + _num_width - 1, _num_shift), \ .num_shift = _num_shift, \ .den_mask = GENMASK(_den_shift + _den_width - 1, _den_shift), \ - .den_shift = _den_shift, \ + .den_shift = _den_shift, \ + .pre_div = _pre_div, \ } static inline struct ccu_ddn *hw_to_ccu_ddn(struct clk_hw *hw) diff --git a/drivers/clk/spacemit/ccu_mix.c b/drivers/clk/spacemit/ccu_mix.c index 9b852aa61f78..7b7990875372 100644 --- a/drivers/clk/spacemit/ccu_mix.c +++ b/drivers/clk/spacemit/ccu_mix.c @@ -80,10 +80,12 @@ static int ccu_mix_trigger_fc(struct clk_hw *hw) MIX_FC_TIMEOUT_US); } -static long ccu_factor_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *prate) +static int ccu_factor_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { - return ccu_factor_recalc_rate(hw, *prate); + req->rate = ccu_factor_recalc_rate(hw, req->best_parent_rate); + + return 0; } static int ccu_factor_set_rate(struct clk_hw *hw, unsigned long rate, @@ -198,7 +200,7 @@ const struct clk_ops spacemit_ccu_gate_ops = { }; const struct clk_ops spacemit_ccu_factor_ops = { - .round_rate = ccu_factor_round_rate, + .determine_rate = ccu_factor_determine_rate, .recalc_rate = ccu_factor_recalc_rate, .set_rate = ccu_factor_set_rate, }; @@ -220,7 +222,7 @@ const struct clk_ops spacemit_ccu_factor_gate_ops = { .enable = ccu_gate_enable, .is_enabled = ccu_gate_is_enabled, - .round_rate = ccu_factor_round_rate, + .determine_rate = ccu_factor_determine_rate, .recalc_rate = ccu_factor_recalc_rate, .set_rate = ccu_factor_set_rate, }; diff --git a/drivers/clk/spacemit/ccu_pll.c b/drivers/clk/spacemit/ccu_pll.c index 45f540073a65..d92f0dae65a4 100644 --- a/drivers/clk/spacemit/ccu_pll.c +++ b/drivers/clk/spacemit/ccu_pll.c @@ -125,12 +125,14 @@ static unsigned long ccu_pll_recalc_rate(struct clk_hw *hw, return entry ? entry->rate : 0; } -static long ccu_pll_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *prate) +static int ccu_pll_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { struct ccu_pll *pll = hw_to_ccu_pll(hw); - return ccu_pll_lookup_best_rate(pll, rate)->rate; + req->rate = ccu_pll_lookup_best_rate(pll, req->rate)->rate; + + return 0; } static int ccu_pll_init(struct clk_hw *hw) @@ -152,6 +154,6 @@ const struct clk_ops spacemit_ccu_pll_ops = { .disable = ccu_pll_disable, .set_rate = ccu_pll_set_rate, .recalc_rate = ccu_pll_recalc_rate, - .round_rate = ccu_pll_round_rate, + .determine_rate = ccu_pll_determine_rate, .is_enabled = ccu_pll_is_enabled, }; diff --git a/drivers/clk/spear/clk-aux-synth.c b/drivers/clk/spear/clk-aux-synth.c index 637938e804f8..d0d063147af8 100644 --- a/drivers/clk/spear/clk-aux-synth.c +++ b/drivers/clk/spear/clk-aux-synth.c @@ -49,14 +49,16 @@ static unsigned long aux_calc_rate(struct clk_hw *hw, unsigned long prate, (rtbl[index].yscale * eq)) * 10000; } -static long clk_aux_round_rate(struct clk_hw *hw, unsigned long drate, - unsigned long *prate) +static int clk_aux_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { struct clk_aux *aux = to_clk_aux(hw); int unused; - return clk_round_rate_index(hw, drate, *prate, aux_calc_rate, - aux->rtbl_cnt, &unused); + req->rate = clk_round_rate_index(hw, req->rate, req->best_parent_rate, + aux_calc_rate, aux->rtbl_cnt, &unused); + + return 0; } static unsigned long clk_aux_recalc_rate(struct clk_hw *hw, @@ -127,7 +129,7 @@ static int clk_aux_set_rate(struct clk_hw *hw, unsigned long drate, static const struct clk_ops clk_aux_ops = { .recalc_rate = clk_aux_recalc_rate, - .round_rate = clk_aux_round_rate, + .determine_rate = clk_aux_determine_rate, .set_rate = clk_aux_set_rate, }; diff --git a/drivers/clk/spear/clk-frac-synth.c b/drivers/clk/spear/clk-frac-synth.c index 2380df293a2c..150f051d28e0 100644 --- a/drivers/clk/spear/clk-frac-synth.c +++ b/drivers/clk/spear/clk-frac-synth.c @@ -52,14 +52,16 @@ static unsigned long frac_calc_rate(struct clk_hw *hw, unsigned long prate, return prate; } -static long clk_frac_round_rate(struct clk_hw *hw, unsigned long drate, - unsigned long *prate) +static int clk_frac_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { struct clk_frac *frac = to_clk_frac(hw); int unused; - return clk_round_rate_index(hw, drate, *prate, frac_calc_rate, - frac->rtbl_cnt, &unused); + req->rate = clk_round_rate_index(hw, req->rate, req->best_parent_rate, + frac_calc_rate, frac->rtbl_cnt, &unused); + + return 0; } static unsigned long clk_frac_recalc_rate(struct clk_hw *hw, @@ -115,7 +117,7 @@ static int clk_frac_set_rate(struct clk_hw *hw, unsigned long drate, static const struct clk_ops clk_frac_ops = { .recalc_rate = clk_frac_recalc_rate, - .round_rate = clk_frac_round_rate, + .determine_rate = clk_frac_determine_rate, .set_rate = clk_frac_set_rate, }; diff --git a/drivers/clk/spear/clk-gpt-synth.c b/drivers/clk/spear/clk-gpt-synth.c index 4ef747c2abbb..cf9659dc9073 100644 --- a/drivers/clk/spear/clk-gpt-synth.c +++ b/drivers/clk/spear/clk-gpt-synth.c @@ -39,14 +39,16 @@ static unsigned long gpt_calc_rate(struct clk_hw *hw, unsigned long prate, return prate; } -static long clk_gpt_round_rate(struct clk_hw *hw, unsigned long drate, - unsigned long *prate) +static int clk_gpt_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { struct clk_gpt *gpt = to_clk_gpt(hw); int unused; - return clk_round_rate_index(hw, drate, *prate, gpt_calc_rate, - gpt->rtbl_cnt, &unused); + req->rate = clk_round_rate_index(hw, req->rate, req->best_parent_rate, + gpt_calc_rate, gpt->rtbl_cnt, &unused); + + return 0; } static unsigned long clk_gpt_recalc_rate(struct clk_hw *hw, @@ -104,7 +106,7 @@ static int clk_gpt_set_rate(struct clk_hw *hw, unsigned long drate, static const struct clk_ops clk_gpt_ops = { .recalc_rate = clk_gpt_recalc_rate, - .round_rate = clk_gpt_round_rate, + .determine_rate = clk_gpt_determine_rate, .set_rate = clk_gpt_set_rate, }; diff --git a/drivers/clk/spear/clk-vco-pll.c b/drivers/clk/spear/clk-vco-pll.c index 348eeab0a906..723a6eb67754 100644 --- a/drivers/clk/spear/clk-vco-pll.c +++ b/drivers/clk/spear/clk-vco-pll.c @@ -110,12 +110,15 @@ static long clk_pll_round_rate_index(struct clk_hw *hw, unsigned long drate, return rate; } -static long clk_pll_round_rate(struct clk_hw *hw, unsigned long drate, - unsigned long *prate) +static int clk_pll_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { int unused; - return clk_pll_round_rate_index(hw, drate, prate, &unused); + req->rate = clk_pll_round_rate_index(hw, req->rate, + &req->best_parent_rate, &unused); + + return 0; } static unsigned long clk_pll_recalc_rate(struct clk_hw *hw, unsigned long @@ -164,7 +167,7 @@ static int clk_pll_set_rate(struct clk_hw *hw, unsigned long drate, static const struct clk_ops clk_pll_ops = { .recalc_rate = clk_pll_recalc_rate, - .round_rate = clk_pll_round_rate, + .determine_rate = clk_pll_determine_rate, .set_rate = clk_pll_set_rate, }; @@ -176,14 +179,16 @@ static inline unsigned long vco_calc_rate(struct clk_hw *hw, return pll_calc_rate(vco->rtbl, prate, index, NULL); } -static long clk_vco_round_rate(struct clk_hw *hw, unsigned long drate, - unsigned long *prate) +static int clk_vco_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { struct clk_vco *vco = to_clk_vco(hw); int unused; - return clk_round_rate_index(hw, drate, *prate, vco_calc_rate, - vco->rtbl_cnt, &unused); + req->rate = clk_round_rate_index(hw, req->rate, req->best_parent_rate, + vco_calc_rate, vco->rtbl_cnt, &unused); + + return 0; } static unsigned long clk_vco_recalc_rate(struct clk_hw *hw, @@ -265,7 +270,7 @@ static int clk_vco_set_rate(struct clk_hw *hw, unsigned long drate, static const struct clk_ops clk_vco_ops = { .recalc_rate = clk_vco_recalc_rate, - .round_rate = clk_vco_round_rate, + .determine_rate = clk_vco_determine_rate, .set_rate = clk_vco_set_rate, }; diff --git a/drivers/clk/sprd/div.c b/drivers/clk/sprd/div.c index 936782c24127..013423881968 100644 --- a/drivers/clk/sprd/div.c +++ b/drivers/clk/sprd/div.c @@ -9,13 +9,16 @@ #include "div.h" -static long sprd_div_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *parent_rate) +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_round_rate(&cd->common.hw, rate, parent_rate, NULL, - cd->div.width, 0); + req->rate = divider_round_rate(&cd->common.hw, req->rate, + &req->best_parent_rate, + NULL, cd->div.width, 0); + + return 0; } unsigned long sprd_div_helper_recalc_rate(struct sprd_clk_common *common, @@ -75,7 +78,7 @@ static int sprd_div_set_rate(struct clk_hw *hw, unsigned long rate, const struct clk_ops sprd_div_ops = { .recalc_rate = sprd_div_recalc_rate, - .round_rate = sprd_div_round_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/pll.c b/drivers/clk/sprd/pll.c index 13a322b2535a..bc6610d5fcb7 100644 --- a/drivers/clk/sprd/pll.c +++ b/drivers/clk/sprd/pll.c @@ -254,16 +254,16 @@ static int sprd_pll_clk_prepare(struct clk_hw *hw) return 0; } -static long sprd_pll_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *prate) +static int sprd_pll_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { - return rate; + return 0; } const struct clk_ops sprd_pll_ops = { .prepare = sprd_pll_clk_prepare, .recalc_rate = sprd_pll_recalc_rate, - .round_rate = sprd_pll_round_rate, + .determine_rate = sprd_pll_determine_rate, .set_rate = sprd_pll_set_rate, }; EXPORT_SYMBOL_GPL(sprd_pll_ops); diff --git a/drivers/clk/st/clk-flexgen.c b/drivers/clk/st/clk-flexgen.c index 5292208c4dd8..e8e7626c76db 100644 --- a/drivers/clk/st/clk-flexgen.c +++ b/drivers/clk/st/clk-flexgen.c @@ -303,16 +303,6 @@ static const struct clkgen_data clkgen_video = { .mode = 1, }; -static const struct clkgen_clk_out clkgen_stih407_a0_clk_out[] = { - /* This clk needs to be on so that memory interface is accessible */ - { .name = "clk-ic-lmi0", .flags = CLK_IS_CRITICAL }, -}; - -static const struct clkgen_data clkgen_stih407_a0 = { - .outputs = clkgen_stih407_a0_clk_out, - .outputs_nb = ARRAY_SIZE(clkgen_stih407_a0_clk_out), -}; - static const struct clkgen_clk_out clkgen_stih410_a0_clk_out[] = { /* Those clks need to be on so that memory interface is accessible */ { .name = "clk-ic-lmi0", .flags = CLK_IS_CRITICAL }, @@ -324,51 +314,6 @@ static const struct clkgen_data clkgen_stih410_a0 = { .outputs_nb = ARRAY_SIZE(clkgen_stih410_a0_clk_out), }; -static const struct clkgen_clk_out clkgen_stih407_c0_clk_out[] = { - { .name = "clk-icn-gpu", }, - { .name = "clk-fdma", }, - { .name = "clk-nand", }, - { .name = "clk-hva", }, - { .name = "clk-proc-stfe", }, - { .name = "clk-proc-tp", }, - { .name = "clk-rx-icn-dmu", }, - { .name = "clk-rx-icn-hva", }, - /* This clk needs to be on to keep bus interconnect alive */ - { .name = "clk-icn-cpu", .flags = CLK_IS_CRITICAL }, - /* This clk needs to be on to keep bus interconnect alive */ - { .name = "clk-tx-icn-dmu", .flags = CLK_IS_CRITICAL }, - { .name = "clk-mmc-0", }, - { .name = "clk-mmc-1", }, - { .name = "clk-jpegdec", }, - /* This clk needs to be on to keep A9 running */ - { .name = "clk-ext2fa9", .flags = CLK_IS_CRITICAL }, - { .name = "clk-ic-bdisp-0", }, - { .name = "clk-ic-bdisp-1", }, - { .name = "clk-pp-dmu", }, - { .name = "clk-vid-dmu", }, - { .name = "clk-dss-lpc", }, - { .name = "clk-st231-aud-0", }, - { .name = "clk-st231-gp-1", }, - { .name = "clk-st231-dmu", }, - /* This clk needs to be on to keep bus interconnect alive */ - { .name = "clk-icn-lmi", .flags = CLK_IS_CRITICAL }, - { .name = "clk-tx-icn-disp-1", }, - /* This clk needs to be on to keep bus interconnect alive */ - { .name = "clk-icn-sbc", .flags = CLK_IS_CRITICAL }, - { .name = "clk-stfe-frc2", }, - { .name = "clk-eth-phy", }, - { .name = "clk-eth-ref-phyclk", }, - { .name = "clk-flash-promip", }, - { .name = "clk-main-disp", }, - { .name = "clk-aux-disp", }, - { .name = "clk-compo-dvp", }, -}; - -static const struct clkgen_data clkgen_stih407_c0 = { - .outputs = clkgen_stih407_c0_clk_out, - .outputs_nb = ARRAY_SIZE(clkgen_stih407_c0_clk_out), -}; - static const struct clkgen_clk_out clkgen_stih410_c0_clk_out[] = { { .name = "clk-icn-gpu", }, { .name = "clk-fdma", }, @@ -482,19 +427,6 @@ static const struct clkgen_data clkgen_stih418_c0 = { .outputs_nb = ARRAY_SIZE(clkgen_stih418_c0_clk_out), }; -static const struct clkgen_clk_out clkgen_stih407_d0_clk_out[] = { - { .name = "clk-pcm-0", }, - { .name = "clk-pcm-1", }, - { .name = "clk-pcm-2", }, - { .name = "clk-spdiff", }, -}; - -static const struct clkgen_data clkgen_stih407_d0 = { - .flags = CLK_SET_RATE_PARENT, - .outputs = clkgen_stih407_d0_clk_out, - .outputs_nb = ARRAY_SIZE(clkgen_stih407_d0_clk_out), -}; - static const struct clkgen_clk_out clkgen_stih410_d0_clk_out[] = { { .name = "clk-pcm-0", }, { .name = "clk-pcm-1", }, @@ -597,18 +529,10 @@ static const struct of_device_id flexgen_of_match[] = { .data = &clkgen_video, }, { - .compatible = "st,flexgen-stih407-a0", - .data = &clkgen_stih407_a0, - }, - { .compatible = "st,flexgen-stih410-a0", .data = &clkgen_stih410_a0, }, { - .compatible = "st,flexgen-stih407-c0", - .data = &clkgen_stih407_c0, - }, - { .compatible = "st,flexgen-stih410-c0", .data = &clkgen_stih410_c0, }, @@ -617,10 +541,6 @@ static const struct of_device_id flexgen_of_match[] = { .data = &clkgen_stih418_c0, }, { - .compatible = "st,flexgen-stih407-d0", - .data = &clkgen_stih407_d0, - }, - { .compatible = "st,flexgen-stih410-d0", .data = &clkgen_stih410_d0, }, diff --git a/drivers/clk/st/clkgen-fsyn.c b/drivers/clk/st/clkgen-fsyn.c index 40df1db102a7..e06e7e5cc1a5 100644 --- a/drivers/clk/st/clkgen-fsyn.c +++ b/drivers/clk/st/clkgen-fsyn.c @@ -375,22 +375,21 @@ static int clk_fs660c32_vco_get_params(unsigned long input, return 0; } -static long quadfs_pll_fs660c32_round_rate(struct clk_hw *hw, - unsigned long rate, - unsigned long *prate) +static int quadfs_pll_fs660c32_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { struct stm_fs params; - if (clk_fs660c32_vco_get_params(*prate, rate, ¶ms)) - return rate; + if (clk_fs660c32_vco_get_params(req->best_parent_rate, req->rate, ¶ms)) + return 0; - clk_fs660c32_vco_get_rate(*prate, ¶ms, &rate); + clk_fs660c32_vco_get_rate(req->best_parent_rate, ¶ms, &req->rate); pr_debug("%s: %s new rate %ld [ndiv=%u]\n", __func__, clk_hw_get_name(hw), - rate, (unsigned int)params.ndiv); + req->rate, (unsigned int)params.ndiv); - return rate; + return 0; } static int quadfs_pll_fs660c32_set_rate(struct clk_hw *hw, unsigned long rate, @@ -436,7 +435,7 @@ static const struct clk_ops st_quadfs_pll_c32_ops = { .disable = quadfs_pll_disable, .is_enabled = quadfs_pll_is_enabled, .recalc_rate = quadfs_pll_fs660c32_recalc_rate, - .round_rate = quadfs_pll_fs660c32_round_rate, + .determine_rate = quadfs_pll_fs660c32_determine_rate, .set_rate = quadfs_pll_fs660c32_set_rate, }; @@ -814,19 +813,21 @@ static unsigned long quadfs_recalc_rate(struct clk_hw *hw, return rate; } -static long quadfs_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *prate) +static int quadfs_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { struct stm_fs params; - rate = quadfs_find_best_rate(hw, rate, *prate, ¶ms); + req->rate = quadfs_find_best_rate(hw, req->rate, + req->best_parent_rate, ¶ms); pr_debug("%s: %s new rate %ld [sdiv=0x%x,md=0x%x,pe=0x%x,nsdiv3=%u]\n", __func__, clk_hw_get_name(hw), - rate, (unsigned int)params.sdiv, (unsigned int)params.mdiv, - (unsigned int)params.pe, (unsigned int)params.nsdiv); + req->rate, (unsigned int)params.sdiv, + (unsigned int)params.mdiv, + (unsigned int)params.pe, (unsigned int)params.nsdiv); - return rate; + return 0; } @@ -873,7 +874,7 @@ static const struct clk_ops st_quadfs_ops = { .enable = quadfs_fsynth_enable, .disable = quadfs_fsynth_disable, .is_enabled = quadfs_fsynth_is_enabled, - .round_rate = quadfs_round_rate, + .determine_rate = quadfs_determine_rate, .set_rate = quadfs_set_rate, .recalc_rate = quadfs_recalc_rate, }; diff --git a/drivers/clk/st/clkgen-pll.c b/drivers/clk/st/clkgen-pll.c index b36e4d803636..c258ff87a171 100644 --- a/drivers/clk/st/clkgen-pll.c +++ b/drivers/clk/st/clkgen-pll.c @@ -395,25 +395,28 @@ static unsigned long recalc_stm_pll3200c32(struct clk_hw *hw, return rate; } -static long round_rate_stm_pll3200c32(struct clk_hw *hw, unsigned long rate, - unsigned long *prate) +static int stm_pll3200c32_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { struct stm_pll params; - if (!clk_pll3200c32_get_params(*prate, rate, ¶ms)) - clk_pll3200c32_get_rate(*prate, ¶ms, &rate); + if (!clk_pll3200c32_get_params(req->best_parent_rate, req->rate, ¶ms)) + clk_pll3200c32_get_rate(req->best_parent_rate, ¶ms, + &req->rate); else { pr_debug("%s: %s rate %ld Invalid\n", __func__, - __clk_get_name(hw->clk), rate); + __clk_get_name(hw->clk), req->rate); + req->rate = 0; + return 0; } pr_debug("%s: %s new rate %ld [ndiv=%u] [idf=%u]\n", __func__, __clk_get_name(hw->clk), - rate, (unsigned int)params.ndiv, + req->rate, (unsigned int)params.ndiv, (unsigned int)params.idf); - return rate; + return 0; } static int set_rate_stm_pll3200c32(struct clk_hw *hw, unsigned long rate, @@ -549,25 +552,28 @@ static unsigned long recalc_stm_pll4600c28(struct clk_hw *hw, return rate; } -static long round_rate_stm_pll4600c28(struct clk_hw *hw, unsigned long rate, - unsigned long *prate) +static int stm_pll4600c28_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { struct stm_pll params; - if (!clk_pll4600c28_get_params(*prate, rate, ¶ms)) { - clk_pll4600c28_get_rate(*prate, ¶ms, &rate); + if (!clk_pll4600c28_get_params(req->best_parent_rate, req->rate, ¶ms)) { + clk_pll4600c28_get_rate(req->best_parent_rate, ¶ms, + &req->rate); } else { pr_debug("%s: %s rate %ld Invalid\n", __func__, - __clk_get_name(hw->clk), rate); + __clk_get_name(hw->clk), req->rate); + req->rate = 0; + return 0; } pr_debug("%s: %s new rate %ld [ndiv=%u] [idf=%u]\n", __func__, __clk_get_name(hw->clk), - rate, (unsigned int)params.ndiv, + req->rate, (unsigned int)params.ndiv, (unsigned int)params.idf); - return rate; + return 0; } static int set_rate_stm_pll4600c28(struct clk_hw *hw, unsigned long rate, @@ -628,7 +634,7 @@ static const struct clk_ops stm_pll3200c32_a9_ops = { .disable = clkgen_pll_disable, .is_enabled = clkgen_pll_is_enabled, .recalc_rate = recalc_stm_pll3200c32, - .round_rate = round_rate_stm_pll3200c32, + .determine_rate = stm_pll3200c32_determine_rate, .set_rate = set_rate_stm_pll3200c32, }; @@ -637,7 +643,7 @@ static const struct clk_ops stm_pll4600c28_ops = { .disable = clkgen_pll_disable, .is_enabled = clkgen_pll_is_enabled, .recalc_rate = recalc_stm_pll4600c28, - .round_rate = round_rate_stm_pll4600c28, + .determine_rate = stm_pll4600c28_determine_rate, .set_rate = set_rate_stm_pll4600c28, }; diff --git a/drivers/clk/stm32/Kconfig b/drivers/clk/stm32/Kconfig index 4d2eb993ea08..5dbd75cde657 100644 --- a/drivers/clk/stm32/Kconfig +++ b/drivers/clk/stm32/Kconfig @@ -25,6 +25,13 @@ config COMMON_CLK_STM32MP157 help Support for stm32mp15x SoC family clocks. +config COMMON_CLK_STM32MP215 + bool "Clock driver for stm32mp21x clocks" + depends on ARM || ARM64 || COMPILE_TEST + default y + help + Support for stm32mp21x SoC family clocks + config COMMON_CLK_STM32MP257 bool "Clock driver for stm32mp25x clocks" depends on ARM64 || COMPILE_TEST diff --git a/drivers/clk/stm32/Makefile b/drivers/clk/stm32/Makefile index 0a627164fcce..e04727b59449 100644 --- a/drivers/clk/stm32/Makefile +++ b/drivers/clk/stm32/Makefile @@ -1,3 +1,4 @@ obj-$(CONFIG_COMMON_CLK_STM32MP135) += clk-stm32mp13.o clk-stm32-core.o reset-stm32.o obj-$(CONFIG_COMMON_CLK_STM32MP157) += clk-stm32mp1.o reset-stm32.o +obj-$(CONFIG_COMMON_CLK_STM32MP215) += clk-stm32mp21.o clk-stm32-core.o reset-stm32.o obj-$(CONFIG_COMMON_CLK_STM32MP257) += clk-stm32mp25.o clk-stm32-core.o reset-stm32.o diff --git a/drivers/clk/stm32/clk-stm32-core.c b/drivers/clk/stm32/clk-stm32-core.c index 933e3cde0795..72825b9c36a4 100644 --- a/drivers/clk/stm32/clk-stm32-core.c +++ b/drivers/clk/stm32/clk-stm32-core.c @@ -351,14 +351,14 @@ static int clk_stm32_divider_set_rate(struct clk_hw *hw, unsigned long rate, return ret; } -static long clk_stm32_divider_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *prate) +static int clk_stm32_divider_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { struct clk_stm32_div *div = to_clk_stm32_divider(hw); const struct stm32_div_cfg *divider; if (div->div_id == NO_STM32_DIV) - return rate; + return 0; divider = &div->clock_data->dividers[div->div_id]; @@ -369,14 +369,22 @@ static long clk_stm32_divider_round_rate(struct clk_hw *hw, unsigned long rate, val = readl(div->base + divider->offset) >> divider->shift; val &= clk_div_mask(divider->width); - return divider_ro_round_rate(hw, rate, prate, divider->table, - divider->width, divider->flags, - val); + req->rate = divider_ro_round_rate(hw, req->rate, + &req->best_parent_rate, + divider->table, + divider->width, + divider->flags, val); + + return 0; } - return divider_round_rate_parent(hw, clk_hw_get_parent(hw), - rate, prate, divider->table, - divider->width, divider->flags); + req->rate = divider_round_rate_parent(hw, clk_hw_get_parent(hw), + req->rate, + &req->best_parent_rate, + divider->table, + divider->width, divider->flags); + + return 0; } static unsigned long clk_stm32_divider_recalc_rate(struct clk_hw *hw, @@ -392,7 +400,7 @@ static unsigned long clk_stm32_divider_recalc_rate(struct clk_hw *hw, const struct clk_ops clk_stm32_divider_ops = { .recalc_rate = clk_stm32_divider_recalc_rate, - .round_rate = clk_stm32_divider_round_rate, + .determine_rate = clk_stm32_divider_determine_rate, .set_rate = clk_stm32_divider_set_rate, }; diff --git a/drivers/clk/stm32/clk-stm32mp1.c b/drivers/clk/stm32/clk-stm32mp1.c index b8b45ed22f98..2d9ccd96ec98 100644 --- a/drivers/clk/stm32/clk-stm32mp1.c +++ b/drivers/clk/stm32/clk-stm32mp1.c @@ -970,12 +970,15 @@ static unsigned long __bestmult(struct clk_hw *hw, unsigned long rate, return mult; } -static long timer_ker_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *parent_rate) +static int timer_ker_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { - unsigned long factor = __bestmult(hw, rate, *parent_rate); + unsigned long factor = __bestmult(hw, req->rate, + req->best_parent_rate); - return *parent_rate * factor; + req->rate = req->best_parent_rate * factor; + + return 0; } static int timer_ker_set_rate(struct clk_hw *hw, unsigned long rate, @@ -1026,7 +1029,7 @@ static unsigned long timer_ker_recalc_rate(struct clk_hw *hw, static const struct clk_ops timer_ker_ops = { .recalc_rate = timer_ker_recalc_rate, - .round_rate = timer_ker_round_rate, + .determine_rate = timer_ker_determine_rate, .set_rate = timer_ker_set_rate, }; diff --git a/drivers/clk/stm32/clk-stm32mp21.c b/drivers/clk/stm32/clk-stm32mp21.c new file mode 100644 index 000000000000..c8a37b716bd5 --- /dev/null +++ b/drivers/clk/stm32/clk-stm32mp21.c @@ -0,0 +1,1586 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (C) STMicroelectronics 2023 - All Rights Reserved + * Author: Gabriel Fernandez <gabriel.fernandez@foss.st.com> for STMicroelectronics. + */ + +#include <linux/bus/stm32_firewall_device.h> +#include <linux/clk-provider.h> +#include <linux/io.h> +#include <linux/platform_device.h> + +#include "clk-stm32-core.h" +#include "reset-stm32.h" +#include "stm32mp21_rcc.h" + +#include <dt-bindings/clock/st,stm32mp21-rcc.h> +#include <dt-bindings/reset/st,stm32mp21-rcc.h> + +/* Max clock binding value */ +#define STM32MP21_LAST_CLK CK_SCMI_KER_ETR + +/* Clock security definition */ +#define SECF_NONE -1 + +#define RCC_REG_SIZE 32 +#define RCC_SECCFGR(x) (((x) / RCC_REG_SIZE) * 0x4 + RCC_SECCFGR0) +#define RCC_CIDCFGR(x) ((x) * 0x8 + RCC_R0CIDCFGR) +#define RCC_SEMCR(x) ((x) * 0x8 + RCC_R0SEMCR) +#define RCC_CID1 1 + +/* Register: RIFSC_CIDCFGR */ +#define RCC_CIDCFGR_CFEN BIT(0) +#define RCC_CIDCFGR_SEM_EN BIT(1) +#define RCC_CIDCFGR_SEMWLC1_EN BIT(17) +#define RCC_CIDCFGR_SCID_MASK GENMASK(6, 4) + +/* Register: RIFSC_SEMCR */ +#define RCC_SEMCR_SEMCID_MASK GENMASK(6, 4) + +#define MP21_RIF_RCC_MCO1 108 +#define MP21_RIF_RCC_MCO2 109 + +#define SEC_RIFSC_FLAG BIT(31) +#define SEC_RIFSC(_id) ((_id) | SEC_RIFSC_FLAG) + +enum { + HSE, + HSI, + MSI, + LSE, + LSI, + HSE_DIV2, + ICN_HS_MCU, + ICN_LS_MCU, + ICN_SDMMC, + ICN_DDR, + ICN_DISPLAY, + ICN_HSL, + ICN_NIC, + FLEXGEN_07, + FLEXGEN_08, + FLEXGEN_09, + FLEXGEN_10, + FLEXGEN_11, + FLEXGEN_12, + FLEXGEN_13, + FLEXGEN_14, + FLEXGEN_16, + FLEXGEN_17, + FLEXGEN_18, + FLEXGEN_19, + FLEXGEN_20, + FLEXGEN_21, + FLEXGEN_22, + FLEXGEN_23, + FLEXGEN_24, + FLEXGEN_25, + FLEXGEN_26, + FLEXGEN_27, + FLEXGEN_29, + FLEXGEN_30, + FLEXGEN_31, + FLEXGEN_33, + FLEXGEN_36, + FLEXGEN_37, + FLEXGEN_38, + FLEXGEN_39, + FLEXGEN_40, + FLEXGEN_41, + FLEXGEN_42, + FLEXGEN_43, + FLEXGEN_44, + FLEXGEN_45, + FLEXGEN_46, + FLEXGEN_47, + FLEXGEN_48, + FLEXGEN_50, + FLEXGEN_51, + FLEXGEN_52, + FLEXGEN_53, + FLEXGEN_54, + FLEXGEN_55, + FLEXGEN_56, + FLEXGEN_57, + FLEXGEN_58, + FLEXGEN_61, + FLEXGEN_62, + FLEXGEN_63, + ICN_APB1, + ICN_APB2, + ICN_APB3, + ICN_APB4, + ICN_APB5, + ICN_APBDBG, + TIMG1, + TIMG2, +}; + +static const struct clk_parent_data adc1_src[] = { + { .index = FLEXGEN_46 }, + { .index = ICN_LS_MCU }, +}; + +static const struct clk_parent_data adc2_src[] = { + { .index = FLEXGEN_47 }, + { .index = ICN_LS_MCU }, + { .index = FLEXGEN_46 }, +}; + +static const struct clk_parent_data usb2phy1_src[] = { + { .index = FLEXGEN_57 }, + { .index = HSE_DIV2 }, +}; + +static const struct clk_parent_data usb2phy2_src[] = { + { .index = FLEXGEN_58 }, + { .index = HSE_DIV2 }, +}; + +static const struct clk_parent_data dts_src[] = { + { .index = HSI }, + { .index = HSE }, + { .index = MSI }, +}; + +static const struct clk_parent_data mco1_src[] = { + { .index = FLEXGEN_61 }, +}; + +static const struct clk_parent_data mco2_src[] = { + { .index = FLEXGEN_62 }, +}; + +enum enum_mux_cfg { + MUX_ADC1, + MUX_ADC2, + MUX_DTS, + MUX_MCO1, + MUX_MCO2, + MUX_USB2PHY1, + MUX_USB2PHY2, + MUX_NB +}; + +#define MUX_CFG(id, _offset, _shift, _width) \ + [id] = { \ + .offset = (_offset), \ + .shift = (_shift), \ + .width = (_width), \ + } + +static const struct stm32_mux_cfg stm32mp21_muxes[MUX_NB] = { + MUX_CFG(MUX_ADC1, RCC_ADC1CFGR, 12, 1), + MUX_CFG(MUX_ADC2, RCC_ADC2CFGR, 12, 2), + MUX_CFG(MUX_DTS, RCC_DTSCFGR, 12, 2), + MUX_CFG(MUX_MCO1, RCC_MCO1CFGR, 0, 1), + MUX_CFG(MUX_MCO2, RCC_MCO2CFGR, 0, 1), + MUX_CFG(MUX_USB2PHY1, RCC_USB2PHY1CFGR, 15, 1), + MUX_CFG(MUX_USB2PHY2, RCC_USB2PHY2CFGR, 15, 1), +}; + +enum enum_gate_cfg { + GATE_ADC1, + GATE_ADC2, + GATE_CRC, + GATE_CRYP1, + GATE_CRYP2, + GATE_CSI, + GATE_DCMIPP, + GATE_DCMIPSSI, + GATE_DDRPERFM, + GATE_DTS, + GATE_ETH1, + GATE_ETH1MAC, + GATE_ETH1RX, + GATE_ETH1STP, + GATE_ETH1TX, + GATE_ETH2, + GATE_ETH2MAC, + GATE_ETH2RX, + GATE_ETH2STP, + GATE_ETH2TX, + GATE_FDCAN, + GATE_HASH1, + GATE_HASH2, + GATE_HDP, + GATE_I2C1, + GATE_I2C2, + GATE_I2C3, + GATE_I3C1, + GATE_I3C2, + GATE_I3C3, + GATE_IWDG1, + GATE_IWDG2, + GATE_IWDG3, + GATE_IWDG4, + GATE_LPTIM1, + GATE_LPTIM2, + GATE_LPTIM3, + GATE_LPTIM4, + GATE_LPTIM5, + GATE_LPUART1, + GATE_LTDC, + GATE_MCO1, + GATE_MCO2, + GATE_MDF1, + GATE_OTG, + GATE_PKA, + GATE_RNG1, + GATE_RNG2, + GATE_SAES, + GATE_SAI1, + GATE_SAI2, + GATE_SAI3, + GATE_SAI4, + GATE_SDMMC1, + GATE_SDMMC2, + GATE_SDMMC3, + GATE_SERC, + GATE_SPDIFRX, + GATE_SPI1, + GATE_SPI2, + GATE_SPI3, + GATE_SPI4, + GATE_SPI5, + GATE_SPI6, + GATE_TIM1, + GATE_TIM10, + GATE_TIM11, + GATE_TIM12, + GATE_TIM13, + GATE_TIM14, + GATE_TIM15, + GATE_TIM16, + GATE_TIM17, + GATE_TIM2, + GATE_TIM3, + GATE_TIM4, + GATE_TIM5, + GATE_TIM6, + GATE_TIM7, + GATE_TIM8, + GATE_UART4, + GATE_UART5, + GATE_UART7, + GATE_USART1, + GATE_USART2, + GATE_USART3, + GATE_USART6, + GATE_USB2PHY1, + GATE_USB2PHY2, + GATE_USBH, + GATE_VREF, + GATE_WWDG1, + GATE_NB +}; + +#define GATE_CFG(id, _offset, _bit_idx, _offset_clr) \ + [id] = { \ + .offset = (_offset), \ + .bit_idx = (_bit_idx), \ + .set_clr = (_offset_clr), \ + } + +static const struct stm32_gate_cfg stm32mp21_gates[GATE_NB] = { + GATE_CFG(GATE_ADC1, RCC_ADC1CFGR, 1, 0), + GATE_CFG(GATE_ADC2, RCC_ADC2CFGR, 1, 0), + GATE_CFG(GATE_CRC, RCC_CRCCFGR, 1, 0), + GATE_CFG(GATE_CRYP1, RCC_CRYP1CFGR, 1, 0), + GATE_CFG(GATE_CRYP2, RCC_CRYP2CFGR, 1, 0), + GATE_CFG(GATE_CSI, RCC_CSICFGR, 1, 0), + GATE_CFG(GATE_DCMIPP, RCC_DCMIPPCFGR, 1, 0), + GATE_CFG(GATE_DCMIPSSI, RCC_DCMIPSSICFGR, 1, 0), + GATE_CFG(GATE_DDRPERFM, RCC_DDRPERFMCFGR, 1, 0), + GATE_CFG(GATE_DTS, RCC_DTSCFGR, 1, 0), + GATE_CFG(GATE_ETH1, RCC_ETH1CFGR, 5, 0), + GATE_CFG(GATE_ETH1MAC, RCC_ETH1CFGR, 1, 0), + GATE_CFG(GATE_ETH1RX, RCC_ETH1CFGR, 10, 0), + GATE_CFG(GATE_ETH1STP, RCC_ETH1CFGR, 4, 0), + GATE_CFG(GATE_ETH1TX, RCC_ETH1CFGR, 8, 0), + GATE_CFG(GATE_ETH2, RCC_ETH2CFGR, 5, 0), + GATE_CFG(GATE_ETH2MAC, RCC_ETH2CFGR, 1, 0), + GATE_CFG(GATE_ETH2RX, RCC_ETH2CFGR, 10, 0), + GATE_CFG(GATE_ETH2STP, RCC_ETH2CFGR, 4, 0), + GATE_CFG(GATE_ETH2TX, RCC_ETH2CFGR, 8, 0), + GATE_CFG(GATE_FDCAN, RCC_FDCANCFGR, 1, 0), + GATE_CFG(GATE_HASH1, RCC_HASH1CFGR, 1, 0), + GATE_CFG(GATE_HASH2, RCC_HASH2CFGR, 1, 0), + GATE_CFG(GATE_HDP, RCC_HDPCFGR, 1, 0), + GATE_CFG(GATE_I2C1, RCC_I2C1CFGR, 1, 0), + GATE_CFG(GATE_I2C2, RCC_I2C2CFGR, 1, 0), + GATE_CFG(GATE_I2C3, RCC_I2C3CFGR, 1, 0), + GATE_CFG(GATE_I3C1, RCC_I3C1CFGR, 1, 0), + GATE_CFG(GATE_I3C2, RCC_I3C2CFGR, 1, 0), + GATE_CFG(GATE_I3C3, RCC_I3C3CFGR, 1, 0), + GATE_CFG(GATE_IWDG1, RCC_IWDG1CFGR, 1, 0), + GATE_CFG(GATE_IWDG2, RCC_IWDG2CFGR, 1, 0), + GATE_CFG(GATE_IWDG3, RCC_IWDG3CFGR, 1, 0), + GATE_CFG(GATE_IWDG4, RCC_IWDG4CFGR, 1, 0), + GATE_CFG(GATE_LPTIM1, RCC_LPTIM1CFGR, 1, 0), + GATE_CFG(GATE_LPTIM2, RCC_LPTIM2CFGR, 1, 0), + GATE_CFG(GATE_LPTIM3, RCC_LPTIM3CFGR, 1, 0), + GATE_CFG(GATE_LPTIM4, RCC_LPTIM4CFGR, 1, 0), + GATE_CFG(GATE_LPTIM5, RCC_LPTIM5CFGR, 1, 0), + GATE_CFG(GATE_LPUART1, RCC_LPUART1CFGR, 1, 0), + GATE_CFG(GATE_LTDC, RCC_LTDCCFGR, 1, 0), + GATE_CFG(GATE_MCO1, RCC_MCO1CFGR, 8, 0), + GATE_CFG(GATE_MCO2, RCC_MCO2CFGR, 8, 0), + GATE_CFG(GATE_MDF1, RCC_MDF1CFGR, 1, 0), + GATE_CFG(GATE_OTG, RCC_OTGCFGR, 1, 0), + GATE_CFG(GATE_PKA, RCC_PKACFGR, 1, 0), + GATE_CFG(GATE_RNG1, RCC_RNG1CFGR, 1, 0), + GATE_CFG(GATE_RNG2, RCC_RNG2CFGR, 1, 0), + GATE_CFG(GATE_SAES, RCC_SAESCFGR, 1, 0), + GATE_CFG(GATE_SAI1, RCC_SAI1CFGR, 1, 0), + GATE_CFG(GATE_SAI2, RCC_SAI2CFGR, 1, 0), + GATE_CFG(GATE_SAI3, RCC_SAI3CFGR, 1, 0), + GATE_CFG(GATE_SAI4, RCC_SAI4CFGR, 1, 0), + GATE_CFG(GATE_SDMMC1, RCC_SDMMC1CFGR, 1, 0), + GATE_CFG(GATE_SDMMC2, RCC_SDMMC2CFGR, 1, 0), + GATE_CFG(GATE_SDMMC3, RCC_SDMMC3CFGR, 1, 0), + GATE_CFG(GATE_SERC, RCC_SERCCFGR, 1, 0), + GATE_CFG(GATE_SPDIFRX, RCC_SPDIFRXCFGR, 1, 0), + GATE_CFG(GATE_SPI1, RCC_SPI1CFGR, 1, 0), + GATE_CFG(GATE_SPI2, RCC_SPI2CFGR, 1, 0), + GATE_CFG(GATE_SPI3, RCC_SPI3CFGR, 1, 0), + GATE_CFG(GATE_SPI4, RCC_SPI4CFGR, 1, 0), + GATE_CFG(GATE_SPI5, RCC_SPI5CFGR, 1, 0), + GATE_CFG(GATE_SPI6, RCC_SPI6CFGR, 1, 0), + GATE_CFG(GATE_TIM1, RCC_TIM1CFGR, 1, 0), + GATE_CFG(GATE_TIM10, RCC_TIM10CFGR, 1, 0), + GATE_CFG(GATE_TIM11, RCC_TIM11CFGR, 1, 0), + GATE_CFG(GATE_TIM12, RCC_TIM12CFGR, 1, 0), + GATE_CFG(GATE_TIM13, RCC_TIM13CFGR, 1, 0), + GATE_CFG(GATE_TIM14, RCC_TIM14CFGR, 1, 0), + GATE_CFG(GATE_TIM15, RCC_TIM15CFGR, 1, 0), + GATE_CFG(GATE_TIM16, RCC_TIM16CFGR, 1, 0), + GATE_CFG(GATE_TIM17, RCC_TIM17CFGR, 1, 0), + GATE_CFG(GATE_TIM2, RCC_TIM2CFGR, 1, 0), + GATE_CFG(GATE_TIM3, RCC_TIM3CFGR, 1, 0), + GATE_CFG(GATE_TIM4, RCC_TIM4CFGR, 1, 0), + GATE_CFG(GATE_TIM5, RCC_TIM5CFGR, 1, 0), + GATE_CFG(GATE_TIM6, RCC_TIM6CFGR, 1, 0), + GATE_CFG(GATE_TIM7, RCC_TIM7CFGR, 1, 0), + GATE_CFG(GATE_TIM8, RCC_TIM8CFGR, 1, 0), + GATE_CFG(GATE_UART4, RCC_UART4CFGR, 1, 0), + GATE_CFG(GATE_UART5, RCC_UART5CFGR, 1, 0), + GATE_CFG(GATE_UART7, RCC_UART7CFGR, 1, 0), + GATE_CFG(GATE_USART1, RCC_USART1CFGR, 1, 0), + GATE_CFG(GATE_USART2, RCC_USART2CFGR, 1, 0), + GATE_CFG(GATE_USART3, RCC_USART3CFGR, 1, 0), + GATE_CFG(GATE_USART6, RCC_USART6CFGR, 1, 0), + GATE_CFG(GATE_USB2PHY1, RCC_USB2PHY1CFGR, 1, 0), + GATE_CFG(GATE_USB2PHY2, RCC_USB2PHY2CFGR, 1, 0), + GATE_CFG(GATE_USBH, RCC_USBHCFGR, 1, 0), + GATE_CFG(GATE_VREF, RCC_VREFCFGR, 1, 0), + GATE_CFG(GATE_WWDG1, RCC_WWDG1CFGR, 1, 0), +}; + +#define CLK_HW_INIT_INDEX(_name, _parent, _ops, _flags) \ + (&(struct clk_init_data) { \ + .flags = _flags, \ + .name = _name, \ + .parent_data = (const struct clk_parent_data[]) { \ + { .index = _parent }, \ + }, \ + .num_parents = 1, \ + .ops = _ops, \ + }) + +/* ADC */ +static struct clk_stm32_gate ck_icn_p_adc1 = { + .gate_id = GATE_ADC1, + .hw.init = CLK_HW_INIT_INDEX("ck_icn_p_adc1", ICN_LS_MCU, &clk_stm32_gate_ops, 0), +}; + +static struct clk_stm32_composite ck_ker_adc1 = { + .gate_id = GATE_ADC1, + .mux_id = MUX_ADC1, + .div_id = NO_STM32_DIV, + .hw.init = CLK_HW_INIT_PARENTS_DATA("ck_ker_adc1", adc1_src, &clk_stm32_composite_ops, 0), +}; + +static struct clk_stm32_gate ck_icn_p_adc2 = { + .gate_id = GATE_ADC2, + .hw.init = CLK_HW_INIT_INDEX("ck_icn_p_adc2", ICN_LS_MCU, &clk_stm32_gate_ops, 0), +}; + +static struct clk_stm32_composite ck_ker_adc2 = { + .gate_id = GATE_ADC2, + .mux_id = MUX_ADC2, + .div_id = NO_STM32_DIV, + .hw.init = CLK_HW_INIT_PARENTS_DATA("ck_ker_adc2", adc2_src, &clk_stm32_composite_ops, 0), +}; + +/* CSI-HOST */ +static struct clk_stm32_gate ck_icn_p_csi = { + .gate_id = GATE_CSI, + .hw.init = CLK_HW_INIT_INDEX("ck_icn_p_csi", ICN_APB4, &clk_stm32_gate_ops, 0), +}; + +static struct clk_stm32_gate ck_ker_csi = { + .gate_id = GATE_CSI, + .hw.init = CLK_HW_INIT_INDEX("ck_ker_csi", FLEXGEN_29, &clk_stm32_gate_ops, 0), +}; + +static struct clk_stm32_gate ck_ker_csitxesc = { + .gate_id = GATE_CSI, + .hw.init = CLK_HW_INIT_INDEX("ck_ker_csitxesc", FLEXGEN_30, &clk_stm32_gate_ops, 0), +}; + +/* CSI-PHY */ +static struct clk_stm32_gate ck_ker_csiphy = { + .gate_id = GATE_CSI, + .hw.init = CLK_HW_INIT_INDEX("ck_ker_csiphy", FLEXGEN_31, &clk_stm32_gate_ops, 0), +}; + +/* DCMIPP */ +static struct clk_stm32_gate ck_icn_p_dcmipp = { + .gate_id = GATE_DCMIPP, + .hw.init = CLK_HW_INIT_INDEX("ck_icn_p_dcmipp", ICN_APB4, &clk_stm32_gate_ops, 0), +}; + +static struct clk_stm32_gate ck_icn_p_dcmipssi = { + .gate_id = GATE_DCMIPSSI, + .hw.init = CLK_HW_INIT_INDEX("ck_icn_p_dcmipssi", ICN_LS_MCU, &clk_stm32_gate_ops, 0), +}; + +/* DDRPERMF */ +static struct clk_stm32_gate ck_icn_p_ddrperfm = { + .gate_id = GATE_DDRPERFM, + .hw.init = CLK_HW_INIT_INDEX("ck_icn_p_ddrperfm", ICN_APB4, &clk_stm32_gate_ops, 0), +}; + +/* CRC */ +static struct clk_stm32_gate ck_icn_p_crc = { + .gate_id = GATE_CRC, + .hw.init = CLK_HW_INIT_INDEX("ck_icn_p_crc", ICN_LS_MCU, &clk_stm32_gate_ops, 0), +}; + +/* CRYP */ +static struct clk_stm32_gate ck_icn_p_cryp1 = { + .gate_id = GATE_CRYP1, + .hw.init = CLK_HW_INIT_INDEX("ck_icn_p_cryp1", ICN_LS_MCU, &clk_stm32_gate_ops, 0), +}; + +static struct clk_stm32_gate ck_icn_p_cryp2 = { + .gate_id = GATE_CRYP2, + .hw.init = CLK_HW_INIT_INDEX("ck_icn_p_cryp2", ICN_LS_MCU, &clk_stm32_gate_ops, 0), +}; + +/* DBG & TRACE */ +/* Trace and debug clocks are managed by SCMI */ + +/* LTDC */ +static struct clk_stm32_gate ck_icn_p_ltdc = { + .gate_id = GATE_LTDC, + .hw.init = CLK_HW_INIT_INDEX("ck_icn_p_ltdc", ICN_APB4, &clk_stm32_gate_ops, 0), +}; + +static struct clk_stm32_gate ck_ker_ltdc = { + .gate_id = GATE_LTDC, + .hw.init = CLK_HW_INIT_INDEX("ck_ker_ltdc", FLEXGEN_27, &clk_stm32_gate_ops, + CLK_SET_RATE_PARENT), +}; + +/* DTS */ +static struct clk_stm32_composite ck_ker_dts = { + .gate_id = GATE_DTS, + .mux_id = MUX_DTS, + .div_id = NO_STM32_DIV, + .hw.init = CLK_HW_INIT_PARENTS_DATA("ck_ker_dts", dts_src, + &clk_stm32_composite_ops, 0), +}; + +/* ETHERNET */ +static struct clk_stm32_gate ck_icn_p_eth1 = { + .gate_id = GATE_ETH1, + .hw.init = CLK_HW_INIT_INDEX("ck_icn_p_eth1", ICN_LS_MCU, &clk_stm32_gate_ops, 0), +}; + +static struct clk_stm32_gate ck_ker_eth1stp = { + .gate_id = GATE_ETH1STP, + .hw.init = CLK_HW_INIT_INDEX("ck_ker_eth1stp", ICN_LS_MCU, &clk_stm32_gate_ops, 0), +}; + +static struct clk_stm32_gate ck_ker_eth1 = { + .gate_id = GATE_ETH1, + .hw.init = CLK_HW_INIT_INDEX("ck_ker_eth1", FLEXGEN_54, &clk_stm32_gate_ops, 0), +}; + +static struct clk_stm32_gate ck_ker_eth1ptp = { + .gate_id = GATE_ETH1, + .hw.init = CLK_HW_INIT_INDEX("ck_ker_eth1ptp", FLEXGEN_56, &clk_stm32_gate_ops, 0), +}; + +static struct clk_stm32_gate ck_ker_eth1mac = { + .gate_id = GATE_ETH1MAC, + .hw.init = CLK_HW_INIT_INDEX("ck_ker_eth1mac", ICN_LS_MCU, &clk_stm32_gate_ops, 0), +}; + +static struct clk_stm32_gate ck_ker_eth1tx = { + .gate_id = GATE_ETH1TX, + .hw.init = CLK_HW_INIT_INDEX("ck_ker_eth1tx", ICN_LS_MCU, &clk_stm32_gate_ops, 0), +}; + +static struct clk_stm32_gate ck_ker_eth1rx = { + .gate_id = GATE_ETH1RX, + .hw.init = CLK_HW_INIT_INDEX("ck_ker_eth1rx", ICN_LS_MCU, &clk_stm32_gate_ops, 0), +}; + +static struct clk_stm32_gate ck_icn_p_eth2 = { + .gate_id = GATE_ETH2, + .hw.init = CLK_HW_INIT_INDEX("ck_icn_p_eth2", ICN_LS_MCU, &clk_stm32_gate_ops, 0), +}; + +static struct clk_stm32_gate ck_ker_eth2stp = { + .gate_id = GATE_ETH2STP, + .hw.init = CLK_HW_INIT_INDEX("ck_ker_eth2stp", ICN_LS_MCU, &clk_stm32_gate_ops, 0), +}; + +static struct clk_stm32_gate ck_ker_eth2 = { + .gate_id = GATE_ETH2, + .hw.init = CLK_HW_INIT_INDEX("ck_ker_eth2", FLEXGEN_55, &clk_stm32_gate_ops, 0), +}; + +static struct clk_stm32_gate ck_ker_eth2ptp = { + .gate_id = GATE_ETH2, + .hw.init = CLK_HW_INIT_INDEX("ck_ker_eth2ptp", FLEXGEN_56, &clk_stm32_gate_ops, 0), +}; + +static struct clk_stm32_gate ck_ker_eth2mac = { + .gate_id = GATE_ETH2MAC, + .hw.init = CLK_HW_INIT_INDEX("ck_ker_eth2mac", ICN_LS_MCU, &clk_stm32_gate_ops, 0), +}; + +static struct clk_stm32_gate ck_ker_eth2tx = { + .gate_id = GATE_ETH2TX, + .hw.init = CLK_HW_INIT_INDEX("ck_ker_eth2tx", ICN_LS_MCU, &clk_stm32_gate_ops, 0), +}; + +static struct clk_stm32_gate ck_ker_eth2rx = { + .gate_id = GATE_ETH2RX, + .hw.init = CLK_HW_INIT_INDEX("ck_ker_eth2rx", ICN_LS_MCU, &clk_stm32_gate_ops, 0), +}; + +/* FDCAN */ +static struct clk_stm32_gate ck_icn_p_fdcan = { + .gate_id = GATE_FDCAN, + .hw.init = CLK_HW_INIT_INDEX("ck_icn_p_fdcan", ICN_APB2, &clk_stm32_gate_ops, 0), +}; + +static struct clk_stm32_gate ck_ker_fdcan = { + .gate_id = GATE_FDCAN, + .hw.init = CLK_HW_INIT_INDEX("ck_ker_fdcan", FLEXGEN_26, &clk_stm32_gate_ops, 0), +}; + +/* HASH */ +static struct clk_stm32_gate ck_icn_p_hash1 = { + .gate_id = GATE_HASH1, + .hw.init = CLK_HW_INIT_INDEX("ck_icn_p_hash1", ICN_LS_MCU, &clk_stm32_gate_ops, 0), +}; + +static struct clk_stm32_gate ck_icn_p_hash2 = { + .gate_id = GATE_HASH2, + .hw.init = CLK_HW_INIT_INDEX("ck_icn_p_hash2", ICN_LS_MCU, &clk_stm32_gate_ops, 0), +}; + +/* HDP */ +static struct clk_stm32_gate ck_icn_p_hdp = { + .gate_id = GATE_HDP, + .hw.init = CLK_HW_INIT_INDEX("ck_icn_p_hdp", ICN_APB3, &clk_stm32_gate_ops, 0), +}; + +/* I2C */ +static struct clk_stm32_gate ck_icn_p_i2c1 = { + .gate_id = GATE_I2C1, + .hw.init = CLK_HW_INIT_INDEX("ck_icn_p_i2c1", ICN_APB1, &clk_stm32_gate_ops, 0), +}; + +static struct clk_stm32_gate ck_icn_p_i2c2 = { + .gate_id = GATE_I2C2, + .hw.init = CLK_HW_INIT_INDEX("ck_icn_p_i2c2", ICN_APB1, &clk_stm32_gate_ops, 0), +}; + +static struct clk_stm32_gate ck_icn_p_i2c3 = { + .gate_id = GATE_I2C3, + .hw.init = CLK_HW_INIT_INDEX("ck_icn_p_i2c3", ICN_APB5, &clk_stm32_gate_ops, 0), +}; + +static struct clk_stm32_gate ck_ker_i2c1 = { + .gate_id = GATE_I2C1, + .hw.init = CLK_HW_INIT_INDEX("ck_ker_i2c1", FLEXGEN_13, &clk_stm32_gate_ops, 0), +}; + +static struct clk_stm32_gate ck_ker_i2c2 = { + .gate_id = GATE_I2C2, + .hw.init = CLK_HW_INIT_INDEX("ck_ker_i2c2", FLEXGEN_13, &clk_stm32_gate_ops, 0), +}; + +static struct clk_stm32_gate ck_ker_i2c3 = { + .gate_id = GATE_I2C3, + .hw.init = CLK_HW_INIT_INDEX("ck_ker_i2c3", FLEXGEN_38, &clk_stm32_gate_ops, 0), +}; + +/* I3C */ +static struct clk_stm32_gate ck_icn_p_i3c1 = { + .gate_id = GATE_I3C1, + .hw.init = CLK_HW_INIT_INDEX("ck_icn_p_i3c1", ICN_APB1, &clk_stm32_gate_ops, 0), +}; + +static struct clk_stm32_gate ck_icn_p_i3c2 = { + .gate_id = GATE_I3C2, + .hw.init = CLK_HW_INIT_INDEX("ck_icn_p_i3c2", ICN_APB1, &clk_stm32_gate_ops, 0), +}; + +static struct clk_stm32_gate ck_icn_p_i3c3 = { + .gate_id = GATE_I3C3, + .hw.init = CLK_HW_INIT_INDEX("ck_icn_p_i3c3", ICN_APB5, &clk_stm32_gate_ops, 0), +}; + +static struct clk_stm32_gate ck_ker_i3c1 = { + .gate_id = GATE_I3C1, + .hw.init = CLK_HW_INIT_INDEX("ck_ker_i3c1", FLEXGEN_14, &clk_stm32_gate_ops, 0), +}; + +static struct clk_stm32_gate ck_ker_i3c2 = { + .gate_id = GATE_I3C2, + .hw.init = CLK_HW_INIT_INDEX("ck_ker_i3c2", FLEXGEN_14, &clk_stm32_gate_ops, 0), +}; + +static struct clk_stm32_gate ck_ker_i3c3 = { + .gate_id = GATE_I3C3, + .hw.init = CLK_HW_INIT_INDEX("ck_ker_i3c3", FLEXGEN_36, &clk_stm32_gate_ops, 0), +}; + +/* IWDG */ +static struct clk_stm32_gate ck_icn_p_iwdg1 = { + .gate_id = GATE_IWDG1, + .hw.init = CLK_HW_INIT_INDEX("ck_icn_p_iwdg1", ICN_APB3, &clk_stm32_gate_ops, 0), +}; + +static struct clk_stm32_gate ck_icn_p_iwdg2 = { + .gate_id = GATE_IWDG2, + .hw.init = CLK_HW_INIT_INDEX("ck_icn_p_iwdg2", ICN_APB3, &clk_stm32_gate_ops, 0), +}; + +static struct clk_stm32_gate ck_icn_p_iwdg3 = { + .gate_id = GATE_IWDG3, + .hw.init = CLK_HW_INIT_INDEX("ck_icn_p_iwdg3", ICN_APB3, &clk_stm32_gate_ops, 0), +}; + +static struct clk_stm32_gate ck_icn_p_iwdg4 = { + .gate_id = GATE_IWDG4, + .hw.init = CLK_HW_INIT_INDEX("ck_icn_p_iwdg4", ICN_APB3, &clk_stm32_gate_ops, 0), +}; + +/* LPTIM */ +static struct clk_stm32_gate ck_icn_p_lptim1 = { + .gate_id = GATE_LPTIM1, + .hw.init = CLK_HW_INIT_INDEX("ck_icn_p_lptim1", ICN_APB1, &clk_stm32_gate_ops, 0), +}; + +static struct clk_stm32_gate ck_icn_p_lptim2 = { + .gate_id = GATE_LPTIM2, + .hw.init = CLK_HW_INIT_INDEX("ck_icn_p_lptim2", ICN_APB1, &clk_stm32_gate_ops, 0), +}; + +static struct clk_stm32_gate ck_icn_p_lptim3 = { + .gate_id = GATE_LPTIM3, + .hw.init = CLK_HW_INIT_INDEX("ck_icn_p_lptim3", ICN_LS_MCU, &clk_stm32_gate_ops, 0), +}; + +static struct clk_stm32_gate ck_icn_p_lptim4 = { + .gate_id = GATE_LPTIM4, + .hw.init = CLK_HW_INIT_INDEX("ck_icn_p_lptim4", ICN_LS_MCU, &clk_stm32_gate_ops, 0), +}; + +static struct clk_stm32_gate ck_icn_p_lptim5 = { + .gate_id = GATE_LPTIM5, + .hw.init = CLK_HW_INIT_INDEX("ck_icn_p_lptim5", ICN_LS_MCU, &clk_stm32_gate_ops, 0), +}; + +static struct clk_stm32_gate ck_ker_lptim1 = { + .gate_id = GATE_LPTIM1, + .hw.init = CLK_HW_INIT_INDEX("ck_ker_lptim1", FLEXGEN_07, &clk_stm32_gate_ops, 0), +}; + +static struct clk_stm32_gate ck_ker_lptim2 = { + .gate_id = GATE_LPTIM2, + .hw.init = CLK_HW_INIT_INDEX("ck_ker_lptim2", FLEXGEN_07, &clk_stm32_gate_ops, 0), +}; + +static struct clk_stm32_gate ck_ker_lptim3 = { + .gate_id = GATE_LPTIM3, + .hw.init = CLK_HW_INIT_INDEX("ck_ker_lptim3", FLEXGEN_40, &clk_stm32_gate_ops, 0), +}; + +static struct clk_stm32_gate ck_ker_lptim4 = { + .gate_id = GATE_LPTIM4, + .hw.init = CLK_HW_INIT_INDEX("ck_ker_lptim4", FLEXGEN_41, &clk_stm32_gate_ops, 0), +}; + +static struct clk_stm32_gate ck_ker_lptim5 = { + .gate_id = GATE_LPTIM5, + .hw.init = CLK_HW_INIT_INDEX("ck_ker_lptim5", FLEXGEN_42, &clk_stm32_gate_ops, 0), +}; + +/* LPUART */ +static struct clk_stm32_gate ck_icn_p_lpuart1 = { + .gate_id = GATE_LPUART1, + .hw.init = CLK_HW_INIT_INDEX("ck_icn_p_lpuart1", ICN_LS_MCU, &clk_stm32_gate_ops, 0), +}; + +static struct clk_stm32_gate ck_ker_lpuart1 = { + .gate_id = GATE_LPUART1, + .hw.init = CLK_HW_INIT_INDEX("ck_ker_lpuart1", FLEXGEN_39, &clk_stm32_gate_ops, 0), +}; + +/* MCO1 & MCO2 */ +static struct clk_stm32_composite ck_mco1 = { + .gate_id = GATE_MCO1, + .mux_id = MUX_MCO1, + .div_id = NO_STM32_DIV, + .hw.init = CLK_HW_INIT_PARENTS_DATA("ck_mco1", mco1_src, &clk_stm32_composite_ops, 0), +}; + +static struct clk_stm32_composite ck_mco2 = { + .gate_id = GATE_MCO2, + .mux_id = MUX_MCO2, + .div_id = NO_STM32_DIV, + .hw.init = CLK_HW_INIT_PARENTS_DATA("ck_mco2", mco2_src, &clk_stm32_composite_ops, 0), +}; + +/* MDF */ +static struct clk_stm32_gate ck_icn_p_mdf1 = { + .gate_id = GATE_MDF1, + .hw.init = CLK_HW_INIT_INDEX("ck_icn_p_mdf1", ICN_LS_MCU, &clk_stm32_gate_ops, 0), +}; + +static struct clk_stm32_gate ck_ker_mdf1 = { + .gate_id = GATE_MDF1, + .hw.init = CLK_HW_INIT_INDEX("ck_ker_mdf1", FLEXGEN_21, &clk_stm32_gate_ops, 0), +}; + +/* OTG */ +static struct clk_stm32_gate ck_icn_m_otg = { + .gate_id = GATE_OTG, + .hw.init = CLK_HW_INIT_INDEX("ck_icn_m_otg", ICN_LS_MCU, &clk_stm32_gate_ops, 0), +}; + +/* PKA */ +static struct clk_stm32_gate ck_icn_p_pka = { + .gate_id = GATE_PKA, + .hw.init = CLK_HW_INIT_INDEX("ck_icn_p_pka", ICN_LS_MCU, &clk_stm32_gate_ops, 0), +}; + +/* RNG */ +static struct clk_stm32_gate ck_icn_p_rng1 = { + .gate_id = GATE_RNG1, + .hw.init = CLK_HW_INIT_INDEX("ck_icn_p_rng1", ICN_LS_MCU, &clk_stm32_gate_ops, 0), +}; + +static struct clk_stm32_gate ck_icn_p_rng2 = { + .gate_id = GATE_RNG2, + .hw.init = CLK_HW_INIT_INDEX("ck_icn_p_rng2", ICN_LS_MCU, &clk_stm32_gate_ops, 0), +}; + +/* SAES */ +static struct clk_stm32_gate ck_icn_p_saes = { + .gate_id = GATE_SAES, + .hw.init = CLK_HW_INIT_INDEX("ck_icn_p_saes", ICN_LS_MCU, &clk_stm32_gate_ops, 0), +}; + +/* SAI */ +static struct clk_stm32_gate ck_icn_p_sai1 = { + .gate_id = GATE_SAI1, + .hw.init = CLK_HW_INIT_INDEX("ck_icn_p_sai1", ICN_APB2, &clk_stm32_gate_ops, 0), +}; + +static struct clk_stm32_gate ck_icn_p_sai2 = { + .gate_id = GATE_SAI2, + .hw.init = CLK_HW_INIT_INDEX("ck_icn_p_sai2", ICN_APB2, &clk_stm32_gate_ops, 0), +}; + +static struct clk_stm32_gate ck_icn_p_sai3 = { + .gate_id = GATE_SAI3, + .hw.init = CLK_HW_INIT_INDEX("ck_icn_p_sai3", ICN_APB2, &clk_stm32_gate_ops, 0), +}; + +static struct clk_stm32_gate ck_icn_p_sai4 = { + .gate_id = GATE_SAI4, + .hw.init = CLK_HW_INIT_INDEX("ck_icn_p_sai4", ICN_APB2, &clk_stm32_gate_ops, 0), +}; + +static struct clk_stm32_gate ck_ker_sai1 = { + .gate_id = GATE_SAI1, + .hw.init = CLK_HW_INIT_INDEX("ck_ker_sai1", FLEXGEN_22, &clk_stm32_gate_ops, + CLK_SET_RATE_PARENT), +}; + +static struct clk_stm32_gate ck_ker_sai2 = { + .gate_id = GATE_SAI2, + .hw.init = CLK_HW_INIT_INDEX("ck_ker_sai2", FLEXGEN_23, &clk_stm32_gate_ops, + CLK_SET_RATE_PARENT), +}; + +static struct clk_stm32_gate ck_ker_sai3 = { + .gate_id = GATE_SAI3, + .hw.init = CLK_HW_INIT_INDEX("ck_ker_sai3", FLEXGEN_24, &clk_stm32_gate_ops, + CLK_SET_RATE_PARENT), +}; + +static struct clk_stm32_gate ck_ker_sai4 = { + .gate_id = GATE_SAI4, + .hw.init = CLK_HW_INIT_INDEX("ck_ker_sai4", FLEXGEN_25, &clk_stm32_gate_ops, + CLK_SET_RATE_PARENT), +}; + +/* SDMMC */ +static struct clk_stm32_gate ck_icn_m_sdmmc1 = { + .gate_id = GATE_SDMMC1, + .hw.init = CLK_HW_INIT_INDEX("ck_icn_m_sdmmc1", ICN_SDMMC, &clk_stm32_gate_ops, 0), +}; + +static struct clk_stm32_gate ck_icn_m_sdmmc2 = { + .gate_id = GATE_SDMMC2, + .hw.init = CLK_HW_INIT_INDEX("ck_icn_m_sdmmc2", ICN_SDMMC, &clk_stm32_gate_ops, 0), +}; + +static struct clk_stm32_gate ck_icn_m_sdmmc3 = { + .gate_id = GATE_SDMMC3, + .hw.init = CLK_HW_INIT_INDEX("ck_icn_m_sdmmc3", ICN_SDMMC, &clk_stm32_gate_ops, 0), +}; + +static struct clk_stm32_gate ck_ker_sdmmc1 = { + .gate_id = GATE_SDMMC1, + .hw.init = CLK_HW_INIT_INDEX("ck_ker_sdmmc1", FLEXGEN_51, &clk_stm32_gate_ops, 0), +}; + +static struct clk_stm32_gate ck_ker_sdmmc2 = { + .gate_id = GATE_SDMMC2, + .hw.init = CLK_HW_INIT_INDEX("ck_ker_sdmmc2", FLEXGEN_52, &clk_stm32_gate_ops, 0), +}; + +static struct clk_stm32_gate ck_ker_sdmmc3 = { + .gate_id = GATE_SDMMC3, + .hw.init = CLK_HW_INIT_INDEX("ck_ker_sdmmc3", FLEXGEN_53, &clk_stm32_gate_ops, 0), +}; + +/* SERC */ +static struct clk_stm32_gate ck_icn_p_serc = { + .gate_id = GATE_SERC, + .hw.init = CLK_HW_INIT_INDEX("ck_icn_p_serc", ICN_APB3, &clk_stm32_gate_ops, 0), +}; + +/* SPDIF */ +static struct clk_stm32_gate ck_icn_p_spdifrx = { + .gate_id = GATE_SPDIFRX, + .hw.init = CLK_HW_INIT_INDEX("ck_icn_p_spdifrx", ICN_APB1, &clk_stm32_gate_ops, 0), +}; + +static struct clk_stm32_gate ck_ker_spdifrx = { + .gate_id = GATE_SPDIFRX, + .hw.init = CLK_HW_INIT_INDEX("ck_ker_spdifrx", FLEXGEN_12, &clk_stm32_gate_ops, 0), +}; + +/* SPI */ +static struct clk_stm32_gate ck_icn_p_spi1 = { + .gate_id = GATE_SPI1, + .hw.init = CLK_HW_INIT_INDEX("ck_icn_p_spi1", ICN_APB2, &clk_stm32_gate_ops, 0), +}; + +static struct clk_stm32_gate ck_icn_p_spi2 = { + .gate_id = GATE_SPI2, + .hw.init = CLK_HW_INIT_INDEX("ck_icn_p_spi2", ICN_APB1, &clk_stm32_gate_ops, 0), +}; + +static struct clk_stm32_gate ck_icn_p_spi3 = { + .gate_id = GATE_SPI3, + .hw.init = CLK_HW_INIT_INDEX("ck_icn_p_spi3", ICN_APB1, &clk_stm32_gate_ops, 0), +}; + +static struct clk_stm32_gate ck_icn_p_spi4 = { + .gate_id = GATE_SPI4, + .hw.init = CLK_HW_INIT_INDEX("ck_icn_p_spi4", ICN_APB2, &clk_stm32_gate_ops, 0), +}; + +static struct clk_stm32_gate ck_icn_p_spi5 = { + .gate_id = GATE_SPI5, + .hw.init = CLK_HW_INIT_INDEX("ck_icn_p_spi5", ICN_APB2, &clk_stm32_gate_ops, 0), +}; + +static struct clk_stm32_gate ck_icn_p_spi6 = { + .gate_id = GATE_SPI6, + .hw.init = CLK_HW_INIT_INDEX("ck_icn_p_spi6", ICN_APB2, &clk_stm32_gate_ops, 0), +}; + +static struct clk_stm32_gate ck_ker_spi1 = { + .gate_id = GATE_SPI1, + .hw.init = CLK_HW_INIT_INDEX("ck_ker_spi1", FLEXGEN_16, &clk_stm32_gate_ops, + CLK_SET_RATE_PARENT), +}; + +static struct clk_stm32_gate ck_ker_spi2 = { + .gate_id = GATE_SPI2, + .hw.init = CLK_HW_INIT_INDEX("ck_ker_spi2", FLEXGEN_10, &clk_stm32_gate_ops, + CLK_SET_RATE_PARENT), +}; + +static struct clk_stm32_gate ck_ker_spi3 = { + .gate_id = GATE_SPI3, + .hw.init = CLK_HW_INIT_INDEX("ck_ker_spi3", FLEXGEN_11, &clk_stm32_gate_ops, + CLK_SET_RATE_PARENT), +}; + +static struct clk_stm32_gate ck_ker_spi4 = { + .gate_id = GATE_SPI4, + .hw.init = CLK_HW_INIT_INDEX("ck_ker_spi4", FLEXGEN_17, &clk_stm32_gate_ops, 0), +}; + +static struct clk_stm32_gate ck_ker_spi5 = { + .gate_id = GATE_SPI5, + .hw.init = CLK_HW_INIT_INDEX("ck_ker_spi5", FLEXGEN_17, &clk_stm32_gate_ops, 0), +}; + +static struct clk_stm32_gate ck_ker_spi6 = { + .gate_id = GATE_SPI6, + .hw.init = CLK_HW_INIT_INDEX("ck_ker_spi6", FLEXGEN_37, &clk_stm32_gate_ops, 0), +}; + +/* Timers */ +static struct clk_stm32_gate ck_icn_p_tim2 = { + .gate_id = GATE_TIM2, + .hw.init = CLK_HW_INIT_INDEX("ck_icn_p_tim2", ICN_APB1, &clk_stm32_gate_ops, 0), +}; + +static struct clk_stm32_gate ck_icn_p_tim3 = { + .gate_id = GATE_TIM3, + .hw.init = CLK_HW_INIT_INDEX("ck_icn_p_tim3", ICN_APB1, &clk_stm32_gate_ops, 0), +}; + +static struct clk_stm32_gate ck_icn_p_tim4 = { + .gate_id = GATE_TIM4, + .hw.init = CLK_HW_INIT_INDEX("ck_icn_p_tim4", ICN_APB1, &clk_stm32_gate_ops, 0), +}; + +static struct clk_stm32_gate ck_icn_p_tim5 = { + .gate_id = GATE_TIM5, + .hw.init = CLK_HW_INIT_INDEX("ck_icn_p_tim5", ICN_APB1, &clk_stm32_gate_ops, 0), +}; + +static struct clk_stm32_gate ck_icn_p_tim6 = { + .gate_id = GATE_TIM6, + .hw.init = CLK_HW_INIT_INDEX("ck_icn_p_tim6", ICN_APB1, &clk_stm32_gate_ops, 0), +}; + +static struct clk_stm32_gate ck_icn_p_tim7 = { + .gate_id = GATE_TIM7, + .hw.init = CLK_HW_INIT_INDEX("ck_icn_p_tim7", ICN_APB1, &clk_stm32_gate_ops, 0), +}; + +static struct clk_stm32_gate ck_icn_p_tim10 = { + .gate_id = GATE_TIM10, + .hw.init = CLK_HW_INIT_INDEX("ck_icn_p_tim10", ICN_APB1, &clk_stm32_gate_ops, 0), +}; + +static struct clk_stm32_gate ck_icn_p_tim11 = { + .gate_id = GATE_TIM11, + .hw.init = CLK_HW_INIT_INDEX("ck_icn_p_tim11", ICN_APB1, &clk_stm32_gate_ops, 0), +}; + +static struct clk_stm32_gate ck_icn_p_tim12 = { + .gate_id = GATE_TIM12, + .hw.init = CLK_HW_INIT_INDEX("ck_icn_p_tim12", ICN_APB1, &clk_stm32_gate_ops, 0), +}; + +static struct clk_stm32_gate ck_icn_p_tim13 = { + .gate_id = GATE_TIM13, + .hw.init = CLK_HW_INIT_INDEX("ck_icn_p_tim13", ICN_APB1, &clk_stm32_gate_ops, 0), +}; + +static struct clk_stm32_gate ck_icn_p_tim14 = { + .gate_id = GATE_TIM14, + .hw.init = CLK_HW_INIT_INDEX("ck_icn_p_tim14", ICN_APB1, &clk_stm32_gate_ops, 0), +}; + +static struct clk_stm32_gate ck_icn_p_tim1 = { + .gate_id = GATE_TIM1, + .hw.init = CLK_HW_INIT_INDEX("ck_icn_p_tim1", ICN_APB2, &clk_stm32_gate_ops, 0), +}; + +static struct clk_stm32_gate ck_icn_p_tim8 = { + .gate_id = GATE_TIM8, + .hw.init = CLK_HW_INIT_INDEX("ck_icn_p_tim8", ICN_APB2, &clk_stm32_gate_ops, 0), +}; + +static struct clk_stm32_gate ck_icn_p_tim15 = { + .gate_id = GATE_TIM15, + .hw.init = CLK_HW_INIT_INDEX("ck_icn_p_tim15", ICN_APB2, &clk_stm32_gate_ops, 0), +}; + +static struct clk_stm32_gate ck_icn_p_tim16 = { + .gate_id = GATE_TIM16, + .hw.init = CLK_HW_INIT_INDEX("ck_icn_p_tim16", ICN_APB2, &clk_stm32_gate_ops, 0), +}; + +static struct clk_stm32_gate ck_icn_p_tim17 = { + .gate_id = GATE_TIM17, + .hw.init = CLK_HW_INIT_INDEX("ck_icn_p_tim17", ICN_APB2, &clk_stm32_gate_ops, 0), +}; + +static struct clk_stm32_gate ck_ker_tim2 = { + .gate_id = GATE_TIM2, + .hw.init = CLK_HW_INIT_INDEX("ck_ker_tim2", TIMG1, &clk_stm32_gate_ops, 0), +}; + +static struct clk_stm32_gate ck_ker_tim3 = { + .gate_id = GATE_TIM3, + .hw.init = CLK_HW_INIT_INDEX("ck_ker_tim3", TIMG1, &clk_stm32_gate_ops, 0), +}; + +static struct clk_stm32_gate ck_ker_tim4 = { + .gate_id = GATE_TIM4, + .hw.init = CLK_HW_INIT_INDEX("ck_ker_tim4", TIMG1, &clk_stm32_gate_ops, 0), +}; + +static struct clk_stm32_gate ck_ker_tim5 = { + .gate_id = GATE_TIM5, + .hw.init = CLK_HW_INIT_INDEX("ck_ker_tim5", TIMG1, &clk_stm32_gate_ops, 0), +}; + +static struct clk_stm32_gate ck_ker_tim6 = { + .gate_id = GATE_TIM6, + .hw.init = CLK_HW_INIT_INDEX("ck_ker_tim6", TIMG1, &clk_stm32_gate_ops, 0), +}; + +static struct clk_stm32_gate ck_ker_tim7 = { + .gate_id = GATE_TIM7, + .hw.init = CLK_HW_INIT_INDEX("ck_ker_tim7", TIMG1, &clk_stm32_gate_ops, 0), +}; + +static struct clk_stm32_gate ck_ker_tim10 = { + .gate_id = GATE_TIM10, + .hw.init = CLK_HW_INIT_INDEX("ck_ker_tim10", TIMG1, &clk_stm32_gate_ops, 0), +}; + +static struct clk_stm32_gate ck_ker_tim11 = { + .gate_id = GATE_TIM11, + .hw.init = CLK_HW_INIT_INDEX("ck_ker_tim11", TIMG1, &clk_stm32_gate_ops, 0), +}; + +static struct clk_stm32_gate ck_ker_tim12 = { + .gate_id = GATE_TIM12, + .hw.init = CLK_HW_INIT_INDEX("ck_ker_tim12", TIMG1, &clk_stm32_gate_ops, 0), +}; + +static struct clk_stm32_gate ck_ker_tim13 = { + .gate_id = GATE_TIM13, + .hw.init = CLK_HW_INIT_INDEX("ck_ker_tim13", TIMG1, &clk_stm32_gate_ops, 0), +}; + +static struct clk_stm32_gate ck_ker_tim14 = { + .gate_id = GATE_TIM14, + .hw.init = CLK_HW_INIT_INDEX("ck_ker_tim14", TIMG1, &clk_stm32_gate_ops, 0), +}; + +static struct clk_stm32_gate ck_ker_tim1 = { + .gate_id = GATE_TIM1, + .hw.init = CLK_HW_INIT_INDEX("ck_ker_tim1", TIMG2, &clk_stm32_gate_ops, 0), +}; + +static struct clk_stm32_gate ck_ker_tim8 = { + .gate_id = GATE_TIM8, + .hw.init = CLK_HW_INIT_INDEX("ck_ker_tim8", TIMG2, &clk_stm32_gate_ops, 0), +}; + +static struct clk_stm32_gate ck_ker_tim15 = { + .gate_id = GATE_TIM15, + .hw.init = CLK_HW_INIT_INDEX("ck_ker_tim15", TIMG2, &clk_stm32_gate_ops, 0), +}; + +static struct clk_stm32_gate ck_ker_tim16 = { + .gate_id = GATE_TIM16, + .hw.init = CLK_HW_INIT_INDEX("ck_ker_tim16", TIMG2, &clk_stm32_gate_ops, 0), +}; + +static struct clk_stm32_gate ck_ker_tim17 = { + .gate_id = GATE_TIM17, + .hw.init = CLK_HW_INIT_INDEX("ck_ker_tim17", TIMG2, &clk_stm32_gate_ops, 0), +}; + +/* UART/USART */ +static struct clk_stm32_gate ck_icn_p_usart2 = { + .gate_id = GATE_USART2, + .hw.init = CLK_HW_INIT_INDEX("ck_icn_p_usart2", ICN_APB1, &clk_stm32_gate_ops, 0), +}; + +static struct clk_stm32_gate ck_icn_p_usart3 = { + .gate_id = GATE_USART3, + .hw.init = CLK_HW_INIT_INDEX("ck_icn_p_usart3", ICN_APB1, &clk_stm32_gate_ops, 0), +}; + +static struct clk_stm32_gate ck_icn_p_uart4 = { + .gate_id = GATE_UART4, + .hw.init = CLK_HW_INIT_INDEX("ck_icn_p_uart4", ICN_APB1, &clk_stm32_gate_ops, 0), +}; + +static struct clk_stm32_gate ck_icn_p_uart5 = { + .gate_id = GATE_UART5, + .hw.init = CLK_HW_INIT_INDEX("ck_icn_p_uart5", ICN_APB1, &clk_stm32_gate_ops, 0), +}; + +static struct clk_stm32_gate ck_icn_p_usart1 = { + .gate_id = GATE_USART1, + .hw.init = CLK_HW_INIT_INDEX("ck_icn_p_usart1", ICN_APB2, &clk_stm32_gate_ops, 0), +}; + +static struct clk_stm32_gate ck_icn_p_usart6 = { + .gate_id = GATE_USART6, + .hw.init = CLK_HW_INIT_INDEX("ck_icn_p_usart6", ICN_APB2, &clk_stm32_gate_ops, 0), +}; + +static struct clk_stm32_gate ck_icn_p_uart7 = { + .gate_id = GATE_UART7, + .hw.init = CLK_HW_INIT_INDEX("ck_icn_p_uart7", ICN_APB2, &clk_stm32_gate_ops, 0), +}; + +static struct clk_stm32_gate ck_ker_usart2 = { + .gate_id = GATE_USART2, + .hw.init = CLK_HW_INIT_INDEX("ck_ker_usart2", FLEXGEN_08, &clk_stm32_gate_ops, 0), +}; + +static struct clk_stm32_gate ck_ker_uart4 = { + .gate_id = GATE_UART4, + .hw.init = CLK_HW_INIT_INDEX("ck_ker_uart4", FLEXGEN_08, &clk_stm32_gate_ops, 0), +}; + +static struct clk_stm32_gate ck_ker_usart3 = { + .gate_id = GATE_USART3, + .hw.init = CLK_HW_INIT_INDEX("ck_ker_usart3", FLEXGEN_09, &clk_stm32_gate_ops, 0), +}; + +static struct clk_stm32_gate ck_ker_uart5 = { + .gate_id = GATE_UART5, + .hw.init = CLK_HW_INIT_INDEX("ck_ker_uart5", FLEXGEN_09, &clk_stm32_gate_ops, 0), +}; + +static struct clk_stm32_gate ck_ker_usart1 = { + .gate_id = GATE_USART1, + .hw.init = CLK_HW_INIT_INDEX("ck_ker_usart1", FLEXGEN_18, &clk_stm32_gate_ops, 0), +}; + +static struct clk_stm32_gate ck_ker_usart6 = { + .gate_id = GATE_USART6, + .hw.init = CLK_HW_INIT_INDEX("ck_ker_usart6", FLEXGEN_19, &clk_stm32_gate_ops, 0), +}; + +static struct clk_stm32_gate ck_ker_uart7 = { + .gate_id = GATE_UART7, + .hw.init = CLK_HW_INIT_INDEX("ck_ker_uart7", FLEXGEN_20, &clk_stm32_gate_ops, 0), +}; + +/* USB2PHY1 */ +static struct clk_stm32_composite ck_ker_usb2phy1 = { + .gate_id = GATE_USB2PHY1, + .mux_id = MUX_USB2PHY1, + .div_id = NO_STM32_DIV, + .hw.init = CLK_HW_INIT_PARENTS_DATA("ck_ker_usb2phy1", usb2phy1_src, + &clk_stm32_composite_ops, 0), +}; + +/* USBH */ +static struct clk_stm32_gate ck_icn_m_usbhehci = { + .gate_id = GATE_USBH, + .hw.init = CLK_HW_INIT_INDEX("ck_icn_m_usbhehci", ICN_HSL, &clk_stm32_gate_ops, 0), +}; + +static struct clk_stm32_gate ck_icn_m_usbhohci = { + .gate_id = GATE_USBH, + .hw.init = CLK_HW_INIT_INDEX("ck_icn_m_usbhohci", ICN_HSL, &clk_stm32_gate_ops, 0), +}; + +/* USB2PHY2 */ +static struct clk_stm32_composite ck_ker_usb2phy2_en = { + .gate_id = GATE_USB2PHY2, + .mux_id = MUX_USB2PHY2, + .div_id = NO_STM32_DIV, + .hw.init = CLK_HW_INIT_PARENTS_DATA("ck_ker_usb2phy2_en", usb2phy2_src, + &clk_stm32_composite_ops, 0), +}; + +/* VREF */ +static struct clk_stm32_gate ck_icn_p_vref = { + .gate_id = GATE_VREF, + .hw.init = CLK_HW_INIT_INDEX("ck_icn_p_vref", ICN_APB3, &clk_stm32_gate_ops, 0), +}; + +/* WWDG */ +static struct clk_stm32_gate ck_icn_p_wwdg1 = { + .gate_id = GATE_WWDG1, + .hw.init = CLK_HW_INIT_INDEX("ck_icn_p_wwdg1", ICN_APB3, &clk_stm32_gate_ops, 0), +}; + +static int stm32_rcc_get_access(void __iomem *base, u32 index) +{ + u32 seccfgr, cidcfgr, semcr; + int bit, cid; + + bit = index % RCC_REG_SIZE; + + seccfgr = readl(base + RCC_SECCFGR(index)); + if (seccfgr & BIT(bit)) + return -EACCES; + + cidcfgr = readl(base + RCC_CIDCFGR(index)); + if (!(cidcfgr & RCC_CIDCFGR_CFEN)) + /* CID filtering is turned off: access granted */ + return 0; + + if (!(cidcfgr & RCC_CIDCFGR_SEM_EN)) { + /* Static CID mode */ + cid = FIELD_GET(RCC_CIDCFGR_SCID_MASK, cidcfgr); + if (cid != RCC_CID1) + return -EACCES; + return 0; + } + + /* Pass-list with semaphore mode */ + if (!(cidcfgr & RCC_CIDCFGR_SEMWLC1_EN)) + return -EACCES; + + semcr = readl(base + RCC_SEMCR(index)); + + cid = FIELD_GET(RCC_SEMCR_SEMCID_MASK, semcr); + if (cid != RCC_CID1) + return -EACCES; + + return 0; +} + +static int stm32mp21_check_security(struct device_node *np, void __iomem *base, + const struct clock_config *cfg) +{ + int ret = 0; + + if (cfg->sec_id != SECF_NONE) { + struct stm32_firewall firewall; + u32 index = (u32)cfg->sec_id; + + if (index & SEC_RIFSC_FLAG) { + ret = stm32_firewall_get_firewall(np, &firewall, 1); + if (ret) + return ret; + ret = stm32_firewall_grant_access_by_id(&firewall, index & ~SEC_RIFSC_FLAG); + } else { + ret = stm32_rcc_get_access(base, cfg->sec_id & ~SEC_RIFSC_FLAG); + } + } + + return ret; +} + +static const struct clock_config stm32mp21_clock_cfg[] = { + STM32_GATE_CFG(CK_BUS_ETH1, ck_icn_p_eth1, SEC_RIFSC(60)), + STM32_GATE_CFG(CK_BUS_ETH2, ck_icn_p_eth2, SEC_RIFSC(61)), + STM32_GATE_CFG(CK_BUS_ADC1, ck_icn_p_adc1, SEC_RIFSC(58)), + STM32_GATE_CFG(CK_BUS_ADC2, ck_icn_p_adc2, SEC_RIFSC(59)), + STM32_GATE_CFG(CK_BUS_CRC, ck_icn_p_crc, SEC_RIFSC(109)), + STM32_GATE_CFG(CK_BUS_MDF1, ck_icn_p_mdf1, SEC_RIFSC(54)), + STM32_GATE_CFG(CK_BUS_HASH1, ck_icn_p_hash1, SEC_RIFSC(96)), + STM32_GATE_CFG(CK_BUS_HASH2, ck_icn_p_hash2, SEC_RIFSC(97)), + STM32_GATE_CFG(CK_BUS_RNG1, ck_icn_p_rng1, SEC_RIFSC(92)), + STM32_GATE_CFG(CK_BUS_RNG2, ck_icn_p_rng2, SEC_RIFSC(93)), + STM32_GATE_CFG(CK_BUS_CRYP1, ck_icn_p_cryp1, SEC_RIFSC(98)), + STM32_GATE_CFG(CK_BUS_CRYP2, ck_icn_p_cryp2, SEC_RIFSC(99)), + STM32_GATE_CFG(CK_BUS_SAES, ck_icn_p_saes, SEC_RIFSC(95)), + STM32_GATE_CFG(CK_BUS_PKA, ck_icn_p_pka, SEC_RIFSC(94)), + STM32_GATE_CFG(CK_BUS_LPUART1, ck_icn_p_lpuart1, SEC_RIFSC(40)), + STM32_GATE_CFG(CK_BUS_LPTIM3, ck_icn_p_lptim3, SEC_RIFSC(19)), + STM32_GATE_CFG(CK_BUS_LPTIM4, ck_icn_p_lptim4, SEC_RIFSC(20)), + STM32_GATE_CFG(CK_BUS_LPTIM5, ck_icn_p_lptim5, SEC_RIFSC(21)), + STM32_GATE_CFG(CK_BUS_SDMMC1, ck_icn_m_sdmmc1, SEC_RIFSC(76)), + STM32_GATE_CFG(CK_BUS_SDMMC2, ck_icn_m_sdmmc2, SEC_RIFSC(77)), + STM32_GATE_CFG(CK_BUS_SDMMC3, ck_icn_m_sdmmc3, SEC_RIFSC(78)), + STM32_GATE_CFG(CK_BUS_USBHOHCI, ck_icn_m_usbhohci, SEC_RIFSC(63)), + STM32_GATE_CFG(CK_BUS_USBHEHCI, ck_icn_m_usbhehci, SEC_RIFSC(63)), + STM32_GATE_CFG(CK_BUS_OTG, ck_icn_m_otg, SEC_RIFSC(66)), + STM32_GATE_CFG(CK_BUS_TIM2, ck_icn_p_tim2, SEC_RIFSC(1)), + STM32_GATE_CFG(CK_BUS_TIM3, ck_icn_p_tim3, SEC_RIFSC(2)), + STM32_GATE_CFG(CK_BUS_TIM4, ck_icn_p_tim4, SEC_RIFSC(3)), + STM32_GATE_CFG(CK_BUS_TIM5, ck_icn_p_tim5, SEC_RIFSC(4)), + STM32_GATE_CFG(CK_BUS_TIM6, ck_icn_p_tim6, SEC_RIFSC(5)), + STM32_GATE_CFG(CK_BUS_TIM7, ck_icn_p_tim7, SEC_RIFSC(6)), + STM32_GATE_CFG(CK_BUS_TIM10, ck_icn_p_tim10, SEC_RIFSC(8)), + STM32_GATE_CFG(CK_BUS_TIM11, ck_icn_p_tim11, SEC_RIFSC(9)), + STM32_GATE_CFG(CK_BUS_TIM12, ck_icn_p_tim12, SEC_RIFSC(10)), + STM32_GATE_CFG(CK_BUS_TIM13, ck_icn_p_tim13, SEC_RIFSC(11)), + STM32_GATE_CFG(CK_BUS_TIM14, ck_icn_p_tim14, SEC_RIFSC(12)), + STM32_GATE_CFG(CK_BUS_LPTIM1, ck_icn_p_lptim1, SEC_RIFSC(17)), + STM32_GATE_CFG(CK_BUS_LPTIM2, ck_icn_p_lptim2, SEC_RIFSC(18)), + STM32_GATE_CFG(CK_BUS_SPI2, ck_icn_p_spi2, SEC_RIFSC(23)), + STM32_GATE_CFG(CK_BUS_SPI3, ck_icn_p_spi3, SEC_RIFSC(24)), + STM32_GATE_CFG(CK_BUS_SPDIFRX, ck_icn_p_spdifrx, SEC_RIFSC(30)), + STM32_GATE_CFG(CK_BUS_USART2, ck_icn_p_usart2, SEC_RIFSC(32)), + STM32_GATE_CFG(CK_BUS_USART3, ck_icn_p_usart3, SEC_RIFSC(33)), + STM32_GATE_CFG(CK_BUS_UART4, ck_icn_p_uart4, SEC_RIFSC(34)), + STM32_GATE_CFG(CK_BUS_UART5, ck_icn_p_uart5, SEC_RIFSC(35)), + STM32_GATE_CFG(CK_BUS_I2C1, ck_icn_p_i2c1, SEC_RIFSC(41)), + STM32_GATE_CFG(CK_BUS_I2C2, ck_icn_p_i2c2, SEC_RIFSC(42)), + STM32_GATE_CFG(CK_BUS_I2C3, ck_icn_p_i2c3, SEC_RIFSC(43)), + STM32_GATE_CFG(CK_BUS_I3C1, ck_icn_p_i3c1, SEC_RIFSC(114)), + STM32_GATE_CFG(CK_BUS_I3C2, ck_icn_p_i3c2, SEC_RIFSC(115)), + STM32_GATE_CFG(CK_BUS_I3C3, ck_icn_p_i3c3, SEC_RIFSC(116)), + STM32_GATE_CFG(CK_BUS_TIM1, ck_icn_p_tim1, SEC_RIFSC(0)), + STM32_GATE_CFG(CK_BUS_TIM8, ck_icn_p_tim8, SEC_RIFSC(7)), + STM32_GATE_CFG(CK_BUS_TIM15, ck_icn_p_tim15, SEC_RIFSC(13)), + STM32_GATE_CFG(CK_BUS_TIM16, ck_icn_p_tim16, SEC_RIFSC(14)), + STM32_GATE_CFG(CK_BUS_TIM17, ck_icn_p_tim17, SEC_RIFSC(15)), + STM32_GATE_CFG(CK_BUS_SAI1, ck_icn_p_sai1, SEC_RIFSC(49)), + STM32_GATE_CFG(CK_BUS_SAI2, ck_icn_p_sai2, SEC_RIFSC(50)), + STM32_GATE_CFG(CK_BUS_SAI3, ck_icn_p_sai3, SEC_RIFSC(51)), + STM32_GATE_CFG(CK_BUS_SAI4, ck_icn_p_sai4, SEC_RIFSC(52)), + STM32_GATE_CFG(CK_BUS_USART1, ck_icn_p_usart1, SEC_RIFSC(31)), + STM32_GATE_CFG(CK_BUS_USART6, ck_icn_p_usart6, SEC_RIFSC(36)), + STM32_GATE_CFG(CK_BUS_UART7, ck_icn_p_uart7, SEC_RIFSC(37)), + STM32_GATE_CFG(CK_BUS_FDCAN, ck_icn_p_fdcan, SEC_RIFSC(56)), + STM32_GATE_CFG(CK_BUS_SPI1, ck_icn_p_spi1, SEC_RIFSC(22)), + STM32_GATE_CFG(CK_BUS_SPI4, ck_icn_p_spi4, SEC_RIFSC(25)), + STM32_GATE_CFG(CK_BUS_SPI5, ck_icn_p_spi5, SEC_RIFSC(26)), + STM32_GATE_CFG(CK_BUS_SPI6, ck_icn_p_spi6, SEC_RIFSC(27)), + STM32_GATE_CFG(CK_BUS_IWDG1, ck_icn_p_iwdg1, SEC_RIFSC(100)), + STM32_GATE_CFG(CK_BUS_IWDG2, ck_icn_p_iwdg2, SEC_RIFSC(101)), + STM32_GATE_CFG(CK_BUS_IWDG3, ck_icn_p_iwdg3, SEC_RIFSC(102)), + STM32_GATE_CFG(CK_BUS_IWDG4, ck_icn_p_iwdg4, SEC_RIFSC(103)), + STM32_GATE_CFG(CK_BUS_WWDG1, ck_icn_p_wwdg1, SEC_RIFSC(104)), + STM32_GATE_CFG(CK_BUS_VREF, ck_icn_p_vref, SEC_RIFSC(106)), + STM32_GATE_CFG(CK_BUS_SERC, ck_icn_p_serc, SEC_RIFSC(110)), + STM32_GATE_CFG(CK_BUS_HDP, ck_icn_p_hdp, SEC_RIFSC(57)), + STM32_GATE_CFG(CK_BUS_LTDC, ck_icn_p_ltdc, SEC_RIFSC(80)), + STM32_GATE_CFG(CK_BUS_CSI, ck_icn_p_csi, SEC_RIFSC(86)), + STM32_GATE_CFG(CK_BUS_DCMIPP, ck_icn_p_dcmipp, SEC_RIFSC(87)), + STM32_GATE_CFG(CK_BUS_DCMIPSSI, ck_icn_p_dcmipssi, SEC_RIFSC(88)), + STM32_GATE_CFG(CK_BUS_DDRPERFM, ck_icn_p_ddrperfm, SEC_RIFSC(67)), + STM32_GATE_CFG(CK_KER_TIM2, ck_ker_tim2, SEC_RIFSC(1)), + STM32_GATE_CFG(CK_KER_TIM3, ck_ker_tim3, SEC_RIFSC(2)), + STM32_GATE_CFG(CK_KER_TIM4, ck_ker_tim4, SEC_RIFSC(3)), + STM32_GATE_CFG(CK_KER_TIM5, ck_ker_tim5, SEC_RIFSC(4)), + STM32_GATE_CFG(CK_KER_TIM6, ck_ker_tim6, SEC_RIFSC(5)), + STM32_GATE_CFG(CK_KER_TIM7, ck_ker_tim7, SEC_RIFSC(6)), + STM32_GATE_CFG(CK_KER_TIM10, ck_ker_tim10, SEC_RIFSC(8)), + STM32_GATE_CFG(CK_KER_TIM11, ck_ker_tim11, SEC_RIFSC(9)), + STM32_GATE_CFG(CK_KER_TIM12, ck_ker_tim12, SEC_RIFSC(10)), + STM32_GATE_CFG(CK_KER_TIM13, ck_ker_tim13, SEC_RIFSC(11)), + STM32_GATE_CFG(CK_KER_TIM14, ck_ker_tim14, SEC_RIFSC(12)), + STM32_GATE_CFG(CK_KER_TIM1, ck_ker_tim1, SEC_RIFSC(0)), + STM32_GATE_CFG(CK_KER_TIM8, ck_ker_tim8, SEC_RIFSC(7)), + STM32_GATE_CFG(CK_KER_TIM15, ck_ker_tim15, SEC_RIFSC(13)), + STM32_GATE_CFG(CK_KER_TIM16, ck_ker_tim16, SEC_RIFSC(14)), + STM32_GATE_CFG(CK_KER_TIM17, ck_ker_tim17, SEC_RIFSC(15)), + STM32_GATE_CFG(CK_KER_LPTIM1, ck_ker_lptim1, SEC_RIFSC(17)), + STM32_GATE_CFG(CK_KER_LPTIM2, ck_ker_lptim2, SEC_RIFSC(18)), + STM32_GATE_CFG(CK_KER_USART2, ck_ker_usart2, SEC_RIFSC(32)), + STM32_GATE_CFG(CK_KER_UART4, ck_ker_uart4, SEC_RIFSC(34)), + STM32_GATE_CFG(CK_KER_USART3, ck_ker_usart3, SEC_RIFSC(33)), + STM32_GATE_CFG(CK_KER_UART5, ck_ker_uart5, SEC_RIFSC(35)), + STM32_GATE_CFG(CK_KER_SPI2, ck_ker_spi2, SEC_RIFSC(23)), + STM32_GATE_CFG(CK_KER_SPI3, ck_ker_spi3, SEC_RIFSC(24)), + STM32_GATE_CFG(CK_KER_SPDIFRX, ck_ker_spdifrx, SEC_RIFSC(30)), + STM32_GATE_CFG(CK_KER_I2C1, ck_ker_i2c1, SEC_RIFSC(41)), + STM32_GATE_CFG(CK_KER_I2C2, ck_ker_i2c2, SEC_RIFSC(42)), + STM32_GATE_CFG(CK_KER_I3C1, ck_ker_i3c1, SEC_RIFSC(114)), + STM32_GATE_CFG(CK_KER_I3C2, ck_ker_i3c2, SEC_RIFSC(115)), + STM32_GATE_CFG(CK_KER_I2C3, ck_ker_i2c3, SEC_RIFSC(43)), + STM32_GATE_CFG(CK_KER_I3C3, ck_ker_i3c3, SEC_RIFSC(116)), + STM32_GATE_CFG(CK_KER_SPI1, ck_ker_spi1, SEC_RIFSC(22)), + STM32_GATE_CFG(CK_KER_SPI4, ck_ker_spi4, SEC_RIFSC(25)), + STM32_GATE_CFG(CK_KER_SPI5, ck_ker_spi5, SEC_RIFSC(26)), + STM32_GATE_CFG(CK_KER_SPI6, ck_ker_spi6, SEC_RIFSC(27)), + STM32_GATE_CFG(CK_KER_USART1, ck_ker_usart1, SEC_RIFSC(31)), + STM32_GATE_CFG(CK_KER_USART6, ck_ker_usart6, SEC_RIFSC(36)), + STM32_GATE_CFG(CK_KER_UART7, ck_ker_uart7, SEC_RIFSC(37)), + STM32_GATE_CFG(CK_KER_MDF1, ck_ker_mdf1, SEC_RIFSC(54)), + STM32_GATE_CFG(CK_KER_SAI1, ck_ker_sai1, SEC_RIFSC(49)), + STM32_GATE_CFG(CK_KER_SAI2, ck_ker_sai2, SEC_RIFSC(50)), + STM32_GATE_CFG(CK_KER_SAI3, ck_ker_sai3, SEC_RIFSC(51)), + STM32_GATE_CFG(CK_KER_SAI4, ck_ker_sai4, SEC_RIFSC(52)), + STM32_GATE_CFG(CK_KER_FDCAN, ck_ker_fdcan, SEC_RIFSC(56)), + STM32_GATE_CFG(CK_KER_CSI, ck_ker_csi, SEC_RIFSC(86)), + STM32_GATE_CFG(CK_KER_CSITXESC, ck_ker_csitxesc, SEC_RIFSC(86)), + STM32_GATE_CFG(CK_KER_CSIPHY, ck_ker_csiphy, SEC_RIFSC(86)), + STM32_GATE_CFG(CK_KER_LPUART1, ck_ker_lpuart1, SEC_RIFSC(40)), + STM32_GATE_CFG(CK_KER_LPTIM3, ck_ker_lptim3, SEC_RIFSC(19)), + STM32_GATE_CFG(CK_KER_LPTIM4, ck_ker_lptim4, SEC_RIFSC(20)), + STM32_GATE_CFG(CK_KER_LPTIM5, ck_ker_lptim5, SEC_RIFSC(21)), + STM32_GATE_CFG(CK_KER_SDMMC1, ck_ker_sdmmc1, SEC_RIFSC(76)), + STM32_GATE_CFG(CK_KER_SDMMC2, ck_ker_sdmmc2, SEC_RIFSC(77)), + STM32_GATE_CFG(CK_KER_SDMMC3, ck_ker_sdmmc3, SEC_RIFSC(78)), + STM32_GATE_CFG(CK_KER_ETH1, ck_ker_eth1, SEC_RIFSC(60)), + STM32_GATE_CFG(CK_ETH1_STP, ck_ker_eth1stp, SEC_RIFSC(60)), + STM32_GATE_CFG(CK_KER_ETH2, ck_ker_eth2, SEC_RIFSC(61)), + STM32_GATE_CFG(CK_ETH2_STP, ck_ker_eth2stp, SEC_RIFSC(61)), + STM32_GATE_CFG(CK_KER_ETH1PTP, ck_ker_eth1ptp, SEC_RIFSC(60)), + STM32_GATE_CFG(CK_KER_ETH2PTP, ck_ker_eth2ptp, SEC_RIFSC(61)), + STM32_GATE_CFG(CK_ETH1_MAC, ck_ker_eth1mac, SEC_RIFSC(60)), + STM32_GATE_CFG(CK_ETH1_TX, ck_ker_eth1tx, SEC_RIFSC(60)), + STM32_GATE_CFG(CK_ETH1_RX, ck_ker_eth1rx, SEC_RIFSC(60)), + STM32_GATE_CFG(CK_ETH2_MAC, ck_ker_eth2mac, SEC_RIFSC(61)), + STM32_GATE_CFG(CK_ETH2_TX, ck_ker_eth2tx, SEC_RIFSC(61)), + STM32_GATE_CFG(CK_ETH2_RX, ck_ker_eth2rx, SEC_RIFSC(61)), + STM32_COMPOSITE_CFG(CK_MCO1, ck_mco1, MP21_RIF_RCC_MCO1), + STM32_COMPOSITE_CFG(CK_MCO2, ck_mco2, MP21_RIF_RCC_MCO2), + STM32_COMPOSITE_CFG(CK_KER_ADC1, ck_ker_adc1, SEC_RIFSC(58)), + STM32_COMPOSITE_CFG(CK_KER_ADC2, ck_ker_adc2, SEC_RIFSC(59)), + STM32_COMPOSITE_CFG(CK_KER_USB2PHY1, ck_ker_usb2phy1, SEC_RIFSC(63)), + STM32_COMPOSITE_CFG(CK_KER_USB2PHY2EN, ck_ker_usb2phy2_en, SEC_RIFSC(66)), + STM32_COMPOSITE_CFG(CK_KER_DTS, ck_ker_dts, SEC_RIFSC(107)), + STM32_GATE_CFG(CK_KER_LTDC, ck_ker_ltdc, SEC_RIFSC(80)), +}; + +#define RESET_MP21(id, _offset, _bit_idx, _set_clr) \ + [id] = &(struct stm32_reset_cfg){ \ + .offset = (_offset), \ + .bit_idx = (_bit_idx), \ + .set_clr = (_set_clr), \ + } + +static const struct stm32_reset_cfg *stm32mp21_reset_cfg[] = { + RESET_MP21(TIM1_R, RCC_TIM1CFGR, 0, 0), + RESET_MP21(TIM2_R, RCC_TIM2CFGR, 0, 0), + RESET_MP21(TIM3_R, RCC_TIM3CFGR, 0, 0), + RESET_MP21(TIM4_R, RCC_TIM4CFGR, 0, 0), + RESET_MP21(TIM5_R, RCC_TIM5CFGR, 0, 0), + RESET_MP21(TIM6_R, RCC_TIM6CFGR, 0, 0), + RESET_MP21(TIM7_R, RCC_TIM7CFGR, 0, 0), + RESET_MP21(TIM8_R, RCC_TIM8CFGR, 0, 0), + RESET_MP21(TIM10_R, RCC_TIM10CFGR, 0, 0), + RESET_MP21(TIM11_R, RCC_TIM11CFGR, 0, 0), + RESET_MP21(TIM12_R, RCC_TIM12CFGR, 0, 0), + RESET_MP21(TIM13_R, RCC_TIM13CFGR, 0, 0), + RESET_MP21(TIM14_R, RCC_TIM14CFGR, 0, 0), + RESET_MP21(TIM15_R, RCC_TIM15CFGR, 0, 0), + RESET_MP21(TIM16_R, RCC_TIM16CFGR, 0, 0), + RESET_MP21(TIM17_R, RCC_TIM17CFGR, 0, 0), + RESET_MP21(LPTIM1_R, RCC_LPTIM1CFGR, 0, 0), + RESET_MP21(LPTIM2_R, RCC_LPTIM2CFGR, 0, 0), + RESET_MP21(LPTIM3_R, RCC_LPTIM3CFGR, 0, 0), + RESET_MP21(LPTIM4_R, RCC_LPTIM4CFGR, 0, 0), + RESET_MP21(LPTIM5_R, RCC_LPTIM5CFGR, 0, 0), + RESET_MP21(SPI1_R, RCC_SPI1CFGR, 0, 0), + RESET_MP21(SPI2_R, RCC_SPI2CFGR, 0, 0), + RESET_MP21(SPI3_R, RCC_SPI3CFGR, 0, 0), + RESET_MP21(SPI4_R, RCC_SPI4CFGR, 0, 0), + RESET_MP21(SPI5_R, RCC_SPI5CFGR, 0, 0), + RESET_MP21(SPI6_R, RCC_SPI6CFGR, 0, 0), + RESET_MP21(SPDIFRX_R, RCC_SPDIFRXCFGR, 0, 0), + RESET_MP21(USART1_R, RCC_USART1CFGR, 0, 0), + RESET_MP21(USART2_R, RCC_USART2CFGR, 0, 0), + RESET_MP21(USART3_R, RCC_USART3CFGR, 0, 0), + RESET_MP21(UART4_R, RCC_UART4CFGR, 0, 0), + RESET_MP21(UART5_R, RCC_UART5CFGR, 0, 0), + RESET_MP21(USART6_R, RCC_USART6CFGR, 0, 0), + RESET_MP21(UART7_R, RCC_UART7CFGR, 0, 0), + RESET_MP21(LPUART1_R, RCC_LPUART1CFGR, 0, 0), + RESET_MP21(I2C1_R, RCC_I2C1CFGR, 0, 0), + RESET_MP21(I2C2_R, RCC_I2C2CFGR, 0, 0), + RESET_MP21(I2C3_R, RCC_I2C3CFGR, 0, 0), + RESET_MP21(SAI1_R, RCC_SAI1CFGR, 0, 0), + RESET_MP21(SAI2_R, RCC_SAI2CFGR, 0, 0), + RESET_MP21(SAI3_R, RCC_SAI3CFGR, 0, 0), + RESET_MP21(SAI4_R, RCC_SAI4CFGR, 0, 0), + RESET_MP21(MDF1_R, RCC_MDF1CFGR, 0, 0), + RESET_MP21(FDCAN_R, RCC_FDCANCFGR, 0, 0), + RESET_MP21(HDP_R, RCC_HDPCFGR, 0, 0), + RESET_MP21(ADC1_R, RCC_ADC1CFGR, 0, 0), + RESET_MP21(ADC2_R, RCC_ADC2CFGR, 0, 0), + RESET_MP21(ETH1_R, RCC_ETH1CFGR, 0, 0), + RESET_MP21(ETH2_R, RCC_ETH2CFGR, 0, 0), + RESET_MP21(OTG_R, RCC_OTGCFGR, 0, 0), + RESET_MP21(USBH_R, RCC_USBHCFGR, 0, 0), + RESET_MP21(USB2PHY1_R, RCC_USB2PHY1CFGR, 0, 0), + RESET_MP21(USB2PHY2_R, RCC_USB2PHY2CFGR, 0, 0), + RESET_MP21(SDMMC1_R, RCC_SDMMC1CFGR, 0, 0), + RESET_MP21(SDMMC1DLL_R, RCC_SDMMC1CFGR, 16, 0), + RESET_MP21(SDMMC2_R, RCC_SDMMC2CFGR, 0, 0), + RESET_MP21(SDMMC2DLL_R, RCC_SDMMC2CFGR, 16, 0), + RESET_MP21(SDMMC3_R, RCC_SDMMC3CFGR, 0, 0), + RESET_MP21(SDMMC3DLL_R, RCC_SDMMC3CFGR, 16, 0), + RESET_MP21(LTDC_R, RCC_LTDCCFGR, 0, 0), + RESET_MP21(CSI_R, RCC_CSICFGR, 0, 0), + RESET_MP21(DCMIPP_R, RCC_DCMIPPCFGR, 0, 0), + RESET_MP21(DCMIPSSI_R, RCC_DCMIPSSICFGR, 0, 0), + RESET_MP21(WWDG1_R, RCC_WWDG1CFGR, 0, 0), + RESET_MP21(VREF_R, RCC_VREFCFGR, 0, 0), + RESET_MP21(DTS_R, RCC_DTSCFGR, 0, 0), + RESET_MP21(CRC_R, RCC_CRCCFGR, 0, 0), + RESET_MP21(SERC_R, RCC_SERCCFGR, 0, 0), + RESET_MP21(I3C1_R, RCC_I3C1CFGR, 0, 0), + RESET_MP21(I3C2_R, RCC_I3C2CFGR, 0, 0), + RESET_MP21(IWDG2_KER_R, RCC_IWDGC1CFGSETR, 18, 1), + RESET_MP21(IWDG4_KER_R, RCC_IWDGC2CFGSETR, 18, 1), + RESET_MP21(RNG1_R, RCC_RNG1CFGR, 0, 0), + RESET_MP21(RNG2_R, RCC_RNG2CFGR, 0, 0), + RESET_MP21(PKA_R, RCC_PKACFGR, 0, 0), + RESET_MP21(SAES_R, RCC_SAESCFGR, 0, 0), + RESET_MP21(HASH1_R, RCC_HASH1CFGR, 0, 0), + RESET_MP21(HASH2_R, RCC_HASH2CFGR, 0, 0), + RESET_MP21(CRYP1_R, RCC_CRYP1CFGR, 0, 0), + RESET_MP21(CRYP2_R, RCC_CRYP2CFGR, 0, 0), +}; + +static u16 stm32mp21_cpt_gate[GATE_NB]; + +static struct clk_stm32_clock_data stm32mp21_clock_data = { + .gate_cpt = stm32mp21_cpt_gate, + .gates = stm32mp21_gates, + .muxes = stm32mp21_muxes, +}; + +static struct clk_stm32_reset_data stm32mp21_reset_data = { + .reset_lines = stm32mp21_reset_cfg, + .nr_lines = ARRAY_SIZE(stm32mp21_reset_cfg), +}; + +static const struct stm32_rcc_match_data stm32mp21_data = { + .tab_clocks = stm32mp21_clock_cfg, + .num_clocks = ARRAY_SIZE(stm32mp21_clock_cfg), + .maxbinding = STM32MP21_LAST_CLK, + .clock_data = &stm32mp21_clock_data, + .reset_data = &stm32mp21_reset_data, + .check_security = &stm32mp21_check_security, +}; + +static const struct of_device_id stm32mp21_match_data[] = { + { .compatible = "st,stm32mp21-rcc", .data = &stm32mp21_data, }, + { } +}; +MODULE_DEVICE_TABLE(of, stm32mp21_match_data); + +static int stm32mp21_rcc_clocks_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + void __iomem *base; + + base = devm_platform_ioremap_resource(pdev, 0); + if (WARN_ON(IS_ERR(base))) + return PTR_ERR(base); + + return stm32_rcc_init(dev, stm32mp21_match_data, base); +} + +static struct platform_driver stm32mp21_rcc_clocks_driver = { + .driver = { + .name = "stm32mp21_rcc", + .of_match_table = stm32mp21_match_data, + }, + .probe = stm32mp21_rcc_clocks_probe, +}; + +static int __init stm32mp21_clocks_init(void) +{ + return platform_driver_register(&stm32mp21_rcc_clocks_driver); +} + +core_initcall(stm32mp21_clocks_init); + diff --git a/drivers/clk/stm32/stm32mp21_rcc.h b/drivers/clk/stm32/stm32mp21_rcc.h new file mode 100644 index 000000000000..df3ea921ffba --- /dev/null +++ b/drivers/clk/stm32/stm32mp21_rcc.h @@ -0,0 +1,651 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (C) STMicroelectronics 2025 - All Rights Reserved + * Author: Gabriel Fernandez <gabriel.fernandez@foss.st.com> for STMicroelectronics. + */ + +#ifndef STM32MP21_RCC_H +#define STM32MP21_RCC_H + +#define RCC_SECCFGR0 0x0 +#define RCC_SECCFGR1 0x4 +#define RCC_SECCFGR2 0x8 +#define RCC_SECCFGR3 0xC +#define RCC_PRIVCFGR0 0x10 +#define RCC_PRIVCFGR1 0x14 +#define RCC_PRIVCFGR2 0x18 +#define RCC_PRIVCFGR3 0x1C +#define RCC_RCFGLOCKR0 0x20 +#define RCC_RCFGLOCKR1 0x24 +#define RCC_RCFGLOCKR2 0x28 +#define RCC_RCFGLOCKR3 0x2C +#define RCC_R0CIDCFGR 0x30 +#define RCC_R0SEMCR 0x34 +#define RCC_R1CIDCFGR 0x38 +#define RCC_R1SEMCR 0x3C +#define RCC_R2CIDCFGR 0x40 +#define RCC_R2SEMCR 0x44 +#define RCC_R3CIDCFGR 0x48 +#define RCC_R3SEMCR 0x4C +#define RCC_R4CIDCFGR 0x50 +#define RCC_R4SEMCR 0x54 +#define RCC_R5CIDCFGR 0x58 +#define RCC_R5SEMCR 0x5C +#define RCC_R6CIDCFGR 0x60 +#define RCC_R6SEMCR 0x64 +#define RCC_R7CIDCFGR 0x68 +#define RCC_R7SEMCR 0x6C +#define RCC_R8CIDCFGR 0x70 +#define RCC_R8SEMCR 0x74 +#define RCC_R9CIDCFGR 0x78 +#define RCC_R9SEMCR 0x7C +#define RCC_R10CIDCFGR 0x80 +#define RCC_R10SEMCR 0x84 +#define RCC_R11CIDCFGR 0x88 +#define RCC_R11SEMCR 0x8C +#define RCC_R12CIDCFGR 0x90 +#define RCC_R12SEMCR 0x94 +#define RCC_R13CIDCFGR 0x98 +#define RCC_R13SEMCR 0x9C +#define RCC_R14CIDCFGR 0xA0 +#define RCC_R14SEMCR 0xA4 +#define RCC_R15CIDCFGR 0xA8 +#define RCC_R15SEMCR 0xAC +#define RCC_R16CIDCFGR 0xB0 +#define RCC_R16SEMCR 0xB4 +#define RCC_R17CIDCFGR 0xB8 +#define RCC_R17SEMCR 0xBC +#define RCC_R18CIDCFGR 0xC0 +#define RCC_R18SEMCR 0xC4 +#define RCC_R19CIDCFGR 0xC8 +#define RCC_R19SEMCR 0xCC +#define RCC_R20CIDCFGR 0xD0 +#define RCC_R20SEMCR 0xD4 +#define RCC_R21CIDCFGR 0xD8 +#define RCC_R21SEMCR 0xDC +#define RCC_R22CIDCFGR 0xE0 +#define RCC_R22SEMCR 0xE4 +#define RCC_R23CIDCFGR 0xE8 +#define RCC_R23SEMCR 0xEC +#define RCC_R24CIDCFGR 0xF0 +#define RCC_R24SEMCR 0xF4 +#define RCC_R25CIDCFGR 0xF8 +#define RCC_R25SEMCR 0xFC +#define RCC_R26CIDCFGR 0x100 +#define RCC_R26SEMCR 0x104 +#define RCC_R27CIDCFGR 0x108 +#define RCC_R27SEMCR 0x10C +#define RCC_R28CIDCFGR 0x110 +#define RCC_R28SEMCR 0x114 +#define RCC_R29CIDCFGR 0x118 +#define RCC_R29SEMCR 0x11C +#define RCC_R30CIDCFGR 0x120 +#define RCC_R30SEMCR 0x124 +#define RCC_R31CIDCFGR 0x128 +#define RCC_R31SEMCR 0x12C +#define RCC_R32CIDCFGR 0x130 +#define RCC_R32SEMCR 0x134 +#define RCC_R33CIDCFGR 0x138 +#define RCC_R33SEMCR 0x13C +#define RCC_R34CIDCFGR 0x140 +#define RCC_R34SEMCR 0x144 +#define RCC_R35CIDCFGR 0x148 +#define RCC_R35SEMCR 0x14C +#define RCC_R36CIDCFGR 0x150 +#define RCC_R36SEMCR 0x154 +#define RCC_R37CIDCFGR 0x158 +#define RCC_R37SEMCR 0x15C +#define RCC_R38CIDCFGR 0x160 +#define RCC_R38SEMCR 0x164 +#define RCC_R39CIDCFGR 0x168 +#define RCC_R39SEMCR 0x16C +#define RCC_R40CIDCFGR 0x170 +#define RCC_R40SEMCR 0x174 +#define RCC_R41CIDCFGR 0x178 +#define RCC_R41SEMCR 0x17C +#define RCC_R42CIDCFGR 0x180 +#define RCC_R42SEMCR 0x184 +#define RCC_R43CIDCFGR 0x188 +#define RCC_R43SEMCR 0x18C +#define RCC_R44CIDCFGR 0x190 +#define RCC_R44SEMCR 0x194 +#define RCC_R45CIDCFGR 0x198 +#define RCC_R45SEMCR 0x19C +#define RCC_R46CIDCFGR 0x1A0 +#define RCC_R46SEMCR 0x1A4 +#define RCC_R47CIDCFGR 0x1A8 +#define RCC_R47SEMCR 0x1AC +#define RCC_R48CIDCFGR 0x1B0 +#define RCC_R48SEMCR 0x1B4 +#define RCC_R49CIDCFGR 0x1B8 +#define RCC_R49SEMCR 0x1BC +#define RCC_R50CIDCFGR 0x1C0 +#define RCC_R50SEMCR 0x1C4 +#define RCC_R51CIDCFGR 0x1C8 +#define RCC_R51SEMCR 0x1CC +#define RCC_R52CIDCFGR 0x1D0 +#define RCC_R52SEMCR 0x1D4 +#define RCC_R53CIDCFGR 0x1D8 +#define RCC_R53SEMCR 0x1DC +#define RCC_R54CIDCFGR 0x1E0 +#define RCC_R54SEMCR 0x1E4 +#define RCC_R55CIDCFGR 0x1E8 +#define RCC_R55SEMCR 0x1EC +#define RCC_R56CIDCFGR 0x1F0 +#define RCC_R56SEMCR 0x1F4 +#define RCC_R57CIDCFGR 0x1F8 +#define RCC_R57SEMCR 0x1FC +#define RCC_R58CIDCFGR 0x200 +#define RCC_R58SEMCR 0x204 +#define RCC_R59CIDCFGR 0x208 +#define RCC_R59SEMCR 0x20C +#define RCC_R60CIDCFGR 0x210 +#define RCC_R60SEMCR 0x214 +#define RCC_R61CIDCFGR 0x218 +#define RCC_R61SEMCR 0x21C +#define RCC_R62CIDCFGR 0x220 +#define RCC_R62SEMCR 0x224 +#define RCC_R63CIDCFGR 0x228 +#define RCC_R63SEMCR 0x22C +#define RCC_R64CIDCFGR 0x230 +#define RCC_R64SEMCR 0x234 +#define RCC_R65CIDCFGR 0x238 +#define RCC_R65SEMCR 0x23C +#define RCC_R66CIDCFGR 0x240 +#define RCC_R66SEMCR 0x244 +#define RCC_R67CIDCFGR 0x248 +#define RCC_R67SEMCR 0x24C +#define RCC_R68CIDCFGR 0x250 +#define RCC_R68SEMCR 0x254 +#define RCC_R69CIDCFGR 0x258 +#define RCC_R69SEMCR 0x25C +#define RCC_R70CIDCFGR 0x260 +#define RCC_R70SEMCR 0x264 +#define RCC_R71CIDCFGR 0x268 +#define RCC_R71SEMCR 0x26C +#define RCC_R73CIDCFGR 0x278 +#define RCC_R73SEMCR 0x27C +#define RCC_R74CIDCFGR 0x280 +#define RCC_R74SEMCR 0x284 +#define RCC_R75CIDCFGR 0x288 +#define RCC_R75SEMCR 0x28C +#define RCC_R76CIDCFGR 0x290 +#define RCC_R76SEMCR 0x294 +#define RCC_R77CIDCFGR 0x298 +#define RCC_R77SEMCR 0x29C +#define RCC_R78CIDCFGR 0x2A0 +#define RCC_R78SEMCR 0x2A4 +#define RCC_R79CIDCFGR 0x2A8 +#define RCC_R79SEMCR 0x2AC +#define RCC_R83CIDCFGR 0x2C8 +#define RCC_R83SEMCR 0x2CC +#define RCC_R84CIDCFGR 0x2D0 +#define RCC_R84SEMCR 0x2D4 +#define RCC_R85CIDCFGR 0x2D8 +#define RCC_R85SEMCR 0x2DC +#define RCC_R86CIDCFGR 0x2E0 +#define RCC_R86SEMCR 0x2E4 +#define RCC_R87CIDCFGR 0x2E8 +#define RCC_R87SEMCR 0x2EC +#define RCC_R88CIDCFGR 0x2F0 +#define RCC_R88SEMCR 0x2F4 +#define RCC_R90CIDCFGR 0x300 +#define RCC_R90SEMCR 0x304 +#define RCC_R91CIDCFGR 0x308 +#define RCC_R91SEMCR 0x30C +#define RCC_R92CIDCFGR 0x310 +#define RCC_R92SEMCR 0x314 +#define RCC_R93CIDCFGR 0x318 +#define RCC_R93SEMCR 0x31C +#define RCC_R94CIDCFGR 0x320 +#define RCC_R94SEMCR 0x324 +#define RCC_R95CIDCFGR 0x328 +#define RCC_R95SEMCR 0x32C +#define RCC_R96CIDCFGR 0x330 +#define RCC_R96SEMCR 0x334 +#define RCC_R97CIDCFGR 0x338 +#define RCC_R97SEMCR 0x33C +#define RCC_R98CIDCFGR 0x340 +#define RCC_R98SEMCR 0x344 +#define RCC_R101CIDCFGR 0x358 +#define RCC_R101SEMCR 0x35C +#define RCC_R102CIDCFGR 0x360 +#define RCC_R102SEMCR 0x364 +#define RCC_R103CIDCFGR 0x368 +#define RCC_R103SEMCR 0x36C +#define RCC_R104CIDCFGR 0x370 +#define RCC_R104SEMCR 0x374 +#define RCC_R105CIDCFGR 0x378 +#define RCC_R105SEMCR 0x37C +#define RCC_R106CIDCFGR 0x380 +#define RCC_R106SEMCR 0x384 +#define RCC_R108CIDCFGR 0x390 +#define RCC_R108SEMCR 0x394 +#define RCC_R109CIDCFGR 0x398 +#define RCC_R109SEMCR 0x39C +#define RCC_R110CIDCFGR 0x3A0 +#define RCC_R110SEMCR 0x3A4 +#define RCC_R111CIDCFGR 0x3A8 +#define RCC_R111SEMCR 0x3AC +#define RCC_R112CIDCFGR 0x3B0 +#define RCC_R112SEMCR 0x3B4 +#define RCC_R113CIDCFGR 0x3B8 +#define RCC_R113SEMCR 0x3BC +#define RCC_GRSTCSETR 0x400 +#define RCC_C1RSTCSETR 0x404 +#define RCC_C2RSTCSETR 0x40C +#define RCC_HWRSTSCLRR 0x410 +#define RCC_C1HWRSTSCLRR 0x414 +#define RCC_C2HWRSTSCLRR 0x418 +#define RCC_C1BOOTRSTSSETR 0x41C +#define RCC_C1BOOTRSTSCLRR 0x420 +#define RCC_C2BOOTRSTSSETR 0x424 +#define RCC_C2BOOTRSTSCLRR 0x428 +#define RCC_C1SREQSETR 0x42C +#define RCC_C1SREQCLRR 0x430 +#define RCC_CPUBOOTCR 0x434 +#define RCC_STBYBOOTCR 0x438 +#define RCC_LEGBOOTCR 0x43C +#define RCC_BDCR 0x440 +#define RCC_RDCR 0x44C +#define RCC_C1MSRDCR 0x450 +#define RCC_PWRLPDLYCR 0x454 +#define RCC_C1CIESETR 0x458 +#define RCC_C1CIFCLRR 0x45C +#define RCC_C2CIESETR 0x460 +#define RCC_C2CIFCLRR 0x464 +#define RCC_IWDGC1FZSETR 0x468 +#define RCC_IWDGC1FZCLRR 0x46C +#define RCC_IWDGC1CFGSETR 0x470 +#define RCC_IWDGC1CFGCLRR 0x474 +#define RCC_IWDGC2FZSETR 0x478 +#define RCC_IWDGC2FZCLRR 0x47C +#define RCC_IWDGC2CFGSETR 0x480 +#define RCC_IWDGC2CFGCLRR 0x484 +#define RCC_MCO1CFGR 0x488 +#define RCC_MCO2CFGR 0x48C +#define RCC_OCENSETR 0x490 +#define RCC_OCENCLRR 0x494 +#define RCC_OCRDYR 0x498 +#define RCC_HSICFGR 0x49C +#define RCC_MSICFGR 0x4A0 +#define RCC_LSICR 0x4A4 +#define RCC_RTCDIVR 0x4A8 +#define RCC_APB1DIVR 0x4AC +#define RCC_APB2DIVR 0x4B0 +#define RCC_APB3DIVR 0x4B4 +#define RCC_APB4DIVR 0x4B8 +#define RCC_APB5DIVR 0x4BC +#define RCC_APBDBGDIVR 0x4C0 +#define RCC_TIMG1PRER 0x4C8 +#define RCC_TIMG2PRER 0x4CC +#define RCC_LSMCUDIVR 0x4D0 +#define RCC_DDRCPCFGR 0x4D4 +#define RCC_DDRCAPBCFGR 0x4D8 +#define RCC_DDRPHYCAPBCFGR 0x4DC +#define RCC_DDRPHYCCFGR 0x4E0 +#define RCC_DDRCFGR 0x4E4 +#define RCC_DDRITFCFGR 0x4E8 +#define RCC_SYSRAMCFGR 0x4F0 +#define RCC_SRAM1CFGR 0x4F8 +#define RCC_RETRAMCFGR 0x500 +#define RCC_BKPSRAMCFGR 0x504 +#define RCC_OSPI1CFGR 0x514 +#define RCC_FMCCFGR 0x51C +#define RCC_DBGCFGR 0x520 +#define RCC_STMCFGR 0x524 +#define RCC_ETRCFGR 0x528 +#define RCC_GPIOACFGR 0x52C +#define RCC_GPIOBCFGR 0x530 +#define RCC_GPIOCCFGR 0x534 +#define RCC_GPIODCFGR 0x538 +#define RCC_GPIOECFGR 0x53C +#define RCC_GPIOFCFGR 0x540 +#define RCC_GPIOGCFGR 0x544 +#define RCC_GPIOHCFGR 0x548 +#define RCC_GPIOICFGR 0x54C +#define RCC_GPIOZCFGR 0x558 +#define RCC_HPDMA1CFGR 0x55C +#define RCC_HPDMA2CFGR 0x560 +#define RCC_HPDMA3CFGR 0x564 +#define RCC_IPCC1CFGR 0x570 +#define RCC_RTCCFGR 0x578 +#define RCC_SYSCPU1CFGR 0x580 +#define RCC_BSECCFGR 0x584 +#define RCC_PLL2CFGR1 0x590 +#define RCC_PLL2CFGR2 0x594 +#define RCC_PLL2CFGR3 0x598 +#define RCC_PLL2CFGR4 0x59C +#define RCC_PLL2CFGR5 0x5A0 +#define RCC_PLL2CFGR6 0x5A8 +#define RCC_PLL2CFGR7 0x5AC +#define RCC_HSIFMONCR 0x5E0 +#define RCC_HSIFVALR 0x5E4 +#define RCC_MSIFMONCR 0x5E8 +#define RCC_MSIFVALR 0x5EC +#define RCC_TIM1CFGR 0x700 +#define RCC_TIM2CFGR 0x704 +#define RCC_TIM3CFGR 0x708 +#define RCC_TIM4CFGR 0x70C +#define RCC_TIM5CFGR 0x710 +#define RCC_TIM6CFGR 0x714 +#define RCC_TIM7CFGR 0x718 +#define RCC_TIM8CFGR 0x71C +#define RCC_TIM10CFGR 0x720 +#define RCC_TIM11CFGR 0x724 +#define RCC_TIM12CFGR 0x728 +#define RCC_TIM13CFGR 0x72C +#define RCC_TIM14CFGR 0x730 +#define RCC_TIM15CFGR 0x734 +#define RCC_TIM16CFGR 0x738 +#define RCC_TIM17CFGR 0x73C +#define RCC_LPTIM1CFGR 0x744 +#define RCC_LPTIM2CFGR 0x748 +#define RCC_LPTIM3CFGR 0x74C +#define RCC_LPTIM4CFGR 0x750 +#define RCC_LPTIM5CFGR 0x754 +#define RCC_SPI1CFGR 0x758 +#define RCC_SPI2CFGR 0x75C +#define RCC_SPI3CFGR 0x760 +#define RCC_SPI4CFGR 0x764 +#define RCC_SPI5CFGR 0x768 +#define RCC_SPI6CFGR 0x76C +#define RCC_SPDIFRXCFGR 0x778 +#define RCC_USART1CFGR 0x77C +#define RCC_USART2CFGR 0x780 +#define RCC_USART3CFGR 0x784 +#define RCC_UART4CFGR 0x788 +#define RCC_UART5CFGR 0x78C +#define RCC_USART6CFGR 0x790 +#define RCC_UART7CFGR 0x794 +#define RCC_LPUART1CFGR 0x7A0 +#define RCC_I2C1CFGR 0x7A4 +#define RCC_I2C2CFGR 0x7A8 +#define RCC_I2C3CFGR 0x7AC +#define RCC_SAI1CFGR 0x7C4 +#define RCC_SAI2CFGR 0x7C8 +#define RCC_SAI3CFGR 0x7CC +#define RCC_SAI4CFGR 0x7D0 +#define RCC_MDF1CFGR 0x7D8 +#define RCC_FDCANCFGR 0x7E0 +#define RCC_HDPCFGR 0x7E4 +#define RCC_ADC1CFGR 0x7E8 +#define RCC_ADC2CFGR 0x7EC +#define RCC_ETH1CFGR 0x7F0 +#define RCC_ETH2CFGR 0x7F4 +#define RCC_USBHCFGR 0x7FC +#define RCC_USB2PHY1CFGR 0x800 +#define RCC_OTGCFGR 0x808 +#define RCC_USB2PHY2CFGR 0x80C +#define RCC_STGENCFGR 0x824 +#define RCC_SDMMC1CFGR 0x830 +#define RCC_SDMMC2CFGR 0x834 +#define RCC_SDMMC3CFGR 0x838 +#define RCC_LTDCCFGR 0x840 +#define RCC_CSICFGR 0x858 +#define RCC_DCMIPPCFGR 0x85C +#define RCC_DCMIPSSICFGR 0x860 +#define RCC_RNG1CFGR 0x870 +#define RCC_RNG2CFGR 0x874 +#define RCC_PKACFGR 0x878 +#define RCC_SAESCFGR 0x87C +#define RCC_HASH1CFGR 0x880 +#define RCC_HASH2CFGR 0x884 +#define RCC_CRYP1CFGR 0x888 +#define RCC_CRYP2CFGR 0x88C +#define RCC_IWDG1CFGR 0x894 +#define RCC_IWDG2CFGR 0x898 +#define RCC_IWDG3CFGR 0x89C +#define RCC_IWDG4CFGR 0x8A0 +#define RCC_WWDG1CFGR 0x8A4 +#define RCC_VREFCFGR 0x8AC +#define RCC_DTSCFGR 0x8B0 +#define RCC_CRCCFGR 0x8B4 +#define RCC_SERCCFGR 0x8B8 +#define RCC_DDRPERFMCFGR 0x8C0 +#define RCC_I3C1CFGR 0x8C8 +#define RCC_I3C2CFGR 0x8CC +#define RCC_I3C3CFGR 0x8D0 +#define RCC_MUXSELCFGR 0x1000 +#define RCC_XBAR0CFGR 0x1018 +#define RCC_XBAR1CFGR 0x101C +#define RCC_XBAR2CFGR 0x1020 +#define RCC_XBAR3CFGR 0x1024 +#define RCC_XBAR4CFGR 0x1028 +#define RCC_XBAR5CFGR 0x102C +#define RCC_XBAR6CFGR 0x1030 +#define RCC_XBAR7CFGR 0x1034 +#define RCC_XBAR8CFGR 0x1038 +#define RCC_XBAR9CFGR 0x103C +#define RCC_XBAR10CFGR 0x1040 +#define RCC_XBAR11CFGR 0x1044 +#define RCC_XBAR12CFGR 0x1048 +#define RCC_XBAR13CFGR 0x104C +#define RCC_XBAR14CFGR 0x1050 +#define RCC_XBAR15CFGR 0x1054 +#define RCC_XBAR16CFGR 0x1058 +#define RCC_XBAR17CFGR 0x105C +#define RCC_XBAR18CFGR 0x1060 +#define RCC_XBAR19CFGR 0x1064 +#define RCC_XBAR20CFGR 0x1068 +#define RCC_XBAR21CFGR 0x106C +#define RCC_XBAR22CFGR 0x1070 +#define RCC_XBAR23CFGR 0x1074 +#define RCC_XBAR24CFGR 0x1078 +#define RCC_XBAR25CFGR 0x107C +#define RCC_XBAR26CFGR 0x1080 +#define RCC_XBAR27CFGR 0x1084 +#define RCC_XBAR28CFGR 0x1088 +#define RCC_XBAR29CFGR 0x108C +#define RCC_XBAR30CFGR 0x1090 +#define RCC_XBAR31CFGR 0x1094 +#define RCC_XBAR32CFGR 0x1098 +#define RCC_XBAR33CFGR 0x109C +#define RCC_XBAR34CFGR 0x10A0 +#define RCC_XBAR35CFGR 0x10A4 +#define RCC_XBAR36CFGR 0x10A8 +#define RCC_XBAR37CFGR 0x10AC +#define RCC_XBAR38CFGR 0x10B0 +#define RCC_XBAR39CFGR 0x10B4 +#define RCC_XBAR40CFGR 0x10B8 +#define RCC_XBAR41CFGR 0x10BC +#define RCC_XBAR42CFGR 0x10C0 +#define RCC_XBAR43CFGR 0x10C4 +#define RCC_XBAR44CFGR 0x10C8 +#define RCC_XBAR45CFGR 0x10CC +#define RCC_XBAR46CFGR 0x10D0 +#define RCC_XBAR47CFGR 0x10D4 +#define RCC_XBAR48CFGR 0x10D8 +#define RCC_XBAR49CFGR 0x10DC +#define RCC_XBAR50CFGR 0x10E0 +#define RCC_XBAR51CFGR 0x10E4 +#define RCC_XBAR52CFGR 0x10E8 +#define RCC_XBAR53CFGR 0x10EC +#define RCC_XBAR54CFGR 0x10F0 +#define RCC_XBAR55CFGR 0x10F4 +#define RCC_XBAR56CFGR 0x10F8 +#define RCC_XBAR57CFGR 0x10FC +#define RCC_XBAR58CFGR 0x1100 +#define RCC_XBAR59CFGR 0x1104 +#define RCC_XBAR60CFGR 0x1108 +#define RCC_XBAR61CFGR 0x110C +#define RCC_XBAR62CFGR 0x1110 +#define RCC_XBAR63CFGR 0x1114 +#define RCC_PREDIV0CFGR 0x1118 +#define RCC_PREDIV1CFGR 0x111C +#define RCC_PREDIV2CFGR 0x1120 +#define RCC_PREDIV3CFGR 0x1124 +#define RCC_PREDIV4CFGR 0x1128 +#define RCC_PREDIV5CFGR 0x112C +#define RCC_PREDIV6CFGR 0x1130 +#define RCC_PREDIV7CFGR 0x1134 +#define RCC_PREDIV8CFGR 0x1138 +#define RCC_PREDIV9CFGR 0x113C +#define RCC_PREDIV10CFGR 0x1140 +#define RCC_PREDIV11CFGR 0x1144 +#define RCC_PREDIV12CFGR 0x1148 +#define RCC_PREDIV13CFGR 0x114C +#define RCC_PREDIV14CFGR 0x1150 +#define RCC_PREDIV15CFGR 0x1154 +#define RCC_PREDIV16CFGR 0x1158 +#define RCC_PREDIV17CFGR 0x115C +#define RCC_PREDIV18CFGR 0x1160 +#define RCC_PREDIV19CFGR 0x1164 +#define RCC_PREDIV20CFGR 0x1168 +#define RCC_PREDIV21CFGR 0x116C +#define RCC_PREDIV22CFGR 0x1170 +#define RCC_PREDIV23CFGR 0x1174 +#define RCC_PREDIV24CFGR 0x1178 +#define RCC_PREDIV25CFGR 0x117C +#define RCC_PREDIV26CFGR 0x1180 +#define RCC_PREDIV27CFGR 0x1184 +#define RCC_PREDIV28CFGR 0x1188 +#define RCC_PREDIV29CFGR 0x118C +#define RCC_PREDIV30CFGR 0x1190 +#define RCC_PREDIV31CFGR 0x1194 +#define RCC_PREDIV32CFGR 0x1198 +#define RCC_PREDIV33CFGR 0x119C +#define RCC_PREDIV34CFGR 0x11A0 +#define RCC_PREDIV35CFGR 0x11A4 +#define RCC_PREDIV36CFGR 0x11A8 +#define RCC_PREDIV37CFGR 0x11AC +#define RCC_PREDIV38CFGR 0x11B0 +#define RCC_PREDIV39CFGR 0x11B4 +#define RCC_PREDIV40CFGR 0x11B8 +#define RCC_PREDIV41CFGR 0x11BC +#define RCC_PREDIV42CFGR 0x11C0 +#define RCC_PREDIV43CFGR 0x11C4 +#define RCC_PREDIV44CFGR 0x11C8 +#define RCC_PREDIV45CFGR 0x11CC +#define RCC_PREDIV46CFGR 0x11D0 +#define RCC_PREDIV47CFGR 0x11D4 +#define RCC_PREDIV48CFGR 0x11D8 +#define RCC_PREDIV49CFGR 0x11DC +#define RCC_PREDIV50CFGR 0x11E0 +#define RCC_PREDIV51CFGR 0x11E4 +#define RCC_PREDIV52CFGR 0x11E8 +#define RCC_PREDIV53CFGR 0x11EC +#define RCC_PREDIV54CFGR 0x11F0 +#define RCC_PREDIV55CFGR 0x11F4 +#define RCC_PREDIV56CFGR 0x11F8 +#define RCC_PREDIV57CFGR 0x11FC +#define RCC_PREDIV58CFGR 0x1200 +#define RCC_PREDIV59CFGR 0x1204 +#define RCC_PREDIV60CFGR 0x1208 +#define RCC_PREDIV61CFGR 0x120C +#define RCC_PREDIV62CFGR 0x1210 +#define RCC_PREDIV63CFGR 0x1214 +#define RCC_PREDIVSR1 0x1218 +#define RCC_PREDIVSR2 0x121C +#define RCC_FINDIV0CFGR 0x1224 +#define RCC_FINDIV1CFGR 0x1228 +#define RCC_FINDIV2CFGR 0x122C +#define RCC_FINDIV3CFGR 0x1230 +#define RCC_FINDIV4CFGR 0x1234 +#define RCC_FINDIV5CFGR 0x1238 +#define RCC_FINDIV6CFGR 0x123C +#define RCC_FINDIV7CFGR 0x1240 +#define RCC_FINDIV8CFGR 0x1244 +#define RCC_FINDIV9CFGR 0x1248 +#define RCC_FINDIV10CFGR 0x124C +#define RCC_FINDIV11CFGR 0x1250 +#define RCC_FINDIV12CFGR 0x1254 +#define RCC_FINDIV13CFGR 0x1258 +#define RCC_FINDIV14CFGR 0x125C +#define RCC_FINDIV15CFGR 0x1260 +#define RCC_FINDIV16CFGR 0x1264 +#define RCC_FINDIV17CFGR 0x1268 +#define RCC_FINDIV18CFGR 0x126C +#define RCC_FINDIV19CFGR 0x1270 +#define RCC_FINDIV20CFGR 0x1274 +#define RCC_FINDIV21CFGR 0x1278 +#define RCC_FINDIV22CFGR 0x127C +#define RCC_FINDIV23CFGR 0x1280 +#define RCC_FINDIV24CFGR 0x1284 +#define RCC_FINDIV25CFGR 0x1288 +#define RCC_FINDIV26CFGR 0x128C +#define RCC_FINDIV27CFGR 0x1290 +#define RCC_FINDIV28CFGR 0x1294 +#define RCC_FINDIV29CFGR 0x1298 +#define RCC_FINDIV30CFGR 0x129C +#define RCC_FINDIV31CFGR 0x12A0 +#define RCC_FINDIV32CFGR 0x12A4 +#define RCC_FINDIV33CFGR 0x12A8 +#define RCC_FINDIV34CFGR 0x12AC +#define RCC_FINDIV35CFGR 0x12B0 +#define RCC_FINDIV36CFGR 0x12B4 +#define RCC_FINDIV37CFGR 0x12B8 +#define RCC_FINDIV38CFGR 0x12BC +#define RCC_FINDIV39CFGR 0x12C0 +#define RCC_FINDIV40CFGR 0x12C4 +#define RCC_FINDIV41CFGR 0x12C8 +#define RCC_FINDIV42CFGR 0x12CC +#define RCC_FINDIV43CFGR 0x12D0 +#define RCC_FINDIV44CFGR 0x12D4 +#define RCC_FINDIV45CFGR 0x12D8 +#define RCC_FINDIV46CFGR 0x12DC +#define RCC_FINDIV47CFGR 0x12E0 +#define RCC_FINDIV48CFGR 0x12E4 +#define RCC_FINDIV49CFGR 0x12E8 +#define RCC_FINDIV50CFGR 0x12EC +#define RCC_FINDIV51CFGR 0x12F0 +#define RCC_FINDIV52CFGR 0x12F4 +#define RCC_FINDIV53CFGR 0x12F8 +#define RCC_FINDIV54CFGR 0x12FC +#define RCC_FINDIV55CFGR 0x1300 +#define RCC_FINDIV56CFGR 0x1304 +#define RCC_FINDIV57CFGR 0x1308 +#define RCC_FINDIV58CFGR 0x130C +#define RCC_FINDIV59CFGR 0x1310 +#define RCC_FINDIV60CFGR 0x1314 +#define RCC_FINDIV61CFGR 0x1318 +#define RCC_FINDIV62CFGR 0x131C +#define RCC_FINDIV63CFGR 0x1320 +#define RCC_FINDIVSR1 0x1324 +#define RCC_FINDIVSR2 0x1328 +#define RCC_FCALCOBS0CFGR 0x1340 +#define RCC_FCALCOBS1CFGR 0x1344 +#define RCC_FCALCREFCFGR 0x1348 +#define RCC_FCALCCR1 0x134C +#define RCC_FCALCCR2 0x1354 +#define RCC_FCALCSR 0x1358 +#define RCC_PLL4CFGR1 0x1360 +#define RCC_PLL4CFGR2 0x1364 +#define RCC_PLL4CFGR3 0x1368 +#define RCC_PLL4CFGR4 0x136C +#define RCC_PLL4CFGR5 0x1370 +#define RCC_PLL4CFGR6 0x1378 +#define RCC_PLL4CFGR7 0x137C +#define RCC_PLL5CFGR1 0x1388 +#define RCC_PLL5CFGR2 0x138C +#define RCC_PLL5CFGR3 0x1390 +#define RCC_PLL5CFGR4 0x1394 +#define RCC_PLL5CFGR5 0x1398 +#define RCC_PLL5CFGR6 0x13A0 +#define RCC_PLL5CFGR7 0x13A4 +#define RCC_PLL6CFGR1 0x13B0 +#define RCC_PLL6CFGR2 0x13B4 +#define RCC_PLL6CFGR3 0x13B8 +#define RCC_PLL6CFGR4 0x13BC +#define RCC_PLL6CFGR5 0x13C0 +#define RCC_PLL6CFGR6 0x13C8 +#define RCC_PLL6CFGR7 0x13CC +#define RCC_PLL7CFGR1 0x13D8 +#define RCC_PLL7CFGR2 0x13DC +#define RCC_PLL7CFGR3 0x13E0 +#define RCC_PLL7CFGR4 0x13E4 +#define RCC_PLL7CFGR5 0x13E8 +#define RCC_PLL7CFGR6 0x13F0 +#define RCC_PLL7CFGR7 0x13F4 +#define RCC_PLL8CFGR1 0x1400 +#define RCC_PLL8CFGR2 0x1404 +#define RCC_PLL8CFGR3 0x1408 +#define RCC_PLL8CFGR4 0x140C +#define RCC_PLL8CFGR5 0x1410 +#define RCC_PLL8CFGR6 0x1418 +#define RCC_PLL8CFGR7 0x141C +#define RCC_VERR 0xFFF4 +#define RCC_IDR 0xFFF8 +#define RCC_SIDR 0xFFFC + +#endif /* STM32MP21_RCC_H */ diff --git a/drivers/clk/sunxi-ng/Kconfig b/drivers/clk/sunxi-ng/Kconfig index 8896fd052ef1..6af2d020e03e 100644 --- a/drivers/clk/sunxi-ng/Kconfig +++ b/drivers/clk/sunxi-ng/Kconfig @@ -57,6 +57,11 @@ config SUN55I_A523_CCU default ARCH_SUNXI depends on ARM64 || COMPILE_TEST +config SUN55I_A523_MCU_CCU + tristate "Support for the Allwinner A523/T527 MCU CCU" + default ARCH_SUNXI + depends on ARM64 || COMPILE_TEST + config SUN55I_A523_R_CCU tristate "Support for the Allwinner A523/T527 PRCM CCU" default ARCH_SUNXI diff --git a/drivers/clk/sunxi-ng/Makefile b/drivers/clk/sunxi-ng/Makefile index 82e471036de6..a1c4087d7241 100644 --- a/drivers/clk/sunxi-ng/Makefile +++ b/drivers/clk/sunxi-ng/Makefile @@ -34,6 +34,7 @@ obj-$(CONFIG_SUN50I_H6_CCU) += sun50i-h6-ccu.o obj-$(CONFIG_SUN50I_H6_R_CCU) += sun50i-h6-r-ccu.o obj-$(CONFIG_SUN50I_H616_CCU) += sun50i-h616-ccu.o obj-$(CONFIG_SUN55I_A523_CCU) += sun55i-a523-ccu.o +obj-$(CONFIG_SUN55I_A523_MCU_CCU) += sun55i-a523-mcu-ccu.o obj-$(CONFIG_SUN55I_A523_R_CCU) += sun55i-a523-r-ccu.o obj-$(CONFIG_SUN4I_A10_CCU) += sun4i-a10-ccu.o obj-$(CONFIG_SUN5I_CCU) += sun5i-ccu.o @@ -61,6 +62,7 @@ sun50i-h6-ccu-y += ccu-sun50i-h6.o sun50i-h6-r-ccu-y += ccu-sun50i-h6-r.o sun50i-h616-ccu-y += ccu-sun50i-h616.o sun55i-a523-ccu-y += ccu-sun55i-a523.o +sun55i-a523-mcu-ccu-y += ccu-sun55i-a523-mcu.o sun55i-a523-r-ccu-y += ccu-sun55i-a523-r.o sun4i-a10-ccu-y += ccu-sun4i-a10.o sun5i-ccu-y += ccu-sun5i.o diff --git a/drivers/clk/sunxi-ng/ccu-sun55i-a523-mcu.c b/drivers/clk/sunxi-ng/ccu-sun55i-a523-mcu.c new file mode 100644 index 000000000000..197844f0fe4e --- /dev/null +++ b/drivers/clk/sunxi-ng/ccu-sun55i-a523-mcu.c @@ -0,0 +1,469 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2025 Chen-Yu Tsai <wens@csie.org> + * + * Based on the A523 CCU driver: + * Copyright (C) 2023-2024 Arm Ltd. + */ + +#include <linux/clk-provider.h> +#include <linux/io.h> +#include <linux/module.h> +#include <linux/platform_device.h> + +#include <dt-bindings/clock/sun55i-a523-mcu-ccu.h> +#include <dt-bindings/reset/sun55i-a523-mcu-ccu.h> + +#include "ccu_common.h" +#include "ccu_reset.h" + +#include "ccu_div.h" +#include "ccu_gate.h" +#include "ccu_mp.h" +#include "ccu_mult.h" +#include "ccu_nm.h" + +static const struct clk_parent_data osc24M[] = { + { .fw_name = "hosc" } +}; + +static const struct clk_parent_data ahb[] = { + { .fw_name = "r-ahb" } +}; + +static const struct clk_parent_data apb[] = { + { .fw_name = "r-apb0" } +}; + +#define SUN55I_A523_PLL_AUDIO1_REG 0x00c +static struct ccu_sdm_setting pll_audio1_sdm_table[] = { + { .rate = 2167603200, .pattern = 0xa000a234, .m = 1, .n = 90 }, /* div2->22.5792 */ + { .rate = 2359296000, .pattern = 0xa0009ba6, .m = 1, .n = 98 }, /* div2->24.576 */ + { .rate = 1806336000, .pattern = 0xa000872b, .m = 1, .n = 75 }, /* div5->22.576 */ +}; + +static struct ccu_nm pll_audio1_clk = { + .enable = BIT(27), + .lock = BIT(28), + .n = _SUNXI_CCU_MULT_MIN(8, 8, 11), + .m = _SUNXI_CCU_DIV(1, 1), + .sdm = _SUNXI_CCU_SDM(pll_audio1_sdm_table, BIT(24), + 0x010, BIT(31)), + .min_rate = 180000000U, + .max_rate = 3500000000U, + .common = { + .reg = 0x00c, + .features = CCU_FEATURE_SIGMA_DELTA_MOD, + .hw.init = CLK_HW_INIT_PARENTS_DATA("pll-audio1", + osc24M, &ccu_nm_ops, + CLK_SET_RATE_GATE), + }, +}; + +/* + * /2 and /5 dividers are actually programmable, but we just use the + * values from the BSP, since the audio PLL only needs to provide a + * couple clock rates. This also matches the names given in the manual. + */ +static const struct clk_hw *pll_audio1_div_parents[] = { &pll_audio1_clk.common.hw }; +static CLK_FIXED_FACTOR_HWS(pll_audio1_div2_clk, "pll-audio1-div2", + pll_audio1_div_parents, 2, 1, + CLK_SET_RATE_PARENT); +static CLK_FIXED_FACTOR_HWS(pll_audio1_div5_clk, "pll-audio1-div5", + pll_audio1_div_parents, 5, 1, + CLK_SET_RATE_PARENT); + +static SUNXI_CCU_M_WITH_GATE(audio_out_clk, "audio-out", + "pll-audio1-div2", 0x01c, + 0, 5, BIT(31), CLK_SET_RATE_PARENT); + +static const struct clk_parent_data dsp_parents[] = { + { .fw_name = "hosc" }, + { .fw_name = "losc" }, + { .fw_name = "iosc" }, + /* + * The order of the following two parent is from the BSP code. It is + * the opposite in the manual. Testing with the DSP is required to + * figure out the real order. + */ + { .hw = &pll_audio1_div5_clk.hw }, + { .hw = &pll_audio1_div2_clk.hw }, + { .fw_name = "dsp" }, +}; +static SUNXI_CCU_M_DATA_WITH_MUX_GATE(dsp_clk, "mcu-dsp", dsp_parents, 0x0020, + 0, 5, /* M */ + 24, 3, /* mux */ + BIT(31), /* gate */ + 0); + +static const struct clk_parent_data i2s_parents[] = { + { .fw_name = "pll-audio0-4x" }, + { .hw = &pll_audio1_div2_clk.hw }, + { .hw = &pll_audio1_div5_clk.hw }, +}; + +static SUNXI_CCU_DUALDIV_MUX_GATE(i2s0_clk, "i2s0", i2s_parents, 0x02c, + 0, 5, /* M */ + 5, 5, /* P */ + 24, 3, /* mux */ + BIT(31), /* gate */ + CLK_SET_RATE_PARENT); +static SUNXI_CCU_DUALDIV_MUX_GATE(i2s1_clk, "i2s1", i2s_parents, 0x030, + 0, 5, /* M */ + 5, 5, /* P */ + 24, 3, /* mux */ + BIT(31), /* gate */ + CLK_SET_RATE_PARENT); +static SUNXI_CCU_DUALDIV_MUX_GATE(i2s2_clk, "i2s2", i2s_parents, 0x034, + 0, 5, /* M */ + 5, 5, /* P */ + 24, 3, /* mux */ + BIT(31), /* gate */ + CLK_SET_RATE_PARENT); +static SUNXI_CCU_DUALDIV_MUX_GATE(i2s3_clk, "i2s3", i2s_parents, 0x038, + 0, 5, /* M */ + 5, 5, /* P */ + 24, 3, /* mux */ + BIT(31), /* gate */ + CLK_SET_RATE_PARENT); + +static const struct clk_parent_data i2s3_asrc_parents[] = { + { .fw_name = "pll-periph0-300m" }, + { .hw = &pll_audio1_div2_clk.hw }, + { .hw = &pll_audio1_div5_clk.hw }, +}; +static SUNXI_CCU_DUALDIV_MUX_GATE(i2s3_asrc_clk, "i2s3-asrc", + i2s3_asrc_parents, 0x03c, + 0, 5, /* M */ + 5, 5, /* P */ + 24, 3, /* mux */ + BIT(31), /* gate */ + CLK_SET_RATE_PARENT); + +static SUNXI_CCU_GATE_DATA(bus_i2s0_clk, "bus-i2s0", apb, 0x040, BIT(0), 0); +static SUNXI_CCU_GATE_DATA(bus_i2s1_clk, "bus-i2s1", apb, 0x040, BIT(1), 0); +static SUNXI_CCU_GATE_DATA(bus_i2s2_clk, "bus-i2s2", apb, 0x040, BIT(2), 0); +static SUNXI_CCU_GATE_DATA(bus_i2s3_clk, "bus-i2s3", apb, 0x040, BIT(3), 0); + +static const struct clk_parent_data audio_parents[] = { + { .fw_name = "pll-audio0-4x" }, + { .hw = &pll_audio1_div2_clk.hw }, + { .hw = &pll_audio1_div5_clk.hw }, +}; +static SUNXI_CCU_DUALDIV_MUX_GATE(spdif_tx_clk, "spdif-tx", + audio_parents, 0x044, + 0, 5, /* M */ + 5, 5, /* P */ + 24, 3, /* mux */ + BIT(31), /* gate */ + CLK_SET_RATE_PARENT); +static SUNXI_CCU_DUALDIV_MUX_GATE(spdif_rx_clk, "spdif-rx", + i2s3_asrc_parents, 0x048, + 0, 5, /* M */ + 5, 5, /* P */ + 24, 3, /* mux */ + BIT(31), /* gate */ + CLK_SET_RATE_PARENT); + +static SUNXI_CCU_GATE_DATA(bus_spdif_clk, "bus-spdif", apb, 0x04c, BIT(0), 0); + +static SUNXI_CCU_DUALDIV_MUX_GATE(dmic_clk, "dmic", audio_parents, 0x050, + 0, 5, /* M */ + 5, 5, /* P */ + 24, 3, /* mux */ + BIT(31), /* gate */ + CLK_SET_RATE_PARENT); + +static SUNXI_CCU_GATE_DATA(bus_dmic_clk, "bus-dmic", apb, 0x054, BIT(0), 0); + +static SUNXI_CCU_DUALDIV_MUX_GATE(audio_dac_clk, "audio-dac", + audio_parents, 0x058, + 0, 5, /* M */ + 5, 5, /* P */ + 24, 3, /* mux */ + BIT(31), /* gate */ + CLK_SET_RATE_PARENT); +static SUNXI_CCU_DUALDIV_MUX_GATE(audio_adc_clk, "audio-adc", + audio_parents, 0x05c, + 0, 5, /* M */ + 5, 5, /* P */ + 24, 3, /* mux */ + BIT(31), /* gate */ + CLK_SET_RATE_PARENT); + +static SUNXI_CCU_GATE_DATA(bus_audio_codec_clk, "bus-audio-codec", + apb, 0x060, BIT(0), 0); + +static SUNXI_CCU_GATE_DATA(bus_dsp_msgbox_clk, "bus-dsp-msgbox", + ahb, 0x068, BIT(0), 0); +static SUNXI_CCU_GATE_DATA(bus_dsp_cfg_clk, "bus-dsp-cfg", + apb, 0x06c, BIT(0), 0); + +static SUNXI_CCU_GATE_DATA(bus_npu_hclk, "bus-npu-hclk", ahb, 0x070, BIT(1), 0); +static SUNXI_CCU_GATE_DATA(bus_npu_aclk, "bus-npu-aclk", ahb, 0x070, BIT(2), 0); + +static const struct clk_parent_data timer_parents[] = { + { .fw_name = "hosc" }, + { .fw_name = "losc" }, + { .fw_name = "iosc" }, + { .fw_name = "r-ahb" } +}; +static SUNXI_CCU_P_DATA_WITH_MUX_GATE(mcu_timer0_clk, "mcu-timer0", timer_parents, + 0x074, + 1, 3, /* P */ + 4, 2, /* mux */ + BIT(0), /* gate */ + 0); +static SUNXI_CCU_P_DATA_WITH_MUX_GATE(mcu_timer1_clk, "mcu-timer1", timer_parents, + 0x078, + 1, 3, /* P */ + 4, 2, /* mux */ + BIT(0), /* gate */ + 0); +static SUNXI_CCU_P_DATA_WITH_MUX_GATE(mcu_timer2_clk, "mcu-timer2", timer_parents, + 0x07c, + 1, 3, /* P */ + 4, 2, /* mux */ + BIT(0), /* gate */ + 0); +static SUNXI_CCU_P_DATA_WITH_MUX_GATE(mcu_timer3_clk, "mcu-timer3", timer_parents, + 0x080, + 1, 3, /* P */ + 4, 2, /* mux */ + BIT(0), /* gate */ + 0); +static SUNXI_CCU_P_DATA_WITH_MUX_GATE(mcu_timer4_clk, "mcu-timer4", timer_parents, + 0x084, + 1, 3, /* P */ + 4, 2, /* mux */ + BIT(0), /* gate */ + 0); +static SUNXI_CCU_P_DATA_WITH_MUX_GATE(mcu_timer5_clk, "mcu-timer5", timer_parents, + 0x088, + 1, 3, /* P */ + 4, 2, /* mux */ + BIT(0), /* gate */ + 0); +static SUNXI_CCU_GATE_DATA(bus_mcu_timer_clk, "bus-mcu-timer", ahb, 0x08c, BIT(0), 0); +static SUNXI_CCU_GATE_DATA(bus_mcu_dma_clk, "bus-mcu-dma", ahb, 0x104, BIT(0), 0); +/* tzma* only found in BSP code. */ +static SUNXI_CCU_GATE_DATA(tzma0_clk, "tzma0", ahb, 0x108, BIT(0), 0); +static SUNXI_CCU_GATE_DATA(tzma1_clk, "tzma1", ahb, 0x10c, BIT(0), 0); +/* parent is a guess as this block is not shown in the system bus tree diagram */ +static SUNXI_CCU_GATE_DATA(bus_pubsram_clk, "bus-pubsram", ahb, 0x114, BIT(0), 0); + +/* + * user manual has "mbus" clock as parent of both clocks below, + * but this makes more sense, since BSP MCU DMA controller has + * reference to both of them, likely needing both enabled. + */ +static SUNXI_CCU_GATE_FW(mbus_mcu_clk, "mbus-mcu", "mbus", 0x11c, BIT(1), 0); +static SUNXI_CCU_GATE_HW(mbus_mcu_dma_clk, "mbus-mcu-dma", + &mbus_mcu_clk.common.hw, 0x11c, BIT(0), 0); + +static const struct clk_parent_data riscv_pwm_parents[] = { + { .fw_name = "hosc" }, + { .fw_name = "losc" }, + { .fw_name = "iosc" }, +}; + +static SUNXI_CCU_MUX_DATA_WITH_GATE(riscv_clk, "riscv", + riscv_pwm_parents, 0x120, + 27, 3, BIT(31), 0); +/* Parents are guesses as these two blocks are not shown in the system bus tree diagram */ +static SUNXI_CCU_GATE_DATA(bus_riscv_cfg_clk, "bus-riscv-cfg", ahb, + 0x124, BIT(0), 0); +static SUNXI_CCU_GATE_DATA(bus_riscv_msgbox_clk, "bus-riscv-msgbox", ahb, + 0x128, BIT(0), 0); + +static SUNXI_CCU_MUX_DATA_WITH_GATE(mcu_pwm0_clk, "mcu-pwm0", + riscv_pwm_parents, 0x130, + 24, 3, BIT(31), 0); +static SUNXI_CCU_GATE_DATA(bus_mcu_pwm0_clk, "bus-mcu-pwm0", apb, + 0x134, BIT(0), 0); + +/* + * Contains all clocks that are controlled by a hardware register. They + * have a (sunxi) .common member, which needs to be initialised by the common + * sunxi CCU code, to be filled with the MMIO base address and the shared lock. + */ +static struct ccu_common *sun55i_a523_mcu_ccu_clks[] = { + &pll_audio1_clk.common, + &audio_out_clk.common, + &dsp_clk.common, + &i2s0_clk.common, + &i2s1_clk.common, + &i2s2_clk.common, + &i2s3_clk.common, + &i2s3_asrc_clk.common, + &bus_i2s0_clk.common, + &bus_i2s1_clk.common, + &bus_i2s2_clk.common, + &bus_i2s3_clk.common, + &spdif_tx_clk.common, + &spdif_rx_clk.common, + &bus_spdif_clk.common, + &dmic_clk.common, + &bus_dmic_clk.common, + &audio_dac_clk.common, + &audio_adc_clk.common, + &bus_audio_codec_clk.common, + &bus_dsp_msgbox_clk.common, + &bus_dsp_cfg_clk.common, + &bus_npu_aclk.common, + &bus_npu_hclk.common, + &mcu_timer0_clk.common, + &mcu_timer1_clk.common, + &mcu_timer2_clk.common, + &mcu_timer3_clk.common, + &mcu_timer4_clk.common, + &mcu_timer5_clk.common, + &bus_mcu_timer_clk.common, + &bus_mcu_dma_clk.common, + &tzma0_clk.common, + &tzma1_clk.common, + &bus_pubsram_clk.common, + &mbus_mcu_dma_clk.common, + &mbus_mcu_clk.common, + &riscv_clk.common, + &bus_riscv_cfg_clk.common, + &bus_riscv_msgbox_clk.common, + &mcu_pwm0_clk.common, + &bus_mcu_pwm0_clk.common, +}; + +static struct clk_hw_onecell_data sun55i_a523_mcu_hw_clks = { + .hws = { + [CLK_MCU_PLL_AUDIO1] = &pll_audio1_clk.common.hw, + [CLK_MCU_PLL_AUDIO1_DIV2] = &pll_audio1_div2_clk.hw, + [CLK_MCU_PLL_AUDIO1_DIV5] = &pll_audio1_div5_clk.hw, + [CLK_MCU_AUDIO_OUT] = &audio_out_clk.common.hw, + [CLK_MCU_DSP] = &dsp_clk.common.hw, + [CLK_MCU_I2S0] = &i2s0_clk.common.hw, + [CLK_MCU_I2S1] = &i2s1_clk.common.hw, + [CLK_MCU_I2S2] = &i2s2_clk.common.hw, + [CLK_MCU_I2S3] = &i2s3_clk.common.hw, + [CLK_MCU_I2S3_ASRC] = &i2s3_asrc_clk.common.hw, + [CLK_BUS_MCU_I2S0] = &bus_i2s0_clk.common.hw, + [CLK_BUS_MCU_I2S1] = &bus_i2s1_clk.common.hw, + [CLK_BUS_MCU_I2S2] = &bus_i2s2_clk.common.hw, + [CLK_BUS_MCU_I2S3] = &bus_i2s3_clk.common.hw, + [CLK_MCU_SPDIF_TX] = &spdif_tx_clk.common.hw, + [CLK_MCU_SPDIF_RX] = &spdif_rx_clk.common.hw, + [CLK_BUS_MCU_SPDIF] = &bus_spdif_clk.common.hw, + [CLK_MCU_DMIC] = &dmic_clk.common.hw, + [CLK_BUS_MCU_DMIC] = &bus_dmic_clk.common.hw, + [CLK_MCU_AUDIO_CODEC_DAC] = &audio_dac_clk.common.hw, + [CLK_MCU_AUDIO_CODEC_ADC] = &audio_adc_clk.common.hw, + [CLK_BUS_MCU_AUDIO_CODEC] = &bus_audio_codec_clk.common.hw, + [CLK_BUS_MCU_DSP_MSGBOX] = &bus_dsp_msgbox_clk.common.hw, + [CLK_BUS_MCU_DSP_CFG] = &bus_dsp_cfg_clk.common.hw, + [CLK_BUS_MCU_NPU_HCLK] = &bus_npu_hclk.common.hw, + [CLK_BUS_MCU_NPU_ACLK] = &bus_npu_aclk.common.hw, + [CLK_MCU_TIMER0] = &mcu_timer0_clk.common.hw, + [CLK_MCU_TIMER1] = &mcu_timer1_clk.common.hw, + [CLK_MCU_TIMER2] = &mcu_timer2_clk.common.hw, + [CLK_MCU_TIMER3] = &mcu_timer3_clk.common.hw, + [CLK_MCU_TIMER4] = &mcu_timer4_clk.common.hw, + [CLK_MCU_TIMER5] = &mcu_timer5_clk.common.hw, + [CLK_BUS_MCU_TIMER] = &bus_mcu_timer_clk.common.hw, + [CLK_BUS_MCU_DMA] = &bus_mcu_dma_clk.common.hw, + [CLK_MCU_TZMA0] = &tzma0_clk.common.hw, + [CLK_MCU_TZMA1] = &tzma1_clk.common.hw, + [CLK_BUS_MCU_PUBSRAM] = &bus_pubsram_clk.common.hw, + [CLK_MCU_MBUS_DMA] = &mbus_mcu_dma_clk.common.hw, + [CLK_MCU_MBUS] = &mbus_mcu_clk.common.hw, + [CLK_MCU_RISCV] = &riscv_clk.common.hw, + [CLK_BUS_MCU_RISCV_CFG] = &bus_riscv_cfg_clk.common.hw, + [CLK_BUS_MCU_RISCV_MSGBOX] = &bus_riscv_msgbox_clk.common.hw, + [CLK_MCU_PWM0] = &mcu_pwm0_clk.common.hw, + [CLK_BUS_MCU_PWM0] = &bus_mcu_pwm0_clk.common.hw, + }, + .num = CLK_BUS_MCU_PWM0 + 1, +}; + +static struct ccu_reset_map sun55i_a523_mcu_ccu_resets[] = { + [RST_BUS_MCU_I2S0] = { 0x0040, BIT(16) }, + [RST_BUS_MCU_I2S1] = { 0x0040, BIT(17) }, + [RST_BUS_MCU_I2S2] = { 0x0040, BIT(18) }, + [RST_BUS_MCU_I2S3] = { 0x0040, BIT(19) }, + [RST_BUS_MCU_SPDIF] = { 0x004c, BIT(16) }, + [RST_BUS_MCU_DMIC] = { 0x0054, BIT(16) }, + [RST_BUS_MCU_AUDIO_CODEC] = { 0x0060, BIT(16) }, + [RST_BUS_MCU_DSP_MSGBOX] = { 0x0068, BIT(16) }, + [RST_BUS_MCU_DSP_CFG] = { 0x006c, BIT(16) }, + [RST_BUS_MCU_NPU] = { 0x0070, BIT(16) }, + [RST_BUS_MCU_TIMER] = { 0x008c, BIT(16) }, + /* dsp and dsp_debug resets only found in BSP code. */ + [RST_BUS_MCU_DSP_DEBUG] = { 0x0100, BIT(16) }, + [RST_BUS_MCU_DSP] = { 0x0100, BIT(17) }, + [RST_BUS_MCU_DMA] = { 0x0104, BIT(16) }, + [RST_BUS_MCU_PUBSRAM] = { 0x0114, BIT(16) }, + [RST_BUS_MCU_RISCV_CFG] = { 0x0124, BIT(16) }, + [RST_BUS_MCU_RISCV_DEBUG] = { 0x0124, BIT(17) }, + [RST_BUS_MCU_RISCV_CORE] = { 0x0124, BIT(18) }, + [RST_BUS_MCU_RISCV_MSGBOX] = { 0x0128, BIT(16) }, + [RST_BUS_MCU_PWM0] = { 0x0134, BIT(16) }, +}; + +static const struct sunxi_ccu_desc sun55i_a523_mcu_ccu_desc = { + .ccu_clks = sun55i_a523_mcu_ccu_clks, + .num_ccu_clks = ARRAY_SIZE(sun55i_a523_mcu_ccu_clks), + + .hw_clks = &sun55i_a523_mcu_hw_clks, + + .resets = sun55i_a523_mcu_ccu_resets, + .num_resets = ARRAY_SIZE(sun55i_a523_mcu_ccu_resets), +}; + +static int sun55i_a523_mcu_ccu_probe(struct platform_device *pdev) +{ + void __iomem *reg; + u32 val; + int ret; + + reg = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(reg)) + return PTR_ERR(reg); + + val = readl(reg + SUN55I_A523_PLL_AUDIO1_REG); + + /* + * The PLL clock code does not model all bits, for instance it does + * not support a separate enable and gate bit. We present the + * gate bit(27) as the enable bit, but then have to set the + * PLL Enable, LDO Enable, and Lock Enable bits on all PLLs here. + */ + val |= BIT(31) | BIT(30) | BIT(29); + + /* Enforce p1 = 5, p0 = 2 (the default) for PLL_AUDIO1 */ + val &= ~(GENMASK(22, 20) | GENMASK(18, 16)); + val |= (4 << 20) | (1 << 16); + + writel(val, reg + SUN55I_A523_PLL_AUDIO1_REG); + + ret = devm_sunxi_ccu_probe(&pdev->dev, reg, &sun55i_a523_mcu_ccu_desc); + if (ret) + return ret; + + return 0; +} + +static const struct of_device_id sun55i_a523_mcu_ccu_ids[] = { + { .compatible = "allwinner,sun55i-a523-mcu-ccu" }, + { } +}; + +static struct platform_driver sun55i_a523_mcu_ccu_driver = { + .probe = sun55i_a523_mcu_ccu_probe, + .driver = { + .name = "sun55i-a523-mcu-ccu", + .suppress_bind_attrs = true, + .of_match_table = sun55i_a523_mcu_ccu_ids, + }, +}; +module_platform_driver(sun55i_a523_mcu_ccu_driver); + +MODULE_IMPORT_NS("SUNXI_CCU"); +MODULE_DESCRIPTION("Support for the Allwinner A523 MCU CCU"); +MODULE_LICENSE("GPL"); diff --git a/drivers/clk/sunxi-ng/ccu-sun55i-a523.c b/drivers/clk/sunxi-ng/ccu-sun55i-a523.c index 1a9a1cb869e2..acb532f8361b 100644 --- a/drivers/clk/sunxi-ng/ccu-sun55i-a523.c +++ b/drivers/clk/sunxi-ng/ccu-sun55i-a523.c @@ -11,6 +11,9 @@ #include <linux/module.h> #include <linux/platform_device.h> +#include <dt-bindings/clock/sun55i-a523-ccu.h> +#include <dt-bindings/reset/sun55i-a523-ccu.h> + #include "../clk.h" #include "ccu_common.h" @@ -25,8 +28,6 @@ #include "ccu_nkmp.h" #include "ccu_nm.h" -#include "ccu-sun55i-a523.h" - /* * The 24 MHz oscillator, the root of most of the clock tree. * .fw_name is the string used in the DT "clock-names" property, used to @@ -486,6 +487,18 @@ static SUNXI_CCU_M_HW_WITH_MUX_GATE(ve_clk, "ve", ve_parents, 0x690, static SUNXI_CCU_GATE_HWS(bus_ve_clk, "bus-ve", ahb_hws, 0x69c, BIT(0), 0); +static const struct clk_hw *npu_parents[] = { + &pll_periph0_480M_clk.common.hw, + &pll_periph0_600M_clk.hw, + &pll_periph0_800M_clk.common.hw, + &pll_npu_2x_clk.hw, +}; +static SUNXI_CCU_M_HW_WITH_MUX_GATE(npu_clk, "npu", npu_parents, 0x6e0, + 0, 5, /* M */ + 24, 3, /* mux */ + BIT(31), /* gate */ + CLK_SET_RATE_PARENT); + static SUNXI_CCU_GATE_HWS(bus_dma_clk, "bus-dma", ahb_hws, 0x70c, BIT(0), 0); static SUNXI_CCU_GATE_HWS(bus_msgbox_clk, "bus-msgbox", ahb_hws, 0x71c, @@ -1217,6 +1230,7 @@ static struct ccu_common *sun55i_a523_ccu_clks[] = { &bus_ce_sys_clk.common, &ve_clk.common, &bus_ve_clk.common, + &npu_clk.common, &bus_dma_clk.common, &bus_msgbox_clk.common, &bus_spinlock_clk.common, @@ -1343,7 +1357,6 @@ static struct ccu_common *sun55i_a523_ccu_clks[] = { }; static struct clk_hw_onecell_data sun55i_a523_hw_clks = { - .num = CLK_NUMBER, .hws = { [CLK_PLL_DDR0] = &pll_ddr_clk.common.hw, [CLK_PLL_PERIPH0_4X] = &pll_periph0_4x_clk.common.hw, @@ -1524,7 +1537,9 @@ static struct clk_hw_onecell_data sun55i_a523_hw_clks = { [CLK_FANOUT0] = &fanout0_clk.common.hw, [CLK_FANOUT1] = &fanout1_clk.common.hw, [CLK_FANOUT2] = &fanout2_clk.common.hw, + [CLK_NPU] = &npu_clk.common.hw, }, + .num = CLK_NPU + 1, }; static struct ccu_reset_map sun55i_a523_ccu_resets[] = { diff --git a/drivers/clk/sunxi-ng/ccu-sun55i-a523.h b/drivers/clk/sunxi-ng/ccu-sun55i-a523.h deleted file mode 100644 index fc8dd42f1b47..000000000000 --- a/drivers/clk/sunxi-ng/ccu-sun55i-a523.h +++ /dev/null @@ -1,14 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* - * Copyright 2024 Arm Ltd. - */ - -#ifndef _CCU_SUN55I_A523_H -#define _CCU_SUN55I_A523_H - -#include <dt-bindings/clock/sun55i-a523-ccu.h> -#include <dt-bindings/reset/sun55i-a523-ccu.h> - -#define CLK_NUMBER (CLK_FANOUT2 + 1) - -#endif /* _CCU_SUN55I_A523_H */ diff --git a/drivers/clk/sunxi-ng/ccu-sun6i-rtc.c b/drivers/clk/sunxi-ng/ccu-sun6i-rtc.c index 0536e880b80f..f6bfeba009e8 100644 --- a/drivers/clk/sunxi-ng/ccu-sun6i-rtc.c +++ b/drivers/clk/sunxi-ng/ccu-sun6i-rtc.c @@ -325,6 +325,13 @@ static const struct sun6i_rtc_match_data sun50i_r329_rtc_ccu_data = { .osc32k_fanout_nparents = ARRAY_SIZE(sun50i_r329_osc32k_fanout_parents), }; +static const struct sun6i_rtc_match_data sun55i_a523_rtc_ccu_data = { + .have_ext_osc32k = true, + .have_iosc_calibration = true, + .osc32k_fanout_parents = sun50i_r329_osc32k_fanout_parents, + .osc32k_fanout_nparents = ARRAY_SIZE(sun50i_r329_osc32k_fanout_parents), +}; + static const struct of_device_id sun6i_rtc_ccu_match[] = { { .compatible = "allwinner,sun50i-h616-rtc", @@ -334,6 +341,10 @@ static const struct of_device_id sun6i_rtc_ccu_match[] = { .compatible = "allwinner,sun50i-r329-rtc", .data = &sun50i_r329_rtc_ccu_data, }, + { + .compatible = "allwinner,sun55i-a523-rtc", + .data = &sun55i_a523_rtc_ccu_data, + }, {}, }; MODULE_DEVICE_TABLE(of, sun6i_rtc_ccu_match); diff --git a/drivers/clk/sunxi-ng/ccu_div.h b/drivers/clk/sunxi-ng/ccu_div.h index 90d49ee8e0cc..be00b3277e97 100644 --- a/drivers/clk/sunxi-ng/ccu_div.h +++ b/drivers/clk/sunxi-ng/ccu_div.h @@ -274,6 +274,24 @@ struct ccu_div { SUNXI_CCU_M_HWS_WITH_GATE(_struct, _name, _parent, _reg, \ _mshift, _mwidth, 0, _flags) +#define SUNXI_CCU_P_DATA_WITH_MUX_GATE(_struct, _name, _parents, _reg, \ + _mshift, _mwidth, \ + _muxshift, _muxwidth, \ + _gate, _flags) \ + struct ccu_div _struct = { \ + .enable = _gate, \ + .div = _SUNXI_CCU_DIV_FLAGS(_mshift, _mwidth, \ + CLK_DIVIDER_POWER_OF_TWO), \ + .mux = _SUNXI_CCU_MUX(_muxshift, _muxwidth), \ + .common = { \ + .reg = _reg, \ + .hw.init = CLK_HW_INIT_PARENTS_DATA(_name, \ + _parents, \ + &ccu_div_ops, \ + _flags), \ + }, \ + } + static inline struct ccu_div *hw_to_ccu_div(struct clk_hw *hw) { struct ccu_common *common = hw_to_ccu_common(hw); diff --git a/drivers/clk/tegra/Kconfig b/drivers/clk/tegra/Kconfig index 90df619dc087..62147a069606 100644 --- a/drivers/clk/tegra/Kconfig +++ b/drivers/clk/tegra/Kconfig @@ -4,7 +4,7 @@ config CLK_TEGRA_BPMP depends on TEGRA_BPMP config TEGRA_CLK_DFLL - depends on ARCH_TEGRA_124_SOC || ARCH_TEGRA_210_SOC + depends on ARCH_TEGRA_114_SOC || ARCH_TEGRA_124_SOC || ARCH_TEGRA_210_SOC select PM_OPP def_bool y diff --git a/drivers/clk/tegra/clk-audio-sync.c b/drivers/clk/tegra/clk-audio-sync.c index 2c4bb96eae16..468a4403f147 100644 --- a/drivers/clk/tegra/clk-audio-sync.c +++ b/drivers/clk/tegra/clk-audio-sync.c @@ -17,15 +17,15 @@ static unsigned long clk_sync_source_recalc_rate(struct clk_hw *hw, return sync->rate; } -static long clk_sync_source_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *prate) +static int clk_sync_source_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { struct tegra_clk_sync_source *sync = to_clk_sync_source(hw); - if (rate > sync->max_rate) + if (req->rate > sync->max_rate) return -EINVAL; else - return rate; + return 0; } static int clk_sync_source_set_rate(struct clk_hw *hw, unsigned long rate, @@ -38,7 +38,7 @@ static int clk_sync_source_set_rate(struct clk_hw *hw, unsigned long rate, } const struct clk_ops tegra_clk_sync_source_ops = { - .round_rate = clk_sync_source_round_rate, + .determine_rate = clk_sync_source_determine_rate, .set_rate = clk_sync_source_set_rate, .recalc_rate = clk_sync_source_recalc_rate, }; diff --git a/drivers/clk/tegra/clk-bpmp.c b/drivers/clk/tegra/clk-bpmp.c index b2323cb8eddc..77a2586dbe00 100644 --- a/drivers/clk/tegra/clk-bpmp.c +++ b/drivers/clk/tegra/clk-bpmp.c @@ -635,7 +635,7 @@ static int tegra_bpmp_register_clocks(struct tegra_bpmp *bpmp, bpmp->num_clocks = count; - bpmp->clocks = devm_kcalloc(bpmp->dev, count, sizeof(struct tegra_bpmp_clk), GFP_KERNEL); + bpmp->clocks = devm_kcalloc(bpmp->dev, count, sizeof(*bpmp->clocks), GFP_KERNEL); if (!bpmp->clocks) return -ENOMEM; diff --git a/drivers/clk/tegra/clk-dfll.c b/drivers/clk/tegra/clk-dfll.c index 58fa5a59e0c7..22dc29432eff 100644 --- a/drivers/clk/tegra/clk-dfll.c +++ b/drivers/clk/tegra/clk-dfll.c @@ -882,7 +882,7 @@ static void dfll_set_frequency_request(struct tegra_dfll *td, { u32 val = 0; int force_val; - int coef = 128; /* FIXME: td->cg_scale? */; + int coef = 128; /* FIXME: td->cg_scale? */ force_val = (req->lut_index - td->lut_safe) * coef / td->cg; force_val = clamp(force_val, FORCE_MIN, FORCE_MAX); diff --git a/drivers/clk/tegra/clk-divider.c b/drivers/clk/tegra/clk-divider.c index 38daf483ddf1..37439fcb3ac0 100644 --- a/drivers/clk/tegra/clk-divider.c +++ b/drivers/clk/tegra/clk-divider.c @@ -58,23 +58,31 @@ static unsigned long clk_frac_div_recalc_rate(struct clk_hw *hw, return rate; } -static long clk_frac_div_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *prate) +static int clk_frac_div_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { struct tegra_clk_frac_div *divider = to_clk_frac_div(hw); int div, mul; - unsigned long output_rate = *prate; + unsigned long output_rate = req->best_parent_rate; - if (!rate) - return output_rate; + if (!req->rate) { + req->rate = output_rate; - div = get_div(divider, rate, output_rate); - if (div < 0) - return *prate; + return 0; + } + + div = get_div(divider, req->rate, output_rate); + if (div < 0) { + req->rate = req->best_parent_rate; + + return 0; + } mul = get_mul(divider); - return DIV_ROUND_UP(output_rate * mul, div + mul); + req->rate = DIV_ROUND_UP(output_rate * mul, div + mul); + + return 0; } static int clk_frac_div_set_rate(struct clk_hw *hw, unsigned long rate, @@ -127,7 +135,7 @@ static void clk_divider_restore_context(struct clk_hw *hw) const struct clk_ops tegra_clk_frac_div_ops = { .recalc_rate = clk_frac_div_recalc_rate, .set_rate = clk_frac_div_set_rate, - .round_rate = clk_frac_div_round_rate, + .determine_rate = clk_frac_div_determine_rate, .restore_context = clk_divider_restore_context, }; diff --git a/drivers/clk/tegra/clk-periph.c b/drivers/clk/tegra/clk-periph.c index fa0cd7bb8ee6..6ebeaa7cb656 100644 --- a/drivers/clk/tegra/clk-periph.c +++ b/drivers/clk/tegra/clk-periph.c @@ -51,16 +51,10 @@ static int clk_periph_determine_rate(struct clk_hw *hw, struct tegra_clk_periph *periph = to_clk_periph(hw); const struct clk_ops *div_ops = periph->div_ops; struct clk_hw *div_hw = &periph->divider.hw; - long rate; __clk_hw_set_clk(div_hw, hw); - rate = div_ops->round_rate(div_hw, req->rate, &req->best_parent_rate); - if (rate < 0) - return rate; - - req->rate = (unsigned long)rate; - return 0; + return div_ops->determine_rate(div_hw, req); } static int clk_periph_set_rate(struct clk_hw *hw, unsigned long rate, diff --git a/drivers/clk/tegra/clk-pll.c b/drivers/clk/tegra/clk-pll.c index 100b5d9b7e26..591b9f0c155a 100644 --- a/drivers/clk/tegra/clk-pll.c +++ b/drivers/clk/tegra/clk-pll.c @@ -840,8 +840,8 @@ static int clk_pll_set_rate(struct clk_hw *hw, unsigned long rate, return ret; } -static long clk_pll_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *prate) +static int clk_pll_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { struct tegra_clk_pll *pll = to_clk_pll(hw); struct tegra_clk_pll_freq_table cfg; @@ -849,15 +849,20 @@ static long clk_pll_round_rate(struct clk_hw *hw, unsigned long rate, if (pll->params->flags & TEGRA_PLL_FIXED) { /* PLLM/MB are used for memory; we do not change rate */ if (pll->params->flags & (TEGRA_PLLM | TEGRA_PLLMB)) - return clk_hw_get_rate(hw); - return pll->params->fixed_rate; + req->rate = clk_hw_get_rate(hw); + else + req->rate = pll->params->fixed_rate; + + return 0; } - if (_get_table_rate(hw, &cfg, rate, *prate) && - pll->params->calc_rate(hw, &cfg, rate, *prate)) + if (_get_table_rate(hw, &cfg, req->rate, req->best_parent_rate) && + pll->params->calc_rate(hw, &cfg, req->rate, req->best_parent_rate)) return -EINVAL; - return cfg.output_rate; + req->rate = cfg.output_rate; + + return 0; } static unsigned long clk_pll_recalc_rate(struct clk_hw *hw, @@ -1057,7 +1062,7 @@ const struct clk_ops tegra_clk_pll_ops = { .enable = clk_pll_enable, .disable = clk_pll_disable, .recalc_rate = clk_pll_recalc_rate, - .round_rate = clk_pll_round_rate, + .determine_rate = clk_pll_determine_rate, .set_rate = clk_pll_set_rate, .restore_context = tegra_clk_pll_restore_context, }; @@ -1195,7 +1200,7 @@ static const struct clk_ops tegra_clk_pllu_ops = { .enable = clk_pllu_enable, .disable = clk_pll_disable, .recalc_rate = clk_pll_recalc_rate, - .round_rate = clk_pll_round_rate, + .determine_rate = clk_pll_determine_rate, .set_rate = clk_pll_set_rate, }; @@ -1353,15 +1358,15 @@ static int clk_pllxc_set_rate(struct clk_hw *hw, unsigned long rate, return ret; } -static long clk_pll_ramp_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *prate) +static int clk_pll_ramp_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { struct tegra_clk_pll *pll = to_clk_pll(hw); struct tegra_clk_pll_freq_table cfg; int ret, p_div; - u64 output_rate = *prate; + u64 output_rate = req->best_parent_rate; - ret = _pll_ramp_calc_pll(hw, &cfg, rate, *prate); + ret = _pll_ramp_calc_pll(hw, &cfg, req->rate, req->best_parent_rate); if (ret < 0) return ret; @@ -1375,7 +1380,9 @@ static long clk_pll_ramp_round_rate(struct clk_hw *hw, unsigned long rate, output_rate *= cfg.n; do_div(output_rate, cfg.m * p_div); - return output_rate; + req->rate = output_rate; + + return 0; } static void _pllcx_strobe(struct tegra_clk_pll *pll) @@ -1598,12 +1605,15 @@ static unsigned long clk_pllre_recalc_rate(struct clk_hw *hw, return rate; } -static long clk_pllre_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *prate) +static int clk_pllre_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { struct tegra_clk_pll *pll = to_clk_pll(hw); - return _pllre_calc_rate(pll, NULL, rate, *prate); + req->rate = _pllre_calc_rate(pll, NULL, req->rate, + req->best_parent_rate); + + return 0; } static int clk_plle_tegra114_enable(struct clk_hw *hw) @@ -2003,7 +2013,7 @@ static const struct clk_ops tegra_clk_pllxc_ops = { .enable = clk_pll_enable, .disable = clk_pll_disable, .recalc_rate = clk_pll_recalc_rate, - .round_rate = clk_pll_ramp_round_rate, + .determine_rate = clk_pll_ramp_determine_rate, .set_rate = clk_pllxc_set_rate, }; @@ -2012,7 +2022,7 @@ static const struct clk_ops tegra_clk_pllc_ops = { .enable = clk_pllc_enable, .disable = clk_pllc_disable, .recalc_rate = clk_pll_recalc_rate, - .round_rate = clk_pll_ramp_round_rate, + .determine_rate = clk_pll_ramp_determine_rate, .set_rate = clk_pllc_set_rate, }; @@ -2021,7 +2031,7 @@ static const struct clk_ops tegra_clk_pllre_ops = { .enable = clk_pll_enable, .disable = clk_pll_disable, .recalc_rate = clk_pllre_recalc_rate, - .round_rate = clk_pllre_round_rate, + .determine_rate = clk_pllre_determine_rate, .set_rate = clk_pllre_set_rate, }; @@ -2321,7 +2331,7 @@ static const struct clk_ops tegra_clk_pllss_ops = { .enable = clk_pll_enable, .disable = clk_pll_disable, .recalc_rate = clk_pll_recalc_rate, - .round_rate = clk_pll_ramp_round_rate, + .determine_rate = clk_pll_ramp_determine_rate, .set_rate = clk_pllxc_set_rate, .restore_context = tegra_clk_pll_restore_context, }; diff --git a/drivers/clk/tegra/clk-super.c b/drivers/clk/tegra/clk-super.c index 7ec47942720c..51fb356e770e 100644 --- a/drivers/clk/tegra/clk-super.c +++ b/drivers/clk/tegra/clk-super.c @@ -147,17 +147,10 @@ static int clk_super_determine_rate(struct clk_hw *hw, { struct tegra_clk_super_mux *super = to_clk_super_mux(hw); struct clk_hw *div_hw = &super->frac_div.hw; - unsigned long rate; __clk_hw_set_clk(div_hw, hw); - rate = super->div_ops->round_rate(div_hw, req->rate, - &req->best_parent_rate); - if (rate < 0) - return rate; - - req->rate = rate; - return 0; + return super->div_ops->determine_rate(div_hw, req); } static unsigned long clk_super_recalc_rate(struct clk_hw *hw, diff --git a/drivers/clk/tegra/clk-tegra114.c b/drivers/clk/tegra/clk-tegra114.c index 73303458e886..6c8e053311c3 100644 --- a/drivers/clk/tegra/clk-tegra114.c +++ b/drivers/clk/tegra/clk-tegra114.c @@ -11,6 +11,7 @@ #include <linux/export.h> #include <linux/clk/tegra.h> #include <dt-bindings/clock/tegra114-car.h> +#include <dt-bindings/reset/nvidia,tegra114-car.h> #include "clk.h" #include "clk-id.h" @@ -1272,7 +1273,7 @@ EXPORT_SYMBOL(tegra114_clock_tune_cpu_trimmers_init); * * Assert the reset line of the DFLL's DVCO. No return value. */ -void tegra114_clock_assert_dfll_dvco_reset(void) +static void tegra114_clock_assert_dfll_dvco_reset(void) { u32 v; @@ -1281,7 +1282,6 @@ void tegra114_clock_assert_dfll_dvco_reset(void) writel_relaxed(v, clk_base + RST_DFLL_DVCO); tegra114_car_barrier(); } -EXPORT_SYMBOL(tegra114_clock_assert_dfll_dvco_reset); /** * tegra114_clock_deassert_dfll_dvco_reset - deassert the DFLL's DVCO reset @@ -1289,7 +1289,7 @@ EXPORT_SYMBOL(tegra114_clock_assert_dfll_dvco_reset); * Deassert the reset line of the DFLL's DVCO, allowing the DVCO to * operate. No return value. */ -void tegra114_clock_deassert_dfll_dvco_reset(void) +static void tegra114_clock_deassert_dfll_dvco_reset(void) { u32 v; @@ -1298,7 +1298,26 @@ void tegra114_clock_deassert_dfll_dvco_reset(void) writel_relaxed(v, clk_base + RST_DFLL_DVCO); tegra114_car_barrier(); } -EXPORT_SYMBOL(tegra114_clock_deassert_dfll_dvco_reset); + +static int tegra114_reset_assert(unsigned long id) +{ + if (id == TEGRA114_RST_DFLL_DVCO) + tegra114_clock_assert_dfll_dvco_reset(); + else + return -EINVAL; + + return 0; +} + +static int tegra114_reset_deassert(unsigned long id) +{ + if (id == TEGRA114_RST_DFLL_DVCO) + tegra114_clock_deassert_dfll_dvco_reset(); + else + return -EINVAL; + + return 0; +} static void __init tegra114_clock_init(struct device_node *np) { @@ -1344,6 +1363,9 @@ static void __init tegra114_clock_init(struct device_node *np) tegra_super_clk_gen4_init(clk_base, pmc_base, tegra114_clks, &pll_x_params); + tegra_init_special_resets(1, tegra114_reset_assert, + tegra114_reset_deassert); + tegra_add_of_provider(np, of_clk_src_onecell_get); tegra_register_devclks(devclks, ARRAY_SIZE(devclks)); diff --git a/drivers/clk/tegra/clk-tegra124-dfll-fcpu.c b/drivers/clk/tegra/clk-tegra124-dfll-fcpu.c index 0251618b82c8..457a77c5bb62 100644 --- a/drivers/clk/tegra/clk-tegra124-dfll-fcpu.c +++ b/drivers/clk/tegra/clk-tegra124-dfll-fcpu.c @@ -29,6 +29,99 @@ struct dfll_fcpu_data { }; /* Maximum CPU frequency, indexed by CPU speedo id */ +static const unsigned long tegra114_cpu_max_freq_table[] = { + [0] = 2040000000UL, + [1] = 1810500000UL, + [2] = 1912500000UL, + [3] = 1810500000UL, +}; + +#define T114_CPU_CVB_TABLE \ + .min_millivolts = 1000, \ + .max_millivolts = 1320, \ + .speedo_scale = 100, \ + .voltage_scale = 1000, \ + .entries = { \ + { 306000000UL, { 2190643, -141851, 3576 } }, \ + { 408000000UL, { 2250968, -144331, 3576 } }, \ + { 510000000UL, { 2313333, -146811, 3576 } }, \ + { 612000000UL, { 2377738, -149291, 3576 } }, \ + { 714000000UL, { 2444183, -151771, 3576 } }, \ + { 816000000UL, { 2512669, -154251, 3576 } }, \ + { 918000000UL, { 2583194, -156731, 3576 } }, \ + { 1020000000UL, { 2655759, -159211, 3576 } }, \ + { 1122000000UL, { 2730365, -161691, 3576 } }, \ + { 1224000000UL, { 2807010, -164171, 3576 } }, \ + { 1326000000UL, { 2885696, -166651, 3576 } }, \ + { 1428000000UL, { 2966422, -169131, 3576 } }, \ + { 1530000000UL, { 3049183, -171601, 3576 } }, \ + { 1606500000UL, { 3112179, -173451, 3576 } }, \ + { 1708500000UL, { 3198504, -175931, 3576 } }, \ + { 1810500000UL, { 3304747, -179126, 3576 } }, \ + { 1912500000UL, { 3395401, -181606, 3576 } }, \ + { 0UL, { 0, 0, 0 } }, \ + }, \ + .cpu_dfll_data = { \ + .tune0_low = 0x00b0039d, \ + .tune0_high = 0x00b0009d, \ + .tune1 = 0x0000001f, \ + .tune_high_min_millivolts = 1050, \ + } + +static const struct cvb_table tegra114_cpu_cvb_tables[] = { + { + .speedo_id = 0, + .process_id = -1, + .min_millivolts = 1000, + .max_millivolts = 1250, + .speedo_scale = 100, + .voltage_scale = 100, + .entries = { + { 306000000UL, { 107330, -1569, 0 } }, + { 408000000UL, { 111250, -1666, 0 } }, + { 510000000UL, { 110000, -1460, 0 } }, + { 612000000UL, { 117290, -1745, 0 } }, + { 714000000UL, { 122700, -1910, 0 } }, + { 816000000UL, { 125620, -1945, 0 } }, + { 918000000UL, { 130560, -2076, 0 } }, + { 1020000000UL, { 137280, -2303, 0 } }, + { 1122000000UL, { 146440, -2660, 0 } }, + { 1224000000UL, { 152190, -2825, 0 } }, + { 1326000000UL, { 157520, -2953, 0 } }, + { 1428000000UL, { 166100, -3261, 0 } }, + { 1530000000UL, { 176410, -3647, 0 } }, + { 1632000000UL, { 189620, -4186, 0 } }, + { 1734000000UL, { 203190, -4725, 0 } }, + { 1836000000UL, { 222670, -5573, 0 } }, + { 1938000000UL, { 256210, -7165, 0 } }, + { 2040000000UL, { 250050, -6544, 0 } }, + { 0UL, { 0, 0, 0 } }, + }, + .cpu_dfll_data = { + .tune0_low = 0x00b0019d, + .tune0_high = 0x00b0019d, + .tune1 = 0x0000001f, + .tune_high_min_millivolts = 1000, + } + }, + { + .speedo_id = 1, + .process_id = -1, + T114_CPU_CVB_TABLE + }, + { + .speedo_id = 2, + .process_id = -1, + T114_CPU_CVB_TABLE + }, + { + .speedo_id = 3, + .process_id = -1, + T114_CPU_CVB_TABLE + }, +}; + +/* Maximum CPU frequency, indexed by CPU speedo id */ static const unsigned long tegra124_cpu_max_freq_table[] = { [0] = 2014500000UL, [1] = 2320500000UL, @@ -93,7 +186,7 @@ static const unsigned long tegra210_cpu_max_freq_table[] = { [10] = 1504500000UL, }; -#define CPU_CVB_TABLE \ +#define TEGRA210_CPU_CVB_TABLE \ .speedo_scale = 100, \ .voltage_scale = 1000, \ .entries = { \ @@ -120,7 +213,7 @@ static const unsigned long tegra210_cpu_max_freq_table[] = { { 0UL, { 0, 0, 0 } }, \ } -#define CPU_CVB_TABLE_XA \ +#define TEGRA210_CPU_CVB_TABLE_XA \ .speedo_scale = 100, \ .voltage_scale = 1000, \ .entries = { \ @@ -143,7 +236,7 @@ static const unsigned long tegra210_cpu_max_freq_table[] = { { 0UL, { 0, 0, 0 } }, \ } -#define CPU_CVB_TABLE_EUCM1 \ +#define TEGRA210_CPU_CVB_TABLE_EUCM1 \ .speedo_scale = 100, \ .voltage_scale = 1000, \ .entries = { \ @@ -166,7 +259,7 @@ static const unsigned long tegra210_cpu_max_freq_table[] = { { 0UL, { 0, 0, 0 } }, \ } -#define CPU_CVB_TABLE_EUCM2 \ +#define TEGRA210_CPU_CVB_TABLE_EUCM2 \ .speedo_scale = 100, \ .voltage_scale = 1000, \ .entries = { \ @@ -188,7 +281,7 @@ static const unsigned long tegra210_cpu_max_freq_table[] = { { 0UL, { 0, 0, 0 } }, \ } -#define CPU_CVB_TABLE_EUCM2_JOINT_RAIL \ +#define TEGRA210_CPU_CVB_TABLE_EUCM2_JOINT_RAIL \ .speedo_scale = 100, \ .voltage_scale = 1000, \ .entries = { \ @@ -209,7 +302,7 @@ static const unsigned long tegra210_cpu_max_freq_table[] = { { 0UL, { 0, 0, 0 } }, \ } -#define CPU_CVB_TABLE_ODN \ +#define TEGRA210_CPU_CVB_TABLE_ODN \ .speedo_scale = 100, \ .voltage_scale = 1000, \ .entries = { \ @@ -238,7 +331,7 @@ static struct cvb_table tegra210_cpu_cvb_tables[] = { .process_id = 0, .min_millivolts = 840, .max_millivolts = 1120, - CPU_CVB_TABLE_EUCM2_JOINT_RAIL, + TEGRA210_CPU_CVB_TABLE_EUCM2_JOINT_RAIL, .cpu_dfll_data = { .tune0_low = 0xffead0ff, .tune0_high = 0xffead0ff, @@ -251,7 +344,7 @@ static struct cvb_table tegra210_cpu_cvb_tables[] = { .process_id = 1, .min_millivolts = 840, .max_millivolts = 1120, - CPU_CVB_TABLE_EUCM2_JOINT_RAIL, + TEGRA210_CPU_CVB_TABLE_EUCM2_JOINT_RAIL, .cpu_dfll_data = { .tune0_low = 0xffead0ff, .tune0_high = 0xffead0ff, @@ -264,7 +357,7 @@ static struct cvb_table tegra210_cpu_cvb_tables[] = { .process_id = 0, .min_millivolts = 900, .max_millivolts = 1162, - CPU_CVB_TABLE_EUCM2, + TEGRA210_CPU_CVB_TABLE_EUCM2, .cpu_dfll_data = { .tune0_low = 0xffead0ff, .tune0_high = 0xffead0ff, @@ -276,7 +369,7 @@ static struct cvb_table tegra210_cpu_cvb_tables[] = { .process_id = 1, .min_millivolts = 900, .max_millivolts = 1162, - CPU_CVB_TABLE_EUCM2, + TEGRA210_CPU_CVB_TABLE_EUCM2, .cpu_dfll_data = { .tune0_low = 0xffead0ff, .tune0_high = 0xffead0ff, @@ -288,7 +381,7 @@ static struct cvb_table tegra210_cpu_cvb_tables[] = { .process_id = 0, .min_millivolts = 900, .max_millivolts = 1195, - CPU_CVB_TABLE_EUCM2, + TEGRA210_CPU_CVB_TABLE_EUCM2, .cpu_dfll_data = { .tune0_low = 0xffead0ff, .tune0_high = 0xffead0ff, @@ -300,7 +393,7 @@ static struct cvb_table tegra210_cpu_cvb_tables[] = { .process_id = 1, .min_millivolts = 900, .max_millivolts = 1195, - CPU_CVB_TABLE_EUCM2, + TEGRA210_CPU_CVB_TABLE_EUCM2, .cpu_dfll_data = { .tune0_low = 0xffead0ff, .tune0_high = 0xffead0ff, @@ -312,7 +405,7 @@ static struct cvb_table tegra210_cpu_cvb_tables[] = { .process_id = 0, .min_millivolts = 841, .max_millivolts = 1227, - CPU_CVB_TABLE_EUCM1, + TEGRA210_CPU_CVB_TABLE_EUCM1, .cpu_dfll_data = { .tune0_low = 0xffead0ff, .tune0_high = 0xffead0ff, @@ -325,7 +418,7 @@ static struct cvb_table tegra210_cpu_cvb_tables[] = { .process_id = 1, .min_millivolts = 841, .max_millivolts = 1227, - CPU_CVB_TABLE_EUCM1, + TEGRA210_CPU_CVB_TABLE_EUCM1, .cpu_dfll_data = { .tune0_low = 0xffead0ff, .tune0_high = 0xffead0ff, @@ -338,7 +431,7 @@ static struct cvb_table tegra210_cpu_cvb_tables[] = { .process_id = 0, .min_millivolts = 870, .max_millivolts = 1150, - CPU_CVB_TABLE, + TEGRA210_CPU_CVB_TABLE, .cpu_dfll_data = { .tune0_low = 0xffead0ff, .tune1 = 0x20091d9, @@ -349,7 +442,7 @@ static struct cvb_table tegra210_cpu_cvb_tables[] = { .process_id = 1, .min_millivolts = 870, .max_millivolts = 1150, - CPU_CVB_TABLE, + TEGRA210_CPU_CVB_TABLE, .cpu_dfll_data = { .tune0_low = 0xffead0ff, .tune1 = 0x25501d0, @@ -360,7 +453,7 @@ static struct cvb_table tegra210_cpu_cvb_tables[] = { .process_id = 0, .min_millivolts = 818, .max_millivolts = 1227, - CPU_CVB_TABLE, + TEGRA210_CPU_CVB_TABLE, .cpu_dfll_data = { .tune0_low = 0xffead0ff, .tune0_high = 0xffead0ff, @@ -373,7 +466,7 @@ static struct cvb_table tegra210_cpu_cvb_tables[] = { .process_id = 1, .min_millivolts = 818, .max_millivolts = 1227, - CPU_CVB_TABLE, + TEGRA210_CPU_CVB_TABLE, .cpu_dfll_data = { .tune0_low = 0xffead0ff, .tune0_high = 0xffead0ff, @@ -386,7 +479,7 @@ static struct cvb_table tegra210_cpu_cvb_tables[] = { .process_id = -1, .min_millivolts = 918, .max_millivolts = 1113, - CPU_CVB_TABLE_XA, + TEGRA210_CPU_CVB_TABLE_XA, .cpu_dfll_data = { .tune0_low = 0xffead0ff, .tune1 = 0x17711BD, @@ -397,7 +490,7 @@ static struct cvb_table tegra210_cpu_cvb_tables[] = { .process_id = 0, .min_millivolts = 825, .max_millivolts = 1227, - CPU_CVB_TABLE_ODN, + TEGRA210_CPU_CVB_TABLE_ODN, .cpu_dfll_data = { .tune0_low = 0xffead0ff, .tune0_high = 0xffead0ff, @@ -410,7 +503,7 @@ static struct cvb_table tegra210_cpu_cvb_tables[] = { .process_id = 1, .min_millivolts = 825, .max_millivolts = 1227, - CPU_CVB_TABLE_ODN, + TEGRA210_CPU_CVB_TABLE_ODN, .cpu_dfll_data = { .tune0_low = 0xffead0ff, .tune0_high = 0xffead0ff, @@ -423,7 +516,7 @@ static struct cvb_table tegra210_cpu_cvb_tables[] = { .process_id = 0, .min_millivolts = 870, .max_millivolts = 1227, - CPU_CVB_TABLE, + TEGRA210_CPU_CVB_TABLE, .cpu_dfll_data = { .tune0_low = 0xffead0ff, .tune1 = 0x20091d9, @@ -434,7 +527,7 @@ static struct cvb_table tegra210_cpu_cvb_tables[] = { .process_id = 1, .min_millivolts = 870, .max_millivolts = 1227, - CPU_CVB_TABLE, + TEGRA210_CPU_CVB_TABLE, .cpu_dfll_data = { .tune0_low = 0xffead0ff, .tune1 = 0x25501d0, @@ -445,7 +538,7 @@ static struct cvb_table tegra210_cpu_cvb_tables[] = { .process_id = 0, .min_millivolts = 837, .max_millivolts = 1227, - CPU_CVB_TABLE, + TEGRA210_CPU_CVB_TABLE, .cpu_dfll_data = { .tune0_low = 0xffead0ff, .tune0_high = 0xffead0ff, @@ -458,7 +551,7 @@ static struct cvb_table tegra210_cpu_cvb_tables[] = { .process_id = 1, .min_millivolts = 837, .max_millivolts = 1227, - CPU_CVB_TABLE, + TEGRA210_CPU_CVB_TABLE, .cpu_dfll_data = { .tune0_low = 0xffead0ff, .tune0_high = 0xffead0ff, @@ -471,7 +564,7 @@ static struct cvb_table tegra210_cpu_cvb_tables[] = { .process_id = 0, .min_millivolts = 850, .max_millivolts = 1170, - CPU_CVB_TABLE, + TEGRA210_CPU_CVB_TABLE, .cpu_dfll_data = { .tune0_low = 0xffead0ff, .tune0_high = 0xffead0ff, @@ -484,7 +577,7 @@ static struct cvb_table tegra210_cpu_cvb_tables[] = { .process_id = 1, .min_millivolts = 850, .max_millivolts = 1170, - CPU_CVB_TABLE, + TEGRA210_CPU_CVB_TABLE, .cpu_dfll_data = { .tune0_low = 0xffead0ff, .tune0_high = 0xffead0ff, @@ -494,6 +587,13 @@ static struct cvb_table tegra210_cpu_cvb_tables[] = { }, }; +static const struct dfll_fcpu_data tegra114_dfll_fcpu_data = { + .cpu_max_freq_table = tegra114_cpu_max_freq_table, + .cpu_max_freq_table_size = ARRAY_SIZE(tegra114_cpu_max_freq_table), + .cpu_cvb_tables = tegra114_cpu_cvb_tables, + .cpu_cvb_tables_size = ARRAY_SIZE(tegra114_cpu_cvb_tables) +}; + static const struct dfll_fcpu_data tegra124_dfll_fcpu_data = { .cpu_max_freq_table = tegra124_cpu_max_freq_table, .cpu_max_freq_table_size = ARRAY_SIZE(tegra124_cpu_max_freq_table), @@ -510,6 +610,10 @@ static const struct dfll_fcpu_data tegra210_dfll_fcpu_data = { static const struct of_device_id tegra124_dfll_fcpu_of_match[] = { { + .compatible = "nvidia,tegra114-dfll", + .data = &tegra114_dfll_fcpu_data, + }, + { .compatible = "nvidia,tegra124-dfll", .data = &tegra124_dfll_fcpu_data, }, diff --git a/drivers/clk/tegra/clk-tegra210-emc.c b/drivers/clk/tegra/clk-tegra210-emc.c index 672ca8c184d2..fbf3c894eb56 100644 --- a/drivers/clk/tegra/clk-tegra210-emc.c +++ b/drivers/clk/tegra/clk-tegra210-emc.c @@ -86,22 +86,30 @@ static unsigned long tegra210_clk_emc_recalc_rate(struct clk_hw *hw, return DIV_ROUND_UP(parent_rate * 2, div); } -static long tegra210_clk_emc_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *prate) +static int tegra210_clk_emc_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { struct tegra210_clk_emc *emc = to_tegra210_clk_emc(hw); struct tegra210_clk_emc_provider *provider = emc->provider; unsigned int i; - if (!provider || !provider->configs || provider->num_configs == 0) - return clk_hw_get_rate(hw); + if (!provider || !provider->configs || provider->num_configs == 0) { + req->rate = clk_hw_get_rate(hw); + + return 0; + } for (i = 0; i < provider->num_configs; i++) { - if (provider->configs[i].rate >= rate) - return provider->configs[i].rate; + if (provider->configs[i].rate >= req->rate) { + req->rate = provider->configs[i].rate; + + return 0; + } } - return provider->configs[i - 1].rate; + req->rate = provider->configs[i - 1].rate; + + return 0; } static struct clk *tegra210_clk_emc_find_parent(struct tegra210_clk_emc *emc, @@ -259,7 +267,7 @@ static int tegra210_clk_emc_set_rate(struct clk_hw *hw, unsigned long rate, static const struct clk_ops tegra210_clk_emc_ops = { .get_parent = tegra210_clk_emc_get_parent, .recalc_rate = tegra210_clk_emc_recalc_rate, - .round_rate = tegra210_clk_emc_round_rate, + .determine_rate = tegra210_clk_emc_determine_rate, .set_rate = tegra210_clk_emc_set_rate, }; diff --git a/drivers/clk/tegra/clk.h b/drivers/clk/tegra/clk.h index 9ea839af14bc..73efd2ff37c9 100644 --- a/drivers/clk/tegra/clk.h +++ b/drivers/clk/tegra/clk.h @@ -897,8 +897,6 @@ static inline bool tegra124_clk_emc_driver_available(struct clk_hw *emc_hw) void tegra114_clock_tune_cpu_trimmers_high(void); void tegra114_clock_tune_cpu_trimmers_low(void); void tegra114_clock_tune_cpu_trimmers_init(void); -void tegra114_clock_assert_dfll_dvco_reset(void); -void tegra114_clock_deassert_dfll_dvco_reset(void); typedef void (*tegra_clk_apply_init_table_func)(void); extern tegra_clk_apply_init_table_func tegra_clk_apply_init_table; diff --git a/drivers/clk/thead/clk-th1520-ap.c b/drivers/clk/thead/clk-th1520-ap.c index cf1bba58f641..71ad03a998e8 100644 --- a/drivers/clk/thead/clk-th1520-ap.c +++ b/drivers/clk/thead/clk-th1520-ap.c @@ -18,6 +18,7 @@ #define TH1520_PLL_FBDIV GENMASK(19, 8) #define TH1520_PLL_REFDIV GENMASK(5, 0) #define TH1520_PLL_BYPASS BIT(30) +#define TH1520_PLL_VCO_RST BIT(29) #define TH1520_PLL_DSMPD BIT(24) #define TH1520_PLL_FRAC GENMASK(23, 0) #define TH1520_PLL_FRAC_BITS 24 @@ -48,12 +49,14 @@ struct ccu_mux { }; struct ccu_gate { - u32 enable; - struct ccu_common common; + int clkid; + u32 reg; + struct clk_gate gate; }; struct ccu_div { u32 enable; + u32 div_en; struct ccu_div_internal div; struct ccu_internal mux; struct ccu_common common; @@ -87,12 +90,12 @@ struct ccu_pll { 0), \ } -#define CCU_GATE(_clkid, _struct, _name, _parent, _reg, _gate, _flags) \ +#define CCU_GATE(_clkid, _struct, _name, _parent, _reg, _bit, _flags) \ struct ccu_gate _struct = { \ - .enable = _gate, \ - .common = { \ - .clkid = _clkid, \ - .cfg0 = _reg, \ + .clkid = _clkid, \ + .reg = _reg, \ + .gate = { \ + .bit_idx = _bit, \ .hw.init = CLK_HW_INIT_PARENTS_DATA( \ _name, \ _parent, \ @@ -120,13 +123,6 @@ static inline struct ccu_div *hw_to_ccu_div(struct clk_hw *hw) return container_of(common, struct ccu_div, common); } -static inline struct ccu_gate *hw_to_ccu_gate(struct clk_hw *hw) -{ - struct ccu_common *common = hw_to_ccu_common(hw); - - return container_of(common, struct ccu_gate, common); -} - static u8 ccu_get_parent_helper(struct ccu_common *common, struct ccu_internal *mux) { @@ -197,6 +193,55 @@ static unsigned long ccu_div_recalc_rate(struct clk_hw *hw, return rate; } +static int ccu_div_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) +{ + struct ccu_div *cd = hw_to_ccu_div(hw); + unsigned int val; + + if (cd->div_en) + return divider_determine_rate(hw, req, NULL, + cd->div.width, cd->div.flags); + + regmap_read(cd->common.map, cd->common.cfg0, &val); + val = val >> cd->div.shift; + val &= GENMASK(cd->div.width - 1, 0); + return divider_ro_determine_rate(hw, req, NULL, cd->div.width, + cd->div.flags, val); +} + +static int ccu_div_set_rate(struct clk_hw *hw, unsigned long rate, + unsigned long parent_rate) +{ + struct ccu_div *cd = hw_to_ccu_div(hw); + int val = divider_get_val(rate, parent_rate, NULL, + cd->div.width, cd->div.flags); + unsigned int curr_val, reg_val; + + if (val < 0) + return val; + + regmap_read(cd->common.map, cd->common.cfg0, ®_val); + curr_val = reg_val >> cd->div.shift; + curr_val &= GENMASK(cd->div.width - 1, 0); + + if (!cd->div_en && curr_val != val) + return -EINVAL; + + reg_val &= ~cd->div_en; + regmap_write(cd->common.map, cd->common.cfg0, reg_val); + udelay(1); + + reg_val &= ~GENMASK(cd->div.width + cd->div.shift - 1, cd->div.shift); + reg_val |= val << cd->div.shift; + regmap_write(cd->common.map, cd->common.cfg0, reg_val); + + reg_val |= cd->div_en; + regmap_write(cd->common.map, cd->common.cfg0, reg_val); + + return 0; +} + static u8 ccu_div_get_parent(struct clk_hw *hw) { struct ccu_div *cd = hw_to_ccu_div(hw); @@ -239,9 +284,34 @@ static const struct clk_ops ccu_div_ops = { .get_parent = ccu_div_get_parent, .set_parent = ccu_div_set_parent, .recalc_rate = ccu_div_recalc_rate, - .determine_rate = clk_hw_determine_rate_no_reparent, + .set_rate = ccu_div_set_rate, + .determine_rate = ccu_div_determine_rate, }; +static void ccu_pll_disable(struct clk_hw *hw) +{ + struct ccu_pll *pll = hw_to_ccu_pll(hw); + + regmap_set_bits(pll->common.map, pll->common.cfg1, + TH1520_PLL_VCO_RST); +} + +static int ccu_pll_enable(struct clk_hw *hw) +{ + struct ccu_pll *pll = hw_to_ccu_pll(hw); + + return regmap_clear_bits(pll->common.map, pll->common.cfg1, + TH1520_PLL_VCO_RST); +} + +static int ccu_pll_is_enabled(struct clk_hw *hw) +{ + struct ccu_pll *pll = hw_to_ccu_pll(hw); + + return !regmap_test_bits(pll->common.map, pll->common.cfg1, + TH1520_PLL_VCO_RST); +} + static unsigned long th1520_pll_vco_recalc_rate(struct clk_hw *hw, unsigned long parent_rate) { @@ -299,6 +369,9 @@ static unsigned long ccu_pll_recalc_rate(struct clk_hw *hw, } static const struct clk_ops clk_pll_ops = { + .disable = ccu_pll_disable, + .enable = ccu_pll_enable, + .is_enabled = ccu_pll_is_enabled, .recalc_rate = ccu_pll_recalc_rate, }; @@ -314,7 +387,7 @@ static struct ccu_pll cpu_pll0_clk = { .hw.init = CLK_HW_INIT_PARENTS_DATA("cpu-pll0", osc_24m_clk, &clk_pll_ops, - 0), + CLK_IS_CRITICAL), }, }; @@ -326,7 +399,7 @@ static struct ccu_pll cpu_pll1_clk = { .hw.init = CLK_HW_INIT_PARENTS_DATA("cpu-pll1", osc_24m_clk, &clk_pll_ops, - 0), + CLK_IS_CRITICAL), }, }; @@ -338,7 +411,7 @@ static struct ccu_pll gmac_pll_clk = { .hw.init = CLK_HW_INIT_PARENTS_DATA("gmac-pll", osc_24m_clk, &clk_pll_ops, - 0), + CLK_IS_CRITICAL), }, }; @@ -358,7 +431,7 @@ static struct ccu_pll video_pll_clk = { .hw.init = CLK_HW_INIT_PARENTS_DATA("video-pll", osc_24m_clk, &clk_pll_ops, - 0), + CLK_IS_CRITICAL), }, }; @@ -410,7 +483,7 @@ static struct ccu_pll tee_pll_clk = { .hw.init = CLK_HW_INIT_PARENTS_DATA("tee-pll", osc_24m_clk, &clk_pll_ops, - 0), + CLK_IS_CRITICAL), }, }; @@ -486,7 +559,7 @@ static struct ccu_div axi4_cpusys2_aclk = { .hw.init = CLK_HW_INIT_PARENTS_HW("axi4-cpusys2-aclk", gmac_pll_clk_parent, &ccu_div_ops, - 0), + CLK_IS_CRITICAL), }, }; @@ -508,7 +581,7 @@ static struct ccu_div axi_aclk = { .hw.init = CLK_HW_INIT_PARENTS_DATA("axi-aclk", axi_parents, &ccu_div_ops, - 0), + CLK_IS_CRITICAL), }, }; @@ -657,7 +730,7 @@ static struct ccu_div apb_pclk = { .hw.init = CLK_HW_INIT_PARENTS_DATA("apb-pclk", apb_parents, &ccu_div_ops, - CLK_IGNORE_UNUSED), + CLK_IS_CRITICAL), }, }; @@ -688,7 +761,7 @@ static struct ccu_div vi_clk = { .hw.init = CLK_HW_INIT_PARENTS_HW("vi", video_pll_clk_parent, &ccu_div_ops, - 0), + CLK_IS_CRITICAL), }, }; @@ -713,7 +786,7 @@ static struct ccu_div vo_axi_clk = { .hw.init = CLK_HW_INIT_PARENTS_HW("vo-axi", video_pll_clk_parent, &ccu_div_ops, - 0), + CLK_IS_CRITICAL), }, }; @@ -738,7 +811,7 @@ static struct ccu_div vp_axi_clk = { .hw.init = CLK_HW_INIT_PARENTS_HW("vp-axi", video_pll_clk_parent, &ccu_div_ops, - CLK_IGNORE_UNUSED), + CLK_IS_CRITICAL), }, }; @@ -756,6 +829,7 @@ static struct ccu_div venc_clk = { }; static struct ccu_div dpu0_clk = { + .div_en = BIT(8), .div = TH_CCU_DIV_FLAGS(0, 8, CLK_DIVIDER_ONE_BASED), .common = { .clkid = CLK_DPU0, @@ -763,11 +837,16 @@ static struct ccu_div dpu0_clk = { .hw.init = CLK_HW_INIT_PARENTS_HW("dpu0", dpu0_pll_clk_parent, &ccu_div_ops, - 0), + CLK_SET_RATE_UNGATE), }, }; +static const struct clk_parent_data dpu0_clk_pd[] = { + { .hw = &dpu0_clk.common.hw } +}; + static struct ccu_div dpu1_clk = { + .div_en = BIT(8), .div = TH_CCU_DIV_FLAGS(0, 8, CLK_DIVIDER_ONE_BASED), .common = { .clkid = CLK_DPU1, @@ -775,10 +854,14 @@ static struct ccu_div dpu1_clk = { .hw.init = CLK_HW_INIT_PARENTS_HW("dpu1", dpu1_pll_clk_parent, &ccu_div_ops, - 0), + CLK_SET_RATE_UNGATE), }, }; +static const struct clk_parent_data dpu1_clk_pd[] = { + { .hw = &dpu1_clk.common.hw } +}; + static CLK_FIXED_FACTOR_HW(emmc_sdio_ref_clk, "emmc-sdio-ref", &video_pll_clk.common.hw, 4, 1, 0); @@ -786,128 +869,132 @@ static const struct clk_parent_data emmc_sdio_ref_clk_pd[] = { { .hw = &emmc_sdio_ref_clk.hw }, }; -static CCU_GATE(CLK_BROM, brom_clk, "brom", ahb2_cpusys_hclk_pd, 0x100, BIT(4), 0); -static CCU_GATE(CLK_BMU, bmu_clk, "bmu", axi4_cpusys2_aclk_pd, 0x100, BIT(5), 0); +static CCU_GATE(CLK_BROM, brom_clk, "brom", ahb2_cpusys_hclk_pd, 0x100, 4, 0); +static CCU_GATE(CLK_BMU, bmu_clk, "bmu", axi4_cpusys2_aclk_pd, 0x100, 5, 0); static CCU_GATE(CLK_AON2CPU_A2X, aon2cpu_a2x_clk, "aon2cpu-a2x", axi4_cpusys2_aclk_pd, - 0x134, BIT(8), 0); + 0x134, 8, CLK_IS_CRITICAL); static CCU_GATE(CLK_X2X_CPUSYS, x2x_cpusys_clk, "x2x-cpusys", axi4_cpusys2_aclk_pd, - 0x134, BIT(7), 0); + 0x134, 7, CLK_IS_CRITICAL); static CCU_GATE(CLK_CPU2AON_X2H, cpu2aon_x2h_clk, "cpu2aon-x2h", axi_aclk_pd, - 0x138, BIT(8), CLK_IGNORE_UNUSED); + 0x138, 8, CLK_IS_CRITICAL); static CCU_GATE(CLK_CPU2PERI_X2H, cpu2peri_x2h_clk, "cpu2peri-x2h", axi4_cpusys2_aclk_pd, - 0x140, BIT(9), CLK_IGNORE_UNUSED); + 0x140, 9, CLK_IS_CRITICAL); static CCU_GATE(CLK_PERISYS_APB1_HCLK, perisys_apb1_hclk, "perisys-apb1-hclk", perisys_ahb_hclk_pd, - 0x150, BIT(9), CLK_IGNORE_UNUSED); + 0x150, 9, CLK_IS_CRITICAL); static CCU_GATE(CLK_PERISYS_APB2_HCLK, perisys_apb2_hclk, "perisys-apb2-hclk", perisys_ahb_hclk_pd, - 0x150, BIT(10), CLK_IGNORE_UNUSED); + 0x150, 10, CLK_IS_CRITICAL); static CCU_GATE(CLK_PERISYS_APB3_HCLK, perisys_apb3_hclk, "perisys-apb3-hclk", perisys_ahb_hclk_pd, - 0x150, BIT(11), CLK_IGNORE_UNUSED); + 0x150, 11, CLK_IS_CRITICAL); static CCU_GATE(CLK_PERISYS_APB4_HCLK, perisys_apb4_hclk, "perisys-apb4-hclk", perisys_ahb_hclk_pd, - 0x150, BIT(12), 0); -static CCU_GATE(CLK_NPU_AXI, npu_axi_clk, "npu-axi", axi_aclk_pd, 0x1c8, BIT(5), 0); -static CCU_GATE(CLK_CPU2VP, cpu2vp_clk, "cpu2vp", axi_aclk_pd, 0x1e0, BIT(13), 0); -static CCU_GATE(CLK_EMMC_SDIO, emmc_sdio_clk, "emmc-sdio", emmc_sdio_ref_clk_pd, 0x204, BIT(30), 0); -static CCU_GATE(CLK_GMAC1, gmac1_clk, "gmac1", gmac_pll_clk_pd, 0x204, BIT(26), 0); -static CCU_GATE(CLK_PADCTRL1, padctrl1_clk, "padctrl1", perisys_apb_pclk_pd, 0x204, BIT(24), 0); -static CCU_GATE(CLK_DSMART, dsmart_clk, "dsmart", perisys_apb_pclk_pd, 0x204, BIT(23), 0); -static CCU_GATE(CLK_PADCTRL0, padctrl0_clk, "padctrl0", perisys_apb_pclk_pd, 0x204, BIT(22), 0); -static CCU_GATE(CLK_GMAC_AXI, gmac_axi_clk, "gmac-axi", axi4_cpusys2_aclk_pd, 0x204, BIT(21), 0); -static CCU_GATE(CLK_GPIO3, gpio3_clk, "gpio3-clk", peri2sys_apb_pclk_pd, 0x204, BIT(20), 0); -static CCU_GATE(CLK_GMAC0, gmac0_clk, "gmac0", gmac_pll_clk_pd, 0x204, BIT(19), 0); -static CCU_GATE(CLK_PWM, pwm_clk, "pwm", perisys_apb_pclk_pd, 0x204, BIT(18), 0); -static CCU_GATE(CLK_QSPI0, qspi0_clk, "qspi0", video_pll_clk_pd, 0x204, BIT(17), 0); -static CCU_GATE(CLK_QSPI1, qspi1_clk, "qspi1", video_pll_clk_pd, 0x204, BIT(16), 0); -static CCU_GATE(CLK_SPI, spi_clk, "spi", video_pll_clk_pd, 0x204, BIT(15), 0); -static CCU_GATE(CLK_UART0_PCLK, uart0_pclk, "uart0-pclk", perisys_apb_pclk_pd, 0x204, BIT(14), 0); -static CCU_GATE(CLK_UART1_PCLK, uart1_pclk, "uart1-pclk", perisys_apb_pclk_pd, 0x204, BIT(13), 0); -static CCU_GATE(CLK_UART2_PCLK, uart2_pclk, "uart2-pclk", perisys_apb_pclk_pd, 0x204, BIT(12), 0); -static CCU_GATE(CLK_UART3_PCLK, uart3_pclk, "uart3-pclk", perisys_apb_pclk_pd, 0x204, BIT(11), 0); -static CCU_GATE(CLK_UART4_PCLK, uart4_pclk, "uart4-pclk", perisys_apb_pclk_pd, 0x204, BIT(10), 0); -static CCU_GATE(CLK_UART5_PCLK, uart5_pclk, "uart5-pclk", perisys_apb_pclk_pd, 0x204, BIT(9), 0); -static CCU_GATE(CLK_GPIO0, gpio0_clk, "gpio0-clk", perisys_apb_pclk_pd, 0x204, BIT(8), 0); -static CCU_GATE(CLK_GPIO1, gpio1_clk, "gpio1-clk", perisys_apb_pclk_pd, 0x204, BIT(7), 0); -static CCU_GATE(CLK_GPIO2, gpio2_clk, "gpio2-clk", peri2sys_apb_pclk_pd, 0x204, BIT(6), 0); -static CCU_GATE(CLK_I2C0, i2c0_clk, "i2c0", perisys_apb_pclk_pd, 0x204, BIT(5), 0); -static CCU_GATE(CLK_I2C1, i2c1_clk, "i2c1", perisys_apb_pclk_pd, 0x204, BIT(4), 0); -static CCU_GATE(CLK_I2C2, i2c2_clk, "i2c2", perisys_apb_pclk_pd, 0x204, BIT(3), 0); -static CCU_GATE(CLK_I2C3, i2c3_clk, "i2c3", perisys_apb_pclk_pd, 0x204, BIT(2), 0); -static CCU_GATE(CLK_I2C4, i2c4_clk, "i2c4", perisys_apb_pclk_pd, 0x204, BIT(1), 0); -static CCU_GATE(CLK_I2C5, i2c5_clk, "i2c5", perisys_apb_pclk_pd, 0x204, BIT(0), 0); -static CCU_GATE(CLK_SPINLOCK, spinlock_clk, "spinlock", ahb2_cpusys_hclk_pd, 0x208, BIT(10), 0); -static CCU_GATE(CLK_DMA, dma_clk, "dma", axi4_cpusys2_aclk_pd, 0x208, BIT(8), 0); -static CCU_GATE(CLK_MBOX0, mbox0_clk, "mbox0", apb3_cpusys_pclk_pd, 0x208, BIT(7), 0); -static CCU_GATE(CLK_MBOX1, mbox1_clk, "mbox1", apb3_cpusys_pclk_pd, 0x208, BIT(6), 0); -static CCU_GATE(CLK_MBOX2, mbox2_clk, "mbox2", apb3_cpusys_pclk_pd, 0x208, BIT(5), 0); -static CCU_GATE(CLK_MBOX3, mbox3_clk, "mbox3", apb3_cpusys_pclk_pd, 0x208, BIT(4), 0); -static CCU_GATE(CLK_WDT0, wdt0_clk, "wdt0", apb3_cpusys_pclk_pd, 0x208, BIT(3), 0); -static CCU_GATE(CLK_WDT1, wdt1_clk, "wdt1", apb3_cpusys_pclk_pd, 0x208, BIT(2), 0); -static CCU_GATE(CLK_TIMER0, timer0_clk, "timer0", apb3_cpusys_pclk_pd, 0x208, BIT(1), 0); -static CCU_GATE(CLK_TIMER1, timer1_clk, "timer1", apb3_cpusys_pclk_pd, 0x208, BIT(0), 0); -static CCU_GATE(CLK_SRAM0, sram0_clk, "sram0", axi_aclk_pd, 0x20c, BIT(4), 0); -static CCU_GATE(CLK_SRAM1, sram1_clk, "sram1", axi_aclk_pd, 0x20c, BIT(3), 0); -static CCU_GATE(CLK_SRAM2, sram2_clk, "sram2", axi_aclk_pd, 0x20c, BIT(2), 0); -static CCU_GATE(CLK_SRAM3, sram3_clk, "sram3", axi_aclk_pd, 0x20c, BIT(1), 0); + 0x150, 12, 0); +static const struct clk_parent_data perisys_apb4_hclk_pd[] = { + { .hw = &perisys_apb4_hclk.gate.hw }, +}; + +static CCU_GATE(CLK_NPU_AXI, npu_axi_clk, "npu-axi", axi_aclk_pd, 0x1c8, 5, CLK_IS_CRITICAL); +static CCU_GATE(CLK_CPU2VP, cpu2vp_clk, "cpu2vp", axi_aclk_pd, 0x1e0, 13, CLK_IS_CRITICAL); +static CCU_GATE(CLK_EMMC_SDIO, emmc_sdio_clk, "emmc-sdio", emmc_sdio_ref_clk_pd, 0x204, 30, 0); +static CCU_GATE(CLK_GMAC1, gmac1_clk, "gmac1", gmac_pll_clk_pd, 0x204, 26, 0); +static CCU_GATE(CLK_PADCTRL1, padctrl1_clk, "padctrl1", perisys_apb_pclk_pd, 0x204, 24, 0); +static CCU_GATE(CLK_DSMART, dsmart_clk, "dsmart", perisys_apb_pclk_pd, 0x204, 23, 0); +static CCU_GATE(CLK_PADCTRL0, padctrl0_clk, "padctrl0", perisys_apb4_hclk_pd, 0x204, 22, 0); +static CCU_GATE(CLK_GMAC_AXI, gmac_axi_clk, "gmac-axi", axi4_cpusys2_aclk_pd, 0x204, 21, 0); +static CCU_GATE(CLK_GPIO3, gpio3_clk, "gpio3-clk", peri2sys_apb_pclk_pd, 0x204, 20, 0); +static CCU_GATE(CLK_GMAC0, gmac0_clk, "gmac0", gmac_pll_clk_pd, 0x204, 19, 0); +static CCU_GATE(CLK_PWM, pwm_clk, "pwm", perisys_apb_pclk_pd, 0x204, 18, 0); +static CCU_GATE(CLK_QSPI0, qspi0_clk, "qspi0", video_pll_clk_pd, 0x204, 17, 0); +static CCU_GATE(CLK_QSPI1, qspi1_clk, "qspi1", video_pll_clk_pd, 0x204, 16, 0); +static CCU_GATE(CLK_SPI, spi_clk, "spi", video_pll_clk_pd, 0x204, 15, 0); +static CCU_GATE(CLK_UART0_PCLK, uart0_pclk, "uart0-pclk", perisys_apb_pclk_pd, 0x204, 14, 0); +static CCU_GATE(CLK_UART1_PCLK, uart1_pclk, "uart1-pclk", perisys_apb_pclk_pd, 0x204, 13, 0); +static CCU_GATE(CLK_UART2_PCLK, uart2_pclk, "uart2-pclk", perisys_apb_pclk_pd, 0x204, 12, 0); +static CCU_GATE(CLK_UART3_PCLK, uart3_pclk, "uart3-pclk", perisys_apb_pclk_pd, 0x204, 11, 0); +static CCU_GATE(CLK_UART4_PCLK, uart4_pclk, "uart4-pclk", perisys_apb_pclk_pd, 0x204, 10, 0); +static CCU_GATE(CLK_UART5_PCLK, uart5_pclk, "uart5-pclk", perisys_apb_pclk_pd, 0x204, 9, 0); +static CCU_GATE(CLK_GPIO0, gpio0_clk, "gpio0-clk", perisys_apb_pclk_pd, 0x204, 8, 0); +static CCU_GATE(CLK_GPIO1, gpio1_clk, "gpio1-clk", perisys_apb_pclk_pd, 0x204, 7, 0); +static CCU_GATE(CLK_GPIO2, gpio2_clk, "gpio2-clk", peri2sys_apb_pclk_pd, 0x204, 6, 0); +static CCU_GATE(CLK_I2C0, i2c0_clk, "i2c0", perisys_apb_pclk_pd, 0x204, 5, 0); +static CCU_GATE(CLK_I2C1, i2c1_clk, "i2c1", perisys_apb_pclk_pd, 0x204, 4, 0); +static CCU_GATE(CLK_I2C2, i2c2_clk, "i2c2", perisys_apb_pclk_pd, 0x204, 3, 0); +static CCU_GATE(CLK_I2C3, i2c3_clk, "i2c3", perisys_apb_pclk_pd, 0x204, 2, 0); +static CCU_GATE(CLK_I2C4, i2c4_clk, "i2c4", perisys_apb_pclk_pd, 0x204, 1, 0); +static CCU_GATE(CLK_I2C5, i2c5_clk, "i2c5", perisys_apb_pclk_pd, 0x204, 0, 0); +static CCU_GATE(CLK_SPINLOCK, spinlock_clk, "spinlock", ahb2_cpusys_hclk_pd, 0x208, 10, 0); +static CCU_GATE(CLK_DMA, dma_clk, "dma", axi4_cpusys2_aclk_pd, 0x208, 8, 0); +static CCU_GATE(CLK_MBOX0, mbox0_clk, "mbox0", apb3_cpusys_pclk_pd, 0x208, 7, 0); +static CCU_GATE(CLK_MBOX1, mbox1_clk, "mbox1", apb3_cpusys_pclk_pd, 0x208, 6, 0); +static CCU_GATE(CLK_MBOX2, mbox2_clk, "mbox2", apb3_cpusys_pclk_pd, 0x208, 5, 0); +static CCU_GATE(CLK_MBOX3, mbox3_clk, "mbox3", apb3_cpusys_pclk_pd, 0x208, 4, 0); +static CCU_GATE(CLK_WDT0, wdt0_clk, "wdt0", apb3_cpusys_pclk_pd, 0x208, 3, 0); +static CCU_GATE(CLK_WDT1, wdt1_clk, "wdt1", apb3_cpusys_pclk_pd, 0x208, 2, 0); +static CCU_GATE(CLK_TIMER0, timer0_clk, "timer0", apb3_cpusys_pclk_pd, 0x208, 1, 0); +static CCU_GATE(CLK_TIMER1, timer1_clk, "timer1", apb3_cpusys_pclk_pd, 0x208, 0, 0); +static CCU_GATE(CLK_SRAM0, sram0_clk, "sram0", axi_aclk_pd, 0x20c, 4, 0); +static CCU_GATE(CLK_SRAM1, sram1_clk, "sram1", axi_aclk_pd, 0x20c, 3, 0); +static CCU_GATE(CLK_SRAM2, sram2_clk, "sram2", axi_aclk_pd, 0x20c, 2, 0); +static CCU_GATE(CLK_SRAM3, sram3_clk, "sram3", axi_aclk_pd, 0x20c, 1, 0); static CCU_GATE(CLK_AXI4_VO_ACLK, axi4_vo_aclk, "axi4-vo-aclk", - video_pll_clk_pd, 0x0, BIT(0), 0); + video_pll_clk_pd, 0x0, 0, CLK_IS_CRITICAL); static CCU_GATE(CLK_GPU_CORE, gpu_core_clk, "gpu-core-clk", video_pll_clk_pd, - 0x0, BIT(3), 0); + 0x0, 3, 0); static CCU_GATE(CLK_GPU_CFG_ACLK, gpu_cfg_aclk, "gpu-cfg-aclk", - video_pll_clk_pd, 0x0, BIT(4), 0); + video_pll_clk_pd, 0x0, 4, CLK_IS_CRITICAL); static CCU_GATE(CLK_DPU_PIXELCLK0, dpu0_pixelclk, "dpu0-pixelclk", - video_pll_clk_pd, 0x0, BIT(5), 0); + dpu0_clk_pd, 0x0, 5, CLK_SET_RATE_PARENT); static CCU_GATE(CLK_DPU_PIXELCLK1, dpu1_pixelclk, "dpu1-pixelclk", - video_pll_clk_pd, 0x0, BIT(6), 0); + dpu1_clk_pd, 0x0, 6, CLK_SET_RATE_PARENT); static CCU_GATE(CLK_DPU_HCLK, dpu_hclk, "dpu-hclk", video_pll_clk_pd, 0x0, - BIT(7), 0); + 7, 0); static CCU_GATE(CLK_DPU_ACLK, dpu_aclk, "dpu-aclk", video_pll_clk_pd, 0x0, - BIT(8), 0); + 8, 0); static CCU_GATE(CLK_DPU_CCLK, dpu_cclk, "dpu-cclk", video_pll_clk_pd, 0x0, - BIT(9), 0); + 9, 0); static CCU_GATE(CLK_HDMI_SFR, hdmi_sfr_clk, "hdmi-sfr-clk", video_pll_clk_pd, - 0x0, BIT(10), 0); + 0x0, 10, 0); static CCU_GATE(CLK_HDMI_PCLK, hdmi_pclk, "hdmi-pclk", video_pll_clk_pd, 0x0, - BIT(11), 0); + 11, 0); static CCU_GATE(CLK_HDMI_CEC, hdmi_cec_clk, "hdmi-cec-clk", video_pll_clk_pd, - 0x0, BIT(12), 0); + 0x0, 12, 0); static CCU_GATE(CLK_MIPI_DSI0_PCLK, mipi_dsi0_pclk, "mipi-dsi0-pclk", - video_pll_clk_pd, 0x0, BIT(13), 0); + video_pll_clk_pd, 0x0, 13, 0); static CCU_GATE(CLK_MIPI_DSI1_PCLK, mipi_dsi1_pclk, "mipi-dsi1-pclk", - video_pll_clk_pd, 0x0, BIT(14), 0); + video_pll_clk_pd, 0x0, 14, 0); static CCU_GATE(CLK_MIPI_DSI0_CFG, mipi_dsi0_cfg_clk, "mipi-dsi0-cfg-clk", - video_pll_clk_pd, 0x0, BIT(15), 0); + video_pll_clk_pd, 0x0, 15, 0); static CCU_GATE(CLK_MIPI_DSI1_CFG, mipi_dsi1_cfg_clk, "mipi-dsi1-cfg-clk", - video_pll_clk_pd, 0x0, BIT(16), 0); + video_pll_clk_pd, 0x0, 16, 0); static CCU_GATE(CLK_MIPI_DSI0_REFCLK, mipi_dsi0_refclk, "mipi-dsi0-refclk", - video_pll_clk_pd, 0x0, BIT(17), 0); + video_pll_clk_pd, 0x0, 17, 0); static CCU_GATE(CLK_MIPI_DSI1_REFCLK, mipi_dsi1_refclk, "mipi-dsi1-refclk", - video_pll_clk_pd, 0x0, BIT(18), 0); + video_pll_clk_pd, 0x0, 18, 0); static CCU_GATE(CLK_HDMI_I2S, hdmi_i2s_clk, "hdmi-i2s-clk", video_pll_clk_pd, - 0x0, BIT(19), 0); + 0x0, 19, 0); static CCU_GATE(CLK_X2H_DPU1_ACLK, x2h_dpu1_aclk, "x2h-dpu1-aclk", - video_pll_clk_pd, 0x0, BIT(20), 0); + video_pll_clk_pd, 0x0, 20, CLK_IS_CRITICAL); static CCU_GATE(CLK_X2H_DPU_ACLK, x2h_dpu_aclk, "x2h-dpu-aclk", - video_pll_clk_pd, 0x0, BIT(21), 0); + video_pll_clk_pd, 0x0, 21, CLK_IS_CRITICAL); static CCU_GATE(CLK_AXI4_VO_PCLK, axi4_vo_pclk, "axi4-vo-pclk", - video_pll_clk_pd, 0x0, BIT(22), 0); + video_pll_clk_pd, 0x0, 22, 0); static CCU_GATE(CLK_IOPMP_VOSYS_DPU_PCLK, iopmp_vosys_dpu_pclk, - "iopmp-vosys-dpu-pclk", video_pll_clk_pd, 0x0, BIT(23), 0); + "iopmp-vosys-dpu-pclk", video_pll_clk_pd, 0x0, 23, 0); static CCU_GATE(CLK_IOPMP_VOSYS_DPU1_PCLK, iopmp_vosys_dpu1_pclk, - "iopmp-vosys-dpu1-pclk", video_pll_clk_pd, 0x0, BIT(24), 0); + "iopmp-vosys-dpu1-pclk", video_pll_clk_pd, 0x0, 24, 0); static CCU_GATE(CLK_IOPMP_VOSYS_GPU_PCLK, iopmp_vosys_gpu_pclk, - "iopmp-vosys-gpu-pclk", video_pll_clk_pd, 0x0, BIT(25), 0); + "iopmp-vosys-gpu-pclk", video_pll_clk_pd, 0x0, 25, 0); static CCU_GATE(CLK_IOPMP_DPU1_ACLK, iopmp_dpu1_aclk, "iopmp-dpu1-aclk", - video_pll_clk_pd, 0x0, BIT(27), 0); + video_pll_clk_pd, 0x0, 27, CLK_IS_CRITICAL); static CCU_GATE(CLK_IOPMP_DPU_ACLK, iopmp_dpu_aclk, "iopmp-dpu-aclk", - video_pll_clk_pd, 0x0, BIT(28), 0); + video_pll_clk_pd, 0x0, 28, CLK_IS_CRITICAL); static CCU_GATE(CLK_IOPMP_GPU_ACLK, iopmp_gpu_aclk, "iopmp-gpu-aclk", - video_pll_clk_pd, 0x0, BIT(29), 0); + video_pll_clk_pd, 0x0, 29, CLK_IS_CRITICAL); static CCU_GATE(CLK_MIPIDSI0_PIXCLK, mipi_dsi0_pixclk, "mipi-dsi0-pixclk", - video_pll_clk_pd, 0x0, BIT(30), 0); + video_pll_clk_pd, 0x0, 30, 0); static CCU_GATE(CLK_MIPIDSI1_PIXCLK, mipi_dsi1_pixclk, "mipi-dsi1-pixclk", - video_pll_clk_pd, 0x0, BIT(31), 0); + video_pll_clk_pd, 0x0, 31, 0); static CCU_GATE(CLK_HDMI_PIXCLK, hdmi_pixclk, "hdmi-pixclk", video_pll_clk_pd, - 0x4, BIT(0), 0); + 0x4, 0, 0); static CLK_FIXED_FACTOR_HW(gmac_pll_clk_100m, "gmac-pll-clk-100m", &gmac_pll_clk.common.hw, 10, 1, 0); @@ -963,107 +1050,106 @@ static struct ccu_mux *th1520_mux_clks[] = { &uart_sclk, }; -static struct ccu_common *th1520_gate_clks[] = { - &emmc_sdio_clk.common, - &aon2cpu_a2x_clk.common, - &x2x_cpusys_clk.common, - &brom_clk.common, - &bmu_clk.common, - &cpu2aon_x2h_clk.common, - &cpu2peri_x2h_clk.common, - &cpu2vp_clk.common, - &perisys_apb1_hclk.common, - &perisys_apb2_hclk.common, - &perisys_apb3_hclk.common, - &perisys_apb4_hclk.common, - &npu_axi_clk.common, - &gmac1_clk.common, - &padctrl1_clk.common, - &dsmart_clk.common, - &padctrl0_clk.common, - &gmac_axi_clk.common, - &gpio3_clk.common, - &gmac0_clk.common, - &pwm_clk.common, - &qspi0_clk.common, - &qspi1_clk.common, - &spi_clk.common, - &uart0_pclk.common, - &uart1_pclk.common, - &uart2_pclk.common, - &uart3_pclk.common, - &uart4_pclk.common, - &uart5_pclk.common, - &gpio0_clk.common, - &gpio1_clk.common, - &gpio2_clk.common, - &i2c0_clk.common, - &i2c1_clk.common, - &i2c2_clk.common, - &i2c3_clk.common, - &i2c4_clk.common, - &i2c5_clk.common, - &spinlock_clk.common, - &dma_clk.common, - &mbox0_clk.common, - &mbox1_clk.common, - &mbox2_clk.common, - &mbox3_clk.common, - &wdt0_clk.common, - &wdt1_clk.common, - &timer0_clk.common, - &timer1_clk.common, - &sram0_clk.common, - &sram1_clk.common, - &sram2_clk.common, - &sram3_clk.common, -}; - -static struct ccu_common *th1520_vo_gate_clks[] = { - &axi4_vo_aclk.common, - &gpu_core_clk.common, - &gpu_cfg_aclk.common, - &dpu0_pixelclk.common, - &dpu1_pixelclk.common, - &dpu_hclk.common, - &dpu_aclk.common, - &dpu_cclk.common, - &hdmi_sfr_clk.common, - &hdmi_pclk.common, - &hdmi_cec_clk.common, - &mipi_dsi0_pclk.common, - &mipi_dsi1_pclk.common, - &mipi_dsi0_cfg_clk.common, - &mipi_dsi1_cfg_clk.common, - &mipi_dsi0_refclk.common, - &mipi_dsi1_refclk.common, - &hdmi_i2s_clk.common, - &x2h_dpu1_aclk.common, - &x2h_dpu_aclk.common, - &axi4_vo_pclk.common, - &iopmp_vosys_dpu_pclk.common, - &iopmp_vosys_dpu1_pclk.common, - &iopmp_vosys_gpu_pclk.common, - &iopmp_dpu1_aclk.common, - &iopmp_dpu_aclk.common, - &iopmp_gpu_aclk.common, - &mipi_dsi0_pixclk.common, - &mipi_dsi1_pixclk.common, - &hdmi_pixclk.common +static struct ccu_gate *th1520_gate_clks[] = { + &emmc_sdio_clk, + &aon2cpu_a2x_clk, + &x2x_cpusys_clk, + &brom_clk, + &bmu_clk, + &cpu2aon_x2h_clk, + &cpu2peri_x2h_clk, + &cpu2vp_clk, + &perisys_apb1_hclk, + &perisys_apb2_hclk, + &perisys_apb3_hclk, + &perisys_apb4_hclk, + &npu_axi_clk, + &gmac1_clk, + &padctrl1_clk, + &dsmart_clk, + &padctrl0_clk, + &gmac_axi_clk, + &gpio3_clk, + &gmac0_clk, + &pwm_clk, + &qspi0_clk, + &qspi1_clk, + &spi_clk, + &uart0_pclk, + &uart1_pclk, + &uart2_pclk, + &uart3_pclk, + &uart4_pclk, + &uart5_pclk, + &gpio0_clk, + &gpio1_clk, + &gpio2_clk, + &i2c0_clk, + &i2c1_clk, + &i2c2_clk, + &i2c3_clk, + &i2c4_clk, + &i2c5_clk, + &spinlock_clk, + &dma_clk, + &mbox0_clk, + &mbox1_clk, + &mbox2_clk, + &mbox3_clk, + &wdt0_clk, + &wdt1_clk, + &timer0_clk, + &timer1_clk, + &sram0_clk, + &sram1_clk, + &sram2_clk, + &sram3_clk, +}; + +static struct ccu_gate *th1520_vo_gate_clks[] = { + &axi4_vo_aclk, + &gpu_core_clk, + &gpu_cfg_aclk, + &dpu0_pixelclk, + &dpu1_pixelclk, + &dpu_hclk, + &dpu_aclk, + &dpu_cclk, + &hdmi_sfr_clk, + &hdmi_pclk, + &hdmi_cec_clk, + &mipi_dsi0_pclk, + &mipi_dsi1_pclk, + &mipi_dsi0_cfg_clk, + &mipi_dsi1_cfg_clk, + &mipi_dsi0_refclk, + &mipi_dsi1_refclk, + &hdmi_i2s_clk, + &x2h_dpu1_aclk, + &x2h_dpu_aclk, + &axi4_vo_pclk, + &iopmp_vosys_dpu_pclk, + &iopmp_vosys_dpu1_pclk, + &iopmp_vosys_gpu_pclk, + &iopmp_dpu1_aclk, + &iopmp_dpu_aclk, + &iopmp_gpu_aclk, + &mipi_dsi0_pixclk, + &mipi_dsi1_pixclk, + &hdmi_pixclk }; static const struct regmap_config th1520_clk_regmap_config = { .reg_bits = 32, .val_bits = 32, .reg_stride = 4, - .fast_io = true, }; struct th1520_plat_data { struct ccu_common **th1520_pll_clks; struct ccu_common **th1520_div_clks; struct ccu_mux **th1520_mux_clks; - struct ccu_common **th1520_gate_clks; + struct ccu_gate **th1520_gate_clks; int nr_clks; int nr_pll_clks; @@ -1102,7 +1188,6 @@ static int th1520_clk_probe(struct platform_device *pdev) struct regmap *map; void __iomem *base; - struct clk_hw *hw; int ret, i; plat_data = device_get_match_data(&pdev->dev); @@ -1161,20 +1246,15 @@ static int th1520_clk_probe(struct platform_device *pdev) } for (i = 0; i < plat_data->nr_gate_clks; i++) { - struct ccu_gate *cg = hw_to_ccu_gate(&plat_data->th1520_gate_clks[i]->hw); + struct ccu_gate *cg = plat_data->th1520_gate_clks[i]; - plat_data->th1520_gate_clks[i]->map = map; + cg->gate.reg = base + cg->reg; - hw = devm_clk_hw_register_gate_parent_data(dev, - cg->common.hw.init->name, - cg->common.hw.init->parent_data, - cg->common.hw.init->flags, - base + cg->common.cfg0, - ffs(cg->enable) - 1, 0, NULL); - if (IS_ERR(hw)) - return PTR_ERR(hw); + ret = devm_clk_hw_register(dev, &cg->gate.hw); + if (ret) + return ret; - priv->hws[cg->common.clkid] = hw; + priv->hws[cg->clkid] = &cg->gate.hw; } if (plat_data == &th1520_ap_platdata) { diff --git a/drivers/clk/ti/clk-33xx.c b/drivers/clk/ti/clk-33xx.c index 85c50ea39e6d..9269e6a0db6a 100644 --- a/drivers/clk/ti/clk-33xx.c +++ b/drivers/clk/ti/clk-33xx.c @@ -258,6 +258,8 @@ static const char *enable_init_clks[] = { "dpll_ddr_m2_ck", "dpll_mpu_m2_ck", "l3_gclk", + /* WKUP_DEBUGSS_CLKCTRL - disable fails, AM335x Errata Advisory 1.0.42 */ + "l3-aon-clkctrl:0000:0", /* AM3_L3_L3_MAIN_CLKCTRL, needed during suspend */ "l3-clkctrl:00bc:0", "l4hs_gclk", diff --git a/drivers/clk/ti/clk-dra7-atl.c b/drivers/clk/ti/clk-dra7-atl.c index 0eab7f3e2eab..b02f84d49b96 100644 --- a/drivers/clk/ti/clk-dra7-atl.c +++ b/drivers/clk/ti/clk-dra7-atl.c @@ -120,16 +120,18 @@ static unsigned long atl_clk_recalc_rate(struct clk_hw *hw, return parent_rate / cdesc->divider; } -static long atl_clk_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *parent_rate) +static int atl_clk_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { unsigned divider; - divider = (*parent_rate + rate / 2) / rate; + divider = (req->best_parent_rate + req->rate / 2) / req->rate; if (divider > DRA7_ATL_DIVIDER_MASK + 1) divider = DRA7_ATL_DIVIDER_MASK + 1; - return *parent_rate / divider; + req->rate = req->best_parent_rate / divider; + + return 0; } static int atl_clk_set_rate(struct clk_hw *hw, unsigned long rate, @@ -156,7 +158,7 @@ static const struct clk_ops atl_clk_ops = { .disable = atl_clk_disable, .is_enabled = atl_clk_is_enabled, .recalc_rate = atl_clk_recalc_rate, - .round_rate = atl_clk_round_rate, + .determine_rate = atl_clk_determine_rate, .set_rate = atl_clk_set_rate, }; diff --git a/drivers/clk/ti/clkt_dpll.c b/drivers/clk/ti/clkt_dpll.c index dfaa4d1f0b64..2ecd66968af4 100644 --- a/drivers/clk/ti/clkt_dpll.c +++ b/drivers/clk/ti/clkt_dpll.c @@ -268,20 +268,18 @@ unsigned long omap2_get_dpll_rate(struct clk_hw_omap *clk) /* DPLL rate rounding code */ /** - * omap2_dpll_round_rate - round a target rate for an OMAP DPLL + * omap2_dpll_determine_rate - round a target rate for an OMAP DPLL * @hw: struct clk_hw containing the struct clk * for a DPLL - * @target_rate: desired DPLL clock rate - * @parent_rate: parent's DPLL clock rate + * @req: rate request * * Given a DPLL and a desired target rate, round the target rate to a * possible, programmable rate for this DPLL. Attempts to select the * minimum possible n. Stores the computed (m, n) in the DPLL's * dpll_data structure so set_rate() will not need to call this - * (expensive) function again. Returns ~0 if the target rate cannot - * be rounded, or the rounded rate upon success. + * (expensive) function again. Returns -EINVAL if the target rate + * cannot be rounded, or the rounded rate upon success. */ -long omap2_dpll_round_rate(struct clk_hw *hw, unsigned long target_rate, - unsigned long *parent_rate) +int omap2_dpll_determine_rate(struct clk_hw *hw, struct clk_rate_request *req) { struct clk_hw_omap *clk = to_clk_hw_omap(hw); int m, n, r, scaled_max_m; @@ -295,19 +293,19 @@ long omap2_dpll_round_rate(struct clk_hw *hw, unsigned long target_rate, const char *clk_name; if (!clk || !clk->dpll_data) - return ~0; + return -EINVAL; dd = clk->dpll_data; - if (dd->max_rate && target_rate > dd->max_rate) - target_rate = dd->max_rate; + if (dd->max_rate && req->rate > dd->max_rate) + req->rate = dd->max_rate; ref_rate = clk_hw_get_rate(dd->clk_ref); clk_name = clk_hw_get_name(hw); pr_debug("clock: %s: starting DPLL round_rate, target rate %lu\n", - clk_name, target_rate); + clk_name, req->rate); - scaled_rt_rp = target_rate / (ref_rate / DPLL_SCALE_FACTOR); + scaled_rt_rp = req->rate / (ref_rate / DPLL_SCALE_FACTOR); scaled_max_m = dd->max_multiplier * DPLL_SCALE_FACTOR; dd->last_rounded_rate = 0; @@ -332,7 +330,7 @@ long omap2_dpll_round_rate(struct clk_hw *hw, unsigned long target_rate, if (m > scaled_max_m) break; - r = _dpll_test_mult(&m, n, &new_rate, target_rate, + r = _dpll_test_mult(&m, n, &new_rate, req->rate, ref_rate); /* m can't be set low enough for this n - try with a larger n */ @@ -340,7 +338,7 @@ long omap2_dpll_round_rate(struct clk_hw *hw, unsigned long target_rate, continue; /* skip rates above our target rate */ - delta = target_rate - new_rate; + delta = req->rate - new_rate; if (delta < 0) continue; @@ -359,13 +357,15 @@ long omap2_dpll_round_rate(struct clk_hw *hw, unsigned long target_rate, if (prev_min_delta == LONG_MAX) { pr_debug("clock: %s: cannot round to rate %lu\n", - clk_name, target_rate); - return ~0; + clk_name, req->rate); + return -EINVAL; } dd->last_rounded_m = min_delta_m; dd->last_rounded_n = min_delta_n; - dd->last_rounded_rate = target_rate - prev_min_delta; + dd->last_rounded_rate = req->rate - prev_min_delta; - return dd->last_rounded_rate; + req->rate = dd->last_rounded_rate; + + return 0; } diff --git a/drivers/clk/ti/clock.h b/drivers/clk/ti/clock.h index 2de7acea1ea0..d5e24fe4ae3a 100644 --- a/drivers/clk/ti/clock.h +++ b/drivers/clk/ti/clock.h @@ -273,8 +273,7 @@ int omap3_noncore_dpll_set_rate_and_parent(struct clk_hw *hw, u8 index); int omap3_noncore_dpll_determine_rate(struct clk_hw *hw, struct clk_rate_request *req); -long omap2_dpll_round_rate(struct clk_hw *hw, unsigned long target_rate, - unsigned long *parent_rate); +int omap2_dpll_determine_rate(struct clk_hw *hw, struct clk_rate_request *req); unsigned long omap3_clkoutx2_recalc(struct clk_hw *hw, unsigned long parent_rate); @@ -296,9 +295,6 @@ void omap3_clk_lock_dpll5(void); unsigned long omap4_dpll_regm4xen_recalc(struct clk_hw *hw, unsigned long parent_rate); -long omap4_dpll_regm4xen_round_rate(struct clk_hw *hw, - unsigned long target_rate, - unsigned long *parent_rate); int omap4_dpll_regm4xen_determine_rate(struct clk_hw *hw, struct clk_rate_request *req); int omap2_clk_for_each(int (*fn)(struct clk_hw_omap *hw)); diff --git a/drivers/clk/ti/composite.c b/drivers/clk/ti/composite.c index b85382c370f7..8cba259188d4 100644 --- a/drivers/clk/ti/composite.c +++ b/drivers/clk/ti/composite.c @@ -26,8 +26,8 @@ static unsigned long ti_composite_recalc_rate(struct clk_hw *hw, return ti_clk_divider_ops.recalc_rate(hw, parent_rate); } -static long ti_composite_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *prate) +static int ti_composite_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { return -EINVAL; } @@ -40,7 +40,7 @@ static int ti_composite_set_rate(struct clk_hw *hw, unsigned long rate, static const struct clk_ops ti_composite_divider_ops = { .recalc_rate = &ti_composite_recalc_rate, - .round_rate = &ti_composite_round_rate, + .determine_rate = &ti_composite_determine_rate, .set_rate = &ti_composite_set_rate, }; diff --git a/drivers/clk/ti/divider.c b/drivers/clk/ti/divider.c index ade99ab6cfa9..6f58a0f2e74a 100644 --- a/drivers/clk/ti/divider.c +++ b/drivers/clk/ti/divider.c @@ -223,13 +223,15 @@ static int ti_clk_divider_bestdiv(struct clk_hw *hw, unsigned long rate, return bestdiv; } -static long ti_clk_divider_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *prate) +static int ti_clk_divider_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { int div; - div = ti_clk_divider_bestdiv(hw, rate, prate); + div = ti_clk_divider_bestdiv(hw, req->rate, &req->best_parent_rate); - return DIV_ROUND_UP(*prate, div); + req->rate = DIV_ROUND_UP(req->best_parent_rate, div); + + return 0; } static int ti_clk_divider_set_rate(struct clk_hw *hw, unsigned long rate, @@ -299,7 +301,7 @@ static void clk_divider_restore_context(struct clk_hw *hw) const struct clk_ops ti_clk_divider_ops = { .recalc_rate = ti_clk_divider_recalc_rate, - .round_rate = ti_clk_divider_round_rate, + .determine_rate = ti_clk_divider_determine_rate, .set_rate = ti_clk_divider_set_rate, .save_context = clk_divider_save_context, .restore_context = clk_divider_restore_context, diff --git a/drivers/clk/ti/dpll.c b/drivers/clk/ti/dpll.c index 3386bd1903df..971adafd9a8b 100644 --- a/drivers/clk/ti/dpll.c +++ b/drivers/clk/ti/dpll.c @@ -25,7 +25,6 @@ static const struct clk_ops dpll_m4xen_ck_ops = { .enable = &omap3_noncore_dpll_enable, .disable = &omap3_noncore_dpll_disable, .recalc_rate = &omap4_dpll_regm4xen_recalc, - .round_rate = &omap4_dpll_regm4xen_round_rate, .set_rate = &omap3_noncore_dpll_set_rate, .set_parent = &omap3_noncore_dpll_set_parent, .set_rate_and_parent = &omap3_noncore_dpll_set_rate_and_parent, @@ -48,7 +47,6 @@ static const struct clk_ops dpll_ck_ops = { .enable = &omap3_noncore_dpll_enable, .disable = &omap3_noncore_dpll_disable, .recalc_rate = &omap3_dpll_recalc, - .round_rate = &omap2_dpll_round_rate, .set_rate = &omap3_noncore_dpll_set_rate, .set_parent = &omap3_noncore_dpll_set_parent, .set_rate_and_parent = &omap3_noncore_dpll_set_rate_and_parent, @@ -61,7 +59,6 @@ static const struct clk_ops dpll_ck_ops = { static const struct clk_ops dpll_no_gate_ck_ops = { .recalc_rate = &omap3_dpll_recalc, .get_parent = &omap2_init_dpll_parent, - .round_rate = &omap2_dpll_round_rate, .set_rate = &omap3_noncore_dpll_set_rate, .set_parent = &omap3_noncore_dpll_set_parent, .set_rate_and_parent = &omap3_noncore_dpll_set_rate_and_parent, @@ -80,7 +77,7 @@ const struct clk_hw_omap_ops clkhwops_omap3_dpll = {}; static const struct clk_ops omap2_dpll_core_ck_ops = { .get_parent = &omap2_init_dpll_parent, .recalc_rate = &omap2_dpllcore_recalc, - .round_rate = &omap2_dpll_round_rate, + .determine_rate = &omap2_dpll_determine_rate, .set_rate = &omap2_reprogram_dpllcore, }; #else @@ -91,7 +88,7 @@ static const struct clk_ops omap2_dpll_core_ck_ops = {}; static const struct clk_ops omap3_dpll_core_ck_ops = { .get_parent = &omap2_init_dpll_parent, .recalc_rate = &omap3_dpll_recalc, - .round_rate = &omap2_dpll_round_rate, + .determine_rate = &omap2_dpll_determine_rate, }; static const struct clk_ops omap3_dpll_ck_ops = { @@ -103,7 +100,6 @@ static const struct clk_ops omap3_dpll_ck_ops = { .set_parent = &omap3_noncore_dpll_set_parent, .set_rate_and_parent = &omap3_noncore_dpll_set_rate_and_parent, .determine_rate = &omap3_noncore_dpll_determine_rate, - .round_rate = &omap2_dpll_round_rate, }; static const struct clk_ops omap3_dpll5_ck_ops = { @@ -115,7 +111,6 @@ static const struct clk_ops omap3_dpll5_ck_ops = { .set_parent = &omap3_noncore_dpll_set_parent, .set_rate_and_parent = &omap3_noncore_dpll_set_rate_and_parent, .determine_rate = &omap3_noncore_dpll_determine_rate, - .round_rate = &omap2_dpll_round_rate, }; static const struct clk_ops omap3_dpll_per_ck_ops = { @@ -127,7 +122,6 @@ static const struct clk_ops omap3_dpll_per_ck_ops = { .set_parent = &omap3_noncore_dpll_set_parent, .set_rate_and_parent = &omap3_dpll4_set_rate_and_parent, .determine_rate = &omap3_noncore_dpll_determine_rate, - .round_rate = &omap2_dpll_round_rate, }; #endif diff --git a/drivers/clk/ti/dpll3xxx.c b/drivers/clk/ti/dpll3xxx.c index 00680486b1bd..8c51b988a04f 100644 --- a/drivers/clk/ti/dpll3xxx.c +++ b/drivers/clk/ti/dpll3xxx.c @@ -587,6 +587,7 @@ int omap3_noncore_dpll_determine_rate(struct clk_hw *hw, { struct clk_hw_omap *clk = to_clk_hw_omap(hw); struct dpll_data *dd; + int ret; if (!req->rate) return -EINVAL; @@ -599,8 +600,10 @@ int omap3_noncore_dpll_determine_rate(struct clk_hw *hw, (dd->modes & (1 << DPLL_LOW_POWER_BYPASS))) { req->best_parent_hw = dd->clk_bypass; } else { - req->rate = omap2_dpll_round_rate(hw, req->rate, - &req->best_parent_rate); + ret = omap2_dpll_determine_rate(hw, req); + if (ret != 0) + return ret; + req->best_parent_hw = dd->clk_ref; } diff --git a/drivers/clk/ti/dpll44xx.c b/drivers/clk/ti/dpll44xx.c index 3fc2cab69a3f..08ed57f181b4 100644 --- a/drivers/clk/ti/dpll44xx.c +++ b/drivers/clk/ti/dpll44xx.c @@ -134,68 +134,13 @@ unsigned long omap4_dpll_regm4xen_recalc(struct clk_hw *hw, } /** - * omap4_dpll_regm4xen_round_rate - round DPLL rate, considering REGM4XEN bit - * @hw: struct hw_clk containing the struct clk * of the DPLL to round a rate for - * @target_rate: the desired rate of the DPLL - * @parent_rate: clock rate of the DPLL parent - * - * Compute the rate that would be programmed into the DPLL hardware - * for @clk if set_rate() were to be provided with the rate - * @target_rate. Takes the REGM4XEN bit into consideration, which is - * needed for the OMAP4 ABE DPLL. Returns the rounded rate (before - * M-dividers) upon success, -EINVAL if @clk is null or not a DPLL, or - * ~0 if an error occurred in omap2_dpll_round_rate(). - */ -long omap4_dpll_regm4xen_round_rate(struct clk_hw *hw, - unsigned long target_rate, - unsigned long *parent_rate) -{ - struct clk_hw_omap *clk = to_clk_hw_omap(hw); - struct dpll_data *dd; - long r; - - if (!clk || !clk->dpll_data) - return -EINVAL; - - dd = clk->dpll_data; - - dd->last_rounded_m4xen = 0; - - /* - * First try to compute the DPLL configuration for - * target rate without using the 4X multiplier. - */ - r = omap2_dpll_round_rate(hw, target_rate, NULL); - if (r != ~0) - goto out; - - /* - * If we did not find a valid DPLL configuration, try again, but - * this time see if using the 4X multiplier can help. Enabling the - * 4X multiplier is equivalent to dividing the target rate by 4. - */ - r = omap2_dpll_round_rate(hw, target_rate / OMAP4430_REGM4XEN_MULT, - NULL); - if (r == ~0) - return r; - - dd->last_rounded_rate *= OMAP4430_REGM4XEN_MULT; - dd->last_rounded_m4xen = 1; - -out: - omap4_dpll_lpmode_recalc(dd); - - return dd->last_rounded_rate; -} - -/** * omap4_dpll_regm4xen_determine_rate - determine rate for a DPLL * @hw: pointer to the clock to determine rate for * @req: target rate request * * Determines which DPLL mode to use for reaching a desired rate. * Checks whether the DPLL shall be in bypass or locked mode, and if - * locked, calculates the M,N values for the DPLL via round-rate. + * locked, calculates the M,N values for the DPLL. * Returns 0 on success and a negative error value otherwise. */ int omap4_dpll_regm4xen_determine_rate(struct clk_hw *hw, @@ -215,8 +160,36 @@ int omap4_dpll_regm4xen_determine_rate(struct clk_hw *hw, (dd->modes & (1 << DPLL_LOW_POWER_BYPASS))) { req->best_parent_hw = dd->clk_bypass; } else { - req->rate = omap4_dpll_regm4xen_round_rate(hw, req->rate, - &req->best_parent_rate); + struct clk_rate_request tmp_req; + long r; + + clk_hw_init_rate_request(hw, &tmp_req, req->rate); + dd->last_rounded_m4xen = 0; + + /* + * First try to compute the DPLL configuration for + * target rate without using the 4X multiplier. + */ + + r = omap2_dpll_determine_rate(hw, &tmp_req); + if (r < 0) { + /* + * If we did not find a valid DPLL configuration, try again, but + * this time see if using the 4X multiplier can help. Enabling the + * 4X multiplier is equivalent to dividing the target rate by 4. + */ + tmp_req.rate /= OMAP4430_REGM4XEN_MULT; + r = omap2_dpll_determine_rate(hw, &tmp_req); + if (r < 0) + return r; + + dd->last_rounded_rate *= OMAP4430_REGM4XEN_MULT; + dd->last_rounded_m4xen = 1; + } + + omap4_dpll_lpmode_recalc(dd); + + req->rate = dd->last_rounded_rate; req->best_parent_hw = dd->clk_ref; } diff --git a/drivers/clk/ti/fapll.c b/drivers/clk/ti/fapll.c index 2db3fc4a443e..4f28138d2d8a 100644 --- a/drivers/clk/ti/fapll.c +++ b/drivers/clk/ti/fapll.c @@ -214,24 +214,27 @@ static int ti_fapll_set_div_mult(unsigned long rate, return 0; } -static long ti_fapll_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *parent_rate) +static int ti_fapll_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { u32 pre_div_p, mult_n; int error; - if (!rate) + if (!req->rate) return -EINVAL; - error = ti_fapll_set_div_mult(rate, *parent_rate, + error = ti_fapll_set_div_mult(req->rate, req->best_parent_rate, &pre_div_p, &mult_n); - if (error) - return error; + if (error) { + req->rate = error; - rate = *parent_rate / pre_div_p; - rate *= mult_n; + return 0; + } - return rate; + req->rate = req->best_parent_rate / pre_div_p; + req->rate *= mult_n; + + return 0; } static int ti_fapll_set_rate(struct clk_hw *hw, unsigned long rate, @@ -268,7 +271,7 @@ static const struct clk_ops ti_fapll_ops = { .is_enabled = ti_fapll_is_enabled, .recalc_rate = ti_fapll_recalc_rate, .get_parent = ti_fapll_get_parent, - .round_rate = ti_fapll_round_rate, + .determine_rate = ti_fapll_determine_rate, .set_rate = ti_fapll_set_rate, }; @@ -399,14 +402,14 @@ static u32 ti_fapll_synth_set_frac_rate(struct fapll_synth *synth, return post_div_m; } -static long ti_fapll_synth_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *parent_rate) +static int ti_fapll_synth_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { struct fapll_synth *synth = to_synth(hw); struct fapll_data *fd = synth->fd; unsigned long r; - if (ti_fapll_clock_is_bypass(fd) || !synth->div || !rate) + if (ti_fapll_clock_is_bypass(fd) || !synth->div || !req->rate) return -EINVAL; /* Only post divider m available with no fractional divider? */ @@ -414,23 +417,26 @@ static long ti_fapll_synth_round_rate(struct clk_hw *hw, unsigned long rate, unsigned long frac_rate; u32 synth_post_div_m; - frac_rate = ti_fapll_synth_get_frac_rate(hw, *parent_rate); - synth_post_div_m = DIV_ROUND_UP(frac_rate, rate); + frac_rate = ti_fapll_synth_get_frac_rate(hw, + req->best_parent_rate); + synth_post_div_m = DIV_ROUND_UP(frac_rate, req->rate); r = DIV_ROUND_UP(frac_rate, synth_post_div_m); goto out; } - r = *parent_rate * SYNTH_PHASE_K; - if (rate > r) + r = req->best_parent_rate * SYNTH_PHASE_K; + if (req->rate > r) goto out; r = DIV_ROUND_UP_ULL(r, SYNTH_MAX_INT_DIV * SYNTH_MAX_DIV_M); - if (rate < r) + if (req->rate < r) goto out; - r = rate; + r = req->rate; out: - return r; + req->rate = r; + + return 0; } static int ti_fapll_synth_set_rate(struct clk_hw *hw, unsigned long rate, @@ -477,7 +483,7 @@ static const struct clk_ops ti_fapll_synt_ops = { .disable = ti_fapll_synth_disable, .is_enabled = ti_fapll_synth_is_enabled, .recalc_rate = ti_fapll_synth_recalc_rate, - .round_rate = ti_fapll_synth_round_rate, + .determine_rate = ti_fapll_synth_determine_rate, .set_rate = ti_fapll_synth_set_rate, }; diff --git a/drivers/clk/ux500/clk-prcmu.c b/drivers/clk/ux500/clk-prcmu.c index 5cbf24c94606..f775e18acd46 100644 --- a/drivers/clk/ux500/clk-prcmu.c +++ b/drivers/clk/ux500/clk-prcmu.c @@ -53,11 +53,13 @@ static unsigned long clk_prcmu_recalc_rate(struct clk_hw *hw, return prcmu_clock_rate(clk->cg_sel); } -static long clk_prcmu_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *parent_rate) +static int clk_prcmu_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { struct clk_prcmu *clk = to_clk_prcmu(hw); - return prcmu_round_clock_rate(clk->cg_sel, rate); + req->rate = prcmu_round_clock_rate(clk->cg_sel, req->rate); + + return 0; } static int clk_prcmu_set_rate(struct clk_hw *hw, unsigned long rate, @@ -157,7 +159,7 @@ static const struct clk_ops clk_prcmu_scalable_ops = { .prepare = clk_prcmu_prepare, .unprepare = clk_prcmu_unprepare, .recalc_rate = clk_prcmu_recalc_rate, - .round_rate = clk_prcmu_round_rate, + .determine_rate = clk_prcmu_determine_rate, .set_rate = clk_prcmu_set_rate, }; @@ -169,7 +171,7 @@ static const struct clk_ops clk_prcmu_gate_ops = { static const struct clk_ops clk_prcmu_scalable_rate_ops = { .recalc_rate = clk_prcmu_recalc_rate, - .round_rate = clk_prcmu_round_rate, + .determine_rate = clk_prcmu_determine_rate, .set_rate = clk_prcmu_set_rate, }; @@ -187,7 +189,7 @@ static const struct clk_ops clk_prcmu_opp_volt_scalable_ops = { .prepare = clk_prcmu_opp_volt_prepare, .unprepare = clk_prcmu_opp_volt_unprepare, .recalc_rate = clk_prcmu_recalc_rate, - .round_rate = clk_prcmu_round_rate, + .determine_rate = clk_prcmu_determine_rate, .set_rate = clk_prcmu_set_rate, }; diff --git a/drivers/clk/versatile/clk-icst.c b/drivers/clk/versatile/clk-icst.c index b69c3fbdfbce..86ca04ad9fab 100644 --- a/drivers/clk/versatile/clk-icst.c +++ b/drivers/clk/versatile/clk-icst.c @@ -234,39 +234,51 @@ static unsigned long icst_recalc_rate(struct clk_hw *hw, return icst->rate; } -static long icst_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *prate) +static int icst_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { struct clk_icst *icst = to_icst(hw); struct icst_vco vco; if (icst->ctype == ICST_INTEGRATOR_AP_CM || icst->ctype == ICST_INTEGRATOR_CP_CM_CORE) { - if (rate <= 12000000) - return 12000000; - if (rate >= 160000000) - return 160000000; - /* Slam to closest megahertz */ - return DIV_ROUND_CLOSEST(rate, 1000000) * 1000000; + if (req->rate <= 12000000) + req->rate = 12000000; + else if (req->rate >= 160000000) + req->rate = 160000000; + else { + /* Slam to closest megahertz */ + req->rate = DIV_ROUND_CLOSEST(req->rate, 1000000) * 1000000; + } + + return 0; } if (icst->ctype == ICST_INTEGRATOR_CP_CM_MEM) { - if (rate <= 6000000) - return 6000000; - if (rate >= 66000000) - return 66000000; - /* Slam to closest 0.5 megahertz */ - return DIV_ROUND_CLOSEST(rate, 500000) * 500000; + if (req->rate <= 6000000) + req->rate = 6000000; + else if (req->rate >= 66000000) + req->rate = 66000000; + else { + /* Slam to closest 0.5 megahertz */ + req->rate = DIV_ROUND_CLOSEST(req->rate, 500000) * 500000; + } + + return 0; } if (icst->ctype == ICST_INTEGRATOR_AP_SYS) { /* Divides between 3 and 50 MHz in steps of 0.25 MHz */ - if (rate <= 3000000) - return 3000000; - if (rate >= 50000000) - return 5000000; - /* Slam to closest 0.25 MHz */ - return DIV_ROUND_CLOSEST(rate, 250000) * 250000; + if (req->rate <= 3000000) + req->rate = 3000000; + else if (req->rate >= 50000000) + req->rate = 5000000; + else { + /* Slam to closest 0.25 MHz */ + req->rate = DIV_ROUND_CLOSEST(req->rate, 250000) * 250000; + } + + return 0; } if (icst->ctype == ICST_INTEGRATOR_AP_PCI) { @@ -274,14 +286,20 @@ static long icst_round_rate(struct clk_hw *hw, unsigned long rate, * If we're below or less than halfway from 25 to 33 MHz * select 25 MHz */ - if (rate <= 25000000 || rate < 29000000) - return 25000000; - /* Else just return the default frequency */ - return 33000000; + if (req->rate <= 25000000 || req->rate < 29000000) + req->rate = 25000000; + else { + /* Else just return the default frequency */ + req->rate = 33000000; + } + + return 0; } - vco = icst_hz_to_vco(icst->params, rate); - return icst_hz(icst->params, vco); + vco = icst_hz_to_vco(icst->params, req->rate); + req->rate = icst_hz(icst->params, vco); + + return 0; } static int icst_set_rate(struct clk_hw *hw, unsigned long rate, @@ -329,7 +347,7 @@ static int icst_set_rate(struct clk_hw *hw, unsigned long rate, static const struct clk_ops icst_ops = { .recalc_rate = icst_recalc_rate, - .round_rate = icst_round_rate, + .determine_rate = icst_determine_rate, .set_rate = icst_set_rate, }; diff --git a/drivers/clk/versatile/clk-vexpress-osc.c b/drivers/clk/versatile/clk-vexpress-osc.c index c385ca2f4a74..9adbf5c33bd1 100644 --- a/drivers/clk/versatile/clk-vexpress-osc.c +++ b/drivers/clk/versatile/clk-vexpress-osc.c @@ -33,18 +33,18 @@ static unsigned long vexpress_osc_recalc_rate(struct clk_hw *hw, return rate; } -static long vexpress_osc_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *parent_rate) +static int vexpress_osc_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { struct vexpress_osc *osc = to_vexpress_osc(hw); - if (osc->rate_min && rate < osc->rate_min) - rate = osc->rate_min; + if (osc->rate_min && req->rate < osc->rate_min) + req->rate = osc->rate_min; - if (osc->rate_max && rate > osc->rate_max) - rate = osc->rate_max; + if (osc->rate_max && req->rate > osc->rate_max) + req->rate = osc->rate_max; - return rate; + return 0; } static int vexpress_osc_set_rate(struct clk_hw *hw, unsigned long rate, @@ -57,7 +57,7 @@ static int vexpress_osc_set_rate(struct clk_hw *hw, unsigned long rate, static const struct clk_ops vexpress_osc_ops = { .recalc_rate = vexpress_osc_recalc_rate, - .round_rate = vexpress_osc_round_rate, + .determine_rate = vexpress_osc_determine_rate, .set_rate = vexpress_osc_set_rate, }; diff --git a/drivers/clk/visconti/pll.c b/drivers/clk/visconti/pll.c index 8ca1bad61864..681721d85032 100644 --- a/drivers/clk/visconti/pll.c +++ b/drivers/clk/visconti/pll.c @@ -100,8 +100,8 @@ static unsigned long visconti_get_pll_rate_from_data(struct visconti_pll *pll, return rate_table[0].rate; } -static long visconti_pll_round_rate(struct clk_hw *hw, - unsigned long rate, unsigned long *prate) +static int visconti_pll_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { struct visconti_pll *pll = to_visconti_pll(hw); const struct visconti_pll_rate_table *rate_table = pll->rate_table; @@ -109,11 +109,16 @@ static long visconti_pll_round_rate(struct clk_hw *hw, /* Assuming rate_table is in descending order */ for (i = 0; i < pll->rate_count; i++) - if (rate >= rate_table[i].rate) - return rate_table[i].rate; + if (req->rate >= rate_table[i].rate) { + req->rate = rate_table[i].rate; + + return 0; + } /* return minimum supported value */ - return rate_table[i - 1].rate; + req->rate = rate_table[i - 1].rate; + + return 0; } static unsigned long visconti_pll_recalc_rate(struct clk_hw *hw, @@ -232,7 +237,7 @@ static const struct clk_ops visconti_pll_ops = { .enable = visconti_pll_enable, .disable = visconti_pll_disable, .is_enabled = visconti_pll_is_enabled, - .round_rate = visconti_pll_round_rate, + .determine_rate = visconti_pll_determine_rate, .recalc_rate = visconti_pll_recalc_rate, .set_rate = visconti_pll_set_rate, }; diff --git a/drivers/clk/x86/clk-cgu.c b/drivers/clk/x86/clk-cgu.c index 89b53f280aee..d099667355f8 100644 --- a/drivers/clk/x86/clk-cgu.c +++ b/drivers/clk/x86/clk-cgu.c @@ -132,14 +132,15 @@ lgm_clk_divider_recalc_rate(struct clk_hw *hw, unsigned long parent_rate) divider->flags, divider->width); } -static long -lgm_clk_divider_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *prate) +static int lgm_clk_divider_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { struct lgm_clk_divider *divider = to_lgm_clk_divider(hw); - return divider_round_rate(hw, rate, prate, divider->table, - divider->width, divider->flags); + req->rate = divider_round_rate(hw, req->rate, &req->best_parent_rate, divider->table, + divider->width, divider->flags); + + return 0; } static int @@ -182,7 +183,7 @@ static void lgm_clk_divider_disable(struct clk_hw *hw) static const struct clk_ops lgm_clk_divider_ops = { .recalc_rate = lgm_clk_divider_recalc_rate, - .round_rate = lgm_clk_divider_round_rate, + .determine_rate = lgm_clk_divider_determine_rate, .set_rate = lgm_clk_divider_set_rate, .enable = lgm_clk_divider_enable, .disable = lgm_clk_divider_disable, @@ -487,15 +488,14 @@ lgm_clk_ddiv_set_rate(struct clk_hw *hw, unsigned long rate, return 0; } -static long -lgm_clk_ddiv_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *prate) +static int lgm_clk_ddiv_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { struct lgm_clk_ddiv *ddiv = to_lgm_clk_ddiv(hw); u32 div, ddiv1, ddiv2; u64 rate64; - div = DIV_ROUND_CLOSEST_ULL((u64)*prate, rate); + div = DIV_ROUND_CLOSEST_ULL((u64)req->best_parent_rate, req->rate); /* if predivide bit is enabled, modify div by factor of 2.5 */ if (lgm_get_clk_val(ddiv->membase, ddiv->reg, ddiv->shift2, 1)) { @@ -503,14 +503,17 @@ lgm_clk_ddiv_round_rate(struct clk_hw *hw, unsigned long rate, div = DIV_ROUND_CLOSEST_ULL((u64)div, 5); } - if (div <= 0) - return *prate; + if (div <= 0) { + req->rate = req->best_parent_rate; + + return 0; + } if (lgm_clk_get_ddiv_val(div, &ddiv1, &ddiv2) != 0) if (lgm_clk_get_ddiv_val(div + 1, &ddiv1, &ddiv2) != 0) return -EINVAL; - rate64 = *prate; + rate64 = req->best_parent_rate; do_div(rate64, ddiv1); do_div(rate64, ddiv2); @@ -520,7 +523,9 @@ lgm_clk_ddiv_round_rate(struct clk_hw *hw, unsigned long rate, rate64 = DIV_ROUND_CLOSEST_ULL(rate64, 5); } - return rate64; + req->rate = rate64; + + return 0; } static const struct clk_ops lgm_clk_ddiv_ops = { @@ -528,7 +533,7 @@ static const struct clk_ops lgm_clk_ddiv_ops = { .enable = lgm_clk_ddiv_enable, .disable = lgm_clk_ddiv_disable, .set_rate = lgm_clk_ddiv_set_rate, - .round_rate = lgm_clk_ddiv_round_rate, + .determine_rate = lgm_clk_ddiv_determine_rate, }; int lgm_clk_register_ddiv(struct lgm_clk_provider *ctx, diff --git a/drivers/clk/xilinx/clk-xlnx-clock-wizard.c b/drivers/clk/xilinx/clk-xlnx-clock-wizard.c index 0295a13a811c..4a0136349f71 100644 --- a/drivers/clk/xilinx/clk-xlnx-clock-wizard.c +++ b/drivers/clk/xilinx/clk-xlnx-clock-wizard.c @@ -322,8 +322,8 @@ err_reconfig: return err; } -static long clk_wzrd_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *prate) +static int clk_wzrd_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { u8 div; @@ -331,16 +331,18 @@ static long clk_wzrd_round_rate(struct clk_hw *hw, unsigned long rate, * since we don't change parent rate we just round rate to closest * achievable */ - div = DIV_ROUND_CLOSEST(*prate, rate); + div = DIV_ROUND_CLOSEST(req->best_parent_rate, req->rate); - return *prate / div; + req->rate = req->best_parent_rate / div; + + return 0; } static int clk_wzrd_get_divisors_ver(struct clk_hw *hw, unsigned long rate, unsigned long parent_rate) { struct clk_wzrd_divider *divider = to_clk_wzrd_divider(hw); - u64 vco_freq, freq, diff, vcomin, vcomax; + u64 vco_freq, freq, diff, vcomin, vcomax, best_diff = -1ULL; u32 m, d, o; u32 mmin, mmax, dmin, dmax, omin, omax; @@ -356,22 +358,26 @@ static int clk_wzrd_get_divisors_ver(struct clk_hw *hw, unsigned long rate, for (m = mmin; m <= mmax; m++) { for (d = dmin; d <= dmax; d++) { vco_freq = DIV_ROUND_CLOSEST((parent_rate * m), d); - if (vco_freq >= vcomin && vco_freq <= vcomax) { - for (o = omin; o <= omax; o++) { - freq = DIV_ROUND_CLOSEST_ULL(vco_freq, o); - diff = abs(freq - rate); - - if (diff < WZRD_MIN_ERR) { - divider->m = m; - divider->d = d; - divider->o = o; - return 0; - } - } + if (vco_freq < vcomin || vco_freq > vcomax) + continue; + + o = DIV_ROUND_CLOSEST_ULL(vco_freq, rate); + if (o < omin || o > omax) + continue; + freq = DIV_ROUND_CLOSEST_ULL(vco_freq, o); + diff = abs(freq - rate); + + if (diff < best_diff) { + best_diff = diff; + divider->m = m; + divider->d = d; + divider->o = o; + if (!diff) + return 0; } } } - return -EBUSY; + return 0; } static int clk_wzrd_get_divisors(struct clk_hw *hw, unsigned long rate, @@ -642,14 +648,14 @@ static unsigned long clk_wzrd_recalc_rate_all_ver(struct clk_hw *hw, divider->flags, divider->width); } -static long clk_wzrd_round_rate_all(struct clk_hw *hw, unsigned long rate, - unsigned long *prate) +static int clk_wzrd_determine_rate_all(struct clk_hw *hw, + struct clk_rate_request *req) { struct clk_wzrd_divider *divider = to_clk_wzrd_divider(hw); u32 m, d, o; int err; - err = clk_wzrd_get_divisors(hw, rate, *prate); + err = clk_wzrd_get_divisors(hw, req->rate, req->best_parent_rate); if (err) return err; @@ -657,19 +663,20 @@ static long clk_wzrd_round_rate_all(struct clk_hw *hw, unsigned long rate, d = divider->d; o = divider->o; - rate = div_u64(*prate * (m * 1000 + divider->m_frac), d * (o * 1000 + divider->o_frac)); - return rate; + req->rate = div_u64(req->best_parent_rate * (m * 1000 + divider->m_frac), + d * (o * 1000 + divider->o_frac)); + return 0; } -static long clk_wzrd_ver_round_rate_all(struct clk_hw *hw, unsigned long rate, - unsigned long *prate) +static int clk_wzrd_ver_determine_rate_all(struct clk_hw *hw, + struct clk_rate_request *req) { struct clk_wzrd_divider *divider = to_clk_wzrd_divider(hw); unsigned long int_freq; u32 m, d, o, div, f; int err; - err = clk_wzrd_get_divisors_ver(hw, rate, *prate); + err = clk_wzrd_get_divisors_ver(hw, req->rate, req->best_parent_rate); if (err) return err; @@ -678,36 +685,38 @@ static long clk_wzrd_ver_round_rate_all(struct clk_hw *hw, unsigned long rate, o = divider->o; div = d * o; - int_freq = divider_recalc_rate(hw, *prate * m, div, divider->table, + int_freq = divider_recalc_rate(hw, req->best_parent_rate * m, div, + divider->table, divider->flags, divider->width); - if (rate > int_freq) { - f = DIV_ROUND_CLOSEST_ULL(rate * WZRD_FRAC_POINTS, int_freq); - rate = DIV_ROUND_CLOSEST(int_freq * f, WZRD_FRAC_POINTS); + if (req->rate > int_freq) { + f = DIV_ROUND_CLOSEST_ULL(req->rate * WZRD_FRAC_POINTS, + int_freq); + req->rate = DIV_ROUND_CLOSEST(int_freq * f, WZRD_FRAC_POINTS); } - return rate; + return 0; } static const struct clk_ops clk_wzrd_ver_divider_ops = { - .round_rate = clk_wzrd_round_rate, + .determine_rate = clk_wzrd_determine_rate, .set_rate = clk_wzrd_ver_dynamic_reconfig, .recalc_rate = clk_wzrd_recalc_rate_ver, }; static const struct clk_ops clk_wzrd_ver_div_all_ops = { - .round_rate = clk_wzrd_ver_round_rate_all, + .determine_rate = clk_wzrd_ver_determine_rate_all, .set_rate = clk_wzrd_dynamic_all_ver, .recalc_rate = clk_wzrd_recalc_rate_all_ver, }; static const struct clk_ops clk_wzrd_clk_divider_ops = { - .round_rate = clk_wzrd_round_rate, + .determine_rate = clk_wzrd_determine_rate, .set_rate = clk_wzrd_dynamic_reconfig, .recalc_rate = clk_wzrd_recalc_rate, }; static const struct clk_ops clk_wzrd_clk_div_all_ops = { - .round_rate = clk_wzrd_round_rate_all, + .determine_rate = clk_wzrd_determine_rate_all, .set_rate = clk_wzrd_dynamic_all, .recalc_rate = clk_wzrd_recalc_rate_all, }; @@ -769,14 +778,14 @@ static int clk_wzrd_dynamic_reconfig_f(struct clk_hw *hw, unsigned long rate, WZRD_USEC_POLL, WZRD_TIMEOUT_POLL); } -static long clk_wzrd_round_rate_f(struct clk_hw *hw, unsigned long rate, - unsigned long *prate) +static int clk_wzrd_determine_rate_f(struct clk_hw *hw, + struct clk_rate_request *req) { - return rate; + return 0; } static const struct clk_ops clk_wzrd_clk_divider_ops_f = { - .round_rate = clk_wzrd_round_rate_f, + .determine_rate = clk_wzrd_determine_rate_f, .set_rate = clk_wzrd_dynamic_reconfig_f, .recalc_rate = clk_wzrd_recalc_ratef, }; @@ -1108,7 +1117,7 @@ static int clk_wzrd_register_output_clocks(struct device *dev, int nr_outputs) (dev, clkout_name, clk_name, 0, clk_wzrd->base, - (WZRD_CLK_CFG_REG(is_versal, 3) + i * 8), + (WZRD_CLK_CFG_REG(is_versal, 2) + i * 8), WZRD_CLKOUT_DIVIDE_SHIFT, WZRD_CLKOUT_DIVIDE_WIDTH, CLK_DIVIDER_ONE_BASED | diff --git a/drivers/clk/xilinx/xlnx_vcu.c b/drivers/clk/xilinx/xlnx_vcu.c index 1ded67bee06c..02699bc0f82c 100644 --- a/drivers/clk/xilinx/xlnx_vcu.c +++ b/drivers/clk/xilinx/xlnx_vcu.c @@ -311,18 +311,21 @@ static int xvcu_pll_set_div(struct vcu_pll *pll, int div) return 0; } -static long xvcu_pll_round_rate(struct clk_hw *hw, - unsigned long rate, unsigned long *parent_rate) +static int xvcu_pll_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { struct vcu_pll *pll = to_vcu_pll(hw); unsigned int feedback_div; - rate = clamp_t(unsigned long, rate, pll->fvco_min, pll->fvco_max); + req->rate = clamp_t(unsigned long, req->rate, pll->fvco_min, + pll->fvco_max); - feedback_div = DIV_ROUND_CLOSEST_ULL(rate, *parent_rate); + feedback_div = DIV_ROUND_CLOSEST_ULL(req->rate, req->best_parent_rate); feedback_div = clamp_t(unsigned int, feedback_div, 25, 125); - return *parent_rate * feedback_div; + req->rate = req->best_parent_rate * feedback_div; + + return 0; } static unsigned long xvcu_pll_recalc_rate(struct clk_hw *hw, @@ -394,7 +397,7 @@ static void xvcu_pll_disable(struct clk_hw *hw) static const struct clk_ops vcu_pll_ops = { .enable = xvcu_pll_enable, .disable = xvcu_pll_disable, - .round_rate = xvcu_pll_round_rate, + .determine_rate = xvcu_pll_determine_rate, .recalc_rate = xvcu_pll_recalc_rate, .set_rate = xvcu_pll_set_rate, }; diff --git a/drivers/clk/zynq/pll.c b/drivers/clk/zynq/pll.c index e5f8fb704df2..5eca1c14981a 100644 --- a/drivers/clk/zynq/pll.c +++ b/drivers/clk/zynq/pll.c @@ -48,18 +48,20 @@ struct zynq_pll { * @prate: Clock frequency of parent clock * Return: frequency closest to @rate the hardware can generate. */ -static long zynq_pll_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *prate) +static int zynq_pll_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { u32 fbdiv; - fbdiv = DIV_ROUND_CLOSEST(rate, *prate); + fbdiv = DIV_ROUND_CLOSEST(req->rate, req->best_parent_rate); if (fbdiv < PLL_FBDIV_MIN) fbdiv = PLL_FBDIV_MIN; else if (fbdiv > PLL_FBDIV_MAX) fbdiv = PLL_FBDIV_MAX; - return *prate * fbdiv; + req->rate = req->best_parent_rate * fbdiv; + + return 0; } /** @@ -167,7 +169,7 @@ static const struct clk_ops zynq_pll_ops = { .enable = zynq_pll_enable, .disable = zynq_pll_disable, .is_enabled = zynq_pll_is_enabled, - .round_rate = zynq_pll_round_rate, + .determine_rate = zynq_pll_determine_rate, .recalc_rate = zynq_pll_recalc_rate }; diff --git a/drivers/clk/zynqmp/divider.c b/drivers/clk/zynqmp/divider.c index 5a00487ae408..c824eeacd8eb 100644 --- a/drivers/clk/zynqmp/divider.c +++ b/drivers/clk/zynqmp/divider.c @@ -118,9 +118,8 @@ static unsigned long zynqmp_clk_divider_recalc_rate(struct clk_hw *hw, * * Return: 0 on success else error+reason */ -static long zynqmp_clk_divider_round_rate(struct clk_hw *hw, - unsigned long rate, - unsigned long *prate) +static int zynqmp_clk_divider_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { struct zynqmp_clk_divider *divider = to_zynqmp_clk_divider(hw); const char *clk_name = clk_hw_get_name(hw); @@ -145,17 +144,21 @@ static long zynqmp_clk_divider_round_rate(struct clk_hw *hw, if (divider->flags & CLK_DIVIDER_POWER_OF_TWO) bestdiv = 1 << bestdiv; - return DIV_ROUND_UP_ULL((u64)*prate, bestdiv); + req->rate = DIV_ROUND_UP_ULL((u64)req->best_parent_rate, bestdiv); + + return 0; } width = fls(divider->max_div); - rate = divider_round_rate(hw, rate, prate, NULL, width, divider->flags); + req->rate = divider_round_rate(hw, req->rate, &req->best_parent_rate, + NULL, width, divider->flags); - if (divider->is_frac && (clk_hw_get_flags(hw) & CLK_SET_RATE_PARENT) && (rate % *prate)) - *prate = rate; + if (divider->is_frac && (clk_hw_get_flags(hw) & CLK_SET_RATE_PARENT) && + (req->rate % req->best_parent_rate)) + req->best_parent_rate = req->rate; - return rate; + return 0; } /** @@ -199,13 +202,13 @@ static int zynqmp_clk_divider_set_rate(struct clk_hw *hw, unsigned long rate, static const struct clk_ops zynqmp_clk_divider_ops = { .recalc_rate = zynqmp_clk_divider_recalc_rate, - .round_rate = zynqmp_clk_divider_round_rate, + .determine_rate = zynqmp_clk_divider_determine_rate, .set_rate = zynqmp_clk_divider_set_rate, }; static const struct clk_ops zynqmp_clk_divider_ro_ops = { .recalc_rate = zynqmp_clk_divider_recalc_rate, - .round_rate = zynqmp_clk_divider_round_rate, + .determine_rate = zynqmp_clk_divider_determine_rate, }; /** diff --git a/drivers/clk/zynqmp/pll.c b/drivers/clk/zynqmp/pll.c index 7411a7fd50ac..630a3936c97c 100644 --- a/drivers/clk/zynqmp/pll.c +++ b/drivers/clk/zynqmp/pll.c @@ -98,29 +98,29 @@ static inline void zynqmp_pll_set_mode(struct clk_hw *hw, bool on) * * Return: Frequency closest to @rate the hardware can generate */ -static long zynqmp_pll_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *prate) +static int zynqmp_pll_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { u32 fbdiv; u32 mult, div; /* Let rate fall inside the range PS_PLL_VCO_MIN ~ PS_PLL_VCO_MAX */ - if (rate > PS_PLL_VCO_MAX) { - div = DIV_ROUND_UP(rate, PS_PLL_VCO_MAX); - rate = rate / div; + if (req->rate > PS_PLL_VCO_MAX) { + div = DIV_ROUND_UP(req->rate, PS_PLL_VCO_MAX); + req->rate = req->rate / div; } - if (rate < PS_PLL_VCO_MIN) { - mult = DIV_ROUND_UP(PS_PLL_VCO_MIN, rate); - rate = rate * mult; + if (req->rate < PS_PLL_VCO_MIN) { + mult = DIV_ROUND_UP(PS_PLL_VCO_MIN, req->rate); + req->rate = req->rate * mult; } - fbdiv = DIV_ROUND_CLOSEST(rate, *prate); + fbdiv = DIV_ROUND_CLOSEST(req->rate, req->best_parent_rate); if (fbdiv < PLL_FBDIV_MIN || fbdiv > PLL_FBDIV_MAX) { fbdiv = clamp_t(u32, fbdiv, PLL_FBDIV_MIN, PLL_FBDIV_MAX); - rate = *prate * fbdiv; + req->rate = req->best_parent_rate * fbdiv; } - return rate; + return 0; } /** @@ -294,7 +294,7 @@ static const struct clk_ops zynqmp_pll_ops = { .enable = zynqmp_pll_enable, .disable = zynqmp_pll_disable, .is_enabled = zynqmp_pll_is_enabled, - .round_rate = zynqmp_pll_round_rate, + .determine_rate = zynqmp_pll_determine_rate, .recalc_rate = zynqmp_pll_recalc_rate, .set_rate = zynqmp_pll_set_rate, }; diff --git a/drivers/clocksource/hyperv_timer.c b/drivers/clocksource/hyperv_timer.c index 2edc13ca184e..10356d4ec55c 100644 --- a/drivers/clocksource/hyperv_timer.c +++ b/drivers/clocksource/hyperv_timer.c @@ -549,14 +549,22 @@ static void __init hv_init_tsc_clocksource(void) union hv_reference_tsc_msr tsc_msr; /* + * When running as a guest partition: + * * If Hyper-V offers TSC_INVARIANT, then the virtualized TSC correctly * handles frequency and offset changes due to live migration, * pause/resume, and other VM management operations. So lower the * Hyper-V Reference TSC rating, causing the generic TSC to be used. * TSC_INVARIANT is not offered on ARM64, so the Hyper-V Reference * TSC will be preferred over the virtualized ARM64 arch counter. + * + * When running as the root partition: + * + * There is no HV_ACCESS_TSC_INVARIANT feature. Always lower the rating + * of the Hyper-V Reference TSC. */ - if (ms_hyperv.features & HV_ACCESS_TSC_INVARIANT) { + if ((ms_hyperv.features & HV_ACCESS_TSC_INVARIANT) || + hv_root_partition()) { hyperv_cs_tsc.rating = 250; hyperv_cs_msr.rating = 245; } diff --git a/drivers/cpufreq/amd-pstate.c b/drivers/cpufreq/amd-pstate.c index b4c79fde1979..298e92d8cc03 100644 --- a/drivers/cpufreq/amd-pstate.c +++ b/drivers/cpufreq/amd-pstate.c @@ -872,10 +872,10 @@ static void amd_pstate_update_limits(struct cpufreq_policy *policy) */ static u32 amd_pstate_get_transition_delay_us(unsigned int cpu) { - u32 transition_delay_ns; + int transition_delay_ns; transition_delay_ns = cppc_get_transition_latency(cpu); - if (transition_delay_ns == CPUFREQ_ETERNAL) { + if (transition_delay_ns < 0) { if (cpu_feature_enabled(X86_FEATURE_AMD_FAST_CPPC)) return AMD_PSTATE_FAST_CPPC_TRANSITION_DELAY; else @@ -891,10 +891,10 @@ static u32 amd_pstate_get_transition_delay_us(unsigned int cpu) */ static u32 amd_pstate_get_transition_latency(unsigned int cpu) { - u32 transition_latency; + int transition_latency; transition_latency = cppc_get_transition_latency(cpu); - if (transition_latency == CPUFREQ_ETERNAL) + if (transition_latency < 0) return AMD_PSTATE_TRANSITION_LATENCY; return transition_latency; diff --git a/drivers/cpufreq/cppc_cpufreq.c b/drivers/cpufreq/cppc_cpufreq.c index 12de0ac7bbaf..e23d9abea135 100644 --- a/drivers/cpufreq/cppc_cpufreq.c +++ b/drivers/cpufreq/cppc_cpufreq.c @@ -308,6 +308,16 @@ static int cppc_verify_policy(struct cpufreq_policy_data *policy) return 0; } +static unsigned int __cppc_cpufreq_get_transition_delay_us(unsigned int cpu) +{ + int transition_latency_ns = cppc_get_transition_latency(cpu); + + if (transition_latency_ns < 0) + return CPUFREQ_DEFAULT_TRANSITION_LATENCY_NS / NSEC_PER_USEC; + + return transition_latency_ns / NSEC_PER_USEC; +} + /* * The PCC subspace describes the rate at which platform can accept commands * on the shared PCC channel (including READs which do not count towards freq @@ -330,12 +340,12 @@ static unsigned int cppc_cpufreq_get_transition_delay_us(unsigned int cpu) return 10000; } } - return cppc_get_transition_latency(cpu) / NSEC_PER_USEC; + return __cppc_cpufreq_get_transition_delay_us(cpu); } #else static unsigned int cppc_cpufreq_get_transition_delay_us(unsigned int cpu) { - return cppc_get_transition_latency(cpu) / NSEC_PER_USEC; + return __cppc_cpufreq_get_transition_delay_us(cpu); } #endif diff --git a/drivers/cpufreq/cpufreq-dt.c b/drivers/cpufreq/cpufreq-dt.c index 506437489b4d..7d5079fd1688 100644 --- a/drivers/cpufreq/cpufreq-dt.c +++ b/drivers/cpufreq/cpufreq-dt.c @@ -104,7 +104,7 @@ static int cpufreq_init(struct cpufreq_policy *policy) transition_latency = dev_pm_opp_get_max_transition_latency(cpu_dev); if (!transition_latency) - transition_latency = CPUFREQ_ETERNAL; + transition_latency = CPUFREQ_DEFAULT_TRANSITION_LATENCY_NS; cpumask_copy(policy->cpus, priv->cpus); policy->driver_data = priv; diff --git a/drivers/cpufreq/imx6q-cpufreq.c b/drivers/cpufreq/imx6q-cpufreq.c index db1c88e9d3f9..e93697d3edfd 100644 --- a/drivers/cpufreq/imx6q-cpufreq.c +++ b/drivers/cpufreq/imx6q-cpufreq.c @@ -442,7 +442,7 @@ soc_opp_out: } if (of_property_read_u32(np, "clock-latency", &transition_latency)) - transition_latency = CPUFREQ_ETERNAL; + transition_latency = CPUFREQ_DEFAULT_TRANSITION_LATENCY_NS; /* * Calculate the ramp time for max voltage change in the diff --git a/drivers/cpufreq/mediatek-cpufreq-hw.c b/drivers/cpufreq/mediatek-cpufreq-hw.c index fce5aa5ceea0..ae4500ab4891 100644 --- a/drivers/cpufreq/mediatek-cpufreq-hw.c +++ b/drivers/cpufreq/mediatek-cpufreq-hw.c @@ -309,7 +309,7 @@ static int mtk_cpufreq_hw_cpu_init(struct cpufreq_policy *policy) latency = readl_relaxed(data->reg_bases[REG_FREQ_LATENCY]) * 1000; if (!latency) - latency = CPUFREQ_ETERNAL; + latency = CPUFREQ_DEFAULT_TRANSITION_LATENCY_NS; policy->cpuinfo.transition_latency = latency; policy->fast_switch_possible = true; diff --git a/drivers/cpufreq/mediatek-cpufreq.c b/drivers/cpufreq/mediatek-cpufreq.c index 00de1166188a..5d50a231f944 100644 --- a/drivers/cpufreq/mediatek-cpufreq.c +++ b/drivers/cpufreq/mediatek-cpufreq.c @@ -403,9 +403,11 @@ static int mtk_cpu_dvfs_info_init(struct mtk_cpu_dvfs_info *info, int cpu) } info->cpu_clk = clk_get(cpu_dev, "cpu"); - if (IS_ERR(info->cpu_clk)) - return dev_err_probe(cpu_dev, PTR_ERR(info->cpu_clk), - "cpu%d: failed to get cpu clk\n", cpu); + if (IS_ERR(info->cpu_clk)) { + ret = PTR_ERR(info->cpu_clk); + dev_err_probe(cpu_dev, ret, "cpu%d: failed to get cpu clk\n", cpu); + goto out_put_cci_dev; + } info->inter_clk = clk_get(cpu_dev, "intermediate"); if (IS_ERR(info->inter_clk)) { @@ -551,6 +553,10 @@ out_free_inter_clock: out_free_mux_clock: clk_put(info->cpu_clk); +out_put_cci_dev: + if (info->soc_data->ccifreq_supported) + put_device(info->cci_dev); + return ret; } @@ -568,6 +574,8 @@ static void mtk_cpu_dvfs_info_release(struct mtk_cpu_dvfs_info *info) clk_put(info->inter_clk); dev_pm_opp_of_cpumask_remove_table(&info->cpus); dev_pm_opp_unregister_notifier(info->cpu_dev, &info->opp_nb); + if (info->soc_data->ccifreq_supported) + put_device(info->cci_dev); } static int mtk_cpufreq_init(struct cpufreq_policy *policy) diff --git a/drivers/cpufreq/rcpufreq_dt.rs b/drivers/cpufreq/rcpufreq_dt.rs index 7e1fbf9a091f..53923b8ef7a1 100644 --- a/drivers/cpufreq/rcpufreq_dt.rs +++ b/drivers/cpufreq/rcpufreq_dt.rs @@ -28,15 +28,11 @@ fn find_supply_name_exact(dev: &Device, name: &str) -> Option<CString> { /// Finds supply name for the CPU from DT. fn find_supply_names(dev: &Device, cpu: cpu::CpuId) -> Option<KVec<CString>> { // Try "cpu0" for older DTs, fallback to "cpu". - let name = (cpu.as_u32() == 0) + (cpu.as_u32() == 0) .then(|| find_supply_name_exact(dev, "cpu0")) .flatten() - .or_else(|| find_supply_name_exact(dev, "cpu"))?; - - let mut list = KVec::with_capacity(1, GFP_KERNEL).ok()?; - list.push(name, GFP_KERNEL).ok()?; - - Some(list) + .or_else(|| find_supply_name_exact(dev, "cpu")) + .and_then(|name| kernel::kvec![name].ok()) } /// Represents the cpufreq dt device. @@ -123,7 +119,7 @@ impl cpufreq::Driver for CPUFreqDTDriver { let mut transition_latency = opp_table.max_transition_latency_ns() as u32; if transition_latency == 0 { - transition_latency = cpufreq::ETERNAL_LATENCY_NS; + transition_latency = cpufreq::DEFAULT_TRANSITION_LATENCY_NS; } policy diff --git a/drivers/cpufreq/scmi-cpufreq.c b/drivers/cpufreq/scmi-cpufreq.c index 38c165d526d1..d2a110079f5f 100644 --- a/drivers/cpufreq/scmi-cpufreq.c +++ b/drivers/cpufreq/scmi-cpufreq.c @@ -294,7 +294,7 @@ static int scmi_cpufreq_init(struct cpufreq_policy *policy) latency = perf_ops->transition_latency_get(ph, domain); if (!latency) - latency = CPUFREQ_ETERNAL; + latency = CPUFREQ_DEFAULT_TRANSITION_LATENCY_NS; policy->cpuinfo.transition_latency = latency; diff --git a/drivers/cpufreq/scpi-cpufreq.c b/drivers/cpufreq/scpi-cpufreq.c index dcbb0ae7dd47..e530345baddf 100644 --- a/drivers/cpufreq/scpi-cpufreq.c +++ b/drivers/cpufreq/scpi-cpufreq.c @@ -157,7 +157,7 @@ static int scpi_cpufreq_init(struct cpufreq_policy *policy) latency = scpi_ops->get_transition_latency(cpu_dev); if (!latency) - latency = CPUFREQ_ETERNAL; + latency = CPUFREQ_DEFAULT_TRANSITION_LATENCY_NS; policy->cpuinfo.transition_latency = latency; diff --git a/drivers/cpufreq/spear-cpufreq.c b/drivers/cpufreq/spear-cpufreq.c index 707c71090cc3..2a1550e1aa21 100644 --- a/drivers/cpufreq/spear-cpufreq.c +++ b/drivers/cpufreq/spear-cpufreq.c @@ -182,7 +182,7 @@ static int spear_cpufreq_probe(struct platform_device *pdev) if (of_property_read_u32(np, "clock-latency", &spear_cpufreq.transition_latency)) - spear_cpufreq.transition_latency = CPUFREQ_ETERNAL; + spear_cpufreq.transition_latency = CPUFREQ_DEFAULT_TRANSITION_LATENCY_NS; cnt = of_property_count_u32_elems(np, "cpufreq_tbl"); if (cnt <= 0) { diff --git a/drivers/cpufreq/tegra186-cpufreq.c b/drivers/cpufreq/tegra186-cpufreq.c index 4270686fc3e3..136ab102f636 100644 --- a/drivers/cpufreq/tegra186-cpufreq.c +++ b/drivers/cpufreq/tegra186-cpufreq.c @@ -93,10 +93,14 @@ static int tegra186_cpufreq_set_target(struct cpufreq_policy *policy, { struct tegra186_cpufreq_data *data = cpufreq_get_driver_data(); struct cpufreq_frequency_table *tbl = policy->freq_table + index; - unsigned int edvd_offset = data->cpus[policy->cpu].edvd_offset; + unsigned int edvd_offset; u32 edvd_val = tbl->driver_data; + u32 cpu; - writel(edvd_val, data->regs + edvd_offset); + for_each_cpu(cpu, policy->cpus) { + edvd_offset = data->cpus[cpu].edvd_offset; + writel(edvd_val, data->regs + edvd_offset); + } return 0; } @@ -132,13 +136,14 @@ static struct cpufreq_driver tegra186_cpufreq_driver = { static struct cpufreq_frequency_table *init_vhint_table( struct platform_device *pdev, struct tegra_bpmp *bpmp, - struct tegra186_cpufreq_cluster *cluster, unsigned int cluster_id) + struct tegra186_cpufreq_cluster *cluster, unsigned int cluster_id, + int *num_rates) { struct cpufreq_frequency_table *table; struct mrq_cpu_vhint_request req; struct tegra_bpmp_message msg; struct cpu_vhint_data *data; - int err, i, j, num_rates = 0; + int err, i, j; dma_addr_t phys; void *virt; @@ -168,6 +173,7 @@ static struct cpufreq_frequency_table *init_vhint_table( goto free; } + *num_rates = 0; for (i = data->vfloor; i <= data->vceil; i++) { u16 ndiv = data->ndiv[i]; @@ -178,10 +184,10 @@ static struct cpufreq_frequency_table *init_vhint_table( if (i > 0 && ndiv == data->ndiv[i - 1]) continue; - num_rates++; + (*num_rates)++; } - table = devm_kcalloc(&pdev->dev, num_rates + 1, sizeof(*table), + table = devm_kcalloc(&pdev->dev, *num_rates + 1, sizeof(*table), GFP_KERNEL); if (!table) { table = ERR_PTR(-ENOMEM); @@ -223,7 +229,9 @@ static int tegra186_cpufreq_probe(struct platform_device *pdev) { struct tegra186_cpufreq_data *data; struct tegra_bpmp *bpmp; - unsigned int i = 0, err; + unsigned int i = 0, err, edvd_offset; + int num_rates = 0; + u32 edvd_val, cpu; data = devm_kzalloc(&pdev->dev, struct_size(data, clusters, TEGRA186_NUM_CLUSTERS), @@ -246,10 +254,21 @@ static int tegra186_cpufreq_probe(struct platform_device *pdev) for (i = 0; i < TEGRA186_NUM_CLUSTERS; i++) { struct tegra186_cpufreq_cluster *cluster = &data->clusters[i]; - cluster->table = init_vhint_table(pdev, bpmp, cluster, i); + cluster->table = init_vhint_table(pdev, bpmp, cluster, i, &num_rates); if (IS_ERR(cluster->table)) { err = PTR_ERR(cluster->table); goto put_bpmp; + } else if (!num_rates) { + err = -EINVAL; + goto put_bpmp; + } + + for (cpu = 0; cpu < ARRAY_SIZE(tegra186_cpus); cpu++) { + if (data->cpus[cpu].bpmp_cluster_id == i) { + edvd_val = cluster->table[num_rates - 1].driver_data; + edvd_offset = data->cpus[cpu].edvd_offset; + writel(edvd_val, data->regs + edvd_offset); + } } } diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig index 05c7c7d9e5a4..b8a74b1798ba 100644 --- a/drivers/dma/Kconfig +++ b/drivers/dma/Kconfig @@ -450,7 +450,7 @@ config MILBEAUT_XDMAC config MMP_PDMA tristate "MMP PDMA support" - depends on ARCH_MMP || ARCH_PXA || COMPILE_TEST + depends on ARCH_MMP || ARCH_PXA || ARCH_SPACEMIT || COMPILE_TEST select DMA_ENGINE help Support the MMP PDMA engine for PXA and MMP platform. diff --git a/drivers/dma/dw-edma/dw-edma-core.c b/drivers/dma/dw-edma/dw-edma-core.c index b43255f914f3..8e5f7defa6b6 100644 --- a/drivers/dma/dw-edma/dw-edma-core.c +++ b/drivers/dma/dw-edma/dw-edma-core.c @@ -584,6 +584,25 @@ dw_edma_device_prep_interleaved_dma(struct dma_chan *dchan, return dw_edma_device_transfer(&xfer); } +static void dw_hdma_set_callback_result(struct virt_dma_desc *vd, + enum dmaengine_tx_result result) +{ + u32 residue = 0; + struct dw_edma_desc *desc; + struct dmaengine_result *res; + + if (!vd->tx.callback_result) + return; + + desc = vd2dw_edma_desc(vd); + if (desc) + residue = desc->alloc_sz - desc->xfer_sz; + + res = &vd->tx_result; + res->result = result; + res->residue = residue; +} + static void dw_edma_done_interrupt(struct dw_edma_chan *chan) { struct dw_edma_desc *desc; @@ -597,6 +616,8 @@ static void dw_edma_done_interrupt(struct dw_edma_chan *chan) case EDMA_REQ_NONE: desc = vd2dw_edma_desc(vd); if (!desc->chunks_alloc) { + dw_hdma_set_callback_result(vd, + DMA_TRANS_NOERROR); list_del(&vd->node); vchan_cookie_complete(vd); } @@ -633,6 +654,7 @@ static void dw_edma_abort_interrupt(struct dw_edma_chan *chan) spin_lock_irqsave(&chan->vc.lock, flags); vd = vchan_next_desc(&chan->vc); if (vd) { + dw_hdma_set_callback_result(vd, DMA_TRANS_ABORTED); list_del(&vd->node); vchan_cookie_complete(vd); } diff --git a/drivers/dma/idxd/defaults.c b/drivers/dma/idxd/defaults.c index c607ae8dd12c..2bbbcd02a0da 100644 --- a/drivers/dma/idxd/defaults.c +++ b/drivers/dma/idxd/defaults.c @@ -36,12 +36,10 @@ int idxd_load_iaa_device_defaults(struct idxd_device *idxd) group->num_wqs++; /* set name to "iaa_crypto" */ - memset(wq->name, 0, WQ_NAME_SIZE + 1); - strscpy(wq->name, "iaa_crypto", WQ_NAME_SIZE + 1); + strscpy_pad(wq->name, "iaa_crypto"); /* set driver_name to "crypto" */ - memset(wq->driver_name, 0, DRIVER_NAME_SIZE + 1); - strscpy(wq->driver_name, "crypto", DRIVER_NAME_SIZE + 1); + strscpy_pad(wq->driver_name, "crypto"); engine = idxd->engines[0]; diff --git a/drivers/dma/idxd/init.c b/drivers/dma/idxd/init.c index 8c4725ad1f64..2acc34b3daff 100644 --- a/drivers/dma/idxd/init.c +++ b/drivers/dma/idxd/init.c @@ -80,6 +80,8 @@ static struct pci_device_id idxd_pci_tbl[] = { { PCI_DEVICE_DATA(INTEL, IAA_DMR, &idxd_driver_data[IDXD_TYPE_IAX]) }, /* IAA PTL platforms */ { PCI_DEVICE_DATA(INTEL, IAA_PTL, &idxd_driver_data[IDXD_TYPE_IAX]) }, + /* IAA WCL platforms */ + { PCI_DEVICE_DATA(INTEL, IAA_WCL, &idxd_driver_data[IDXD_TYPE_IAX]) }, { 0, } }; MODULE_DEVICE_TABLE(pci, idxd_pci_tbl); diff --git a/drivers/dma/idxd/registers.h b/drivers/dma/idxd/registers.h index 02bab136385e..8dc2e8bca779 100644 --- a/drivers/dma/idxd/registers.h +++ b/drivers/dma/idxd/registers.h @@ -14,6 +14,7 @@ #define PCI_DEVICE_ID_INTEL_DSA_DMR 0x1212 #define PCI_DEVICE_ID_INTEL_IAA_DMR 0x1216 #define PCI_DEVICE_ID_INTEL_IAA_PTL 0xb02d +#define PCI_DEVICE_ID_INTEL_IAA_WCL 0xfd2d #define DEVICE_VERSION_1 0x100 #define DEVICE_VERSION_2 0x200 diff --git a/drivers/dma/imx-sdma.c b/drivers/dma/imx-sdma.c index 02a85d6f1bea..ed9e56de5a9b 100644 --- a/drivers/dma/imx-sdma.c +++ b/drivers/dma/imx-sdma.c @@ -256,7 +256,7 @@ struct sdma_script_start_addrs { /* End of v3 array */ union { s32 v3_end; s32 mcu_2_zqspi_addr; }; /* End of v4 array */ - s32 v4_end[0]; + s32 v4_end[]; }; /* diff --git a/drivers/dma/mmp_pdma.c b/drivers/dma/mmp_pdma.c index a95d31103d30..d07229a74886 100644 --- a/drivers/dma/mmp_pdma.c +++ b/drivers/dma/mmp_pdma.c @@ -15,6 +15,8 @@ #include <linux/device.h> #include <linux/platform_data/mmp_dma.h> #include <linux/dmapool.h> +#include <linux/clk.h> +#include <linux/reset.h> #include <linux/of_dma.h> #include <linux/of.h> @@ -23,9 +25,12 @@ #define DCSR 0x0000 #define DALGN 0x00a0 #define DINT 0x00f0 -#define DDADR 0x0200 +#define DDADR(n) (0x0200 + ((n) << 4)) #define DSADR(n) (0x0204 + ((n) << 4)) #define DTADR(n) (0x0208 + ((n) << 4)) +#define DDADRH(n) (0x0300 + ((n) << 4)) +#define DSADRH(n) (0x0304 + ((n) << 4)) +#define DTADRH(n) (0x0308 + ((n) << 4)) #define DCMD 0x020c #define DCSR_RUN BIT(31) /* Run Bit (read / write) */ @@ -42,6 +47,7 @@ #define DCSR_EORSTOPEN BIT(26) /* STOP on an EOR */ #define DCSR_SETCMPST BIT(25) /* Set Descriptor Compare Status */ #define DCSR_CLRCMPST BIT(24) /* Clear Descriptor Compare Status */ +#define DCSR_LPAEEN BIT(21) /* Long Physical Address Extension Enable */ #define DCSR_CMPST BIT(10) /* The Descriptor Compare Status */ #define DCSR_EORINTR BIT(9) /* The end of Receive */ @@ -74,6 +80,16 @@ struct mmp_pdma_desc_hw { u32 dsadr; /* DSADR value for the current transfer */ u32 dtadr; /* DTADR value for the current transfer */ u32 dcmd; /* DCMD value for the current transfer */ + /* + * The following 32-bit words are only used in the 64-bit, ie. + * LPAE (Long Physical Address Extension) mode. + * They are used to specify the high 32 bits of the descriptor's + * addresses. + */ + u32 ddadrh; /* High 32-bit of DDADR */ + u32 dsadrh; /* High 32-bit of DSADR */ + u32 dtadrh; /* High 32-bit of DTADR */ + u32 rsvd; /* reserved */ } __aligned(32); struct mmp_pdma_desc_sw { @@ -118,12 +134,55 @@ struct mmp_pdma_phy { struct mmp_pdma_chan *vchan; }; +/** + * struct mmp_pdma_ops - Operations for the MMP PDMA controller + * + * Hardware Register Operations (read/write hardware registers): + * @write_next_addr: Function to program address of next descriptor into + * DDADR/DDADRH + * @read_src_addr: Function to read the source address from DSADR/DSADRH + * @read_dst_addr: Function to read the destination address from DTADR/DTADRH + * + * Descriptor Memory Operations (manipulate descriptor structs in memory): + * @set_desc_next_addr: Function to set next descriptor address in descriptor + * @set_desc_src_addr: Function to set the source address in descriptor + * @set_desc_dst_addr: Function to set the destination address in descriptor + * @get_desc_src_addr: Function to get the source address from descriptor + * @get_desc_dst_addr: Function to get the destination address from descriptor + * + * Controller Configuration: + * @run_bits: Control bits in DCSR register for channel start/stop + * @dma_mask: DMA addressing capability of controller. 0 to use OF/platform + * settings, or explicit mask like DMA_BIT_MASK(32/64) + */ +struct mmp_pdma_ops { + /* Hardware Register Operations */ + void (*write_next_addr)(struct mmp_pdma_phy *phy, dma_addr_t addr); + u64 (*read_src_addr)(struct mmp_pdma_phy *phy); + u64 (*read_dst_addr)(struct mmp_pdma_phy *phy); + + /* Descriptor Memory Operations */ + void (*set_desc_next_addr)(struct mmp_pdma_desc_hw *desc, + dma_addr_t addr); + void (*set_desc_src_addr)(struct mmp_pdma_desc_hw *desc, + dma_addr_t addr); + void (*set_desc_dst_addr)(struct mmp_pdma_desc_hw *desc, + dma_addr_t addr); + u64 (*get_desc_src_addr)(const struct mmp_pdma_desc_hw *desc); + u64 (*get_desc_dst_addr)(const struct mmp_pdma_desc_hw *desc); + + /* Controller Configuration */ + u32 run_bits; + u64 dma_mask; +}; + struct mmp_pdma_device { int dma_channels; void __iomem *base; struct device *dev; struct dma_device device; struct mmp_pdma_phy *phy; + const struct mmp_pdma_ops *ops; spinlock_t phy_lock; /* protect alloc/free phy channels */ }; @@ -136,24 +195,112 @@ struct mmp_pdma_device { #define to_mmp_pdma_dev(dmadev) \ container_of(dmadev, struct mmp_pdma_device, device) -static int mmp_pdma_config_write(struct dma_chan *dchan, - struct dma_slave_config *cfg, - enum dma_transfer_direction direction); +/* For 32-bit PDMA */ +static void write_next_addr_32(struct mmp_pdma_phy *phy, dma_addr_t addr) +{ + writel(addr, phy->base + DDADR(phy->idx)); +} + +static u64 read_src_addr_32(struct mmp_pdma_phy *phy) +{ + return readl(phy->base + DSADR(phy->idx)); +} + +static u64 read_dst_addr_32(struct mmp_pdma_phy *phy) +{ + return readl(phy->base + DTADR(phy->idx)); +} + +static void set_desc_next_addr_32(struct mmp_pdma_desc_hw *desc, dma_addr_t addr) +{ + desc->ddadr = addr; +} + +static void set_desc_src_addr_32(struct mmp_pdma_desc_hw *desc, dma_addr_t addr) +{ + desc->dsadr = addr; +} + +static void set_desc_dst_addr_32(struct mmp_pdma_desc_hw *desc, dma_addr_t addr) +{ + desc->dtadr = addr; +} + +static u64 get_desc_src_addr_32(const struct mmp_pdma_desc_hw *desc) +{ + return desc->dsadr; +} + +static u64 get_desc_dst_addr_32(const struct mmp_pdma_desc_hw *desc) +{ + return desc->dtadr; +} + +/* For 64-bit PDMA */ +static void write_next_addr_64(struct mmp_pdma_phy *phy, dma_addr_t addr) +{ + writel(lower_32_bits(addr), phy->base + DDADR(phy->idx)); + writel(upper_32_bits(addr), phy->base + DDADRH(phy->idx)); +} + +static u64 read_src_addr_64(struct mmp_pdma_phy *phy) +{ + u32 low = readl(phy->base + DSADR(phy->idx)); + u32 high = readl(phy->base + DSADRH(phy->idx)); + + return ((u64)high << 32) | low; +} -static void set_desc(struct mmp_pdma_phy *phy, dma_addr_t addr) +static u64 read_dst_addr_64(struct mmp_pdma_phy *phy) { - u32 reg = (phy->idx << 4) + DDADR; + u32 low = readl(phy->base + DTADR(phy->idx)); + u32 high = readl(phy->base + DTADRH(phy->idx)); - writel(addr, phy->base + reg); + return ((u64)high << 32) | low; } +static void set_desc_next_addr_64(struct mmp_pdma_desc_hw *desc, dma_addr_t addr) +{ + desc->ddadr = lower_32_bits(addr); + desc->ddadrh = upper_32_bits(addr); +} + +static void set_desc_src_addr_64(struct mmp_pdma_desc_hw *desc, dma_addr_t addr) +{ + desc->dsadr = lower_32_bits(addr); + desc->dsadrh = upper_32_bits(addr); +} + +static void set_desc_dst_addr_64(struct mmp_pdma_desc_hw *desc, dma_addr_t addr) +{ + desc->dtadr = lower_32_bits(addr); + desc->dtadrh = upper_32_bits(addr); +} + +static u64 get_desc_src_addr_64(const struct mmp_pdma_desc_hw *desc) +{ + return ((u64)desc->dsadrh << 32) | desc->dsadr; +} + +static u64 get_desc_dst_addr_64(const struct mmp_pdma_desc_hw *desc) +{ + return ((u64)desc->dtadrh << 32) | desc->dtadr; +} + +static int mmp_pdma_config_write(struct dma_chan *dchan, + struct dma_slave_config *cfg, + enum dma_transfer_direction direction); + static void enable_chan(struct mmp_pdma_phy *phy) { u32 reg, dalgn; + struct mmp_pdma_device *pdev; if (!phy->vchan) return; + pdev = to_mmp_pdma_dev(phy->vchan->chan.device); + reg = DRCMR(phy->vchan->drcmr); writel(DRCMR_MAPVLD | phy->idx, phy->base + reg); @@ -165,18 +312,29 @@ static void enable_chan(struct mmp_pdma_phy *phy) writel(dalgn, phy->base + DALGN); reg = (phy->idx << 2) + DCSR; - writel(readl(phy->base + reg) | DCSR_RUN, phy->base + reg); + writel(readl(phy->base + reg) | pdev->ops->run_bits, + phy->base + reg); } static void disable_chan(struct mmp_pdma_phy *phy) { - u32 reg; + u32 reg, dcsr; if (!phy) return; reg = (phy->idx << 2) + DCSR; - writel(readl(phy->base + reg) & ~DCSR_RUN, phy->base + reg); + dcsr = readl(phy->base + reg); + + if (phy->vchan) { + struct mmp_pdma_device *pdev; + + pdev = to_mmp_pdma_dev(phy->vchan->chan.device); + writel(dcsr & ~pdev->ops->run_bits, phy->base + reg); + } else { + /* If no vchan, just clear the RUN bit */ + writel(dcsr & ~DCSR_RUN, phy->base + reg); + } } static int clear_chan_irq(struct mmp_pdma_phy *phy) @@ -295,6 +453,7 @@ static void mmp_pdma_free_phy(struct mmp_pdma_chan *pchan) static void start_pending_queue(struct mmp_pdma_chan *chan) { struct mmp_pdma_desc_sw *desc; + struct mmp_pdma_device *pdev = to_mmp_pdma_dev(chan->chan.device); /* still in running, irq will start the pending list */ if (!chan->idle) { @@ -329,7 +488,7 @@ static void start_pending_queue(struct mmp_pdma_chan *chan) * Program the descriptor's address into the DMA controller, * then start the DMA transaction */ - set_desc(chan->phy, desc->async_tx.phys); + pdev->ops->write_next_addr(chan->phy, desc->async_tx.phys); enable_chan(chan->phy); chan->idle = false; } @@ -445,15 +604,14 @@ mmp_pdma_prep_memcpy(struct dma_chan *dchan, size_t len, unsigned long flags) { struct mmp_pdma_chan *chan; + struct mmp_pdma_device *pdev; struct mmp_pdma_desc_sw *first = NULL, *prev = NULL, *new; size_t copy = 0; - if (!dchan) - return NULL; - - if (!len) + if (!dchan || !len) return NULL; + pdev = to_mmp_pdma_dev(dchan->device); chan = to_mmp_pdma_chan(dchan); chan->byte_align = false; @@ -476,13 +634,14 @@ mmp_pdma_prep_memcpy(struct dma_chan *dchan, chan->byte_align = true; new->desc.dcmd = chan->dcmd | (DCMD_LENGTH & copy); - new->desc.dsadr = dma_src; - new->desc.dtadr = dma_dst; + pdev->ops->set_desc_src_addr(&new->desc, dma_src); + pdev->ops->set_desc_dst_addr(&new->desc, dma_dst); if (!first) first = new; else - prev->desc.ddadr = new->async_tx.phys; + pdev->ops->set_desc_next_addr(&prev->desc, + new->async_tx.phys); new->async_tx.cookie = 0; async_tx_ack(&new->async_tx); @@ -526,6 +685,7 @@ mmp_pdma_prep_slave_sg(struct dma_chan *dchan, struct scatterlist *sgl, unsigned long flags, void *context) { struct mmp_pdma_chan *chan = to_mmp_pdma_chan(dchan); + struct mmp_pdma_device *pdev = to_mmp_pdma_dev(dchan->device); struct mmp_pdma_desc_sw *first = NULL, *prev = NULL, *new = NULL; size_t len, avail; struct scatterlist *sg; @@ -557,17 +717,18 @@ mmp_pdma_prep_slave_sg(struct dma_chan *dchan, struct scatterlist *sgl, new->desc.dcmd = chan->dcmd | (DCMD_LENGTH & len); if (dir == DMA_MEM_TO_DEV) { - new->desc.dsadr = addr; + pdev->ops->set_desc_src_addr(&new->desc, addr); new->desc.dtadr = chan->dev_addr; } else { new->desc.dsadr = chan->dev_addr; - new->desc.dtadr = addr; + pdev->ops->set_desc_dst_addr(&new->desc, addr); } if (!first) first = new; else - prev->desc.ddadr = new->async_tx.phys; + pdev->ops->set_desc_next_addr(&prev->desc, + new->async_tx.phys); new->async_tx.cookie = 0; async_tx_ack(&new->async_tx); @@ -607,12 +768,15 @@ mmp_pdma_prep_dma_cyclic(struct dma_chan *dchan, unsigned long flags) { struct mmp_pdma_chan *chan; + struct mmp_pdma_device *pdev; struct mmp_pdma_desc_sw *first = NULL, *prev = NULL, *new; dma_addr_t dma_src, dma_dst; if (!dchan || !len || !period_len) return NULL; + pdev = to_mmp_pdma_dev(dchan->device); + /* the buffer length must be a multiple of period_len */ if (len % period_len != 0) return NULL; @@ -649,13 +813,14 @@ mmp_pdma_prep_dma_cyclic(struct dma_chan *dchan, new->desc.dcmd = (chan->dcmd | DCMD_ENDIRQEN | (DCMD_LENGTH & period_len)); - new->desc.dsadr = dma_src; - new->desc.dtadr = dma_dst; + pdev->ops->set_desc_src_addr(&new->desc, dma_src); + pdev->ops->set_desc_dst_addr(&new->desc, dma_dst); if (!first) first = new; else - prev->desc.ddadr = new->async_tx.phys; + pdev->ops->set_desc_next_addr(&prev->desc, + new->async_tx.phys); new->async_tx.cookie = 0; async_tx_ack(&new->async_tx); @@ -676,7 +841,7 @@ mmp_pdma_prep_dma_cyclic(struct dma_chan *dchan, first->async_tx.cookie = -EBUSY; /* make the cyclic link */ - new->desc.ddadr = first->async_tx.phys; + pdev->ops->set_desc_next_addr(&new->desc, first->async_tx.phys); chan->cyclic_first = first; return &first->async_tx; @@ -762,7 +927,9 @@ static unsigned int mmp_pdma_residue(struct mmp_pdma_chan *chan, dma_cookie_t cookie) { struct mmp_pdma_desc_sw *sw; - u32 curr, residue = 0; + struct mmp_pdma_device *pdev = to_mmp_pdma_dev(chan->chan.device); + u64 curr; + u32 residue = 0; bool passed = false; bool cyclic = chan->cyclic_first != NULL; @@ -774,17 +941,18 @@ static unsigned int mmp_pdma_residue(struct mmp_pdma_chan *chan, return 0; if (chan->dir == DMA_DEV_TO_MEM) - curr = readl(chan->phy->base + DTADR(chan->phy->idx)); + curr = pdev->ops->read_dst_addr(chan->phy); else - curr = readl(chan->phy->base + DSADR(chan->phy->idx)); + curr = pdev->ops->read_src_addr(chan->phy); list_for_each_entry(sw, &chan->chain_running, node) { - u32 start, end, len; + u64 start, end; + u32 len; if (chan->dir == DMA_DEV_TO_MEM) - start = sw->desc.dtadr; + start = pdev->ops->get_desc_dst_addr(&sw->desc); else - start = sw->desc.dsadr; + start = pdev->ops->get_desc_src_addr(&sw->desc); len = sw->desc.dcmd & DCMD_LENGTH; end = start + len; @@ -800,7 +968,7 @@ static unsigned int mmp_pdma_residue(struct mmp_pdma_chan *chan, if (passed) { residue += len; } else if (curr >= start && curr <= end) { - residue += end - curr; + residue += (u32)(end - curr); passed = true; } @@ -994,9 +1162,42 @@ static int mmp_pdma_chan_init(struct mmp_pdma_device *pdev, int idx, int irq) return 0; } +static const struct mmp_pdma_ops marvell_pdma_v1_ops = { + .write_next_addr = write_next_addr_32, + .read_src_addr = read_src_addr_32, + .read_dst_addr = read_dst_addr_32, + .set_desc_next_addr = set_desc_next_addr_32, + .set_desc_src_addr = set_desc_src_addr_32, + .set_desc_dst_addr = set_desc_dst_addr_32, + .get_desc_src_addr = get_desc_src_addr_32, + .get_desc_dst_addr = get_desc_dst_addr_32, + .run_bits = (DCSR_RUN), + .dma_mask = 0, /* let OF/platform set DMA mask */ +}; + +static const struct mmp_pdma_ops spacemit_k1_pdma_ops = { + .write_next_addr = write_next_addr_64, + .read_src_addr = read_src_addr_64, + .read_dst_addr = read_dst_addr_64, + .set_desc_next_addr = set_desc_next_addr_64, + .set_desc_src_addr = set_desc_src_addr_64, + .set_desc_dst_addr = set_desc_dst_addr_64, + .get_desc_src_addr = get_desc_src_addr_64, + .get_desc_dst_addr = get_desc_dst_addr_64, + .run_bits = (DCSR_RUN | DCSR_LPAEEN), + .dma_mask = DMA_BIT_MASK(64), /* force 64-bit DMA addr capability */ +}; + static const struct of_device_id mmp_pdma_dt_ids[] = { - { .compatible = "marvell,pdma-1.0", }, - {} + { + .compatible = "marvell,pdma-1.0", + .data = &marvell_pdma_v1_ops + }, { + .compatible = "spacemit,k1-pdma", + .data = &spacemit_k1_pdma_ops + }, { + /* sentinel */ + } }; MODULE_DEVICE_TABLE(of, mmp_pdma_dt_ids); @@ -1019,6 +1220,8 @@ static int mmp_pdma_probe(struct platform_device *op) { struct mmp_pdma_device *pdev; struct mmp_dma_platdata *pdata = dev_get_platdata(&op->dev); + struct clk *clk; + struct reset_control *rst; int i, ret, irq = 0; int dma_channels = 0, irq_num = 0; const enum dma_slave_buswidth widths = @@ -1037,6 +1240,19 @@ static int mmp_pdma_probe(struct platform_device *op) if (IS_ERR(pdev->base)) return PTR_ERR(pdev->base); + clk = devm_clk_get_optional_enabled(pdev->dev, NULL); + if (IS_ERR(clk)) + return PTR_ERR(clk); + + rst = devm_reset_control_get_optional_exclusive_deasserted(pdev->dev, + NULL); + if (IS_ERR(rst)) + return PTR_ERR(rst); + + pdev->ops = of_device_get_match_data(&op->dev); + if (!pdev->ops) + return -ENODEV; + if (pdev->dev->of_node) { /* Parse new and deprecated dma-channels properties */ if (of_property_read_u32(pdev->dev->of_node, "dma-channels", @@ -1098,7 +1314,10 @@ static int mmp_pdma_probe(struct platform_device *op) pdev->device.directions = BIT(DMA_MEM_TO_DEV) | BIT(DMA_DEV_TO_MEM); pdev->device.residue_granularity = DMA_RESIDUE_GRANULARITY_DESCRIPTOR; - if (pdev->dev->coherent_dma_mask) + /* Set DMA mask based on ops->dma_mask, or OF/platform */ + if (pdev->ops->dma_mask) + dma_set_mask(pdev->dev, pdev->ops->dma_mask); + else if (pdev->dev->coherent_dma_mask) dma_set_mask(pdev->dev, pdev->dev->coherent_dma_mask); else dma_set_mask(pdev->dev, DMA_BIT_MASK(64)); diff --git a/drivers/dma/mv_xor.c b/drivers/dma/mv_xor.c index 1fdcb0f5c9e7..5e8386296046 100644 --- a/drivers/dma/mv_xor.c +++ b/drivers/dma/mv_xor.c @@ -1013,7 +1013,7 @@ static int mv_xor_channel_remove(struct mv_xor_chan *mv_chan) dma_async_device_unregister(&mv_chan->dmadev); - dma_free_coherent(dev, MV_XOR_POOL_SIZE, + dma_free_wc(dev, MV_XOR_POOL_SIZE, mv_chan->dma_desc_pool_virt, mv_chan->dma_desc_pool); dma_unmap_single(dev, mv_chan->dummy_src_addr, MV_XOR_MIN_BYTE_COUNT, DMA_FROM_DEVICE); @@ -1163,7 +1163,7 @@ mv_xor_channel_add(struct mv_xor_device *xordev, err_free_irq: free_irq(mv_chan->irq, mv_chan); err_free_dma: - dma_free_coherent(&pdev->dev, MV_XOR_POOL_SIZE, + dma_free_wc(&pdev->dev, MV_XOR_POOL_SIZE, mv_chan->dma_desc_pool_virt, mv_chan->dma_desc_pool); err_unmap_dst: dma_unmap_single(dma_dev->dev, mv_chan->dummy_dst_addr, diff --git a/drivers/dma/ppc4xx/adma.c b/drivers/dma/ppc4xx/adma.c index 9d2a5a967a99..61500ad7c850 100644 --- a/drivers/dma/ppc4xx/adma.c +++ b/drivers/dma/ppc4xx/adma.c @@ -874,7 +874,7 @@ static int ppc440spe_dma2_pq_slot_count(dma_addr_t *srcs, pr_err("%s: src_cnt=%d, state=%d, addr_count=%d, order=%lld\n", __func__, src_cnt, state, addr_count, order); for (i = 0; i < src_cnt; i++) - pr_err("\t[%d] 0x%llx \n", i, srcs[i]); + pr_err("\t[%d] 0x%llx\n", i, srcs[i]); BUG(); } @@ -3636,7 +3636,7 @@ static void ppc440spe_adma_issue_pending(struct dma_chan *chan) ppc440spe_chan = to_ppc440spe_adma_chan(chan); dev_dbg(ppc440spe_chan->device->common.dev, - "ppc440spe adma%d: %s %d \n", ppc440spe_chan->device->id, + "ppc440spe adma%d: %s %d\n", ppc440spe_chan->device->id, __func__, ppc440spe_chan->pending); if (ppc440spe_chan->pending) { diff --git a/drivers/dma/sh/shdma-base.c b/drivers/dma/sh/shdma-base.c index 6b4fce453c85..834741adadaa 100644 --- a/drivers/dma/sh/shdma-base.c +++ b/drivers/dma/sh/shdma-base.c @@ -129,12 +129,25 @@ static dma_cookie_t shdma_tx_submit(struct dma_async_tx_descriptor *tx) const struct shdma_ops *ops = sdev->ops; dev_dbg(schan->dev, "Bring up channel %d\n", schan->id); - /* - * TODO: .xfer_setup() might fail on some platforms. - * Make it int then, on error remove chunks from the - * queue again - */ - ops->setup_xfer(schan, schan->slave_id); + + ret = ops->setup_xfer(schan, schan->slave_id); + if (ret < 0) { + dev_err(schan->dev, "setup_xfer failed: %d\n", ret); + + /* Remove chunks from the queue and mark them as idle */ + list_for_each_entry_safe(chunk, c, &schan->ld_queue, node) { + if (chunk->cookie == cookie) { + chunk->mark = DESC_IDLE; + list_move(&chunk->node, &schan->ld_free); + } + } + + schan->pm_state = SHDMA_PM_ESTABLISHED; + ret = pm_runtime_put(schan->dev); + + spin_unlock_irq(&schan->chan_lock); + return ret; + } if (schan->pm_state == SHDMA_PM_PENDING) shdma_chan_xfer_ld_queue(schan); diff --git a/drivers/dma/sh/shdmac.c b/drivers/dma/sh/shdmac.c index 093e449e19ee..603e15102e45 100644 --- a/drivers/dma/sh/shdmac.c +++ b/drivers/dma/sh/shdmac.c @@ -300,21 +300,30 @@ static bool sh_dmae_channel_busy(struct shdma_chan *schan) return dmae_is_busy(sh_chan); } -static void sh_dmae_setup_xfer(struct shdma_chan *schan, - int slave_id) +static int sh_dmae_setup_xfer(struct shdma_chan *schan, int slave_id) { struct sh_dmae_chan *sh_chan = container_of(schan, struct sh_dmae_chan, shdma_chan); + int ret = 0; if (slave_id >= 0) { const struct sh_dmae_slave_config *cfg = sh_chan->config; - dmae_set_dmars(sh_chan, cfg->mid_rid); - dmae_set_chcr(sh_chan, cfg->chcr); + ret = dmae_set_dmars(sh_chan, cfg->mid_rid); + if (ret < 0) + goto END; + + ret = dmae_set_chcr(sh_chan, cfg->chcr); + if (ret < 0) + goto END; + } else { dmae_init(sh_chan); } + +END: + return ret; } /* diff --git a/drivers/dma/xilinx/xilinx_dma.c b/drivers/dma/xilinx/xilinx_dma.c index a34d8f0ceed8..fabff602065f 100644 --- a/drivers/dma/xilinx/xilinx_dma.c +++ b/drivers/dma/xilinx/xilinx_dma.c @@ -2173,6 +2173,99 @@ error: } /** + * xilinx_dma_prep_peripheral_dma_vec - prepare descriptors for a DMA_SLAVE + * transaction from DMA vectors + * @dchan: DMA channel + * @vecs: Array of DMA vectors that should be transferred + * @nb: number of entries in @vecs + * @direction: DMA direction + * @flags: transfer ack flags + * + * Return: Async transaction descriptor on success and NULL on failure + */ +static struct dma_async_tx_descriptor *xilinx_dma_prep_peripheral_dma_vec( + struct dma_chan *dchan, const struct dma_vec *vecs, size_t nb, + enum dma_transfer_direction direction, unsigned long flags) +{ + struct xilinx_dma_chan *chan = to_xilinx_chan(dchan); + struct xilinx_dma_tx_descriptor *desc; + struct xilinx_axidma_tx_segment *segment, *head, *prev = NULL; + size_t copy; + size_t sg_used; + unsigned int i; + + if (!is_slave_direction(direction) || direction != chan->direction) + return NULL; + + desc = xilinx_dma_alloc_tx_descriptor(chan); + if (!desc) + return NULL; + + dma_async_tx_descriptor_init(&desc->async_tx, &chan->common); + desc->async_tx.tx_submit = xilinx_dma_tx_submit; + + /* Build transactions using information from DMA vectors */ + for (i = 0; i < nb; i++) { + sg_used = 0; + + /* Loop until the entire dma_vec entry is used */ + while (sg_used < vecs[i].len) { + struct xilinx_axidma_desc_hw *hw; + + /* Get a free segment */ + segment = xilinx_axidma_alloc_tx_segment(chan); + if (!segment) + goto error; + + /* + * Calculate the maximum number of bytes to transfer, + * making sure it is less than the hw limit + */ + copy = xilinx_dma_calc_copysize(chan, vecs[i].len, + sg_used); + hw = &segment->hw; + + /* Fill in the descriptor */ + xilinx_axidma_buf(chan, hw, vecs[i].addr, sg_used, 0); + hw->control = copy; + + if (prev) + prev->hw.next_desc = segment->phys; + + prev = segment; + sg_used += copy; + + /* + * Insert the segment into the descriptor segments + * list. + */ + list_add_tail(&segment->node, &desc->segments); + } + } + + head = list_first_entry(&desc->segments, struct xilinx_axidma_tx_segment, node); + desc->async_tx.phys = head->phys; + + /* For the last DMA_MEM_TO_DEV transfer, set EOP */ + if (chan->direction == DMA_MEM_TO_DEV) { + segment->hw.control |= XILINX_DMA_BD_SOP; + segment = list_last_entry(&desc->segments, + struct xilinx_axidma_tx_segment, + node); + segment->hw.control |= XILINX_DMA_BD_EOP; + } + + if (chan->xdev->has_axistream_connected) + desc->async_tx.metadata_ops = &xilinx_dma_metadata_ops; + + return &desc->async_tx; + +error: + xilinx_dma_free_tx_descriptor(chan, desc); + return NULL; +} + +/** * xilinx_dma_prep_slave_sg - prepare descriptors for a DMA_SLAVE transaction * @dchan: DMA channel * @sgl: scatterlist to transfer to/from @@ -3180,6 +3273,7 @@ static int xilinx_dma_probe(struct platform_device *pdev) xdev->common.device_config = xilinx_dma_device_config; if (xdev->dma_config->dmatype == XDMA_TYPE_AXIDMA) { dma_cap_set(DMA_CYCLIC, xdev->common.cap_mask); + xdev->common.device_prep_peripheral_dma_vec = xilinx_dma_prep_peripheral_dma_vec; xdev->common.device_prep_slave_sg = xilinx_dma_prep_slave_sg; xdev->common.device_prep_dma_cyclic = xilinx_dma_prep_dma_cyclic; diff --git a/drivers/dma/xilinx/zynqmp_dma.c b/drivers/dma/xilinx/zynqmp_dma.c index d05fc5fcc77d..f7e584de4335 100644 --- a/drivers/dma/xilinx/zynqmp_dma.c +++ b/drivers/dma/xilinx/zynqmp_dma.c @@ -1173,9 +1173,9 @@ static void zynqmp_dma_remove(struct platform_device *pdev) dma_async_device_unregister(&zdev->common); zynqmp_dma_chan_remove(zdev->chan); - pm_runtime_disable(zdev->dev); - if (!pm_runtime_enabled(zdev->dev)) + if (pm_runtime_active(zdev->dev)) zynqmp_dma_runtime_suspend(zdev->dev); + pm_runtime_disable(zdev->dev); } static const struct of_device_id zynqmp_dma_of_match[] = { @@ -1193,6 +1193,7 @@ static struct platform_driver zynqmp_dma_driver = { }, .probe = zynqmp_dma_probe, .remove = zynqmp_dma_remove, + .shutdown = zynqmp_dma_remove, }; module_platform_driver(zynqmp_dma_driver); diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig index fda170730468..7e6bc0b3a589 100644 --- a/drivers/gpu/drm/Kconfig +++ b/drivers/gpu/drm/Kconfig @@ -400,7 +400,7 @@ source "drivers/gpu/drm/tyr/Kconfig" config DRM_HYPERV tristate "DRM Support for Hyper-V synthetic video device" - depends on DRM && PCI && HYPERV + depends on DRM && PCI && HYPERV_VMBUS select DRM_CLIENT_SELECTION select DRM_KMS_HELPER select DRM_GEM_SHMEM_HELPER diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig index 7ff85c7200e5..5341aa79f387 100644 --- a/drivers/hid/Kconfig +++ b/drivers/hid/Kconfig @@ -1171,7 +1171,7 @@ config GREENASIA_FF config HID_HYPERV_MOUSE tristate "Microsoft Hyper-V mouse driver" - depends on HYPERV + depends on HYPERV_VMBUS help Select this option to enable the Hyper-V mouse driver. diff --git a/drivers/hv/Kconfig b/drivers/hv/Kconfig index 57623ca7f350..0b8c391a0342 100644 --- a/drivers/hv/Kconfig +++ b/drivers/hv/Kconfig @@ -3,13 +3,14 @@ menu "Microsoft Hyper-V guest support" config HYPERV - tristate "Microsoft Hyper-V client drivers" + bool "Microsoft Hyper-V core hypervisor support" depends on (X86 && X86_LOCAL_APIC && HYPERVISOR_GUEST) \ || (ARM64 && !CPU_BIG_ENDIAN) select PARAVIRT select X86_HV_CALLBACK_VECTOR if X86 select OF_EARLY_FLATTREE if OF select SYSFB if EFI && !HYPERV_VTL_MODE + select IRQ_MSI_LIB if X86 help Select this option to run Linux as a Hyper-V client operating system. @@ -44,18 +45,25 @@ config HYPERV_TIMER config HYPERV_UTILS tristate "Microsoft Hyper-V Utilities driver" - depends on HYPERV && CONNECTOR && NLS + depends on HYPERV_VMBUS && CONNECTOR && NLS depends on PTP_1588_CLOCK_OPTIONAL help Select this option to enable the Hyper-V Utilities. config HYPERV_BALLOON tristate "Microsoft Hyper-V Balloon driver" - depends on HYPERV + depends on HYPERV_VMBUS select PAGE_REPORTING help Select this option to enable Hyper-V Balloon driver. +config HYPERV_VMBUS + tristate "Microsoft Hyper-V VMBus driver" + depends on HYPERV + default HYPERV + help + Select this option to enable Hyper-V Vmbus driver. + config MSHV_ROOT tristate "Microsoft Hyper-V root partition support" depends on HYPERV && (X86_64 || ARM64) @@ -66,6 +74,7 @@ config MSHV_ROOT # no particular order, making it impossible to reassemble larger pages depends on PAGE_SIZE_4KB select EVENTFD + select VIRT_XFER_TO_GUEST_WORK default n help Select this option to enable support for booting and running as root diff --git a/drivers/hv/Makefile b/drivers/hv/Makefile index 976189c725dc..1a1677bf4dac 100644 --- a/drivers/hv/Makefile +++ b/drivers/hv/Makefile @@ -1,5 +1,5 @@ # SPDX-License-Identifier: GPL-2.0 -obj-$(CONFIG_HYPERV) += hv_vmbus.o +obj-$(CONFIG_HYPERV_VMBUS) += hv_vmbus.o obj-$(CONFIG_HYPERV_UTILS) += hv_utils.o obj-$(CONFIG_HYPERV_BALLOON) += hv_balloon.o obj-$(CONFIG_MSHV_ROOT) += mshv_root.o @@ -16,5 +16,5 @@ mshv_root-y := mshv_root_main.o mshv_synic.o mshv_eventfd.o mshv_irq.o \ mshv_root_hv_call.o mshv_portid_table.o # Code that must be built-in -obj-$(subst m,y,$(CONFIG_HYPERV)) += hv_common.o +obj-$(CONFIG_HYPERV) += hv_common.o obj-$(subst m,y,$(CONFIG_MSHV_ROOT)) += hv_proc.o mshv_common.o diff --git a/drivers/hv/channel.c b/drivers/hv/channel.c index 7c7c66e0dc3f..162d6aeece7b 100644 --- a/drivers/hv/channel.c +++ b/drivers/hv/channel.c @@ -925,7 +925,7 @@ static int vmbus_close_internal(struct vmbus_channel *channel) /* Send a closing message */ - msg = &channel->close_msg.msg; + msg = &channel->close_msg; msg->header.msgtype = CHANNELMSG_CLOSECHANNEL; msg->child_relid = channel->offermsg.child_relid; diff --git a/drivers/hv/hv_common.c b/drivers/hv/hv_common.c index 49898d10faff..e109a620c83f 100644 --- a/drivers/hv/hv_common.c +++ b/drivers/hv/hv_common.c @@ -257,7 +257,7 @@ static void hv_kmsg_dump_register(void) static inline bool hv_output_page_exists(void) { - return hv_root_partition() || IS_ENABLED(CONFIG_HYPERV_VTL_MODE); + return hv_parent_partition() || IS_ENABLED(CONFIG_HYPERV_VTL_MODE); } void __init hv_get_partition_id(void) @@ -377,7 +377,7 @@ int __init hv_common_init(void) BUG_ON(!hyperv_pcpu_output_arg); } - if (hv_root_partition()) { + if (hv_parent_partition()) { hv_synic_eventring_tail = alloc_percpu(u8 *); BUG_ON(!hv_synic_eventring_tail); } @@ -531,7 +531,7 @@ int hv_common_cpu_init(unsigned int cpu) if (msr_vp_index > hv_max_vp_index) hv_max_vp_index = msr_vp_index; - if (hv_root_partition()) { + if (hv_parent_partition()) { synic_eventring_tail = (u8 **)this_cpu_ptr(hv_synic_eventring_tail); *synic_eventring_tail = kcalloc(HV_SYNIC_SINT_COUNT, sizeof(u8), flags); @@ -558,7 +558,7 @@ int hv_common_cpu_die(unsigned int cpu) * originally allocated memory is reused in hv_common_cpu_init(). */ - if (hv_root_partition()) { + if (hv_parent_partition()) { synic_eventring_tail = this_cpu_ptr(hv_synic_eventring_tail); kfree(*synic_eventring_tail); *synic_eventring_tail = NULL; @@ -729,13 +729,17 @@ void hv_identify_partition_type(void) * the root partition setting if also a Confidential VM. */ if ((ms_hyperv.priv_high & HV_CREATE_PARTITIONS) && - (ms_hyperv.priv_high & HV_CPU_MANAGEMENT) && !(ms_hyperv.priv_high & HV_ISOLATION)) { - pr_info("Hyper-V: running as root partition\n"); - if (IS_ENABLED(CONFIG_MSHV_ROOT)) - hv_curr_partition_type = HV_PARTITION_TYPE_ROOT; - else + + if (!IS_ENABLED(CONFIG_MSHV_ROOT)) { pr_crit("Hyper-V: CONFIG_MSHV_ROOT not enabled!\n"); + } else if (ms_hyperv.priv_high & HV_CPU_MANAGEMENT) { + pr_info("Hyper-V: running as root partition\n"); + hv_curr_partition_type = HV_PARTITION_TYPE_ROOT; + } else { + pr_info("Hyper-V: running as L1VH partition\n"); + hv_curr_partition_type = HV_PARTITION_TYPE_L1VH; + } } } diff --git a/drivers/hv/hv_utils_transport.c b/drivers/hv/hv_utils_transport.c index 832885198643..b3de35ff6334 100644 --- a/drivers/hv/hv_utils_transport.c +++ b/drivers/hv/hv_utils_transport.c @@ -129,8 +129,7 @@ static int hvt_op_open(struct inode *inode, struct file *file) * device gets released. */ hvt->mode = HVUTIL_TRANSPORT_CHARDEV; - } - else if (hvt->mode == HVUTIL_TRANSPORT_NETLINK) { + } else if (hvt->mode == HVUTIL_TRANSPORT_NETLINK) { /* * We're switching from netlink communication to using char * device. Issue the reset first. @@ -195,7 +194,7 @@ static void hvt_cn_callback(struct cn_msg *msg, struct netlink_skb_parms *nsp) } spin_unlock(&hvt_list_lock); if (!hvt_found) { - pr_warn("hvt_cn_callback: spurious message received!\n"); + pr_warn("%s: spurious message received!\n", __func__); return; } @@ -210,7 +209,7 @@ static void hvt_cn_callback(struct cn_msg *msg, struct netlink_skb_parms *nsp) if (hvt->mode == HVUTIL_TRANSPORT_NETLINK) hvt_found->on_msg(msg->data, msg->len); else - pr_warn("hvt_cn_callback: unexpected netlink message!\n"); + pr_warn("%s: unexpected netlink message!\n", __func__); mutex_unlock(&hvt->lock); } @@ -260,8 +259,9 @@ int hvutil_transport_send(struct hvutil_transport *hvt, void *msg, int len, hvt->outmsg_len = len; hvt->on_read = on_read_cb; wake_up_interruptible(&hvt->outmsg_q); - } else + } else { ret = -ENOMEM; + } out_unlock: mutex_unlock(&hvt->lock); return ret; diff --git a/drivers/hv/mshv.h b/drivers/hv/mshv.h index 0340a67acd0a..d4813df92b9c 100644 --- a/drivers/hv/mshv.h +++ b/drivers/hv/mshv.h @@ -25,6 +25,4 @@ int hv_call_set_vp_registers(u32 vp_index, u64 partition_id, u16 count, int hv_call_get_partition_property(u64 partition_id, u64 property_code, u64 *property_value); -int mshv_do_pre_guest_mode_work(ulong th_flags); - #endif /* _MSHV_H */ diff --git a/drivers/hv/mshv_common.c b/drivers/hv/mshv_common.c index 6f227a8a5af7..aa2be51979fd 100644 --- a/drivers/hv/mshv_common.c +++ b/drivers/hv/mshv_common.c @@ -138,25 +138,3 @@ int hv_call_get_partition_property(u64 partition_id, return 0; } EXPORT_SYMBOL_GPL(hv_call_get_partition_property); - -/* - * Handle any pre-processing before going into the guest mode on this cpu, most - * notably call schedule(). Must be invoked with both preemption and - * interrupts enabled. - * - * Returns: 0 on success, -errno on error. - */ -int mshv_do_pre_guest_mode_work(ulong th_flags) -{ - if (th_flags & (_TIF_SIGPENDING | _TIF_NOTIFY_SIGNAL)) - return -EINTR; - - if (th_flags & _TIF_NEED_RESCHED) - schedule(); - - if (th_flags & _TIF_NOTIFY_RESUME) - resume_user_mode_work(NULL); - - return 0; -} -EXPORT_SYMBOL_GPL(mshv_do_pre_guest_mode_work); diff --git a/drivers/hv/mshv_root_main.c b/drivers/hv/mshv_root_main.c index 72df774e410a..e3b2bd417c46 100644 --- a/drivers/hv/mshv_root_main.c +++ b/drivers/hv/mshv_root_main.c @@ -8,6 +8,7 @@ * Authors: Microsoft Linux virtualization team */ +#include <linux/entry-virt.h> #include <linux/kernel.h> #include <linux/module.h> #include <linux/fs.h> @@ -37,12 +38,6 @@ MODULE_AUTHOR("Microsoft"); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("Microsoft Hyper-V root partition VMM interface /dev/mshv"); -/* TODO move this to mshyperv.h when needed outside driver */ -static inline bool hv_parent_partition(void) -{ - return hv_root_partition(); -} - /* TODO move this to another file when debugfs code is added */ enum hv_stats_vp_counters { /* HV_THREAD_COUNTER */ #if defined(CONFIG_X86) @@ -487,28 +482,6 @@ mshv_vp_wait_for_hv_kick(struct mshv_vp *vp) return 0; } -static int mshv_pre_guest_mode_work(struct mshv_vp *vp) -{ - const ulong work_flags = _TIF_NOTIFY_SIGNAL | _TIF_SIGPENDING | - _TIF_NEED_RESCHED | _TIF_NOTIFY_RESUME; - ulong th_flags; - - th_flags = read_thread_flags(); - while (th_flags & work_flags) { - int ret; - - /* nb: following will call schedule */ - ret = mshv_do_pre_guest_mode_work(th_flags); - - if (ret) - return ret; - - th_flags = read_thread_flags(); - } - - return 0; -} - /* Must be called with interrupts enabled */ static long mshv_run_vp_with_root_scheduler(struct mshv_vp *vp) { @@ -529,9 +502,11 @@ static long mshv_run_vp_with_root_scheduler(struct mshv_vp *vp) u32 flags = 0; struct hv_output_dispatch_vp output; - ret = mshv_pre_guest_mode_work(vp); - if (ret) - break; + if (__xfer_to_guest_mode_work_pending()) { + ret = xfer_to_guest_mode_handle_work(); + if (ret) + break; + } if (vp->run.flags.intercept_suspend) flags |= HV_DISPATCH_VP_FLAG_CLEAR_INTERCEPT_SUSPEND; @@ -2074,9 +2049,13 @@ static int __init hv_retrieve_scheduler_type(enum hv_scheduler_type *out) /* Retrieve and stash the supported scheduler type */ static int __init mshv_retrieve_scheduler_type(struct device *dev) { - int ret; + int ret = 0; + + if (hv_l1vh_partition()) + hv_scheduler_type = HV_SCHEDULER_TYPE_CORE_SMT; + else + ret = hv_retrieve_scheduler_type(&hv_scheduler_type); - ret = hv_retrieve_scheduler_type(&hv_scheduler_type); if (ret) return ret; @@ -2203,9 +2182,6 @@ static int __init mshv_root_partition_init(struct device *dev) { int err; - if (mshv_retrieve_scheduler_type(dev)) - return -ENODEV; - err = root_scheduler_init(dev); if (err) return err; @@ -2227,7 +2203,7 @@ static int __init mshv_parent_partition_init(void) struct device *dev; union hv_hypervisor_version_info version_info; - if (!hv_root_partition() || is_kdump_kernel()) + if (!hv_parent_partition() || is_kdump_kernel()) return -ENODEV; if (hv_get_hypervisor_version(&version_info)) @@ -2264,7 +2240,12 @@ static int __init mshv_parent_partition_init(void) mshv_cpuhp_online = ret; - ret = mshv_root_partition_init(dev); + ret = mshv_retrieve_scheduler_type(dev); + if (ret) + goto remove_cpu_state; + + if (hv_root_partition()) + ret = mshv_root_partition_init(dev); if (ret) goto remove_cpu_state; diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c index 2ed5a1e89d69..69591dc7bad2 100644 --- a/drivers/hv/vmbus_drv.c +++ b/drivers/hv/vmbus_drv.c @@ -322,7 +322,7 @@ static ssize_t out_read_index_show(struct device *dev, &outbound); if (ret < 0) return ret; - return sysfs_emit(buf, "%d\n", outbound.current_read_index); + return sysfs_emit(buf, "%u\n", outbound.current_read_index); } static DEVICE_ATTR_RO(out_read_index); @@ -341,7 +341,7 @@ static ssize_t out_write_index_show(struct device *dev, &outbound); if (ret < 0) return ret; - return sysfs_emit(buf, "%d\n", outbound.current_write_index); + return sysfs_emit(buf, "%u\n", outbound.current_write_index); } static DEVICE_ATTR_RO(out_write_index); @@ -1742,7 +1742,7 @@ static ssize_t target_cpu_store(struct vmbus_channel *channel, u32 target_cpu; ssize_t ret; - if (sscanf(buf, "%uu", &target_cpu) != 1) + if (sscanf(buf, "%u", &target_cpu) != 1) return -EIO; cpus_read_lock(); @@ -1947,7 +1947,7 @@ static const struct kobj_type vmbus_chan_ktype = { * is running. * For example, HV_NIC device is used either by uio_hv_generic or hv_netvsc at any given point of * time, and "ring" sysfs is needed only when uio_hv_generic is bound to that device. To avoid - * exposing the ring buffer by default, this function is reponsible to enable visibility of + * exposing the ring buffer by default, this function is responsible to enable visibility of * ring for userspace to use. * Note: Race conditions can happen with userspace and it is not encouraged to create new * use-cases for this. This was added to maintain backward compatibility, while solving @@ -2110,7 +2110,7 @@ int vmbus_device_register(struct hv_device *child_device_obj) ret = vmbus_add_channel_kobj(child_device_obj, child_device_obj->channel); if (ret) { - pr_err("Unable to register primary channeln"); + pr_err("Unable to register primary channel\n"); goto err_kset_unregister; } hv_debug_add_dev_dir(child_device_obj); diff --git a/drivers/input/serio/Kconfig b/drivers/input/serio/Kconfig index 17edc1597446..c7ef347a4dff 100644 --- a/drivers/input/serio/Kconfig +++ b/drivers/input/serio/Kconfig @@ -276,8 +276,8 @@ config SERIO_OLPC_APSP config HYPERV_KEYBOARD tristate "Microsoft Synthetic Keyboard driver" - depends on HYPERV - default HYPERV + depends on HYPERV_VMBUS + default HYPERV_VMBUS help Select this option to enable the Hyper-V Keyboard driver. diff --git a/drivers/misc/fastrpc.c b/drivers/misc/fastrpc.c index 8e1d97873423..621bce7e101c 100644 --- a/drivers/misc/fastrpc.c +++ b/drivers/misc/fastrpc.c @@ -320,11 +320,11 @@ static void fastrpc_free_map(struct kref *ref) perm.vmid = QCOM_SCM_VMID_HLOS; perm.perm = QCOM_SCM_PERM_RWX; - err = qcom_scm_assign_mem(map->phys, map->size, + err = qcom_scm_assign_mem(map->phys, map->len, &src_perms, &perm, 1); if (err) { dev_err(map->fl->sctx->dev, "Failed to assign memory phys 0x%llx size 0x%llx err %d\n", - map->phys, map->size, err); + map->phys, map->len, err); return; } } @@ -360,26 +360,21 @@ static int fastrpc_map_get(struct fastrpc_map *map) static int fastrpc_map_lookup(struct fastrpc_user *fl, int fd, - struct fastrpc_map **ppmap, bool take_ref) + struct fastrpc_map **ppmap) { - struct fastrpc_session_ctx *sess = fl->sctx; struct fastrpc_map *map = NULL; + struct dma_buf *buf; int ret = -ENOENT; + buf = dma_buf_get(fd); + if (IS_ERR(buf)) + return PTR_ERR(buf); + spin_lock(&fl->lock); list_for_each_entry(map, &fl->maps, node) { - if (map->fd != fd) + if (map->fd != fd || map->buf != buf) continue; - if (take_ref) { - ret = fastrpc_map_get(map); - if (ret) { - dev_dbg(sess->dev, "%s: Failed to get map fd=%d ret=%d\n", - __func__, fd, ret); - break; - } - } - *ppmap = map; ret = 0; break; @@ -749,16 +744,14 @@ static const struct dma_buf_ops fastrpc_dma_buf_ops = { .release = fastrpc_release, }; -static int fastrpc_map_create(struct fastrpc_user *fl, int fd, +static int fastrpc_map_attach(struct fastrpc_user *fl, int fd, u64 len, u32 attr, struct fastrpc_map **ppmap) { struct fastrpc_session_ctx *sess = fl->sctx; struct fastrpc_map *map = NULL; struct sg_table *table; - int err = 0; - - if (!fastrpc_map_lookup(fl, fd, ppmap, true)) - return 0; + struct scatterlist *sgl = NULL; + int err = 0, sgl_index = 0; map = kzalloc(sizeof(*map), GFP_KERNEL); if (!map) @@ -795,7 +788,15 @@ static int fastrpc_map_create(struct fastrpc_user *fl, int fd, map->phys = sg_dma_address(map->table->sgl); map->phys += ((u64)fl->sctx->sid << 32); } - map->size = len; + for_each_sg(map->table->sgl, sgl, map->table->nents, + sgl_index) + map->size += sg_dma_len(sgl); + if (len > map->size) { + dev_dbg(sess->dev, "Bad size passed len 0x%llx map size 0x%llx\n", + len, map->size); + err = -EINVAL; + goto map_err; + } map->va = sg_virt(map->table->sgl); map->len = len; @@ -812,10 +813,10 @@ static int fastrpc_map_create(struct fastrpc_user *fl, int fd, dst_perms[1].vmid = fl->cctx->vmperms[0].vmid; dst_perms[1].perm = QCOM_SCM_PERM_RWX; map->attr = attr; - err = qcom_scm_assign_mem(map->phys, (u64)map->size, &src_perms, dst_perms, 2); + err = qcom_scm_assign_mem(map->phys, (u64)map->len, &src_perms, dst_perms, 2); if (err) { dev_err(sess->dev, "Failed to assign memory with phys 0x%llx size 0x%llx err %d\n", - map->phys, map->size, err); + map->phys, map->len, err); goto map_err; } } @@ -836,6 +837,24 @@ get_err: return err; } +static int fastrpc_map_create(struct fastrpc_user *fl, int fd, + u64 len, u32 attr, struct fastrpc_map **ppmap) +{ + struct fastrpc_session_ctx *sess = fl->sctx; + int err = 0; + + if (!fastrpc_map_lookup(fl, fd, ppmap)) { + if (!fastrpc_map_get(*ppmap)) + return 0; + dev_dbg(sess->dev, "%s: Failed to get map fd=%d\n", + __func__, fd); + } + + err = fastrpc_map_attach(fl, fd, len, attr, ppmap); + + return err; +} + /* * Fastrpc payload buffer with metadata looks like: * @@ -908,8 +927,12 @@ static int fastrpc_create_maps(struct fastrpc_invoke_ctx *ctx) ctx->args[i].length == 0) continue; - err = fastrpc_map_create(ctx->fl, ctx->args[i].fd, - ctx->args[i].length, ctx->args[i].attr, &ctx->maps[i]); + if (i < ctx->nbufs) + err = fastrpc_map_create(ctx->fl, ctx->args[i].fd, + ctx->args[i].length, ctx->args[i].attr, &ctx->maps[i]); + else + err = fastrpc_map_attach(ctx->fl, ctx->args[i].fd, + ctx->args[i].length, ctx->args[i].attr, &ctx->maps[i]); if (err) { dev_err(dev, "Error Creating map %d\n", err); return -EINVAL; @@ -1068,6 +1091,7 @@ static int fastrpc_put_args(struct fastrpc_invoke_ctx *ctx, struct fastrpc_phy_page *pages; u64 *fdlist; int i, inbufs, outbufs, handles; + int ret = 0; inbufs = REMOTE_SCALARS_INBUFS(ctx->sc); outbufs = REMOTE_SCALARS_OUTBUFS(ctx->sc); @@ -1083,23 +1107,26 @@ static int fastrpc_put_args(struct fastrpc_invoke_ctx *ctx, u64 len = rpra[i].buf.len; if (!kernel) { - if (copy_to_user((void __user *)dst, src, len)) - return -EFAULT; + if (copy_to_user((void __user *)dst, src, len)) { + ret = -EFAULT; + goto cleanup_fdlist; + } } else { memcpy(dst, src, len); } } } +cleanup_fdlist: /* Clean up fdlist which is updated by DSP */ for (i = 0; i < FASTRPC_MAX_FDLIST; i++) { if (!fdlist[i]) break; - if (!fastrpc_map_lookup(fl, (int)fdlist[i], &mmap, false)) + if (!fastrpc_map_lookup(fl, (int)fdlist[i], &mmap)) fastrpc_map_put(mmap); } - return 0; + return ret; } static int fastrpc_invoke_send(struct fastrpc_session_ctx *sctx, @@ -2031,7 +2058,7 @@ static int fastrpc_req_mem_map(struct fastrpc_user *fl, char __user *argp) args[0].length = sizeof(req_msg); pages.addr = map->phys; - pages.size = map->size; + pages.size = map->len; args[1].ptr = (u64) (uintptr_t) &pages; args[1].length = sizeof(pages); @@ -2046,7 +2073,7 @@ static int fastrpc_req_mem_map(struct fastrpc_user *fl, char __user *argp) err = fastrpc_internal_invoke(fl, true, FASTRPC_INIT_HANDLE, sc, &args[0]); if (err) { dev_err(dev, "mem mmap error, fd %d, vaddr %llx, size %lld\n", - req.fd, req.vaddrin, map->size); + req.fd, req.vaddrin, map->len); goto err_invoke; } @@ -2059,7 +2086,7 @@ static int fastrpc_req_mem_map(struct fastrpc_user *fl, char __user *argp) if (copy_to_user((void __user *)argp, &req, sizeof(req))) { /* unmap the memory and release the buffer */ req_unmap.vaddr = (uintptr_t) rsp_msg.vaddr; - req_unmap.length = map->size; + req_unmap.length = map->len; fastrpc_req_mem_unmap_impl(fl, &req_unmap); return -EFAULT; } diff --git a/drivers/misc/pci_endpoint_test.c b/drivers/misc/pci_endpoint_test.c index 1c156a3f845e..1c0fd185114f 100644 --- a/drivers/misc/pci_endpoint_test.c +++ b/drivers/misc/pci_endpoint_test.c @@ -436,7 +436,11 @@ static int pci_endpoint_test_msi_irq(struct pci_endpoint_test *test, { struct pci_dev *pdev = test->pdev; u32 val; - int ret; + int irq; + + irq = pci_irq_vector(pdev, msi_num - 1); + if (irq < 0) + return irq; pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_IRQ_TYPE, msix ? PCITEST_IRQ_TYPE_MSIX : @@ -450,11 +454,7 @@ static int pci_endpoint_test_msi_irq(struct pci_endpoint_test *test, if (!val) return -ETIMEDOUT; - ret = pci_irq_vector(pdev, msi_num - 1); - if (ret < 0) - return ret; - - if (ret != test->last_irq) + if (irq != test->last_irq) return -EIO; return 0; @@ -937,7 +937,7 @@ static long pci_endpoint_test_ioctl(struct file *file, unsigned int cmd, switch (cmd) { case PCITEST_BAR: bar = arg; - if (bar > BAR_5) + if (bar <= NO_BAR || bar > BAR_5) goto ret; if (is_am654_pci_dev(pdev) && bar == BAR_0) goto ret; @@ -1020,8 +1020,6 @@ static int pci_endpoint_test_probe(struct pci_dev *pdev, if (!test) return -ENOMEM; - test->test_reg_bar = 0; - test->alignment = 0; test->pdev = pdev; test->irq_type = PCITEST_IRQ_TYPE_UNDEFINED; diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c index d7cdea8f604d..91e7b38143ea 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c @@ -4215,7 +4215,6 @@ static pci_ers_result_t qlcnic_83xx_io_slot_reset(struct pci_dev *pdev) struct qlcnic_adapter *adapter = pci_get_drvdata(pdev); int err = 0; - pdev->error_state = pci_channel_io_normal; err = pci_enable_device(pdev); if (err) goto disconnect; diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c index 53cdd36c4123..e051d8c7a28d 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c @@ -3766,8 +3766,6 @@ static int qlcnic_attach_func(struct pci_dev *pdev) struct qlcnic_adapter *adapter = pci_get_drvdata(pdev); struct net_device *netdev = adapter->netdev; - pdev->error_state = pci_channel_io_normal; - err = pci_enable_device(pdev); if (err) return err; diff --git a/drivers/net/ethernet/sfc/efx_common.c b/drivers/net/ethernet/sfc/efx_common.c index 5a14d94163b1..e8fdbb62d872 100644 --- a/drivers/net/ethernet/sfc/efx_common.c +++ b/drivers/net/ethernet/sfc/efx_common.c @@ -1258,9 +1258,6 @@ out: /* For simplicity and reliability, we always require a slot reset and try to * reset the hardware when a pci error affecting the device is detected. - * We leave both the link_reset and mmio_enabled callback unimplemented: - * with our request for slot reset the mmio_enabled callback will never be - * called, and the link_reset callback is not used by AER or EEH mechanisms. */ const struct pci_error_handlers efx_err_handlers = { .error_detected = efx_io_error_detected, diff --git a/drivers/net/ethernet/sfc/falcon/efx.c b/drivers/net/ethernet/sfc/falcon/efx.c index d19fbf8732ff..6ea41f6c9ef5 100644 --- a/drivers/net/ethernet/sfc/falcon/efx.c +++ b/drivers/net/ethernet/sfc/falcon/efx.c @@ -3127,9 +3127,6 @@ out: /* For simplicity and reliability, we always require a slot reset and try to * reset the hardware when a pci error affecting the device is detected. - * We leave both the link_reset and mmio_enabled callback unimplemented: - * with our request for slot reset the mmio_enabled callback will never be - * called, and the link_reset callback is not used by AER or EEH mechanisms. */ static const struct pci_error_handlers ef4_err_handlers = { .error_detected = ef4_io_error_detected, diff --git a/drivers/net/ethernet/sfc/siena/efx_common.c b/drivers/net/ethernet/sfc/siena/efx_common.c index a0966f879664..35036cc902fe 100644 --- a/drivers/net/ethernet/sfc/siena/efx_common.c +++ b/drivers/net/ethernet/sfc/siena/efx_common.c @@ -1285,9 +1285,6 @@ out: /* For simplicity and reliability, we always require a slot reset and try to * reset the hardware when a pci error affecting the device is detected. - * We leave both the link_reset and mmio_enabled callback unimplemented: - * with our request for slot reset the mmio_enabled callback will never be - * called, and the link_reset callback is not used by AER or EEH mechanisms. */ const struct pci_error_handlers efx_siena_err_handlers = { .error_detected = efx_io_error_detected, diff --git a/drivers/net/hyperv/Kconfig b/drivers/net/hyperv/Kconfig index c8cbd85adcf9..982964c1a9fb 100644 --- a/drivers/net/hyperv/Kconfig +++ b/drivers/net/hyperv/Kconfig @@ -1,7 +1,7 @@ # SPDX-License-Identifier: GPL-2.0-only config HYPERV_NET tristate "Microsoft Hyper-V virtual network driver" - depends on HYPERV + depends on HYPERV_VMBUS select UCS2_STRING select NLS help diff --git a/drivers/nvdimm/badrange.c b/drivers/nvdimm/badrange.c index ee478ccde7c6..36c626db459a 100644 --- a/drivers/nvdimm/badrange.c +++ b/drivers/nvdimm/badrange.c @@ -278,8 +278,7 @@ void nvdimm_badblocks_populate(struct nd_region *nd_region, } nvdimm_bus = walk_to_nvdimm_bus(&nd_region->dev); - nvdimm_bus_lock(&nvdimm_bus->dev); + guard(nvdimm_bus)(&nvdimm_bus->dev); badblocks_populate(&nvdimm_bus->badrange, bb, range); - nvdimm_bus_unlock(&nvdimm_bus->dev); } EXPORT_SYMBOL_GPL(nvdimm_badblocks_populate); diff --git a/drivers/nvdimm/btt_devs.c b/drivers/nvdimm/btt_devs.c index 497fd434a6a1..b3279b86bbfd 100644 --- a/drivers/nvdimm/btt_devs.c +++ b/drivers/nvdimm/btt_devs.c @@ -50,14 +50,12 @@ static ssize_t sector_size_store(struct device *dev, struct nd_btt *nd_btt = to_nd_btt(dev); ssize_t rc; - device_lock(dev); - nvdimm_bus_lock(dev); + guard(device)(dev); + guard(nvdimm_bus)(dev); rc = nd_size_select_store(dev, buf, &nd_btt->lbasize, btt_lbasize_supported); dev_dbg(dev, "result: %zd wrote: %s%s", rc, buf, buf[len - 1] == '\n' ? "" : "\n"); - nvdimm_bus_unlock(dev); - device_unlock(dev); return rc ? rc : len; } @@ -93,13 +91,10 @@ static ssize_t namespace_show(struct device *dev, struct device_attribute *attr, char *buf) { struct nd_btt *nd_btt = to_nd_btt(dev); - ssize_t rc; - nvdimm_bus_lock(dev); - rc = sprintf(buf, "%s\n", nd_btt->ndns + guard(nvdimm_bus)(dev); + return sprintf(buf, "%s\n", nd_btt->ndns ? dev_name(&nd_btt->ndns->dev) : ""); - nvdimm_bus_unlock(dev); - return rc; } static ssize_t namespace_store(struct device *dev, @@ -108,13 +103,11 @@ static ssize_t namespace_store(struct device *dev, struct nd_btt *nd_btt = to_nd_btt(dev); ssize_t rc; - device_lock(dev); - nvdimm_bus_lock(dev); + guard(device)(dev); + guard(nvdimm_bus)(dev); rc = nd_namespace_store(dev, &nd_btt->ndns, buf, len); dev_dbg(dev, "result: %zd wrote: %s%s", rc, buf, buf[len - 1] == '\n' ? "" : "\n"); - nvdimm_bus_unlock(dev); - device_unlock(dev); return rc; } @@ -351,9 +344,8 @@ int nd_btt_probe(struct device *dev, struct nd_namespace_common *ndns) return -ENODEV; } - nvdimm_bus_lock(&ndns->dev); - btt_dev = __nd_btt_create(nd_region, 0, NULL, ndns); - nvdimm_bus_unlock(&ndns->dev); + scoped_guard(nvdimm_bus, &ndns->dev) + btt_dev = __nd_btt_create(nd_region, 0, NULL, ndns); if (!btt_dev) return -ENOMEM; btt_sb = devm_kzalloc(dev, sizeof(*btt_sb), GFP_KERNEL); diff --git a/drivers/nvdimm/bus.c b/drivers/nvdimm/bus.c index 0ccf4a9e523a..87178a53ff9c 100644 --- a/drivers/nvdimm/bus.c +++ b/drivers/nvdimm/bus.c @@ -5,7 +5,7 @@ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt #include <linux/libnvdimm.h> #include <linux/sched/mm.h> -#include <linux/vmalloc.h> +#include <linux/slab.h> #include <linux/uaccess.h> #include <linux/module.h> #include <linux/blkdev.h> @@ -13,7 +13,6 @@ #include <linux/async.h> #include <linux/ndctl.h> #include <linux/sched.h> -#include <linux/slab.h> #include <linux/cpu.h> #include <linux/fs.h> #include <linux/io.h> @@ -64,17 +63,15 @@ static struct module *to_bus_provider(struct device *dev) static void nvdimm_bus_probe_start(struct nvdimm_bus *nvdimm_bus) { - nvdimm_bus_lock(&nvdimm_bus->dev); + guard(nvdimm_bus)(&nvdimm_bus->dev); nvdimm_bus->probe_active++; - nvdimm_bus_unlock(&nvdimm_bus->dev); } static void nvdimm_bus_probe_end(struct nvdimm_bus *nvdimm_bus) { - nvdimm_bus_lock(&nvdimm_bus->dev); + guard(nvdimm_bus)(&nvdimm_bus->dev); if (--nvdimm_bus->probe_active == 0) wake_up(&nvdimm_bus->wait); - nvdimm_bus_unlock(&nvdimm_bus->dev); } static int nvdimm_bus_probe(struct device *dev) @@ -1031,14 +1028,12 @@ static int __nd_ioctl(struct nvdimm_bus *nvdimm_bus, struct nvdimm *nvdimm, unsigned int cmd = _IOC_NR(ioctl_cmd); struct device *dev = &nvdimm_bus->dev; void __user *p = (void __user *) arg; - char *out_env = NULL, *in_env = NULL; const char *cmd_name, *dimm_name; u32 in_len = 0, out_len = 0; unsigned int func = cmd; unsigned long cmd_mask; struct nd_cmd_pkg pkg; int rc, i, cmd_rc; - void *buf = NULL; u64 buf_len = 0; if (nvdimm) { @@ -1097,7 +1092,7 @@ static int __nd_ioctl(struct nvdimm_bus *nvdimm_bus, struct nvdimm *nvdimm, } /* process an input envelope */ - in_env = kzalloc(ND_CMD_MAX_ENVELOPE, GFP_KERNEL); + char *in_env __free(kfree) = kzalloc(ND_CMD_MAX_ENVELOPE, GFP_KERNEL); if (!in_env) return -ENOMEM; for (i = 0; i < desc->in_num; i++) { @@ -1107,17 +1102,14 @@ static int __nd_ioctl(struct nvdimm_bus *nvdimm_bus, struct nvdimm *nvdimm, if (in_size == UINT_MAX) { dev_err(dev, "%s:%s unknown input size cmd: %s field: %d\n", __func__, dimm_name, cmd_name, i); - rc = -ENXIO; - goto out; + return -ENXIO; } if (in_len < ND_CMD_MAX_ENVELOPE) copy = min_t(u32, ND_CMD_MAX_ENVELOPE - in_len, in_size); else copy = 0; - if (copy && copy_from_user(&in_env[in_len], p + in_len, copy)) { - rc = -EFAULT; - goto out; - } + if (copy && copy_from_user(&in_env[in_len], p + in_len, copy)) + return -EFAULT; in_len += in_size; } @@ -1129,11 +1121,9 @@ static int __nd_ioctl(struct nvdimm_bus *nvdimm_bus, struct nvdimm *nvdimm, } /* process an output envelope */ - out_env = kzalloc(ND_CMD_MAX_ENVELOPE, GFP_KERNEL); - if (!out_env) { - rc = -ENOMEM; - goto out; - } + char *out_env __free(kfree) = kzalloc(ND_CMD_MAX_ENVELOPE, GFP_KERNEL); + if (!out_env) + return -ENOMEM; for (i = 0; i < desc->out_num; i++) { u32 out_size = nd_cmd_out_size(nvdimm, cmd, desc, i, @@ -1143,8 +1133,7 @@ static int __nd_ioctl(struct nvdimm_bus *nvdimm_bus, struct nvdimm *nvdimm, if (out_size == UINT_MAX) { dev_dbg(dev, "%s unknown output size cmd: %s field: %d\n", dimm_name, cmd_name, i); - rc = -EFAULT; - goto out; + return -EFAULT; } if (out_len < ND_CMD_MAX_ENVELOPE) copy = min_t(u32, ND_CMD_MAX_ENVELOPE - out_len, out_size); @@ -1152,8 +1141,7 @@ static int __nd_ioctl(struct nvdimm_bus *nvdimm_bus, struct nvdimm *nvdimm, copy = 0; if (copy && copy_from_user(&out_env[out_len], p + in_len + out_len, copy)) { - rc = -EFAULT; - goto out; + return -EFAULT; } out_len += out_size; } @@ -1162,30 +1150,25 @@ static int __nd_ioctl(struct nvdimm_bus *nvdimm_bus, struct nvdimm *nvdimm, if (buf_len > ND_IOCTL_MAX_BUFLEN) { dev_dbg(dev, "%s cmd: %s buf_len: %llu > %d\n", dimm_name, cmd_name, buf_len, ND_IOCTL_MAX_BUFLEN); - rc = -EINVAL; - goto out; + return -EINVAL; } - buf = vmalloc(buf_len); - if (!buf) { - rc = -ENOMEM; - goto out; - } + void *buf __free(kvfree) = kvzalloc(buf_len, GFP_KERNEL); + if (!buf) + return -ENOMEM; - if (copy_from_user(buf, p, buf_len)) { - rc = -EFAULT; - goto out; - } + if (copy_from_user(buf, p, buf_len)) + return -EFAULT; - device_lock(dev); - nvdimm_bus_lock(dev); + guard(device)(dev); + guard(nvdimm_bus)(dev); rc = nd_cmd_clear_to_send(nvdimm_bus, nvdimm, func, buf); if (rc) - goto out_unlock; + return rc; rc = nd_desc->ndctl(nd_desc, nvdimm, cmd, buf, buf_len, &cmd_rc); if (rc < 0) - goto out_unlock; + return rc; if (!nvdimm && cmd == ND_CMD_CLEAR_ERROR && cmd_rc >= 0) { struct nd_cmd_clear_error *clear_err = buf; @@ -1195,16 +1178,9 @@ static int __nd_ioctl(struct nvdimm_bus *nvdimm_bus, struct nvdimm *nvdimm, } if (copy_to_user(p, buf, buf_len)) - rc = -EFAULT; + return -EFAULT; -out_unlock: - nvdimm_bus_unlock(dev); - device_unlock(dev); -out: - kfree(in_env); - kfree(out_env); - vfree(buf); - return rc; + return 0; } enum nd_ioctl_mode { diff --git a/drivers/nvdimm/claim.c b/drivers/nvdimm/claim.c index 51614651d2e7..309cd2cddb0e 100644 --- a/drivers/nvdimm/claim.c +++ b/drivers/nvdimm/claim.c @@ -34,11 +34,10 @@ void nd_detach_ndns(struct device *dev, if (!ndns) return; - get_device(&ndns->dev); - nvdimm_bus_lock(&ndns->dev); + + struct device *ndev __free(put_device) = get_device(&ndns->dev); + guard(nvdimm_bus)(ndev); __nd_detach_ndns(dev, _ndns); - nvdimm_bus_unlock(&ndns->dev); - put_device(&ndns->dev); } bool __nd_attach_ndns(struct device *dev, struct nd_namespace_common *attach, diff --git a/drivers/nvdimm/core.c b/drivers/nvdimm/core.c index eaa796629c27..5ba204113fe1 100644 --- a/drivers/nvdimm/core.c +++ b/drivers/nvdimm/core.c @@ -141,9 +141,8 @@ static void nvdimm_map_put(void *data) struct nvdimm_map *nvdimm_map = data; struct nvdimm_bus *nvdimm_bus = nvdimm_map->nvdimm_bus; - nvdimm_bus_lock(&nvdimm_bus->dev); + guard(nvdimm_bus)(&nvdimm_bus->dev); kref_put(&nvdimm_map->kref, nvdimm_map_release); - nvdimm_bus_unlock(&nvdimm_bus->dev); } /** @@ -158,13 +157,13 @@ void *devm_nvdimm_memremap(struct device *dev, resource_size_t offset, { struct nvdimm_map *nvdimm_map; - nvdimm_bus_lock(dev); - nvdimm_map = find_nvdimm_map(dev, offset); - if (!nvdimm_map) - nvdimm_map = alloc_nvdimm_map(dev, offset, size, flags); - else - kref_get(&nvdimm_map->kref); - nvdimm_bus_unlock(dev); + scoped_guard(nvdimm_bus, dev) { + nvdimm_map = find_nvdimm_map(dev, offset); + if (!nvdimm_map) + nvdimm_map = alloc_nvdimm_map(dev, offset, size, flags); + else + kref_get(&nvdimm_map->kref); + } if (!nvdimm_map) return NULL; diff --git a/drivers/nvdimm/dax_devs.c b/drivers/nvdimm/dax_devs.c index 37b743acbb7b..ba4c409ede65 100644 --- a/drivers/nvdimm/dax_devs.c +++ b/drivers/nvdimm/dax_devs.c @@ -104,12 +104,12 @@ int nd_dax_probe(struct device *dev, struct nd_namespace_common *ndns) return -ENODEV; } - nvdimm_bus_lock(&ndns->dev); - nd_dax = nd_dax_alloc(nd_region); - dax_dev = nd_dax_devinit(nd_dax, ndns); - nvdimm_bus_unlock(&ndns->dev); - if (!dax_dev) - return -ENOMEM; + scoped_guard(nvdimm_bus, &ndns->dev) { + nd_dax = nd_dax_alloc(nd_region); + dax_dev = nd_dax_devinit(nd_dax, ndns); + if (!dax_dev) + return -ENOMEM; + } pfn_sb = devm_kmalloc(dev, sizeof(*pfn_sb), GFP_KERNEL); nd_pfn = &nd_dax->nd_pfn; nd_pfn->pfn_sb = pfn_sb; diff --git a/drivers/nvdimm/dimm.c b/drivers/nvdimm/dimm.c index 91d9163ee303..2f6c26cc6a3e 100644 --- a/drivers/nvdimm/dimm.c +++ b/drivers/nvdimm/dimm.c @@ -117,9 +117,8 @@ static void nvdimm_remove(struct device *dev) { struct nvdimm_drvdata *ndd = dev_get_drvdata(dev); - nvdimm_bus_lock(dev); - dev_set_drvdata(dev, NULL); - nvdimm_bus_unlock(dev); + scoped_guard(nvdimm_bus, dev) + dev_set_drvdata(dev, NULL); put_ndd(ndd); } diff --git a/drivers/nvdimm/dimm_devs.c b/drivers/nvdimm/dimm_devs.c index 21498d461fde..e1349ef5f8fd 100644 --- a/drivers/nvdimm/dimm_devs.c +++ b/drivers/nvdimm/dimm_devs.c @@ -226,10 +226,10 @@ void nvdimm_drvdata_release(struct kref *kref) struct resource *res, *_r; dev_dbg(dev, "trace\n"); - nvdimm_bus_lock(dev); - for_each_dpa_resource_safe(ndd, res, _r) - nvdimm_free_dpa(ndd, res); - nvdimm_bus_unlock(dev); + scoped_guard(nvdimm_bus, dev) { + for_each_dpa_resource_safe(ndd, res, _r) + nvdimm_free_dpa(ndd, res); + } kvfree(ndd->data); kfree(ndd); @@ -319,23 +319,20 @@ static DEVICE_ATTR_RO(state); static ssize_t __available_slots_show(struct nvdimm_drvdata *ndd, char *buf) { struct device *dev; - ssize_t rc; u32 nfree; if (!ndd) return -ENXIO; dev = ndd->dev; - nvdimm_bus_lock(dev); + guard(nvdimm_bus)(dev); nfree = nd_label_nfree(ndd); if (nfree - 1 > nfree) { dev_WARN_ONCE(dev, 1, "we ate our last label?\n"); nfree = 0; } else nfree--; - rc = sprintf(buf, "%d\n", nfree); - nvdimm_bus_unlock(dev); - return rc; + return sprintf(buf, "%d\n", nfree); } static ssize_t available_slots_show(struct device *dev, @@ -388,21 +385,15 @@ static ssize_t security_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t len) { - ssize_t rc; - /* * Require all userspace triggered security management to be * done while probing is idle and the DIMM is not in active use * in any region. */ - device_lock(dev); - nvdimm_bus_lock(dev); + guard(device)(dev); + guard(nvdimm_bus)(dev); wait_nvdimm_bus_probe_idle(dev); - rc = nvdimm_security_store(dev, buf, len); - nvdimm_bus_unlock(dev); - device_unlock(dev); - - return rc; + return nvdimm_security_store(dev, buf, len); } static DEVICE_ATTR_RW(security); @@ -454,9 +445,8 @@ static ssize_t result_show(struct device *dev, struct device_attribute *attr, ch if (!nvdimm->fw_ops) return -EOPNOTSUPP; - nvdimm_bus_lock(dev); + guard(nvdimm_bus)(dev); result = nvdimm->fw_ops->activate_result(nvdimm); - nvdimm_bus_unlock(dev); switch (result) { case NVDIMM_FWA_RESULT_NONE: @@ -483,9 +473,8 @@ static ssize_t activate_show(struct device *dev, struct device_attribute *attr, if (!nvdimm->fw_ops) return -EOPNOTSUPP; - nvdimm_bus_lock(dev); + guard(nvdimm_bus)(dev); state = nvdimm->fw_ops->activate_state(nvdimm); - nvdimm_bus_unlock(dev); switch (state) { case NVDIMM_FWA_IDLE: @@ -516,9 +505,8 @@ static ssize_t activate_store(struct device *dev, struct device_attribute *attr, else return -EINVAL; - nvdimm_bus_lock(dev); + guard(nvdimm_bus)(dev); rc = nvdimm->fw_ops->arm(nvdimm, arg); - nvdimm_bus_unlock(dev); if (rc < 0) return rc; @@ -545,9 +533,8 @@ static umode_t nvdimm_firmware_visible(struct kobject *kobj, struct attribute *a if (!nvdimm->fw_ops) return 0; - nvdimm_bus_lock(dev); + guard(nvdimm_bus)(dev); cap = nd_desc->fw_ops->capability(nd_desc); - nvdimm_bus_unlock(dev); if (cap < NVDIMM_FWA_CAP_QUIESCE) return 0; @@ -641,11 +628,10 @@ void nvdimm_delete(struct nvdimm *nvdimm) bool dev_put = false; /* We are shutting down. Make state frozen artificially. */ - nvdimm_bus_lock(dev); - set_bit(NVDIMM_SECURITY_FROZEN, &nvdimm->sec.flags); - if (test_and_clear_bit(NDD_WORK_PENDING, &nvdimm->flags)) - dev_put = true; - nvdimm_bus_unlock(dev); + scoped_guard(nvdimm_bus, dev) { + set_bit(NVDIMM_SECURITY_FROZEN, &nvdimm->sec.flags); + dev_put = test_and_clear_bit(NDD_WORK_PENDING, &nvdimm->flags); + } cancel_delayed_work_sync(&nvdimm->dwork); if (dev_put) put_device(dev); diff --git a/drivers/nvdimm/namespace_devs.c b/drivers/nvdimm/namespace_devs.c index 55cfbf1e0a95..a5edcacfe46d 100644 --- a/drivers/nvdimm/namespace_devs.c +++ b/drivers/nvdimm/namespace_devs.c @@ -264,15 +264,13 @@ static ssize_t alt_name_store(struct device *dev, struct nd_region *nd_region = to_nd_region(dev->parent); ssize_t rc; - device_lock(dev); - nvdimm_bus_lock(dev); + guard(device)(dev); + guard(nvdimm_bus)(dev); wait_nvdimm_bus_probe_idle(dev); rc = __alt_name_store(dev, buf, len); if (rc >= 0) rc = nd_namespace_label_update(nd_region, dev); dev_dbg(dev, "%s(%zd)\n", rc < 0 ? "fail " : "", rc); - nvdimm_bus_unlock(dev); - device_unlock(dev); return rc < 0 ? rc : len; } @@ -849,8 +847,8 @@ static ssize_t size_store(struct device *dev, if (rc) return rc; - device_lock(dev); - nvdimm_bus_lock(dev); + guard(device)(dev); + guard(nvdimm_bus)(dev); wait_nvdimm_bus_probe_idle(dev); rc = __size_store(dev, val); if (rc >= 0) @@ -866,9 +864,6 @@ static ssize_t size_store(struct device *dev, dev_dbg(dev, "%llx %s (%d)\n", val, rc < 0 ? "fail" : "success", rc); - nvdimm_bus_unlock(dev); - device_unlock(dev); - return rc < 0 ? rc : len; } @@ -891,13 +886,8 @@ resource_size_t __nvdimm_namespace_capacity(struct nd_namespace_common *ndns) resource_size_t nvdimm_namespace_capacity(struct nd_namespace_common *ndns) { - resource_size_t size; - - nvdimm_bus_lock(&ndns->dev); - size = __nvdimm_namespace_capacity(ndns); - nvdimm_bus_unlock(&ndns->dev); - - return size; + guard(nvdimm_bus)(&ndns->dev); + return __nvdimm_namespace_capacity(ndns); } EXPORT_SYMBOL(nvdimm_namespace_capacity); @@ -1044,8 +1034,8 @@ static ssize_t uuid_store(struct device *dev, } else return -ENXIO; - device_lock(dev); - nvdimm_bus_lock(dev); + guard(device)(dev); + guard(nvdimm_bus)(dev); wait_nvdimm_bus_probe_idle(dev); if (to_ndns(dev)->claim) rc = -EBUSY; @@ -1059,8 +1049,6 @@ static ssize_t uuid_store(struct device *dev, kfree(uuid); dev_dbg(dev, "result: %zd wrote: %s%s", rc, buf, buf[len - 1] == '\n' ? "" : "\n"); - nvdimm_bus_unlock(dev); - device_unlock(dev); return rc < 0 ? rc : len; } @@ -1119,20 +1107,30 @@ static ssize_t sector_size_store(struct device *dev, } else return -ENXIO; - device_lock(dev); - nvdimm_bus_lock(dev); - if (to_ndns(dev)->claim) - rc = -EBUSY; - if (rc >= 0) - rc = nd_size_select_store(dev, buf, lbasize, supported); - if (rc >= 0) - rc = nd_namespace_label_update(nd_region, dev); - dev_dbg(dev, "result: %zd %s: %s%s", rc, rc < 0 ? "tried" : "wrote", + guard(device)(dev); + guard(nvdimm_bus)(dev); + if (to_ndns(dev)->claim) { + dev_dbg(dev, "namespace %s already claimed\n", dev_name(dev)); + return -EBUSY; + } + + rc = nd_size_select_store(dev, buf, lbasize, supported); + if (rc < 0) { + dev_dbg(dev, "size select fail: %zd tried: %s%s", rc, buf, buf[len - 1] == '\n' ? "" : "\n"); - nvdimm_bus_unlock(dev); - device_unlock(dev); + return rc; + } + + rc = nd_namespace_label_update(nd_region, dev); + if (rc < 0) { + dev_dbg(dev, "label update fail: %zd tried: %s%s", + rc, buf, buf[len - 1] == '\n' ? "" : "\n"); + return rc; + } + + dev_dbg(dev, "wrote: %s%s", buf, buf[len - 1] == '\n' ? "" : "\n"); - return rc ? rc : len; + return len; } static DEVICE_ATTR_RW(sector_size); @@ -1145,7 +1143,7 @@ static ssize_t dpa_extents_show(struct device *dev, int count = 0, i; u32 flags = 0; - nvdimm_bus_lock(dev); + guard(nvdimm_bus)(dev); if (is_namespace_pmem(dev)) { struct nd_namespace_pmem *nspm = to_nd_namespace_pmem(dev); @@ -1154,7 +1152,7 @@ static ssize_t dpa_extents_show(struct device *dev, } if (!uuid) - goto out; + return sprintf(buf, "%d\n", count); nd_label_gen_id(&label_id, uuid, flags); for (i = 0; i < nd_region->ndr_mappings; i++) { @@ -1166,8 +1164,6 @@ static ssize_t dpa_extents_show(struct device *dev, if (strcmp(res->name, label_id.id) == 0) count++; } - out: - nvdimm_bus_unlock(dev); return sprintf(buf, "%d\n", count); } @@ -1279,15 +1275,13 @@ static ssize_t holder_class_store(struct device *dev, struct nd_region *nd_region = to_nd_region(dev->parent); int rc; - device_lock(dev); - nvdimm_bus_lock(dev); + guard(device)(dev); + guard(nvdimm_bus)(dev); wait_nvdimm_bus_probe_idle(dev); rc = __holder_class_store(dev, buf); if (rc >= 0) rc = nd_namespace_label_update(nd_region, dev); dev_dbg(dev, "%s(%d)\n", rc < 0 ? "fail " : "", rc); - nvdimm_bus_unlock(dev); - device_unlock(dev); return rc < 0 ? rc : len; } @@ -1983,7 +1977,7 @@ static struct device **scan_labels(struct nd_region *nd_region) } dev_dbg(&nd_region->dev, "discovered %d namespace%s\n", count, - count == 1 ? "" : "s"); + str_plural(count)); if (count == 0) { struct nd_namespace_pmem *nspm; @@ -2152,31 +2146,38 @@ out: nd_region); } -int nd_region_register_namespaces(struct nd_region *nd_region, int *err) +static int create_relevant_namespaces(struct nd_region *nd_region, int *type, + struct device ***devs) { - struct device **devs = NULL; - int i, rc = 0, type; + int rc; - *err = 0; - nvdimm_bus_lock(&nd_region->dev); + guard(nvdimm_bus)(&nd_region->dev); rc = init_active_labels(nd_region); - if (rc) { - nvdimm_bus_unlock(&nd_region->dev); + if (rc) return rc; - } - type = nd_region_to_nstype(nd_region); - switch (type) { + *type = nd_region_to_nstype(nd_region); + switch (*type) { case ND_DEVICE_NAMESPACE_IO: - devs = create_namespace_io(nd_region); + *devs = create_namespace_io(nd_region); break; case ND_DEVICE_NAMESPACE_PMEM: - devs = create_namespaces(nd_region); - break; - default: + *devs = create_namespaces(nd_region); break; } - nvdimm_bus_unlock(&nd_region->dev); + + return 0; +} + +int nd_region_register_namespaces(struct nd_region *nd_region, int *err) +{ + struct device **devs = NULL; + int i, rc = 0, type; + + *err = 0; + rc = create_relevant_namespaces(nd_region, &type, &devs); + if (rc) + return rc; if (!devs) return -ENODEV; diff --git a/drivers/nvdimm/nd.h b/drivers/nvdimm/nd.h index cc5c8f3f81e8..b199eea3260e 100644 --- a/drivers/nvdimm/nd.h +++ b/drivers/nvdimm/nd.h @@ -632,6 +632,9 @@ u64 nd_region_interleave_set_cookie(struct nd_region *nd_region, u64 nd_region_interleave_set_altcookie(struct nd_region *nd_region); void nvdimm_bus_lock(struct device *dev); void nvdimm_bus_unlock(struct device *dev); +DEFINE_GUARD(nvdimm_bus, struct device *, + if (_T) nvdimm_bus_lock(_T), if (_T) nvdimm_bus_unlock(_T)); + bool is_nvdimm_bus_locked(struct device *dev); void nvdimm_check_and_set_ro(struct gendisk *disk); void nvdimm_drvdata_release(struct kref *kref); diff --git a/drivers/nvdimm/pfn_devs.c b/drivers/nvdimm/pfn_devs.c index 8f3e816e805d..42b172fc5576 100644 --- a/drivers/nvdimm/pfn_devs.c +++ b/drivers/nvdimm/pfn_devs.c @@ -56,30 +56,26 @@ static ssize_t mode_store(struct device *dev, { struct nd_pfn *nd_pfn = to_nd_pfn_safe(dev); ssize_t rc = 0; + size_t n = len - 1; - device_lock(dev); - nvdimm_bus_lock(dev); + guard(device)(dev); + guard(nvdimm_bus)(dev); if (dev->driver) - rc = -EBUSY; - else { - size_t n = len - 1; - - if (strncmp(buf, "pmem\n", n) == 0 - || strncmp(buf, "pmem", n) == 0) { - nd_pfn->mode = PFN_MODE_PMEM; - } else if (strncmp(buf, "ram\n", n) == 0 - || strncmp(buf, "ram", n) == 0) - nd_pfn->mode = PFN_MODE_RAM; - else if (strncmp(buf, "none\n", n) == 0 - || strncmp(buf, "none", n) == 0) - nd_pfn->mode = PFN_MODE_NONE; - else - rc = -EINVAL; - } + return -EBUSY; + + if (strncmp(buf, "pmem\n", n) == 0 + || strncmp(buf, "pmem", n) == 0) { + nd_pfn->mode = PFN_MODE_PMEM; + } else if (strncmp(buf, "ram\n", n) == 0 + || strncmp(buf, "ram", n) == 0) + nd_pfn->mode = PFN_MODE_RAM; + else if (strncmp(buf, "none\n", n) == 0 + || strncmp(buf, "none", n) == 0) + nd_pfn->mode = PFN_MODE_NONE; + else + rc = -EINVAL; dev_dbg(dev, "result: %zd wrote: %s%s", rc, buf, buf[len - 1] == '\n' ? "" : "\n"); - nvdimm_bus_unlock(dev); - device_unlock(dev); return rc ? rc : len; } @@ -125,14 +121,12 @@ static ssize_t align_store(struct device *dev, unsigned long aligns[MAX_NVDIMM_ALIGN] = { [0] = 0, }; ssize_t rc; - device_lock(dev); - nvdimm_bus_lock(dev); + guard(device)(dev); + guard(nvdimm_bus)(dev); rc = nd_size_select_store(dev, buf, &nd_pfn->align, nd_pfn_supported_alignments(aligns)); dev_dbg(dev, "result: %zd wrote: %s%s", rc, buf, buf[len - 1] == '\n' ? "" : "\n"); - nvdimm_bus_unlock(dev); - device_unlock(dev); return rc ? rc : len; } @@ -168,13 +162,10 @@ static ssize_t namespace_show(struct device *dev, struct device_attribute *attr, char *buf) { struct nd_pfn *nd_pfn = to_nd_pfn_safe(dev); - ssize_t rc; - nvdimm_bus_lock(dev); - rc = sprintf(buf, "%s\n", nd_pfn->ndns + guard(nvdimm_bus)(dev); + return sprintf(buf, "%s\n", nd_pfn->ndns ? dev_name(&nd_pfn->ndns->dev) : ""); - nvdimm_bus_unlock(dev); - return rc; } static ssize_t namespace_store(struct device *dev, @@ -183,13 +174,11 @@ static ssize_t namespace_store(struct device *dev, struct nd_pfn *nd_pfn = to_nd_pfn_safe(dev); ssize_t rc; - device_lock(dev); - nvdimm_bus_lock(dev); + guard(device)(dev); + guard(nvdimm_bus)(dev); rc = nd_namespace_store(dev, &nd_pfn->ndns, buf, len); dev_dbg(dev, "result: %zd wrote: %s%s", rc, buf, buf[len - 1] == '\n' ? "" : "\n"); - nvdimm_bus_unlock(dev); - device_unlock(dev); return rc; } @@ -639,10 +628,10 @@ int nd_pfn_probe(struct device *dev, struct nd_namespace_common *ndns) return -ENODEV; } - nvdimm_bus_lock(&ndns->dev); - nd_pfn = nd_pfn_alloc(nd_region); - pfn_dev = nd_pfn_devinit(nd_pfn, ndns); - nvdimm_bus_unlock(&ndns->dev); + scoped_guard(nvdimm_bus, &ndns->dev) { + nd_pfn = nd_pfn_alloc(nd_region); + pfn_dev = nd_pfn_devinit(nd_pfn, ndns); + } if (!pfn_dev) return -ENOMEM; pfn_sb = devm_kmalloc(dev, sizeof(*pfn_sb), GFP_KERNEL); diff --git a/drivers/nvdimm/region.c b/drivers/nvdimm/region.c index 88dc062af5f8..cd9b52040d7b 100644 --- a/drivers/nvdimm/region.c +++ b/drivers/nvdimm/region.c @@ -70,7 +70,7 @@ static int nd_region_probe(struct device *dev) * "<async-registered>/<total>" namespace count. */ dev_err(dev, "failed to register %d namespace%s, continuing...\n", - err, err == 1 ? "" : "s"); + err, str_plural(err)); return 0; } @@ -87,13 +87,13 @@ static void nd_region_remove(struct device *dev) device_for_each_child(dev, NULL, child_unregister); /* flush attribute readers and disable */ - nvdimm_bus_lock(dev); - nd_region->ns_seed = NULL; - nd_region->btt_seed = NULL; - nd_region->pfn_seed = NULL; - nd_region->dax_seed = NULL; - dev_set_drvdata(dev, NULL); - nvdimm_bus_unlock(dev); + scoped_guard(nvdimm_bus, dev) { + nd_region->ns_seed = NULL; + nd_region->btt_seed = NULL; + nd_region->pfn_seed = NULL; + nd_region->dax_seed = NULL; + dev_set_drvdata(dev, NULL); + } /* * Note, this assumes device_lock() context to not race diff --git a/drivers/nvdimm/region_devs.c b/drivers/nvdimm/region_devs.c index de1ee5ebc851..a5ceaf5db595 100644 --- a/drivers/nvdimm/region_devs.c +++ b/drivers/nvdimm/region_devs.c @@ -102,31 +102,44 @@ out: return 0; } -int nd_region_activate(struct nd_region *nd_region) +static int get_flush_data(struct nd_region *nd_region, size_t *size, int *num_flush) { - int i, j, rc, num_flush = 0; - struct nd_region_data *ndrd; - struct device *dev = &nd_region->dev; size_t flush_data_size = sizeof(void *); + int _num_flush = 0; + int i; - nvdimm_bus_lock(&nd_region->dev); + guard(nvdimm_bus)(&nd_region->dev); for (i = 0; i < nd_region->ndr_mappings; i++) { struct nd_mapping *nd_mapping = &nd_region->mapping[i]; struct nvdimm *nvdimm = nd_mapping->nvdimm; - if (test_bit(NDD_SECURITY_OVERWRITE, &nvdimm->flags)) { - nvdimm_bus_unlock(&nd_region->dev); + if (test_bit(NDD_SECURITY_OVERWRITE, &nvdimm->flags)) return -EBUSY; - } /* at least one null hint slot per-dimm for the "no-hint" case */ flush_data_size += sizeof(void *); - num_flush = min_not_zero(num_flush, nvdimm->num_flush); + _num_flush = min_not_zero(_num_flush, nvdimm->num_flush); if (!nvdimm->num_flush) continue; flush_data_size += nvdimm->num_flush * sizeof(void *); } - nvdimm_bus_unlock(&nd_region->dev); + + *size = flush_data_size; + *num_flush = _num_flush; + + return 0; +} + +int nd_region_activate(struct nd_region *nd_region) +{ + int i, j, rc, num_flush; + struct nd_region_data *ndrd; + struct device *dev = &nd_region->dev; + size_t flush_data_size; + + rc = get_flush_data(nd_region, &flush_data_size, &num_flush); + if (rc) + return rc; rc = nd_region_invalidate_memregion(nd_region); if (rc) @@ -327,8 +340,8 @@ static ssize_t set_cookie_show(struct device *dev, * the v1.1 namespace label cookie definition. To read all this * data we need to wait for probing to settle. */ - device_lock(dev); - nvdimm_bus_lock(dev); + guard(device)(dev); + guard(nvdimm_bus)(dev); wait_nvdimm_bus_probe_idle(dev); if (nd_region->ndr_mappings) { struct nd_mapping *nd_mapping = &nd_region->mapping[0]; @@ -343,8 +356,6 @@ static ssize_t set_cookie_show(struct device *dev, nsindex)); } } - nvdimm_bus_unlock(dev); - device_unlock(dev); if (rc) return rc; @@ -393,7 +404,6 @@ static ssize_t available_size_show(struct device *dev, struct device_attribute *attr, char *buf) { struct nd_region *nd_region = to_nd_region(dev); - unsigned long long available = 0; /* * Flush in-flight updates and grab a snapshot of the available @@ -401,14 +411,11 @@ static ssize_t available_size_show(struct device *dev, * memory nvdimm_bus_lock() is dropped, but that's userspace's * problem to not race itself. */ - device_lock(dev); - nvdimm_bus_lock(dev); + guard(device)(dev); + guard(nvdimm_bus)(dev); wait_nvdimm_bus_probe_idle(dev); - available = nd_region_available_dpa(nd_region); - nvdimm_bus_unlock(dev); - device_unlock(dev); - return sprintf(buf, "%llu\n", available); + return sprintf(buf, "%llu\n", nd_region_available_dpa(nd_region)); } static DEVICE_ATTR_RO(available_size); @@ -416,16 +423,12 @@ static ssize_t max_available_extent_show(struct device *dev, struct device_attribute *attr, char *buf) { struct nd_region *nd_region = to_nd_region(dev); - unsigned long long available = 0; - device_lock(dev); - nvdimm_bus_lock(dev); + guard(device)(dev); + guard(nvdimm_bus)(dev); wait_nvdimm_bus_probe_idle(dev); - available = nd_region_allocatable_dpa(nd_region); - nvdimm_bus_unlock(dev); - device_unlock(dev); - return sprintf(buf, "%llu\n", available); + return sprintf(buf, "%llu\n", nd_region_allocatable_dpa(nd_region)); } static DEVICE_ATTR_RO(max_available_extent); @@ -433,16 +436,12 @@ static ssize_t init_namespaces_show(struct device *dev, struct device_attribute *attr, char *buf) { struct nd_region_data *ndrd = dev_get_drvdata(dev); - ssize_t rc; - nvdimm_bus_lock(dev); - if (ndrd) - rc = sprintf(buf, "%d/%d\n", ndrd->ns_active, ndrd->ns_count); - else - rc = -ENXIO; - nvdimm_bus_unlock(dev); + guard(nvdimm_bus)(dev); + if (!ndrd) + return -ENXIO; - return rc; + return sprintf(buf, "%d/%d\n", ndrd->ns_active, ndrd->ns_count); } static DEVICE_ATTR_RO(init_namespaces); @@ -450,15 +449,12 @@ static ssize_t namespace_seed_show(struct device *dev, struct device_attribute *attr, char *buf) { struct nd_region *nd_region = to_nd_region(dev); - ssize_t rc; - nvdimm_bus_lock(dev); + guard(nvdimm_bus)(dev); if (nd_region->ns_seed) - rc = sprintf(buf, "%s\n", dev_name(nd_region->ns_seed)); - else - rc = sprintf(buf, "\n"); - nvdimm_bus_unlock(dev); - return rc; + return sprintf(buf, "%s\n", dev_name(nd_region->ns_seed)); + + return sprintf(buf, "\n"); } static DEVICE_ATTR_RO(namespace_seed); @@ -466,16 +462,12 @@ static ssize_t btt_seed_show(struct device *dev, struct device_attribute *attr, char *buf) { struct nd_region *nd_region = to_nd_region(dev); - ssize_t rc; - nvdimm_bus_lock(dev); + guard(nvdimm_bus)(dev); if (nd_region->btt_seed) - rc = sprintf(buf, "%s\n", dev_name(nd_region->btt_seed)); - else - rc = sprintf(buf, "\n"); - nvdimm_bus_unlock(dev); + return sprintf(buf, "%s\n", dev_name(nd_region->btt_seed)); - return rc; + return sprintf(buf, "\n"); } static DEVICE_ATTR_RO(btt_seed); @@ -483,16 +475,12 @@ static ssize_t pfn_seed_show(struct device *dev, struct device_attribute *attr, char *buf) { struct nd_region *nd_region = to_nd_region(dev); - ssize_t rc; - nvdimm_bus_lock(dev); + guard(nvdimm_bus)(dev); if (nd_region->pfn_seed) - rc = sprintf(buf, "%s\n", dev_name(nd_region->pfn_seed)); - else - rc = sprintf(buf, "\n"); - nvdimm_bus_unlock(dev); + return sprintf(buf, "%s\n", dev_name(nd_region->pfn_seed)); - return rc; + return sprintf(buf, "\n"); } static DEVICE_ATTR_RO(pfn_seed); @@ -500,16 +488,12 @@ static ssize_t dax_seed_show(struct device *dev, struct device_attribute *attr, char *buf) { struct nd_region *nd_region = to_nd_region(dev); - ssize_t rc; - nvdimm_bus_lock(dev); + guard(nvdimm_bus)(dev); if (nd_region->dax_seed) - rc = sprintf(buf, "%s\n", dev_name(nd_region->dax_seed)); - else - rc = sprintf(buf, "\n"); - nvdimm_bus_unlock(dev); + return sprintf(buf, "%s\n", dev_name(nd_region->dax_seed)); - return rc; + return sprintf(buf, "\n"); } static DEVICE_ATTR_RO(dax_seed); @@ -581,9 +565,8 @@ static ssize_t align_store(struct device *dev, * times ensure it does not change for the duration of the * allocation. */ - nvdimm_bus_lock(dev); + guard(nvdimm_bus)(dev); nd_region->align = val; - nvdimm_bus_unlock(dev); return len; } @@ -890,7 +873,7 @@ void nd_mapping_free_labels(struct nd_mapping *nd_mapping) */ void nd_region_advance_seeds(struct nd_region *nd_region, struct device *dev) { - nvdimm_bus_lock(dev); + guard(nvdimm_bus)(dev); if (nd_region->ns_seed == dev) { nd_region_create_ns_seed(nd_region); } else if (is_nd_btt(dev)) { @@ -915,7 +898,6 @@ void nd_region_advance_seeds(struct nd_region *nd_region, struct device *dev) if (nd_region->ns_seed == &nd_dax->nd_pfn.ndns->dev) nd_region_create_ns_seed(nd_region); } - nvdimm_bus_unlock(dev); } /** diff --git a/drivers/nvdimm/security.c b/drivers/nvdimm/security.c index a03e3c45f297..4adce8c38870 100644 --- a/drivers/nvdimm/security.c +++ b/drivers/nvdimm/security.c @@ -219,12 +219,9 @@ static int __nvdimm_security_unlock(struct nvdimm *nvdimm) int nvdimm_security_unlock(struct device *dev) { struct nvdimm *nvdimm = to_nvdimm(dev); - int rc; - nvdimm_bus_lock(dev); - rc = __nvdimm_security_unlock(nvdimm); - nvdimm_bus_unlock(dev); - return rc; + guard(nvdimm_bus)(dev); + return __nvdimm_security_unlock(nvdimm); } static int check_security_state(struct nvdimm *nvdimm) @@ -490,9 +487,8 @@ void nvdimm_security_overwrite_query(struct work_struct *work) struct nvdimm *nvdimm = container_of(work, typeof(*nvdimm), dwork.work); - nvdimm_bus_lock(&nvdimm->dev); + guard(nvdimm_bus)(&nvdimm->dev); __nvdimm_security_overwrite_query(nvdimm); - nvdimm_bus_unlock(&nvdimm->dev); } #define OPS \ diff --git a/drivers/nvmem/layouts.c b/drivers/nvmem/layouts.c index 65d39e19f6ec..f381ce1e84bd 100644 --- a/drivers/nvmem/layouts.c +++ b/drivers/nvmem/layouts.c @@ -45,11 +45,24 @@ static void nvmem_layout_bus_remove(struct device *dev) return drv->remove(layout); } +static int nvmem_layout_bus_uevent(const struct device *dev, + struct kobj_uevent_env *env) +{ + int ret; + + ret = of_device_uevent_modalias(dev, env); + if (ret != ENODEV) + return ret; + + return 0; +} + static const struct bus_type nvmem_layout_bus_type = { .name = "nvmem-layout", .match = nvmem_layout_bus_match, .probe = nvmem_layout_bus_probe, .remove = nvmem_layout_bus_remove, + .uevent = nvmem_layout_bus_uevent, }; int __nvmem_layout_driver_register(struct nvmem_layout_driver *drv, diff --git a/drivers/pci/Kconfig b/drivers/pci/Kconfig index 9a249c65aedc..7065a8e5f9b1 100644 --- a/drivers/pci/Kconfig +++ b/drivers/pci/Kconfig @@ -221,7 +221,7 @@ config PCI_LABEL config PCI_HYPERV tristate "Hyper-V PCI Frontend" - depends on ((X86 && X86_64) || ARM64) && HYPERV && PCI_MSI && SYSFS + depends on ((X86 && X86_64) || ARM64) && HYPERV_VMBUS && PCI_MSI && SYSFS select PCI_HYPERV_INTERFACE select IRQ_MSI_LIB help diff --git a/drivers/pci/bus.c b/drivers/pci/bus.c index b77fd30bbfd9..f26aec6ff588 100644 --- a/drivers/pci/bus.c +++ b/drivers/pci/bus.c @@ -204,6 +204,9 @@ static int pci_bus_alloc_from_region(struct pci_bus *bus, struct resource *res, if (!r) continue; + if (r->flags & (IORESOURCE_UNSET|IORESOURCE_DISABLED)) + continue; + /* type_mask must match */ if ((res->flags ^ r->flags) & type_mask) continue; @@ -361,11 +364,15 @@ void pci_bus_add_device(struct pci_dev *dev) * before PCI client drivers. */ pdev = of_find_device_by_node(dn); - if (pdev && of_pci_supply_present(dn)) { - if (!device_link_add(&dev->dev, &pdev->dev, - DL_FLAG_AUTOREMOVE_CONSUMER)) - pci_err(dev, "failed to add device link to power control device %s\n", - pdev->name); + if (pdev) { + if (of_pci_supply_present(dn)) { + if (!device_link_add(&dev->dev, &pdev->dev, + DL_FLAG_AUTOREMOVE_CONSUMER)) { + pci_err(dev, "failed to add device link to power control device %s\n", + pdev->name); + } + } + put_device(&pdev->dev); } if (!dn || of_device_is_available(dn)) diff --git a/drivers/pci/controller/cadence/Kconfig b/drivers/pci/controller/cadence/Kconfig index 666e16b6367f..02a639e55fd8 100644 --- a/drivers/pci/controller/cadence/Kconfig +++ b/drivers/pci/controller/cadence/Kconfig @@ -42,6 +42,15 @@ config PCIE_CADENCE_PLAT_EP endpoint mode. This PCIe controller may be embedded into many different vendors SoCs. +config PCIE_SG2042_HOST + tristate "Sophgo SG2042 PCIe controller (host mode)" + depends on OF && (ARCH_SOPHGO || COMPILE_TEST) + select PCIE_CADENCE_HOST + help + Say Y here if you want to support the Sophgo SG2042 PCIe platform + controller in host mode. Sophgo SG2042 PCIe controller uses Cadence + PCIe core. + config PCI_J721E tristate select PCIE_CADENCE_HOST if PCI_J721E_HOST != n @@ -67,4 +76,5 @@ config PCI_J721E_EP Say Y here if you want to support the TI J721E PCIe platform controller in endpoint mode. TI J721E PCIe controller uses Cadence PCIe core. + endmenu diff --git a/drivers/pci/controller/cadence/Makefile b/drivers/pci/controller/cadence/Makefile index 9bac5fb2f13d..5e23f8539ecc 100644 --- a/drivers/pci/controller/cadence/Makefile +++ b/drivers/pci/controller/cadence/Makefile @@ -4,3 +4,4 @@ obj-$(CONFIG_PCIE_CADENCE_HOST) += pcie-cadence-host.o obj-$(CONFIG_PCIE_CADENCE_EP) += pcie-cadence-ep.o obj-$(CONFIG_PCIE_CADENCE_PLAT) += pcie-cadence-plat.o obj-$(CONFIG_PCI_J721E) += pci-j721e.o +obj-$(CONFIG_PCIE_SG2042_HOST) += pcie-sg2042.o diff --git a/drivers/pci/controller/cadence/pci-j721e.c b/drivers/pci/controller/cadence/pci-j721e.c index 6c93f39d0288..5bc5ab20aa6d 100644 --- a/drivers/pci/controller/cadence/pci-j721e.c +++ b/drivers/pci/controller/cadence/pci-j721e.c @@ -284,6 +284,25 @@ static int j721e_pcie_ctrl_init(struct j721e_pcie *pcie) if (!ret) offset = args.args[0]; + /* + * The PCIe Controller's registers have different "reset-values" + * depending on the "strap" settings programmed into the PCIEn_CTRL + * register within the CTRL_MMR memory-mapped register space. + * The registers latch onto a "reset-value" based on the "strap" + * settings sampled after the PCIe Controller is powered on. + * To ensure that the "reset-values" are sampled accurately, power + * off the PCIe Controller before programming the "strap" settings + * and power it on after that. The runtime PM APIs namely + * pm_runtime_put_sync() and pm_runtime_get_sync() will decrement and + * increment the usage counter respectively, causing GENPD to power off + * and power on the PCIe Controller. + */ + ret = pm_runtime_put_sync(dev); + if (ret < 0) { + dev_err(dev, "Failed to power off PCIe Controller\n"); + return ret; + } + ret = j721e_pcie_set_mode(pcie, syscon, offset); if (ret < 0) { dev_err(dev, "Failed to set pci mode\n"); @@ -302,6 +321,12 @@ static int j721e_pcie_ctrl_init(struct j721e_pcie *pcie) return ret; } + ret = pm_runtime_get_sync(dev); + if (ret < 0) { + dev_err(dev, "Failed to power on PCIe Controller\n"); + return ret; + } + /* Enable ACSPCIE refclk output if the optional property exists */ syscon = syscon_regmap_lookup_by_phandle_optional(node, "ti,syscon-acspcie-proxy-ctrl"); @@ -440,6 +465,7 @@ static const struct of_device_id of_j721e_pcie_match[] = { }, {}, }; +MODULE_DEVICE_TABLE(of, of_j721e_pcie_match); static int j721e_pcie_probe(struct platform_device *pdev) { @@ -549,7 +575,7 @@ static int j721e_pcie_probe(struct platform_device *pdev) ret = j721e_pcie_ctrl_init(pcie); if (ret < 0) { - dev_err_probe(dev, ret, "pm_runtime_get_sync failed\n"); + dev_err_probe(dev, ret, "j721e_pcie_ctrl_init failed\n"); goto err_get_sync; } diff --git a/drivers/pci/controller/cadence/pcie-cadence-ep.c b/drivers/pci/controller/cadence/pcie-cadence-ep.c index 77c5a19b2ab1..1eac012a8226 100644 --- a/drivers/pci/controller/cadence/pcie-cadence-ep.c +++ b/drivers/pci/controller/cadence/pcie-cadence-ep.c @@ -21,12 +21,13 @@ static u8 cdns_pcie_get_fn_from_vfn(struct cdns_pcie *pcie, u8 fn, u8 vfn) { - u32 cap = CDNS_PCIE_EP_FUNC_SRIOV_CAP_OFFSET; u32 first_vf_offset, stride; + u16 cap; if (vfn == 0) return fn; + cap = cdns_pcie_find_ext_capability(pcie, PCI_EXT_CAP_ID_SRIOV); first_vf_offset = cdns_pcie_ep_fn_readw(pcie, fn, cap + PCI_SRIOV_VF_OFFSET); stride = cdns_pcie_ep_fn_readw(pcie, fn, cap + PCI_SRIOV_VF_STRIDE); fn = fn + first_vf_offset + ((vfn - 1) * stride); @@ -38,10 +39,11 @@ static int cdns_pcie_ep_write_header(struct pci_epc *epc, u8 fn, u8 vfn, struct pci_epf_header *hdr) { struct cdns_pcie_ep *ep = epc_get_drvdata(epc); - u32 cap = CDNS_PCIE_EP_FUNC_SRIOV_CAP_OFFSET; struct cdns_pcie *pcie = &ep->pcie; u32 reg; + u16 cap; + cap = cdns_pcie_find_ext_capability(pcie, PCI_EXT_CAP_ID_SRIOV); if (vfn > 1) { dev_err(&epc->dev, "Only Virtual Function #1 has deviceID\n"); return -EINVAL; @@ -227,9 +229,10 @@ static int cdns_pcie_ep_set_msi(struct pci_epc *epc, u8 fn, u8 vfn, u8 nr_irqs) struct cdns_pcie_ep *ep = epc_get_drvdata(epc); struct cdns_pcie *pcie = &ep->pcie; u8 mmc = order_base_2(nr_irqs); - u32 cap = CDNS_PCIE_EP_FUNC_MSI_CAP_OFFSET; u16 flags; + u8 cap; + cap = cdns_pcie_find_capability(pcie, PCI_CAP_ID_MSI); fn = cdns_pcie_get_fn_from_vfn(pcie, fn, vfn); /* @@ -249,9 +252,10 @@ static int cdns_pcie_ep_get_msi(struct pci_epc *epc, u8 fn, u8 vfn) { struct cdns_pcie_ep *ep = epc_get_drvdata(epc); struct cdns_pcie *pcie = &ep->pcie; - u32 cap = CDNS_PCIE_EP_FUNC_MSI_CAP_OFFSET; u16 flags, mme; + u8 cap; + cap = cdns_pcie_find_capability(pcie, PCI_CAP_ID_MSIX); fn = cdns_pcie_get_fn_from_vfn(pcie, fn, vfn); /* Validate that the MSI feature is actually enabled. */ @@ -272,9 +276,10 @@ static int cdns_pcie_ep_get_msix(struct pci_epc *epc, u8 func_no, u8 vfunc_no) { struct cdns_pcie_ep *ep = epc_get_drvdata(epc); struct cdns_pcie *pcie = &ep->pcie; - u32 cap = CDNS_PCIE_EP_FUNC_MSIX_CAP_OFFSET; u32 val, reg; + u8 cap; + cap = cdns_pcie_find_capability(pcie, PCI_CAP_ID_MSIX); func_no = cdns_pcie_get_fn_from_vfn(pcie, func_no, vfunc_no); reg = cap + PCI_MSIX_FLAGS; @@ -292,9 +297,10 @@ static int cdns_pcie_ep_set_msix(struct pci_epc *epc, u8 fn, u8 vfn, { struct cdns_pcie_ep *ep = epc_get_drvdata(epc); struct cdns_pcie *pcie = &ep->pcie; - u32 cap = CDNS_PCIE_EP_FUNC_MSIX_CAP_OFFSET; u32 val, reg; + u8 cap; + cap = cdns_pcie_find_capability(pcie, PCI_CAP_ID_MSIX); fn = cdns_pcie_get_fn_from_vfn(pcie, fn, vfn); reg = cap + PCI_MSIX_FLAGS; @@ -380,11 +386,11 @@ static int cdns_pcie_ep_send_msi_irq(struct cdns_pcie_ep *ep, u8 fn, u8 vfn, u8 interrupt_num) { struct cdns_pcie *pcie = &ep->pcie; - u32 cap = CDNS_PCIE_EP_FUNC_MSI_CAP_OFFSET; u16 flags, mme, data, data_mask; - u8 msi_count; u64 pci_addr, pci_addr_mask = 0xff; + u8 msi_count, cap; + cap = cdns_pcie_find_capability(pcie, PCI_CAP_ID_MSI); fn = cdns_pcie_get_fn_from_vfn(pcie, fn, vfn); /* Check whether the MSI feature has been enabled by the PCI host. */ @@ -432,14 +438,14 @@ static int cdns_pcie_ep_map_msi_irq(struct pci_epc *epc, u8 fn, u8 vfn, u32 *msi_addr_offset) { struct cdns_pcie_ep *ep = epc_get_drvdata(epc); - u32 cap = CDNS_PCIE_EP_FUNC_MSI_CAP_OFFSET; struct cdns_pcie *pcie = &ep->pcie; u64 pci_addr, pci_addr_mask = 0xff; u16 flags, mme, data, data_mask; - u8 msi_count; + u8 msi_count, cap; int ret; int i; + cap = cdns_pcie_find_capability(pcie, PCI_CAP_ID_MSI); fn = cdns_pcie_get_fn_from_vfn(pcie, fn, vfn); /* Check whether the MSI feature has been enabled by the PCI host. */ @@ -482,16 +488,16 @@ static int cdns_pcie_ep_map_msi_irq(struct pci_epc *epc, u8 fn, u8 vfn, static int cdns_pcie_ep_send_msix_irq(struct cdns_pcie_ep *ep, u8 fn, u8 vfn, u16 interrupt_num) { - u32 cap = CDNS_PCIE_EP_FUNC_MSIX_CAP_OFFSET; u32 tbl_offset, msg_data, reg; struct cdns_pcie *pcie = &ep->pcie; struct pci_epf_msix_tbl *msix_tbl; struct cdns_pcie_epf *epf; u64 pci_addr_mask = 0xff; u64 msg_addr; + u8 bir, cap; u16 flags; - u8 bir; + cap = cdns_pcie_find_capability(pcie, PCI_CAP_ID_MSIX); epf = &ep->epf[fn]; if (vfn > 0) epf = &epf->epf[vfn - 1]; @@ -565,7 +571,9 @@ static int cdns_pcie_ep_start(struct pci_epc *epc) int max_epfs = sizeof(epc->function_num_map) * 8; int ret, epf, last_fn; u32 reg, value; + u8 cap; + cap = cdns_pcie_find_capability(pcie, PCI_CAP_ID_EXP); /* * BIT(0) is hardwired to 1, hence function 0 is always enabled * and can't be disabled anyway. @@ -589,12 +597,10 @@ static int cdns_pcie_ep_start(struct pci_epc *epc) continue; value = cdns_pcie_ep_fn_readl(pcie, epf, - CDNS_PCIE_EP_FUNC_DEV_CAP_OFFSET + - PCI_EXP_DEVCAP); + cap + PCI_EXP_DEVCAP); value &= ~PCI_EXP_DEVCAP_FLR; cdns_pcie_ep_fn_writel(pcie, epf, - CDNS_PCIE_EP_FUNC_DEV_CAP_OFFSET + - PCI_EXP_DEVCAP, value); + cap + PCI_EXP_DEVCAP, value); } } @@ -608,14 +614,12 @@ static int cdns_pcie_ep_start(struct pci_epc *epc) } static const struct pci_epc_features cdns_pcie_epc_vf_features = { - .linkup_notifier = false, .msi_capable = true, .msix_capable = true, .align = 65536, }; static const struct pci_epc_features cdns_pcie_epc_features = { - .linkup_notifier = false, .msi_capable = true, .msix_capable = true, .align = 256, diff --git a/drivers/pci/controller/cadence/pcie-cadence-host.c b/drivers/pci/controller/cadence/pcie-cadence-host.c index 59a4631de79f..fffd63d6665e 100644 --- a/drivers/pci/controller/cadence/pcie-cadence-host.c +++ b/drivers/pci/controller/cadence/pcie-cadence-host.c @@ -531,7 +531,7 @@ static int cdns_pcie_host_init_address_translation(struct cdns_pcie_rc *rc) cdns_pcie_writel(pcie, CDNS_PCIE_AT_OB_REGION_PCI_ADDR1(0), addr1); cdns_pcie_writel(pcie, CDNS_PCIE_AT_OB_REGION_DESC1(0), desc1); - if (pcie->ops->cpu_addr_fixup) + if (pcie->ops && pcie->ops->cpu_addr_fixup) cpu_addr = pcie->ops->cpu_addr_fixup(pcie, cpu_addr); addr0 = CDNS_PCIE_AT_OB_REGION_CPU_ADDR0_NBITS(12) | diff --git a/drivers/pci/controller/cadence/pcie-cadence.c b/drivers/pci/controller/cadence/pcie-cadence.c index 70a19573440e..bd683d0fecb2 100644 --- a/drivers/pci/controller/cadence/pcie-cadence.c +++ b/drivers/pci/controller/cadence/pcie-cadence.c @@ -8,6 +8,20 @@ #include <linux/of.h> #include "pcie-cadence.h" +#include "../../pci.h" + +u8 cdns_pcie_find_capability(struct cdns_pcie *pcie, u8 cap) +{ + return PCI_FIND_NEXT_CAP(cdns_pcie_read_cfg, PCI_CAPABILITY_LIST, + cap, pcie); +} +EXPORT_SYMBOL_GPL(cdns_pcie_find_capability); + +u16 cdns_pcie_find_ext_capability(struct cdns_pcie *pcie, u8 cap) +{ + return PCI_FIND_NEXT_EXT_CAP(cdns_pcie_read_cfg, 0, cap, pcie); +} +EXPORT_SYMBOL_GPL(cdns_pcie_find_ext_capability); void cdns_pcie_detect_quiet_min_delay_set(struct cdns_pcie *pcie) { @@ -92,7 +106,7 @@ void cdns_pcie_set_outbound_region(struct cdns_pcie *pcie, u8 busnr, u8 fn, cdns_pcie_writel(pcie, CDNS_PCIE_AT_OB_REGION_DESC1(r), desc1); /* Set the CPU address */ - if (pcie->ops->cpu_addr_fixup) + if (pcie->ops && pcie->ops->cpu_addr_fixup) cpu_addr = pcie->ops->cpu_addr_fixup(pcie, cpu_addr); addr0 = CDNS_PCIE_AT_OB_REGION_CPU_ADDR0_NBITS(nbits) | @@ -123,7 +137,7 @@ void cdns_pcie_set_outbound_region_for_normal_msg(struct cdns_pcie *pcie, } /* Set the CPU address */ - if (pcie->ops->cpu_addr_fixup) + if (pcie->ops && pcie->ops->cpu_addr_fixup) cpu_addr = pcie->ops->cpu_addr_fixup(pcie, cpu_addr); addr0 = CDNS_PCIE_AT_OB_REGION_CPU_ADDR0_NBITS(17) | diff --git a/drivers/pci/controller/cadence/pcie-cadence.h b/drivers/pci/controller/cadence/pcie-cadence.h index 1d81c4bf6c6d..e2a853d2c0ab 100644 --- a/drivers/pci/controller/cadence/pcie-cadence.h +++ b/drivers/pci/controller/cadence/pcie-cadence.h @@ -125,11 +125,6 @@ */ #define CDNS_PCIE_EP_FUNC_BASE(fn) (((fn) << 12) & GENMASK(19, 12)) -#define CDNS_PCIE_EP_FUNC_MSI_CAP_OFFSET 0x90 -#define CDNS_PCIE_EP_FUNC_MSIX_CAP_OFFSET 0xb0 -#define CDNS_PCIE_EP_FUNC_DEV_CAP_OFFSET 0xc0 -#define CDNS_PCIE_EP_FUNC_SRIOV_CAP_OFFSET 0x200 - /* * Endpoint PF Registers */ @@ -367,6 +362,37 @@ static inline u32 cdns_pcie_readl(struct cdns_pcie *pcie, u32 reg) return readl(pcie->reg_base + reg); } +static inline u16 cdns_pcie_readw(struct cdns_pcie *pcie, u32 reg) +{ + return readw(pcie->reg_base + reg); +} + +static inline u8 cdns_pcie_readb(struct cdns_pcie *pcie, u32 reg) +{ + return readb(pcie->reg_base + reg); +} + +static inline int cdns_pcie_read_cfg_byte(struct cdns_pcie *pcie, int where, + u8 *val) +{ + *val = cdns_pcie_readb(pcie, where); + return PCIBIOS_SUCCESSFUL; +} + +static inline int cdns_pcie_read_cfg_word(struct cdns_pcie *pcie, int where, + u16 *val) +{ + *val = cdns_pcie_readw(pcie, where); + return PCIBIOS_SUCCESSFUL; +} + +static inline int cdns_pcie_read_cfg_dword(struct cdns_pcie *pcie, int where, + u32 *val) +{ + *val = cdns_pcie_readl(pcie, where); + return PCIBIOS_SUCCESSFUL; +} + static inline u32 cdns_pcie_read_sz(void __iomem *addr, int size) { void __iomem *aligned_addr = PTR_ALIGN_DOWN(addr, 0x4); @@ -468,7 +494,7 @@ static inline u32 cdns_pcie_ep_fn_readl(struct cdns_pcie *pcie, u8 fn, u32 reg) static inline int cdns_pcie_start_link(struct cdns_pcie *pcie) { - if (pcie->ops->start_link) + if (pcie->ops && pcie->ops->start_link) return pcie->ops->start_link(pcie); return 0; @@ -476,13 +502,13 @@ static inline int cdns_pcie_start_link(struct cdns_pcie *pcie) static inline void cdns_pcie_stop_link(struct cdns_pcie *pcie) { - if (pcie->ops->stop_link) + if (pcie->ops && pcie->ops->stop_link) pcie->ops->stop_link(pcie); } static inline bool cdns_pcie_link_up(struct cdns_pcie *pcie) { - if (pcie->ops->link_up) + if (pcie->ops && pcie->ops->link_up) return pcie->ops->link_up(pcie); return true; @@ -536,6 +562,9 @@ static inline void cdns_pcie_ep_disable(struct cdns_pcie_ep *ep) } #endif +u8 cdns_pcie_find_capability(struct cdns_pcie *pcie, u8 cap); +u16 cdns_pcie_find_ext_capability(struct cdns_pcie *pcie, u8 cap); + void cdns_pcie_detect_quiet_min_delay_set(struct cdns_pcie *pcie); void cdns_pcie_set_outbound_region(struct cdns_pcie *pcie, u8 busnr, u8 fn, diff --git a/drivers/pci/controller/cadence/pcie-sg2042.c b/drivers/pci/controller/cadence/pcie-sg2042.c new file mode 100644 index 000000000000..a077b28d4894 --- /dev/null +++ b/drivers/pci/controller/cadence/pcie-sg2042.c @@ -0,0 +1,134 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * pcie-sg2042 - PCIe controller driver for Sophgo SG2042 SoC + * + * Copyright (C) 2025 Sophgo Technology Inc. + * Copyright (C) 2025 Chen Wang <unicorn_wang@outlook.com> + */ + +#include <linux/mod_devicetable.h> +#include <linux/pci.h> +#include <linux/platform_device.h> +#include <linux/pm_runtime.h> + +#include "pcie-cadence.h" + +/* + * SG2042 only supports 4-byte aligned access, so for the rootbus (i.e. to + * read/write the Root Port itself, read32/write32 is required. For + * non-rootbus (i.e. to read/write the PCIe peripheral registers, supports + * 1/2/4 byte aligned access, so directly using read/write should be fine. + */ + +static struct pci_ops sg2042_pcie_root_ops = { + .map_bus = cdns_pci_map_bus, + .read = pci_generic_config_read32, + .write = pci_generic_config_write32, +}; + +static struct pci_ops sg2042_pcie_child_ops = { + .map_bus = cdns_pci_map_bus, + .read = pci_generic_config_read, + .write = pci_generic_config_write, +}; + +static int sg2042_pcie_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct pci_host_bridge *bridge; + struct cdns_pcie *pcie; + struct cdns_pcie_rc *rc; + int ret; + + bridge = devm_pci_alloc_host_bridge(dev, sizeof(*rc)); + if (!bridge) + return dev_err_probe(dev, -ENOMEM, "Failed to alloc host bridge!\n"); + + bridge->ops = &sg2042_pcie_root_ops; + bridge->child_ops = &sg2042_pcie_child_ops; + + rc = pci_host_bridge_priv(bridge); + pcie = &rc->pcie; + pcie->dev = dev; + + platform_set_drvdata(pdev, pcie); + + pm_runtime_set_active(dev); + pm_runtime_no_callbacks(dev); + devm_pm_runtime_enable(dev); + + ret = cdns_pcie_init_phy(dev, pcie); + if (ret) + return dev_err_probe(dev, ret, "Failed to init phy!\n"); + + ret = cdns_pcie_host_setup(rc); + if (ret) { + dev_err_probe(dev, ret, "Failed to setup host!\n"); + cdns_pcie_disable_phy(pcie); + return ret; + } + + return 0; +} + +static void sg2042_pcie_remove(struct platform_device *pdev) +{ + struct cdns_pcie *pcie = platform_get_drvdata(pdev); + struct device *dev = &pdev->dev; + struct cdns_pcie_rc *rc; + + rc = container_of(pcie, struct cdns_pcie_rc, pcie); + cdns_pcie_host_disable(rc); + + cdns_pcie_disable_phy(pcie); + + pm_runtime_disable(dev); +} + +static int sg2042_pcie_suspend_noirq(struct device *dev) +{ + struct cdns_pcie *pcie = dev_get_drvdata(dev); + + cdns_pcie_disable_phy(pcie); + + return 0; +} + +static int sg2042_pcie_resume_noirq(struct device *dev) +{ + struct cdns_pcie *pcie = dev_get_drvdata(dev); + int ret; + + ret = cdns_pcie_enable_phy(pcie); + if (ret) { + dev_err(dev, "failed to enable PHY\n"); + return ret; + } + + return 0; +} + +static DEFINE_NOIRQ_DEV_PM_OPS(sg2042_pcie_pm_ops, + sg2042_pcie_suspend_noirq, + sg2042_pcie_resume_noirq); + +static const struct of_device_id sg2042_pcie_of_match[] = { + { .compatible = "sophgo,sg2042-pcie-host" }, + {}, +}; +MODULE_DEVICE_TABLE(of, sg2042_pcie_of_match); + +static struct platform_driver sg2042_pcie_driver = { + .driver = { + .name = "sg2042-pcie", + .of_match_table = sg2042_pcie_of_match, + .pm = pm_sleep_ptr(&sg2042_pcie_pm_ops), + }, + .probe = sg2042_pcie_probe, + .remove = sg2042_pcie_remove, +}; +module_platform_driver(sg2042_pcie_driver); + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("PCIe controller driver for SG2042 SoCs"); +MODULE_AUTHOR("Chen Wang <unicorn_wang@outlook.com>"); diff --git a/drivers/pci/controller/dwc/Kconfig b/drivers/pci/controller/dwc/Kconfig index ff6b6d9e18ec..349d4657393c 100644 --- a/drivers/pci/controller/dwc/Kconfig +++ b/drivers/pci/controller/dwc/Kconfig @@ -20,6 +20,7 @@ config PCIE_DW_HOST bool select PCIE_DW select IRQ_MSI_LIB + select PCI_HOST_COMMON config PCIE_DW_EP bool @@ -298,6 +299,7 @@ config PCIE_QCOM select CRC8 select PCIE_QCOM_COMMON select PCI_HOST_COMMON + select PCI_PWRCTRL_SLOT help Say Y here to enable PCIe controller support on Qualcomm SoCs. The PCIe controller uses the DesignWare core plus Qualcomm-specific @@ -422,6 +424,30 @@ config PCIE_SPEAR13XX help Say Y here if you want PCIe support on SPEAr13XX SoCs. +config PCIE_STM32_HOST + tristate "STMicroelectronics STM32MP25 PCIe Controller (host mode)" + depends on ARCH_STM32 || COMPILE_TEST + depends on PCI_MSI + select PCIE_DW_HOST + help + Enables Root Complex (RC) support for the DesignWare core based PCIe + controller found in STM32MP25 SoC. + + This driver can also be built as a module. If so, the module + will be called pcie-stm32. + +config PCIE_STM32_EP + tristate "STMicroelectronics STM32MP25 PCIe Controller (endpoint mode)" + depends on ARCH_STM32 || COMPILE_TEST + depends on PCI_ENDPOINT + select PCIE_DW_EP + help + Enables Endpoint (EP) support for the DesignWare core based PCIe + controller found in STM32MP25 SoC. + + This driver can also be built as a module. If so, the module + will be called pcie-stm32-ep. + config PCI_DRA7XX tristate diff --git a/drivers/pci/controller/dwc/Makefile b/drivers/pci/controller/dwc/Makefile index 6919d27798d1..7ae28f3b0fb3 100644 --- a/drivers/pci/controller/dwc/Makefile +++ b/drivers/pci/controller/dwc/Makefile @@ -31,6 +31,8 @@ obj-$(CONFIG_PCIE_UNIPHIER) += pcie-uniphier.o obj-$(CONFIG_PCIE_UNIPHIER_EP) += pcie-uniphier-ep.o obj-$(CONFIG_PCIE_VISCONTI_HOST) += pcie-visconti.o obj-$(CONFIG_PCIE_RCAR_GEN4) += pcie-rcar-gen4.o +obj-$(CONFIG_PCIE_STM32_HOST) += pcie-stm32.o +obj-$(CONFIG_PCIE_STM32_EP) += pcie-stm32-ep.o # The following drivers are for devices that use the generic ACPI # pci_root.c driver but don't support standard ECAM config access. diff --git a/drivers/pci/controller/dwc/pci-dra7xx.c b/drivers/pci/controller/dwc/pci-dra7xx.c index f97f5266d196..01cfd9aeb0b8 100644 --- a/drivers/pci/controller/dwc/pci-dra7xx.c +++ b/drivers/pci/controller/dwc/pci-dra7xx.c @@ -426,7 +426,6 @@ static int dra7xx_pcie_raise_irq(struct dw_pcie_ep *ep, u8 func_no, static const struct pci_epc_features dra7xx_pcie_epc_features = { .linkup_notifier = true, .msi_capable = true, - .msix_capable = false, }; static const struct pci_epc_features* diff --git a/drivers/pci/controller/dwc/pci-exynos.c b/drivers/pci/controller/dwc/pci-exynos.c index 1f0e98d07109..0bb7d4f5d784 100644 --- a/drivers/pci/controller/dwc/pci-exynos.c +++ b/drivers/pci/controller/dwc/pci-exynos.c @@ -53,7 +53,6 @@ struct exynos_pcie { struct dw_pcie pci; - void __iomem *elbi_base; struct clk_bulk_data *clks; struct phy *phy; struct regulator_bulk_data supplies[2]; @@ -71,73 +70,78 @@ static u32 exynos_pcie_readl(void __iomem *base, u32 reg) static void exynos_pcie_sideband_dbi_w_mode(struct exynos_pcie *ep, bool on) { + struct dw_pcie *pci = &ep->pci; u32 val; - val = exynos_pcie_readl(ep->elbi_base, PCIE_ELBI_SLV_AWMISC); + val = exynos_pcie_readl(pci->elbi_base, PCIE_ELBI_SLV_AWMISC); if (on) val |= PCIE_ELBI_SLV_DBI_ENABLE; else val &= ~PCIE_ELBI_SLV_DBI_ENABLE; - exynos_pcie_writel(ep->elbi_base, val, PCIE_ELBI_SLV_AWMISC); + exynos_pcie_writel(pci->elbi_base, val, PCIE_ELBI_SLV_AWMISC); } static void exynos_pcie_sideband_dbi_r_mode(struct exynos_pcie *ep, bool on) { + struct dw_pcie *pci = &ep->pci; u32 val; - val = exynos_pcie_readl(ep->elbi_base, PCIE_ELBI_SLV_ARMISC); + val = exynos_pcie_readl(pci->elbi_base, PCIE_ELBI_SLV_ARMISC); if (on) val |= PCIE_ELBI_SLV_DBI_ENABLE; else val &= ~PCIE_ELBI_SLV_DBI_ENABLE; - exynos_pcie_writel(ep->elbi_base, val, PCIE_ELBI_SLV_ARMISC); + exynos_pcie_writel(pci->elbi_base, val, PCIE_ELBI_SLV_ARMISC); } static void exynos_pcie_assert_core_reset(struct exynos_pcie *ep) { + struct dw_pcie *pci = &ep->pci; u32 val; - val = exynos_pcie_readl(ep->elbi_base, PCIE_CORE_RESET); + val = exynos_pcie_readl(pci->elbi_base, PCIE_CORE_RESET); val &= ~PCIE_CORE_RESET_ENABLE; - exynos_pcie_writel(ep->elbi_base, val, PCIE_CORE_RESET); - exynos_pcie_writel(ep->elbi_base, 0, PCIE_STICKY_RESET); - exynos_pcie_writel(ep->elbi_base, 0, PCIE_NONSTICKY_RESET); + exynos_pcie_writel(pci->elbi_base, val, PCIE_CORE_RESET); + exynos_pcie_writel(pci->elbi_base, 0, PCIE_STICKY_RESET); + exynos_pcie_writel(pci->elbi_base, 0, PCIE_NONSTICKY_RESET); } static void exynos_pcie_deassert_core_reset(struct exynos_pcie *ep) { + struct dw_pcie *pci = &ep->pci; u32 val; - val = exynos_pcie_readl(ep->elbi_base, PCIE_CORE_RESET); + val = exynos_pcie_readl(pci->elbi_base, PCIE_CORE_RESET); val |= PCIE_CORE_RESET_ENABLE; - exynos_pcie_writel(ep->elbi_base, val, PCIE_CORE_RESET); - exynos_pcie_writel(ep->elbi_base, 1, PCIE_STICKY_RESET); - exynos_pcie_writel(ep->elbi_base, 1, PCIE_NONSTICKY_RESET); - exynos_pcie_writel(ep->elbi_base, 1, PCIE_APP_INIT_RESET); - exynos_pcie_writel(ep->elbi_base, 0, PCIE_APP_INIT_RESET); + exynos_pcie_writel(pci->elbi_base, val, PCIE_CORE_RESET); + exynos_pcie_writel(pci->elbi_base, 1, PCIE_STICKY_RESET); + exynos_pcie_writel(pci->elbi_base, 1, PCIE_NONSTICKY_RESET); + exynos_pcie_writel(pci->elbi_base, 1, PCIE_APP_INIT_RESET); + exynos_pcie_writel(pci->elbi_base, 0, PCIE_APP_INIT_RESET); } static int exynos_pcie_start_link(struct dw_pcie *pci) { - struct exynos_pcie *ep = to_exynos_pcie(pci); u32 val; - val = exynos_pcie_readl(ep->elbi_base, PCIE_SW_WAKE); + val = exynos_pcie_readl(pci->elbi_base, PCIE_SW_WAKE); val &= ~PCIE_BUS_EN; - exynos_pcie_writel(ep->elbi_base, val, PCIE_SW_WAKE); + exynos_pcie_writel(pci->elbi_base, val, PCIE_SW_WAKE); /* assert LTSSM enable */ - exynos_pcie_writel(ep->elbi_base, PCIE_ELBI_LTSSM_ENABLE, + exynos_pcie_writel(pci->elbi_base, PCIE_ELBI_LTSSM_ENABLE, PCIE_APP_LTSSM_ENABLE); return 0; } static void exynos_pcie_clear_irq_pulse(struct exynos_pcie *ep) { - u32 val = exynos_pcie_readl(ep->elbi_base, PCIE_IRQ_PULSE); + struct dw_pcie *pci = &ep->pci; - exynos_pcie_writel(ep->elbi_base, val, PCIE_IRQ_PULSE); + u32 val = exynos_pcie_readl(pci->elbi_base, PCIE_IRQ_PULSE); + + exynos_pcie_writel(pci->elbi_base, val, PCIE_IRQ_PULSE); } static irqreturn_t exynos_pcie_irq_handler(int irq, void *arg) @@ -150,12 +154,14 @@ static irqreturn_t exynos_pcie_irq_handler(int irq, void *arg) static void exynos_pcie_enable_irq_pulse(struct exynos_pcie *ep) { + struct dw_pcie *pci = &ep->pci; + u32 val = IRQ_INTA_ASSERT | IRQ_INTB_ASSERT | IRQ_INTC_ASSERT | IRQ_INTD_ASSERT; - exynos_pcie_writel(ep->elbi_base, val, PCIE_IRQ_EN_PULSE); - exynos_pcie_writel(ep->elbi_base, 0, PCIE_IRQ_EN_LEVEL); - exynos_pcie_writel(ep->elbi_base, 0, PCIE_IRQ_EN_SPECIAL); + exynos_pcie_writel(pci->elbi_base, val, PCIE_IRQ_EN_PULSE); + exynos_pcie_writel(pci->elbi_base, 0, PCIE_IRQ_EN_LEVEL); + exynos_pcie_writel(pci->elbi_base, 0, PCIE_IRQ_EN_SPECIAL); } static u32 exynos_pcie_read_dbi(struct dw_pcie *pci, void __iomem *base, @@ -211,8 +217,7 @@ static struct pci_ops exynos_pci_ops = { static bool exynos_pcie_link_up(struct dw_pcie *pci) { - struct exynos_pcie *ep = to_exynos_pcie(pci); - u32 val = exynos_pcie_readl(ep->elbi_base, PCIE_ELBI_RDLH_LINKUP); + u32 val = exynos_pcie_readl(pci->elbi_base, PCIE_ELBI_RDLH_LINKUP); return val & PCIE_ELBI_XMLH_LINKUP; } @@ -295,11 +300,6 @@ static int exynos_pcie_probe(struct platform_device *pdev) if (IS_ERR(ep->phy)) return PTR_ERR(ep->phy); - /* External Local Bus interface (ELBI) registers */ - ep->elbi_base = devm_platform_ioremap_resource_byname(pdev, "elbi"); - if (IS_ERR(ep->elbi_base)) - return PTR_ERR(ep->elbi_base); - ret = devm_clk_bulk_get_all_enabled(dev, &ep->clks); if (ret < 0) return ret; diff --git a/drivers/pci/controller/dwc/pci-imx6.c b/drivers/pci/controller/dwc/pci-imx6.c index 80e48746bbaf..4668fc9648bf 100644 --- a/drivers/pci/controller/dwc/pci-imx6.c +++ b/drivers/pci/controller/dwc/pci-imx6.c @@ -1387,9 +1387,7 @@ static int imx_pcie_ep_raise_irq(struct dw_pcie_ep *ep, u8 func_no, } static const struct pci_epc_features imx8m_pcie_epc_features = { - .linkup_notifier = false, .msi_capable = true, - .msix_capable = false, .bar[BAR_1] = { .type = BAR_RESERVED, }, .bar[BAR_3] = { .type = BAR_RESERVED, }, .bar[BAR_4] = { .type = BAR_FIXED, .fixed_size = SZ_256, }, @@ -1398,9 +1396,7 @@ static const struct pci_epc_features imx8m_pcie_epc_features = { }; static const struct pci_epc_features imx8q_pcie_epc_features = { - .linkup_notifier = false, .msi_capable = true, - .msix_capable = false, .bar[BAR_1] = { .type = BAR_RESERVED, }, .bar[BAR_3] = { .type = BAR_RESERVED, }, .bar[BAR_5] = { .type = BAR_RESERVED, }, @@ -1745,6 +1741,10 @@ static int imx_pcie_probe(struct platform_device *pdev) pci->max_link_speed = 1; of_property_read_u32(node, "fsl,max-link-speed", &pci->max_link_speed); + ret = devm_regulator_get_enable_optional(&pdev->dev, "vpcie3v3aux"); + if (ret < 0 && ret != -ENODEV) + return dev_err_probe(dev, ret, "failed to enable Vaux supply\n"); + imx_pcie->vpcie = devm_regulator_get_optional(&pdev->dev, "vpcie"); if (IS_ERR(imx_pcie->vpcie)) { if (PTR_ERR(imx_pcie->vpcie) != -ENODEV) diff --git a/drivers/pci/controller/dwc/pci-keystone.c b/drivers/pci/controller/dwc/pci-keystone.c index 2b2632e513b5..eb00aa380722 100644 --- a/drivers/pci/controller/dwc/pci-keystone.c +++ b/drivers/pci/controller/dwc/pci-keystone.c @@ -960,7 +960,6 @@ static int ks_pcie_am654_raise_irq(struct dw_pcie_ep *ep, u8 func_no, } static const struct pci_epc_features ks_pcie_am654_epc_features = { - .linkup_notifier = false, .msi_capable = true, .msix_capable = true, .bar[BAR_0] = { .type = BAR_RESERVED, }, @@ -1201,8 +1200,8 @@ static int ks_pcie_probe(struct platform_device *pdev) if (irq < 0) return irq; - ret = request_irq(irq, ks_pcie_err_irq_handler, IRQF_SHARED, - "ks-pcie-error-irq", ks_pcie); + ret = devm_request_irq(dev, irq, ks_pcie_err_irq_handler, IRQF_SHARED, + "ks-pcie-error-irq", ks_pcie); if (ret < 0) { dev_err(dev, "failed to request error IRQ %d\n", irq); @@ -1213,11 +1212,11 @@ static int ks_pcie_probe(struct platform_device *pdev) if (ret) num_lanes = 1; - phy = devm_kzalloc(dev, sizeof(*phy) * num_lanes, GFP_KERNEL); + phy = devm_kcalloc(dev, num_lanes, sizeof(*phy), GFP_KERNEL); if (!phy) return -ENOMEM; - link = devm_kzalloc(dev, sizeof(*link) * num_lanes, GFP_KERNEL); + link = devm_kcalloc(dev, num_lanes, sizeof(*link), GFP_KERNEL); if (!link) return -ENOMEM; diff --git a/drivers/pci/controller/dwc/pcie-al.c b/drivers/pci/controller/dwc/pcie-al.c index 643115f74092..345c281c74fe 100644 --- a/drivers/pci/controller/dwc/pcie-al.c +++ b/drivers/pci/controller/dwc/pcie-al.c @@ -352,6 +352,7 @@ static int al_pcie_probe(struct platform_device *pdev) return -ENOENT; } al_pcie->ecam_size = resource_size(ecam_res); + pci->pp.native_ecam = true; controller_res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "controller"); diff --git a/drivers/pci/controller/dwc/pcie-amd-mdb.c b/drivers/pci/controller/dwc/pcie-amd-mdb.c index 9f7251a16d32..3c6e837465bb 100644 --- a/drivers/pci/controller/dwc/pcie-amd-mdb.c +++ b/drivers/pci/controller/dwc/pcie-amd-mdb.c @@ -18,6 +18,7 @@ #include <linux/resource.h> #include <linux/types.h> +#include "../../pci.h" #include "pcie-designware.h" #define AMD_MDB_TLP_IR_STATUS_MISC 0x4C0 @@ -56,6 +57,7 @@ * @slcr: MDB System Level Control and Status Register (SLCR) base * @intx_domain: INTx IRQ domain pointer * @mdb_domain: MDB IRQ domain pointer + * @perst_gpio: GPIO descriptor for PERST# signal handling * @intx_irq: INTx IRQ interrupt number */ struct amd_mdb_pcie { @@ -63,6 +65,7 @@ struct amd_mdb_pcie { void __iomem *slcr; struct irq_domain *intx_domain; struct irq_domain *mdb_domain; + struct gpio_desc *perst_gpio; int intx_irq; }; @@ -284,7 +287,7 @@ static int amd_mdb_pcie_init_irq_domains(struct amd_mdb_pcie *pcie, struct device_node *pcie_intc_node; int err; - pcie_intc_node = of_get_next_child(node, NULL); + pcie_intc_node = of_get_child_by_name(node, "interrupt-controller"); if (!pcie_intc_node) { dev_err(dev, "No PCIe Intc node found\n"); return -ENODEV; @@ -402,6 +405,28 @@ static int amd_mdb_setup_irq(struct amd_mdb_pcie *pcie, return 0; } +static int amd_mdb_parse_pcie_port(struct amd_mdb_pcie *pcie) +{ + struct device *dev = pcie->pci.dev; + struct device_node *pcie_port_node __maybe_unused; + + /* + * This platform currently supports only one Root Port, so the loop + * will execute only once. + * TODO: Enhance the driver to handle multiple Root Ports in the future. + */ + for_each_child_of_node_with_prefix(dev->of_node, pcie_port_node, "pcie") { + pcie->perst_gpio = devm_fwnode_gpiod_get(dev, of_fwnode_handle(pcie_port_node), + "reset", GPIOD_OUT_HIGH, NULL); + if (IS_ERR(pcie->perst_gpio)) + return dev_err_probe(dev, PTR_ERR(pcie->perst_gpio), + "Failed to request reset GPIO\n"); + return 0; + } + + return -ENODEV; +} + static int amd_mdb_add_pcie_port(struct amd_mdb_pcie *pcie, struct platform_device *pdev) { @@ -426,6 +451,12 @@ static int amd_mdb_add_pcie_port(struct amd_mdb_pcie *pcie, pp->ops = &amd_mdb_pcie_host_ops; + if (pcie->perst_gpio) { + mdelay(PCIE_T_PVPERL_MS); + gpiod_set_value_cansleep(pcie->perst_gpio, 0); + mdelay(PCIE_RESET_CONFIG_WAIT_MS); + } + err = dw_pcie_host_init(pp); if (err) { dev_err(dev, "Failed to initialize host, err=%d\n", err); @@ -444,6 +475,7 @@ static int amd_mdb_pcie_probe(struct platform_device *pdev) struct device *dev = &pdev->dev; struct amd_mdb_pcie *pcie; struct dw_pcie *pci; + int ret; pcie = devm_kzalloc(dev, sizeof(*pcie), GFP_KERNEL); if (!pcie) @@ -454,6 +486,24 @@ static int amd_mdb_pcie_probe(struct platform_device *pdev) platform_set_drvdata(pdev, pcie); + ret = amd_mdb_parse_pcie_port(pcie); + /* + * If amd_mdb_parse_pcie_port returns -ENODEV, it indicates that the + * PCIe Bridge node was not found in the device tree. This is not + * considered a fatal error and will trigger a fallback where the + * reset GPIO is acquired directly from the PCIe Host Bridge node. + */ + if (ret) { + if (ret != -ENODEV) + return ret; + + pcie->perst_gpio = devm_gpiod_get_optional(dev, "reset", + GPIOD_OUT_HIGH); + if (IS_ERR(pcie->perst_gpio)) + return dev_err_probe(dev, PTR_ERR(pcie->perst_gpio), + "Failed to request reset GPIO\n"); + } + return amd_mdb_add_pcie_port(pcie, pdev); } diff --git a/drivers/pci/controller/dwc/pcie-artpec6.c b/drivers/pci/controller/dwc/pcie-artpec6.c index 234c8cbcae3a..f4a136ee2daf 100644 --- a/drivers/pci/controller/dwc/pcie-artpec6.c +++ b/drivers/pci/controller/dwc/pcie-artpec6.c @@ -370,9 +370,7 @@ static int artpec6_pcie_raise_irq(struct dw_pcie_ep *ep, u8 func_no, } static const struct pci_epc_features artpec6_pcie_epc_features = { - .linkup_notifier = false, .msi_capable = true, - .msix_capable = false, }; static const struct pci_epc_features * diff --git a/drivers/pci/controller/dwc/pcie-designware-ep.c b/drivers/pci/controller/dwc/pcie-designware-ep.c index 0ae54a94809b..7f2112c2fb21 100644 --- a/drivers/pci/controller/dwc/pcie-designware-ep.c +++ b/drivers/pci/controller/dwc/pcie-designware-ep.c @@ -69,37 +69,10 @@ void dw_pcie_ep_reset_bar(struct dw_pcie *pci, enum pci_barno bar) } EXPORT_SYMBOL_GPL(dw_pcie_ep_reset_bar); -static u8 __dw_pcie_ep_find_next_cap(struct dw_pcie_ep *ep, u8 func_no, - u8 cap_ptr, u8 cap) -{ - u8 cap_id, next_cap_ptr; - u16 reg; - - if (!cap_ptr) - return 0; - - reg = dw_pcie_ep_readw_dbi(ep, func_no, cap_ptr); - cap_id = (reg & 0x00ff); - - if (cap_id > PCI_CAP_ID_MAX) - return 0; - - if (cap_id == cap) - return cap_ptr; - - next_cap_ptr = (reg & 0xff00) >> 8; - return __dw_pcie_ep_find_next_cap(ep, func_no, next_cap_ptr, cap); -} - static u8 dw_pcie_ep_find_capability(struct dw_pcie_ep *ep, u8 func_no, u8 cap) { - u8 next_cap_ptr; - u16 reg; - - reg = dw_pcie_ep_readw_dbi(ep, func_no, PCI_CAPABILITY_LIST); - next_cap_ptr = (reg & 0x00ff); - - return __dw_pcie_ep_find_next_cap(ep, func_no, next_cap_ptr, cap); + return PCI_FIND_NEXT_CAP(dw_pcie_ep_read_cfg, PCI_CAPABILITY_LIST, + cap, ep, func_no); } /** diff --git a/drivers/pci/controller/dwc/pcie-designware-host.c b/drivers/pci/controller/dwc/pcie-designware-host.c index 952f8594b501..20c9333bcb1c 100644 --- a/drivers/pci/controller/dwc/pcie-designware-host.c +++ b/drivers/pci/controller/dwc/pcie-designware-host.c @@ -8,6 +8,7 @@ * Author: Jingoo Han <jg1.han@samsung.com> */ +#include <linux/align.h> #include <linux/iopoll.h> #include <linux/irqchip/chained_irq.h> #include <linux/irqchip/irq-msi-lib.h> @@ -32,6 +33,8 @@ static struct pci_ops dw_child_pcie_ops; MSI_FLAG_PCI_MSIX | \ MSI_GENERIC_FLAGS_MASK) +#define IS_256MB_ALIGNED(x) IS_ALIGNED(x, SZ_256M) + static const struct msi_parent_ops dw_pcie_msi_parent_ops = { .required_flags = DW_PCIE_MSI_FLAGS_REQUIRED, .supported_flags = DW_PCIE_MSI_FLAGS_SUPPORTED, @@ -413,6 +416,95 @@ static void dw_pcie_host_request_msg_tlp_res(struct dw_pcie_rp *pp) } } +static int dw_pcie_config_ecam_iatu(struct dw_pcie_rp *pp) +{ + struct dw_pcie *pci = to_dw_pcie_from_pp(pp); + struct dw_pcie_ob_atu_cfg atu = {0}; + resource_size_t bus_range_max; + struct resource_entry *bus; + int ret; + + bus = resource_list_first_type(&pp->bridge->windows, IORESOURCE_BUS); + + /* + * Root bus under the host bridge doesn't require any iATU configuration + * as DBI region will be used to access root bus config space. + * Immediate bus under Root Bus, needs type 0 iATU configuration and + * remaining buses need type 1 iATU configuration. + */ + atu.index = 0; + atu.type = PCIE_ATU_TYPE_CFG0; + atu.parent_bus_addr = pp->cfg0_base + SZ_1M; + /* 1MiB is to cover 1 (bus) * 32 (devices) * 8 (functions) */ + atu.size = SZ_1M; + atu.ctrl2 = PCIE_ATU_CFG_SHIFT_MODE_ENABLE; + ret = dw_pcie_prog_outbound_atu(pci, &atu); + if (ret) + return ret; + + bus_range_max = resource_size(bus->res); + + if (bus_range_max < 2) + return 0; + + /* Configure remaining buses in type 1 iATU configuration */ + atu.index = 1; + atu.type = PCIE_ATU_TYPE_CFG1; + atu.parent_bus_addr = pp->cfg0_base + SZ_2M; + atu.size = (SZ_1M * bus_range_max) - SZ_2M; + atu.ctrl2 = PCIE_ATU_CFG_SHIFT_MODE_ENABLE; + + return dw_pcie_prog_outbound_atu(pci, &atu); +} + +static int dw_pcie_create_ecam_window(struct dw_pcie_rp *pp, struct resource *res) +{ + struct dw_pcie *pci = to_dw_pcie_from_pp(pp); + struct device *dev = pci->dev; + struct resource_entry *bus; + + bus = resource_list_first_type(&pp->bridge->windows, IORESOURCE_BUS); + if (!bus) + return -ENODEV; + + pp->cfg = pci_ecam_create(dev, res, bus->res, &pci_generic_ecam_ops); + if (IS_ERR(pp->cfg)) + return PTR_ERR(pp->cfg); + + pci->dbi_base = pp->cfg->win; + pci->dbi_phys_addr = res->start; + + return 0; +} + +static bool dw_pcie_ecam_enabled(struct dw_pcie_rp *pp, struct resource *config_res) +{ + struct resource *bus_range; + u64 nr_buses; + + /* Vendor glue drivers may implement their own ECAM mechanism */ + if (pp->native_ecam) + return false; + + /* + * PCIe spec r6.0, sec 7.2.2 mandates the base address used for ECAM to + * be aligned on a 2^(n+20) byte boundary, where n is the number of bits + * used for representing 'bus' in BDF. Since the DWC cores always use 8 + * bits for representing 'bus', the base address has to be aligned to + * 2^28 byte boundary, which is 256 MiB. + */ + if (!IS_256MB_ALIGNED(config_res->start)) + return false; + + bus_range = resource_list_first_type(&pp->bridge->windows, IORESOURCE_BUS)->res; + if (!bus_range) + return false; + + nr_buses = resource_size(config_res) >> PCIE_ECAM_BUS_SHIFT; + + return nr_buses >= resource_size(bus_range); +} + static int dw_pcie_host_get_resources(struct dw_pcie_rp *pp) { struct dw_pcie *pci = to_dw_pcie_from_pp(pp); @@ -422,10 +514,6 @@ static int dw_pcie_host_get_resources(struct dw_pcie_rp *pp) struct resource *res; int ret; - ret = dw_pcie_get_resources(pci); - if (ret) - return ret; - res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "config"); if (!res) { dev_err(dev, "Missing \"config\" reg space\n"); @@ -435,9 +523,32 @@ static int dw_pcie_host_get_resources(struct dw_pcie_rp *pp) pp->cfg0_size = resource_size(res); pp->cfg0_base = res->start; - pp->va_cfg0_base = devm_pci_remap_cfg_resource(dev, res); - if (IS_ERR(pp->va_cfg0_base)) - return PTR_ERR(pp->va_cfg0_base); + pp->ecam_enabled = dw_pcie_ecam_enabled(pp, res); + if (pp->ecam_enabled) { + ret = dw_pcie_create_ecam_window(pp, res); + if (ret) + return ret; + + pp->bridge->ops = (struct pci_ops *)&pci_generic_ecam_ops.pci_ops; + pp->bridge->sysdata = pp->cfg; + pp->cfg->priv = pp; + } else { + pp->va_cfg0_base = devm_pci_remap_cfg_resource(dev, res); + if (IS_ERR(pp->va_cfg0_base)) + return PTR_ERR(pp->va_cfg0_base); + + /* Set default bus ops */ + pp->bridge->ops = &dw_pcie_ops; + pp->bridge->child_ops = &dw_child_pcie_ops; + pp->bridge->sysdata = pp; + } + + ret = dw_pcie_get_resources(pci); + if (ret) { + if (pp->cfg) + pci_ecam_free(pp->cfg); + return ret; + } /* Get the I/O range from DT */ win = resource_list_first_type(&pp->bridge->windows, IORESOURCE_IO); @@ -476,14 +587,10 @@ int dw_pcie_host_init(struct dw_pcie_rp *pp) if (ret) return ret; - /* Set default bus ops */ - bridge->ops = &dw_pcie_ops; - bridge->child_ops = &dw_child_pcie_ops; - if (pp->ops->init) { ret = pp->ops->init(pp); if (ret) - return ret; + goto err_free_ecam; } if (pci_msi_enabled()) { @@ -525,6 +632,14 @@ int dw_pcie_host_init(struct dw_pcie_rp *pp) if (ret) goto err_free_msi; + if (pp->ecam_enabled) { + ret = dw_pcie_config_ecam_iatu(pp); + if (ret) { + dev_err(dev, "Failed to configure iATU in ECAM mode\n"); + goto err_free_msi; + } + } + /* * Allocate the resource for MSG TLP before programming the iATU * outbound window in dw_pcie_setup_rc(). Since the allocation depends @@ -560,8 +675,6 @@ int dw_pcie_host_init(struct dw_pcie_rp *pp) /* Ignore errors, the link may come up later */ dw_pcie_wait_for_link(pci); - bridge->sysdata = pp; - ret = pci_host_probe(bridge); if (ret) goto err_stop_link; @@ -587,6 +700,10 @@ err_deinit_host: if (pp->ops->deinit) pp->ops->deinit(pp); +err_free_ecam: + if (pp->cfg) + pci_ecam_free(pp->cfg); + return ret; } EXPORT_SYMBOL_GPL(dw_pcie_host_init); @@ -609,6 +726,9 @@ void dw_pcie_host_deinit(struct dw_pcie_rp *pp) if (pp->ops->deinit) pp->ops->deinit(pp); + + if (pp->cfg) + pci_ecam_free(pp->cfg); } EXPORT_SYMBOL_GPL(dw_pcie_host_deinit); diff --git a/drivers/pci/controller/dwc/pcie-designware-plat.c b/drivers/pci/controller/dwc/pcie-designware-plat.c index 771b9d9be077..12f41886c65d 100644 --- a/drivers/pci/controller/dwc/pcie-designware-plat.c +++ b/drivers/pci/controller/dwc/pcie-designware-plat.c @@ -61,7 +61,6 @@ static int dw_plat_pcie_ep_raise_irq(struct dw_pcie_ep *ep, u8 func_no, } static const struct pci_epc_features dw_plat_pcie_epc_features = { - .linkup_notifier = false, .msi_capable = true, .msix_capable = true, }; diff --git a/drivers/pci/controller/dwc/pcie-designware.c b/drivers/pci/controller/dwc/pcie-designware.c index 89aad5a08928..c644216995f6 100644 --- a/drivers/pci/controller/dwc/pcie-designware.c +++ b/drivers/pci/controller/dwc/pcie-designware.c @@ -167,6 +167,14 @@ int dw_pcie_get_resources(struct dw_pcie *pci) } } + /* ELBI is an optional resource */ + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "elbi"); + if (res) { + pci->elbi_base = devm_ioremap_resource(pci->dev, res); + if (IS_ERR(pci->elbi_base)) + return PTR_ERR(pci->elbi_base); + } + /* LLDD is supposed to manually switch the clocks and resets state */ if (dw_pcie_cap_is(pci, REQ_RES)) { ret = dw_pcie_get_clocks(pci); @@ -213,83 +221,16 @@ void dw_pcie_version_detect(struct dw_pcie *pci) pci->type = ver; } -/* - * These interfaces resemble the pci_find_*capability() interfaces, but these - * are for configuring host controllers, which are bridges *to* PCI devices but - * are not PCI devices themselves. - */ -static u8 __dw_pcie_find_next_cap(struct dw_pcie *pci, u8 cap_ptr, - u8 cap) -{ - u8 cap_id, next_cap_ptr; - u16 reg; - - if (!cap_ptr) - return 0; - - reg = dw_pcie_readw_dbi(pci, cap_ptr); - cap_id = (reg & 0x00ff); - - if (cap_id > PCI_CAP_ID_MAX) - return 0; - - if (cap_id == cap) - return cap_ptr; - - next_cap_ptr = (reg & 0xff00) >> 8; - return __dw_pcie_find_next_cap(pci, next_cap_ptr, cap); -} - u8 dw_pcie_find_capability(struct dw_pcie *pci, u8 cap) { - u8 next_cap_ptr; - u16 reg; - - reg = dw_pcie_readw_dbi(pci, PCI_CAPABILITY_LIST); - next_cap_ptr = (reg & 0x00ff); - - return __dw_pcie_find_next_cap(pci, next_cap_ptr, cap); + return PCI_FIND_NEXT_CAP(dw_pcie_read_cfg, PCI_CAPABILITY_LIST, cap, + pci); } EXPORT_SYMBOL_GPL(dw_pcie_find_capability); -static u16 dw_pcie_find_next_ext_capability(struct dw_pcie *pci, u16 start, - u8 cap) -{ - u32 header; - int ttl; - int pos = PCI_CFG_SPACE_SIZE; - - /* minimum 8 bytes per capability */ - ttl = (PCI_CFG_SPACE_EXP_SIZE - PCI_CFG_SPACE_SIZE) / 8; - - if (start) - pos = start; - - header = dw_pcie_readl_dbi(pci, pos); - /* - * If we have no capabilities, this is indicated by cap ID, - * cap version and next pointer all being 0. - */ - if (header == 0) - return 0; - - while (ttl-- > 0) { - if (PCI_EXT_CAP_ID(header) == cap && pos != start) - return pos; - - pos = PCI_EXT_CAP_NEXT(header); - if (pos < PCI_CFG_SPACE_SIZE) - break; - - header = dw_pcie_readl_dbi(pci, pos); - } - - return 0; -} - u16 dw_pcie_find_ext_capability(struct dw_pcie *pci, u8 cap) { - return dw_pcie_find_next_ext_capability(pci, 0, cap); + return PCI_FIND_NEXT_EXT_CAP(dw_pcie_read_cfg, 0, cap, pci); } EXPORT_SYMBOL_GPL(dw_pcie_find_ext_capability); @@ -302,8 +243,8 @@ static u16 __dw_pcie_find_vsec_capability(struct dw_pcie *pci, u16 vendor_id, if (vendor_id != dw_pcie_readw_dbi(pci, PCI_VENDOR_ID)) return 0; - while ((vsec = dw_pcie_find_next_ext_capability(pci, vsec, - PCI_EXT_CAP_ID_VNDR))) { + while ((vsec = PCI_FIND_NEXT_EXT_CAP(dw_pcie_read_cfg, vsec, + PCI_EXT_CAP_ID_VNDR, pci))) { header = dw_pcie_readl_dbi(pci, vsec + PCI_VNDR_HEADER); if (PCI_VNDR_HEADER_ID(header) == vsec_id) return vsec; @@ -567,7 +508,7 @@ int dw_pcie_prog_outbound_atu(struct dw_pcie *pci, val = dw_pcie_enable_ecrc(val); dw_pcie_writel_atu_ob(pci, atu->index, PCIE_ATU_REGION_CTRL1, val); - val = PCIE_ATU_ENABLE; + val = PCIE_ATU_ENABLE | atu->ctrl2; if (atu->type == PCIE_ATU_TYPE_MSG) { /* The data-less messages only for now */ val |= PCIE_ATU_INHIBIT_PAYLOAD | atu->code; @@ -841,6 +782,9 @@ static void dw_pcie_link_set_max_link_width(struct dw_pcie *pci, u32 num_lanes) case 8: plc |= PORT_LINK_MODE_8_LANES; break; + case 16: + plc |= PORT_LINK_MODE_16_LANES; + break; default: dev_err(pci->dev, "num-lanes %u: invalid value\n", num_lanes); return; @@ -1045,9 +989,7 @@ static int dw_pcie_edma_irq_verify(struct dw_pcie *pci) char name[15]; int ret; - if (pci->edma.nr_irqs == 1) - return 0; - else if (pci->edma.nr_irqs > 1) + if (pci->edma.nr_irqs > 1) return pci->edma.nr_irqs != ch_cnt ? -EINVAL : 0; ret = platform_get_irq_byname_optional(pdev, "dma"); diff --git a/drivers/pci/controller/dwc/pcie-designware.h b/drivers/pci/controller/dwc/pcie-designware.h index 00f52d472dcd..e995f692a1ec 100644 --- a/drivers/pci/controller/dwc/pcie-designware.h +++ b/drivers/pci/controller/dwc/pcie-designware.h @@ -20,6 +20,7 @@ #include <linux/irq.h> #include <linux/msi.h> #include <linux/pci.h> +#include <linux/pci-ecam.h> #include <linux/reset.h> #include <linux/pci-epc.h> @@ -90,6 +91,7 @@ #define PORT_LINK_MODE_2_LANES PORT_LINK_MODE(0x3) #define PORT_LINK_MODE_4_LANES PORT_LINK_MODE(0x7) #define PORT_LINK_MODE_8_LANES PORT_LINK_MODE(0xf) +#define PORT_LINK_MODE_16_LANES PORT_LINK_MODE(0x1f) #define PCIE_PORT_LANE_SKEW 0x714 #define PORT_LANE_SKEW_INSERT_MASK GENMASK(23, 0) @@ -123,7 +125,6 @@ #define GEN3_RELATED_OFF_GEN3_EQ_DISABLE BIT(16) #define GEN3_RELATED_OFF_RATE_SHADOW_SEL_SHIFT 24 #define GEN3_RELATED_OFF_RATE_SHADOW_SEL_MASK GENMASK(25, 24) -#define GEN3_RELATED_OFF_RATE_SHADOW_SEL_16_0GT 0x1 #define GEN3_EQ_CONTROL_OFF 0x8A8 #define GEN3_EQ_CONTROL_OFF_FB_MODE GENMASK(3, 0) @@ -134,8 +135,8 @@ #define GEN3_EQ_FB_MODE_DIR_CHANGE_OFF 0x8AC #define GEN3_EQ_FMDC_T_MIN_PHASE23 GENMASK(4, 0) #define GEN3_EQ_FMDC_N_EVALS GENMASK(9, 5) -#define GEN3_EQ_FMDC_MAX_PRE_CUSROR_DELTA GENMASK(13, 10) -#define GEN3_EQ_FMDC_MAX_POST_CUSROR_DELTA GENMASK(17, 14) +#define GEN3_EQ_FMDC_MAX_PRE_CURSOR_DELTA GENMASK(13, 10) +#define GEN3_EQ_FMDC_MAX_POST_CURSOR_DELTA GENMASK(17, 14) #define PCIE_PORT_MULTI_LANE_CTRL 0x8C0 #define PORT_MLTI_UPCFG_SUPPORT BIT(7) @@ -169,6 +170,7 @@ #define PCIE_ATU_REGION_CTRL2 0x004 #define PCIE_ATU_ENABLE BIT(31) #define PCIE_ATU_BAR_MODE_ENABLE BIT(30) +#define PCIE_ATU_CFG_SHIFT_MODE_ENABLE BIT(28) #define PCIE_ATU_INHIBIT_PAYLOAD BIT(22) #define PCIE_ATU_FUNC_NUM_MATCH_EN BIT(19) #define PCIE_ATU_LOWER_BASE 0x008 @@ -387,6 +389,7 @@ struct dw_pcie_ob_atu_cfg { u8 func_no; u8 code; u8 routing; + u32 ctrl2; u64 parent_bus_addr; u64 pci_addr; u64 size; @@ -425,6 +428,9 @@ struct dw_pcie_rp { struct resource *msg_res; bool use_linkup_irq; struct pci_eq_presets presets; + struct pci_config_window *cfg; + bool ecam_enabled; + bool native_ecam; }; struct dw_pcie_ep_ops { @@ -492,6 +498,7 @@ struct dw_pcie { resource_size_t dbi_phys_addr; void __iomem *dbi_base2; void __iomem *atu_base; + void __iomem *elbi_base; resource_size_t atu_phys_addr; size_t atu_size; resource_size_t parent_bus_offset; @@ -609,6 +616,27 @@ static inline void dw_pcie_writel_dbi2(struct dw_pcie *pci, u32 reg, u32 val) dw_pcie_write_dbi2(pci, reg, 0x4, val); } +static inline int dw_pcie_read_cfg_byte(struct dw_pcie *pci, int where, + u8 *val) +{ + *val = dw_pcie_readb_dbi(pci, where); + return PCIBIOS_SUCCESSFUL; +} + +static inline int dw_pcie_read_cfg_word(struct dw_pcie *pci, int where, + u16 *val) +{ + *val = dw_pcie_readw_dbi(pci, where); + return PCIBIOS_SUCCESSFUL; +} + +static inline int dw_pcie_read_cfg_dword(struct dw_pcie *pci, int where, + u32 *val) +{ + *val = dw_pcie_readl_dbi(pci, where); + return PCIBIOS_SUCCESSFUL; +} + static inline unsigned int dw_pcie_ep_get_dbi_offset(struct dw_pcie_ep *ep, u8 func_no) { @@ -674,6 +702,27 @@ static inline u8 dw_pcie_ep_readb_dbi(struct dw_pcie_ep *ep, u8 func_no, return dw_pcie_ep_read_dbi(ep, func_no, reg, 0x1); } +static inline int dw_pcie_ep_read_cfg_byte(struct dw_pcie_ep *ep, u8 func_no, + int where, u8 *val) +{ + *val = dw_pcie_ep_readb_dbi(ep, func_no, where); + return PCIBIOS_SUCCESSFUL; +} + +static inline int dw_pcie_ep_read_cfg_word(struct dw_pcie_ep *ep, u8 func_no, + int where, u16 *val) +{ + *val = dw_pcie_ep_readw_dbi(ep, func_no, where); + return PCIBIOS_SUCCESSFUL; +} + +static inline int dw_pcie_ep_read_cfg_dword(struct dw_pcie_ep *ep, u8 func_no, + int where, u32 *val) +{ + *val = dw_pcie_ep_readl_dbi(ep, func_no, where); + return PCIBIOS_SUCCESSFUL; +} + static inline unsigned int dw_pcie_ep_get_dbi2_offset(struct dw_pcie_ep *ep, u8 func_no) { diff --git a/drivers/pci/controller/dwc/pcie-dw-rockchip.c b/drivers/pci/controller/dwc/pcie-dw-rockchip.c index 5d7f6f544942..3e2752c7dd09 100644 --- a/drivers/pci/controller/dwc/pcie-dw-rockchip.c +++ b/drivers/pci/controller/dwc/pcie-dw-rockchip.c @@ -331,7 +331,6 @@ static const struct pci_epc_features rockchip_pcie_epc_features_rk3568 = { .linkup_notifier = true, .msi_capable = true, .msix_capable = true, - .intx_capable = false, .align = SZ_64K, .bar[BAR_0] = { .type = BAR_RESIZABLE, }, .bar[BAR_1] = { .type = BAR_RESIZABLE, }, @@ -352,7 +351,6 @@ static const struct pci_epc_features rockchip_pcie_epc_features_rk3588 = { .linkup_notifier = true, .msi_capable = true, .msix_capable = true, - .intx_capable = false, .align = SZ_64K, .bar[BAR_0] = { .type = BAR_RESIZABLE, }, .bar[BAR_1] = { .type = BAR_RESIZABLE, }, diff --git a/drivers/pci/controller/dwc/pcie-keembay.c b/drivers/pci/controller/dwc/pcie-keembay.c index 67dd3337b447..60e74ac782af 100644 --- a/drivers/pci/controller/dwc/pcie-keembay.c +++ b/drivers/pci/controller/dwc/pcie-keembay.c @@ -309,7 +309,6 @@ static int keembay_pcie_ep_raise_irq(struct dw_pcie_ep *ep, u8 func_no, } static const struct pci_epc_features keembay_pcie_epc_features = { - .linkup_notifier = false, .msi_capable = true, .msix_capable = true, .bar[BAR_0] = { .only_64bit = true, }, diff --git a/drivers/pci/controller/dwc/pcie-qcom-common.c b/drivers/pci/controller/dwc/pcie-qcom-common.c index 3aad19b56da8..01c5387e53bf 100644 --- a/drivers/pci/controller/dwc/pcie-qcom-common.c +++ b/drivers/pci/controller/dwc/pcie-qcom-common.c @@ -8,9 +8,11 @@ #include "pcie-designware.h" #include "pcie-qcom-common.h" -void qcom_pcie_common_set_16gt_equalization(struct dw_pcie *pci) +void qcom_pcie_common_set_equalization(struct dw_pcie *pci) { + struct device *dev = pci->dev; u32 reg; + u16 speed; /* * GEN3_RELATED_OFF register is repurposed to apply equalization @@ -19,32 +21,40 @@ void qcom_pcie_common_set_16gt_equalization(struct dw_pcie *pci) * determines the data rate for which these equalization settings are * applied. */ - reg = dw_pcie_readl_dbi(pci, GEN3_RELATED_OFF); - reg &= ~GEN3_RELATED_OFF_GEN3_ZRXDC_NONCOMPL; - reg &= ~GEN3_RELATED_OFF_RATE_SHADOW_SEL_MASK; - reg |= FIELD_PREP(GEN3_RELATED_OFF_RATE_SHADOW_SEL_MASK, - GEN3_RELATED_OFF_RATE_SHADOW_SEL_16_0GT); - dw_pcie_writel_dbi(pci, GEN3_RELATED_OFF, reg); - reg = dw_pcie_readl_dbi(pci, GEN3_EQ_FB_MODE_DIR_CHANGE_OFF); - reg &= ~(GEN3_EQ_FMDC_T_MIN_PHASE23 | - GEN3_EQ_FMDC_N_EVALS | - GEN3_EQ_FMDC_MAX_PRE_CUSROR_DELTA | - GEN3_EQ_FMDC_MAX_POST_CUSROR_DELTA); - reg |= FIELD_PREP(GEN3_EQ_FMDC_T_MIN_PHASE23, 0x1) | - FIELD_PREP(GEN3_EQ_FMDC_N_EVALS, 0xd) | - FIELD_PREP(GEN3_EQ_FMDC_MAX_PRE_CUSROR_DELTA, 0x5) | - FIELD_PREP(GEN3_EQ_FMDC_MAX_POST_CUSROR_DELTA, 0x5); - dw_pcie_writel_dbi(pci, GEN3_EQ_FB_MODE_DIR_CHANGE_OFF, reg); + for (speed = PCIE_SPEED_8_0GT; speed <= pcie_link_speed[pci->max_link_speed]; speed++) { + if (speed > PCIE_SPEED_32_0GT) { + dev_warn(dev, "Skipped equalization settings for unsupported data rate\n"); + break; + } - reg = dw_pcie_readl_dbi(pci, GEN3_EQ_CONTROL_OFF); - reg &= ~(GEN3_EQ_CONTROL_OFF_FB_MODE | - GEN3_EQ_CONTROL_OFF_PHASE23_EXIT_MODE | - GEN3_EQ_CONTROL_OFF_FOM_INC_INITIAL_EVAL | - GEN3_EQ_CONTROL_OFF_PSET_REQ_VEC); - dw_pcie_writel_dbi(pci, GEN3_EQ_CONTROL_OFF, reg); + reg = dw_pcie_readl_dbi(pci, GEN3_RELATED_OFF); + reg &= ~GEN3_RELATED_OFF_GEN3_ZRXDC_NONCOMPL; + reg &= ~GEN3_RELATED_OFF_RATE_SHADOW_SEL_MASK; + reg |= FIELD_PREP(GEN3_RELATED_OFF_RATE_SHADOW_SEL_MASK, + speed - PCIE_SPEED_8_0GT); + dw_pcie_writel_dbi(pci, GEN3_RELATED_OFF, reg); + + reg = dw_pcie_readl_dbi(pci, GEN3_EQ_FB_MODE_DIR_CHANGE_OFF); + reg &= ~(GEN3_EQ_FMDC_T_MIN_PHASE23 | + GEN3_EQ_FMDC_N_EVALS | + GEN3_EQ_FMDC_MAX_PRE_CURSOR_DELTA | + GEN3_EQ_FMDC_MAX_POST_CURSOR_DELTA); + reg |= FIELD_PREP(GEN3_EQ_FMDC_T_MIN_PHASE23, 0x1) | + FIELD_PREP(GEN3_EQ_FMDC_N_EVALS, 0xd) | + FIELD_PREP(GEN3_EQ_FMDC_MAX_PRE_CURSOR_DELTA, 0x5) | + FIELD_PREP(GEN3_EQ_FMDC_MAX_POST_CURSOR_DELTA, 0x5); + dw_pcie_writel_dbi(pci, GEN3_EQ_FB_MODE_DIR_CHANGE_OFF, reg); + + reg = dw_pcie_readl_dbi(pci, GEN3_EQ_CONTROL_OFF); + reg &= ~(GEN3_EQ_CONTROL_OFF_FB_MODE | + GEN3_EQ_CONTROL_OFF_PHASE23_EXIT_MODE | + GEN3_EQ_CONTROL_OFF_FOM_INC_INITIAL_EVAL | + GEN3_EQ_CONTROL_OFF_PSET_REQ_VEC); + dw_pcie_writel_dbi(pci, GEN3_EQ_CONTROL_OFF, reg); + } } -EXPORT_SYMBOL_GPL(qcom_pcie_common_set_16gt_equalization); +EXPORT_SYMBOL_GPL(qcom_pcie_common_set_equalization); void qcom_pcie_common_set_16gt_lane_margining(struct dw_pcie *pci) { diff --git a/drivers/pci/controller/dwc/pcie-qcom-common.h b/drivers/pci/controller/dwc/pcie-qcom-common.h index 7d88d29e4766..7f5ca2fd9a72 100644 --- a/drivers/pci/controller/dwc/pcie-qcom-common.h +++ b/drivers/pci/controller/dwc/pcie-qcom-common.h @@ -8,7 +8,7 @@ struct dw_pcie; -void qcom_pcie_common_set_16gt_equalization(struct dw_pcie *pci); +void qcom_pcie_common_set_equalization(struct dw_pcie *pci); void qcom_pcie_common_set_16gt_lane_margining(struct dw_pcie *pci); #endif diff --git a/drivers/pci/controller/dwc/pcie-qcom-ep.c b/drivers/pci/controller/dwc/pcie-qcom-ep.c index bf7c6ac0f3e3..f1bc0ac81a92 100644 --- a/drivers/pci/controller/dwc/pcie-qcom-ep.c +++ b/drivers/pci/controller/dwc/pcie-qcom-ep.c @@ -179,7 +179,6 @@ struct qcom_pcie_ep_cfg { * struct qcom_pcie_ep - Qualcomm PCIe Endpoint Controller * @pci: Designware PCIe controller struct * @parf: Qualcomm PCIe specific PARF register base - * @elbi: Designware PCIe specific ELBI register base * @mmio: MMIO register base * @perst_map: PERST regmap * @mmio_res: MMIO region resource @@ -202,7 +201,6 @@ struct qcom_pcie_ep { struct dw_pcie pci; void __iomem *parf; - void __iomem *elbi; void __iomem *mmio; struct regmap *perst_map; struct resource *mmio_res; @@ -267,10 +265,9 @@ static void qcom_pcie_ep_configure_tcsr(struct qcom_pcie_ep *pcie_ep) static bool qcom_pcie_dw_link_up(struct dw_pcie *pci) { - struct qcom_pcie_ep *pcie_ep = to_pcie_ep(pci); u32 reg; - reg = readl_relaxed(pcie_ep->elbi + ELBI_SYS_STTS); + reg = readl_relaxed(pci->elbi_base + ELBI_SYS_STTS); return reg & XMLH_LINK_UP; } @@ -294,16 +291,15 @@ static void qcom_pcie_dw_stop_link(struct dw_pcie *pci) static void qcom_pcie_dw_write_dbi2(struct dw_pcie *pci, void __iomem *base, u32 reg, size_t size, u32 val) { - struct qcom_pcie_ep *pcie_ep = to_pcie_ep(pci); int ret; - writel(1, pcie_ep->elbi + ELBI_CS2_ENABLE); + writel(1, pci->elbi_base + ELBI_CS2_ENABLE); ret = dw_pcie_write(pci->dbi_base2 + reg, size, val); if (ret) dev_err(pci->dev, "Failed to write DBI2 register (0x%x): %d\n", reg, ret); - writel(0, pcie_ep->elbi + ELBI_CS2_ENABLE); + writel(0, pci->elbi_base + ELBI_CS2_ENABLE); } static void qcom_pcie_ep_icc_update(struct qcom_pcie_ep *pcie_ep) @@ -511,10 +507,10 @@ static int qcom_pcie_perst_deassert(struct dw_pcie *pci) goto err_disable_resources; } - if (pcie_link_speed[pci->max_link_speed] == PCIE_SPEED_16_0GT) { - qcom_pcie_common_set_16gt_equalization(pci); + qcom_pcie_common_set_equalization(pci); + + if (pcie_link_speed[pci->max_link_speed] == PCIE_SPEED_16_0GT) qcom_pcie_common_set_16gt_lane_margining(pci); - } /* * The physical address of the MMIO region which is exposed as the BAR @@ -583,11 +579,6 @@ static int qcom_pcie_ep_get_io_resources(struct platform_device *pdev, return PTR_ERR(pci->dbi_base); pci->dbi_base2 = pci->dbi_base; - res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "elbi"); - pcie_ep->elbi = devm_pci_remap_cfg_resource(dev, res); - if (IS_ERR(pcie_ep->elbi)) - return PTR_ERR(pcie_ep->elbi); - pcie_ep->mmio_res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "mmio"); if (!pcie_ep->mmio_res) { @@ -831,7 +822,6 @@ static void qcom_pcie_ep_init_debugfs(struct qcom_pcie_ep *pcie_ep) static const struct pci_epc_features qcom_pcie_epc_features = { .linkup_notifier = true, .msi_capable = true, - .msix_capable = false, .align = SZ_4K, .bar[BAR_0] = { .only_64bit = true, }, .bar[BAR_1] = { .type = BAR_RESERVED, }, @@ -874,7 +864,6 @@ static int qcom_pcie_ep_probe(struct platform_device *pdev) pcie_ep->pci.dev = dev; pcie_ep->pci.ops = &pci_ops; pcie_ep->pci.ep.ops = &pci_ep_ops; - pcie_ep->pci.edma.nr_irqs = 1; pcie_ep->cfg = of_device_get_match_data(dev); if (pcie_ep->cfg && pcie_ep->cfg->hdma_support) { diff --git a/drivers/pci/controller/dwc/pcie-qcom.c b/drivers/pci/controller/dwc/pcie-qcom.c index 294babe1816e..805edbbfe7eb 100644 --- a/drivers/pci/controller/dwc/pcie-qcom.c +++ b/drivers/pci/controller/dwc/pcie-qcom.c @@ -55,6 +55,7 @@ #define PARF_AXI_MSTR_WR_ADDR_HALT_V2 0x1a8 #define PARF_Q2A_FLUSH 0x1ac #define PARF_LTSSM 0x1b0 +#define PARF_SLV_DBI_ELBI 0x1b4 #define PARF_INT_ALL_STATUS 0x224 #define PARF_INT_ALL_CLEAR 0x228 #define PARF_INT_ALL_MASK 0x22c @@ -64,6 +65,16 @@ #define PARF_DBI_BASE_ADDR_V2_HI 0x354 #define PARF_SLV_ADDR_SPACE_SIZE_V2 0x358 #define PARF_SLV_ADDR_SPACE_SIZE_V2_HI 0x35c +#define PARF_BLOCK_SLV_AXI_WR_BASE 0x360 +#define PARF_BLOCK_SLV_AXI_WR_BASE_HI 0x364 +#define PARF_BLOCK_SLV_AXI_WR_LIMIT 0x368 +#define PARF_BLOCK_SLV_AXI_WR_LIMIT_HI 0x36c +#define PARF_BLOCK_SLV_AXI_RD_BASE 0x370 +#define PARF_BLOCK_SLV_AXI_RD_BASE_HI 0x374 +#define PARF_BLOCK_SLV_AXI_RD_LIMIT 0x378 +#define PARF_BLOCK_SLV_AXI_RD_LIMIT_HI 0x37c +#define PARF_ECAM_BASE 0x380 +#define PARF_ECAM_BASE_HI 0x384 #define PARF_NO_SNOOP_OVERRIDE 0x3d4 #define PARF_ATU_BASE_ADDR 0x634 #define PARF_ATU_BASE_ADDR_HI 0x638 @@ -87,6 +98,7 @@ /* PARF_SYS_CTRL register fields */ #define MAC_PHY_POWERDOWN_IN_P2_D_MUX_EN BIT(29) +#define PCIE_ECAM_BLOCKER_EN BIT(26) #define MST_WAKEUP_EN BIT(13) #define SLV_WAKEUP_EN BIT(12) #define MSTR_ACLK_CGC_DIS BIT(10) @@ -134,6 +146,9 @@ /* PARF_LTSSM register fields */ #define LTSSM_EN BIT(8) +/* PARF_SLV_DBI_ELBI */ +#define SLV_DBI_ELBI_ADDR_BASE GENMASK(11, 0) + /* PARF_INT_ALL_{STATUS/CLEAR/MASK} register fields */ #define PARF_INT_ALL_LINK_UP BIT(13) #define PARF_INT_MSI_DEV_0_7 GENMASK(30, 23) @@ -247,7 +262,6 @@ struct qcom_pcie_ops { int (*get_resources)(struct qcom_pcie *pcie); int (*init)(struct qcom_pcie *pcie); int (*post_init)(struct qcom_pcie *pcie); - void (*host_post_init)(struct qcom_pcie *pcie); void (*deinit)(struct qcom_pcie *pcie); void (*ltssm_enable)(struct qcom_pcie *pcie); int (*config_sid)(struct qcom_pcie *pcie); @@ -276,11 +290,8 @@ struct qcom_pcie_port { struct qcom_pcie { struct dw_pcie *pci; void __iomem *parf; /* DT parf */ - void __iomem *elbi; /* DT elbi */ void __iomem *mhi; union qcom_pcie_resources res; - struct phy *phy; - struct gpio_desc *reset; struct icc_path *icc_mem; struct icc_path *icc_cpu; const struct qcom_pcie_cfg *cfg; @@ -297,11 +308,8 @@ static void qcom_perst_assert(struct qcom_pcie *pcie, bool assert) struct qcom_pcie_port *port; int val = assert ? 1 : 0; - if (list_empty(&pcie->ports)) - gpiod_set_value_cansleep(pcie->reset, val); - else - list_for_each_entry(port, &pcie->ports, list) - gpiod_set_value_cansleep(port->reset, val); + list_for_each_entry(port, &pcie->ports, list) + gpiod_set_value_cansleep(port->reset, val); usleep_range(PERST_DELAY_US, PERST_DELAY_US + 500); } @@ -318,14 +326,55 @@ static void qcom_ep_reset_deassert(struct qcom_pcie *pcie) qcom_perst_assert(pcie, false); } +static void qcom_pci_config_ecam(struct dw_pcie_rp *pp) +{ + struct dw_pcie *pci = to_dw_pcie_from_pp(pp); + struct qcom_pcie *pcie = to_qcom_pcie(pci); + u64 addr, addr_end; + u32 val; + + writel_relaxed(lower_32_bits(pci->dbi_phys_addr), pcie->parf + PARF_ECAM_BASE); + writel_relaxed(upper_32_bits(pci->dbi_phys_addr), pcie->parf + PARF_ECAM_BASE_HI); + + /* + * The only device on the root bus is a single Root Port. If we try to + * access any devices other than Device/Function 00.0 on Bus 0, the TLP + * will go outside of the controller to the PCI bus. But with CFG Shift + * Feature (ECAM) enabled in iATU, there is no guarantee that the + * response is going to be all F's. Hence, to make sure that the + * requester gets all F's response for accesses other than the Root + * Port, configure iATU to block the transactions starting from + * function 1 of the root bus to the end of the root bus (i.e., from + * dbi_base + 4KB to dbi_base + 1MB). + */ + addr = pci->dbi_phys_addr + SZ_4K; + writel_relaxed(lower_32_bits(addr), pcie->parf + PARF_BLOCK_SLV_AXI_WR_BASE); + writel_relaxed(upper_32_bits(addr), pcie->parf + PARF_BLOCK_SLV_AXI_WR_BASE_HI); + + writel_relaxed(lower_32_bits(addr), pcie->parf + PARF_BLOCK_SLV_AXI_RD_BASE); + writel_relaxed(upper_32_bits(addr), pcie->parf + PARF_BLOCK_SLV_AXI_RD_BASE_HI); + + addr_end = pci->dbi_phys_addr + SZ_1M - 1; + + writel_relaxed(lower_32_bits(addr_end), pcie->parf + PARF_BLOCK_SLV_AXI_WR_LIMIT); + writel_relaxed(upper_32_bits(addr_end), pcie->parf + PARF_BLOCK_SLV_AXI_WR_LIMIT_HI); + + writel_relaxed(lower_32_bits(addr_end), pcie->parf + PARF_BLOCK_SLV_AXI_RD_LIMIT); + writel_relaxed(upper_32_bits(addr_end), pcie->parf + PARF_BLOCK_SLV_AXI_RD_LIMIT_HI); + + val = readl_relaxed(pcie->parf + PARF_SYS_CTRL); + val |= PCIE_ECAM_BLOCKER_EN; + writel_relaxed(val, pcie->parf + PARF_SYS_CTRL); +} + static int qcom_pcie_start_link(struct dw_pcie *pci) { struct qcom_pcie *pcie = to_qcom_pcie(pci); - if (pcie_link_speed[pci->max_link_speed] == PCIE_SPEED_16_0GT) { - qcom_pcie_common_set_16gt_equalization(pci); + qcom_pcie_common_set_equalization(pci); + + if (pcie_link_speed[pci->max_link_speed] == PCIE_SPEED_16_0GT) qcom_pcie_common_set_16gt_lane_margining(pci); - } /* Enable Link Training state machine */ if (pcie->cfg->ops->ltssm_enable) @@ -414,12 +463,17 @@ static void qcom_pcie_configure_dbi_atu_base(struct qcom_pcie *pcie) static void qcom_pcie_2_1_0_ltssm_enable(struct qcom_pcie *pcie) { + struct dw_pcie *pci = pcie->pci; u32 val; + if (!pci->elbi_base) { + dev_err(pci->dev, "ELBI is not present\n"); + return; + } /* enable link training */ - val = readl(pcie->elbi + ELBI_SYS_CTRL); + val = readl(pci->elbi_base + ELBI_SYS_CTRL); val |= ELBI_SYS_CTRL_LT_ENABLE; - writel(val, pcie->elbi + ELBI_SYS_CTRL); + writel(val, pci->elbi_base + ELBI_SYS_CTRL); } static int qcom_pcie_get_resources_2_1_0(struct qcom_pcie *pcie) @@ -1040,25 +1094,6 @@ static int qcom_pcie_post_init_2_7_0(struct qcom_pcie *pcie) return 0; } -static int qcom_pcie_enable_aspm(struct pci_dev *pdev, void *userdata) -{ - /* - * Downstream devices need to be in D0 state before enabling PCI PM - * substates. - */ - pci_set_power_state_locked(pdev, PCI_D0); - pci_enable_link_state_locked(pdev, PCIE_LINK_STATE_ALL); - - return 0; -} - -static void qcom_pcie_host_post_init_2_7_0(struct qcom_pcie *pcie) -{ - struct dw_pcie_rp *pp = &pcie->pci->pp; - - pci_walk_bus(pp->bridge->bus, qcom_pcie_enable_aspm, NULL); -} - static void qcom_pcie_deinit_2_7_0(struct qcom_pcie *pcie) { struct qcom_pcie_resources_2_7_0 *res = &pcie->res.v2_7_0; @@ -1253,63 +1288,39 @@ static bool qcom_pcie_link_up(struct dw_pcie *pci) return val & PCI_EXP_LNKSTA_DLLLA; } -static void qcom_pcie_phy_exit(struct qcom_pcie *pcie) -{ - struct qcom_pcie_port *port; - - if (list_empty(&pcie->ports)) - phy_exit(pcie->phy); - else - list_for_each_entry(port, &pcie->ports, list) - phy_exit(port->phy); -} - static void qcom_pcie_phy_power_off(struct qcom_pcie *pcie) { struct qcom_pcie_port *port; - if (list_empty(&pcie->ports)) { - phy_power_off(pcie->phy); - } else { - list_for_each_entry(port, &pcie->ports, list) - phy_power_off(port->phy); - } + list_for_each_entry(port, &pcie->ports, list) + phy_power_off(port->phy); } static int qcom_pcie_phy_power_on(struct qcom_pcie *pcie) { struct qcom_pcie_port *port; - int ret = 0; + int ret; - if (list_empty(&pcie->ports)) { - ret = phy_set_mode_ext(pcie->phy, PHY_MODE_PCIE, PHY_MODE_PCIE_RC); + list_for_each_entry(port, &pcie->ports, list) { + ret = phy_set_mode_ext(port->phy, PHY_MODE_PCIE, PHY_MODE_PCIE_RC); if (ret) return ret; - ret = phy_power_on(pcie->phy); - if (ret) + ret = phy_power_on(port->phy); + if (ret) { + qcom_pcie_phy_power_off(pcie); return ret; - } else { - list_for_each_entry(port, &pcie->ports, list) { - ret = phy_set_mode_ext(port->phy, PHY_MODE_PCIE, PHY_MODE_PCIE_RC); - if (ret) - return ret; - - ret = phy_power_on(port->phy); - if (ret) { - qcom_pcie_phy_power_off(pcie); - return ret; - } } } - return ret; + return 0; } static int qcom_pcie_host_init(struct dw_pcie_rp *pp) { struct dw_pcie *pci = to_dw_pcie_from_pp(pp); struct qcom_pcie *pcie = to_qcom_pcie(pci); + u16 offset; int ret; qcom_ep_reset_assert(pcie); @@ -1318,6 +1329,17 @@ static int qcom_pcie_host_init(struct dw_pcie_rp *pp) if (ret) return ret; + if (pp->ecam_enabled) { + /* + * Override ELBI when ECAM is enabled, as when ECAM is enabled, + * ELBI moves under the 'config' space. + */ + offset = FIELD_GET(SLV_DBI_ELBI_ADDR_BASE, readl(pcie->parf + PARF_SLV_DBI_ELBI)); + pci->elbi_base = pci->dbi_base + offset; + + qcom_pci_config_ecam(pp); + } + ret = qcom_pcie_phy_power_on(pcie); if (ret) goto err_deinit; @@ -1358,19 +1380,9 @@ static void qcom_pcie_host_deinit(struct dw_pcie_rp *pp) pcie->cfg->ops->deinit(pcie); } -static void qcom_pcie_host_post_init(struct dw_pcie_rp *pp) -{ - struct dw_pcie *pci = to_dw_pcie_from_pp(pp); - struct qcom_pcie *pcie = to_qcom_pcie(pci); - - if (pcie->cfg->ops->host_post_init) - pcie->cfg->ops->host_post_init(pcie); -} - static const struct dw_pcie_host_ops qcom_pcie_dw_ops = { .init = qcom_pcie_host_init, .deinit = qcom_pcie_host_deinit, - .post_init = qcom_pcie_host_post_init, }; /* Qcom IP rev.: 2.1.0 Synopsys IP rev.: 4.01a */ @@ -1432,7 +1444,6 @@ static const struct qcom_pcie_ops ops_1_9_0 = { .get_resources = qcom_pcie_get_resources_2_7_0, .init = qcom_pcie_init_2_7_0, .post_init = qcom_pcie_post_init_2_7_0, - .host_post_init = qcom_pcie_host_post_init_2_7_0, .deinit = qcom_pcie_deinit_2_7_0, .ltssm_enable = qcom_pcie_2_3_2_ltssm_enable, .config_sid = qcom_pcie_config_sid_1_9_0, @@ -1443,7 +1454,6 @@ static const struct qcom_pcie_ops ops_1_21_0 = { .get_resources = qcom_pcie_get_resources_2_7_0, .init = qcom_pcie_init_2_7_0, .post_init = qcom_pcie_post_init_2_7_0, - .host_post_init = qcom_pcie_host_post_init_2_7_0, .deinit = qcom_pcie_deinit_2_7_0, .ltssm_enable = qcom_pcie_2_3_2_ltssm_enable, }; @@ -1740,6 +1750,8 @@ static int qcom_pcie_parse_ports(struct qcom_pcie *pcie) int ret = -ENOENT; for_each_available_child_of_node_scoped(dev->of_node, of_port) { + if (!of_node_is_type(of_port, "pci")) + continue; ret = qcom_pcie_parse_port(pcie, of_port); if (ret) goto err_port_del; @@ -1748,8 +1760,10 @@ static int qcom_pcie_parse_ports(struct qcom_pcie *pcie) return ret; err_port_del: - list_for_each_entry_safe(port, tmp, &pcie->ports, list) + list_for_each_entry_safe(port, tmp, &pcie->ports, list) { + phy_exit(port->phy); list_del(&port->list); + } return ret; } @@ -1757,20 +1771,32 @@ err_port_del: static int qcom_pcie_parse_legacy_binding(struct qcom_pcie *pcie) { struct device *dev = pcie->pci->dev; + struct qcom_pcie_port *port; + struct gpio_desc *reset; + struct phy *phy; int ret; - pcie->phy = devm_phy_optional_get(dev, "pciephy"); - if (IS_ERR(pcie->phy)) - return PTR_ERR(pcie->phy); + phy = devm_phy_optional_get(dev, "pciephy"); + if (IS_ERR(phy)) + return PTR_ERR(phy); - pcie->reset = devm_gpiod_get_optional(dev, "perst", GPIOD_OUT_HIGH); - if (IS_ERR(pcie->reset)) - return PTR_ERR(pcie->reset); + reset = devm_gpiod_get_optional(dev, "perst", GPIOD_OUT_HIGH); + if (IS_ERR(reset)) + return PTR_ERR(reset); - ret = phy_init(pcie->phy); + ret = phy_init(phy); if (ret) return ret; + port = devm_kzalloc(dev, sizeof(*port), GFP_KERNEL); + if (!port) + return -ENOMEM; + + port->reset = reset; + port->phy = phy; + INIT_LIST_HEAD(&port->list); + list_add_tail(&port->list, &pcie->ports); + return 0; } @@ -1861,12 +1887,6 @@ static int qcom_pcie_probe(struct platform_device *pdev) goto err_pm_runtime_put; } - pcie->elbi = devm_platform_ioremap_resource_byname(pdev, "elbi"); - if (IS_ERR(pcie->elbi)) { - ret = PTR_ERR(pcie->elbi); - goto err_pm_runtime_put; - } - /* MHI region is optional */ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "mhi"); if (res) { @@ -1984,9 +2004,10 @@ static int qcom_pcie_probe(struct platform_device *pdev) err_host_deinit: dw_pcie_host_deinit(pp); err_phy_exit: - qcom_pcie_phy_exit(pcie); - list_for_each_entry_safe(port, tmp, &pcie->ports, list) + list_for_each_entry_safe(port, tmp, &pcie->ports, list) { + phy_exit(port->phy); list_del(&port->list); + } err_pm_runtime_put: pm_runtime_put(dev); pm_runtime_disable(dev); diff --git a/drivers/pci/controller/dwc/pcie-rcar-gen4.c b/drivers/pci/controller/dwc/pcie-rcar-gen4.c index 18055807a4f5..80778917d2dd 100644 --- a/drivers/pci/controller/dwc/pcie-rcar-gen4.c +++ b/drivers/pci/controller/dwc/pcie-rcar-gen4.c @@ -182,8 +182,17 @@ static int rcar_gen4_pcie_common_init(struct rcar_gen4_pcie *rcar) return ret; } - if (!reset_control_status(dw->core_rsts[DW_PCIE_PWR_RST].rstc)) + if (!reset_control_status(dw->core_rsts[DW_PCIE_PWR_RST].rstc)) { reset_control_assert(dw->core_rsts[DW_PCIE_PWR_RST].rstc); + /* + * R-Car V4H Reference Manual R19UH0186EJ0130 Rev.1.30 Apr. + * 21, 2025 page 585 Figure 9.3.2 Software Reset flow (B) + * indicates that for peripherals in HSC domain, after + * reset has been asserted by writing a matching reset bit + * into register SRCR, it is mandatory to wait 1ms. + */ + fsleep(1000); + } val = readl(rcar->base + PCIEMSR0); if (rcar->drvdata->mode == DW_PCIE_RC_TYPE) { @@ -204,6 +213,19 @@ static int rcar_gen4_pcie_common_init(struct rcar_gen4_pcie *rcar) if (ret) goto err_unprepare; + /* + * Assure the reset is latched and the core is ready for DBI access. + * On R-Car V4H, the PCIe reset is asynchronous and does not take + * effect immediately, but needs a short time to complete. In case + * DBI access happens in that short time, that access generates an + * SError. To make sure that condition can never happen, read back the + * state of the reset, which should turn the asynchronous reset into + * synchronous one, and wait a little over 1ms to add additional + * safety margin. + */ + reset_control_status(dw->core_rsts[DW_PCIE_PWR_RST].rstc); + fsleep(1000); + if (rcar->drvdata->additional_common_init) rcar->drvdata->additional_common_init(rcar); @@ -398,9 +420,7 @@ static int rcar_gen4_pcie_ep_raise_irq(struct dw_pcie_ep *ep, u8 func_no, } static const struct pci_epc_features rcar_gen4_pcie_epc_features = { - .linkup_notifier = false, .msi_capable = true, - .msix_capable = false, .bar[BAR_1] = { .type = BAR_RESERVED, }, .bar[BAR_3] = { .type = BAR_RESERVED, }, .bar[BAR_4] = { .type = BAR_FIXED, .fixed_size = 256 }, @@ -701,7 +721,7 @@ static int rcar_gen4_pcie_ltssm_control(struct rcar_gen4_pcie *rcar, bool enable rcar_gen4_pcie_phy_reg_update_bits(rcar, 0x148, GENMASK(23, 22), BIT(22)); rcar_gen4_pcie_phy_reg_update_bits(rcar, 0x148, GENMASK(18, 16), GENMASK(17, 16)); rcar_gen4_pcie_phy_reg_update_bits(rcar, 0x148, GENMASK(7, 6), BIT(6)); - rcar_gen4_pcie_phy_reg_update_bits(rcar, 0x148, GENMASK(2, 0), GENMASK(11, 0)); + rcar_gen4_pcie_phy_reg_update_bits(rcar, 0x148, GENMASK(2, 0), GENMASK(1, 0)); rcar_gen4_pcie_phy_reg_update_bits(rcar, 0x1d4, GENMASK(16, 15), GENMASK(16, 15)); rcar_gen4_pcie_phy_reg_update_bits(rcar, 0x514, BIT(26), BIT(26)); rcar_gen4_pcie_phy_reg_update_bits(rcar, 0x0f8, BIT(16), 0); @@ -711,7 +731,7 @@ static int rcar_gen4_pcie_ltssm_control(struct rcar_gen4_pcie *rcar, bool enable val &= ~APP_HOLD_PHY_RST; writel(val, rcar->base + PCIERSTCTRL1); - ret = readl_poll_timeout(rcar->phy_base + 0x0f8, val, !(val & BIT(18)), 100, 10000); + ret = readl_poll_timeout(rcar->phy_base + 0x0f8, val, val & BIT(18), 100, 10000); if (ret < 0) return ret; diff --git a/drivers/pci/controller/dwc/pcie-stm32-ep.c b/drivers/pci/controller/dwc/pcie-stm32-ep.c new file mode 100644 index 000000000000..3400c7cd2d88 --- /dev/null +++ b/drivers/pci/controller/dwc/pcie-stm32-ep.c @@ -0,0 +1,364 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * STMicroelectronics STM32MP25 PCIe endpoint driver. + * + * Copyright (C) 2025 STMicroelectronics + * Author: Christian Bruel <christian.bruel@foss.st.com> + */ + +#include <linux/clk.h> +#include <linux/mfd/syscon.h> +#include <linux/of_platform.h> +#include <linux/of_gpio.h> +#include <linux/phy/phy.h> +#include <linux/platform_device.h> +#include <linux/pm_runtime.h> +#include <linux/regmap.h> +#include <linux/reset.h> +#include "pcie-designware.h" +#include "pcie-stm32.h" + +struct stm32_pcie { + struct dw_pcie pci; + struct regmap *regmap; + struct reset_control *rst; + struct phy *phy; + struct clk *clk; + struct gpio_desc *perst_gpio; + unsigned int perst_irq; +}; + +static void stm32_pcie_ep_init(struct dw_pcie_ep *ep) +{ + struct dw_pcie *pci = to_dw_pcie_from_ep(ep); + enum pci_barno bar; + + for (bar = 0; bar < PCI_STD_NUM_BARS; bar++) + dw_pcie_ep_reset_bar(pci, bar); +} + +static int stm32_pcie_enable_link(struct dw_pcie *pci) +{ + struct stm32_pcie *stm32_pcie = to_stm32_pcie(pci); + + regmap_update_bits(stm32_pcie->regmap, SYSCFG_PCIECR, + STM32MP25_PCIECR_LTSSM_EN, + STM32MP25_PCIECR_LTSSM_EN); + + return dw_pcie_wait_for_link(pci); +} + +static void stm32_pcie_disable_link(struct dw_pcie *pci) +{ + struct stm32_pcie *stm32_pcie = to_stm32_pcie(pci); + + regmap_update_bits(stm32_pcie->regmap, SYSCFG_PCIECR, STM32MP25_PCIECR_LTSSM_EN, 0); +} + +static int stm32_pcie_start_link(struct dw_pcie *pci) +{ + struct stm32_pcie *stm32_pcie = to_stm32_pcie(pci); + int ret; + + dev_dbg(pci->dev, "Enable link\n"); + + ret = stm32_pcie_enable_link(pci); + if (ret) { + dev_err(pci->dev, "PCIe cannot establish link: %d\n", ret); + return ret; + } + + enable_irq(stm32_pcie->perst_irq); + + return 0; +} + +static void stm32_pcie_stop_link(struct dw_pcie *pci) +{ + struct stm32_pcie *stm32_pcie = to_stm32_pcie(pci); + + dev_dbg(pci->dev, "Disable link\n"); + + disable_irq(stm32_pcie->perst_irq); + + stm32_pcie_disable_link(pci); +} + +static int stm32_pcie_raise_irq(struct dw_pcie_ep *ep, u8 func_no, + unsigned int type, u16 interrupt_num) +{ + struct dw_pcie *pci = to_dw_pcie_from_ep(ep); + + switch (type) { + case PCI_IRQ_INTX: + return dw_pcie_ep_raise_intx_irq(ep, func_no); + case PCI_IRQ_MSI: + return dw_pcie_ep_raise_msi_irq(ep, func_no, interrupt_num); + default: + dev_err(pci->dev, "UNKNOWN IRQ type\n"); + return -EINVAL; + } +} + +static const struct pci_epc_features stm32_pcie_epc_features = { + .msi_capable = true, + .align = SZ_64K, +}; + +static const struct pci_epc_features* +stm32_pcie_get_features(struct dw_pcie_ep *ep) +{ + return &stm32_pcie_epc_features; +} + +static const struct dw_pcie_ep_ops stm32_pcie_ep_ops = { + .init = stm32_pcie_ep_init, + .raise_irq = stm32_pcie_raise_irq, + .get_features = stm32_pcie_get_features, +}; + +static const struct dw_pcie_ops dw_pcie_ops = { + .start_link = stm32_pcie_start_link, + .stop_link = stm32_pcie_stop_link, +}; + +static int stm32_pcie_enable_resources(struct stm32_pcie *stm32_pcie) +{ + int ret; + + ret = phy_init(stm32_pcie->phy); + if (ret) + return ret; + + ret = clk_prepare_enable(stm32_pcie->clk); + if (ret) + phy_exit(stm32_pcie->phy); + + return ret; +} + +static void stm32_pcie_disable_resources(struct stm32_pcie *stm32_pcie) +{ + clk_disable_unprepare(stm32_pcie->clk); + + phy_exit(stm32_pcie->phy); +} + +static void stm32_pcie_perst_assert(struct dw_pcie *pci) +{ + struct stm32_pcie *stm32_pcie = to_stm32_pcie(pci); + struct dw_pcie_ep *ep = &stm32_pcie->pci.ep; + struct device *dev = pci->dev; + + dev_dbg(dev, "PERST asserted by host\n"); + + pci_epc_deinit_notify(ep->epc); + + stm32_pcie_disable_resources(stm32_pcie); + + pm_runtime_put_sync(dev); +} + +static void stm32_pcie_perst_deassert(struct dw_pcie *pci) +{ + struct stm32_pcie *stm32_pcie = to_stm32_pcie(pci); + struct device *dev = pci->dev; + struct dw_pcie_ep *ep = &pci->ep; + int ret; + + dev_dbg(dev, "PERST de-asserted by host\n"); + + ret = pm_runtime_resume_and_get(dev); + if (ret < 0) { + dev_err(dev, "Failed to resume runtime PM: %d\n", ret); + return; + } + + ret = stm32_pcie_enable_resources(stm32_pcie); + if (ret) { + dev_err(dev, "Failed to enable resources: %d\n", ret); + goto err_pm_put_sync; + } + + /* + * Reprogram the configuration space registers here because the DBI + * registers were reset by the PHY RCC during phy_init(). + */ + ret = dw_pcie_ep_init_registers(ep); + if (ret) { + dev_err(dev, "Failed to complete initialization: %d\n", ret); + goto err_disable_resources; + } + + pci_epc_init_notify(ep->epc); + + return; + +err_disable_resources: + stm32_pcie_disable_resources(stm32_pcie); + +err_pm_put_sync: + pm_runtime_put_sync(dev); +} + +static irqreturn_t stm32_pcie_ep_perst_irq_thread(int irq, void *data) +{ + struct stm32_pcie *stm32_pcie = data; + struct dw_pcie *pci = &stm32_pcie->pci; + u32 perst; + + perst = gpiod_get_value(stm32_pcie->perst_gpio); + if (perst) + stm32_pcie_perst_assert(pci); + else + stm32_pcie_perst_deassert(pci); + + irq_set_irq_type(gpiod_to_irq(stm32_pcie->perst_gpio), + (perst ? IRQF_TRIGGER_HIGH : IRQF_TRIGGER_LOW)); + + return IRQ_HANDLED; +} + +static int stm32_add_pcie_ep(struct stm32_pcie *stm32_pcie, + struct platform_device *pdev) +{ + struct dw_pcie_ep *ep = &stm32_pcie->pci.ep; + struct device *dev = &pdev->dev; + int ret; + + ret = regmap_update_bits(stm32_pcie->regmap, SYSCFG_PCIECR, + STM32MP25_PCIECR_TYPE_MASK, + STM32MP25_PCIECR_EP); + if (ret) + return ret; + + reset_control_assert(stm32_pcie->rst); + reset_control_deassert(stm32_pcie->rst); + + ep->ops = &stm32_pcie_ep_ops; + + ret = dw_pcie_ep_init(ep); + if (ret) { + dev_err(dev, "Failed to initialize ep: %d\n", ret); + return ret; + } + + ret = stm32_pcie_enable_resources(stm32_pcie); + if (ret) { + dev_err(dev, "Failed to enable resources: %d\n", ret); + dw_pcie_ep_deinit(ep); + return ret; + } + + return 0; +} + +static int stm32_pcie_probe(struct platform_device *pdev) +{ + struct stm32_pcie *stm32_pcie; + struct device *dev = &pdev->dev; + int ret; + + stm32_pcie = devm_kzalloc(dev, sizeof(*stm32_pcie), GFP_KERNEL); + if (!stm32_pcie) + return -ENOMEM; + + stm32_pcie->pci.dev = dev; + stm32_pcie->pci.ops = &dw_pcie_ops; + + stm32_pcie->regmap = syscon_regmap_lookup_by_compatible("st,stm32mp25-syscfg"); + if (IS_ERR(stm32_pcie->regmap)) + return dev_err_probe(dev, PTR_ERR(stm32_pcie->regmap), + "No syscfg specified\n"); + + stm32_pcie->phy = devm_phy_get(dev, NULL); + if (IS_ERR(stm32_pcie->phy)) + return dev_err_probe(dev, PTR_ERR(stm32_pcie->phy), + "failed to get pcie-phy\n"); + + stm32_pcie->clk = devm_clk_get(dev, NULL); + if (IS_ERR(stm32_pcie->clk)) + return dev_err_probe(dev, PTR_ERR(stm32_pcie->clk), + "Failed to get PCIe clock source\n"); + + stm32_pcie->rst = devm_reset_control_get_exclusive(dev, NULL); + if (IS_ERR(stm32_pcie->rst)) + return dev_err_probe(dev, PTR_ERR(stm32_pcie->rst), + "Failed to get PCIe reset\n"); + + stm32_pcie->perst_gpio = devm_gpiod_get(dev, "reset", GPIOD_IN); + if (IS_ERR(stm32_pcie->perst_gpio)) + return dev_err_probe(dev, PTR_ERR(stm32_pcie->perst_gpio), + "Failed to get reset GPIO\n"); + + ret = phy_set_mode(stm32_pcie->phy, PHY_MODE_PCIE); + if (ret) + return ret; + + platform_set_drvdata(pdev, stm32_pcie); + + pm_runtime_get_noresume(dev); + + ret = devm_pm_runtime_enable(dev); + if (ret < 0) { + pm_runtime_put_noidle(&pdev->dev); + return dev_err_probe(dev, ret, "Failed to enable runtime PM\n"); + } + + stm32_pcie->perst_irq = gpiod_to_irq(stm32_pcie->perst_gpio); + + /* Will be enabled in start_link when device is initialized. */ + irq_set_status_flags(stm32_pcie->perst_irq, IRQ_NOAUTOEN); + + ret = devm_request_threaded_irq(dev, stm32_pcie->perst_irq, NULL, + stm32_pcie_ep_perst_irq_thread, + IRQF_TRIGGER_HIGH | IRQF_ONESHOT, + "perst_irq", stm32_pcie); + if (ret) { + pm_runtime_put_noidle(&pdev->dev); + return dev_err_probe(dev, ret, "Failed to request PERST IRQ\n"); + } + + ret = stm32_add_pcie_ep(stm32_pcie, pdev); + if (ret) + pm_runtime_put_noidle(&pdev->dev); + + return ret; +} + +static void stm32_pcie_remove(struct platform_device *pdev) +{ + struct stm32_pcie *stm32_pcie = platform_get_drvdata(pdev); + struct dw_pcie *pci = &stm32_pcie->pci; + struct dw_pcie_ep *ep = &pci->ep; + + dw_pcie_stop_link(pci); + + pci_epc_deinit_notify(ep->epc); + dw_pcie_ep_deinit(ep); + + stm32_pcie_disable_resources(stm32_pcie); + + pm_runtime_put_sync(&pdev->dev); +} + +static const struct of_device_id stm32_pcie_ep_of_match[] = { + { .compatible = "st,stm32mp25-pcie-ep" }, + {}, +}; + +static struct platform_driver stm32_pcie_ep_driver = { + .probe = stm32_pcie_probe, + .remove = stm32_pcie_remove, + .driver = { + .name = "stm32-ep-pcie", + .of_match_table = stm32_pcie_ep_of_match, + }, +}; + +module_platform_driver(stm32_pcie_ep_driver); + +MODULE_AUTHOR("Christian Bruel <christian.bruel@foss.st.com>"); +MODULE_DESCRIPTION("STM32MP25 PCIe Endpoint Controller driver"); +MODULE_LICENSE("GPL"); +MODULE_DEVICE_TABLE(of, stm32_pcie_ep_of_match); diff --git a/drivers/pci/controller/dwc/pcie-stm32.c b/drivers/pci/controller/dwc/pcie-stm32.c new file mode 100644 index 000000000000..96a5fb893af4 --- /dev/null +++ b/drivers/pci/controller/dwc/pcie-stm32.c @@ -0,0 +1,358 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * STMicroelectronics STM32MP25 PCIe root complex driver. + * + * Copyright (C) 2025 STMicroelectronics + * Author: Christian Bruel <christian.bruel@foss.st.com> + */ + +#include <linux/clk.h> +#include <linux/mfd/syscon.h> +#include <linux/of_platform.h> +#include <linux/phy/phy.h> +#include <linux/pinctrl/consumer.h> +#include <linux/platform_device.h> +#include <linux/pm_runtime.h> +#include <linux/pm_wakeirq.h> +#include <linux/regmap.h> +#include <linux/reset.h> +#include "pcie-designware.h" +#include "pcie-stm32.h" +#include "../../pci.h" + +struct stm32_pcie { + struct dw_pcie pci; + struct regmap *regmap; + struct reset_control *rst; + struct phy *phy; + struct clk *clk; + struct gpio_desc *perst_gpio; + struct gpio_desc *wake_gpio; +}; + +static void stm32_pcie_deassert_perst(struct stm32_pcie *stm32_pcie) +{ + if (stm32_pcie->perst_gpio) { + msleep(PCIE_T_PVPERL_MS); + gpiod_set_value(stm32_pcie->perst_gpio, 0); + } + + msleep(PCIE_RESET_CONFIG_WAIT_MS); +} + +static void stm32_pcie_assert_perst(struct stm32_pcie *stm32_pcie) +{ + gpiod_set_value(stm32_pcie->perst_gpio, 1); +} + +static int stm32_pcie_start_link(struct dw_pcie *pci) +{ + struct stm32_pcie *stm32_pcie = to_stm32_pcie(pci); + + return regmap_update_bits(stm32_pcie->regmap, SYSCFG_PCIECR, + STM32MP25_PCIECR_LTSSM_EN, + STM32MP25_PCIECR_LTSSM_EN); +} + +static void stm32_pcie_stop_link(struct dw_pcie *pci) +{ + struct stm32_pcie *stm32_pcie = to_stm32_pcie(pci); + + regmap_update_bits(stm32_pcie->regmap, SYSCFG_PCIECR, + STM32MP25_PCIECR_LTSSM_EN, 0); +} + +static int stm32_pcie_suspend_noirq(struct device *dev) +{ + struct stm32_pcie *stm32_pcie = dev_get_drvdata(dev); + int ret; + + ret = dw_pcie_suspend_noirq(&stm32_pcie->pci); + if (ret) + return ret; + + stm32_pcie_assert_perst(stm32_pcie); + + clk_disable_unprepare(stm32_pcie->clk); + + if (!device_wakeup_path(dev)) + phy_exit(stm32_pcie->phy); + + return pinctrl_pm_select_sleep_state(dev); +} + +static int stm32_pcie_resume_noirq(struct device *dev) +{ + struct stm32_pcie *stm32_pcie = dev_get_drvdata(dev); + int ret; + + /* + * The core clock is gated with CLKREQ# from the COMBOPHY REFCLK, + * thus if no device is present, must deassert it with a GPIO from + * pinctrl pinmux before accessing the DBI registers. + */ + ret = pinctrl_pm_select_init_state(dev); + if (ret) { + dev_err(dev, "Failed to activate pinctrl pm state: %d\n", ret); + return ret; + } + + if (!device_wakeup_path(dev)) { + ret = phy_init(stm32_pcie->phy); + if (ret) { + pinctrl_pm_select_default_state(dev); + return ret; + } + } + + ret = clk_prepare_enable(stm32_pcie->clk); + if (ret) + goto err_phy_exit; + + stm32_pcie_deassert_perst(stm32_pcie); + + ret = dw_pcie_resume_noirq(&stm32_pcie->pci); + if (ret) + goto err_disable_clk; + + pinctrl_pm_select_default_state(dev); + + return 0; + +err_disable_clk: + stm32_pcie_assert_perst(stm32_pcie); + clk_disable_unprepare(stm32_pcie->clk); + +err_phy_exit: + phy_exit(stm32_pcie->phy); + pinctrl_pm_select_default_state(dev); + + return ret; +} + +static const struct dev_pm_ops stm32_pcie_pm_ops = { + NOIRQ_SYSTEM_SLEEP_PM_OPS(stm32_pcie_suspend_noirq, + stm32_pcie_resume_noirq) +}; + +static const struct dw_pcie_host_ops stm32_pcie_host_ops = { +}; + +static const struct dw_pcie_ops dw_pcie_ops = { + .start_link = stm32_pcie_start_link, + .stop_link = stm32_pcie_stop_link +}; + +static int stm32_add_pcie_port(struct stm32_pcie *stm32_pcie) +{ + struct device *dev = stm32_pcie->pci.dev; + unsigned int wake_irq; + int ret; + + ret = phy_set_mode(stm32_pcie->phy, PHY_MODE_PCIE); + if (ret) + return ret; + + ret = phy_init(stm32_pcie->phy); + if (ret) + return ret; + + ret = regmap_update_bits(stm32_pcie->regmap, SYSCFG_PCIECR, + STM32MP25_PCIECR_TYPE_MASK, + STM32MP25_PCIECR_RC); + if (ret) + goto err_phy_exit; + + stm32_pcie_deassert_perst(stm32_pcie); + + if (stm32_pcie->wake_gpio) { + wake_irq = gpiod_to_irq(stm32_pcie->wake_gpio); + ret = dev_pm_set_dedicated_wake_irq(dev, wake_irq); + if (ret) { + dev_err(dev, "Failed to enable wakeup irq %d\n", ret); + goto err_assert_perst; + } + irq_set_irq_type(wake_irq, IRQ_TYPE_EDGE_FALLING); + } + + return 0; + +err_assert_perst: + stm32_pcie_assert_perst(stm32_pcie); + +err_phy_exit: + phy_exit(stm32_pcie->phy); + + return ret; +} + +static void stm32_remove_pcie_port(struct stm32_pcie *stm32_pcie) +{ + dev_pm_clear_wake_irq(stm32_pcie->pci.dev); + + stm32_pcie_assert_perst(stm32_pcie); + + phy_exit(stm32_pcie->phy); +} + +static int stm32_pcie_parse_port(struct stm32_pcie *stm32_pcie) +{ + struct device *dev = stm32_pcie->pci.dev; + struct device_node *root_port; + + root_port = of_get_next_available_child(dev->of_node, NULL); + + stm32_pcie->phy = devm_of_phy_get(dev, root_port, NULL); + if (IS_ERR(stm32_pcie->phy)) { + of_node_put(root_port); + return dev_err_probe(dev, PTR_ERR(stm32_pcie->phy), + "Failed to get pcie-phy\n"); + } + + stm32_pcie->perst_gpio = devm_fwnode_gpiod_get(dev, of_fwnode_handle(root_port), + "reset", GPIOD_OUT_HIGH, NULL); + if (IS_ERR(stm32_pcie->perst_gpio)) { + if (PTR_ERR(stm32_pcie->perst_gpio) != -ENOENT) { + of_node_put(root_port); + return dev_err_probe(dev, PTR_ERR(stm32_pcie->perst_gpio), + "Failed to get reset GPIO\n"); + } + stm32_pcie->perst_gpio = NULL; + } + + stm32_pcie->wake_gpio = devm_fwnode_gpiod_get(dev, of_fwnode_handle(root_port), + "wake", GPIOD_IN, NULL); + + if (IS_ERR(stm32_pcie->wake_gpio)) { + if (PTR_ERR(stm32_pcie->wake_gpio) != -ENOENT) { + of_node_put(root_port); + return dev_err_probe(dev, PTR_ERR(stm32_pcie->wake_gpio), + "Failed to get wake GPIO\n"); + } + stm32_pcie->wake_gpio = NULL; + } + + of_node_put(root_port); + + return 0; +} + +static int stm32_pcie_probe(struct platform_device *pdev) +{ + struct stm32_pcie *stm32_pcie; + struct device *dev = &pdev->dev; + int ret; + + stm32_pcie = devm_kzalloc(dev, sizeof(*stm32_pcie), GFP_KERNEL); + if (!stm32_pcie) + return -ENOMEM; + + stm32_pcie->pci.dev = dev; + stm32_pcie->pci.ops = &dw_pcie_ops; + stm32_pcie->pci.pp.ops = &stm32_pcie_host_ops; + + stm32_pcie->regmap = syscon_regmap_lookup_by_compatible("st,stm32mp25-syscfg"); + if (IS_ERR(stm32_pcie->regmap)) + return dev_err_probe(dev, PTR_ERR(stm32_pcie->regmap), + "No syscfg specified\n"); + + stm32_pcie->clk = devm_clk_get(dev, NULL); + if (IS_ERR(stm32_pcie->clk)) + return dev_err_probe(dev, PTR_ERR(stm32_pcie->clk), + "Failed to get PCIe clock source\n"); + + stm32_pcie->rst = devm_reset_control_get_exclusive(dev, NULL); + if (IS_ERR(stm32_pcie->rst)) + return dev_err_probe(dev, PTR_ERR(stm32_pcie->rst), + "Failed to get PCIe reset\n"); + + ret = stm32_pcie_parse_port(stm32_pcie); + if (ret) + return ret; + + platform_set_drvdata(pdev, stm32_pcie); + + ret = stm32_add_pcie_port(stm32_pcie); + if (ret) + return ret; + + reset_control_assert(stm32_pcie->rst); + reset_control_deassert(stm32_pcie->rst); + + ret = clk_prepare_enable(stm32_pcie->clk); + if (ret) { + dev_err(dev, "Core clock enable failed %d\n", ret); + goto err_remove_port; + } + + ret = pm_runtime_set_active(dev); + if (ret < 0) { + dev_err_probe(dev, ret, "Failed to activate runtime PM\n"); + goto err_disable_clk; + } + + pm_runtime_no_callbacks(dev); + + ret = devm_pm_runtime_enable(dev); + if (ret < 0) { + dev_err_probe(dev, ret, "Failed to enable runtime PM\n"); + goto err_disable_clk; + } + + ret = dw_pcie_host_init(&stm32_pcie->pci.pp); + if (ret) + goto err_disable_clk; + + if (stm32_pcie->wake_gpio) + device_init_wakeup(dev, true); + + return 0; + +err_disable_clk: + clk_disable_unprepare(stm32_pcie->clk); + +err_remove_port: + stm32_remove_pcie_port(stm32_pcie); + + return ret; +} + +static void stm32_pcie_remove(struct platform_device *pdev) +{ + struct stm32_pcie *stm32_pcie = platform_get_drvdata(pdev); + struct dw_pcie_rp *pp = &stm32_pcie->pci.pp; + + if (stm32_pcie->wake_gpio) + device_init_wakeup(&pdev->dev, false); + + dw_pcie_host_deinit(pp); + + clk_disable_unprepare(stm32_pcie->clk); + + stm32_remove_pcie_port(stm32_pcie); + + pm_runtime_put_noidle(&pdev->dev); +} + +static const struct of_device_id stm32_pcie_of_match[] = { + { .compatible = "st,stm32mp25-pcie-rc" }, + {}, +}; + +static struct platform_driver stm32_pcie_driver = { + .probe = stm32_pcie_probe, + .remove = stm32_pcie_remove, + .driver = { + .name = "stm32-pcie", + .of_match_table = stm32_pcie_of_match, + .pm = &stm32_pcie_pm_ops, + .probe_type = PROBE_PREFER_ASYNCHRONOUS, + }, +}; + +module_platform_driver(stm32_pcie_driver); + +MODULE_AUTHOR("Christian Bruel <christian.bruel@foss.st.com>"); +MODULE_DESCRIPTION("STM32MP25 PCIe Controller driver"); +MODULE_LICENSE("GPL"); +MODULE_DEVICE_TABLE(of, stm32_pcie_of_match); diff --git a/drivers/pci/controller/dwc/pcie-stm32.h b/drivers/pci/controller/dwc/pcie-stm32.h new file mode 100644 index 000000000000..09d39f04e469 --- /dev/null +++ b/drivers/pci/controller/dwc/pcie-stm32.h @@ -0,0 +1,16 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * ST PCIe driver definitions for STM32-MP25 SoC + * + * Copyright (C) 2025 STMicroelectronics - All Rights Reserved + * Author: Christian Bruel <christian.bruel@foss.st.com> + */ + +#define to_stm32_pcie(x) dev_get_drvdata((x)->dev) + +#define STM32MP25_PCIECR_TYPE_MASK GENMASK(11, 8) +#define STM32MP25_PCIECR_EP 0 +#define STM32MP25_PCIECR_LTSSM_EN BIT(2) +#define STM32MP25_PCIECR_RC BIT(10) + +#define SYSCFG_PCIECR 0x6000 diff --git a/drivers/pci/controller/dwc/pcie-tegra194.c b/drivers/pci/controller/dwc/pcie-tegra194.c index 4f26086f25da..10e74458e667 100644 --- a/drivers/pci/controller/dwc/pcie-tegra194.c +++ b/drivers/pci/controller/dwc/pcie-tegra194.c @@ -1214,6 +1214,7 @@ static int tegra_pcie_bpmp_set_ctrl_state(struct tegra_pcie_dw *pcie, struct mrq_uphy_response resp; struct tegra_bpmp_message msg; struct mrq_uphy_request req; + int err; /* * Controller-5 doesn't need to have its state set by BPMP-FW in @@ -1236,7 +1237,13 @@ static int tegra_pcie_bpmp_set_ctrl_state(struct tegra_pcie_dw *pcie, msg.rx.data = &resp; msg.rx.size = sizeof(resp); - return tegra_bpmp_transfer(pcie->bpmp, &msg); + err = tegra_bpmp_transfer(pcie->bpmp, &msg); + if (err) + return err; + if (msg.rx.ret) + return -EINVAL; + + return 0; } static int tegra_pcie_bpmp_set_pll_state(struct tegra_pcie_dw *pcie, @@ -1245,6 +1252,7 @@ static int tegra_pcie_bpmp_set_pll_state(struct tegra_pcie_dw *pcie, struct mrq_uphy_response resp; struct tegra_bpmp_message msg; struct mrq_uphy_request req; + int err; memset(&req, 0, sizeof(req)); memset(&resp, 0, sizeof(resp)); @@ -1264,13 +1272,19 @@ static int tegra_pcie_bpmp_set_pll_state(struct tegra_pcie_dw *pcie, msg.rx.data = &resp; msg.rx.size = sizeof(resp); - return tegra_bpmp_transfer(pcie->bpmp, &msg); + err = tegra_bpmp_transfer(pcie->bpmp, &msg); + if (err) + return err; + if (msg.rx.ret) + return -EINVAL; + + return 0; } static void tegra_pcie_downstream_dev_to_D0(struct tegra_pcie_dw *pcie) { struct dw_pcie_rp *pp = &pcie->pci.pp; - struct pci_bus *child, *root_bus = NULL; + struct pci_bus *child, *root_port_bus = NULL; struct pci_dev *pdev; /* @@ -1283,19 +1297,19 @@ static void tegra_pcie_downstream_dev_to_D0(struct tegra_pcie_dw *pcie) */ list_for_each_entry(child, &pp->bridge->bus->children, node) { - /* Bring downstream devices to D0 if they are not already in */ if (child->parent == pp->bridge->bus) { - root_bus = child; + root_port_bus = child; break; } } - if (!root_bus) { - dev_err(pcie->dev, "Failed to find downstream devices\n"); + if (!root_port_bus) { + dev_err(pcie->dev, "Failed to find downstream bus of Root Port\n"); return; } - list_for_each_entry(pdev, &root_bus->devices, bus_list) { + /* Bring downstream devices to D0 if they are not already in */ + list_for_each_entry(pdev, &root_port_bus->devices, bus_list) { if (PCI_SLOT(pdev->devfn) == 0) { if (pci_set_power_state(pdev, PCI_D0)) dev_err(pcie->dev, @@ -1722,9 +1736,9 @@ static void pex_ep_event_pex_rst_assert(struct tegra_pcie_dw *pcie) ret); } - ret = tegra_pcie_bpmp_set_pll_state(pcie, false); + ret = tegra_pcie_bpmp_set_ctrl_state(pcie, false); if (ret) - dev_err(pcie->dev, "Failed to turn off UPHY: %d\n", ret); + dev_err(pcie->dev, "Failed to disable controller: %d\n", ret); pcie->ep_state = EP_STATE_DISABLED; dev_dbg(pcie->dev, "Uninitialization of endpoint is completed\n"); @@ -1941,6 +1955,15 @@ static irqreturn_t tegra_pcie_ep_pex_rst_irq(int irq, void *arg) return IRQ_HANDLED; } +static void tegra_pcie_ep_init(struct dw_pcie_ep *ep) +{ + struct dw_pcie *pci = to_dw_pcie_from_ep(ep); + enum pci_barno bar; + + for (bar = 0; bar < PCI_STD_NUM_BARS; bar++) + dw_pcie_ep_reset_bar(pci, bar); +}; + static int tegra_pcie_ep_raise_intx_irq(struct tegra_pcie_dw *pcie, u16 irq) { /* Tegra194 supports only INTA */ @@ -1955,10 +1978,10 @@ static int tegra_pcie_ep_raise_intx_irq(struct tegra_pcie_dw *pcie, u16 irq) static int tegra_pcie_ep_raise_msi_irq(struct tegra_pcie_dw *pcie, u16 irq) { - if (unlikely(irq > 31)) + if (unlikely(irq > 32)) return -EINVAL; - appl_writel(pcie, BIT(irq), APPL_MSI_CTRL_1); + appl_writel(pcie, BIT(irq - 1), APPL_MSI_CTRL_1); return 0; } @@ -1998,8 +2021,7 @@ static int tegra_pcie_ep_raise_irq(struct dw_pcie_ep *ep, u8 func_no, static const struct pci_epc_features tegra_pcie_epc_features = { .linkup_notifier = true, - .msi_capable = false, - .msix_capable = false, + .msi_capable = true, .bar[BAR_0] = { .type = BAR_FIXED, .fixed_size = SZ_1M, .only_64bit = true, }, .bar[BAR_1] = { .type = BAR_RESERVED, }, @@ -2017,6 +2039,7 @@ tegra_pcie_ep_get_features(struct dw_pcie_ep *ep) } static const struct dw_pcie_ep_ops pcie_ep_ops = { + .init = tegra_pcie_ep_init, .raise_irq = tegra_pcie_ep_raise_irq, .get_features = tegra_pcie_ep_get_features, }; diff --git a/drivers/pci/controller/pci-hyperv.c b/drivers/pci/controller/pci-hyperv.c index d2b7e8ea710b..146b43981b27 100644 --- a/drivers/pci/controller/pci-hyperv.c +++ b/drivers/pci/controller/pci-hyperv.c @@ -1680,7 +1680,6 @@ static void hv_int_desc_free(struct hv_pci_dev *hpdev, /** * hv_msi_free() - Free the MSI. * @domain: The interrupt domain pointer - * @info: Extra MSI-related context * @irq: Identifies the IRQ. * * The Hyper-V parent partition and hypervisor are tracking the @@ -1688,8 +1687,7 @@ static void hv_int_desc_free(struct hv_pci_dev *hpdev, * table up to date. This callback sends a message that frees * the IRT entry and related tracking nonsense. */ -static void hv_msi_free(struct irq_domain *domain, struct msi_domain_info *info, - unsigned int irq) +static void hv_msi_free(struct irq_domain *domain, unsigned int irq) { struct hv_pcibus_device *hbus; struct hv_pci_dev *hpdev; @@ -2181,10 +2179,8 @@ static int hv_pcie_domain_alloc(struct irq_domain *d, unsigned int virq, unsigne static void hv_pcie_domain_free(struct irq_domain *d, unsigned int virq, unsigned int nr_irqs) { - struct msi_domain_info *info = d->host_data; - for (int i = 0; i < nr_irqs; i++) - hv_msi_free(d, info, virq + i); + hv_msi_free(d, virq + i); irq_domain_free_irqs_top(d, virq, nr_irqs); } diff --git a/drivers/pci/controller/pci-tegra.c b/drivers/pci/controller/pci-tegra.c index 467ddc701adc..942ddfca3bf6 100644 --- a/drivers/pci/controller/pci-tegra.c +++ b/drivers/pci/controller/pci-tegra.c @@ -14,6 +14,7 @@ */ #include <linux/clk.h> +#include <linux/cleanup.h> #include <linux/debugfs.h> #include <linux/delay.h> #include <linux/export.h> @@ -270,7 +271,7 @@ struct tegra_msi { DECLARE_BITMAP(used, INT_PCI_MSI_NR); struct irq_domain *domain; struct mutex map_lock; - spinlock_t mask_lock; + raw_spinlock_t mask_lock; void *virt; dma_addr_t phys; int irq; @@ -1344,7 +1345,7 @@ static int tegra_pcie_port_get_phys(struct tegra_pcie_port *port) unsigned int i; int err; - port->phys = devm_kcalloc(dev, sizeof(phy), port->lanes, GFP_KERNEL); + port->phys = devm_kcalloc(dev, port->lanes, sizeof(phy), GFP_KERNEL); if (!port->phys) return -ENOMEM; @@ -1581,14 +1582,13 @@ static void tegra_msi_irq_mask(struct irq_data *d) struct tegra_msi *msi = irq_data_get_irq_chip_data(d); struct tegra_pcie *pcie = msi_to_pcie(msi); unsigned int index = d->hwirq / 32; - unsigned long flags; u32 value; - spin_lock_irqsave(&msi->mask_lock, flags); - value = afi_readl(pcie, AFI_MSI_EN_VEC(index)); - value &= ~BIT(d->hwirq % 32); - afi_writel(pcie, value, AFI_MSI_EN_VEC(index)); - spin_unlock_irqrestore(&msi->mask_lock, flags); + scoped_guard(raw_spinlock_irqsave, &msi->mask_lock) { + value = afi_readl(pcie, AFI_MSI_EN_VEC(index)); + value &= ~BIT(d->hwirq % 32); + afi_writel(pcie, value, AFI_MSI_EN_VEC(index)); + } } static void tegra_msi_irq_unmask(struct irq_data *d) @@ -1596,14 +1596,13 @@ static void tegra_msi_irq_unmask(struct irq_data *d) struct tegra_msi *msi = irq_data_get_irq_chip_data(d); struct tegra_pcie *pcie = msi_to_pcie(msi); unsigned int index = d->hwirq / 32; - unsigned long flags; u32 value; - spin_lock_irqsave(&msi->mask_lock, flags); - value = afi_readl(pcie, AFI_MSI_EN_VEC(index)); - value |= BIT(d->hwirq % 32); - afi_writel(pcie, value, AFI_MSI_EN_VEC(index)); - spin_unlock_irqrestore(&msi->mask_lock, flags); + scoped_guard(raw_spinlock_irqsave, &msi->mask_lock) { + value = afi_readl(pcie, AFI_MSI_EN_VEC(index)); + value |= BIT(d->hwirq % 32); + afi_writel(pcie, value, AFI_MSI_EN_VEC(index)); + } } static void tegra_compose_msi_msg(struct irq_data *data, struct msi_msg *msg) @@ -1711,7 +1710,7 @@ static int tegra_pcie_msi_setup(struct tegra_pcie *pcie) int err; mutex_init(&msi->map_lock); - spin_lock_init(&msi->mask_lock); + raw_spin_lock_init(&msi->mask_lock); if (IS_ENABLED(CONFIG_PCI_MSI)) { err = tegra_allocate_domains(msi); diff --git a/drivers/pci/controller/pci-xgene-msi.c b/drivers/pci/controller/pci-xgene-msi.c index 0a37a3f1809c..654639bccd10 100644 --- a/drivers/pci/controller/pci-xgene-msi.c +++ b/drivers/pci/controller/pci-xgene-msi.c @@ -311,7 +311,7 @@ static int xgene_msi_handler_setup(struct platform_device *pdev) msi_val = xgene_msi_int_read(xgene_msi, i); if (msi_val) { dev_err(&pdev->dev, "Failed to clear spurious IRQ\n"); - return EINVAL; + return -EINVAL; } irq = platform_get_irq(pdev, i); diff --git a/drivers/pci/controller/pcie-mediatek-gen3.c b/drivers/pci/controller/pcie-mediatek-gen3.c index 97147f43e41c..75ddb8bee168 100644 --- a/drivers/pci/controller/pcie-mediatek-gen3.c +++ b/drivers/pci/controller/pcie-mediatek-gen3.c @@ -102,6 +102,9 @@ #define PCIE_MSI_SET_ADDR_HI_BASE 0xc80 #define PCIE_MSI_SET_ADDR_HI_OFFSET 0x04 +#define PCIE_RESOURCE_CTRL_REG 0xd2c +#define PCIE_RSRC_SYS_CLK_RDY_TIME_MASK GENMASK(7, 0) + #define PCIE_ICMD_PM_REG 0x198 #define PCIE_TURN_OFF_LINK BIT(4) @@ -149,6 +152,7 @@ enum mtk_gen3_pcie_flags { * struct mtk_gen3_pcie_pdata - differentiate between host generations * @power_up: pcie power_up callback * @phy_resets: phy reset lines SoC data. + * @sys_clk_rdy_time_us: System clock ready time override (microseconds) * @flags: pcie device flags. */ struct mtk_gen3_pcie_pdata { @@ -157,6 +161,7 @@ struct mtk_gen3_pcie_pdata { const char *id[MAX_NUM_PHY_RESETS]; int num_resets; } phy_resets; + u8 sys_clk_rdy_time_us; u32 flags; }; @@ -435,6 +440,14 @@ static int mtk_pcie_startup_port(struct mtk_gen3_pcie *pcie) writel_relaxed(val, pcie->base + PCIE_CONF_LINK2_CTL_STS); } + /* If parameter is present, adjust SYS_CLK_RDY_TIME to avoid glitching */ + if (pcie->soc->sys_clk_rdy_time_us) { + val = readl_relaxed(pcie->base + PCIE_RESOURCE_CTRL_REG); + FIELD_MODIFY(PCIE_RSRC_SYS_CLK_RDY_TIME_MASK, &val, + pcie->soc->sys_clk_rdy_time_us); + writel_relaxed(val, pcie->base + PCIE_RESOURCE_CTRL_REG); + } + /* Set class code */ val = readl_relaxed(pcie->base + PCIE_PCI_IDS_1); val &= ~GENMASK(31, 8); @@ -1327,6 +1340,15 @@ static const struct mtk_gen3_pcie_pdata mtk_pcie_soc_mt8192 = { }, }; +static const struct mtk_gen3_pcie_pdata mtk_pcie_soc_mt8196 = { + .power_up = mtk_pcie_power_up, + .phy_resets = { + .id[0] = "phy", + .num_resets = 1, + }, + .sys_clk_rdy_time_us = 10, +}; + static const struct mtk_gen3_pcie_pdata mtk_pcie_soc_en7581 = { .power_up = mtk_pcie_en7581_power_up, .phy_resets = { @@ -1341,6 +1363,7 @@ static const struct mtk_gen3_pcie_pdata mtk_pcie_soc_en7581 = { static const struct of_device_id mtk_pcie_of_match[] = { { .compatible = "airoha,en7581-pcie", .data = &mtk_pcie_soc_en7581 }, { .compatible = "mediatek,mt8192-pcie", .data = &mtk_pcie_soc_mt8192 }, + { .compatible = "mediatek,mt8196-pcie", .data = &mtk_pcie_soc_mt8196 }, {}, }; MODULE_DEVICE_TABLE(of, mtk_pcie_of_match); diff --git a/drivers/pci/controller/pcie-rcar-ep.c b/drivers/pci/controller/pcie-rcar-ep.c index a8a966844cf3..657875ef4657 100644 --- a/drivers/pci/controller/pcie-rcar-ep.c +++ b/drivers/pci/controller/pcie-rcar-ep.c @@ -436,9 +436,7 @@ static void rcar_pcie_ep_stop(struct pci_epc *epc) } static const struct pci_epc_features rcar_pcie_epc_features = { - .linkup_notifier = false, .msi_capable = true, - .msix_capable = false, /* use 64-bit BARs so mark BAR[1,3,5] as reserved */ .bar[BAR_0] = { .type = BAR_FIXED, .fixed_size = 128, .only_64bit = true, }, diff --git a/drivers/pci/controller/pcie-rcar-host.c b/drivers/pci/controller/pcie-rcar-host.c index fe288fd770c4..213028052aa5 100644 --- a/drivers/pci/controller/pcie-rcar-host.c +++ b/drivers/pci/controller/pcie-rcar-host.c @@ -12,6 +12,7 @@ */ #include <linux/bitops.h> +#include <linux/cleanup.h> #include <linux/clk.h> #include <linux/clk-provider.h> #include <linux/delay.h> @@ -38,7 +39,7 @@ struct rcar_msi { DECLARE_BITMAP(used, INT_PCI_MSI_NR); struct irq_domain *domain; struct mutex map_lock; - spinlock_t mask_lock; + raw_spinlock_t mask_lock; int irq1; int irq2; }; @@ -52,20 +53,13 @@ struct rcar_pcie_host { int (*phy_init_fn)(struct rcar_pcie_host *host); }; -static DEFINE_SPINLOCK(pmsr_lock); - static int rcar_pcie_wakeup(struct device *pcie_dev, void __iomem *pcie_base) { - unsigned long flags; u32 pmsr, val; int ret = 0; - spin_lock_irqsave(&pmsr_lock, flags); - - if (!pcie_base || pm_runtime_suspended(pcie_dev)) { - ret = -EINVAL; - goto unlock_exit; - } + if (!pcie_base || pm_runtime_suspended(pcie_dev)) + return -EINVAL; pmsr = readl(pcie_base + PMSR); @@ -87,8 +81,6 @@ static int rcar_pcie_wakeup(struct device *pcie_dev, void __iomem *pcie_base) writel(L1FAEG | PMEL1RX, pcie_base + PMSR); } -unlock_exit: - spin_unlock_irqrestore(&pmsr_lock, flags); return ret; } @@ -584,7 +576,7 @@ static irqreturn_t rcar_pcie_msi_irq(int irq, void *data) unsigned int index = find_first_bit(®, 32); int ret; - ret = generic_handle_domain_irq(msi->domain->parent, index); + ret = generic_handle_domain_irq(msi->domain, index); if (ret) { /* Unknown MSI, just clear it */ dev_dbg(dev, "unexpected MSI\n"); @@ -611,28 +603,26 @@ static void rcar_msi_irq_mask(struct irq_data *d) { struct rcar_msi *msi = irq_data_get_irq_chip_data(d); struct rcar_pcie *pcie = &msi_to_host(msi)->pcie; - unsigned long flags; u32 value; - spin_lock_irqsave(&msi->mask_lock, flags); - value = rcar_pci_read_reg(pcie, PCIEMSIIER); - value &= ~BIT(d->hwirq); - rcar_pci_write_reg(pcie, value, PCIEMSIIER); - spin_unlock_irqrestore(&msi->mask_lock, flags); + scoped_guard(raw_spinlock_irqsave, &msi->mask_lock) { + value = rcar_pci_read_reg(pcie, PCIEMSIIER); + value &= ~BIT(d->hwirq); + rcar_pci_write_reg(pcie, value, PCIEMSIIER); + } } static void rcar_msi_irq_unmask(struct irq_data *d) { struct rcar_msi *msi = irq_data_get_irq_chip_data(d); struct rcar_pcie *pcie = &msi_to_host(msi)->pcie; - unsigned long flags; u32 value; - spin_lock_irqsave(&msi->mask_lock, flags); - value = rcar_pci_read_reg(pcie, PCIEMSIIER); - value |= BIT(d->hwirq); - rcar_pci_write_reg(pcie, value, PCIEMSIIER); - spin_unlock_irqrestore(&msi->mask_lock, flags); + scoped_guard(raw_spinlock_irqsave, &msi->mask_lock) { + value = rcar_pci_read_reg(pcie, PCIEMSIIER); + value |= BIT(d->hwirq); + rcar_pci_write_reg(pcie, value, PCIEMSIIER); + } } static void rcar_compose_msi_msg(struct irq_data *data, struct msi_msg *msg) @@ -745,7 +735,7 @@ static int rcar_pcie_enable_msi(struct rcar_pcie_host *host) int err; mutex_init(&msi->map_lock); - spin_lock_init(&msi->mask_lock); + raw_spin_lock_init(&msi->mask_lock); err = of_address_to_resource(dev->of_node, 0, &res); if (err) diff --git a/drivers/pci/controller/pcie-rockchip-ep.c b/drivers/pci/controller/pcie-rockchip-ep.c index 300cd85fa035..799461335762 100644 --- a/drivers/pci/controller/pcie-rockchip-ep.c +++ b/drivers/pci/controller/pcie-rockchip-ep.c @@ -694,7 +694,6 @@ static int rockchip_pcie_ep_setup_irq(struct pci_epc *epc) static const struct pci_epc_features rockchip_pcie_epc_features = { .linkup_notifier = true, .msi_capable = true, - .msix_capable = false, .intx_capable = true, .align = ROCKCHIP_PCIE_AT_SIZE_ALIGN, }; diff --git a/drivers/pci/controller/pcie-xilinx-nwl.c b/drivers/pci/controller/pcie-xilinx-nwl.c index 05b8c205493c..7db2c96c6cec 100644 --- a/drivers/pci/controller/pcie-xilinx-nwl.c +++ b/drivers/pci/controller/pcie-xilinx-nwl.c @@ -718,9 +718,10 @@ static int nwl_pcie_bridge_init(struct nwl_pcie *pcie) nwl_bridge_writel(pcie, nwl_bridge_readl(pcie, E_ECAM_CONTROL) | E_ECAM_CR_ENABLE, E_ECAM_CONTROL); - nwl_bridge_writel(pcie, nwl_bridge_readl(pcie, E_ECAM_CONTROL) | - (NWL_ECAM_MAX_SIZE << E_ECAM_SIZE_SHIFT), - E_ECAM_CONTROL); + ecam_val = nwl_bridge_readl(pcie, E_ECAM_CONTROL); + ecam_val &= ~E_ECAM_SIZE_LOC; + ecam_val |= NWL_ECAM_MAX_SIZE << E_ECAM_SIZE_SHIFT; + nwl_bridge_writel(pcie, ecam_val, E_ECAM_CONTROL); nwl_bridge_writel(pcie, lower_32_bits(pcie->phys_ecam_base), E_ECAM_BASE_LO); diff --git a/drivers/pci/controller/plda/pcie-plda-host.c b/drivers/pci/controller/plda/pcie-plda-host.c index 8e2db2e5b64b..3c2f68383010 100644 --- a/drivers/pci/controller/plda/pcie-plda-host.c +++ b/drivers/pci/controller/plda/pcie-plda-host.c @@ -599,8 +599,7 @@ int plda_pcie_host_init(struct plda_pcie_rp *port, struct pci_ops *ops, bridge = devm_pci_alloc_host_bridge(dev, 0); if (!bridge) - return dev_err_probe(dev, -ENOMEM, - "failed to alloc bridge\n"); + return -ENOMEM; if (port->host_ops && port->host_ops->host_init) { ret = port->host_ops->host_init(port); diff --git a/drivers/pci/endpoint/functions/pci-epf-test.c b/drivers/pci/endpoint/functions/pci-epf-test.c index e091193bd8a8..31617772ad51 100644 --- a/drivers/pci/endpoint/functions/pci-epf-test.c +++ b/drivers/pci/endpoint/functions/pci-epf-test.c @@ -301,15 +301,20 @@ static void pci_epf_test_clean_dma_chan(struct pci_epf_test *epf_test) if (!epf_test->dma_supported) return; - dma_release_channel(epf_test->dma_chan_tx); - if (epf_test->dma_chan_tx == epf_test->dma_chan_rx) { + if (epf_test->dma_chan_tx) { + dma_release_channel(epf_test->dma_chan_tx); + if (epf_test->dma_chan_tx == epf_test->dma_chan_rx) { + epf_test->dma_chan_tx = NULL; + epf_test->dma_chan_rx = NULL; + return; + } epf_test->dma_chan_tx = NULL; - epf_test->dma_chan_rx = NULL; - return; } - dma_release_channel(epf_test->dma_chan_rx); - epf_test->dma_chan_rx = NULL; + if (epf_test->dma_chan_rx) { + dma_release_channel(epf_test->dma_chan_rx); + epf_test->dma_chan_rx = NULL; + } } static void pci_epf_test_print_rate(struct pci_epf_test *epf_test, @@ -772,12 +777,24 @@ static void pci_epf_test_disable_doorbell(struct pci_epf_test *epf_test, u32 status = le32_to_cpu(reg->status); struct pci_epf *epf = epf_test->epf; struct pci_epc *epc = epf->epc; + int ret; if (bar < BAR_0) goto set_status_err; pci_epf_test_doorbell_cleanup(epf_test); - pci_epc_clear_bar(epc, epf->func_no, epf->vfunc_no, &epf_test->db_bar); + + /* + * The doorbell feature temporarily overrides the inbound translation + * to point to the address stored in epf_test->db_bar.phys_addr, i.e., + * it calls set_bar() twice without ever calling clear_bar(), as + * calling clear_bar() would clear the BAR's PCI address assigned by + * the host. Thus, when disabling the doorbell, restore the inbound + * translation to point to the memory allocated for the BAR. + */ + ret = pci_epc_set_bar(epc, epf->func_no, epf->vfunc_no, &epf->bar[bar]); + if (ret) + goto set_status_err; status |= STATUS_DOORBELL_DISABLE_SUCCESS; reg->status = cpu_to_le32(status); @@ -1050,7 +1067,12 @@ static int pci_epf_test_alloc_space(struct pci_epf *epf) if (bar == test_reg_bar) continue; - base = pci_epf_alloc_space(epf, bar_size[bar], bar, + if (epc_features->bar[bar].type == BAR_FIXED) + test_reg_size = epc_features->bar[bar].fixed_size; + else + test_reg_size = bar_size[bar]; + + base = pci_epf_alloc_space(epf, test_reg_size, bar, epc_features, PRIMARY_INTERFACE); if (!base) dev_err(dev, "Failed to allocate space for BAR%d\n", diff --git a/drivers/pci/endpoint/pci-ep-msi.c b/drivers/pci/endpoint/pci-ep-msi.c index 9ca89cbfec15..1b58357b905f 100644 --- a/drivers/pci/endpoint/pci-ep-msi.c +++ b/drivers/pci/endpoint/pci-ep-msi.c @@ -24,7 +24,7 @@ static void pci_epf_write_msi_msg(struct msi_desc *desc, struct msi_msg *msg) struct pci_epf *epf; epc = pci_epc_get(dev_name(msi_desc_to_dev(desc))); - if (!epc) + if (IS_ERR(epc)) return; epf = list_first_entry_or_null(&epc->pci_epf, struct pci_epf, list); diff --git a/drivers/pci/hotplug/cpqphp_pci.c b/drivers/pci/hotplug/cpqphp_pci.c index ef7534a3ca40..88929360fe77 100644 --- a/drivers/pci/hotplug/cpqphp_pci.c +++ b/drivers/pci/hotplug/cpqphp_pci.c @@ -1302,7 +1302,7 @@ int cpqhp_find_available_resources(struct controller *ctrl, void __iomem *rom_st dbg("found io_node(base, length) = %x, %x\n", io_node->base, io_node->length); - dbg("populated slot =%d \n", populated_slot); + dbg("populated slot = %d\n", populated_slot); if (!populated_slot) { io_node->next = ctrl->io_head; ctrl->io_head = io_node; @@ -1325,7 +1325,7 @@ int cpqhp_find_available_resources(struct controller *ctrl, void __iomem *rom_st dbg("found mem_node(base, length) = %x, %x\n", mem_node->base, mem_node->length); - dbg("populated slot =%d \n", populated_slot); + dbg("populated slot = %d\n", populated_slot); if (!populated_slot) { mem_node->next = ctrl->mem_head; ctrl->mem_head = mem_node; @@ -1349,7 +1349,7 @@ int cpqhp_find_available_resources(struct controller *ctrl, void __iomem *rom_st p_mem_node->length = pre_mem_length << 16; dbg("found p_mem_node(base, length) = %x, %x\n", p_mem_node->base, p_mem_node->length); - dbg("populated slot =%d \n", populated_slot); + dbg("populated slot = %d\n", populated_slot); if (!populated_slot) { p_mem_node->next = ctrl->p_mem_head; @@ -1373,7 +1373,7 @@ int cpqhp_find_available_resources(struct controller *ctrl, void __iomem *rom_st bus_node->length = max_bus - secondary_bus + 1; dbg("found bus_node(base, length) = %x, %x\n", bus_node->base, bus_node->length); - dbg("populated slot =%d \n", populated_slot); + dbg("populated slot = %d\n", populated_slot); if (!populated_slot) { bus_node->next = ctrl->bus_head; ctrl->bus_head = bus_node; diff --git a/drivers/pci/hotplug/ibmphp_hpc.c b/drivers/pci/hotplug/ibmphp_hpc.c index a5720d12e573..2324167656a6 100644 --- a/drivers/pci/hotplug/ibmphp_hpc.c +++ b/drivers/pci/hotplug/ibmphp_hpc.c @@ -124,7 +124,7 @@ static u8 i2c_ctrl_read(struct controller *ctlr_ptr, void __iomem *WPGBbar, u8 i unsigned long ultemp; unsigned long data; // actual data HILO format - debug_polling("%s - Entry WPGBbar[%p] index[%x] \n", __func__, WPGBbar, index); + debug_polling("%s - Entry WPGBbar[%p] index[%x]\n", __func__, WPGBbar, index); //-------------------------------------------------------------------- // READ - step 1 @@ -147,7 +147,7 @@ static u8 i2c_ctrl_read(struct controller *ctlr_ptr, void __iomem *WPGBbar, u8 i ultemp = ultemp << 8; data |= ultemp; } else { - err("this controller type is not supported \n"); + err("this controller type is not supported\n"); return HPC_ERROR; } @@ -258,7 +258,7 @@ static u8 i2c_ctrl_write(struct controller *ctlr_ptr, void __iomem *WPGBbar, u8 ultemp = ultemp << 8; data |= ultemp; } else { - err("this controller type is not supported \n"); + err("this controller type is not supported\n"); return HPC_ERROR; } diff --git a/drivers/pci/iov.c b/drivers/pci/iov.c index ac4375954c94..77dee43b7858 100644 --- a/drivers/pci/iov.c +++ b/drivers/pci/iov.c @@ -629,15 +629,18 @@ static int sriov_add_vfs(struct pci_dev *dev, u16 num_vfs) if (dev->no_vf_scan) return 0; + pci_lock_rescan_remove(); for (i = 0; i < num_vfs; i++) { rc = pci_iov_add_virtfn(dev, i); if (rc) goto failed; } + pci_unlock_rescan_remove(); return 0; failed: while (i--) pci_iov_remove_virtfn(dev, i); + pci_unlock_rescan_remove(); return rc; } @@ -762,8 +765,10 @@ static void sriov_del_vfs(struct pci_dev *dev) struct pci_sriov *iov = dev->sriov; int i; + pci_lock_rescan_remove(); for (i = 0; i < iov->num_VFs; i++) pci_iov_remove_virtfn(dev, i); + pci_unlock_rescan_remove(); } static void sriov_disable(struct pci_dev *dev) diff --git a/drivers/pci/of_property.c b/drivers/pci/of_property.c index 506fcd507113..7aae46f333d9 100644 --- a/drivers/pci/of_property.c +++ b/drivers/pci/of_property.c @@ -279,13 +279,21 @@ static int of_pci_prop_intr_map(struct pci_dev *pdev, struct of_changeset *ocs, mapp++; *mapp = out_irq[i].np->phandle; mapp++; - if (addr_sz[i]) { - ret = of_property_read_u32_array(out_irq[i].np, - "reg", mapp, - addr_sz[i]); - if (ret) - goto failed; - } + + /* + * A device address does not affect the device <-> + * interrupt-controller HW connection for all + * modern interrupt controllers; moreover, the + * kernel (i.e., of_irq_parse_raw()) ignores the + * values in the parent unit address cells while + * parsing the interrupt-map property because they + * are irrelevant for interrupt mapping in modern + * systems. + * + * Leave the parent unit address initialized to 0 -- + * just take into account the #address-cells size + * to build the property properly. + */ mapp += addr_sz[i]; memcpy(mapp, out_irq[i].args, out_irq[i].args_count * sizeof(u32)); diff --git a/drivers/pci/p2pdma.c b/drivers/pci/p2pdma.c index da5657a02007..78e108e47254 100644 --- a/drivers/pci/p2pdma.c +++ b/drivers/pci/p2pdma.c @@ -360,7 +360,7 @@ int pci_p2pdma_add_resource(struct pci_dev *pdev, int bar, size_t size, pages_free: devm_memunmap_pages(&pdev->dev, pgmap); pgmap_free: - devm_kfree(&pdev->dev, pgmap); + devm_kfree(&pdev->dev, p2p_pgmap); return error; } EXPORT_SYMBOL_GPL(pci_p2pdma_add_resource); @@ -738,7 +738,7 @@ EXPORT_SYMBOL_GPL(pci_p2pdma_distance_many); * pci_has_p2pmem - check if a given PCI device has published any p2pmem * @pdev: PCI device to check */ -bool pci_has_p2pmem(struct pci_dev *pdev) +static bool pci_has_p2pmem(struct pci_dev *pdev) { struct pci_p2pdma *p2pdma; bool res; @@ -750,7 +750,6 @@ bool pci_has_p2pmem(struct pci_dev *pdev) return res; } -EXPORT_SYMBOL_GPL(pci_has_p2pmem); /** * pci_p2pmem_find_many - find a peer-to-peer DMA memory device compatible with diff --git a/drivers/pci/pci-acpi.c b/drivers/pci/pci-acpi.c index ddb25960ea47..9369377725fa 100644 --- a/drivers/pci/pci-acpi.c +++ b/drivers/pci/pci-acpi.c @@ -122,6 +122,8 @@ phys_addr_t acpi_pci_root_get_mcfg_addr(acpi_handle handle) bool pci_acpi_preserve_config(struct pci_host_bridge *host_bridge) { + bool ret = false; + if (ACPI_HANDLE(&host_bridge->dev)) { union acpi_object *obj; @@ -135,11 +137,11 @@ bool pci_acpi_preserve_config(struct pci_host_bridge *host_bridge) 1, DSM_PCI_PRESERVE_BOOT_CONFIG, NULL, ACPI_TYPE_INTEGER); if (obj && obj->integer.value == 0) - return true; + ret = true; ACPI_FREE(obj); } - return false; + return ret; } /* _HPX PCI Setting Record (Type 0); same as _HPP */ diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c index 63665240ae87..302d61783f6c 100644 --- a/drivers/pci/pci-driver.c +++ b/drivers/pci/pci-driver.c @@ -1582,7 +1582,7 @@ static int pci_uevent(const struct device *dev, struct kobj_uevent_env *env) return 0; } -#if defined(CONFIG_PCIEAER) || defined(CONFIG_EEH) +#if defined(CONFIG_PCIEAER) || defined(CONFIG_EEH) || defined(CONFIG_S390) /** * pci_uevent_ers - emit a uevent during recovery path of PCI device * @pdev: PCI device undergoing error recovery @@ -1596,6 +1596,7 @@ void pci_uevent_ers(struct pci_dev *pdev, enum pci_ers_result err_type) switch (err_type) { case PCI_ERS_RESULT_NONE: case PCI_ERS_RESULT_CAN_RECOVER: + case PCI_ERS_RESULT_NEED_RESET: envp[idx++] = "ERROR_EVENT=BEGIN_RECOVERY"; envp[idx++] = "DEVICE_ONLINE=0"; break; diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c index 5eea14c1f7f5..9d6f74bd95f8 100644 --- a/drivers/pci/pci-sysfs.c +++ b/drivers/pci/pci-sysfs.c @@ -30,6 +30,7 @@ #include <linux/msi.h> #include <linux/of.h> #include <linux/aperture.h> +#include <linux/unaligned.h> #include "pci.h" #ifndef ARCH_PCI_DEV_GROUPS @@ -177,6 +178,13 @@ static ssize_t resource_show(struct device *dev, struct device_attribute *attr, for (i = 0; i < max; i++) { struct resource *res = &pci_dev->resource[i]; + struct resource zerores = {}; + + /* For backwards compatibility */ + if (i >= PCI_BRIDGE_RESOURCES && i <= PCI_BRIDGE_RESOURCE_END && + res->flags & (IORESOURCE_UNSET | IORESOURCE_DISABLED)) + res = &zerores; + pci_resource_to_user(pci_dev, i, res, &start, &end); len += sysfs_emit_at(buf, len, "0x%016llx 0x%016llx 0x%016llx\n", (unsigned long long)start, @@ -201,8 +209,14 @@ static ssize_t max_link_width_show(struct device *dev, struct device_attribute *attr, char *buf) { struct pci_dev *pdev = to_pci_dev(dev); + ssize_t ret; - return sysfs_emit(buf, "%u\n", pcie_get_width_cap(pdev)); + /* We read PCI_EXP_LNKCAP, so we need the device to be accessible. */ + pci_config_pm_runtime_get(pdev); + ret = sysfs_emit(buf, "%u\n", pcie_get_width_cap(pdev)); + pci_config_pm_runtime_put(pdev); + + return ret; } static DEVICE_ATTR_RO(max_link_width); @@ -214,7 +228,10 @@ static ssize_t current_link_speed_show(struct device *dev, int err; enum pci_bus_speed speed; + pci_config_pm_runtime_get(pci_dev); err = pcie_capability_read_word(pci_dev, PCI_EXP_LNKSTA, &linkstat); + pci_config_pm_runtime_put(pci_dev); + if (err) return -EINVAL; @@ -231,7 +248,10 @@ static ssize_t current_link_width_show(struct device *dev, u16 linkstat; int err; + pci_config_pm_runtime_get(pci_dev); err = pcie_capability_read_word(pci_dev, PCI_EXP_LNKSTA, &linkstat); + pci_config_pm_runtime_put(pci_dev); + if (err) return -EINVAL; @@ -247,7 +267,10 @@ static ssize_t secondary_bus_number_show(struct device *dev, u8 sec_bus; int err; + pci_config_pm_runtime_get(pci_dev); err = pci_read_config_byte(pci_dev, PCI_SECONDARY_BUS, &sec_bus); + pci_config_pm_runtime_put(pci_dev); + if (err) return -EINVAL; @@ -263,7 +286,10 @@ static ssize_t subordinate_bus_number_show(struct device *dev, u8 sub_bus; int err; + pci_config_pm_runtime_get(pci_dev); err = pci_read_config_byte(pci_dev, PCI_SUBORDINATE_BUS, &sub_bus); + pci_config_pm_runtime_put(pci_dev); + if (err) return -EINVAL; @@ -694,6 +720,22 @@ static ssize_t boot_vga_show(struct device *dev, struct device_attribute *attr, } static DEVICE_ATTR_RO(boot_vga); +static ssize_t serial_number_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct pci_dev *pci_dev = to_pci_dev(dev); + u64 dsn; + u8 bytes[8]; + + dsn = pci_get_dsn(pci_dev); + if (!dsn) + return -EIO; + + put_unaligned_be64(dsn, bytes); + return sysfs_emit(buf, "%8phD\n", bytes); +} +static DEVICE_ATTR_ADMIN_RO(serial_number); + static ssize_t pci_read_config(struct file *filp, struct kobject *kobj, const struct bin_attribute *bin_attr, char *buf, loff_t off, size_t count) @@ -1475,8 +1517,9 @@ static ssize_t reset_method_store(struct device *dev, return count; } - pm_runtime_get_sync(dev); - struct device *pmdev __free(pm_runtime_put) = dev; + ACQUIRE(pm_runtime_active_try, pm)(dev); + if (ACQUIRE_ERR(pm_runtime_active_try, &pm)) + return -ENXIO; if (sysfs_streq(buf, "default")) { pci_init_reset_methods(pdev); @@ -1555,13 +1598,19 @@ static ssize_t __resource_resize_store(struct device *dev, int n, const char *buf, size_t count) { struct pci_dev *pdev = to_pci_dev(dev); - unsigned long size, flags; + struct pci_bus *bus = pdev->bus; + struct resource *b_win, *res; + unsigned long size; int ret, i; u16 cmd; if (kstrtoul(buf, 0, &size) < 0) return -EINVAL; + b_win = pbus_select_window(bus, pci_resource_n(pdev, n)); + if (!b_win) + return -EINVAL; + device_lock(dev); if (dev->driver || pci_num_vf(pdev)) { ret = -EBUSY; @@ -1581,19 +1630,19 @@ static ssize_t __resource_resize_store(struct device *dev, int n, pci_write_config_word(pdev, PCI_COMMAND, cmd & ~PCI_COMMAND_MEMORY); - flags = pci_resource_flags(pdev, n); - pci_remove_resource_files(pdev); - for (i = 0; i < PCI_BRIDGE_RESOURCES; i++) { - if (pci_resource_len(pdev, i) && - pci_resource_flags(pdev, i) == flags) + pci_dev_for_each_resource(pdev, res, i) { + if (i >= PCI_BRIDGE_RESOURCES) + break; + + if (b_win == pbus_select_window(bus, res)) pci_release_resource(pdev, i); } ret = pci_resize_resource(pdev, n, size); - pci_assign_unassigned_bus_resources(pdev->bus); + pci_assign_unassigned_bus_resources(bus); if (pci_create_resource_files(pdev)) pci_warn(pdev, "Failed to recreate resource files after BAR resizing\n"); @@ -1698,6 +1747,7 @@ late_initcall(pci_sysfs_init); static struct attribute *pci_dev_dev_attrs[] = { &dev_attr_boot_vga.attr, + &dev_attr_serial_number.attr, NULL, }; @@ -1710,6 +1760,9 @@ static umode_t pci_dev_attrs_are_visible(struct kobject *kobj, if (a == &dev_attr_boot_vga.attr && pci_is_vga(pdev)) return a->mode; + if (a == &dev_attr_serial_number.attr && pci_get_dsn(pdev)) + return a->mode; + return 0; } diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 005b92e6585e..b14dd064006c 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -423,36 +423,10 @@ found: return 1; } -static u8 __pci_find_next_cap_ttl(struct pci_bus *bus, unsigned int devfn, - u8 pos, int cap, int *ttl) -{ - u8 id; - u16 ent; - - pci_bus_read_config_byte(bus, devfn, pos, &pos); - - while ((*ttl)--) { - if (pos < 0x40) - break; - pos &= ~3; - pci_bus_read_config_word(bus, devfn, pos, &ent); - - id = ent & 0xff; - if (id == 0xff) - break; - if (id == cap) - return pos; - pos = (ent >> 8); - } - return 0; -} - static u8 __pci_find_next_cap(struct pci_bus *bus, unsigned int devfn, u8 pos, int cap) { - int ttl = PCI_FIND_CAP_TTL; - - return __pci_find_next_cap_ttl(bus, devfn, pos, cap, &ttl); + return PCI_FIND_NEXT_CAP(pci_bus_read_config, pos, cap, bus, devfn); } u8 pci_find_next_capability(struct pci_dev *dev, u8 pos, int cap) @@ -553,42 +527,11 @@ EXPORT_SYMBOL(pci_bus_find_capability); */ u16 pci_find_next_ext_capability(struct pci_dev *dev, u16 start, int cap) { - u32 header; - int ttl; - u16 pos = PCI_CFG_SPACE_SIZE; - - /* minimum 8 bytes per capability */ - ttl = (PCI_CFG_SPACE_EXP_SIZE - PCI_CFG_SPACE_SIZE) / 8; - if (dev->cfg_size <= PCI_CFG_SPACE_SIZE) return 0; - if (start) - pos = start; - - if (pci_read_config_dword(dev, pos, &header) != PCIBIOS_SUCCESSFUL) - return 0; - - /* - * If we have no capabilities, this is indicated by cap ID, - * cap version and next pointer all being 0. - */ - if (header == 0) - return 0; - - while (ttl-- > 0) { - if (PCI_EXT_CAP_ID(header) == cap && pos != start) - return pos; - - pos = PCI_EXT_CAP_NEXT(header); - if (pos < PCI_CFG_SPACE_SIZE) - break; - - if (pci_read_config_dword(dev, pos, &header) != PCIBIOS_SUCCESSFUL) - break; - } - - return 0; + return PCI_FIND_NEXT_EXT_CAP(pci_bus_read_config, start, cap, + dev->bus, dev->devfn); } EXPORT_SYMBOL_GPL(pci_find_next_ext_capability); @@ -648,7 +591,7 @@ EXPORT_SYMBOL_GPL(pci_get_dsn); static u8 __pci_find_next_ht_cap(struct pci_dev *dev, u8 pos, int ht_cap) { - int rc, ttl = PCI_FIND_CAP_TTL; + int rc; u8 cap, mask; if (ht_cap == HT_CAPTYPE_SLAVE || ht_cap == HT_CAPTYPE_HOST) @@ -656,8 +599,8 @@ static u8 __pci_find_next_ht_cap(struct pci_dev *dev, u8 pos, int ht_cap) else mask = HT_5BIT_CAP_MASK; - pos = __pci_find_next_cap_ttl(dev->bus, dev->devfn, pos, - PCI_CAP_ID_HT, &ttl); + pos = PCI_FIND_NEXT_CAP(pci_bus_read_config, pos, + PCI_CAP_ID_HT, dev->bus, dev->devfn); while (pos) { rc = pci_read_config_byte(dev, pos + 3, &cap); if (rc != PCIBIOS_SUCCESSFUL) @@ -666,9 +609,10 @@ static u8 __pci_find_next_ht_cap(struct pci_dev *dev, u8 pos, int ht_cap) if ((cap & mask) == ht_cap) return pos; - pos = __pci_find_next_cap_ttl(dev->bus, dev->devfn, - pos + PCI_CAP_LIST_NEXT, - PCI_CAP_ID_HT, &ttl); + pos = PCI_FIND_NEXT_CAP(pci_bus_read_config, + pos + PCI_CAP_LIST_NEXT, + PCI_CAP_ID_HT, dev->bus, + dev->devfn); } return 0; @@ -1374,6 +1318,11 @@ int pci_power_up(struct pci_dev *dev) return -EIO; } + if (pci_dev_is_disconnected(dev)) { + dev->current_state = PCI_D3cold; + return -EIO; + } + pci_read_config_word(dev, dev->pm_cap + PCI_PM_CTRL, &pmcsr); if (PCI_POSSIBLE_ERROR(pmcsr)) { pci_err(dev, "Unable to change power state from %s to D0, device inaccessible\n", diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h index 34f65d69662e..4492b809094b 100644 --- a/drivers/pci/pci.h +++ b/drivers/pci/pci.h @@ -2,12 +2,15 @@ #ifndef DRIVERS_PCI_H #define DRIVERS_PCI_H +#include <linux/align.h> +#include <linux/bitfield.h> #include <linux/pci.h> struct pcie_tlp_log; /* Number of possible devfns: 0.0 to 1f.7 inclusive */ #define MAX_NR_DEVFNS 256 +#define PCI_MAX_NR_DEVS 32 #define MAX_NR_LANES 16 @@ -81,13 +84,102 @@ struct pcie_tlp_log; #define PCIE_MSG_CODE_DEASSERT_INTC 0x26 #define PCIE_MSG_CODE_DEASSERT_INTD 0x27 +#define PCI_BUS_BRIDGE_IO_WINDOW 0 +#define PCI_BUS_BRIDGE_MEM_WINDOW 1 +#define PCI_BUS_BRIDGE_PREF_MEM_WINDOW 2 + extern const unsigned char pcie_link_speed[]; extern bool pci_early_dump; +extern struct mutex pci_rescan_remove_lock; + bool pcie_cap_has_lnkctl(const struct pci_dev *dev); bool pcie_cap_has_lnkctl2(const struct pci_dev *dev); bool pcie_cap_has_rtctl(const struct pci_dev *dev); +/* Standard Capability finder */ +/** + * PCI_FIND_NEXT_CAP - Find a PCI standard capability + * @read_cfg: Function pointer for reading PCI config space + * @start: Starting position to begin search + * @cap: Capability ID to find + * @args: Arguments to pass to read_cfg function + * + * Search the capability list in PCI config space to find @cap. + * Implements TTL (time-to-live) protection against infinite loops. + * + * Return: Position of the capability if found, 0 otherwise. + */ +#define PCI_FIND_NEXT_CAP(read_cfg, start, cap, args...) \ +({ \ + int __ttl = PCI_FIND_CAP_TTL; \ + u8 __id, __found_pos = 0; \ + u8 __pos = (start); \ + u16 __ent; \ + \ + read_cfg##_byte(args, __pos, &__pos); \ + \ + while (__ttl--) { \ + if (__pos < PCI_STD_HEADER_SIZEOF) \ + break; \ + \ + __pos = ALIGN_DOWN(__pos, 4); \ + read_cfg##_word(args, __pos, &__ent); \ + \ + __id = FIELD_GET(PCI_CAP_ID_MASK, __ent); \ + if (__id == 0xff) \ + break; \ + \ + if (__id == (cap)) { \ + __found_pos = __pos; \ + break; \ + } \ + \ + __pos = FIELD_GET(PCI_CAP_LIST_NEXT_MASK, __ent); \ + } \ + __found_pos; \ +}) + +/* Extended Capability finder */ +/** + * PCI_FIND_NEXT_EXT_CAP - Find a PCI extended capability + * @read_cfg: Function pointer for reading PCI config space + * @start: Starting position to begin search (0 for initial search) + * @cap: Extended capability ID to find + * @args: Arguments to pass to read_cfg function + * + * Search the extended capability list in PCI config space to find @cap. + * Implements TTL protection against infinite loops using a calculated + * maximum search count. + * + * Return: Position of the capability if found, 0 otherwise. + */ +#define PCI_FIND_NEXT_EXT_CAP(read_cfg, start, cap, args...) \ +({ \ + u16 __pos = (start) ?: PCI_CFG_SPACE_SIZE; \ + u16 __found_pos = 0; \ + int __ttl, __ret; \ + u32 __header; \ + \ + __ttl = (PCI_CFG_SPACE_EXP_SIZE - PCI_CFG_SPACE_SIZE) / 8; \ + while (__ttl-- > 0 && __pos >= PCI_CFG_SPACE_SIZE) { \ + __ret = read_cfg##_dword(args, __pos, &__header); \ + if (__ret != PCIBIOS_SUCCESSFUL) \ + break; \ + \ + if (__header == 0) \ + break; \ + \ + if (PCI_EXT_CAP_ID(__header) == (cap) && __pos != start) {\ + __found_pos = __pos; \ + break; \ + } \ + \ + __pos = PCI_EXT_CAP_NEXT(__header); \ + } \ + __found_pos; \ +}) + /* Functions internal to the PCI core code */ #ifdef CONFIG_DMI @@ -330,7 +422,7 @@ struct device *pci_get_host_bridge_device(struct pci_dev *dev); void pci_put_host_bridge_device(struct device *dev); unsigned int pci_rescan_bus_bridge_resize(struct pci_dev *bridge); -int pci_reassign_bridge_resources(struct pci_dev *bridge, unsigned long type); +int pbus_reassign_bridge_resources(struct pci_bus *bus, struct resource *res); int __must_check pci_reassign_resource(struct pci_dev *dev, int i, resource_size_t add_size, resource_size_t align); int pci_configure_extended_tags(struct pci_dev *dev, void *ign); @@ -381,6 +473,8 @@ static inline int pci_resource_num(const struct pci_dev *dev, return resno; } +struct resource *pbus_select_window(struct pci_bus *bus, + const struct resource *res); void pci_reassigndev_resource_alignment(struct pci_dev *dev); void pci_disable_bridge_window(struct pci_dev *dev); struct pci_bus *pci_bus_get(struct pci_bus *bus); diff --git a/drivers/pci/pcie/aer.c b/drivers/pci/pcie/aer.c index e286c197d716..0b5ed4722ac3 100644 --- a/drivers/pci/pcie/aer.c +++ b/drivers/pci/pcie/aer.c @@ -43,7 +43,7 @@ #define AER_ERROR_SOURCES_MAX 128 #define AER_MAX_TYPEOF_COR_ERRS 16 /* as per PCI_ERR_COR_STATUS */ -#define AER_MAX_TYPEOF_UNCOR_ERRS 27 /* as per PCI_ERR_UNCOR_STATUS*/ +#define AER_MAX_TYPEOF_UNCOR_ERRS 32 /* as per PCI_ERR_UNCOR_STATUS*/ struct aer_err_source { u32 status; /* PCI_ERR_ROOT_STATUS */ @@ -96,11 +96,21 @@ struct aer_info { }; #define AER_LOG_TLP_MASKS (PCI_ERR_UNC_POISON_TLP| \ + PCI_ERR_UNC_POISON_BLK | \ PCI_ERR_UNC_ECRC| \ PCI_ERR_UNC_UNSUP| \ PCI_ERR_UNC_COMP_ABORT| \ PCI_ERR_UNC_UNX_COMP| \ - PCI_ERR_UNC_MALF_TLP) + PCI_ERR_UNC_ACSV | \ + PCI_ERR_UNC_MCBTLP | \ + PCI_ERR_UNC_ATOMEG | \ + PCI_ERR_UNC_DMWR_BLK | \ + PCI_ERR_UNC_XLAT_BLK | \ + PCI_ERR_UNC_TLPPRE | \ + PCI_ERR_UNC_MALF_TLP | \ + PCI_ERR_UNC_IDE_CHECK | \ + PCI_ERR_UNC_MISR_IDE | \ + PCI_ERR_UNC_PCRC_CHECK) #define SYSTEM_ERROR_INTR_ON_MESG_MASK (PCI_EXP_RTCTL_SECEE| \ PCI_EXP_RTCTL_SENFEE| \ @@ -383,6 +393,10 @@ void pci_aer_init(struct pci_dev *dev) return; dev->aer_info = kzalloc(sizeof(*dev->aer_info), GFP_KERNEL); + if (!dev->aer_info) { + dev->aer_cap = 0; + return; + } ratelimit_state_init(&dev->aer_info->correctable_ratelimit, DEFAULT_RATELIMIT_INTERVAL, DEFAULT_RATELIMIT_BURST); @@ -525,11 +539,11 @@ static const char *aer_uncorrectable_error_string[] = { "AtomicOpBlocked", /* Bit Position 24 */ "TLPBlockedErr", /* Bit Position 25 */ "PoisonTLPBlocked", /* Bit Position 26 */ - NULL, /* Bit Position 27 */ - NULL, /* Bit Position 28 */ - NULL, /* Bit Position 29 */ - NULL, /* Bit Position 30 */ - NULL, /* Bit Position 31 */ + "DMWrReqBlocked", /* Bit Position 27 */ + "IDECheck", /* Bit Position 28 */ + "MisIDETLP", /* Bit Position 29 */ + "PCRC_CHECK", /* Bit Position 30 */ + "TLPXlatBlocked", /* Bit Position 31 */ }; static const char *aer_agent_string[] = { @@ -786,6 +800,9 @@ static void pci_rootport_aer_stats_incr(struct pci_dev *pdev, static int aer_ratelimit(struct pci_dev *dev, unsigned int severity) { + if (!dev->aer_info) + return 1; + switch (severity) { case AER_NONFATAL: return __ratelimit(&dev->aer_info->nonfatal_ratelimit); @@ -796,6 +813,20 @@ static int aer_ratelimit(struct pci_dev *dev, unsigned int severity) } } +static bool tlp_header_logged(u32 status, u32 capctl) +{ + /* Errors for which a header is always logged (PCIe r7.0 sec 6.2.7) */ + if (status & AER_LOG_TLP_MASKS) + return true; + + /* Completion Timeout header is only logged on capable devices */ + if (status & PCI_ERR_UNC_COMP_TIME && + capctl & PCI_ERR_CAP_COMP_TIME_LOG) + return true; + + return false; +} + static void __aer_print_error(struct pci_dev *dev, struct aer_err_info *info) { const char **strings; @@ -910,7 +941,7 @@ void pci_print_aer(struct pci_dev *dev, int aer_severity, status = aer->uncor_status; mask = aer->uncor_mask; info.level = KERN_ERR; - tlp_header_valid = status & AER_LOG_TLP_MASKS; + tlp_header_valid = tlp_header_logged(status, aer->cap_control); } info.status = status; @@ -1401,7 +1432,7 @@ int aer_get_device_error_info(struct aer_err_info *info, int i) pci_read_config_dword(dev, aer + PCI_ERR_CAP, &aercc); info->first_error = PCI_ERR_CAP_FEP(aercc); - if (info->status & AER_LOG_TLP_MASKS) { + if (tlp_header_logged(info->status, aercc)) { info->tlp_header_valid = 1; pcie_read_tlp_log(dev, aer + PCI_ERR_HEADER_LOG, aer + PCI_ERR_PREFIX_LOG, diff --git a/drivers/pci/pcie/aspm.c b/drivers/pci/pcie/aspm.c index 919a05b97647..7cc8281e7011 100644 --- a/drivers/pci/pcie/aspm.c +++ b/drivers/pci/pcie/aspm.c @@ -15,6 +15,7 @@ #include <linux/math.h> #include <linux/module.h> #include <linux/moduleparam.h> +#include <linux/of.h> #include <linux/pci.h> #include <linux/pci_regs.h> #include <linux/errno.h> @@ -235,13 +236,15 @@ struct pcie_link_state { u32 aspm_support:7; /* Supported ASPM state */ u32 aspm_enabled:7; /* Enabled ASPM state */ u32 aspm_capable:7; /* Capable ASPM state with latency */ - u32 aspm_default:7; /* Default ASPM state by BIOS */ + u32 aspm_default:7; /* Default ASPM state by BIOS or + override */ u32 aspm_disable:7; /* Disabled ASPM state */ /* Clock PM state */ u32 clkpm_capable:1; /* Clock PM capable? */ u32 clkpm_enabled:1; /* Current Clock PM state */ - u32 clkpm_default:1; /* Default Clock PM state by BIOS */ + u32 clkpm_default:1; /* Default Clock PM state by BIOS or + override */ u32 clkpm_disable:1; /* Clock PM disabled */ }; @@ -373,6 +376,18 @@ static void pcie_set_clkpm(struct pcie_link_state *link, int enable) pcie_set_clkpm_nocheck(link, enable); } +static void pcie_clkpm_override_default_link_state(struct pcie_link_state *link, + int enabled) +{ + struct pci_dev *pdev = link->downstream; + + /* For devicetree platforms, enable ClockPM by default */ + if (of_have_populated_dt() && !enabled) { + link->clkpm_default = 1; + pci_info(pdev, "ASPM: DT platform, enabling ClockPM\n"); + } +} + static void pcie_clkpm_cap_init(struct pcie_link_state *link, int blacklist) { int capable = 1, enabled = 1; @@ -395,6 +410,7 @@ static void pcie_clkpm_cap_init(struct pcie_link_state *link, int blacklist) } link->clkpm_enabled = enabled; link->clkpm_default = enabled; + pcie_clkpm_override_default_link_state(link, enabled); link->clkpm_capable = capable; link->clkpm_disable = blacklist ? 1 : 0; } @@ -788,6 +804,29 @@ static void aspm_l1ss_init(struct pcie_link_state *link) aspm_calc_l12_info(link, parent_l1ss_cap, child_l1ss_cap); } +#define FLAG(x, y, d) (((x) & (PCIE_LINK_STATE_##y)) ? d : "") + +static void pcie_aspm_override_default_link_state(struct pcie_link_state *link) +{ + struct pci_dev *pdev = link->downstream; + u32 override; + + /* For devicetree platforms, enable all ASPM states by default */ + if (of_have_populated_dt()) { + link->aspm_default = PCIE_LINK_STATE_ASPM_ALL; + override = link->aspm_default & ~link->aspm_enabled; + if (override) + pci_info(pdev, "ASPM: DT platform, enabling%s%s%s%s%s%s%s\n", + FLAG(override, L0S_UP, " L0s-up"), + FLAG(override, L0S_DW, " L0s-dw"), + FLAG(override, L1, " L1"), + FLAG(override, L1_1, " ASPM-L1.1"), + FLAG(override, L1_2, " ASPM-L1.2"), + FLAG(override, L1_1_PCIPM, " PCI-PM-L1.1"), + FLAG(override, L1_2_PCIPM, " PCI-PM-L1.2")); + } +} + static void pcie_aspm_cap_init(struct pcie_link_state *link, int blacklist) { struct pci_dev *child = link->downstream, *parent = link->pdev; @@ -868,6 +907,8 @@ static void pcie_aspm_cap_init(struct pcie_link_state *link, int blacklist) /* Save default state */ link->aspm_default = link->aspm_enabled; + pcie_aspm_override_default_link_state(link); + /* Setup initial capable state. Will be updated later */ link->aspm_capable = link->aspm_support; diff --git a/drivers/pci/pcie/err.c b/drivers/pci/pcie/err.c index de6381c690f5..bebe4bc111d7 100644 --- a/drivers/pci/pcie/err.c +++ b/drivers/pci/pcie/err.c @@ -108,6 +108,24 @@ static int report_normal_detected(struct pci_dev *dev, void *data) return report_error_detected(dev, pci_channel_io_normal, data); } +static int report_perm_failure_detected(struct pci_dev *dev, void *data) +{ + struct pci_driver *pdrv; + const struct pci_error_handlers *err_handler; + + device_lock(&dev->dev); + pdrv = dev->driver; + if (!pdrv || !pdrv->err_handler || !pdrv->err_handler->error_detected) + goto out; + + err_handler = pdrv->err_handler; + err_handler->error_detected(dev, pci_channel_io_perm_failure); +out: + pci_uevent_ers(dev, PCI_ERS_RESULT_DISCONNECT); + device_unlock(&dev->dev); + return 0; +} + static int report_mmio_enabled(struct pci_dev *dev, void *data) { struct pci_driver *pdrv; @@ -135,7 +153,8 @@ static int report_slot_reset(struct pci_dev *dev, void *data) device_lock(&dev->dev); pdrv = dev->driver; - if (!pdrv || !pdrv->err_handler || !pdrv->err_handler->slot_reset) + if (!pci_dev_set_io_state(dev, pci_channel_io_normal) || + !pdrv || !pdrv->err_handler || !pdrv->err_handler->slot_reset) goto out; err_handler = pdrv->err_handler; @@ -217,15 +236,10 @@ pci_ers_result_t pcie_do_recovery(struct pci_dev *dev, pci_walk_bridge(bridge, pci_pm_runtime_get_sync, NULL); pci_dbg(bridge, "broadcast error_detected message\n"); - if (state == pci_channel_io_frozen) { + if (state == pci_channel_io_frozen) pci_walk_bridge(bridge, report_frozen_detected, &status); - if (reset_subordinates(bridge) != PCI_ERS_RESULT_RECOVERED) { - pci_warn(bridge, "subordinate device reset failed\n"); - goto failed; - } - } else { + else pci_walk_bridge(bridge, report_normal_detected, &status); - } if (status == PCI_ERS_RESULT_CAN_RECOVER) { status = PCI_ERS_RESULT_RECOVERED; @@ -233,6 +247,14 @@ pci_ers_result_t pcie_do_recovery(struct pci_dev *dev, pci_walk_bridge(bridge, report_mmio_enabled, &status); } + if (status == PCI_ERS_RESULT_NEED_RESET || + state == pci_channel_io_frozen) { + if (reset_subordinates(bridge) != PCI_ERS_RESULT_RECOVERED) { + pci_warn(bridge, "subordinate device reset failed\n"); + goto failed; + } + } + if (status == PCI_ERS_RESULT_NEED_RESET) { /* * TODO: Should call platform-specific @@ -269,7 +291,7 @@ pci_ers_result_t pcie_do_recovery(struct pci_dev *dev, failed: pci_walk_bridge(bridge, pci_pm_runtime_put, NULL); - pci_uevent_ers(bridge, PCI_ERS_RESULT_DISCONNECT); + pci_walk_bridge(bridge, report_perm_failure_detected, NULL); pci_info(bridge, "device recovery failed\n"); diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index f41128f91ca7..c83e75a0ec12 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c @@ -3,6 +3,7 @@ * PCI detection and setup code */ +#include <linux/array_size.h> #include <linux/kernel.h> #include <linux/delay.h> #include <linux/init.h> @@ -419,13 +420,17 @@ static void pci_read_bridge_io(struct pci_dev *dev, struct resource *res, limit |= ((unsigned long) io_limit_hi << 16); } + res->flags = (io_base_lo & PCI_IO_RANGE_TYPE_MASK) | IORESOURCE_IO; + if (base <= limit) { - res->flags = (io_base_lo & PCI_IO_RANGE_TYPE_MASK) | IORESOURCE_IO; region.start = base; region.end = limit + io_granularity - 1; pcibios_bus_to_resource(dev->bus, res, ®ion); if (log) pci_info(dev, " bridge window %pR\n", res); + } else { + resource_set_range(res, 0, 0); + res->flags |= IORESOURCE_UNSET | IORESOURCE_DISABLED; } } @@ -440,13 +445,18 @@ static void pci_read_bridge_mmio(struct pci_dev *dev, struct resource *res, pci_read_config_word(dev, PCI_MEMORY_LIMIT, &mem_limit_lo); base = ((unsigned long) mem_base_lo & PCI_MEMORY_RANGE_MASK) << 16; limit = ((unsigned long) mem_limit_lo & PCI_MEMORY_RANGE_MASK) << 16; + + res->flags = (mem_base_lo & PCI_MEMORY_RANGE_TYPE_MASK) | IORESOURCE_MEM; + if (base <= limit) { - res->flags = (mem_base_lo & PCI_MEMORY_RANGE_TYPE_MASK) | IORESOURCE_MEM; region.start = base; region.end = limit + 0xfffff; pcibios_bus_to_resource(dev->bus, res, ®ion); if (log) pci_info(dev, " bridge window %pR\n", res); + } else { + resource_set_range(res, 0, 0); + res->flags |= IORESOURCE_UNSET | IORESOURCE_DISABLED; } } @@ -489,16 +499,20 @@ static void pci_read_bridge_mmio_pref(struct pci_dev *dev, struct resource *res, return; } + res->flags = (mem_base_lo & PCI_PREF_RANGE_TYPE_MASK) | IORESOURCE_MEM | + IORESOURCE_PREFETCH; + if (res->flags & PCI_PREF_RANGE_TYPE_64) + res->flags |= IORESOURCE_MEM_64; + if (base <= limit) { - res->flags = (mem_base_lo & PCI_PREF_RANGE_TYPE_MASK) | - IORESOURCE_MEM | IORESOURCE_PREFETCH; - if (res->flags & PCI_PREF_RANGE_TYPE_64) - res->flags |= IORESOURCE_MEM_64; region.start = base; region.end = limit + 0xfffff; pcibios_bus_to_resource(dev->bus, res, ®ion); if (log) pci_info(dev, " bridge window %pR\n", res); + } else { + resource_set_range(res, 0, 0); + res->flags |= IORESOURCE_UNSET | IORESOURCE_DISABLED; } } @@ -524,10 +538,14 @@ static void pci_read_bridge_windows(struct pci_dev *bridge) } if (io) { bridge->io_window = 1; - pci_read_bridge_io(bridge, &res, true); + pci_read_bridge_io(bridge, + pci_resource_n(bridge, PCI_BRIDGE_IO_WINDOW), + true); } - pci_read_bridge_mmio(bridge, &res, true); + pci_read_bridge_mmio(bridge, + pci_resource_n(bridge, PCI_BRIDGE_MEM_WINDOW), + true); /* * DECchip 21050 pass 2 errata: the bridge may miss an address @@ -565,7 +583,10 @@ static void pci_read_bridge_windows(struct pci_dev *bridge) bridge->pref_64_window = 1; } - pci_read_bridge_mmio_pref(bridge, &res, true); + pci_read_bridge_mmio_pref(bridge, + pci_resource_n(bridge, + PCI_BRIDGE_PREF_MEM_WINDOW), + true); } void pci_read_bridge_bases(struct pci_bus *child) @@ -585,9 +606,13 @@ void pci_read_bridge_bases(struct pci_bus *child) for (i = 0; i < PCI_BRIDGE_RESOURCE_NUM; i++) child->resource[i] = &dev->resource[PCI_BRIDGE_RESOURCES+i]; - pci_read_bridge_io(child->self, child->resource[0], false); - pci_read_bridge_mmio(child->self, child->resource[1], false); - pci_read_bridge_mmio_pref(child->self, child->resource[2], false); + pci_read_bridge_io(child->self, + child->resource[PCI_BUS_BRIDGE_IO_WINDOW], false); + pci_read_bridge_mmio(child->self, + child->resource[PCI_BUS_BRIDGE_MEM_WINDOW], false); + pci_read_bridge_mmio_pref(child->self, + child->resource[PCI_BUS_BRIDGE_PREF_MEM_WINDOW], + false); if (!dev->transparent) return; @@ -1912,16 +1937,16 @@ static int pci_intx_mask_broken(struct pci_dev *dev) static void early_dump_pci_device(struct pci_dev *pdev) { - u32 value[256 / 4]; + u32 value[PCI_CFG_SPACE_SIZE / sizeof(u32)]; int i; pci_info(pdev, "config space:\n"); - for (i = 0; i < 256; i += 4) - pci_read_config_dword(pdev, i, &value[i / 4]); + for (i = 0; i < ARRAY_SIZE(value); i++) + pci_read_config_dword(pdev, i * sizeof(u32), &value[i]); print_hex_dump(KERN_INFO, "", DUMP_PREFIX_OFFSET, 16, 1, - value, 256, false); + value, ARRAY_SIZE(value) * sizeof(u32), false); } static const char *pci_type_str(struct pci_dev *dev) @@ -1985,8 +2010,8 @@ int pci_setup_device(struct pci_dev *dev) dev->sysdata = dev->bus->sysdata; dev->dev.parent = dev->bus->bridge; dev->dev.bus = &pci_bus_type; - dev->hdr_type = hdr_type & 0x7f; - dev->multifunction = !!(hdr_type & 0x80); + dev->hdr_type = FIELD_GET(PCI_HEADER_TYPE_MASK, hdr_type); + dev->multifunction = FIELD_GET(PCI_HEADER_TYPE_MFD, hdr_type); dev->error_state = pci_channel_io_normal; set_pcie_port_type(dev); @@ -2516,9 +2541,15 @@ static struct platform_device *pci_pwrctrl_create_device(struct pci_bus *bus, in struct device_node *np; np = of_pci_find_child_device(dev_of_node(&bus->dev), devfn); - if (!np || of_find_device_by_node(np)) + if (!np) return NULL; + pdev = of_find_device_by_node(np); + if (pdev) { + put_device(&pdev->dev); + goto err_put_of_node; + } + /* * First check whether the pwrctrl device really needs to be created or * not. This is decided based on at least one of the power supplies @@ -2526,17 +2557,24 @@ static struct platform_device *pci_pwrctrl_create_device(struct pci_bus *bus, in */ if (!of_pci_supply_present(np)) { pr_debug("PCI/pwrctrl: Skipping OF node: %s\n", np->name); - return NULL; + goto err_put_of_node; } /* Now create the pwrctrl device */ pdev = of_platform_device_create(np, NULL, &host->dev); if (!pdev) { pr_err("PCI/pwrctrl: Failed to create pwrctrl device for node: %s\n", np->name); - return NULL; + goto err_put_of_node; } + of_node_put(np); + return pdev; + +err_put_of_node: + of_node_put(np); + + return NULL; } #else static struct platform_device *pci_pwrctrl_create_device(struct pci_bus *bus, int devfn) @@ -3045,14 +3083,14 @@ static unsigned int pci_scan_child_bus_extend(struct pci_bus *bus, { unsigned int used_buses, normal_bridges = 0, hotplug_bridges = 0; unsigned int start = bus->busn_res.start; - unsigned int devfn, cmax, max = start; + unsigned int devnr, cmax, max = start; struct pci_dev *dev; dev_dbg(&bus->dev, "scanning bus\n"); /* Go find them, Rover! */ - for (devfn = 0; devfn < 256; devfn += 8) - pci_scan_slot(bus, devfn); + for (devnr = 0; devnr < PCI_MAX_NR_DEVS; devnr++) + pci_scan_slot(bus, PCI_DEVFN(devnr, 0)); /* Reserve buses for SR-IOV capability */ used_buses = pci_iov_bus_range(bus); @@ -3469,7 +3507,7 @@ EXPORT_SYMBOL_GPL(pci_rescan_bus); * pci_rescan_bus(), pci_rescan_bus_bridge_resize() and PCI device removal * routines should always be executed under this mutex. */ -static DEFINE_MUTEX(pci_rescan_remove_lock); +DEFINE_MUTEX(pci_rescan_remove_lock); void pci_lock_rescan_remove(void) { diff --git a/drivers/pci/pwrctrl/slot.c b/drivers/pci/pwrctrl/slot.c index 6e138310b45b..3320494b62d8 100644 --- a/drivers/pci/pwrctrl/slot.c +++ b/drivers/pci/pwrctrl/slot.c @@ -49,13 +49,14 @@ static int pci_pwrctrl_slot_probe(struct platform_device *pdev) ret = regulator_bulk_enable(slot->num_supplies, slot->supplies); if (ret < 0) { dev_err_probe(dev, ret, "Failed to enable slot regulators\n"); - goto err_regulator_free; + regulator_bulk_free(slot->num_supplies, slot->supplies); + return ret; } ret = devm_add_action_or_reset(dev, devm_pci_pwrctrl_slot_power_off, slot); if (ret) - goto err_regulator_disable; + return ret; clk = devm_clk_get_optional_enabled(dev, NULL); if (IS_ERR(clk)) { @@ -70,13 +71,6 @@ static int pci_pwrctrl_slot_probe(struct platform_device *pdev) return dev_err_probe(dev, ret, "Failed to register pwrctrl driver\n"); return 0; - -err_regulator_disable: - regulator_bulk_disable(slot->num_supplies, slot->supplies); -err_regulator_free: - regulator_bulk_free(slot->num_supplies, slot->supplies); - - return ret; } static const struct of_device_id pci_pwrctrl_slot_of_match[] = { diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index 17315a825674..214ed060ca1b 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c @@ -2717,6 +2717,7 @@ static void quirk_disable_msi(struct pci_dev *dev) DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8131_BRIDGE, quirk_disable_msi); DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, 0xa238, quirk_disable_msi); DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, 0x5a3f, quirk_disable_msi); +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_RDC, 0x1031, quirk_disable_msi); /* * The APC bridge device in AMD 780 family northbridges has some random diff --git a/drivers/pci/remove.c b/drivers/pci/remove.c index 445afdfa6498..ce5c25adef55 100644 --- a/drivers/pci/remove.c +++ b/drivers/pci/remove.c @@ -31,6 +31,8 @@ static void pci_pwrctrl_unregister(struct device *dev) return; of_device_unregister(pdev); + put_device(&pdev->dev); + of_node_clear_flag(np, OF_POPULATED); } @@ -138,6 +140,7 @@ static void pci_remove_bus_device(struct pci_dev *dev) */ void pci_stop_and_remove_bus_device(struct pci_dev *dev) { + lockdep_assert_held(&pci_rescan_remove_lock); pci_stop_bus_device(dev); pci_remove_bus_device(dev); } diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c index 7853ac6999e2..362ad108794d 100644 --- a/drivers/pci/setup-bus.c +++ b/drivers/pci/setup-bus.c @@ -28,6 +28,10 @@ #include <linux/acpi.h> #include "pci.h" +#define PCI_RES_TYPE_MASK \ + (IORESOURCE_IO | IORESOURCE_MEM | IORESOURCE_PREFETCH |\ + IORESOURCE_MEM_64) + unsigned int pci_flags; EXPORT_SYMBOL_GPL(pci_flags); @@ -136,6 +140,139 @@ static void restore_dev_resource(struct pci_dev_resource *dev_res) res->flags = dev_res->flags; } +/* + * Helper function for sizing routines. Assigned resources have non-NULL + * parent resource. + * + * Return first unassigned resource of the correct type. If there is none, + * return first assigned resource of the correct type. If none of the + * above, return NULL. + * + * Returning an assigned resource of the correct type allows the caller to + * distinguish between already assigned and no resource of the correct type. + */ +static struct resource *find_bus_resource_of_type(struct pci_bus *bus, + unsigned long type_mask, + unsigned long type) +{ + struct resource *r, *r_assigned = NULL; + + pci_bus_for_each_resource(bus, r) { + if (!r || r == &ioport_resource || r == &iomem_resource) + continue; + + if ((r->flags & type_mask) != type) + continue; + + if (!r->parent) + return r; + if (!r_assigned) + r_assigned = r; + } + return r_assigned; +} + +/** + * pbus_select_window_for_type - Select bridge window for a resource type + * @bus: PCI bus + * @type: Resource type (resource flags can be passed as is) + * + * Select the bridge window based on a resource @type. + * + * For memory resources, the selection is done as follows: + * + * Any non-prefetchable resource is put into the non-prefetchable window. + * + * If there is no prefetchable MMIO window, put all memory resources into the + * non-prefetchable window. + * + * If there's a 64-bit prefetchable MMIO window, put all 64-bit prefetchable + * resources into it and place 32-bit prefetchable memory into the + * non-prefetchable window. + * + * Otherwise, put all prefetchable resources into the prefetchable window. + * + * Return: the bridge window resource or NULL if no bridge window is found. + */ +static struct resource *pbus_select_window_for_type(struct pci_bus *bus, + unsigned long type) +{ + int iores_type = type & IORESOURCE_TYPE_BITS; /* w/o 64bit & pref */ + struct resource *mmio, *mmio_pref, *win; + + type &= PCI_RES_TYPE_MASK; /* with 64bit & pref */ + + if ((iores_type != IORESOURCE_IO) && (iores_type != IORESOURCE_MEM)) + return NULL; + + if (pci_is_root_bus(bus)) { + win = find_bus_resource_of_type(bus, type, type); + if (win) + return win; + + type &= ~IORESOURCE_MEM_64; + win = find_bus_resource_of_type(bus, type, type); + if (win) + return win; + + type &= ~IORESOURCE_PREFETCH; + return find_bus_resource_of_type(bus, type, type); + } + + switch (iores_type) { + case IORESOURCE_IO: + return pci_bus_resource_n(bus, PCI_BUS_BRIDGE_IO_WINDOW); + + case IORESOURCE_MEM: + mmio = pci_bus_resource_n(bus, PCI_BUS_BRIDGE_MEM_WINDOW); + mmio_pref = pci_bus_resource_n(bus, PCI_BUS_BRIDGE_PREF_MEM_WINDOW); + + if (!(type & IORESOURCE_PREFETCH) || + !(mmio_pref->flags & IORESOURCE_MEM)) + return mmio; + + if ((type & IORESOURCE_MEM_64) || + !(mmio_pref->flags & IORESOURCE_MEM_64)) + return mmio_pref; + + return mmio; + default: + return NULL; + } +} + +/** + * pbus_select_window - Select bridge window for a resource + * @bus: PCI bus + * @res: Resource + * + * Select the bridge window for @res. If the resource is already assigned, + * return the current bridge window. + * + * For memory resources, the selection is done as follows: + * + * Any non-prefetchable resource is put into the non-prefetchable window. + * + * If there is no prefetchable MMIO window, put all memory resources into the + * non-prefetchable window. + * + * If there's a 64-bit prefetchable MMIO window, put all 64-bit prefetchable + * resources into it and place 32-bit prefetchable memory into the + * non-prefetchable window. + * + * Otherwise, put all prefetchable resources into the prefetchable window. + * + * Return: the bridge window resource or NULL if no bridge window is found. + */ +struct resource *pbus_select_window(struct pci_bus *bus, + const struct resource *res) +{ + if (res->parent) + return res->parent; + + return pbus_select_window_for_type(bus, res->flags); +} + static bool pdev_resources_assignable(struct pci_dev *dev) { u16 class = dev->class >> 8, command; @@ -154,6 +291,31 @@ static bool pdev_resources_assignable(struct pci_dev *dev) return true; } +static bool pdev_resource_assignable(struct pci_dev *dev, struct resource *res) +{ + int idx = pci_resource_num(dev, res); + + if (!res->flags) + return false; + + if (idx >= PCI_BRIDGE_RESOURCES && idx <= PCI_BRIDGE_RESOURCE_END && + res->flags & IORESOURCE_DISABLED) + return false; + + return true; +} + +static bool pdev_resource_should_fit(struct pci_dev *dev, struct resource *res) +{ + if (res->parent) + return false; + + if (res->flags & IORESOURCE_PCI_FIXED) + return false; + + return pdev_resource_assignable(dev, res); +} + /* Sort resources by alignment */ static void pdev_sort_resources(struct pci_dev *dev, struct list_head *head) { @@ -169,10 +331,7 @@ static void pdev_sort_resources(struct pci_dev *dev, struct list_head *head) resource_size_t r_align; struct list_head *n; - if (r->flags & IORESOURCE_PCI_FIXED) - continue; - - if (!(r->flags) || r->parent) + if (!pdev_resource_should_fit(dev, r)) continue; r_align = pci_resource_alignment(dev, r); @@ -221,8 +380,15 @@ bool pci_resource_is_optional(const struct pci_dev *dev, int resno) return false; } -static inline void reset_resource(struct resource *res) +static inline void reset_resource(struct pci_dev *dev, struct resource *res) { + int idx = pci_resource_num(dev, res); + + if (idx >= PCI_BRIDGE_RESOURCES && idx <= PCI_BRIDGE_RESOURCE_END) { + res->flags |= IORESOURCE_UNSET; + return; + } + res->start = 0; res->end = 0; res->flags = 0; @@ -384,13 +550,19 @@ static bool pci_need_to_release(unsigned long mask, struct resource *res) } /* Return: @true if assignment of a required resource failed. */ -static bool pci_required_resource_failed(struct list_head *fail_head) +static bool pci_required_resource_failed(struct list_head *fail_head, + unsigned long type) { struct pci_dev_resource *fail_res; + type &= PCI_RES_TYPE_MASK; + list_for_each_entry(fail_res, fail_head, list) { int idx = pci_resource_num(fail_res->dev, fail_res->res); + if (type && (fail_res->flags & PCI_RES_TYPE_MASK) != type) + continue; + if (!pci_resource_is_optional(fail_res->dev, idx)) return true; } @@ -431,8 +603,6 @@ static void __assign_resources_sorted(struct list_head *head, struct pci_dev_resource *dev_res, *tmp_res, *dev_res2; struct resource *res; struct pci_dev *dev; - const char *res_name; - int idx; unsigned long fail_type; resource_size_t add_align, align; @@ -504,7 +674,7 @@ assign: } /* Without realloc_head and only optional fails, nothing more to do. */ - if (!pci_required_resource_failed(&local_fail_head) && + if (!pci_required_resource_failed(&local_fail_head, 0) && list_empty(realloc_head)) { list_for_each_entry(save_res, &save_head, list) { struct resource *res = save_res->res; @@ -540,14 +710,7 @@ assign: res = dev_res->res; dev = dev_res->dev; - if (!res->parent) - continue; - - idx = pci_resource_num(dev, res); - res_name = pci_resource_name(dev, idx); - pci_dbg(dev, "%s %pR: releasing\n", res_name, res); - - release_resource(res); + pci_release_resource(dev, pci_resource_num(dev, res)); restore_dev_resource(dev_res); } /* Restore start/end/flags from saved list */ @@ -577,7 +740,7 @@ out: 0 /* don't care */); } - reset_resource(res); + reset_resource(dev, res); } free_list(head); @@ -618,7 +781,7 @@ void pci_setup_cardbus(struct pci_bus *bus) res = bus->resource[0]; pcibios_resource_to_bus(bridge->bus, ®ion, res); - if (res->flags & IORESOURCE_IO) { + if (res->parent && res->flags & IORESOURCE_IO) { /* * The IO resource is allocated a range twice as large as it * would normally need. This allows us to set both IO regs. @@ -632,7 +795,7 @@ void pci_setup_cardbus(struct pci_bus *bus) res = bus->resource[1]; pcibios_resource_to_bus(bridge->bus, ®ion, res); - if (res->flags & IORESOURCE_IO) { + if (res->parent && res->flags & IORESOURCE_IO) { pci_info(bridge, " bridge window %pR\n", res); pci_write_config_dword(bridge, PCI_CB_IO_BASE_1, region.start); @@ -642,7 +805,7 @@ void pci_setup_cardbus(struct pci_bus *bus) res = bus->resource[2]; pcibios_resource_to_bus(bridge->bus, ®ion, res); - if (res->flags & IORESOURCE_MEM) { + if (res->parent && res->flags & IORESOURCE_MEM) { pci_info(bridge, " bridge window %pR\n", res); pci_write_config_dword(bridge, PCI_CB_MEMORY_BASE_0, region.start); @@ -652,7 +815,7 @@ void pci_setup_cardbus(struct pci_bus *bus) res = bus->resource[3]; pcibios_resource_to_bus(bridge->bus, ®ion, res); - if (res->flags & IORESOURCE_MEM) { + if (res->parent && res->flags & IORESOURCE_MEM) { pci_info(bridge, " bridge window %pR\n", res); pci_write_config_dword(bridge, PCI_CB_MEMORY_BASE_1, region.start); @@ -693,7 +856,7 @@ static void pci_setup_bridge_io(struct pci_dev *bridge) res = &bridge->resource[PCI_BRIDGE_IO_WINDOW]; res_name = pci_resource_name(bridge, PCI_BRIDGE_IO_WINDOW); pcibios_resource_to_bus(bridge->bus, ®ion, res); - if (res->flags & IORESOURCE_IO) { + if (res->parent && res->flags & IORESOURCE_IO) { pci_read_config_word(bridge, PCI_IO_BASE, &l); io_base_lo = (region.start >> 8) & io_mask; io_limit_lo = (region.end >> 8) & io_mask; @@ -725,7 +888,7 @@ static void pci_setup_bridge_mmio(struct pci_dev *bridge) res = &bridge->resource[PCI_BRIDGE_MEM_WINDOW]; res_name = pci_resource_name(bridge, PCI_BRIDGE_MEM_WINDOW); pcibios_resource_to_bus(bridge->bus, ®ion, res); - if (res->flags & IORESOURCE_MEM) { + if (res->parent && res->flags & IORESOURCE_MEM) { l = (region.start >> 16) & 0xfff0; l |= region.end & 0xfff00000; pci_info(bridge, " %s %pR\n", res_name, res); @@ -754,7 +917,7 @@ static void pci_setup_bridge_mmio_pref(struct pci_dev *bridge) res = &bridge->resource[PCI_BRIDGE_PREF_MEM_WINDOW]; res_name = pci_resource_name(bridge, PCI_BRIDGE_PREF_MEM_WINDOW); pcibios_resource_to_bus(bridge->bus, ®ion, res); - if (res->flags & IORESOURCE_PREFETCH) { + if (res->parent && res->flags & IORESOURCE_PREFETCH) { l = (region.start >> 16) & 0xfff0; l |= region.end & 0xfff00000; if (res->flags & IORESOURCE_MEM_64) { @@ -790,6 +953,23 @@ static void __pci_setup_bridge(struct pci_bus *bus, unsigned long type) pci_write_config_word(bridge, PCI_BRIDGE_CONTROL, bus->bridge_ctl); } +static void pci_setup_one_bridge_window(struct pci_dev *bridge, int resno) +{ + switch (resno) { + case PCI_BRIDGE_IO_WINDOW: + pci_setup_bridge_io(bridge); + break; + case PCI_BRIDGE_MEM_WINDOW: + pci_setup_bridge_mmio(bridge); + break; + case PCI_BRIDGE_PREF_MEM_WINDOW: + pci_setup_bridge_mmio_pref(bridge); + break; + default: + return; + } +} + void __weak pcibios_setup_bridge(struct pci_bus *bus, unsigned long type) { } @@ -806,6 +986,8 @@ static void pci_setup_bridge(struct pci_bus *bus) int pci_claim_bridge_resource(struct pci_dev *bridge, int i) { + int ret = -EINVAL; + if (i < PCI_BRIDGE_RESOURCES || i > PCI_BRIDGE_RESOURCE_END) return 0; @@ -815,27 +997,16 @@ int pci_claim_bridge_resource(struct pci_dev *bridge, int i) if ((bridge->class >> 8) != PCI_CLASS_BRIDGE_PCI) return 0; - if (!pci_bus_clip_resource(bridge, i)) - return -EINVAL; /* Clipping didn't change anything */ - - switch (i) { - case PCI_BRIDGE_IO_WINDOW: - pci_setup_bridge_io(bridge); - break; - case PCI_BRIDGE_MEM_WINDOW: - pci_setup_bridge_mmio(bridge); - break; - case PCI_BRIDGE_PREF_MEM_WINDOW: - pci_setup_bridge_mmio_pref(bridge); - break; - default: + if (i > PCI_BRIDGE_PREF_MEM_WINDOW) return -EINVAL; - } - if (pci_claim_resource(bridge, i) == 0) - return 0; /* Claimed a smaller window */ + /* Try to clip the resource and claim the smaller window */ + if (pci_bus_clip_resource(bridge, i)) + ret = pci_claim_resource(bridge, i); + + pci_setup_one_bridge_window(bridge, i); - return -EINVAL; + return ret; } /* @@ -866,34 +1037,6 @@ static void pci_bridge_check_ranges(struct pci_bus *bus) } } -/* - * Helper function for sizing routines. Assigned resources have non-NULL - * parent resource. - * - * Return first unassigned resource of the correct type. If there is none, - * return first assigned resource of the correct type. If none of the - * above, return NULL. - * - * Returning an assigned resource of the correct type allows the caller to - * distinguish between already assigned and no resource of the correct type. - */ -static struct resource *find_bus_resource_of_type(struct pci_bus *bus, - unsigned long type_mask, - unsigned long type) -{ - struct resource *r, *r_assigned = NULL; - - pci_bus_for_each_resource(bus, r) { - if (r == &ioport_resource || r == &iomem_resource) - continue; - if (r && (r->flags & type_mask) == type && !r->parent) - return r; - if (r && (r->flags & type_mask) == type && !r_assigned) - r_assigned = r; - } - return r_assigned; -} - static resource_size_t calculate_iosize(resource_size_t size, resource_size_t min_size, resource_size_t size1, @@ -984,8 +1127,7 @@ static void pbus_size_io(struct pci_bus *bus, resource_size_t min_size, struct list_head *realloc_head) { struct pci_dev *dev; - struct resource *b_res = find_bus_resource_of_type(bus, IORESOURCE_IO, - IORESOURCE_IO); + struct resource *b_res = pbus_select_window_for_type(bus, IORESOURCE_IO); resource_size_t size = 0, size0 = 0, size1 = 0; resource_size_t children_add_size = 0; resource_size_t min_align, align; @@ -1006,8 +1148,11 @@ static void pbus_size_io(struct pci_bus *bus, resource_size_t min_size, if (r->parent || !(r->flags & IORESOURCE_IO)) continue; - r_size = resource_size(r); + if (!pdev_resource_assignable(dev, r)) + continue; + + r_size = resource_size(r); if (r_size < SZ_1K) /* Might be re-aligned for ISA */ size += r_size; @@ -1026,6 +1171,9 @@ static void pbus_size_io(struct pci_bus *bus, resource_size_t min_size, size0 = calculate_iosize(size, min_size, size1, 0, 0, resource_size(b_res), min_align); + if (size0) + b_res->flags &= ~IORESOURCE_DISABLED; + size1 = size0; if (realloc_head && (add_size > 0 || children_add_size > 0)) { size1 = calculate_iosize(size, min_size, size1, add_size, @@ -1037,13 +1185,14 @@ static void pbus_size_io(struct pci_bus *bus, resource_size_t min_size, if (bus->self && (b_res->start || b_res->end)) pci_info(bus->self, "disabling bridge window %pR to %pR (unused)\n", b_res, &bus->busn_res); - b_res->flags = 0; + b_res->flags |= IORESOURCE_DISABLED; return; } resource_set_range(b_res, min_align, size0); b_res->flags |= IORESOURCE_STARTALIGN; if (bus->self && size1 > size0 && realloc_head) { + b_res->flags &= ~IORESOURCE_DISABLED; add_to_list(realloc_head, bus->self, b_res, size1-size0, min_align); pci_info(bus->self, "bridge window %pR to %pR add_size %llx\n", @@ -1077,19 +1226,20 @@ static inline resource_size_t calculate_mem_align(resource_size_t *aligns, /** * pbus_upstream_space_available - Check no upstream resource limits allocation * @bus: The bus - * @mask: Mask the resource flag, then compare it with type - * @type: The type of resource from bridge + * @res: The resource to help select the correct bridge window * @size: The size required from the bridge window * @align: Required alignment for the resource * - * Checks that @size can fit inside the upstream bridge resources that are - * already assigned. + * Check that @size can fit inside the upstream bridge resources that are + * already assigned. Select the upstream bridge window based on the type of + * @res. * * Return: %true if enough space is available on all assigned upstream * resources. */ -static bool pbus_upstream_space_available(struct pci_bus *bus, unsigned long mask, - unsigned long type, resource_size_t size, +static bool pbus_upstream_space_available(struct pci_bus *bus, + struct resource *res, + resource_size_t size, resource_size_t align) { struct resource_constraint constraint = { @@ -1097,39 +1247,39 @@ static bool pbus_upstream_space_available(struct pci_bus *bus, unsigned long mas .align = align, }; struct pci_bus *downstream = bus; - struct resource *r; while ((bus = bus->parent)) { if (pci_is_root_bus(bus)) break; - pci_bus_for_each_resource(bus, r) { - if (!r || !r->parent || (r->flags & mask) != type) - continue; - - if (resource_size(r) >= size) { - struct resource gap = {}; + res = pbus_select_window(bus, res); + if (!res) + return false; + if (!res->parent) + continue; - if (find_resource_space(r, &gap, size, &constraint) == 0) { - gap.flags = type; - pci_dbg(bus->self, - "Assigned bridge window %pR to %pR free space at %pR\n", - r, &bus->busn_res, &gap); - return true; - } - } + if (resource_size(res) >= size) { + struct resource gap = {}; - if (bus->self) { - pci_info(bus->self, - "Assigned bridge window %pR to %pR cannot fit 0x%llx required for %s bridging to %pR\n", - r, &bus->busn_res, - (unsigned long long)size, - pci_name(downstream->self), - &downstream->busn_res); + if (find_resource_space(res, &gap, size, &constraint) == 0) { + gap.flags = res->flags; + pci_dbg(bus->self, + "Assigned bridge window %pR to %pR free space at %pR\n", + res, &bus->busn_res, &gap); + return true; } + } - return false; + if (bus->self) { + pci_info(bus->self, + "Assigned bridge window %pR to %pR cannot fit 0x%llx required for %s bridging to %pR\n", + res, &bus->busn_res, + (unsigned long long)size, + pci_name(downstream->self), + &downstream->busn_res); } + + return false; } return true; @@ -1139,24 +1289,22 @@ static bool pbus_upstream_space_available(struct pci_bus *bus, unsigned long mas * pbus_size_mem() - Size the memory window of a given bus * * @bus: The bus - * @mask: Mask the resource flag, then compare it with type - * @type: The type of free resource from bridge - * @type2: Second match type - * @type3: Third match type + * @type: The type of bridge resource * @min_size: The minimum memory window that must be allocated * @add_size: Additional optional memory window * @realloc_head: Track the additional memory window on this list * - * Calculate the size of the bus and minimal alignment which guarantees - * that all child resources fit in this size. + * Calculate the size of the bus resource for @type and minimal alignment + * which guarantees that all child resources fit in this size. + * + * Set the bus resource start/end to indicate the required size if there an + * available unassigned bus resource of the desired @type. * - * Return -ENOSPC if there's no available bus resource of the desired - * type. Otherwise, set the bus resource start/end to indicate the - * required size, add things to realloc_head (if supplied), and return 0. + * Add optional resource requests to the @realloc_head list if it is + * supplied. */ -static int pbus_size_mem(struct pci_bus *bus, unsigned long mask, - unsigned long type, unsigned long type2, - unsigned long type3, resource_size_t min_size, +static void pbus_size_mem(struct pci_bus *bus, unsigned long type, + resource_size_t min_size, resource_size_t add_size, struct list_head *realloc_head) { @@ -1164,18 +1312,19 @@ static int pbus_size_mem(struct pci_bus *bus, unsigned long mask, resource_size_t min_align, win_align, align, size, size0, size1 = 0; resource_size_t aligns[28]; /* Alignments from 1MB to 128TB */ int order, max_order; - struct resource *b_res = find_bus_resource_of_type(bus, - mask | IORESOURCE_PREFETCH, type); + struct resource *b_res = pbus_select_window_for_type(bus, type); resource_size_t children_add_size = 0; resource_size_t children_add_align = 0; resource_size_t add_align = 0; + resource_size_t relaxed_align; + resource_size_t old_size; if (!b_res) - return -ENOSPC; + return; /* If resource is already assigned, nothing more to do */ if (b_res->parent) - return 0; + return; memset(aligns, 0, sizeof(aligns)); max_order = 0; @@ -1189,11 +1338,12 @@ static int pbus_size_mem(struct pci_bus *bus, unsigned long mask, const char *r_name = pci_resource_name(dev, i); resource_size_t r_size; - if (r->parent || (r->flags & IORESOURCE_PCI_FIXED) || - ((r->flags & mask) != type && - (r->flags & mask) != type2 && - (r->flags & mask) != type3)) + if (!pdev_resources_assignable(dev) || + !pdev_resource_should_fit(dev, r)) continue; + if (b_res != pbus_select_window(bus, r)) + continue; + r_size = resource_size(r); /* Put SRIOV requested res to the optional list */ @@ -1238,17 +1388,24 @@ static int pbus_size_mem(struct pci_bus *bus, unsigned long mask, } } + old_size = resource_size(b_res); win_align = window_alignment(bus, b_res->flags); min_align = calculate_mem_align(aligns, max_order); min_align = max(min_align, win_align); - size0 = calculate_memsize(size, min_size, 0, 0, resource_size(b_res), min_align); + size0 = calculate_memsize(size, min_size, 0, 0, old_size, min_align); + + if (size0) { + resource_set_range(b_res, min_align, size0); + b_res->flags &= ~IORESOURCE_DISABLED; + } if (bus->self && size0 && - !pbus_upstream_space_available(bus, mask | IORESOURCE_PREFETCH, type, - size0, min_align)) { - min_align = 1ULL << (max_order + __ffs(SZ_1M)); - min_align = max(min_align, win_align); - size0 = calculate_memsize(size, min_size, 0, 0, resource_size(b_res), win_align); + !pbus_upstream_space_available(bus, b_res, size0, min_align)) { + relaxed_align = 1ULL << (max_order + __ffs(SZ_1M)); + relaxed_align = max(relaxed_align, win_align); + min_align = min(min_align, relaxed_align); + size0 = calculate_memsize(size, min_size, 0, 0, old_size, win_align); + resource_set_range(b_res, min_align, size0); pci_info(bus->self, "bridge window %pR to %pR requires relaxed alignment rules\n", b_res, &bus->busn_res); } @@ -1256,15 +1413,15 @@ static int pbus_size_mem(struct pci_bus *bus, unsigned long mask, if (realloc_head && (add_size > 0 || children_add_size > 0)) { add_align = max(min_align, add_align); size1 = calculate_memsize(size, min_size, add_size, children_add_size, - resource_size(b_res), add_align); + old_size, add_align); if (bus->self && size1 && - !pbus_upstream_space_available(bus, mask | IORESOURCE_PREFETCH, type, - size1, add_align)) { - min_align = 1ULL << (max_order + __ffs(SZ_1M)); - min_align = max(min_align, win_align); + !pbus_upstream_space_available(bus, b_res, size1, add_align)) { + relaxed_align = 1ULL << (max_order + __ffs(SZ_1M)); + relaxed_align = max(relaxed_align, win_align); + min_align = min(min_align, relaxed_align); size1 = calculate_memsize(size, min_size, add_size, children_add_size, - resource_size(b_res), win_align); + old_size, win_align); pci_info(bus->self, "bridge window %pR to %pR requires relaxed alignment rules\n", b_res, &bus->busn_res); @@ -1275,20 +1432,20 @@ static int pbus_size_mem(struct pci_bus *bus, unsigned long mask, if (bus->self && (b_res->start || b_res->end)) pci_info(bus->self, "disabling bridge window %pR to %pR (unused)\n", b_res, &bus->busn_res); - b_res->flags = 0; - return 0; + b_res->flags |= IORESOURCE_DISABLED; + return; } resource_set_range(b_res, min_align, size0); b_res->flags |= IORESOURCE_STARTALIGN; if (bus->self && size1 > size0 && realloc_head) { + b_res->flags &= ~IORESOURCE_DISABLED; add_to_list(realloc_head, bus->self, b_res, size1-size0, add_align); pci_info(bus->self, "bridge window %pR to %pR add_size %llx add_align %llx\n", b_res, &bus->busn_res, (unsigned long long) (size1 - size0), (unsigned long long) add_align); } - return 0; } unsigned long pci_cardbus_resource_alignment(struct resource *res) @@ -1393,12 +1550,11 @@ handle_done: void __pci_bus_size_bridges(struct pci_bus *bus, struct list_head *realloc_head) { struct pci_dev *dev; - unsigned long mask, prefmask, type2 = 0, type3 = 0; resource_size_t additional_io_size = 0, additional_mmio_size = 0, additional_mmio_pref_size = 0; struct resource *pref; struct pci_host_bridge *host; - int hdr_type, ret; + int hdr_type; list_for_each_entry(dev, &bus->devices, bus_list) { struct pci_bus *b = dev->subordinate; @@ -1448,71 +1604,15 @@ void __pci_bus_size_bridges(struct pci_bus *bus, struct list_head *realloc_head) pbus_size_io(bus, realloc_head ? 0 : additional_io_size, additional_io_size, realloc_head); - /* - * If there's a 64-bit prefetchable MMIO window, compute - * the size required to put all 64-bit prefetchable - * resources in it. - */ - mask = IORESOURCE_MEM; - prefmask = IORESOURCE_MEM | IORESOURCE_PREFETCH; - if (pref && (pref->flags & IORESOURCE_MEM_64)) { - prefmask |= IORESOURCE_MEM_64; - ret = pbus_size_mem(bus, prefmask, prefmask, - prefmask, prefmask, - realloc_head ? 0 : additional_mmio_pref_size, - additional_mmio_pref_size, realloc_head); - - /* - * If successful, all non-prefetchable resources - * and any 32-bit prefetchable resources will go in - * the non-prefetchable window. - */ - if (ret == 0) { - mask = prefmask; - type2 = prefmask & ~IORESOURCE_MEM_64; - type3 = prefmask & ~IORESOURCE_PREFETCH; - } - } - - /* - * If there is no 64-bit prefetchable window, compute the - * size required to put all prefetchable resources in the - * 32-bit prefetchable window (if there is one). - */ - if (!type2) { - prefmask &= ~IORESOURCE_MEM_64; - ret = pbus_size_mem(bus, prefmask, prefmask, - prefmask, prefmask, - realloc_head ? 0 : additional_mmio_pref_size, - additional_mmio_pref_size, realloc_head); - - /* - * If successful, only non-prefetchable resources - * will go in the non-prefetchable window. - */ - if (ret == 0) - mask = prefmask; - else - additional_mmio_size += additional_mmio_pref_size; - - type2 = type3 = IORESOURCE_MEM; + if (pref) { + pbus_size_mem(bus, + IORESOURCE_MEM | IORESOURCE_PREFETCH | + (pref->flags & IORESOURCE_MEM_64), + realloc_head ? 0 : additional_mmio_pref_size, + additional_mmio_pref_size, realloc_head); } - /* - * Compute the size required to put everything else in the - * non-prefetchable window. This includes: - * - * - all non-prefetchable resources - * - 32-bit prefetchable resources if there's a 64-bit - * prefetchable window or no prefetchable window at all - * - 64-bit prefetchable resources if there's no prefetchable - * window at all - * - * Note that the strategy in __pci_assign_resource() must match - * that used here. Specifically, we cannot put a 32-bit - * prefetchable resource in a 64-bit prefetchable window. - */ - pbus_size_mem(bus, mask, IORESOURCE_MEM, type2, type3, + pbus_size_mem(bus, IORESOURCE_MEM, realloc_head ? 0 : additional_mmio_size, additional_mmio_size, realloc_head); break; @@ -1704,66 +1804,25 @@ static void __pci_bridge_assign_resources(const struct pci_dev *bridge, } } -#define PCI_RES_TYPE_MASK \ - (IORESOURCE_IO | IORESOURCE_MEM | IORESOURCE_PREFETCH |\ - IORESOURCE_MEM_64) - static void pci_bridge_release_resources(struct pci_bus *bus, - unsigned long type) + struct resource *b_win) { struct pci_dev *dev = bus->self; - struct resource *r; - unsigned int old_flags; - struct resource *b_res; - int idx = 1; + int idx, ret; - b_res = &dev->resource[PCI_BRIDGE_RESOURCES]; - - /* - * 1. If IO port assignment fails, release bridge IO port. - * 2. If non pref MMIO assignment fails, release bridge nonpref MMIO. - * 3. If 64bit pref MMIO assignment fails, and bridge pref is 64bit, - * release bridge pref MMIO. - * 4. If pref MMIO assignment fails, and bridge pref is 32bit, - * release bridge pref MMIO. - * 5. If pref MMIO assignment fails, and bridge pref is not - * assigned, release bridge nonpref MMIO. - */ - if (type & IORESOURCE_IO) - idx = 0; - else if (!(type & IORESOURCE_PREFETCH)) - idx = 1; - else if ((type & IORESOURCE_MEM_64) && - (b_res[2].flags & IORESOURCE_MEM_64)) - idx = 2; - else if (!(b_res[2].flags & IORESOURCE_MEM_64) && - (b_res[2].flags & IORESOURCE_PREFETCH)) - idx = 2; - else - idx = 1; - - r = &b_res[idx]; - - if (!r->parent) + if (!b_win->parent) return; + idx = pci_resource_num(dev, b_win); + /* If there are children, release them all */ - release_child_resources(r); - if (!release_resource(r)) { - type = old_flags = r->flags & PCI_RES_TYPE_MASK; - pci_info(dev, "resource %d %pR released\n", - PCI_BRIDGE_RESOURCES + idx, r); - /* Keep the old size */ - resource_set_range(r, 0, resource_size(r)); - r->flags = 0; + release_child_resources(b_win); - /* Avoiding touch the one without PREF */ - if (type & IORESOURCE_PREFETCH) - type = IORESOURCE_PREFETCH; - __pci_setup_bridge(bus, type); - /* For next child res under same bridge */ - r->flags = old_flags; - } + ret = pci_release_resource(dev, idx); + if (ret) + return; + + pci_setup_one_bridge_window(dev, idx); } enum release_type { @@ -1776,7 +1835,7 @@ enum release_type { * a larger window later. */ static void pci_bus_release_bridge_resources(struct pci_bus *bus, - unsigned long type, + struct resource *b_win, enum release_type rel_type) { struct pci_dev *dev; @@ -1784,6 +1843,8 @@ static void pci_bus_release_bridge_resources(struct pci_bus *bus, list_for_each_entry(dev, &bus->devices, bus_list) { struct pci_bus *b = dev->subordinate; + struct resource *res; + if (!b) continue; @@ -1792,9 +1853,15 @@ static void pci_bus_release_bridge_resources(struct pci_bus *bus, if ((dev->class >> 8) != PCI_CLASS_BRIDGE_PCI) continue; - if (rel_type == whole_subtree) - pci_bus_release_bridge_resources(b, type, - whole_subtree); + if (rel_type != whole_subtree) + continue; + + pci_bus_for_each_resource(b, res) { + if (res->parent != b_win) + continue; + + pci_bus_release_bridge_resources(b, res, rel_type); + } } if (pci_is_root_bus(bus)) @@ -1804,7 +1871,7 @@ static void pci_bus_release_bridge_resources(struct pci_bus *bus, return; if ((rel_type == whole_subtree) || is_leaf_bridge) - pci_bridge_release_resources(bus, type); + pci_bridge_release_resources(bus, b_win); } static void pci_bus_dump_res(struct pci_bus *bus) @@ -1979,33 +2046,21 @@ static void remove_dev_resource(struct resource *avail, struct pci_dev *dev, avail->start = min(avail->start + tmp, avail->end + 1); } -static void remove_dev_resources(struct pci_dev *dev, struct resource *io, - struct resource *mmio, - struct resource *mmio_pref) +static void remove_dev_resources(struct pci_dev *dev, + struct resource available[PCI_P2P_BRIDGE_RESOURCE_NUM]) { - struct resource *res; + struct resource *res, *b_win; + int idx; pci_dev_for_each_resource(dev, res) { - if (resource_type(res) == IORESOURCE_IO) { - remove_dev_resource(io, dev, res); - } else if (resource_type(res) == IORESOURCE_MEM) { + b_win = pbus_select_window(dev->bus, res); + if (!b_win) + continue; - /* - * Make sure prefetchable memory is reduced from - * the correct resource. Specifically we put 32-bit - * prefetchable memory in non-prefetchable window - * if there is a 64-bit prefetchable window. - * - * See comments in __pci_bus_size_bridges() for - * more information. - */ - if ((res->flags & IORESOURCE_PREFETCH) && - ((res->flags & IORESOURCE_MEM_64) == - (mmio_pref->flags & IORESOURCE_MEM_64))) - remove_dev_resource(mmio_pref, dev, res); - else - remove_dev_resource(mmio, dev, res); - } + idx = pci_resource_num(dev->bus->self, b_win); + idx -= PCI_BRIDGE_RESOURCES; + + remove_dev_resource(&available[idx], dev, res); } } @@ -2019,45 +2074,39 @@ static void remove_dev_resources(struct pci_dev *dev, struct resource *io, * shared with the bridges. */ static void pci_bus_distribute_available_resources(struct pci_bus *bus, - struct list_head *add_list, - struct resource io, - struct resource mmio, - struct resource mmio_pref) + struct list_head *add_list, + struct resource available_in[PCI_P2P_BRIDGE_RESOURCE_NUM]) { + struct resource available[PCI_P2P_BRIDGE_RESOURCE_NUM]; unsigned int normal_bridges = 0, hotplug_bridges = 0; - struct resource *io_res, *mmio_res, *mmio_pref_res; struct pci_dev *dev, *bridge = bus->self; - resource_size_t io_per_b, mmio_per_b, mmio_pref_per_b, align; - - io_res = &bridge->resource[PCI_BRIDGE_IO_WINDOW]; - mmio_res = &bridge->resource[PCI_BRIDGE_MEM_WINDOW]; - mmio_pref_res = &bridge->resource[PCI_BRIDGE_PREF_MEM_WINDOW]; + resource_size_t per_bridge[PCI_P2P_BRIDGE_RESOURCE_NUM]; + resource_size_t align; + int i; - /* - * The alignment of this bridge is yet to be considered, hence it must - * be done now before extending its bridge window. - */ - align = pci_resource_alignment(bridge, io_res); - if (!io_res->parent && align) - io.start = min(ALIGN(io.start, align), io.end + 1); + for (i = 0; i < PCI_P2P_BRIDGE_RESOURCE_NUM; i++) { + struct resource *res = pci_bus_resource_n(bus, i); - align = pci_resource_alignment(bridge, mmio_res); - if (!mmio_res->parent && align) - mmio.start = min(ALIGN(mmio.start, align), mmio.end + 1); + available[i] = available_in[i]; - align = pci_resource_alignment(bridge, mmio_pref_res); - if (!mmio_pref_res->parent && align) - mmio_pref.start = min(ALIGN(mmio_pref.start, align), - mmio_pref.end + 1); + /* + * The alignment of this bridge is yet to be considered, + * hence it must be done now before extending its bridge + * window. + */ + align = pci_resource_alignment(bridge, res); + if (!res->parent && align) + available[i].start = min(ALIGN(available[i].start, align), + available[i].end + 1); - /* - * Now that we have adjusted for alignment, update the bridge window - * resources to fill as much remaining resource space as possible. - */ - adjust_bridge_window(bridge, io_res, add_list, resource_size(&io)); - adjust_bridge_window(bridge, mmio_res, add_list, resource_size(&mmio)); - adjust_bridge_window(bridge, mmio_pref_res, add_list, - resource_size(&mmio_pref)); + /* + * Now that we have adjusted for alignment, update the + * bridge window resources to fill as much remaining + * resource space as possible. + */ + adjust_bridge_window(bridge, res, add_list, + resource_size(&available[i])); + } /* * Calculate how many hotplug bridges and normal bridges there @@ -2081,7 +2130,7 @@ static void pci_bus_distribute_available_resources(struct pci_bus *bus, */ list_for_each_entry(dev, &bus->devices, bus_list) { if (!dev->is_virtfn) - remove_dev_resources(dev, &io, &mmio, &mmio_pref); + remove_dev_resources(dev, available); } /* @@ -2093,16 +2142,9 @@ static void pci_bus_distribute_available_resources(struct pci_bus *bus, * split between non-hotplug bridges. This is to allow possible * hotplug bridges below them to get the extra space as well. */ - if (hotplug_bridges) { - io_per_b = div64_ul(resource_size(&io), hotplug_bridges); - mmio_per_b = div64_ul(resource_size(&mmio), hotplug_bridges); - mmio_pref_per_b = div64_ul(resource_size(&mmio_pref), - hotplug_bridges); - } else { - io_per_b = div64_ul(resource_size(&io), normal_bridges); - mmio_per_b = div64_ul(resource_size(&mmio), normal_bridges); - mmio_pref_per_b = div64_ul(resource_size(&mmio_pref), - normal_bridges); + for (i = 0; i < PCI_P2P_BRIDGE_RESOURCE_NUM; i++) { + per_bridge[i] = div64_ul(resource_size(&available[i]), + hotplug_bridges ?: normal_bridges); } for_each_pci_bridge(dev, bus) { @@ -2115,49 +2157,41 @@ static void pci_bus_distribute_available_resources(struct pci_bus *bus, if (hotplug_bridges && !dev->is_hotplug_bridge) continue; - res = &dev->resource[PCI_BRIDGE_IO_WINDOW]; + for (i = 0; i < PCI_P2P_BRIDGE_RESOURCE_NUM; i++) { + res = pci_bus_resource_n(bus, i); - /* - * Make sure the split resource space is properly aligned - * for bridge windows (align it down to avoid going above - * what is available). - */ - align = pci_resource_alignment(dev, res); - resource_set_size(&io, ALIGN_DOWN_IF_NONZERO(io_per_b, align)); - - /* - * The x_per_b holds the extra resource space that can be - * added for each bridge but there is the minimal already - * reserved as well so adjust x.start down accordingly to - * cover the whole space. - */ - io.start -= resource_size(res); - - res = &dev->resource[PCI_BRIDGE_MEM_WINDOW]; - align = pci_resource_alignment(dev, res); - resource_set_size(&mmio, - ALIGN_DOWN_IF_NONZERO(mmio_per_b,align)); - mmio.start -= resource_size(res); + /* + * Make sure the split resource space is properly + * aligned for bridge windows (align it down to + * avoid going above what is available). + */ + align = pci_resource_alignment(dev, res); + resource_set_size(&available[i], + ALIGN_DOWN_IF_NONZERO(per_bridge[i], + align)); - res = &dev->resource[PCI_BRIDGE_PREF_MEM_WINDOW]; - align = pci_resource_alignment(dev, res); - resource_set_size(&mmio_pref, - ALIGN_DOWN_IF_NONZERO(mmio_pref_per_b, align)); - mmio_pref.start -= resource_size(res); + /* + * The per_bridge holds the extra resource space + * that can be added for each bridge but there is + * the minimal already reserved as well so adjust + * x.start down accordingly to cover the whole + * space. + */ + available[i].start -= resource_size(res); + } - pci_bus_distribute_available_resources(b, add_list, io, mmio, - mmio_pref); + pci_bus_distribute_available_resources(b, add_list, available); - io.start += io.end + 1; - mmio.start += mmio.end + 1; - mmio_pref.start += mmio_pref.end + 1; + for (i = 0; i < PCI_P2P_BRIDGE_RESOURCE_NUM; i++) + available[i].start += available[i].end + 1; } } static void pci_bridge_distribute_available_resources(struct pci_dev *bridge, struct list_head *add_list) { - struct resource available_io, available_mmio, available_mmio_pref; + struct resource *res, available[PCI_P2P_BRIDGE_RESOURCE_NUM]; + unsigned int i; if (!bridge->is_hotplug_bridge) return; @@ -2165,14 +2199,13 @@ static void pci_bridge_distribute_available_resources(struct pci_dev *bridge, pci_dbg(bridge, "distributing available resources\n"); /* Take the initial extra resources from the hotplug port */ - available_io = bridge->resource[PCI_BRIDGE_IO_WINDOW]; - available_mmio = bridge->resource[PCI_BRIDGE_MEM_WINDOW]; - available_mmio_pref = bridge->resource[PCI_BRIDGE_PREF_MEM_WINDOW]; + for (i = 0; i < PCI_P2P_BRIDGE_RESOURCE_NUM; i++) { + res = pci_resource_n(bridge, PCI_BRIDGE_RESOURCES + i); + available[i] = *res; + } pci_bus_distribute_available_resources(bridge->subordinate, - add_list, available_io, - available_mmio, - available_mmio_pref); + add_list, available); } static bool pci_bridge_resources_not_assigned(struct pci_dev *dev) @@ -2235,27 +2268,19 @@ static void pci_prepare_next_assign_round(struct list_head *fail_head, * enough to contain child device resources. */ list_for_each_entry(fail_res, fail_head, list) { - pci_bus_release_bridge_resources(fail_res->dev->bus, - fail_res->flags & PCI_RES_TYPE_MASK, - rel_type); + struct pci_bus *bus = fail_res->dev->bus; + struct resource *b_win; + + b_win = pbus_select_window_for_type(bus, fail_res->flags); + if (!b_win) + continue; + pci_bus_release_bridge_resources(bus, b_win, rel_type); } /* Restore size and flags */ - list_for_each_entry(fail_res, fail_head, list) { - struct resource *res = fail_res->res; - struct pci_dev *dev = fail_res->dev; - int idx = pci_resource_num(dev, res); - + list_for_each_entry(fail_res, fail_head, list) restore_dev_resource(fail_res); - if (!pci_is_bridge(dev)) - continue; - - if (idx >= PCI_BRIDGE_RESOURCES && - idx <= PCI_BRIDGE_RESOURCE_END) - res->flags = 0; - } - free_list(fail_head); } @@ -2389,10 +2414,16 @@ void pci_assign_unassigned_bridge_resources(struct pci_dev *bridge) } EXPORT_SYMBOL_GPL(pci_assign_unassigned_bridge_resources); -int pci_reassign_bridge_resources(struct pci_dev *bridge, unsigned long type) +/* + * Walk to the root bus, find the bridge window relevant for @res and + * release it when possible. If the bridge window contains assigned + * resources, it cannot be released. + */ +int pbus_reassign_bridge_resources(struct pci_bus *bus, struct resource *res) { + unsigned long type = res->flags; struct pci_dev_resource *dev_res; - struct pci_dev *next; + struct pci_dev *bridge; LIST_HEAD(saved); LIST_HEAD(added); LIST_HEAD(failed); @@ -2401,39 +2432,31 @@ int pci_reassign_bridge_resources(struct pci_dev *bridge, unsigned long type) down_read(&pci_bus_sem); - /* Walk to the root hub, releasing bridge BARs when possible */ - next = bridge; - do { - bridge = next; - for (i = PCI_BRIDGE_RESOURCES; i < PCI_BRIDGE_RESOURCE_END; - i++) { - struct resource *res = &bridge->resource[i]; - const char *res_name = pci_resource_name(bridge, i); - - if ((res->flags ^ type) & PCI_RES_TYPE_MASK) - continue; + while (!pci_is_root_bus(bus)) { + bridge = bus->self; + res = pbus_select_window(bus, res); + if (!res) + break; - /* Ignore BARs which are still in use */ - if (res->child) - continue; + i = pci_resource_num(bridge, res); + /* Ignore BARs which are still in use */ + if (!res->child) { ret = add_to_list(&saved, bridge, res, 0, 0); if (ret) goto cleanup; - pci_info(bridge, "%s %pR: releasing\n", res_name, res); + pci_release_resource(bridge, i); + } else { + const char *res_name = pci_resource_name(bridge, i); - if (res->parent) - release_resource(res); - res->start = 0; - res->end = 0; - break; + pci_warn(bridge, + "%s %pR: was not released (still contains assigned resources)\n", + res_name, res); } - if (i == PCI_BRIDGE_RESOURCE_END) - break; - next = bridge->bus ? bridge->bus->self : NULL; - } while (next); + bus = bus->parent; + } if (list_empty(&saved)) { up_read(&pci_bus_sem); @@ -2446,8 +2469,12 @@ int pci_reassign_bridge_resources(struct pci_dev *bridge, unsigned long type) free_list(&added); if (!list_empty(&failed)) { - ret = -ENOSPC; - goto cleanup; + if (pci_required_resource_failed(&failed, type)) { + ret = -ENOSPC; + goto cleanup; + } + /* Only resources with unrelated types failed (again) */ + free_list(&failed); } list_for_each_entry(dev_res, &saved, list) { diff --git a/drivers/pci/setup-res.c b/drivers/pci/setup-res.c index d2b3ed51e880..c3ba4ccecd43 100644 --- a/drivers/pci/setup-res.c +++ b/drivers/pci/setup-res.c @@ -359,6 +359,9 @@ int pci_assign_resource(struct pci_dev *dev, int resno) res->flags &= ~IORESOURCE_UNSET; res->flags &= ~IORESOURCE_STARTALIGN; + if (resno >= PCI_BRIDGE_RESOURCES && resno <= PCI_BRIDGE_RESOURCE_END) + res->flags &= ~IORESOURCE_DISABLED; + pci_info(dev, "%s %pR: assigned\n", res_name, res); if (resno < PCI_BRIDGE_RESOURCES) pci_update_resource(dev, resno); @@ -406,20 +409,25 @@ int pci_reassign_resource(struct pci_dev *dev, int resno, return 0; } -void pci_release_resource(struct pci_dev *dev, int resno) +int pci_release_resource(struct pci_dev *dev, int resno) { struct resource *res = pci_resource_n(dev, resno); const char *res_name = pci_resource_name(dev, resno); + int ret; if (!res->parent) - return; + return 0; pci_info(dev, "%s %pR: releasing\n", res_name, res); - release_resource(res); + ret = release_resource(res); + if (ret) + return ret; res->end = resource_size(res) - 1; res->start = 0; res->flags |= IORESOURCE_UNSET; + + return 0; } EXPORT_SYMBOL(pci_release_resource); @@ -488,7 +496,7 @@ int pci_resize_resource(struct pci_dev *dev, int resno, int size) /* Check if the new config works by trying to assign everything. */ if (dev->bus->self) { - ret = pci_reassign_bridge_resources(dev->bus->self, res->flags); + ret = pbus_reassign_bridge_resources(dev->bus, res); if (ret) goto error_resize; } @@ -522,22 +530,26 @@ int pci_enable_resources(struct pci_dev *dev, int mask) if (pci_resource_is_optional(dev, i)) continue; - if (r->flags & IORESOURCE_UNSET) { - pci_err(dev, "%s %pR: not assigned; can't enable device\n", - r_name, r); - return -EINVAL; + if (i < PCI_BRIDGE_RESOURCES) { + if (r->flags & IORESOURCE_UNSET) { + pci_err(dev, "%s %pR: not assigned; can't enable device\n", + r_name, r); + return -EINVAL; + } + + if (!r->parent) { + pci_err(dev, "%s %pR: not claimed; can't enable device\n", + r_name, r); + return -EINVAL; + } } - if (!r->parent) { - pci_err(dev, "%s %pR: not claimed; can't enable device\n", - r_name, r); - return -EINVAL; + if (r->parent) { + if (r->flags & IORESOURCE_IO) + cmd |= PCI_COMMAND_IO; + if (r->flags & IORESOURCE_MEM) + cmd |= PCI_COMMAND_MEMORY; } - - if (r->flags & IORESOURCE_IO) - cmd |= PCI_COMMAND_IO; - if (r->flags & IORESOURCE_MEM) - cmd |= PCI_COMMAND_MEMORY; } if (cmd != old_cmd) { diff --git a/drivers/pci/switch/switchtec.c b/drivers/pci/switch/switchtec.c index b14dfab04d84..5ff84fb8fb0f 100644 --- a/drivers/pci/switch/switchtec.c +++ b/drivers/pci/switch/switchtec.c @@ -269,10 +269,9 @@ static void mrpc_event_work(struct work_struct *work) dev_dbg(&stdev->dev, "%s\n", __func__); - mutex_lock(&stdev->mrpc_mutex); + guard(mutex)(&stdev->mrpc_mutex); cancel_delayed_work(&stdev->mrpc_timeout); mrpc_complete_cmd(stdev); - mutex_unlock(&stdev->mrpc_mutex); } static void mrpc_error_complete_cmd(struct switchtec_dev *stdev) @@ -1322,18 +1321,18 @@ static void stdev_kill(struct switchtec_dev *stdev) cancel_delayed_work_sync(&stdev->mrpc_timeout); /* Mark the hardware as unavailable and complete all completions */ - mutex_lock(&stdev->mrpc_mutex); - stdev->alive = false; - - /* Wake up and kill any users waiting on an MRPC request */ - list_for_each_entry_safe(stuser, tmpuser, &stdev->mrpc_queue, list) { - stuser->cmd_done = true; - wake_up_interruptible(&stuser->cmd_comp); - list_del_init(&stuser->list); - stuser_put(stuser); - } + scoped_guard (mutex, &stdev->mrpc_mutex) { + stdev->alive = false; + + /* Wake up and kill any users waiting on an MRPC request */ + list_for_each_entry_safe(stuser, tmpuser, &stdev->mrpc_queue, list) { + stuser->cmd_done = true; + wake_up_interruptible(&stuser->cmd_comp); + list_del_init(&stuser->list); + stuser_put(stuser); + } - mutex_unlock(&stdev->mrpc_mutex); + } /* Wake up any users waiting on event_wq */ wake_up_interruptible(&stdev->event_wq); diff --git a/drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c b/drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c index bbd81a43047d..f963e4f9e552 100644 --- a/drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c +++ b/drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c @@ -57,6 +57,11 @@ #define L3C_V2_NR_EVENTS 0xFF HISI_PMU_EVENT_ATTR_EXTRACTOR(ext, config, 17, 16); +/* + * Remain the config1:0-7 for backward compatibility if some existing users + * hardcode the config1:0-7 directly without parsing the sysfs attribute. + */ +HISI_PMU_EVENT_ATTR_EXTRACTOR(tt_core_deprecated, config1, 7, 0); HISI_PMU_EVENT_ATTR_EXTRACTOR(tt_req, config1, 10, 8); HISI_PMU_EVENT_ATTR_EXTRACTOR(datasrc_cfg, config1, 15, 11); HISI_PMU_EVENT_ATTR_EXTRACTOR(datasrc_skt, config1, 16, 16); @@ -95,6 +100,21 @@ static bool support_ext(struct hisi_l3c_pmu *pmu) return l3c_pmu_ext->support_ext; } +/* + * tt_core was extended to cover all the CPUs sharing the L3 and was moved from + * config1:0-7 to config2:0-*. Try it first and fallback to tt_core_deprecated + * if user's still using the deprecated one. + */ +static u32 hisi_l3c_pmu_get_tt_core(struct perf_event *event) +{ + u32 core = hisi_get_tt_core(event); + + if (core) + return core; + + return hisi_get_tt_core_deprecated(event); +} + static int hisi_l3c_pmu_get_event_idx(struct perf_event *event) { struct hisi_pmu *l3c_pmu = to_hisi_pmu(event->pmu); @@ -259,7 +279,7 @@ static void hisi_l3c_pmu_clear_ds(struct perf_event *event) static void hisi_l3c_pmu_config_core_tracetag(struct perf_event *event) { struct hw_perf_event *hwc = &event->hw; - u32 core = hisi_get_tt_core(event); + u32 core = hisi_l3c_pmu_get_tt_core(event); if (core) { u32 val; @@ -280,7 +300,7 @@ static void hisi_l3c_pmu_config_core_tracetag(struct perf_event *event) static void hisi_l3c_pmu_clear_core_tracetag(struct perf_event *event) { struct hw_perf_event *hwc = &event->hw; - u32 core = hisi_get_tt_core(event); + u32 core = hisi_l3c_pmu_get_tt_core(event); if (core) { u32 val; @@ -300,7 +320,7 @@ static void hisi_l3c_pmu_clear_core_tracetag(struct perf_event *event) static bool hisi_l3c_pmu_have_filter(struct perf_event *event) { - return hisi_get_tt_req(event) || hisi_get_tt_core(event) || + return hisi_get_tt_req(event) || hisi_l3c_pmu_get_tt_core(event) || hisi_get_datasrc_cfg(event) || hisi_get_datasrc_skt(event); } @@ -331,6 +351,9 @@ static int hisi_l3c_pmu_check_filter(struct perf_event *event) if (ext < 0 || ext > hisi_l3c_pmu->ext_num) return -EINVAL; + if (hisi_get_tt_core(event) && hisi_get_tt_core_deprecated(event)) + return -EINVAL; + return 0; } @@ -602,10 +625,11 @@ static const struct attribute_group hisi_l3c_pmu_v1_format_group = { static struct attribute *hisi_l3c_pmu_v2_format_attr[] = { HISI_PMU_FORMAT_ATTR(event, "config:0-7"), - HISI_PMU_FORMAT_ATTR(tt_core, "config2:0-15"), + HISI_PMU_FORMAT_ATTR(tt_core_deprecated, "config1:0-7"), HISI_PMU_FORMAT_ATTR(tt_req, "config1:8-10"), HISI_PMU_FORMAT_ATTR(datasrc_cfg, "config1:11-15"), HISI_PMU_FORMAT_ATTR(datasrc_skt, "config1:16"), + HISI_PMU_FORMAT_ATTR(tt_core, "config2:0-15"), NULL }; @@ -617,6 +641,7 @@ static const struct attribute_group hisi_l3c_pmu_v2_format_group = { static struct attribute *hisi_l3c_pmu_v3_format_attr[] = { HISI_PMU_FORMAT_ATTR(event, "config:0-7"), HISI_PMU_FORMAT_ATTR(ext, "config:16-17"), + HISI_PMU_FORMAT_ATTR(tt_core_deprecated, "config1:0-7"), HISI_PMU_FORMAT_ATTR(tt_req, "config1:8-10"), HISI_PMU_FORMAT_ATTR(tt_core, "config2:0-15"), NULL diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig index 58c911e1b2d2..678dd0452f0a 100644 --- a/drivers/phy/Kconfig +++ b/drivers/phy/Kconfig @@ -122,6 +122,7 @@ source "drivers/phy/renesas/Kconfig" source "drivers/phy/rockchip/Kconfig" source "drivers/phy/samsung/Kconfig" source "drivers/phy/socionext/Kconfig" +source "drivers/phy/sophgo/Kconfig" source "drivers/phy/st/Kconfig" source "drivers/phy/starfive/Kconfig" source "drivers/phy/sunplus/Kconfig" diff --git a/drivers/phy/Makefile b/drivers/phy/Makefile index c670a8dac468..bfb27fb5a494 100644 --- a/drivers/phy/Makefile +++ b/drivers/phy/Makefile @@ -35,6 +35,7 @@ obj-y += allwinner/ \ rockchip/ \ samsung/ \ socionext/ \ + sophgo/ \ st/ \ starfive/ \ sunplus/ \ diff --git a/drivers/phy/allwinner/phy-sun4i-usb.c b/drivers/phy/allwinner/phy-sun4i-usb.c index 8873aed3a52a..59d38d88efb0 100644 --- a/drivers/phy/allwinner/phy-sun4i-usb.c +++ b/drivers/phy/allwinner/phy-sun4i-usb.c @@ -97,7 +97,6 @@ #define POLL_TIME msecs_to_jiffies(250) struct sun4i_usb_phy_cfg { - int num_phys; int hsic_index; u32 disc_thresh; u32 hci_phy_ctl_clear; @@ -115,6 +114,7 @@ struct sun4i_usb_phy_data { const struct sun4i_usb_phy_cfg *cfg; enum usb_dr_mode dr_mode; spinlock_t reg_lock; /* guard access to phyctl reg */ + int num_phys; struct sun4i_usb_phy { struct phy *phy; void __iomem *pmu; @@ -686,7 +686,7 @@ static struct phy *sun4i_usb_phy_xlate(struct device *dev, { struct sun4i_usb_phy_data *data = dev_get_drvdata(dev); - if (args->args[0] >= data->cfg->num_phys) + if (args->args[0] >= data->num_phys) return ERR_PTR(-ENODEV); if (data->cfg->missing_phys & BIT(args->args[0])) @@ -779,13 +779,22 @@ static int sun4i_usb_phy_probe(struct platform_device *pdev) return ret; } - for (i = 0; i < data->cfg->num_phys; i++) { + for (i = 0; i < MAX_PHYS; i++) { struct sun4i_usb_phy *phy = data->phys + i; char name[32]; if (data->cfg->missing_phys & BIT(i)) continue; + snprintf(name, sizeof(name), "usb%d_reset", i); + phy->reset = devm_reset_control_get(dev, name); + if (IS_ERR(phy->reset)) { + if (PTR_ERR(phy->reset) == -ENOENT) + break; + dev_err(dev, "failed to get reset %s\n", name); + return PTR_ERR(phy->reset); + } + snprintf(name, sizeof(name), "usb%d_vbus", i); phy->vbus = devm_regulator_get_optional(dev, name); if (IS_ERR(phy->vbus)) { @@ -828,13 +837,6 @@ static int sun4i_usb_phy_probe(struct platform_device *pdev) } } - snprintf(name, sizeof(name), "usb%d_reset", i); - phy->reset = devm_reset_control_get(dev, name); - if (IS_ERR(phy->reset)) { - dev_err(dev, "failed to get reset %s\n", name); - return PTR_ERR(phy->reset); - } - if (i || data->cfg->phy0_dual_route) { /* No pmu for musb */ snprintf(name, sizeof(name), "pmu%d", i); phy->pmu = devm_platform_ioremap_resource_byname(pdev, name); @@ -851,6 +853,7 @@ static int sun4i_usb_phy_probe(struct platform_device *pdev) phy->index = i; phy_set_drvdata(phy->phy, &data->phys[i]); } + data->num_phys = i; data->id_det_irq = gpiod_to_irq(data->id_det_gpio); if (data->id_det_irq > 0) { @@ -901,28 +904,24 @@ static int sun4i_usb_phy_probe(struct platform_device *pdev) } static const struct sun4i_usb_phy_cfg suniv_f1c100s_cfg = { - .num_phys = 1, .disc_thresh = 3, .phyctl_offset = REG_PHYCTL_A10, .dedicated_clocks = true, }; static const struct sun4i_usb_phy_cfg sun4i_a10_cfg = { - .num_phys = 3, .disc_thresh = 3, .phyctl_offset = REG_PHYCTL_A10, .dedicated_clocks = false, }; static const struct sun4i_usb_phy_cfg sun5i_a13_cfg = { - .num_phys = 2, .disc_thresh = 2, .phyctl_offset = REG_PHYCTL_A10, .dedicated_clocks = false, }; static const struct sun4i_usb_phy_cfg sun6i_a31_cfg = { - .num_phys = 3, .disc_thresh = 3, .phyctl_offset = REG_PHYCTL_A10, .dedicated_clocks = true, @@ -930,14 +929,12 @@ static const struct sun4i_usb_phy_cfg sun6i_a31_cfg = { }; static const struct sun4i_usb_phy_cfg sun7i_a20_cfg = { - .num_phys = 3, .disc_thresh = 2, .phyctl_offset = REG_PHYCTL_A10, .dedicated_clocks = false, }; static const struct sun4i_usb_phy_cfg sun8i_a23_cfg = { - .num_phys = 2, .disc_thresh = 3, .phyctl_offset = REG_PHYCTL_A10, .dedicated_clocks = true, @@ -945,7 +942,6 @@ static const struct sun4i_usb_phy_cfg sun8i_a23_cfg = { }; static const struct sun4i_usb_phy_cfg sun8i_a33_cfg = { - .num_phys = 2, .disc_thresh = 3, .phyctl_offset = REG_PHYCTL_A33, .dedicated_clocks = true, @@ -953,7 +949,6 @@ static const struct sun4i_usb_phy_cfg sun8i_a33_cfg = { }; static const struct sun4i_usb_phy_cfg sun8i_a83t_cfg = { - .num_phys = 3, .hsic_index = 2, .phyctl_offset = REG_PHYCTL_A33, .dedicated_clocks = true, @@ -961,7 +956,6 @@ static const struct sun4i_usb_phy_cfg sun8i_a83t_cfg = { }; static const struct sun4i_usb_phy_cfg sun8i_h3_cfg = { - .num_phys = 4, .disc_thresh = 3, .phyctl_offset = REG_PHYCTL_A33, .dedicated_clocks = true, @@ -970,7 +964,6 @@ static const struct sun4i_usb_phy_cfg sun8i_h3_cfg = { }; static const struct sun4i_usb_phy_cfg sun8i_r40_cfg = { - .num_phys = 3, .disc_thresh = 3, .phyctl_offset = REG_PHYCTL_A33, .dedicated_clocks = true, @@ -979,7 +972,6 @@ static const struct sun4i_usb_phy_cfg sun8i_r40_cfg = { }; static const struct sun4i_usb_phy_cfg sun8i_v3s_cfg = { - .num_phys = 1, .disc_thresh = 3, .phyctl_offset = REG_PHYCTL_A33, .dedicated_clocks = true, @@ -988,7 +980,6 @@ static const struct sun4i_usb_phy_cfg sun8i_v3s_cfg = { }; static const struct sun4i_usb_phy_cfg sun20i_d1_cfg = { - .num_phys = 2, .phyctl_offset = REG_PHYCTL_A33, .dedicated_clocks = true, .hci_phy_ctl_clear = PHY_CTL_SIDDQ, @@ -997,7 +988,6 @@ static const struct sun4i_usb_phy_cfg sun20i_d1_cfg = { }; static const struct sun4i_usb_phy_cfg sun50i_a64_cfg = { - .num_phys = 2, .disc_thresh = 3, .phyctl_offset = REG_PHYCTL_A33, .dedicated_clocks = true, @@ -1006,7 +996,6 @@ static const struct sun4i_usb_phy_cfg sun50i_a64_cfg = { }; static const struct sun4i_usb_phy_cfg sun50i_h6_cfg = { - .num_phys = 4, .phyctl_offset = REG_PHYCTL_A33, .dedicated_clocks = true, .phy0_dual_route = true, @@ -1015,7 +1004,6 @@ static const struct sun4i_usb_phy_cfg sun50i_h6_cfg = { }; static const struct sun4i_usb_phy_cfg sun50i_h616_cfg = { - .num_phys = 4, .disc_thresh = 3, .phyctl_offset = REG_PHYCTL_A33, .dedicated_clocks = true, diff --git a/drivers/phy/broadcom/phy-brcm-sata.c b/drivers/phy/broadcom/phy-brcm-sata.c index d52dd065e862..fb69e21a0292 100644 --- a/drivers/phy/broadcom/phy-brcm-sata.c +++ b/drivers/phy/broadcom/phy-brcm-sata.c @@ -850,4 +850,3 @@ MODULE_DESCRIPTION("Broadcom SATA PHY driver"); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Marc Carino"); MODULE_AUTHOR("Brian Norris"); -MODULE_ALIAS("platform:phy-brcm-sata"); diff --git a/drivers/phy/broadcom/phy-brcm-usb.c b/drivers/phy/broadcom/phy-brcm-usb.c index 0666864c2f77..59d756a10d6c 100644 --- a/drivers/phy/broadcom/phy-brcm-usb.c +++ b/drivers/phy/broadcom/phy-brcm-usb.c @@ -691,7 +691,6 @@ static struct platform_driver brcm_usb_driver = { module_platform_driver(brcm_usb_driver); -MODULE_ALIAS("platform:brcmstb-usb-phy"); MODULE_AUTHOR("Al Cooper <acooper@broadcom.com>"); MODULE_DESCRIPTION("BRCM USB PHY driver"); MODULE_LICENSE("GPL v2"); diff --git a/drivers/phy/cadence/cdns-dphy-rx.c b/drivers/phy/cadence/cdns-dphy-rx.c index 7729cf80a9bd..3ac80141189c 100644 --- a/drivers/phy/cadence/cdns-dphy-rx.c +++ b/drivers/phy/cadence/cdns-dphy-rx.c @@ -12,6 +12,7 @@ #include <linux/phy/phy.h> #include <linux/phy/phy-mipi-dphy.h> #include <linux/platform_device.h> +#include <linux/pm_runtime.h> #include <linux/sys_soc.h> #define DPHY_PMA_CMN(reg) (reg) @@ -265,7 +266,7 @@ static int cdns_dphy_rx_probe(struct platform_device *pdev) return PTR_ERR(provider); } - return 0; + return devm_pm_runtime_enable(dev); } static const struct of_device_id cdns_dphy_rx_of_match[] = { diff --git a/drivers/phy/cadence/cdns-dphy.c b/drivers/phy/cadence/cdns-dphy.c index ed87a3970f83..d5b0e516b93c 100644 --- a/drivers/phy/cadence/cdns-dphy.c +++ b/drivers/phy/cadence/cdns-dphy.c @@ -30,6 +30,7 @@ #define DPHY_CMN_SSM DPHY_PMA_CMN(0x20) #define DPHY_CMN_SSM_EN BIT(0) +#define DPHY_CMN_SSM_CAL_WAIT_TIME GENMASK(8, 1) #define DPHY_CMN_TX_MODE_EN BIT(9) #define DPHY_CMN_PWM DPHY_PMA_CMN(0x40) @@ -55,14 +56,6 @@ #define DPHY_PSM_CFG_FROM_REG BIT(0) #define DPHY_PSM_CLK_DIV(x) ((x) << 1) -#define DSI_HBP_FRAME_OVERHEAD 12 -#define DSI_HSA_FRAME_OVERHEAD 14 -#define DSI_HFP_FRAME_OVERHEAD 6 -#define DSI_HSS_VSS_VSE_FRAME_OVERHEAD 4 -#define DSI_BLANKING_FRAME_OVERHEAD 6 -#define DSI_NULL_FRAME_OVERHEAD 6 -#define DSI_EOT_PKT_SIZE 4 - #define DPHY_TX_J721E_WIZ_PLL_CTRL 0xF04 #define DPHY_TX_J721E_WIZ_STATUS 0xF08 #define DPHY_TX_J721E_WIZ_RST_CTRL 0xF0C @@ -79,6 +72,7 @@ struct cdns_dphy_cfg { u8 pll_ipdiv; u8 pll_opdiv; u16 pll_fbdiv; + u32 hs_clk_rate; unsigned int nlanes; }; @@ -99,6 +93,8 @@ struct cdns_dphy_ops { void (*set_pll_cfg)(struct cdns_dphy *dphy, const struct cdns_dphy_cfg *cfg); unsigned long (*get_wakeup_time_ns)(struct cdns_dphy *dphy); + int (*wait_for_pll_lock)(struct cdns_dphy *dphy); + int (*wait_for_cmn_ready)(struct cdns_dphy *dphy); }; struct cdns_dphy { @@ -108,6 +104,8 @@ struct cdns_dphy { struct clk *pll_ref_clk; const struct cdns_dphy_ops *ops; struct phy *phy; + bool is_configured; + bool is_powered; }; /* Order of bands is important since the index is the band number. */ @@ -116,10 +114,9 @@ static const unsigned int tx_bands[] = { 870, 950, 1000, 1200, 1400, 1600, 1800, 2000, 2200, 2500 }; -static int cdns_dsi_get_dphy_pll_cfg(struct cdns_dphy *dphy, - struct cdns_dphy_cfg *cfg, - struct phy_configure_opts_mipi_dphy *opts, - unsigned int *dsi_hfp_ext) +static int cdns_dphy_get_pll_cfg(struct cdns_dphy *dphy, + struct cdns_dphy_cfg *cfg, + struct phy_configure_opts_mipi_dphy *opts) { unsigned long pll_ref_hz = clk_get_rate(dphy->pll_ref_clk); u64 dlane_bps; @@ -139,7 +136,7 @@ static int cdns_dsi_get_dphy_pll_cfg(struct cdns_dphy *dphy, dlane_bps = opts->hs_clk_rate; - if (dlane_bps > 2500000000UL || dlane_bps < 160000000UL) + if (dlane_bps > 2500000000UL || dlane_bps < 80000000UL) return -EINVAL; else if (dlane_bps >= 1250000000) cfg->pll_opdiv = 1; @@ -149,11 +146,16 @@ static int cdns_dsi_get_dphy_pll_cfg(struct cdns_dphy *dphy, cfg->pll_opdiv = 4; else if (dlane_bps >= 160000000) cfg->pll_opdiv = 8; + else if (dlane_bps >= 80000000) + cfg->pll_opdiv = 16; cfg->pll_fbdiv = DIV_ROUND_UP_ULL(dlane_bps * 2 * cfg->pll_opdiv * cfg->pll_ipdiv, pll_ref_hz); + cfg->hs_clk_rate = div_u64((u64)pll_ref_hz * cfg->pll_fbdiv, + 2 * cfg->pll_opdiv * cfg->pll_ipdiv); + return 0; } @@ -191,6 +193,16 @@ static unsigned long cdns_dphy_get_wakeup_time_ns(struct cdns_dphy *dphy) return dphy->ops->get_wakeup_time_ns(dphy); } +static int cdns_dphy_wait_for_pll_lock(struct cdns_dphy *dphy) +{ + return dphy->ops->wait_for_pll_lock ? dphy->ops->wait_for_pll_lock(dphy) : 0; +} + +static int cdns_dphy_wait_for_cmn_ready(struct cdns_dphy *dphy) +{ + return dphy->ops->wait_for_cmn_ready ? dphy->ops->wait_for_cmn_ready(dphy) : 0; +} + static unsigned long cdns_dphy_ref_get_wakeup_time_ns(struct cdns_dphy *dphy) { /* Default wakeup time is 800 ns (in a simulated environment). */ @@ -232,7 +244,6 @@ static unsigned long cdns_dphy_j721e_get_wakeup_time_ns(struct cdns_dphy *dphy) static void cdns_dphy_j721e_set_pll_cfg(struct cdns_dphy *dphy, const struct cdns_dphy_cfg *cfg) { - u32 status; /* * set the PWM and PLL Byteclk divider settings to recommended values @@ -249,13 +260,6 @@ static void cdns_dphy_j721e_set_pll_cfg(struct cdns_dphy *dphy, writel(DPHY_TX_J721E_WIZ_LANE_RSTB, dphy->regs + DPHY_TX_J721E_WIZ_RST_CTRL); - - readl_poll_timeout(dphy->regs + DPHY_TX_J721E_WIZ_PLL_CTRL, status, - (status & DPHY_TX_WIZ_PLL_LOCK), 0, POLL_TIMEOUT_US); - - readl_poll_timeout(dphy->regs + DPHY_TX_J721E_WIZ_STATUS, status, - (status & DPHY_TX_WIZ_O_CMN_READY), 0, - POLL_TIMEOUT_US); } static void cdns_dphy_j721e_set_psm_div(struct cdns_dphy *dphy, u8 div) @@ -263,6 +267,23 @@ static void cdns_dphy_j721e_set_psm_div(struct cdns_dphy *dphy, u8 div) writel(div, dphy->regs + DPHY_TX_J721E_WIZ_PSM_FREQ); } +static int cdns_dphy_j721e_wait_for_pll_lock(struct cdns_dphy *dphy) +{ + u32 status; + + return readl_poll_timeout(dphy->regs + DPHY_TX_J721E_WIZ_PLL_CTRL, status, + status & DPHY_TX_WIZ_PLL_LOCK, 0, POLL_TIMEOUT_US); +} + +static int cdns_dphy_j721e_wait_for_cmn_ready(struct cdns_dphy *dphy) +{ + u32 status; + + return readl_poll_timeout(dphy->regs + DPHY_TX_J721E_WIZ_STATUS, status, + status & DPHY_TX_WIZ_O_CMN_READY, 0, + POLL_TIMEOUT_US); +} + /* * This is the reference implementation of DPHY hooks. Specific integration of * this IP may have to re-implement some of them depending on how they decided @@ -278,6 +299,8 @@ static const struct cdns_dphy_ops j721e_dphy_ops = { .get_wakeup_time_ns = cdns_dphy_j721e_get_wakeup_time_ns, .set_pll_cfg = cdns_dphy_j721e_set_pll_cfg, .set_psm_div = cdns_dphy_j721e_set_psm_div, + .wait_for_pll_lock = cdns_dphy_j721e_wait_for_pll_lock, + .wait_for_cmn_ready = cdns_dphy_j721e_wait_for_cmn_ready, }; static int cdns_dphy_config_from_opts(struct phy *phy, @@ -285,18 +308,17 @@ static int cdns_dphy_config_from_opts(struct phy *phy, struct cdns_dphy_cfg *cfg) { struct cdns_dphy *dphy = phy_get_drvdata(phy); - unsigned int dsi_hfp_ext = 0; int ret; ret = phy_mipi_dphy_config_validate(opts); if (ret) return ret; - ret = cdns_dsi_get_dphy_pll_cfg(dphy, cfg, - opts, &dsi_hfp_ext); + ret = cdns_dphy_get_pll_cfg(dphy, cfg, opts); if (ret) return ret; + opts->hs_clk_rate = cfg->hs_clk_rate; opts->wakeup = cdns_dphy_get_wakeup_time_ns(dphy) / 1000; return 0; @@ -334,21 +356,36 @@ static int cdns_dphy_validate(struct phy *phy, enum phy_mode mode, int submode, static int cdns_dphy_configure(struct phy *phy, union phy_configure_opts *opts) { struct cdns_dphy *dphy = phy_get_drvdata(phy); - struct cdns_dphy_cfg cfg = { 0 }; - int ret, band_ctrl; - unsigned int reg; + int ret; - ret = cdns_dphy_config_from_opts(phy, &opts->mipi_dphy, &cfg); - if (ret) - return ret; + ret = cdns_dphy_config_from_opts(phy, &opts->mipi_dphy, &dphy->cfg); + if (!ret) + dphy->is_configured = true; + + return ret; +} + +static int cdns_dphy_power_on(struct phy *phy) +{ + struct cdns_dphy *dphy = phy_get_drvdata(phy); + int ret; + u32 reg; + + if (!dphy->is_configured || dphy->is_powered) + return -EINVAL; + + clk_prepare_enable(dphy->psm_clk); + clk_prepare_enable(dphy->pll_ref_clk); /* * Configure the internal PSM clk divider so that the DPHY has a * 1MHz clk (or something close). */ ret = cdns_dphy_setup_psm(dphy); - if (ret) - return ret; + if (ret) { + dev_err(&dphy->phy->dev, "Failed to setup PSM with error %d\n", ret); + goto err_power_on; + } /* * Configure attach clk lanes to data lanes: the DPHY has 2 clk lanes @@ -363,40 +400,61 @@ static int cdns_dphy_configure(struct phy *phy, union phy_configure_opts *opts) * Configure the DPHY PLL that will be used to generate the TX byte * clk. */ - cdns_dphy_set_pll_cfg(dphy, &cfg); + cdns_dphy_set_pll_cfg(dphy, &dphy->cfg); - band_ctrl = cdns_dphy_tx_get_band_ctrl(opts->mipi_dphy.hs_clk_rate); - if (band_ctrl < 0) - return band_ctrl; + ret = cdns_dphy_tx_get_band_ctrl(dphy->cfg.hs_clk_rate); + if (ret < 0) { + dev_err(&dphy->phy->dev, "Failed to get band control value with error %d\n", ret); + goto err_power_on; + } - reg = FIELD_PREP(DPHY_BAND_CFG_LEFT_BAND, band_ctrl) | - FIELD_PREP(DPHY_BAND_CFG_RIGHT_BAND, band_ctrl); + reg = FIELD_PREP(DPHY_BAND_CFG_LEFT_BAND, ret) | + FIELD_PREP(DPHY_BAND_CFG_RIGHT_BAND, ret); writel(reg, dphy->regs + DPHY_BAND_CFG); - return 0; -} + /* Start TX state machine. */ + reg = readl(dphy->regs + DPHY_CMN_SSM); + writel((reg & DPHY_CMN_SSM_CAL_WAIT_TIME) | DPHY_CMN_SSM_EN | DPHY_CMN_TX_MODE_EN, + dphy->regs + DPHY_CMN_SSM); -static int cdns_dphy_power_on(struct phy *phy) -{ - struct cdns_dphy *dphy = phy_get_drvdata(phy); + ret = cdns_dphy_wait_for_pll_lock(dphy); + if (ret) { + dev_err(&dphy->phy->dev, "Failed to lock PLL with error %d\n", ret); + goto err_power_on; + } - clk_prepare_enable(dphy->psm_clk); - clk_prepare_enable(dphy->pll_ref_clk); + ret = cdns_dphy_wait_for_cmn_ready(dphy); + if (ret) { + dev_err(&dphy->phy->dev, "O_CMN_READY signal failed to assert with error %d\n", + ret); + goto err_power_on; + } - /* Start TX state machine. */ - writel(DPHY_CMN_SSM_EN | DPHY_CMN_TX_MODE_EN, - dphy->regs + DPHY_CMN_SSM); + dphy->is_powered = true; return 0; + +err_power_on: + clk_disable_unprepare(dphy->pll_ref_clk); + clk_disable_unprepare(dphy->psm_clk); + + return ret; } static int cdns_dphy_power_off(struct phy *phy) { struct cdns_dphy *dphy = phy_get_drvdata(phy); + u32 reg; clk_disable_unprepare(dphy->pll_ref_clk); clk_disable_unprepare(dphy->psm_clk); + /* Stop TX state machine. */ + reg = readl(dphy->regs + DPHY_CMN_SSM); + writel(reg & ~DPHY_CMN_SSM_EN, dphy->regs + DPHY_CMN_SSM); + + dphy->is_powered = false; + return 0; } diff --git a/drivers/phy/cadence/phy-cadence-sierra.c b/drivers/phy/cadence/phy-cadence-sierra.c index 74613382ccb0..92ab1a31646a 100644 --- a/drivers/phy/cadence/phy-cadence-sierra.c +++ b/drivers/phy/cadence/phy-cadence-sierra.c @@ -2919,7 +2919,6 @@ static struct platform_driver cdns_sierra_driver = { }; module_platform_driver(cdns_sierra_driver); -MODULE_ALIAS("platform:cdns_sierra"); MODULE_AUTHOR("Cadence Design Systems"); MODULE_DESCRIPTION("CDNS sierra phy driver"); MODULE_LICENSE("GPL v2"); diff --git a/drivers/phy/freescale/phy-fsl-lynx-28g.c b/drivers/phy/freescale/phy-fsl-lynx-28g.c index f7994e8983c8..c20d2636c5e9 100644 --- a/drivers/phy/freescale/phy-fsl-lynx-28g.c +++ b/drivers/phy/freescale/phy-fsl-lynx-28g.c @@ -188,6 +188,10 @@ static struct lynx_28g_pll *lynx_28g_pll_get(struct lynx_28g_priv *priv, return pll; } + /* no pll supports requested mode, either caller forgot to check + * lynx_28g_supports_lane_mode, or this is a bug. + */ + dev_WARN_ONCE(priv->dev, 1, "no pll for interface %s\n", phy_modes(intf)); return NULL; } @@ -276,8 +280,12 @@ static void lynx_28g_lane_set_sgmii(struct lynx_28g_lane *lane) lynx_28g_lane_rmw(lane, LNaGCR0, PROTO_SEL_SGMII, PROTO_SEL_MSK); lynx_28g_lane_rmw(lane, LNaGCR0, IF_WIDTH_10_BIT, IF_WIDTH_MSK); - /* Switch to the PLL that works with this interface type */ + /* Find the PLL that works with this interface type */ pll = lynx_28g_pll_get(priv, PHY_INTERFACE_MODE_SGMII); + if (unlikely(pll == NULL)) + return; + + /* Switch to the PLL that works with this interface type */ lynx_28g_lane_set_pll(lane, pll); /* Choose the portion of clock net to be used on this lane */ @@ -312,8 +320,12 @@ static void lynx_28g_lane_set_10gbaser(struct lynx_28g_lane *lane) lynx_28g_lane_rmw(lane, LNaGCR0, PROTO_SEL_XFI, PROTO_SEL_MSK); lynx_28g_lane_rmw(lane, LNaGCR0, IF_WIDTH_20_BIT, IF_WIDTH_MSK); - /* Switch to the PLL that works with this interface type */ + /* Find the PLL that works with this interface type */ pll = lynx_28g_pll_get(priv, PHY_INTERFACE_MODE_10GBASER); + if (unlikely(pll == NULL)) + return; + + /* Switch to the PLL that works with this interface type */ lynx_28g_lane_set_pll(lane, pll); /* Choose the portion of clock net to be used on this lane */ diff --git a/drivers/phy/hisilicon/phy-hi6220-usb.c b/drivers/phy/hisilicon/phy-hi6220-usb.c index 97bd363dfe87..22d8d8a8dabe 100644 --- a/drivers/phy/hisilicon/phy-hi6220-usb.c +++ b/drivers/phy/hisilicon/phy-hi6220-usb.c @@ -161,5 +161,4 @@ static struct platform_driver hi6220_phy_driver = { module_platform_driver(hi6220_phy_driver); MODULE_DESCRIPTION("HISILICON HI6220 USB PHY driver"); -MODULE_ALIAS("platform:hi6220-usb-phy"); MODULE_LICENSE("GPL"); diff --git a/drivers/phy/hisilicon/phy-histb-combphy.c b/drivers/phy/hisilicon/phy-histb-combphy.c index 7436dcae3981..9dd0bd00b4e4 100644 --- a/drivers/phy/hisilicon/phy-histb-combphy.c +++ b/drivers/phy/hisilicon/phy-histb-combphy.c @@ -73,7 +73,7 @@ static void nano_register_write(struct histb_combphy_priv *priv, static int is_mode_fixed(struct histb_combphy_mode *mode) { - return (mode->fixed != PHY_NONE) ? true : false; + return mode->fixed != PHY_NONE; } static int histb_combphy_set_mode(struct histb_combphy_priv *priv) diff --git a/drivers/phy/ingenic/phy-ingenic-usb.c b/drivers/phy/ingenic/phy-ingenic-usb.c index eb2721f72a4c..7e62d46850fd 100644 --- a/drivers/phy/ingenic/phy-ingenic-usb.c +++ b/drivers/phy/ingenic/phy-ingenic-usb.c @@ -339,17 +339,13 @@ static int ingenic_usb_phy_probe(struct platform_device *pdev) priv->clk = devm_clk_get(dev, NULL); if (IS_ERR(priv->clk)) { err = PTR_ERR(priv->clk); - if (err != -EPROBE_DEFER) - dev_err(dev, "Failed to get clock\n"); - return err; + return dev_err_probe(dev, err, "Failed to get clock\n"); } priv->vcc_supply = devm_regulator_get(dev, "vcc"); if (IS_ERR(priv->vcc_supply)) { err = PTR_ERR(priv->vcc_supply); - if (err != -EPROBE_DEFER) - dev_err(dev, "Failed to get regulator\n"); - return err; + return dev_err_probe(dev, err, "Failed to get regulator\n"); } priv->phy = devm_phy_create(dev, NULL, &ingenic_usb_phy_ops); diff --git a/drivers/phy/qualcomm/phy-qcom-eusb2-repeater.c b/drivers/phy/qualcomm/phy-qcom-eusb2-repeater.c index 8fcbc312fd61..651a12b59bc8 100644 --- a/drivers/phy/qualcomm/phy-qcom-eusb2-repeater.c +++ b/drivers/phy/qualcomm/phy-qcom-eusb2-repeater.c @@ -82,6 +82,14 @@ static const struct eusb2_repeater_cfg pm8550b_eusb2_cfg = { .num_vregs = ARRAY_SIZE(pm8550b_vreg_l), }; +static const struct eusb2_repeater_cfg pmiv0104_eusb2_cfg = { + /* No PMIC-specific init sequence, only board level tuning via DT */ + .init_tbl = (struct eusb2_repeater_init_tbl_reg[]) {}, + .init_tbl_num = 0, + .vreg_list = pm8550b_vreg_l, + .num_vregs = ARRAY_SIZE(pm8550b_vreg_l), +}; + static const struct eusb2_repeater_cfg smb2360_eusb2_cfg = { .init_tbl = smb2360_init_tbl, .init_tbl_num = ARRAY_SIZE(smb2360_init_tbl), @@ -136,6 +144,9 @@ static int eusb2_repeater_init(struct phy *phy) if (!of_property_read_u8(np, "qcom,tune-usb2-amplitude", &val)) regmap_write(regmap, base + EUSB2_TUNE_IUSB2, val); + if (!of_property_read_u8(np, "qcom,tune-res-fsdif", &val)) + regmap_write(regmap, base + EUSB2_TUNE_RES_FSDIF, val); + /* Wait for status OK */ ret = regmap_read_poll_timeout(regmap, base + EUSB2_RPTR_STATUS, poll_val, poll_val & RPTR_OK, 10, 5); @@ -260,6 +271,10 @@ static const struct of_device_id eusb2_repeater_of_match_table[] = { .data = &pm8550b_eusb2_cfg, }, { + .compatible = "qcom,pmiv0104-eusb2-repeater", + .data = &pmiv0104_eusb2_cfg, + }, + { .compatible = "qcom,smb2360-eusb2-repeater", .data = &smb2360_eusb2_cfg, }, diff --git a/drivers/phy/qualcomm/phy-qcom-ipq806x-usb.c b/drivers/phy/qualcomm/phy-qcom-ipq806x-usb.c index 06392ed7c91b..f22c0000479f 100644 --- a/drivers/phy/qualcomm/phy-qcom-ipq806x-usb.c +++ b/drivers/phy/qualcomm/phy-qcom-ipq806x-usb.c @@ -559,7 +559,6 @@ static struct platform_driver qcom_ipq806x_usb_phy_driver = { module_platform_driver(qcom_ipq806x_usb_phy_driver); -MODULE_ALIAS("platform:phy-qcom-ipq806x-usb"); MODULE_LICENSE("GPL v2"); MODULE_AUTHOR("Andy Gross <agross@codeaurora.org>"); MODULE_AUTHOR("Ivan T. Ivanov <iivanov@mm-sol.com>"); diff --git a/drivers/phy/qualcomm/phy-qcom-m31-eusb2.c b/drivers/phy/qualcomm/phy-qcom-m31-eusb2.c index bf32572566c4..0a0d2d9fc846 100644 --- a/drivers/phy/qualcomm/phy-qcom-m31-eusb2.c +++ b/drivers/phy/qualcomm/phy-qcom-m31-eusb2.c @@ -196,7 +196,7 @@ static int m31eusb2_phy_init(struct phy *uphy) ret = clk_prepare_enable(phy->clk); if (ret) { - dev_err(&uphy->dev, "failed to enable cfg ahb clock, %d\n", ret); + dev_err(&uphy->dev, "failed to enable ref clock, %d\n", ret); goto disable_repeater; } diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-combo.c b/drivers/phy/qualcomm/phy-qcom-qmp-combo.c index f07d097b129f..7b5af30f1d02 100644 --- a/drivers/phy/qualcomm/phy-qcom-qmp-combo.c +++ b/drivers/phy/qualcomm/phy-qcom-qmp-combo.c @@ -19,6 +19,7 @@ #include <linux/reset.h> #include <linux/slab.h> #include <linux/usb/typec.h> +#include <linux/usb/typec_dp.h> #include <linux/usb/typec_mux.h> #include <drm/bridge/aux-bridge.h> @@ -62,6 +63,12 @@ #define PHY_INIT_COMPLETE_TIMEOUT 10000 +enum qmpphy_mode { + QMPPHY_MODE_USB3DP = 0, + QMPPHY_MODE_DP_ONLY, + QMPPHY_MODE_USB3_ONLY, +}; + /* set of registers with offsets different per-PHY */ enum qphy_reg_layout { /* PCS registers */ @@ -1844,15 +1851,17 @@ struct qmp_combo { struct mutex phy_mutex; int init_count; + enum qmpphy_mode qmpphy_mode; struct phy *usb_phy; - enum phy_mode mode; + enum phy_mode phy_mode; unsigned int usb_init_count; struct phy *dp_phy; unsigned int dp_aux_cfg; struct phy_configure_opts_dp dp_opts; unsigned int dp_init_count; + bool dp_powered_on; struct clk_fixed_rate pipe_clk_fixed; struct clk_hw dp_link_hw; @@ -1860,6 +1869,8 @@ struct qmp_combo { struct typec_switch_dev *sw; enum typec_orientation orientation; + + struct typec_mux_dev *mux; }; static void qmp_v3_dp_aux_init(struct qmp_combo *qmp); @@ -3036,12 +3047,33 @@ static int qmp_combo_com_init(struct qmp_combo *qmp, bool force) if (qmp->orientation == TYPEC_ORIENTATION_REVERSE) val |= SW_PORTSELECT_VAL; writel(val, com + QPHY_V3_DP_COM_TYPEC_CTRL); - writel(USB3_MODE | DP_MODE, com + QPHY_V3_DP_COM_PHY_MODE_CTRL); - /* bring both QMP USB and QMP DP PHYs PCS block out of reset */ - qphy_clrbits(com, QPHY_V3_DP_COM_RESET_OVRD_CTRL, - SW_DPPHY_RESET_MUX | SW_DPPHY_RESET | - SW_USB3PHY_RESET_MUX | SW_USB3PHY_RESET); + switch (qmp->qmpphy_mode) { + case QMPPHY_MODE_USB3DP: + writel(USB3_MODE | DP_MODE, com + QPHY_V3_DP_COM_PHY_MODE_CTRL); + + /* bring both QMP USB and QMP DP PHYs PCS block out of reset */ + qphy_clrbits(com, QPHY_V3_DP_COM_RESET_OVRD_CTRL, + SW_DPPHY_RESET_MUX | SW_DPPHY_RESET | + SW_USB3PHY_RESET_MUX | SW_USB3PHY_RESET); + break; + + case QMPPHY_MODE_DP_ONLY: + writel(DP_MODE, com + QPHY_V3_DP_COM_PHY_MODE_CTRL); + + /* bring QMP DP PHY PCS block out of reset */ + qphy_clrbits(com, QPHY_V3_DP_COM_RESET_OVRD_CTRL, + SW_DPPHY_RESET_MUX | SW_DPPHY_RESET); + break; + + case QMPPHY_MODE_USB3_ONLY: + writel(USB3_MODE, com + QPHY_V3_DP_COM_PHY_MODE_CTRL); + + /* bring QMP USB PHY PCS block out of reset */ + qphy_clrbits(com, QPHY_V3_DP_COM_RESET_OVRD_CTRL, + SW_USB3PHY_RESET_MUX | SW_USB3PHY_RESET); + break; + } qphy_clrbits(com, QPHY_V3_DP_COM_SWI_CTRL, 0x03); qphy_clrbits(com, QPHY_V3_DP_COM_SW_RESET, SW_RESET); @@ -3133,6 +3165,8 @@ static int qmp_combo_dp_power_on(struct phy *phy) /* Configure link rate, swing, etc. */ cfg->configure_dp_phy(qmp); + qmp->dp_powered_on = true; + mutex_unlock(&qmp->phy_mutex); return 0; @@ -3147,6 +3181,8 @@ static int qmp_combo_dp_power_off(struct phy *phy) /* Assert DP PHY power down */ writel(DP_PHY_PD_CTL_PSR_PWRDN, qmp->dp_dp_phy + QSERDES_DP_PHY_PD_CTL); + qmp->dp_powered_on = false; + mutex_unlock(&qmp->phy_mutex); return 0; @@ -3282,7 +3318,7 @@ static int qmp_combo_usb_set_mode(struct phy *phy, enum phy_mode mode, int submo { struct qmp_combo *qmp = phy_get_drvdata(phy); - qmp->mode = mode; + qmp->phy_mode = mode; return 0; } @@ -3311,8 +3347,8 @@ static void qmp_combo_enable_autonomous_mode(struct qmp_combo *qmp) void __iomem *pcs_misc = qmp->pcs_misc; u32 intr_mask; - if (qmp->mode == PHY_MODE_USB_HOST_SS || - qmp->mode == PHY_MODE_USB_DEVICE_SS) + if (qmp->phy_mode == PHY_MODE_USB_HOST_SS || + qmp->phy_mode == PHY_MODE_USB_DEVICE_SS) intr_mask = ARCVR_DTCT_EN | ALFPS_DTCT_EN; else intr_mask = ARCVR_DTCT_EN | ARCVR_DTCT_EVENT_SEL; @@ -3355,7 +3391,7 @@ static int __maybe_unused qmp_combo_runtime_suspend(struct device *dev) { struct qmp_combo *qmp = dev_get_drvdata(dev); - dev_vdbg(dev, "Suspending QMP phy, mode:%d\n", qmp->mode); + dev_vdbg(dev, "Suspending QMP phy, mode:%d\n", qmp->phy_mode); if (!qmp->init_count) { dev_vdbg(dev, "PHY not initialized, bailing out\n"); @@ -3375,7 +3411,7 @@ static int __maybe_unused qmp_combo_runtime_resume(struct device *dev) struct qmp_combo *qmp = dev_get_drvdata(dev); int ret = 0; - dev_vdbg(dev, "Resuming QMP phy, mode:%d\n", qmp->mode); + dev_vdbg(dev, "Resuming QMP phy, mode:%d\n", qmp->phy_mode); if (!qmp->init_count) { dev_vdbg(dev, "PHY not initialized, bailing out\n"); @@ -3769,17 +3805,109 @@ static int qmp_combo_typec_switch_set(struct typec_switch_dev *sw, return 0; } -static void qmp_combo_typec_unregister(void *data) +static int qmp_combo_typec_mux_set(struct typec_mux_dev *mux, struct typec_mux_state *state) +{ + struct qmp_combo *qmp = typec_mux_get_drvdata(mux); + const struct qmp_phy_cfg *cfg = qmp->cfg; + enum qmpphy_mode new_mode; + unsigned int svid; + + guard(mutex)(&qmp->phy_mutex); + + if (state->alt) + svid = state->alt->svid; + else + svid = 0; + + if (svid == USB_TYPEC_DP_SID) { + switch (state->mode) { + /* DP Only */ + case TYPEC_DP_STATE_C: + case TYPEC_DP_STATE_E: + new_mode = QMPPHY_MODE_DP_ONLY; + break; + + /* DP + USB */ + case TYPEC_DP_STATE_D: + case TYPEC_DP_STATE_F: + + /* Safe fallback...*/ + default: + new_mode = QMPPHY_MODE_USB3DP; + break; + } + } else { + /* No DP SVID => don't care, assume it's just USB3 */ + new_mode = QMPPHY_MODE_USB3_ONLY; + } + + if (new_mode == qmp->qmpphy_mode) { + dev_dbg(qmp->dev, "typec_mux_set: same qmpphy mode, bail out\n"); + return 0; + } + + if (qmp->qmpphy_mode != QMPPHY_MODE_USB3_ONLY && qmp->dp_powered_on) { + dev_dbg(qmp->dev, "typec_mux_set: DP PHY is still in use, delaying switch\n"); + return 0; + } + + dev_dbg(qmp->dev, "typec_mux_set: switching from qmpphy mode %d to %d\n", + qmp->qmpphy_mode, new_mode); + + qmp->qmpphy_mode = new_mode; + + if (qmp->init_count) { + if (qmp->usb_init_count) + qmp_combo_usb_power_off(qmp->usb_phy); + + if (qmp->dp_init_count) + writel(DP_PHY_PD_CTL_PSR_PWRDN, qmp->dp_dp_phy + QSERDES_DP_PHY_PD_CTL); + + qmp_combo_com_exit(qmp, true); + + /* Now everything's powered down, power up the right PHYs */ + qmp_combo_com_init(qmp, true); + + if (new_mode == QMPPHY_MODE_DP_ONLY) { + if (qmp->usb_init_count) + qmp->usb_init_count--; + } + + if (new_mode == QMPPHY_MODE_USB3DP || new_mode == QMPPHY_MODE_USB3_ONLY) { + qmp_combo_usb_power_on(qmp->usb_phy); + if (!qmp->usb_init_count) + qmp->usb_init_count++; + } + + if (new_mode == QMPPHY_MODE_DP_ONLY || new_mode == QMPPHY_MODE_USB3DP) { + if (qmp->dp_init_count) + cfg->dp_aux_init(qmp); + } + } + + return 0; +} + +static void qmp_combo_typec_switch_unregister(void *data) { struct qmp_combo *qmp = data; typec_switch_unregister(qmp->sw); } -static int qmp_combo_typec_switch_register(struct qmp_combo *qmp) +static void qmp_combo_typec_mux_unregister(void *data) +{ + struct qmp_combo *qmp = data; + + typec_mux_unregister(qmp->mux); +} + +static int qmp_combo_typec_register(struct qmp_combo *qmp) { struct typec_switch_desc sw_desc = {}; + struct typec_mux_desc mux_desc = { }; struct device *dev = qmp->dev; + int ret; sw_desc.drvdata = qmp; sw_desc.fwnode = dev->fwnode; @@ -3790,10 +3918,23 @@ static int qmp_combo_typec_switch_register(struct qmp_combo *qmp) return PTR_ERR(qmp->sw); } - return devm_add_action_or_reset(dev, qmp_combo_typec_unregister, qmp); + ret = devm_add_action_or_reset(dev, qmp_combo_typec_switch_unregister, qmp); + if (ret) + return ret; + + mux_desc.drvdata = qmp; + mux_desc.fwnode = dev->fwnode; + mux_desc.set = qmp_combo_typec_mux_set; + qmp->mux = typec_mux_register(dev, &mux_desc); + if (IS_ERR(qmp->mux)) { + dev_err(dev, "Unable to register typec mux: %pe\n", qmp->mux); + return PTR_ERR(qmp->mux); + } + + return devm_add_action_or_reset(dev, qmp_combo_typec_mux_unregister, qmp); } #else -static int qmp_combo_typec_switch_register(struct qmp_combo *qmp) +static int qmp_combo_typec_register(struct qmp_combo *qmp) { return 0; } @@ -4026,7 +4167,7 @@ static int qmp_combo_probe(struct platform_device *pdev) if (ret) goto err_node_put; - ret = qmp_combo_typec_switch_register(qmp); + ret = qmp_combo_typec_register(qmp); if (ret) goto err_node_put; @@ -4048,6 +4189,12 @@ static int qmp_combo_probe(struct platform_device *pdev) if (ret) goto err_node_put; + /* + * The hw default is USB3_ONLY, but USB3+DP mode lets us more easily + * check both sub-blocks' init tables for blunders at probe time. + */ + qmp->qmpphy_mode = QMPPHY_MODE_USB3DP; + qmp->usb_phy = devm_phy_create(dev, usb_np, &qmp_combo_usb_phy_ops); if (IS_ERR(qmp->usb_phy)) { ret = PTR_ERR(qmp->usb_phy); diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c b/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c index 0fa63b734b67..62b1c845b627 100644 --- a/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c +++ b/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c @@ -93,6 +93,13 @@ static const unsigned int pciephy_v6_regs_layout[QPHY_LAYOUT_SIZE] = { [QPHY_PCS_POWER_DOWN_CONTROL] = QPHY_V6_PCS_POWER_DOWN_CONTROL, }; +static const unsigned int pciephy_v7_regs_layout[QPHY_LAYOUT_SIZE] = { + [QPHY_SW_RESET] = QPHY_V7_PCS_SW_RESET, + [QPHY_START_CTRL] = QPHY_V7_PCS_START_CONTROL, + [QPHY_PCS_STATUS] = QPHY_V7_PCS_PCS_STATUS1, + [QPHY_PCS_POWER_DOWN_CONTROL] = QPHY_V7_PCS_POWER_DOWN_CONTROL, +}; + static const struct qmp_phy_init_tbl msm8998_pcie_serdes_tbl[] = { QMP_PHY_INIT_CFG(QSERDES_V3_COM_BIAS_EN_CLKBUFLR_EN, 0x14), QMP_PHY_INIT_CFG(QSERDES_V3_COM_CLK_SELECT, 0x30), @@ -2590,6 +2597,108 @@ static const struct qmp_phy_init_tbl sm8650_qmp_gen4x2_pcie_rx_tbl[] = { QMP_PHY_INIT_CFG(QSERDES_V6_20_RX_MODE_RATE3_B6, 0xff), }; +static const struct qmp_phy_init_tbl sm8750_qmp_gen3x2_pcie_serdes_tbl[] = { + QMP_PHY_INIT_CFG(QSERDES_V7_COM_SSC_EN_CENTER, 0x1), + QMP_PHY_INIT_CFG(QSERDES_V7_COM_SSC_PER1, 0x62), + QMP_PHY_INIT_CFG(QSERDES_V7_COM_SSC_PER2, 0x02), + QMP_PHY_INIT_CFG(QSERDES_V7_COM_SSC_STEP_SIZE1_MODE0, 0xf8), + QMP_PHY_INIT_CFG(QSERDES_V7_COM_SSC_STEP_SIZE2_MODE0, 0x01), + QMP_PHY_INIT_CFG(QSERDES_V7_COM_SSC_STEP_SIZE1_MODE1, 0x93), + QMP_PHY_INIT_CFG(QSERDES_V7_COM_SSC_STEP_SIZE2_MODE1, 0x01), + QMP_PHY_INIT_CFG(QSERDES_V7_COM_CLK_ENABLE1, 0x90), + QMP_PHY_INIT_CFG(QSERDES_V7_COM_SYS_CLK_CTRL, 0x82), + QMP_PHY_INIT_CFG(QSERDES_V7_COM_PLL_IVCO, 0x07), + QMP_PHY_INIT_CFG(QSERDES_V7_COM_CP_CTRL_MODE0, 0x02), + QMP_PHY_INIT_CFG(QSERDES_V7_COM_CP_CTRL_MODE1, 0x02), + QMP_PHY_INIT_CFG(QSERDES_V7_COM_PLL_RCTRL_MODE0, 0x16), + QMP_PHY_INIT_CFG(QSERDES_V7_COM_PLL_RCTRL_MODE1, 0x16), + QMP_PHY_INIT_CFG(QSERDES_V7_COM_PLL_CCTRL_MODE0, 0x36), + QMP_PHY_INIT_CFG(QSERDES_V7_COM_PLL_CCTRL_MODE1, 0x36), + QMP_PHY_INIT_CFG(QSERDES_V7_COM_SYSCLK_EN_SEL, 0x08), + QMP_PHY_INIT_CFG(QSERDES_V7_COM_BG_TIMER, 0x0a), + QMP_PHY_INIT_CFG(QSERDES_V7_COM_LOCK_CMP_EN, 0x42), + QMP_PHY_INIT_CFG(QSERDES_V7_COM_LOCK_CMP1_MODE0, 0x04), + QMP_PHY_INIT_CFG(QSERDES_V7_COM_LOCK_CMP2_MODE0, 0x0d), + QMP_PHY_INIT_CFG(QSERDES_V7_COM_LOCK_CMP1_MODE1, 0x0a), + QMP_PHY_INIT_CFG(QSERDES_V7_COM_LOCK_CMP2_MODE1, 0x1a), + QMP_PHY_INIT_CFG(QSERDES_V7_COM_DEC_START_MODE0, 0x41), + QMP_PHY_INIT_CFG(QSERDES_V7_COM_DEC_START_MODE1, 0x34), + QMP_PHY_INIT_CFG(QSERDES_V7_COM_DIV_FRAC_START1_MODE0, 0xab), + QMP_PHY_INIT_CFG(QSERDES_V7_COM_DIV_FRAC_START2_MODE0, 0xaa), + QMP_PHY_INIT_CFG(QSERDES_V7_COM_DIV_FRAC_START3_MODE0, 0x01), + QMP_PHY_INIT_CFG(QSERDES_V7_COM_DIV_FRAC_START1_MODE1, 0x55), + QMP_PHY_INIT_CFG(QSERDES_V7_COM_DIV_FRAC_START2_MODE1, 0x55), + QMP_PHY_INIT_CFG(QSERDES_V7_COM_DIV_FRAC_START3_MODE1, 0x01), + QMP_PHY_INIT_CFG(QSERDES_V7_COM_VCO_TUNE_MAP, 0x14), + QMP_PHY_INIT_CFG(QSERDES_V7_COM_CLK_SELECT, 0x34), + QMP_PHY_INIT_CFG(QSERDES_V7_COM_HSCLK_SEL_1, 0x01), + QMP_PHY_INIT_CFG(QSERDES_V7_COM_CORECLK_DIV_MODE1, 0x04), + QMP_PHY_INIT_CFG(QSERDES_V7_COM_CMN_CONFIG_1, 0x16), + QMP_PHY_INIT_CFG(QSERDES_V7_COM_ADDITIONAL_MISC_3, 0x0F), + QMP_PHY_INIT_CFG(QSERDES_V7_COM_CORE_CLK_EN, 0xA0), +}; + +static const struct qmp_phy_init_tbl sm8750_qmp_gen3x2_pcie_rx_tbl[] = { + QMP_PHY_INIT_CFG(QSERDES_V7_RX_DFE_CTLE_POST_CAL_OFFSET, 0x38), + QMP_PHY_INIT_CFG(QSERDES_V7_RX_GM_CAL, 0x11), + QMP_PHY_INIT_CFG(QSERDES_V7_RX_RX_MODE_00_HIGH, 0xBF), + QMP_PHY_INIT_CFG(QSERDES_V7_RX_RX_MODE_00_HIGH2, 0xBF), + QMP_PHY_INIT_CFG(QSERDES_V7_RX_RX_MODE_00_HIGH3, 0xB7), + QMP_PHY_INIT_CFG(QSERDES_V7_RX_RX_MODE_00_HIGH4, 0xEA), + QMP_PHY_INIT_CFG(QSERDES_V7_RX_RX_MODE_00_LOW, 0x3F), + QMP_PHY_INIT_CFG(QSERDES_V7_RX_RX_MODE_01_HIGH, 0x09), + QMP_PHY_INIT_CFG(QSERDES_V7_RX_RX_MODE_01_HIGH2, 0x49), + QMP_PHY_INIT_CFG(QSERDES_V7_RX_RX_MODE_01_HIGH3, 0x1B), + QMP_PHY_INIT_CFG(QSERDES_V7_RX_RX_MODE_01_HIGH4, 0x9C), + QMP_PHY_INIT_CFG(QSERDES_V7_RX_RX_MODE_01_LOW, 0xD1), + QMP_PHY_INIT_CFG(QSERDES_V7_RX_RX_MODE_10_HIGH, 0x09), + QMP_PHY_INIT_CFG(QSERDES_V7_RX_RX_MODE_10_HIGH2, 0x49), + QMP_PHY_INIT_CFG(QSERDES_V7_RX_RX_MODE_10_HIGH3, 0x1B), + QMP_PHY_INIT_CFG(QSERDES_V7_RX_RX_MODE_10_HIGH4, 0x9C), + QMP_PHY_INIT_CFG(QSERDES_V7_RX_RX_MODE_10_LOW, 0xD1), + QMP_PHY_INIT_CFG(QSERDES_V7_RX_TX_ADAPT_PRE_THRESH1, 0x3E), + QMP_PHY_INIT_CFG(QSERDES_V7_RX_TX_ADAPT_PRE_THRESH2, 0x1E), + QMP_PHY_INIT_CFG(QSERDES_V7_RX_TX_ADAPT_POST_THRESH, 0xD2), + QMP_PHY_INIT_CFG(QSERDES_V7_RX_UCDR_FO_GAIN, 0x09), + QMP_PHY_INIT_CFG(QSERDES_V7_RX_UCDR_SO_GAIN, 0x05), + QMP_PHY_INIT_CFG(QSERDES_V7_RX_UCDR_SB2_THRESH1, 0x08), + QMP_PHY_INIT_CFG(QSERDES_V7_RX_UCDR_SB2_THRESH2, 0x08), + QMP_PHY_INIT_CFG(QSERDES_V7_RX_VGA_CAL_CNTRL2, 0x09), + QMP_PHY_INIT_CFG(QSERDES_V7_RX_SIGDET_ENABLES, 0x1C), + QMP_PHY_INIT_CFG(QSERDES_V7_RX_SIGDET_CNTRL, 0x60), + QMP_PHY_INIT_CFG(QSERDES_V7_RX_RX_IDAC_TSETTLE_LOW, 0x07), + QMP_PHY_INIT_CFG(QSERDES_V7_RX_SIGDET_CAL_TRIM, 0x08), +}; + +static const struct qmp_phy_init_tbl sm8750_qmp_gen3x2_pcie_tx_tbl[] = { + QMP_PHY_INIT_CFG(QSERDES_V7_TX_LANE_MODE_1, 0x35), + QMP_PHY_INIT_CFG(QSERDES_V7_TX_LANE_MODE_3, 0x10), + QMP_PHY_INIT_CFG(QSERDES_V7_TX_LANE_MODE_4, 0x31), + QMP_PHY_INIT_CFG(QSERDES_V7_TX_LANE_MODE_5, 0x7F), + QMP_PHY_INIT_CFG(QSERDES_V7_TX_PI_QEC_CTRL, 0x02), + QMP_PHY_INIT_CFG(QSERDES_V7_TX_RES_CODE_LANE_OFFSET_RX, 0x08), + QMP_PHY_INIT_CFG(QSERDES_V7_TX_RES_CODE_LANE_OFFSET_TX, 0x14), +}; + +static const struct qmp_phy_init_tbl sm8750_qmp_gen3x2_pcie_pcs_tbl[] = { + QMP_PHY_INIT_CFG(QPHY_V7_PCS_REFGEN_REQ_CONFIG1, 0x05), + QMP_PHY_INIT_CFG(QPHY_V7_PCS_RX_SIGDET_LVL, 0x77), + QMP_PHY_INIT_CFG(QPHY_V7_PCS_RATE_SLEW_CNTRL1, 0x0B), + QMP_PHY_INIT_CFG(QPHY_V7_PCS_EQ_CONFIG2, 0x0F), + QMP_PHY_INIT_CFG(QPHY_V7_PCS_PCS_TX_RX_CONFIG, 0x8C), + QMP_PHY_INIT_CFG(QPHY_V7_PCS_G12S1_TXDEEMPH_M6DB, 0x17), + QMP_PHY_INIT_CFG(QPHY_V7_PCS_G3S2_PRE_GAIN, 0x2E), +}; + +static const struct qmp_phy_init_tbl sm8750_qmp_gen3x2_pcie_pcs_misc_tbl[] = { + QMP_PHY_INIT_CFG(QPHY_PCIE_V6_PCS_PCIE_EQ_CONFIG1, 0x1E), + QMP_PHY_INIT_CFG(QPHY_PCIE_V6_PCS_PCIE_RXEQEVAL_TIME, 0x27), + QMP_PHY_INIT_CFG(QPHY_PCIE_V6_PCS_PCIE_POWER_STATE_CONFIG2, 0x1D), + QMP_PHY_INIT_CFG(QPHY_PCIE_V6_PCS_PCIE_POWER_STATE_CONFIG4, 0x07), + QMP_PHY_INIT_CFG(QPHY_PCIE_V6_PCS_PCIE_ENDPOINT_REFCLK_DRIVE, 0xC1), + QMP_PHY_INIT_CFG(QPHY_PCIE_V6_PCS_PCIE_OSC_DTCT_ACTIONS, 0x00), +}; + static const struct qmp_phy_init_tbl sa8775p_qmp_gen4x2_pcie_serdes_alt_tbl[] = { QMP_PHY_INIT_CFG(QSERDES_V5_COM_BIAS_EN_CLKBUFLR_EN, 0x14), QMP_PHY_INIT_CFG(QSERDES_V5_COM_PLL_IVCO, 0x0f), @@ -3215,6 +3324,16 @@ static const struct qmp_pcie_offsets qmp_pcie_offsets_v5_30 = { .rx2 = 0x3a00, }; +static const struct qmp_pcie_offsets qmp_pcie_offsets_v7 = { + .serdes = 0x0, + .pcs = 0x400, + .pcs_misc = 0x800, + .tx = 0x1000, + .rx = 0x1200, + .tx2 = 0x1800, + .rx2 = 0x1a00, +}; + static const struct qmp_pcie_offsets qmp_pcie_offsets_v6_20 = { .serdes = 0x1000, .pcs = 0x1200, @@ -4004,6 +4123,33 @@ static const struct qmp_phy_cfg sm8550_qmp_gen3x2_pciephy_cfg = { .phy_status = PHYSTATUS, }; +static const struct qmp_phy_cfg sm8750_qmp_gen3x2_pciephy_cfg = { + .lanes = 2, + + .offsets = &qmp_pcie_offsets_v7, + + .tbls = { + .serdes = sm8750_qmp_gen3x2_pcie_serdes_tbl, + .serdes_num = ARRAY_SIZE(sm8750_qmp_gen3x2_pcie_serdes_tbl), + .tx = sm8750_qmp_gen3x2_pcie_tx_tbl, + .tx_num = ARRAY_SIZE(sm8750_qmp_gen3x2_pcie_tx_tbl), + .rx = sm8750_qmp_gen3x2_pcie_rx_tbl, + .rx_num = ARRAY_SIZE(sm8750_qmp_gen3x2_pcie_rx_tbl), + .pcs = sm8750_qmp_gen3x2_pcie_pcs_tbl, + .pcs_num = ARRAY_SIZE(sm8750_qmp_gen3x2_pcie_pcs_tbl), + .pcs_misc = sm8750_qmp_gen3x2_pcie_pcs_misc_tbl, + .pcs_misc_num = ARRAY_SIZE(sm8750_qmp_gen3x2_pcie_pcs_misc_tbl), + }, + .reset_list = sdm845_pciephy_reset_l, + .num_resets = ARRAY_SIZE(sdm845_pciephy_reset_l), + .vreg_list = qmp_phy_vreg_l, + .num_vregs = ARRAY_SIZE(qmp_phy_vreg_l), + .regs = pciephy_v7_regs_layout, + + .pwrdn_ctrl = SW_PWRDN | REFCLK_DRV_DSBL, + .phy_status = PHYSTATUS, +}; + static const struct qmp_phy_cfg sm8550_qmp_gen4x2_pciephy_cfg = { .lanes = 2, @@ -5113,6 +5259,9 @@ static const struct of_device_id qmp_pcie_of_match_table[] = { .compatible = "qcom,sm8650-qmp-gen4x2-pcie-phy", .data = &sm8650_qmp_gen4x2_pciephy_cfg, }, { + .compatible = "qcom,sm8750-qmp-gen3x2-pcie-phy", + .data = &sm8750_qmp_gen3x2_pciephy_cfg, + }, { .compatible = "qcom,x1e80100-qmp-gen3x2-pcie-phy", .data = &sm8550_qmp_gen3x2_pciephy_cfg, }, { diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-pcs-v7.h b/drivers/phy/qualcomm/phy-qcom-qmp-pcs-v7.h index c7759892ed2e..4b7fcaa6a374 100644 --- a/drivers/phy/qualcomm/phy-qcom-qmp-pcs-v7.h +++ b/drivers/phy/qualcomm/phy-qcom-qmp-pcs-v7.h @@ -17,6 +17,8 @@ #define QPHY_V7_PCS_LOCK_DETECT_CONFIG3 0x0cc #define QPHY_V7_PCS_LOCK_DETECT_CONFIG6 0x0d8 #define QPHY_V7_PCS_REFGEN_REQ_CONFIG1 0x0dc +#define QPHY_V7_PCS_G12S1_TXDEEMPH_M6DB 0x168 +#define QPHY_V7_PCS_G3S2_PRE_GAIN 0x170 #define QPHY_V7_PCS_RX_SIGDET_LVL 0x188 #define QPHY_V7_PCS_RCVR_DTCT_DLY_P1U2_L 0x190 #define QPHY_V7_PCS_RCVR_DTCT_DLY_P1U2_H 0x194 diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-txrx-v7.h b/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-txrx-v7.h index 91f865b11347..6ab943ff57ff 100644 --- a/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-txrx-v7.h +++ b/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-txrx-v7.h @@ -40,6 +40,8 @@ #define QSERDES_V7_RX_UCDR_SB2_GAIN1 0x54 #define QSERDES_V7_RX_UCDR_SB2_GAIN2 0x58 #define QSERDES_V7_RX_AUX_DATA_TCOARSE_TFINE 0x60 +#define QSERDES_V7_RX_TX_ADAPT_PRE_THRESH1 0xc4 +#define QSERDES_V7_RX_TX_ADAPT_PRE_THRESH2 0xc8 #define QSERDES_V7_RX_TX_ADAPT_POST_THRESH 0xcc #define QSERDES_V7_RX_VGA_CAL_CNTRL1 0xd4 #define QSERDES_V7_RX_VGA_CAL_CNTRL2 0xd8 @@ -50,7 +52,7 @@ #define QSERDES_V7_RX_RX_IDAC_TSETTLE_LOW 0xf8 #define QSERDES_V7_RX_RX_IDAC_TSETTLE_HIGH 0xfc #define QSERDES_V7_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1 0x110 -#define QSERDES_V7_RX_SIDGET_ENABLES 0x118 +#define QSERDES_V7_RX_SIGDET_ENABLES 0x118 #define QSERDES_V7_RX_SIGDET_CNTRL 0x11c #define QSERDES_V7_RX_SIGDET_DEGLITCH_CNTRL 0x124 #define QSERDES_V7_RX_RX_MODE_00_LOW 0x15c diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c b/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c index 9c69c77d10c8..8a280433a42b 100644 --- a/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c +++ b/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c @@ -1107,7 +1107,7 @@ struct qmp_phy_cfg { const struct qmp_phy_cfg_tbls tbls_hs_overlay[NUM_OVERLAY]; /* regulators to be requested */ - const char * const *vreg_list; + const struct regulator_bulk_data *vreg_list; int num_vregs; /* array of registers with different offsets */ @@ -1164,9 +1164,80 @@ static inline void qphy_clrbits(void __iomem *base, u32 offset, u32 val) readl(base + offset); } -/* list of regulators */ -static const char * const qmp_phy_vreg_l[] = { - "vdda-phy", "vdda-pll", +/* Regulator bulk data with load values for specific configurations */ +static const struct regulator_bulk_data msm8996_ufsphy_vreg_l[] = { + { .supply = "vdda-phy", .init_load_uA = 51400 }, + { .supply = "vdda-pll", .init_load_uA = 14600 }, +}; + +static const struct regulator_bulk_data sa8775p_ufsphy_vreg_l[] = { + { .supply = "vdda-phy", .init_load_uA = 137000 }, + { .supply = "vdda-pll", .init_load_uA = 18300 }, +}; + +static const struct regulator_bulk_data sc7280_ufsphy_vreg_l[] = { + { .supply = "vdda-phy", .init_load_uA = 97500 }, + { .supply = "vdda-pll", .init_load_uA = 18400 }, +}; + +static const struct regulator_bulk_data sc8280xp_ufsphy_vreg_l[] = { + { .supply = "vdda-phy", .init_load_uA = 85700 }, + { .supply = "vdda-pll", .init_load_uA = 18300 }, +}; + +static const struct regulator_bulk_data sdm845_ufsphy_vreg_l[] = { + { .supply = "vdda-phy", .init_load_uA = 51400 }, + { .supply = "vdda-pll", .init_load_uA = 14600 }, +}; + +static const struct regulator_bulk_data sm6115_ufsphy_vreg_l[] = { + { .supply = "vdda-phy", .init_load_uA = 51400 }, + { .supply = "vdda-pll", .init_load_uA = 14200 }, +}; + +static const struct regulator_bulk_data sm7150_ufsphy_vreg_l[] = { + { .supply = "vdda-phy", .init_load_uA = 62900 }, + { .supply = "vdda-pll", .init_load_uA = 18300 }, +}; + +static const struct regulator_bulk_data sm8150_ufsphy_vreg_l[] = { + { .supply = "vdda-phy", .init_load_uA = 90200 }, + { .supply = "vdda-pll", .init_load_uA = 19000 }, +}; + +static const struct regulator_bulk_data sm8250_ufsphy_vreg_l[] = { + { .supply = "vdda-phy", .init_load_uA = 89900 }, + { .supply = "vdda-pll", .init_load_uA = 18800 }, +}; + +static const struct regulator_bulk_data sm8350_ufsphy_vreg_l[] = { + { .supply = "vdda-phy", .init_load_uA = 91600 }, + { .supply = "vdda-pll", .init_load_uA = 19000 }, +}; + +static const struct regulator_bulk_data sm8450_ufsphy_vreg_l[] = { + { .supply = "vdda-phy", .init_load_uA = 173000 }, + { .supply = "vdda-pll", .init_load_uA = 24900 }, +}; + +static const struct regulator_bulk_data sm8475_ufsphy_vreg_l[] = { + { .supply = "vdda-phy", .init_load_uA = 213030 }, + { .supply = "vdda-pll", .init_load_uA = 18340 }, +}; + +static const struct regulator_bulk_data sm8550_ufsphy_vreg_l[] = { + { .supply = "vdda-phy", .init_load_uA = 188000 }, + { .supply = "vdda-pll", .init_load_uA = 18300 }, +}; + +static const struct regulator_bulk_data sm8650_ufsphy_vreg_l[] = { + { .supply = "vdda-phy", .init_load_uA = 205000 }, + { .supply = "vdda-pll", .init_load_uA = 17500 }, +}; + +static const struct regulator_bulk_data sm8750_ufsphy_vreg_l[] = { + { .supply = "vdda-phy", .init_load_uA = 213000 }, + { .supply = "vdda-pll", .init_load_uA = 18300 }, }; static const struct qmp_ufs_offsets qmp_ufs_offsets = { @@ -1202,8 +1273,8 @@ static const struct qmp_phy_cfg msm8996_ufsphy_cfg = { .rx_num = ARRAY_SIZE(msm8996_ufsphy_rx), }, - .vreg_list = qmp_phy_vreg_l, - .num_vregs = ARRAY_SIZE(qmp_phy_vreg_l), + .vreg_list = msm8996_ufsphy_vreg_l, + .num_vregs = ARRAY_SIZE(msm8996_ufsphy_vreg_l), .regs = ufsphy_v2_regs_layout, @@ -1239,8 +1310,8 @@ static const struct qmp_phy_cfg sa8775p_ufsphy_cfg = { .pcs_num = ARRAY_SIZE(sm8350_ufsphy_g4_pcs), .max_gear = UFS_HS_G4, }, - .vreg_list = qmp_phy_vreg_l, - .num_vregs = ARRAY_SIZE(qmp_phy_vreg_l), + .vreg_list = sa8775p_ufsphy_vreg_l, + .num_vregs = ARRAY_SIZE(sa8775p_ufsphy_vreg_l), .regs = ufsphy_v5_regs_layout, }; @@ -1273,8 +1344,8 @@ static const struct qmp_phy_cfg sc7280_ufsphy_cfg = { .pcs_num = ARRAY_SIZE(sm8150_ufsphy_hs_g4_pcs), .max_gear = UFS_HS_G4, }, - .vreg_list = qmp_phy_vreg_l, - .num_vregs = ARRAY_SIZE(qmp_phy_vreg_l), + .vreg_list = sc7280_ufsphy_vreg_l, + .num_vregs = ARRAY_SIZE(sc7280_ufsphy_vreg_l), .regs = ufsphy_v4_regs_layout, }; @@ -1307,8 +1378,8 @@ static const struct qmp_phy_cfg sc8280xp_ufsphy_cfg = { .pcs_num = ARRAY_SIZE(sm8350_ufsphy_g4_pcs), .max_gear = UFS_HS_G4, }, - .vreg_list = qmp_phy_vreg_l, - .num_vregs = ARRAY_SIZE(qmp_phy_vreg_l), + .vreg_list = sc8280xp_ufsphy_vreg_l, + .num_vregs = ARRAY_SIZE(sc8280xp_ufsphy_vreg_l), .regs = ufsphy_v5_regs_layout, }; @@ -1332,8 +1403,8 @@ static const struct qmp_phy_cfg sdm845_ufsphy_cfg = { .serdes = sdm845_ufsphy_hs_b_serdes, .serdes_num = ARRAY_SIZE(sdm845_ufsphy_hs_b_serdes), }, - .vreg_list = qmp_phy_vreg_l, - .num_vregs = ARRAY_SIZE(qmp_phy_vreg_l), + .vreg_list = sdm845_ufsphy_vreg_l, + .num_vregs = ARRAY_SIZE(sdm845_ufsphy_vreg_l), .regs = ufsphy_v3_regs_layout, .no_pcs_sw_reset = true, @@ -1359,8 +1430,8 @@ static const struct qmp_phy_cfg sm6115_ufsphy_cfg = { .serdes = sm6115_ufsphy_hs_b_serdes, .serdes_num = ARRAY_SIZE(sm6115_ufsphy_hs_b_serdes), }, - .vreg_list = qmp_phy_vreg_l, - .num_vregs = ARRAY_SIZE(qmp_phy_vreg_l), + .vreg_list = sm6115_ufsphy_vreg_l, + .num_vregs = ARRAY_SIZE(sm6115_ufsphy_vreg_l), .regs = ufsphy_v2_regs_layout, .no_pcs_sw_reset = true, @@ -1386,8 +1457,8 @@ static const struct qmp_phy_cfg sm7150_ufsphy_cfg = { .serdes = sdm845_ufsphy_hs_b_serdes, .serdes_num = ARRAY_SIZE(sdm845_ufsphy_hs_b_serdes), }, - .vreg_list = qmp_phy_vreg_l, - .num_vregs = ARRAY_SIZE(qmp_phy_vreg_l), + .vreg_list = sm7150_ufsphy_vreg_l, + .num_vregs = ARRAY_SIZE(sm7150_ufsphy_vreg_l), .regs = ufsphy_v3_regs_layout, .no_pcs_sw_reset = true, @@ -1422,8 +1493,8 @@ static const struct qmp_phy_cfg sm8150_ufsphy_cfg = { .pcs_num = ARRAY_SIZE(sm8150_ufsphy_hs_g4_pcs), .max_gear = UFS_HS_G4, }, - .vreg_list = qmp_phy_vreg_l, - .num_vregs = ARRAY_SIZE(qmp_phy_vreg_l), + .vreg_list = sm8150_ufsphy_vreg_l, + .num_vregs = ARRAY_SIZE(sm8150_ufsphy_vreg_l), .regs = ufsphy_v4_regs_layout, }; @@ -1456,8 +1527,8 @@ static const struct qmp_phy_cfg sm8250_ufsphy_cfg = { .pcs_num = ARRAY_SIZE(sm8150_ufsphy_hs_g4_pcs), .max_gear = UFS_HS_G4, }, - .vreg_list = qmp_phy_vreg_l, - .num_vregs = ARRAY_SIZE(qmp_phy_vreg_l), + .vreg_list = sm8250_ufsphy_vreg_l, + .num_vregs = ARRAY_SIZE(sm8250_ufsphy_vreg_l), .regs = ufsphy_v4_regs_layout, }; @@ -1490,8 +1561,8 @@ static const struct qmp_phy_cfg sm8350_ufsphy_cfg = { .pcs_num = ARRAY_SIZE(sm8350_ufsphy_g4_pcs), .max_gear = UFS_HS_G4, }, - .vreg_list = qmp_phy_vreg_l, - .num_vregs = ARRAY_SIZE(qmp_phy_vreg_l), + .vreg_list = sm8350_ufsphy_vreg_l, + .num_vregs = ARRAY_SIZE(sm8350_ufsphy_vreg_l), .regs = ufsphy_v5_regs_layout, }; @@ -1524,8 +1595,8 @@ static const struct qmp_phy_cfg sm8450_ufsphy_cfg = { .pcs_num = ARRAY_SIZE(sm8350_ufsphy_g4_pcs), .max_gear = UFS_HS_G4, }, - .vreg_list = qmp_phy_vreg_l, - .num_vregs = ARRAY_SIZE(qmp_phy_vreg_l), + .vreg_list = sm8450_ufsphy_vreg_l, + .num_vregs = ARRAY_SIZE(sm8450_ufsphy_vreg_l), .regs = ufsphy_v5_regs_layout, }; @@ -1560,8 +1631,8 @@ static const struct qmp_phy_cfg sm8475_ufsphy_cfg = { .pcs_num = ARRAY_SIZE(sm8475_ufsphy_g4_pcs), .max_gear = UFS_HS_G4, }, - .vreg_list = qmp_phy_vreg_l, - .num_vregs = ARRAY_SIZE(qmp_phy_vreg_l), + .vreg_list = sm8475_ufsphy_vreg_l, + .num_vregs = ARRAY_SIZE(sm8475_ufsphy_vreg_l), .regs = ufsphy_v6_regs_layout, }; @@ -1605,8 +1676,8 @@ static const struct qmp_phy_cfg sm8550_ufsphy_cfg = { .pcs_num = ARRAY_SIZE(sm8550_ufsphy_g5_pcs), .max_gear = UFS_HS_G5, }, - .vreg_list = qmp_phy_vreg_l, - .num_vregs = ARRAY_SIZE(qmp_phy_vreg_l), + .vreg_list = sm8550_ufsphy_vreg_l, + .num_vregs = ARRAY_SIZE(sm8550_ufsphy_vreg_l), .regs = ufsphy_v6_regs_layout, }; @@ -1637,8 +1708,8 @@ static const struct qmp_phy_cfg sm8650_ufsphy_cfg = { .max_gear = UFS_HS_G5, }, - .vreg_list = qmp_phy_vreg_l, - .num_vregs = ARRAY_SIZE(qmp_phy_vreg_l), + .vreg_list = sm8650_ufsphy_vreg_l, + .num_vregs = ARRAY_SIZE(sm8650_ufsphy_vreg_l), .regs = ufsphy_v6_regs_layout, }; @@ -1675,8 +1746,8 @@ static const struct qmp_phy_cfg sm8750_ufsphy_cfg = { .max_gear = UFS_HS_G5, }, - .vreg_list = qmp_phy_vreg_l, - .num_vregs = ARRAY_SIZE(qmp_phy_vreg_l), + .vreg_list = sm8750_ufsphy_vreg_l, + .num_vregs = ARRAY_SIZE(sm8750_ufsphy_vreg_l), .regs = ufsphy_v6_regs_layout, }; @@ -1890,22 +1961,6 @@ static const struct phy_ops qcom_qmp_ufs_phy_ops = { .owner = THIS_MODULE, }; -static int qmp_ufs_vreg_init(struct qmp_ufs *qmp) -{ - const struct qmp_phy_cfg *cfg = qmp->cfg; - struct device *dev = qmp->dev; - int num = cfg->num_vregs; - int i; - - qmp->vregs = devm_kcalloc(dev, num, sizeof(*qmp->vregs), GFP_KERNEL); - if (!qmp->vregs) - return -ENOMEM; - - for (i = 0; i < num; i++) - qmp->vregs[i].supply = cfg->vreg_list[i]; - - return devm_regulator_bulk_get(dev, num, qmp->vregs); -} static int qmp_ufs_clk_init(struct qmp_ufs *qmp) { @@ -2068,7 +2123,9 @@ static int qmp_ufs_probe(struct platform_device *pdev) if (ret) return ret; - ret = qmp_ufs_vreg_init(qmp); + ret = devm_regulator_bulk_get_const(dev, qmp->cfg->num_vregs, + qmp->cfg->vreg_list, + &qmp->vregs); if (ret) return ret; diff --git a/drivers/phy/renesas/phy-rcar-gen3-usb2.c b/drivers/phy/renesas/phy-rcar-gen3-usb2.c index 47beb94cd424..3f6b480e1092 100644 --- a/drivers/phy/renesas/phy-rcar-gen3-usb2.c +++ b/drivers/phy/renesas/phy-rcar-gen3-usb2.c @@ -9,6 +9,8 @@ * Copyright (C) 2014 Cogent Embedded, Inc. */ +#include <linux/bitfield.h> +#include <linux/bits.h> #include <linux/cleanup.h> #include <linux/extcon-provider.h> #include <linux/interrupt.h> @@ -69,14 +71,20 @@ #define USB2_COMMCTRL_OTG_PERI BIT(31) /* 1 = Peripheral mode */ /* OBINTSTA and OBINTEN */ +#define USB2_OBINTSTA_CLEAR GENMASK(31, 0) #define USB2_OBINT_SESSVLDCHG BIT(12) #define USB2_OBINT_IDDIGCHG BIT(11) -#define USB2_OBINT_BITS (USB2_OBINT_SESSVLDCHG | \ - USB2_OBINT_IDDIGCHG) +#define USB2_OBINT_VBSTAINT BIT(3) +#define USB2_OBINT_IDCHG_EN BIT(0) /* RZ/G2L specific */ /* VBCTRL */ +#define USB2_VBCTRL_VBSTA_MASK GENMASK(31, 28) +#define USB2_VBCTRL_VBSTA_DEFAULT 2 +#define USB2_VBCTRL_VBLVL_MASK GENMASK(23, 20) +#define USB2_VBCTRL_VBLVL(m) FIELD_PREP_CONST(USB2_VBCTRL_VBLVL_MASK, (m)) #define USB2_VBCTRL_OCCLREN BIT(16) #define USB2_VBCTRL_DRVVBUSSEL BIT(8) +#define USB2_VBCTRL_SIDDQREL BIT(2) #define USB2_VBCTRL_VBOUT BIT(0) /* LINECTRL1 */ @@ -89,11 +97,11 @@ /* ADPCTRL */ #define USB2_ADPCTRL_OTGSESSVLD BIT(20) #define USB2_ADPCTRL_IDDIG BIT(19) +#define USB2_ADPCTRL_VBUSVALID BIT(18) #define USB2_ADPCTRL_IDPULLUP BIT(5) /* 1 = ID sampling is enabled */ #define USB2_ADPCTRL_DRVVBUS BIT(4) /* RZ/G2L specific */ -#define USB2_OBINT_IDCHG_EN BIT(0) #define USB2_LINECTRL1_USB2_IDMON BIT(0) #define NUM_OF_PHYS 4 @@ -122,6 +130,7 @@ struct rcar_gen3_phy { struct rcar_gen3_chan { void __iomem *base; struct device *dev; /* platform_device's device */ + const struct rcar_gen3_phy_drv_data *phy_data; struct extcon_dev *extcon; struct rcar_gen3_phy rphys[NUM_OF_PHYS]; struct regulator *vbus; @@ -129,12 +138,9 @@ struct rcar_gen3_chan { struct work_struct work; spinlock_t lock; /* protects access to hardware and driver data structure. */ enum usb_dr_mode dr_mode; - u32 obint_enable_bits; bool extcon_host; bool is_otg_channel; bool uses_otg_pins; - bool soc_no_adp_ctrl; - bool utmi_ctrl; }; struct rcar_gen3_phy_drv_data { @@ -142,6 +148,8 @@ struct rcar_gen3_phy_drv_data { bool no_adp_ctrl; bool init_bus; bool utmi_ctrl; + bool vblvl_ctrl; + u32 obint_enable_bits; }; /* @@ -203,8 +211,7 @@ static void rcar_gen3_enable_vbus_ctrl(struct rcar_gen3_chan *ch, int vbus) u32 vbus_ctrl_val = USB2_ADPCTRL_DRVVBUS; u32 val; - dev_vdbg(ch->dev, "%s: %08x, %d\n", __func__, val, vbus); - if (ch->soc_no_adp_ctrl) { + if (ch->phy_data->no_adp_ctrl || ch->phy_data->vblvl_ctrl) { if (ch->vbus) regulator_hardware_enable(ch->vbus, vbus); @@ -217,6 +224,7 @@ static void rcar_gen3_enable_vbus_ctrl(struct rcar_gen3_chan *ch, int vbus) val |= vbus_ctrl_val; else val &= ~vbus_ctrl_val; + dev_vdbg(ch->dev, "%s: %08x, %d\n", __func__, val, vbus); writel(val, usb2_base + vbus_ctrl_reg); } @@ -226,9 +234,9 @@ static void rcar_gen3_control_otg_irq(struct rcar_gen3_chan *ch, int enable) u32 val = readl(usb2_base + USB2_OBINTEN); if (ch->uses_otg_pins && enable) - val |= ch->obint_enable_bits; + val |= ch->phy_data->obint_enable_bits; else - val &= ~ch->obint_enable_bits; + val &= ~ch->phy_data->obint_enable_bits; writel(val, usb2_base + USB2_OBINTEN); } @@ -287,10 +295,20 @@ static void rcar_gen3_init_from_a_peri_to_a_host(struct rcar_gen3_chan *ch) static bool rcar_gen3_check_id(struct rcar_gen3_chan *ch) { + if (ch->phy_data->vblvl_ctrl) { + bool vbus_valid; + bool device; + + device = !!(readl(ch->base + USB2_ADPCTRL) & USB2_ADPCTRL_IDDIG); + vbus_valid = !!(readl(ch->base + USB2_ADPCTRL) & USB2_ADPCTRL_VBUSVALID); + + return vbus_valid ? device : !device; + } + if (!ch->uses_otg_pins) - return (ch->dr_mode == USB_DR_MODE_HOST) ? false : true; + return ch->dr_mode != USB_DR_MODE_HOST; - if (ch->soc_no_adp_ctrl) + if (ch->phy_data->no_adp_ctrl) return !!(readl(ch->base + USB2_LINECTRL1) & USB2_LINECTRL1_USB2_IDMON); return !!(readl(ch->base + USB2_ADPCTRL) & USB2_ADPCTRL_IDDIG); @@ -421,21 +439,47 @@ static void rcar_gen3_init_otg(struct rcar_gen3_chan *ch) USB2_LINECTRL1_DMRPD_EN | USB2_LINECTRL1_DM_RPD; writel(val, usb2_base + USB2_LINECTRL1); - if (!ch->soc_no_adp_ctrl) { - val = readl(usb2_base + USB2_VBCTRL); - val &= ~USB2_VBCTRL_OCCLREN; - writel(val | USB2_VBCTRL_DRVVBUSSEL, usb2_base + USB2_VBCTRL); - val = readl(usb2_base + USB2_ADPCTRL); - writel(val | USB2_ADPCTRL_IDPULLUP, usb2_base + USB2_ADPCTRL); + if (!ch->phy_data->no_adp_ctrl) { + if (ch->phy_data->vblvl_ctrl) { + val = readl(usb2_base + USB2_VBCTRL); + val = (val & ~USB2_VBCTRL_VBLVL_MASK) | USB2_VBCTRL_VBLVL(2); + writel(val, usb2_base + USB2_VBCTRL); + val = readl(usb2_base + USB2_ADPCTRL); + writel(val | USB2_ADPCTRL_IDPULLUP | USB2_ADPCTRL_DRVVBUS, + usb2_base + USB2_ADPCTRL); + } else { + val = readl(usb2_base + USB2_VBCTRL); + val &= ~USB2_VBCTRL_OCCLREN; + writel(val | USB2_VBCTRL_DRVVBUSSEL, usb2_base + USB2_VBCTRL); + val = readl(usb2_base + USB2_ADPCTRL); + writel(val | USB2_ADPCTRL_IDPULLUP, usb2_base + USB2_ADPCTRL); + } } mdelay(20); writel(0xffffffff, usb2_base + USB2_OBINTSTA); - writel(ch->obint_enable_bits, usb2_base + USB2_OBINTEN); + writel(ch->phy_data->obint_enable_bits, usb2_base + USB2_OBINTEN); rcar_gen3_device_recognition(ch); } +static void rcar_gen3_configure_vblvl_ctrl(struct rcar_gen3_chan *ch) +{ + void __iomem *usb2_base = ch->base; + u32 val; + + if (!ch->phy_data->vblvl_ctrl) + return; + + val = readl(usb2_base + USB2_VBCTRL); + if ((val & USB2_VBCTRL_VBSTA_MASK) == + FIELD_PREP_CONST(USB2_VBCTRL_VBSTA_MASK, USB2_VBCTRL_VBSTA_DEFAULT)) + val &= ~USB2_VBCTRL_VBLVL_MASK; + else + val |= USB2_VBCTRL_VBLVL(USB2_VBCTRL_VBSTA_DEFAULT); + writel(val, usb2_base + USB2_VBCTRL); +} + static irqreturn_t rcar_gen3_phy_usb2_irq(int irq, void *_ch) { struct rcar_gen3_chan *ch = _ch; @@ -451,10 +495,14 @@ static irqreturn_t rcar_gen3_phy_usb2_irq(int irq, void *_ch) scoped_guard(spinlock, &ch->lock) { status = readl(usb2_base + USB2_OBINTSTA); - if (status & ch->obint_enable_bits) { + if (status & ch->phy_data->obint_enable_bits) { dev_vdbg(dev, "%s: %08x\n", __func__, status); - writel(ch->obint_enable_bits, usb2_base + USB2_OBINTSTA); + if (ch->phy_data->vblvl_ctrl) + writel(USB2_OBINTSTA_CLEAR, usb2_base + USB2_OBINTSTA); + else + writel(ch->phy_data->obint_enable_bits, usb2_base + USB2_OBINTSTA); rcar_gen3_device_recognition(ch); + rcar_gen3_configure_vblvl_ctrl(ch); ret = IRQ_HANDLED; } } @@ -487,7 +535,14 @@ static int rcar_gen3_phy_usb2_init(struct phy *p) if (rphy->int_enable_bits) rcar_gen3_init_otg(channel); - if (channel->utmi_ctrl) { + if (channel->phy_data->vblvl_ctrl) { + /* SIDDQ mode release */ + writel(readl(usb2_base + USB2_VBCTRL) | USB2_VBCTRL_SIDDQREL, + usb2_base + USB2_VBCTRL); + udelay(250); + } + + if (channel->phy_data->utmi_ctrl) { val = readl(usb2_base + USB2_REGEN_CG_CTRL) | USB2_REGEN_CG_CTRL_UPHY_WEN; writel(val, usb2_base + USB2_REGEN_CG_CTRL); @@ -592,28 +647,41 @@ static const struct phy_ops rz_g1c_phy_usb2_ops = { static const struct rcar_gen3_phy_drv_data rcar_gen3_phy_usb2_data = { .phy_usb2_ops = &rcar_gen3_phy_usb2_ops, .no_adp_ctrl = false, + .obint_enable_bits = USB2_OBINT_SESSVLDCHG | + USB2_OBINT_IDDIGCHG, }; static const struct rcar_gen3_phy_drv_data rz_g1c_phy_usb2_data = { .phy_usb2_ops = &rz_g1c_phy_usb2_ops, .no_adp_ctrl = false, + .obint_enable_bits = USB2_OBINT_SESSVLDCHG | + USB2_OBINT_IDDIGCHG, }; static const struct rcar_gen3_phy_drv_data rz_g2l_phy_usb2_data = { .phy_usb2_ops = &rcar_gen3_phy_usb2_ops, .no_adp_ctrl = true, + .obint_enable_bits = USB2_OBINT_IDCHG_EN, }; static const struct rcar_gen3_phy_drv_data rz_g3s_phy_usb2_data = { .phy_usb2_ops = &rcar_gen3_phy_usb2_ops, .no_adp_ctrl = true, .init_bus = true, + .obint_enable_bits = USB2_OBINT_IDCHG_EN, +}; + +static const struct rcar_gen3_phy_drv_data rz_t2h_phy_usb2_data = { + .phy_usb2_ops = &rcar_gen3_phy_usb2_ops, + .vblvl_ctrl = true, + .obint_enable_bits = USB2_OBINT_IDCHG_EN | USB2_OBINT_VBSTAINT, }; static const struct rcar_gen3_phy_drv_data rz_v2h_phy_usb2_data = { .phy_usb2_ops = &rcar_gen3_phy_usb2_ops, .no_adp_ctrl = true, .utmi_ctrl = true, + .obint_enable_bits = USB2_OBINT_IDCHG_EN, }; static const struct of_device_id rcar_gen3_phy_usb2_match_table[] = { @@ -642,6 +710,10 @@ static const struct of_device_id rcar_gen3_phy_usb2_match_table[] = { .data = &rz_v2h_phy_usb2_data, }, { + .compatible = "renesas,usb2-phy-r9a09g077", + .data = &rz_t2h_phy_usb2_data, + }, + { .compatible = "renesas,rzg2l-usb2-phy", .data = &rz_g2l_phy_usb2_data, }, @@ -730,7 +802,6 @@ rpm_put: static int rcar_gen3_phy_usb2_probe(struct platform_device *pdev) { - const struct rcar_gen3_phy_drv_data *phy_data; struct device *dev = &pdev->dev; struct rcar_gen3_chan *channel; struct phy_provider *provider; @@ -749,7 +820,6 @@ static int rcar_gen3_phy_usb2_probe(struct platform_device *pdev) if (IS_ERR(channel->base)) return PTR_ERR(channel->base); - channel->obint_enable_bits = USB2_OBINT_BITS; channel->dr_mode = rcar_gen3_get_dr_mode(dev->of_node); if (channel->dr_mode != USB_DR_MODE_UNKNOWN) { channel->is_otg_channel = true; @@ -773,8 +843,8 @@ static int rcar_gen3_phy_usb2_probe(struct platform_device *pdev) */ pm_runtime_enable(dev); - phy_data = of_device_get_match_data(dev); - if (!phy_data) { + channel->phy_data = of_device_get_match_data(dev); + if (!channel->phy_data) { ret = -EINVAL; goto error; } @@ -782,22 +852,16 @@ static int rcar_gen3_phy_usb2_probe(struct platform_device *pdev) platform_set_drvdata(pdev, channel); channel->dev = dev; - if (phy_data->init_bus) { + if (channel->phy_data->init_bus) { ret = rcar_gen3_phy_usb2_init_bus(channel); if (ret) goto error; } - channel->soc_no_adp_ctrl = phy_data->no_adp_ctrl; - if (phy_data->no_adp_ctrl) - channel->obint_enable_bits = USB2_OBINT_IDCHG_EN; - - channel->utmi_ctrl = phy_data->utmi_ctrl; - spin_lock_init(&channel->lock); for (i = 0; i < NUM_OF_PHYS; i++) { channel->rphys[i].phy = devm_phy_create(dev, NULL, - phy_data->phy_usb2_ops); + channel->phy_data->phy_usb2_ops); if (IS_ERR(channel->rphys[i].phy)) { dev_err(dev, "Failed to create USB2 PHY\n"); ret = PTR_ERR(channel->rphys[i].phy); @@ -808,7 +872,7 @@ static int rcar_gen3_phy_usb2_probe(struct platform_device *pdev) phy_set_drvdata(channel->rphys[i].phy, &channel->rphys[i]); } - if (channel->soc_no_adp_ctrl && channel->is_otg_channel) + if (channel->phy_data->no_adp_ctrl && channel->is_otg_channel) channel->vbus = devm_regulator_get_exclusive(dev, "vbus"); else channel->vbus = devm_regulator_get_optional(dev, "vbus"); diff --git a/drivers/phy/renesas/r8a779f0-ether-serdes.c b/drivers/phy/renesas/r8a779f0-ether-serdes.c index 3b2d8cef75e5..8a6b6f366fe3 100644 --- a/drivers/phy/renesas/r8a779f0-ether-serdes.c +++ b/drivers/phy/renesas/r8a779f0-ether-serdes.c @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0 /* Renesas Ethernet SERDES device driver * - * Copyright (C) 2022 Renesas Electronics Corporation + * Copyright (C) 2022-2025 Renesas Electronics Corporation */ #include <linux/delay.h> @@ -49,6 +49,13 @@ static void r8a779f0_eth_serdes_write32(void __iomem *addr, u32 offs, u32 bank, iowrite32(data, addr + offs); } +static u32 r8a779f0_eth_serdes_read32(void __iomem *addr, u32 offs, u32 bank) +{ + iowrite32(bank, addr + R8A779F0_ETH_SERDES_BANK_SELECT); + + return ioread32(addr + offs); +} + static int r8a779f0_eth_serdes_reg_wait(struct r8a779f0_eth_serdes_channel *channel, u32 offs, u32 bank, u32 mask, u32 expected) @@ -92,17 +99,18 @@ r8a779f0_eth_serdes_common_setting(struct r8a779f0_eth_serdes_channel *channel) { struct r8a779f0_eth_serdes_drv_data *dd = channel->dd; - switch (channel->phy_interface) { - case PHY_INTERFACE_MODE_SGMII: - r8a779f0_eth_serdes_write32(dd->addr, 0x0244, 0x180, 0x0097); - r8a779f0_eth_serdes_write32(dd->addr, 0x01d0, 0x180, 0x0060); - r8a779f0_eth_serdes_write32(dd->addr, 0x01d8, 0x180, 0x2200); - r8a779f0_eth_serdes_write32(dd->addr, 0x01d4, 0x180, 0x0000); - r8a779f0_eth_serdes_write32(dd->addr, 0x01e0, 0x180, 0x003d); - return 0; - default: - return -EOPNOTSUPP; - } + /* Set combination mode */ + r8a779f0_eth_serdes_write32(dd->addr, 0x0244, 0x180, 0x00d7); + r8a779f0_eth_serdes_write32(dd->addr, 0x01cc, 0x180, 0xc200); + r8a779f0_eth_serdes_write32(dd->addr, 0x01c4, 0x180, 0x0042); + r8a779f0_eth_serdes_write32(dd->addr, 0x01c8, 0x180, 0x0000); + r8a779f0_eth_serdes_write32(dd->addr, 0x01dc, 0x180, 0x002f); + r8a779f0_eth_serdes_write32(dd->addr, 0x01d0, 0x180, 0x0060); + r8a779f0_eth_serdes_write32(dd->addr, 0x01d8, 0x180, 0x2200); + r8a779f0_eth_serdes_write32(dd->addr, 0x01d4, 0x180, 0x0000); + r8a779f0_eth_serdes_write32(dd->addr, 0x01e0, 0x180, 0x003d); + + return 0; } static int @@ -155,6 +163,42 @@ r8a779f0_eth_serdes_chan_setting(struct r8a779f0_eth_serdes_channel *channel) r8a779f0_eth_serdes_write32(channel->addr, 0x0028, 0x1f80, 0x07a1); r8a779f0_eth_serdes_write32(channel->addr, 0x0000, 0x1f80, 0x0208); break; + + case PHY_INTERFACE_MODE_USXGMII: + r8a779f0_eth_serdes_write32(channel->addr, 0x001c, 0x300, 0x0000); + r8a779f0_eth_serdes_write32(channel->addr, 0x0014, 0x380, 0x0050); + r8a779f0_eth_serdes_write32(channel->addr, 0x0000, 0x380, 0x2200); + r8a779f0_eth_serdes_write32(channel->addr, 0x001c, 0x380, 0x0400); + r8a779f0_eth_serdes_write32(channel->addr, 0x01c0, 0x180, 0x0001); + r8a779f0_eth_serdes_write32(channel->addr, 0x0248, 0x180, 0x056a); + r8a779f0_eth_serdes_write32(channel->addr, 0x0258, 0x180, 0x0015); + r8a779f0_eth_serdes_write32(channel->addr, 0x0144, 0x180, 0x1100); + r8a779f0_eth_serdes_write32(channel->addr, 0x01a0, 0x180, 0x0001); + r8a779f0_eth_serdes_write32(channel->addr, 0x00d0, 0x180, 0x0001); + r8a779f0_eth_serdes_write32(channel->addr, 0x0150, 0x180, 0x0001); + r8a779f0_eth_serdes_write32(channel->addr, 0x00c8, 0x180, 0x0300); + r8a779f0_eth_serdes_write32(channel->addr, 0x0148, 0x180, 0x0300); + r8a779f0_eth_serdes_write32(channel->addr, 0x0174, 0x180, 0x0000); + r8a779f0_eth_serdes_write32(channel->addr, 0x0160, 0x180, 0x0004); + r8a779f0_eth_serdes_write32(channel->addr, 0x01ac, 0x180, 0x0000); + r8a779f0_eth_serdes_write32(channel->addr, 0x00c4, 0x180, 0x0310); + r8a779f0_eth_serdes_write32(channel->addr, 0x00c8, 0x180, 0x0301); + ret = r8a779f0_eth_serdes_reg_wait(channel, 0x00c8, 0x180, BIT(0), 0); + if (ret) + return ret; + r8a779f0_eth_serdes_write32(channel->addr, 0x0148, 0x180, 0x0301); + ret = r8a779f0_eth_serdes_reg_wait(channel, 0x0148, 0x180, BIT(0), 0); + if (ret) + return ret; + r8a779f0_eth_serdes_write32(channel->addr, 0x00c4, 0x180, 0x1310); + r8a779f0_eth_serdes_write32(channel->addr, 0x00d8, 0x180, 0x1800); + r8a779f0_eth_serdes_write32(channel->addr, 0x00dc, 0x180, 0x0000); + r8a779f0_eth_serdes_write32(channel->addr, 0x0000, 0x380, 0x2300); + ret = r8a779f0_eth_serdes_reg_wait(channel, 0x0000, 0x380, BIT(8), 0); + if (ret) + return ret; + break; + default: return -EOPNOTSUPP; } @@ -179,6 +223,14 @@ r8a779f0_eth_serdes_chan_speed(struct r8a779f0_eth_serdes_channel *channel) return ret; r8a779f0_eth_serdes_write32(channel->addr, 0x0008, 0x1f80, 0x0000); break; + case PHY_INTERFACE_MODE_USXGMII: + r8a779f0_eth_serdes_write32(channel->addr, 0x0000, 0x1f00, 0x0120); + usleep_range(10, 20); + r8a779f0_eth_serdes_write32(channel->addr, 0x0000, 0x380, 0x2600); + ret = r8a779f0_eth_serdes_reg_wait(channel, 0x0000, 0x380, BIT(10), 0); + if (ret) + return ret; + break; default: return -EOPNOTSUPP; } @@ -274,6 +326,7 @@ static int r8a779f0_eth_serdes_hw_init_late(struct r8a779f0_eth_serdes_channel *channel) { int ret; + u32 val; ret = r8a779f0_eth_serdes_chan_setting(channel); if (ret) @@ -287,6 +340,26 @@ static int r8a779f0_eth_serdes_hw_init_late(struct r8a779f0_eth_serdes_channel r8a779f0_eth_serdes_write32(channel->addr, 0x03d0, 0x380, 0x0000); + val = r8a779f0_eth_serdes_read32(channel->addr, 0x00c0, 0x180); + r8a779f0_eth_serdes_write32(channel->addr, 0x00c0, 0x180, val | BIT(8)); + ret = r8a779f0_eth_serdes_reg_wait(channel, 0x0100, 0x180, BIT(0), 1); + if (ret) + return ret; + r8a779f0_eth_serdes_write32(channel->addr, 0x00c0, 0x180, val & ~BIT(8)); + ret = r8a779f0_eth_serdes_reg_wait(channel, 0x0100, 0x180, BIT(0), 0); + if (ret) + return ret; + + val = r8a779f0_eth_serdes_read32(channel->addr, 0x0144, 0x180); + r8a779f0_eth_serdes_write32(channel->addr, 0x0144, 0x180, val | BIT(4)); + ret = r8a779f0_eth_serdes_reg_wait(channel, 0x0180, 0x180, BIT(0), 1); + if (ret) + return ret; + r8a779f0_eth_serdes_write32(channel->addr, 0x0144, 0x180, val & ~BIT(4)); + ret = r8a779f0_eth_serdes_reg_wait(channel, 0x0180, 0x180, BIT(0), 0); + if (ret) + return ret; + return r8a779f0_eth_serdes_monitor_linkup(channel); } diff --git a/drivers/phy/rockchip/phy-rockchip-inno-csidphy.c b/drivers/phy/rockchip/phy-rockchip-inno-csidphy.c index 2ab99e1d47eb..c79fb53d8ee5 100644 --- a/drivers/phy/rockchip/phy-rockchip-inno-csidphy.c +++ b/drivers/phy/rockchip/phy-rockchip-inno-csidphy.c @@ -30,6 +30,8 @@ #define RK3568_GRF_VI_CON0 0x0340 #define RK3568_GRF_VI_CON1 0x0344 +#define RK3588_CSIDPHY_GRF_CON0 0x0000 + /* PHY */ #define CSIDPHY_CTRL_LANE_ENABLE 0x00 #define CSIDPHY_CTRL_LANE_ENABLE_CK BIT(6) @@ -67,6 +69,8 @@ #define RK1808_CSIDPHY_CLK_CALIB_EN 0x168 #define RK3568_CSIDPHY_CLK_CALIB_EN 0x168 +#define RESETS_MAX 2 + /* * The higher 16-bit of this register is used for write protection * only if BIT(x + 16) set to 1 the BIT(x) can be written. @@ -87,10 +91,11 @@ struct dphy_reg { u32 offset; u32 mask; u32 shift; + u8 valid; }; #define PHY_REG(_offset, _width, _shift) \ - { .offset = _offset, .mask = BIT(_width) - 1, .shift = _shift, } + { .offset = _offset, .mask = BIT(_width) - 1, .shift = _shift, .valid = 1, } static const struct dphy_reg rk1808_grf_dphy_regs[] = { [GRF_DPHY_CSIPHY_FORCERXMODE] = PHY_REG(RK1808_GRF_PD_VI_CON_OFFSET, 4, 0), @@ -114,6 +119,12 @@ static const struct dphy_reg rk3568_grf_dphy_regs[] = { [GRF_DPHY_CSIPHY_CLKLANE_EN] = PHY_REG(RK3568_GRF_VI_CON0, 1, 8), }; +static const struct dphy_reg rk3588_grf_dphy_regs[] = { + [GRF_DPHY_CSIPHY_FORCERXMODE] = PHY_REG(RK3588_CSIDPHY_GRF_CON0, 4, 0), + [GRF_DPHY_CSIPHY_DATALANE_EN] = PHY_REG(RK3588_CSIDPHY_GRF_CON0, 4, 4), + [GRF_DPHY_CSIPHY_CLKLANE_EN] = PHY_REG(RK3588_CSIDPHY_GRF_CON0, 1, 8), +}; + struct hsfreq_range { u32 range_h; u8 cfg_bit; @@ -126,6 +137,8 @@ struct dphy_drv_data { const struct hsfreq_range *hsfreq_ranges; int num_hsfreq_ranges; const struct dphy_reg *grf_regs; + const char *const *resets; + unsigned int resets_num; }; struct rockchip_inno_csidphy { @@ -133,7 +146,8 @@ struct rockchip_inno_csidphy { void __iomem *phy_base; struct clk *pclk; struct regmap *grf; - struct reset_control *rst; + struct reset_control_bulk_data resets[RESETS_MAX]; + unsigned int resets_num; const struct dphy_drv_data *drv_data; struct phy_configure_opts_mipi_dphy config; u8 hsfreq; @@ -145,7 +159,7 @@ static inline void write_grf_reg(struct rockchip_inno_csidphy *priv, const struct dphy_drv_data *drv_data = priv->drv_data; const struct dphy_reg *reg = &drv_data->grf_regs[index]; - if (reg->offset) + if (reg->valid) regmap_write(priv->grf, reg->offset, HIWORD_UPDATE(value, reg->mask, reg->shift)); } @@ -173,6 +187,15 @@ static const struct hsfreq_range rk3368_mipidphy_hsfreq_ranges[] = { {1249, 0x0c}, {1349, 0x0d}, {1500, 0x0e} }; +static const char *const rk3368_reset_names[] = { + "apb" +}; + +static const char *const rk3588_reset_names[] = { + "apb", + "phy" +}; + static void rockchip_inno_csidphy_ths_settle(struct rockchip_inno_csidphy *priv, int hsfreq, int offset) { @@ -343,6 +366,8 @@ static const struct dphy_drv_data rk1808_mipidphy_drv_data = { .hsfreq_ranges = rk1808_mipidphy_hsfreq_ranges, .num_hsfreq_ranges = ARRAY_SIZE(rk1808_mipidphy_hsfreq_ranges), .grf_regs = rk1808_grf_dphy_regs, + .resets = rk3368_reset_names, + .resets_num = ARRAY_SIZE(rk3368_reset_names), }; static const struct dphy_drv_data rk3326_mipidphy_drv_data = { @@ -352,6 +377,8 @@ static const struct dphy_drv_data rk3326_mipidphy_drv_data = { .hsfreq_ranges = rk3326_mipidphy_hsfreq_ranges, .num_hsfreq_ranges = ARRAY_SIZE(rk3326_mipidphy_hsfreq_ranges), .grf_regs = rk3326_grf_dphy_regs, + .resets = rk3368_reset_names, + .resets_num = ARRAY_SIZE(rk3368_reset_names), }; static const struct dphy_drv_data rk3368_mipidphy_drv_data = { @@ -361,6 +388,8 @@ static const struct dphy_drv_data rk3368_mipidphy_drv_data = { .hsfreq_ranges = rk3368_mipidphy_hsfreq_ranges, .num_hsfreq_ranges = ARRAY_SIZE(rk3368_mipidphy_hsfreq_ranges), .grf_regs = rk3368_grf_dphy_regs, + .resets = rk3368_reset_names, + .resets_num = ARRAY_SIZE(rk3368_reset_names), }; static const struct dphy_drv_data rk3568_mipidphy_drv_data = { @@ -370,6 +399,19 @@ static const struct dphy_drv_data rk3568_mipidphy_drv_data = { .hsfreq_ranges = rk1808_mipidphy_hsfreq_ranges, .num_hsfreq_ranges = ARRAY_SIZE(rk1808_mipidphy_hsfreq_ranges), .grf_regs = rk3568_grf_dphy_regs, + .resets = rk3368_reset_names, + .resets_num = ARRAY_SIZE(rk3368_reset_names), +}; + +static const struct dphy_drv_data rk3588_mipidphy_drv_data = { + .pwrctl_offset = -1, + .ths_settle_offset = RK3568_CSIDPHY_CLK_WR_THS_SETTLE, + .calib_offset = RK3568_CSIDPHY_CLK_CALIB_EN, + .hsfreq_ranges = rk1808_mipidphy_hsfreq_ranges, + .num_hsfreq_ranges = ARRAY_SIZE(rk1808_mipidphy_hsfreq_ranges), + .grf_regs = rk3588_grf_dphy_regs, + .resets = rk3588_reset_names, + .resets_num = ARRAY_SIZE(rk3588_reset_names), }; static const struct of_device_id rockchip_inno_csidphy_match_id[] = { @@ -393,6 +435,10 @@ static const struct of_device_id rockchip_inno_csidphy_match_id[] = { .compatible = "rockchip,rk3568-csi-dphy", .data = &rk3568_mipidphy_drv_data, }, + { + .compatible = "rockchip,rk3588-csi-dphy", + .data = &rk3588_mipidphy_drv_data, + }, {} }; MODULE_DEVICE_TABLE(of, rockchip_inno_csidphy_match_id); @@ -403,6 +449,7 @@ static int rockchip_inno_csidphy_probe(struct platform_device *pdev) struct device *dev = &pdev->dev; struct phy_provider *phy_provider; struct phy *phy; + int ret; priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); if (!priv) @@ -434,10 +481,18 @@ static int rockchip_inno_csidphy_probe(struct platform_device *pdev) return PTR_ERR(priv->pclk); } - priv->rst = devm_reset_control_get(dev, "apb"); - if (IS_ERR(priv->rst)) { + if (priv->drv_data->resets_num > RESETS_MAX) { + dev_err(dev, "invalid number of resets\n"); + return -EINVAL; + } + priv->resets_num = priv->drv_data->resets_num; + for (unsigned int i = 0; i < priv->resets_num; i++) + priv->resets[i].id = priv->drv_data->resets[i]; + ret = devm_reset_control_bulk_get_exclusive(dev, priv->resets_num, + priv->resets); + if (ret) { dev_err(dev, "failed to get system reset control\n"); - return PTR_ERR(priv->rst); + return ret; } phy = devm_phy_create(dev, NULL, &rockchip_inno_csidphy_ops); diff --git a/drivers/phy/rockchip/phy-rockchip-naneng-combphy.c b/drivers/phy/rockchip/phy-rockchip-naneng-combphy.c index ce91fb1d5167..a3ef19807b9e 100644 --- a/drivers/phy/rockchip/phy-rockchip-naneng-combphy.c +++ b/drivers/phy/rockchip/phy-rockchip-naneng-combphy.c @@ -20,79 +20,120 @@ #define REF_CLOCK_25MHz (25 * HZ_PER_MHZ) #define REF_CLOCK_100MHz (100 * HZ_PER_MHZ) -/* COMBO PHY REG */ -#define PHYREG6 0x14 -#define PHYREG6_PLL_DIV_MASK GENMASK(7, 6) -#define PHYREG6_PLL_DIV_SHIFT 6 -#define PHYREG6_PLL_DIV_2 1 - -#define PHYREG7 0x18 -#define PHYREG7_TX_RTERM_MASK GENMASK(7, 4) -#define PHYREG7_TX_RTERM_SHIFT 4 -#define PHYREG7_TX_RTERM_50OHM 8 -#define PHYREG7_RX_RTERM_MASK GENMASK(3, 0) -#define PHYREG7_RX_RTERM_SHIFT 0 -#define PHYREG7_RX_RTERM_44OHM 15 - -#define PHYREG8 0x1C -#define PHYREG8_SSC_EN BIT(4) - -#define PHYREG10 0x24 -#define PHYREG10_SSC_PCM_MASK GENMASK(3, 0) -#define PHYREG10_SSC_PCM_3500PPM 7 - -#define PHYREG11 0x28 -#define PHYREG11_SU_TRIM_0_7 0xF0 - -#define PHYREG12 0x2C -#define PHYREG12_PLL_LPF_ADJ_VALUE 4 - -#define PHYREG13 0x30 -#define PHYREG13_RESISTER_MASK GENMASK(5, 4) -#define PHYREG13_RESISTER_SHIFT 0x4 -#define PHYREG13_RESISTER_HIGH_Z 3 -#define PHYREG13_CKRCV_AMP0 BIT(7) - -#define PHYREG14 0x34 -#define PHYREG14_CKRCV_AMP1 BIT(0) - -#define PHYREG15 0x38 -#define PHYREG15_CTLE_EN BIT(0) -#define PHYREG15_SSC_CNT_MASK GENMASK(7, 6) -#define PHYREG15_SSC_CNT_SHIFT 6 -#define PHYREG15_SSC_CNT_VALUE 1 - -#define PHYREG16 0x3C -#define PHYREG16_SSC_CNT_VALUE 0x5f - -#define PHYREG17 0x40 - -#define PHYREG18 0x44 -#define PHYREG18_PLL_LOOP 0x32 - -#define PHYREG21 0x50 -#define PHYREG21_RX_SQUELCH_VAL 0x0D - -#define PHYREG27 0x6C -#define PHYREG27_RX_TRIM_RK3588 0x4C - -#define PHYREG30 0x74 - -#define PHYREG32 0x7C -#define PHYREG32_SSC_MASK GENMASK(7, 4) -#define PHYREG32_SSC_DIR_MASK GENMASK(5, 4) -#define PHYREG32_SSC_DIR_SHIFT 4 -#define PHYREG32_SSC_UPWARD 0 -#define PHYREG32_SSC_DOWNWARD 1 -#define PHYREG32_SSC_OFFSET_MASK GENMASK(7, 6) -#define PHYREG32_SSC_OFFSET_SHIFT 6 -#define PHYREG32_SSC_OFFSET_500PPM 1 - -#define PHYREG33 0x80 -#define PHYREG33_PLL_KVCO_MASK GENMASK(4, 2) -#define PHYREG33_PLL_KVCO_SHIFT 2 -#define PHYREG33_PLL_KVCO_VALUE 2 -#define PHYREG33_PLL_KVCO_VALUE_RK3576 4 +/* RK3528 COMBO PHY REG */ +#define RK3528_PHYREG6 0x18 +#define RK3528_PHYREG6_PLL_KVCO GENMASK(12, 10) +#define RK3528_PHYREG6_PLL_KVCO_VALUE 0x2 +#define RK3528_PHYREG6_SSC_DIR GENMASK(5, 4) +#define RK3528_PHYREG6_SSC_UPWARD 0 +#define RK3528_PHYREG6_SSC_DOWNWARD 1 + +#define RK3528_PHYREG40 0x100 +#define RK3528_PHYREG40_SSC_EN BIT(20) +#define RK3528_PHYREG40_SSC_CNT GENMASK(10, 0) +#define RK3528_PHYREG40_SSC_CNT_VALUE 0x17d + +#define RK3528_PHYREG42 0x108 +#define RK3528_PHYREG42_CKDRV_CLK_SEL BIT(29) +#define RK3528_PHYREG42_CKDRV_CLK_PLL 0 +#define RK3528_PHYREG42_CKDRV_CLK_CKRCV 1 +#define RK3528_PHYREG42_PLL_LPF_R1_ADJ GENMASK(10, 7) +#define RK3528_PHYREG42_PLL_LPF_R1_ADJ_VALUE 0x9 +#define RK3528_PHYREG42_PLL_CHGPUMP_CUR_ADJ GENMASK(6, 4) +#define RK3528_PHYREG42_PLL_CHGPUMP_CUR_ADJ_VALUE 0x7 +#define RK3528_PHYREG42_PLL_KVCO_ADJ GENMASK(2, 0) +#define RK3528_PHYREG42_PLL_KVCO_ADJ_VALUE 0x0 + +#define RK3528_PHYREG80 0x200 +#define RK3528_PHYREG80_CTLE_EN BIT(17) + +#define RK3528_PHYREG81 0x204 +#define RK3528_PHYREG81_CDR_PHASE_PATH_GAIN_2X BIT(5) +#define RK3528_PHYREG81_SLEW_RATE_CTRL GENMASK(2, 0) +#define RK3528_PHYREG81_SLEW_RATE_CTRL_SLOW 0x7 + +#define RK3528_PHYREG83 0x20c +#define RK3528_PHYREG83_RX_SQUELCH GENMASK(2, 0) +#define RK3528_PHYREG83_RX_SQUELCH_VALUE 0x6 + +#define RK3528_PHYREG86 0x218 +#define RK3528_PHYREG86_RTERM_DET_CLK_EN BIT(14) + +/* RK3568 COMBO PHY REG */ +#define RK3568_PHYREG6 0x14 +#define RK3568_PHYREG6_PLL_DIV_MASK GENMASK(7, 6) +#define RK3568_PHYREG6_PLL_DIV_SHIFT 6 +#define RK3568_PHYREG6_PLL_DIV_2 1 + +#define RK3568_PHYREG7 0x18 +#define RK3568_PHYREG7_TX_RTERM_MASK GENMASK(7, 4) +#define RK3568_PHYREG7_TX_RTERM_SHIFT 4 +#define RK3568_PHYREG7_TX_RTERM_50OHM 8 +#define RK3568_PHYREG7_RX_RTERM_MASK GENMASK(3, 0) +#define RK3568_PHYREG7_RX_RTERM_SHIFT 0 +#define RK3568_PHYREG7_RX_RTERM_44OHM 15 + +#define RK3568_PHYREG8 0x1C +#define RK3568_PHYREG8_SSC_EN BIT(4) + +#define RK3568_PHYREG11 0x28 +#define RK3568_PHYREG11_SU_TRIM_0_7 0xF0 + +#define RK3568_PHYREG12 0x2C +#define RK3568_PHYREG12_PLL_LPF_ADJ_VALUE 4 + +#define RK3568_PHYREG13 0x30 +#define RK3568_PHYREG13_RESISTER_MASK GENMASK(5, 4) +#define RK3568_PHYREG13_RESISTER_SHIFT 0x4 +#define RK3568_PHYREG13_RESISTER_HIGH_Z 3 +#define RK3568_PHYREG13_CKRCV_AMP0 BIT(7) + +#define RK3568_PHYREG14 0x34 +#define RK3568_PHYREG14_CKRCV_AMP1 BIT(0) + +#define RK3568_PHYREG15 0x38 +#define RK3568_PHYREG15_CTLE_EN BIT(0) +#define RK3568_PHYREG15_SSC_CNT_MASK GENMASK(7, 6) +#define RK3568_PHYREG15_SSC_CNT_SHIFT 6 +#define RK3568_PHYREG15_SSC_CNT_VALUE 1 + +#define RK3568_PHYREG16 0x3C +#define RK3568_PHYREG16_SSC_CNT_VALUE 0x5f + +#define RK3568_PHYREG18 0x44 +#define RK3568_PHYREG18_PLL_LOOP 0x32 + +#define RK3568_PHYREG32 0x7C +#define RK3568_PHYREG32_SSC_MASK GENMASK(7, 4) +#define RK3568_PHYREG32_SSC_DIR_MASK GENMASK(5, 4) +#define RK3568_PHYREG32_SSC_DIR_SHIFT 4 +#define RK3568_PHYREG32_SSC_UPWARD 0 +#define RK3568_PHYREG32_SSC_DOWNWARD 1 +#define RK3568_PHYREG32_SSC_OFFSET_MASK GENMASK(7, 6) +#define RK3568_PHYREG32_SSC_OFFSET_SHIFT 6 +#define RK3568_PHYREG32_SSC_OFFSET_500PPM 1 + +#define RK3568_PHYREG33 0x80 +#define RK3568_PHYREG33_PLL_KVCO_MASK GENMASK(4, 2) +#define RK3568_PHYREG33_PLL_KVCO_SHIFT 2 +#define RK3568_PHYREG33_PLL_KVCO_VALUE 2 +#define RK3576_PHYREG33_PLL_KVCO_VALUE 4 + +/* RK3588 COMBO PHY registers */ +#define RK3588_PHYREG27 0x6C +#define RK3588_PHYREG27_RX_TRIM 0x4C + +/* RK3576 COMBO PHY registers */ +#define RK3576_PHYREG10 0x24 +#define RK3576_PHYREG10_SSC_PCM_MASK GENMASK(3, 0) +#define RK3576_PHYREG10_SSC_PCM_3500PPM 7 + +#define RK3576_PHYREG17 0x40 + +#define RK3576_PHYREG21 0x50 +#define RK3576_PHYREG21_RX_SQUELCH_VAL 0x0D + +#define RK3576_PHYREG30 0x74 struct rockchip_combphy_priv; @@ -137,6 +178,8 @@ struct rockchip_combphy_grfcfg { struct combphy_reg pipe_xpcs_phy_ready; struct combphy_reg pipe_pcie1l0_sel; struct combphy_reg pipe_pcie1l1_sel; + struct combphy_reg u3otg0_port_en; + struct combphy_reg u3otg1_port_en; }; struct rockchip_combphy_cfg { @@ -396,6 +439,150 @@ static int rockchip_combphy_probe(struct platform_device *pdev) return PTR_ERR_OR_ZERO(phy_provider); } +static int rk3528_combphy_cfg(struct rockchip_combphy_priv *priv) +{ + const struct rockchip_combphy_grfcfg *cfg = priv->cfg->grfcfg; + unsigned long rate; + u32 val; + + /* Set SSC downward spread spectrum */ + val = FIELD_PREP(RK3528_PHYREG6_SSC_DIR, RK3528_PHYREG6_SSC_DOWNWARD); + rockchip_combphy_updatel(priv, RK3528_PHYREG6_SSC_DIR, val, RK3528_PHYREG6); + + switch (priv->type) { + case PHY_TYPE_PCIE: + rockchip_combphy_param_write(priv->phy_grf, &cfg->con0_for_pcie, true); + rockchip_combphy_param_write(priv->phy_grf, &cfg->con1_for_pcie, true); + rockchip_combphy_param_write(priv->phy_grf, &cfg->con2_for_pcie, true); + rockchip_combphy_param_write(priv->phy_grf, &cfg->con3_for_pcie, true); + break; + case PHY_TYPE_USB3: + /* Enable adaptive CTLE for USB3.0 Rx */ + rockchip_combphy_updatel(priv, RK3528_PHYREG80_CTLE_EN, RK3528_PHYREG80_CTLE_EN, + RK3528_PHYREG80); + + /* Set slow slew rate control for PI */ + val = FIELD_PREP(RK3528_PHYREG81_SLEW_RATE_CTRL, + RK3528_PHYREG81_SLEW_RATE_CTRL_SLOW); + rockchip_combphy_updatel(priv, RK3528_PHYREG81_SLEW_RATE_CTRL, val, + RK3528_PHYREG81); + + /* Set CDR phase path with 2x gain */ + rockchip_combphy_updatel(priv, RK3528_PHYREG81_CDR_PHASE_PATH_GAIN_2X, + RK3528_PHYREG81_CDR_PHASE_PATH_GAIN_2X, RK3528_PHYREG81); + + /* Set Rx squelch input filler bandwidth */ + val = FIELD_PREP(RK3528_PHYREG83_RX_SQUELCH, RK3528_PHYREG83_RX_SQUELCH_VALUE); + rockchip_combphy_updatel(priv, RK3528_PHYREG83_RX_SQUELCH, val, RK3528_PHYREG83); + + rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_txcomp_sel, false); + rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_txelec_sel, false); + rockchip_combphy_param_write(priv->phy_grf, &cfg->usb_mode_set, true); + rockchip_combphy_param_write(priv->pipe_grf, &cfg->u3otg0_port_en, true); + break; + default: + dev_err(priv->dev, "incompatible PHY type\n"); + return -EINVAL; + } + + rate = clk_get_rate(priv->refclk); + + switch (rate) { + case REF_CLOCK_24MHz: + rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_clk_24m, true); + if (priv->type == PHY_TYPE_USB3) { + /* Set ssc_cnt[10:0]=00101111101 & 31.5KHz */ + val = FIELD_PREP(RK3528_PHYREG40_SSC_CNT, RK3528_PHYREG40_SSC_CNT_VALUE); + rockchip_combphy_updatel(priv, RK3528_PHYREG40_SSC_CNT, val, + RK3528_PHYREG40); + } else if (priv->type == PHY_TYPE_PCIE) { + /* tx_trim[14]=1, Enable the counting clock of the rterm detect */ + rockchip_combphy_updatel(priv, RK3528_PHYREG86_RTERM_DET_CLK_EN, + RK3528_PHYREG86_RTERM_DET_CLK_EN, RK3528_PHYREG86); + } + break; + case REF_CLOCK_100MHz: + rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_clk_100m, true); + if (priv->type == PHY_TYPE_PCIE) { + /* PLL KVCO tuning fine */ + val = FIELD_PREP(RK3528_PHYREG6_PLL_KVCO, RK3528_PHYREG6_PLL_KVCO_VALUE); + rockchip_combphy_updatel(priv, RK3528_PHYREG6_PLL_KVCO, val, + RK3528_PHYREG6); + + /* su_trim[6:4]=111, [10:7]=1001, [2:0]=000, swing 650mv */ + writel(0x570804f0, priv->mmio + RK3528_PHYREG42); + } + break; + default: + dev_err(priv->dev, "Unsupported rate: %lu\n", rate); + return -EINVAL; + } + + if (device_property_read_bool(priv->dev, "rockchip,ext-refclk")) { + rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_clk_ext, true); + + if (priv->type == PHY_TYPE_PCIE && rate == REF_CLOCK_100MHz) { + val = FIELD_PREP(RK3528_PHYREG42_CKDRV_CLK_SEL, + RK3528_PHYREG42_CKDRV_CLK_CKRCV); + val |= FIELD_PREP(RK3528_PHYREG42_PLL_LPF_R1_ADJ, + RK3528_PHYREG42_PLL_LPF_R1_ADJ_VALUE); + val |= FIELD_PREP(RK3528_PHYREG42_PLL_CHGPUMP_CUR_ADJ, + RK3528_PHYREG42_PLL_CHGPUMP_CUR_ADJ_VALUE); + val |= FIELD_PREP(RK3528_PHYREG42_PLL_KVCO_ADJ, + RK3528_PHYREG42_PLL_KVCO_ADJ_VALUE); + rockchip_combphy_updatel(priv, + RK3528_PHYREG42_CKDRV_CLK_SEL | + RK3528_PHYREG42_PLL_LPF_R1_ADJ | + RK3528_PHYREG42_PLL_CHGPUMP_CUR_ADJ | + RK3528_PHYREG42_PLL_KVCO_ADJ, + val, RK3528_PHYREG42); + + val = FIELD_PREP(RK3528_PHYREG6_PLL_KVCO, RK3528_PHYREG6_PLL_KVCO_VALUE); + rockchip_combphy_updatel(priv, RK3528_PHYREG6_PLL_KVCO, val, + RK3528_PHYREG6); + } + } + + if (priv->type == PHY_TYPE_PCIE) { + if (device_property_read_bool(priv->dev, "rockchip,enable-ssc")) + rockchip_combphy_updatel(priv, RK3528_PHYREG40_SSC_EN, + RK3528_PHYREG40_SSC_EN, RK3528_PHYREG40); + } + + return 0; +} + +static const struct rockchip_combphy_grfcfg rk3528_combphy_grfcfgs = { + /* pipe-phy-grf */ + .pcie_mode_set = { 0x0000, 5, 0, 0x00, 0x11 }, + .usb_mode_set = { 0x0000, 5, 0, 0x00, 0x04 }, + .pipe_rxterm_set = { 0x0000, 12, 12, 0x00, 0x01 }, + .pipe_txelec_set = { 0x0004, 1, 1, 0x00, 0x01 }, + .pipe_txcomp_set = { 0x0004, 4, 4, 0x00, 0x01 }, + .pipe_clk_24m = { 0x0004, 14, 13, 0x00, 0x00 }, + .pipe_clk_100m = { 0x0004, 14, 13, 0x00, 0x02 }, + .pipe_rxterm_sel = { 0x0008, 8, 8, 0x00, 0x01 }, + .pipe_txelec_sel = { 0x0008, 12, 12, 0x00, 0x01 }, + .pipe_txcomp_sel = { 0x0008, 15, 15, 0x00, 0x01 }, + .pipe_clk_ext = { 0x000c, 9, 8, 0x02, 0x01 }, + .pipe_phy_status = { 0x0034, 6, 6, 0x01, 0x00 }, + .con0_for_pcie = { 0x0000, 15, 0, 0x00, 0x110 }, + .con1_for_pcie = { 0x0004, 15, 0, 0x00, 0x00 }, + .con2_for_pcie = { 0x0008, 15, 0, 0x00, 0x101 }, + .con3_for_pcie = { 0x000c, 15, 0, 0x00, 0x0200 }, + /* pipe-grf */ + .u3otg0_port_en = { 0x0044, 15, 0, 0x0181, 0x1100 }, +}; + +static const struct rockchip_combphy_cfg rk3528_combphy_cfgs = { + .num_phys = 1, + .phy_ids = { + 0xffdc0000, + }, + .grfcfg = &rk3528_combphy_grfcfgs, + .combphy_cfg = rk3528_combphy_cfg, +}; + static int rk3562_combphy_cfg(struct rockchip_combphy_priv *priv) { const struct rockchip_combphy_grfcfg *cfg = priv->cfg->grfcfg; @@ -405,9 +592,8 @@ static int rk3562_combphy_cfg(struct rockchip_combphy_priv *priv) switch (priv->type) { case PHY_TYPE_PCIE: /* Set SSC downward spread spectrum */ - rockchip_combphy_updatel(priv, PHYREG32_SSC_MASK, - PHYREG32_SSC_DOWNWARD << PHYREG32_SSC_DIR_SHIFT, - PHYREG32); + val = RK3568_PHYREG32_SSC_DOWNWARD << RK3568_PHYREG32_SSC_DIR_SHIFT; + rockchip_combphy_updatel(priv, RK3568_PHYREG32_SSC_MASK, val, RK3568_PHYREG32); rockchip_combphy_param_write(priv->phy_grf, &cfg->con0_for_pcie, true); rockchip_combphy_param_write(priv->phy_grf, &cfg->con1_for_pcie, true); @@ -416,29 +602,30 @@ static int rk3562_combphy_cfg(struct rockchip_combphy_priv *priv) break; case PHY_TYPE_USB3: /* Set SSC downward spread spectrum */ - rockchip_combphy_updatel(priv, PHYREG32_SSC_MASK, - PHYREG32_SSC_DOWNWARD << PHYREG32_SSC_DIR_SHIFT, - PHYREG32); + val = RK3568_PHYREG32_SSC_DOWNWARD << RK3568_PHYREG32_SSC_DIR_SHIFT; + rockchip_combphy_updatel(priv, RK3568_PHYREG32_SSC_MASK, val, + RK3568_PHYREG32); /* Enable adaptive CTLE for USB3.0 Rx */ - rockchip_combphy_updatel(priv, PHYREG15_CTLE_EN, - PHYREG15_CTLE_EN, PHYREG15); + rockchip_combphy_updatel(priv, RK3568_PHYREG15_CTLE_EN, + RK3568_PHYREG15_CTLE_EN, RK3568_PHYREG15); /* Set PLL KVCO fine tuning signals */ - rockchip_combphy_updatel(priv, PHYREG33_PLL_KVCO_MASK, BIT(3), PHYREG33); + rockchip_combphy_updatel(priv, RK3568_PHYREG33_PLL_KVCO_MASK, + BIT(3), RK3568_PHYREG33); /* Set PLL LPF R1 to su_trim[10:7]=1001 */ - writel(PHYREG12_PLL_LPF_ADJ_VALUE, priv->mmio + PHYREG12); + writel(RK3568_PHYREG12_PLL_LPF_ADJ_VALUE, priv->mmio + RK3568_PHYREG12); /* Set PLL input clock divider 1/2 */ - val = FIELD_PREP(PHYREG6_PLL_DIV_MASK, PHYREG6_PLL_DIV_2); - rockchip_combphy_updatel(priv, PHYREG6_PLL_DIV_MASK, val, PHYREG6); + val = FIELD_PREP(RK3568_PHYREG6_PLL_DIV_MASK, RK3568_PHYREG6_PLL_DIV_2); + rockchip_combphy_updatel(priv, RK3568_PHYREG6_PLL_DIV_MASK, val, RK3568_PHYREG6); /* Set PLL loop divider */ - writel(PHYREG18_PLL_LOOP, priv->mmio + PHYREG18); + writel(RK3568_PHYREG18_PLL_LOOP, priv->mmio + RK3568_PHYREG18); /* Set PLL KVCO to min and set PLL charge pump current to max */ - writel(PHYREG11_SU_TRIM_0_7, priv->mmio + PHYREG11); + writel(RK3568_PHYREG11_SU_TRIM_0_7, priv->mmio + RK3568_PHYREG11); rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_sel_usb, true); rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_txcomp_sel, false); @@ -456,11 +643,12 @@ static int rk3562_combphy_cfg(struct rockchip_combphy_priv *priv) case REF_CLOCK_24MHz: if (priv->type == PHY_TYPE_USB3) { /* Set ssc_cnt[9:0]=0101111101 & 31.5KHz */ - val = FIELD_PREP(PHYREG15_SSC_CNT_MASK, PHYREG15_SSC_CNT_VALUE); - rockchip_combphy_updatel(priv, PHYREG15_SSC_CNT_MASK, - val, PHYREG15); + val = FIELD_PREP(RK3568_PHYREG15_SSC_CNT_MASK, + RK3568_PHYREG15_SSC_CNT_VALUE); + rockchip_combphy_updatel(priv, RK3568_PHYREG15_SSC_CNT_MASK, + val, RK3568_PHYREG15); - writel(PHYREG16_SSC_CNT_VALUE, priv->mmio + PHYREG16); + writel(RK3568_PHYREG16_SSC_CNT_VALUE, priv->mmio + RK3568_PHYREG16); } break; case REF_CLOCK_25MHz: @@ -470,19 +658,20 @@ static int rk3562_combphy_cfg(struct rockchip_combphy_priv *priv) rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_clk_100m, true); if (priv->type == PHY_TYPE_PCIE) { /* PLL KVCO tuning fine */ - val = FIELD_PREP(PHYREG33_PLL_KVCO_MASK, PHYREG33_PLL_KVCO_VALUE); - rockchip_combphy_updatel(priv, PHYREG33_PLL_KVCO_MASK, - val, PHYREG33); + val = FIELD_PREP(RK3568_PHYREG33_PLL_KVCO_MASK, + RK3568_PHYREG33_PLL_KVCO_VALUE); + rockchip_combphy_updatel(priv, RK3568_PHYREG33_PLL_KVCO_MASK, + val, RK3568_PHYREG33); /* Enable controlling random jitter, aka RMJ */ - writel(0x4, priv->mmio + PHYREG12); + writel(0x4, priv->mmio + RK3568_PHYREG12); - val = PHYREG6_PLL_DIV_2 << PHYREG6_PLL_DIV_SHIFT; - rockchip_combphy_updatel(priv, PHYREG6_PLL_DIV_MASK, - val, PHYREG6); + val = RK3568_PHYREG6_PLL_DIV_2 << RK3568_PHYREG6_PLL_DIV_SHIFT; + rockchip_combphy_updatel(priv, RK3568_PHYREG6_PLL_DIV_MASK, + val, RK3568_PHYREG6); - writel(0x32, priv->mmio + PHYREG18); - writel(0xf0, priv->mmio + PHYREG11); + writel(0x32, priv->mmio + RK3568_PHYREG18); + writel(0xf0, priv->mmio + RK3568_PHYREG11); } break; default: @@ -493,20 +682,21 @@ static int rk3562_combphy_cfg(struct rockchip_combphy_priv *priv) if (priv->ext_refclk) { rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_clk_ext, true); if (priv->type == PHY_TYPE_PCIE && rate == REF_CLOCK_100MHz) { - val = PHYREG13_RESISTER_HIGH_Z << PHYREG13_RESISTER_SHIFT; - val |= PHYREG13_CKRCV_AMP0; - rockchip_combphy_updatel(priv, PHYREG13_RESISTER_MASK, val, PHYREG13); - - val = readl(priv->mmio + PHYREG14); - val |= PHYREG14_CKRCV_AMP1; - writel(val, priv->mmio + PHYREG14); + val = RK3568_PHYREG13_RESISTER_HIGH_Z << RK3568_PHYREG13_RESISTER_SHIFT; + val |= RK3568_PHYREG13_CKRCV_AMP0; + rockchip_combphy_updatel(priv, RK3568_PHYREG13_RESISTER_MASK, val, + RK3568_PHYREG13); + + val = readl(priv->mmio + RK3568_PHYREG14); + val |= RK3568_PHYREG14_CKRCV_AMP1; + writel(val, priv->mmio + RK3568_PHYREG14); } } if (priv->enable_ssc) { - val = readl(priv->mmio + PHYREG8); - val |= PHYREG8_SSC_EN; - writel(val, priv->mmio + PHYREG8); + val = readl(priv->mmio + RK3568_PHYREG8); + val |= RK3568_PHYREG8_SSC_EN; + writel(val, priv->mmio + RK3568_PHYREG8); } return 0; @@ -553,9 +743,9 @@ static int rk3568_combphy_cfg(struct rockchip_combphy_priv *priv) switch (priv->type) { case PHY_TYPE_PCIE: /* Set SSC downward spread spectrum. */ - rockchip_combphy_updatel(priv, PHYREG32_SSC_MASK, - PHYREG32_SSC_DOWNWARD << PHYREG32_SSC_DIR_SHIFT, - PHYREG32); + val = RK3568_PHYREG32_SSC_DOWNWARD << RK3568_PHYREG32_SSC_DIR_SHIFT; + + rockchip_combphy_updatel(priv, RK3568_PHYREG32_SSC_MASK, val, RK3568_PHYREG32); rockchip_combphy_param_write(priv->phy_grf, &cfg->con0_for_pcie, true); rockchip_combphy_param_write(priv->phy_grf, &cfg->con1_for_pcie, true); @@ -565,49 +755,55 @@ static int rk3568_combphy_cfg(struct rockchip_combphy_priv *priv) case PHY_TYPE_USB3: /* Set SSC downward spread spectrum. */ - rockchip_combphy_updatel(priv, PHYREG32_SSC_MASK, - PHYREG32_SSC_DOWNWARD << PHYREG32_SSC_DIR_SHIFT, - PHYREG32); + val = RK3568_PHYREG32_SSC_DOWNWARD << RK3568_PHYREG32_SSC_DIR_SHIFT, + rockchip_combphy_updatel(priv, RK3568_PHYREG32_SSC_MASK, val, RK3568_PHYREG32); /* Enable adaptive CTLE for USB3.0 Rx. */ - val = readl(priv->mmio + PHYREG15); - val |= PHYREG15_CTLE_EN; - writel(val, priv->mmio + PHYREG15); + val = readl(priv->mmio + RK3568_PHYREG15); + val |= RK3568_PHYREG15_CTLE_EN; + writel(val, priv->mmio + RK3568_PHYREG15); /* Set PLL KVCO fine tuning signals. */ - rockchip_combphy_updatel(priv, PHYREG33_PLL_KVCO_MASK, - PHYREG33_PLL_KVCO_VALUE << PHYREG33_PLL_KVCO_SHIFT, - PHYREG33); + val = RK3568_PHYREG33_PLL_KVCO_VALUE << RK3568_PHYREG33_PLL_KVCO_SHIFT; + rockchip_combphy_updatel(priv, RK3568_PHYREG33_PLL_KVCO_MASK, val, RK3568_PHYREG33); /* Enable controlling random jitter. */ - writel(PHYREG12_PLL_LPF_ADJ_VALUE, priv->mmio + PHYREG12); + writel(RK3568_PHYREG12_PLL_LPF_ADJ_VALUE, priv->mmio + RK3568_PHYREG12); /* Set PLL input clock divider 1/2. */ - rockchip_combphy_updatel(priv, PHYREG6_PLL_DIV_MASK, - PHYREG6_PLL_DIV_2 << PHYREG6_PLL_DIV_SHIFT, - PHYREG6); + rockchip_combphy_updatel(priv, RK3568_PHYREG6_PLL_DIV_MASK, + RK3568_PHYREG6_PLL_DIV_2 << RK3568_PHYREG6_PLL_DIV_SHIFT, + RK3568_PHYREG6); - writel(PHYREG18_PLL_LOOP, priv->mmio + PHYREG18); - writel(PHYREG11_SU_TRIM_0_7, priv->mmio + PHYREG11); + writel(RK3568_PHYREG18_PLL_LOOP, priv->mmio + RK3568_PHYREG18); + writel(RK3568_PHYREG11_SU_TRIM_0_7, priv->mmio + RK3568_PHYREG11); rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_sel_usb, true); rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_txcomp_sel, false); rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_txelec_sel, false); rockchip_combphy_param_write(priv->phy_grf, &cfg->usb_mode_set, true); + switch (priv->id) { + case 0: + rockchip_combphy_param_write(priv->pipe_grf, &cfg->u3otg0_port_en, true); + break; + case 1: + rockchip_combphy_param_write(priv->pipe_grf, &cfg->u3otg1_port_en, true); + break; + } break; case PHY_TYPE_SATA: /* Enable adaptive CTLE for SATA Rx. */ - val = readl(priv->mmio + PHYREG15); - val |= PHYREG15_CTLE_EN; - writel(val, priv->mmio + PHYREG15); + val = readl(priv->mmio + RK3568_PHYREG15); + val |= RK3568_PHYREG15_CTLE_EN; + writel(val, priv->mmio + RK3568_PHYREG15); /* * Set tx_rterm=50ohm and rx_rterm=44ohm for SATA. * 0: 60ohm, 8: 50ohm 15: 44ohm (by step abort 1ohm) */ - val = PHYREG7_TX_RTERM_50OHM << PHYREG7_TX_RTERM_SHIFT; - val |= PHYREG7_RX_RTERM_44OHM << PHYREG7_RX_RTERM_SHIFT; - writel(val, priv->mmio + PHYREG7); + val = RK3568_PHYREG7_TX_RTERM_50OHM << RK3568_PHYREG7_TX_RTERM_SHIFT; + val |= RK3568_PHYREG7_RX_RTERM_44OHM << RK3568_PHYREG7_RX_RTERM_SHIFT; + writel(val, priv->mmio + RK3568_PHYREG7); rockchip_combphy_param_write(priv->phy_grf, &cfg->con0_for_sata, true); rockchip_combphy_param_write(priv->phy_grf, &cfg->con1_for_sata, true); @@ -642,11 +838,11 @@ static int rk3568_combphy_cfg(struct rockchip_combphy_priv *priv) case REF_CLOCK_24MHz: if (priv->type == PHY_TYPE_USB3 || priv->type == PHY_TYPE_SATA) { /* Set ssc_cnt[9:0]=0101111101 & 31.5KHz. */ - val = PHYREG15_SSC_CNT_VALUE << PHYREG15_SSC_CNT_SHIFT; - rockchip_combphy_updatel(priv, PHYREG15_SSC_CNT_MASK, - val, PHYREG15); + val = RK3568_PHYREG15_SSC_CNT_VALUE << RK3568_PHYREG15_SSC_CNT_SHIFT; + rockchip_combphy_updatel(priv, RK3568_PHYREG15_SSC_CNT_MASK, + val, RK3568_PHYREG15); - writel(PHYREG16_SSC_CNT_VALUE, priv->mmio + PHYREG16); + writel(RK3568_PHYREG16_SSC_CNT_VALUE, priv->mmio + RK3568_PHYREG16); } break; @@ -658,24 +854,26 @@ static int rk3568_combphy_cfg(struct rockchip_combphy_priv *priv) rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_clk_100m, true); if (priv->type == PHY_TYPE_PCIE) { /* PLL KVCO fine tuning. */ - val = PHYREG33_PLL_KVCO_VALUE << PHYREG33_PLL_KVCO_SHIFT; - rockchip_combphy_updatel(priv, PHYREG33_PLL_KVCO_MASK, - val, PHYREG33); + val = RK3568_PHYREG33_PLL_KVCO_VALUE << RK3568_PHYREG33_PLL_KVCO_SHIFT; + rockchip_combphy_updatel(priv, RK3568_PHYREG33_PLL_KVCO_MASK, + val, RK3568_PHYREG33); /* Enable controlling random jitter. */ - writel(PHYREG12_PLL_LPF_ADJ_VALUE, priv->mmio + PHYREG12); + writel(RK3568_PHYREG12_PLL_LPF_ADJ_VALUE, priv->mmio + RK3568_PHYREG12); - val = PHYREG6_PLL_DIV_2 << PHYREG6_PLL_DIV_SHIFT; - rockchip_combphy_updatel(priv, PHYREG6_PLL_DIV_MASK, - val, PHYREG6); + val = RK3568_PHYREG6_PLL_DIV_2 << RK3568_PHYREG6_PLL_DIV_SHIFT; + rockchip_combphy_updatel(priv, RK3568_PHYREG6_PLL_DIV_MASK, + val, RK3568_PHYREG6); - writel(PHYREG18_PLL_LOOP, priv->mmio + PHYREG18); - writel(PHYREG11_SU_TRIM_0_7, priv->mmio + PHYREG11); + writel(RK3568_PHYREG18_PLL_LOOP, priv->mmio + RK3568_PHYREG18); + writel(RK3568_PHYREG11_SU_TRIM_0_7, priv->mmio + RK3568_PHYREG11); } else if (priv->type == PHY_TYPE_SATA) { /* downward spread spectrum +500ppm */ - val = PHYREG32_SSC_DOWNWARD << PHYREG32_SSC_DIR_SHIFT; - val |= PHYREG32_SSC_OFFSET_500PPM << PHYREG32_SSC_OFFSET_SHIFT; - rockchip_combphy_updatel(priv, PHYREG32_SSC_MASK, val, PHYREG32); + val = RK3568_PHYREG32_SSC_DOWNWARD << RK3568_PHYREG32_SSC_DIR_SHIFT; + val |= RK3568_PHYREG32_SSC_OFFSET_500PPM << + RK3568_PHYREG32_SSC_OFFSET_SHIFT; + rockchip_combphy_updatel(priv, RK3568_PHYREG32_SSC_MASK, val, + RK3568_PHYREG32); } break; @@ -687,20 +885,21 @@ static int rk3568_combphy_cfg(struct rockchip_combphy_priv *priv) if (priv->ext_refclk) { rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_clk_ext, true); if (priv->type == PHY_TYPE_PCIE && rate == REF_CLOCK_100MHz) { - val = PHYREG13_RESISTER_HIGH_Z << PHYREG13_RESISTER_SHIFT; - val |= PHYREG13_CKRCV_AMP0; - rockchip_combphy_updatel(priv, PHYREG13_RESISTER_MASK, val, PHYREG13); - - val = readl(priv->mmio + PHYREG14); - val |= PHYREG14_CKRCV_AMP1; - writel(val, priv->mmio + PHYREG14); + val = RK3568_PHYREG13_RESISTER_HIGH_Z << RK3568_PHYREG13_RESISTER_SHIFT; + val |= RK3568_PHYREG13_CKRCV_AMP0; + rockchip_combphy_updatel(priv, RK3568_PHYREG13_RESISTER_MASK, val, + RK3568_PHYREG13); + + val = readl(priv->mmio + RK3568_PHYREG14); + val |= RK3568_PHYREG14_CKRCV_AMP1; + writel(val, priv->mmio + RK3568_PHYREG14); } } if (priv->enable_ssc) { - val = readl(priv->mmio + PHYREG8); - val |= PHYREG8_SSC_EN; - writel(val, priv->mmio + PHYREG8); + val = readl(priv->mmio + RK3568_PHYREG8); + val |= RK3568_PHYREG8_SSC_EN; + writel(val, priv->mmio + RK3568_PHYREG8); } return 0; @@ -737,6 +936,8 @@ static const struct rockchip_combphy_grfcfg rk3568_combphy_grfcfgs = { /* pipe-grf */ .pipe_con0_for_sata = { 0x0000, 15, 0, 0x00, 0x2220 }, .pipe_xpcs_phy_ready = { 0x0040, 2, 2, 0x00, 0x01 }, + .u3otg0_port_en = { 0x0104, 15, 0, 0x0181, 0x1100 }, + .u3otg1_port_en = { 0x0144, 15, 0, 0x0181, 0x1100 }, }; static const struct rockchip_combphy_cfg rk3568_combphy_cfgs = { @@ -759,8 +960,8 @@ static int rk3576_combphy_cfg(struct rockchip_combphy_priv *priv) switch (priv->type) { case PHY_TYPE_PCIE: /* Set SSC downward spread spectrum */ - val = FIELD_PREP(PHYREG32_SSC_MASK, PHYREG32_SSC_DOWNWARD); - rockchip_combphy_updatel(priv, PHYREG32_SSC_MASK, val, PHYREG32); + val = FIELD_PREP(RK3568_PHYREG32_SSC_MASK, RK3568_PHYREG32_SSC_DOWNWARD); + rockchip_combphy_updatel(priv, RK3568_PHYREG32_SSC_MASK, val, RK3568_PHYREG32); rockchip_combphy_param_write(priv->phy_grf, &cfg->con0_for_pcie, true); rockchip_combphy_param_write(priv->phy_grf, &cfg->con1_for_pcie, true); @@ -770,32 +971,33 @@ static int rk3576_combphy_cfg(struct rockchip_combphy_priv *priv) case PHY_TYPE_USB3: /* Set SSC downward spread spectrum */ - val = FIELD_PREP(PHYREG32_SSC_MASK, PHYREG32_SSC_DOWNWARD); - rockchip_combphy_updatel(priv, PHYREG32_SSC_MASK, val, PHYREG32); + val = FIELD_PREP(RK3568_PHYREG32_SSC_MASK, RK3568_PHYREG32_SSC_DOWNWARD); + rockchip_combphy_updatel(priv, RK3568_PHYREG32_SSC_MASK, val, RK3568_PHYREG32); /* Enable adaptive CTLE for USB3.0 Rx */ - val = readl(priv->mmio + PHYREG15); - val |= PHYREG15_CTLE_EN; - writel(val, priv->mmio + PHYREG15); + val = readl(priv->mmio + RK3568_PHYREG15); + val |= RK3568_PHYREG15_CTLE_EN; + writel(val, priv->mmio + RK3568_PHYREG15); /* Set PLL KVCO fine tuning signals */ - rockchip_combphy_updatel(priv, PHYREG33_PLL_KVCO_MASK, BIT(3), PHYREG33); + rockchip_combphy_updatel(priv, RK3568_PHYREG33_PLL_KVCO_MASK, BIT(3), + RK3568_PHYREG33); /* Set PLL LPF R1 to su_trim[10:7]=1001 */ - writel(PHYREG12_PLL_LPF_ADJ_VALUE, priv->mmio + PHYREG12); + writel(RK3568_PHYREG12_PLL_LPF_ADJ_VALUE, priv->mmio + RK3568_PHYREG12); /* Set PLL input clock divider 1/2 */ - val = FIELD_PREP(PHYREG6_PLL_DIV_MASK, PHYREG6_PLL_DIV_2); - rockchip_combphy_updatel(priv, PHYREG6_PLL_DIV_MASK, val, PHYREG6); + val = FIELD_PREP(RK3568_PHYREG6_PLL_DIV_MASK, RK3568_PHYREG6_PLL_DIV_2); + rockchip_combphy_updatel(priv, RK3568_PHYREG6_PLL_DIV_MASK, val, RK3568_PHYREG6); /* Set PLL loop divider */ - writel(PHYREG18_PLL_LOOP, priv->mmio + PHYREG18); + writel(RK3568_PHYREG18_PLL_LOOP, priv->mmio + RK3568_PHYREG18); /* Set PLL KVCO to min and set PLL charge pump current to max */ - writel(PHYREG11_SU_TRIM_0_7, priv->mmio + PHYREG11); + writel(RK3568_PHYREG11_SU_TRIM_0_7, priv->mmio + RK3568_PHYREG11); /* Set Rx squelch input filler bandwidth */ - writel(PHYREG21_RX_SQUELCH_VAL, priv->mmio + PHYREG21); + writel(RK3576_PHYREG21_RX_SQUELCH_VAL, priv->mmio + RK3576_PHYREG21); rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_txcomp_sel, false); rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_txelec_sel, false); @@ -804,14 +1006,14 @@ static int rk3576_combphy_cfg(struct rockchip_combphy_priv *priv) case PHY_TYPE_SATA: /* Enable adaptive CTLE for SATA Rx */ - val = readl(priv->mmio + PHYREG15); - val |= PHYREG15_CTLE_EN; - writel(val, priv->mmio + PHYREG15); + val = readl(priv->mmio + RK3568_PHYREG15); + val |= RK3568_PHYREG15_CTLE_EN; + writel(val, priv->mmio + RK3568_PHYREG15); /* Set tx_rterm = 50 ohm and rx_rterm = 43.5 ohm */ - val = PHYREG7_TX_RTERM_50OHM << PHYREG7_TX_RTERM_SHIFT; - val |= PHYREG7_RX_RTERM_44OHM << PHYREG7_RX_RTERM_SHIFT; - writel(val, priv->mmio + PHYREG7); + val = RK3568_PHYREG7_TX_RTERM_50OHM << RK3568_PHYREG7_TX_RTERM_SHIFT; + val |= RK3568_PHYREG7_RX_RTERM_44OHM << RK3568_PHYREG7_RX_RTERM_SHIFT; + writel(val, priv->mmio + RK3568_PHYREG7); rockchip_combphy_param_write(priv->phy_grf, &cfg->con0_for_sata, true); rockchip_combphy_param_write(priv->phy_grf, &cfg->con1_for_sata, true); @@ -833,19 +1035,21 @@ static int rk3576_combphy_cfg(struct rockchip_combphy_priv *priv) rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_clk_24m, true); if (priv->type == PHY_TYPE_USB3 || priv->type == PHY_TYPE_SATA) { /* Set ssc_cnt[9:0]=0101111101 & 31.5KHz */ - val = FIELD_PREP(PHYREG15_SSC_CNT_MASK, PHYREG15_SSC_CNT_VALUE); - rockchip_combphy_updatel(priv, PHYREG15_SSC_CNT_MASK, - val, PHYREG15); + val = FIELD_PREP(RK3568_PHYREG15_SSC_CNT_MASK, + RK3568_PHYREG15_SSC_CNT_VALUE); + rockchip_combphy_updatel(priv, RK3568_PHYREG15_SSC_CNT_MASK, + val, RK3568_PHYREG15); - writel(PHYREG16_SSC_CNT_VALUE, priv->mmio + PHYREG16); + writel(RK3568_PHYREG16_SSC_CNT_VALUE, priv->mmio + RK3568_PHYREG16); } else if (priv->type == PHY_TYPE_PCIE) { /* PLL KVCO tuning fine */ - val = FIELD_PREP(PHYREG33_PLL_KVCO_MASK, PHYREG33_PLL_KVCO_VALUE_RK3576); - rockchip_combphy_updatel(priv, PHYREG33_PLL_KVCO_MASK, - val, PHYREG33); + val = FIELD_PREP(RK3568_PHYREG33_PLL_KVCO_MASK, + RK3576_PHYREG33_PLL_KVCO_VALUE); + rockchip_combphy_updatel(priv, RK3568_PHYREG33_PLL_KVCO_MASK, + val, RK3568_PHYREG33); /* Set up rx_pck invert and rx msb to disable */ - writel(0x00, priv->mmio + PHYREG27); + writel(0x00, priv->mmio + RK3588_PHYREG27); /* * Set up SU adjust signal: @@ -853,11 +1057,11 @@ static int rk3576_combphy_cfg(struct rockchip_combphy_priv *priv) * su_trim[15:8], PLL LPF R1 adujst bits[9:7]=3'b011 * su_trim[31:24], CKDRV adjust */ - writel(0x90, priv->mmio + PHYREG11); - writel(0x02, priv->mmio + PHYREG12); - writel(0x57, priv->mmio + PHYREG14); + writel(0x90, priv->mmio + RK3568_PHYREG11); + writel(0x02, priv->mmio + RK3568_PHYREG12); + writel(0x57, priv->mmio + RK3568_PHYREG14); - writel(PHYREG16_SSC_CNT_VALUE, priv->mmio + PHYREG16); + writel(RK3568_PHYREG16_SSC_CNT_VALUE, priv->mmio + RK3568_PHYREG16); } break; @@ -869,15 +1073,16 @@ static int rk3576_combphy_cfg(struct rockchip_combphy_priv *priv) rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_clk_100m, true); if (priv->type == PHY_TYPE_PCIE) { /* gate_tx_pck_sel length select work for L1SS */ - writel(0xc0, priv->mmio + PHYREG30); + writel(0xc0, priv->mmio + RK3576_PHYREG30); /* PLL KVCO tuning fine */ - val = FIELD_PREP(PHYREG33_PLL_KVCO_MASK, PHYREG33_PLL_KVCO_VALUE_RK3576); - rockchip_combphy_updatel(priv, PHYREG33_PLL_KVCO_MASK, - val, PHYREG33); + val = FIELD_PREP(RK3568_PHYREG33_PLL_KVCO_MASK, + RK3576_PHYREG33_PLL_KVCO_VALUE); + rockchip_combphy_updatel(priv, RK3568_PHYREG33_PLL_KVCO_MASK, + val, RK3568_PHYREG33); /* Set up rx_trim: PLL LPF C1 85pf R1 1.25kohm */ - writel(0x4c, priv->mmio + PHYREG27); + writel(0x4c, priv->mmio + RK3588_PHYREG27); /* * Set up SU adjust signal: @@ -887,20 +1092,23 @@ static int rk3576_combphy_cfg(struct rockchip_combphy_priv *priv) * su_trim[23:16], CKRCV adjust * su_trim[31:24], CKDRV adjust */ - writel(0x90, priv->mmio + PHYREG11); - writel(0x43, priv->mmio + PHYREG12); - writel(0x88, priv->mmio + PHYREG13); - writel(0x56, priv->mmio + PHYREG14); + writel(0x90, priv->mmio + RK3568_PHYREG11); + writel(0x43, priv->mmio + RK3568_PHYREG12); + writel(0x88, priv->mmio + RK3568_PHYREG13); + writel(0x56, priv->mmio + RK3568_PHYREG14); } else if (priv->type == PHY_TYPE_SATA) { /* downward spread spectrum +500ppm */ - val = FIELD_PREP(PHYREG32_SSC_DIR_MASK, PHYREG32_SSC_DOWNWARD); - val |= FIELD_PREP(PHYREG32_SSC_OFFSET_MASK, PHYREG32_SSC_OFFSET_500PPM); - rockchip_combphy_updatel(priv, PHYREG32_SSC_MASK, val, PHYREG32); + val = FIELD_PREP(RK3568_PHYREG32_SSC_DIR_MASK, + RK3568_PHYREG32_SSC_DOWNWARD); + val |= FIELD_PREP(RK3568_PHYREG32_SSC_OFFSET_MASK, + RK3568_PHYREG32_SSC_OFFSET_500PPM); + rockchip_combphy_updatel(priv, RK3568_PHYREG32_SSC_MASK, val, + RK3568_PHYREG32); /* ssc ppm adjust to 3500ppm */ - rockchip_combphy_updatel(priv, PHYREG10_SSC_PCM_MASK, - PHYREG10_SSC_PCM_3500PPM, - PHYREG10); + rockchip_combphy_updatel(priv, RK3576_PHYREG10_SSC_PCM_MASK, + RK3576_PHYREG10_SSC_PCM_3500PPM, + RK3576_PHYREG10); } break; @@ -912,12 +1120,13 @@ static int rk3576_combphy_cfg(struct rockchip_combphy_priv *priv) if (priv->ext_refclk) { rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_clk_ext, true); if (priv->type == PHY_TYPE_PCIE && rate == REF_CLOCK_100MHz) { - val = FIELD_PREP(PHYREG33_PLL_KVCO_MASK, PHYREG33_PLL_KVCO_VALUE_RK3576); - rockchip_combphy_updatel(priv, PHYREG33_PLL_KVCO_MASK, - val, PHYREG33); + val = FIELD_PREP(RK3568_PHYREG33_PLL_KVCO_MASK, + RK3576_PHYREG33_PLL_KVCO_VALUE); + rockchip_combphy_updatel(priv, RK3568_PHYREG33_PLL_KVCO_MASK, + val, RK3568_PHYREG33); /* Set up rx_trim: PLL LPF C1 85pf R1 2.5kohm */ - writel(0x0c, priv->mmio + PHYREG27); + writel(0x0c, priv->mmio + RK3588_PHYREG27); /* * Set up SU adjust signal: @@ -927,25 +1136,25 @@ static int rk3576_combphy_cfg(struct rockchip_combphy_priv *priv) * su_trim[23:16], CKRCV adjust * su_trim[31:24], CKDRV adjust */ - writel(0x90, priv->mmio + PHYREG11); - writel(0x43, priv->mmio + PHYREG12); - writel(0x88, priv->mmio + PHYREG13); - writel(0x56, priv->mmio + PHYREG14); + writel(0x90, priv->mmio + RK3568_PHYREG11); + writel(0x43, priv->mmio + RK3568_PHYREG12); + writel(0x88, priv->mmio + RK3568_PHYREG13); + writel(0x56, priv->mmio + RK3568_PHYREG14); } } if (priv->enable_ssc) { - val = readl(priv->mmio + PHYREG8); - val |= PHYREG8_SSC_EN; - writel(val, priv->mmio + PHYREG8); + val = readl(priv->mmio + RK3568_PHYREG8); + val |= RK3568_PHYREG8_SSC_EN; + writel(val, priv->mmio + RK3568_PHYREG8); if (priv->type == PHY_TYPE_PCIE && rate == REF_CLOCK_24MHz) { /* Set PLL loop divider */ - writel(0x00, priv->mmio + PHYREG17); - writel(PHYREG18_PLL_LOOP, priv->mmio + PHYREG18); + writel(0x00, priv->mmio + RK3576_PHYREG17); + writel(RK3568_PHYREG18_PLL_LOOP, priv->mmio + RK3568_PHYREG18); /* Set up rx_pck invert and rx msb to disable */ - writel(0x00, priv->mmio + PHYREG27); + writel(0x00, priv->mmio + RK3588_PHYREG27); /* * Set up SU adjust signal: @@ -954,16 +1163,17 @@ static int rk3576_combphy_cfg(struct rockchip_combphy_priv *priv) * su_trim[23:16], CKRCV adjust * su_trim[31:24], CKDRV adjust */ - writel(0x90, priv->mmio + PHYREG11); - writel(0x02, priv->mmio + PHYREG12); - writel(0x08, priv->mmio + PHYREG13); - writel(0x57, priv->mmio + PHYREG14); - writel(0x40, priv->mmio + PHYREG15); + writel(0x90, priv->mmio + RK3568_PHYREG11); + writel(0x02, priv->mmio + RK3568_PHYREG12); + writel(0x08, priv->mmio + RK3568_PHYREG13); + writel(0x57, priv->mmio + RK3568_PHYREG14); + writel(0x40, priv->mmio + RK3568_PHYREG15); - writel(PHYREG16_SSC_CNT_VALUE, priv->mmio + PHYREG16); + writel(RK3568_PHYREG16_SSC_CNT_VALUE, priv->mmio + RK3568_PHYREG16); - val = FIELD_PREP(PHYREG33_PLL_KVCO_MASK, PHYREG33_PLL_KVCO_VALUE_RK3576); - writel(val, priv->mmio + PHYREG33); + val = FIELD_PREP(RK3568_PHYREG33_PLL_KVCO_MASK, + RK3576_PHYREG33_PLL_KVCO_VALUE); + writel(val, priv->mmio + RK3568_PHYREG33); } } @@ -1033,30 +1243,28 @@ static int rk3588_combphy_cfg(struct rockchip_combphy_priv *priv) break; case PHY_TYPE_USB3: /* Set SSC downward spread spectrum */ - rockchip_combphy_updatel(priv, PHYREG32_SSC_MASK, - PHYREG32_SSC_DOWNWARD << PHYREG32_SSC_DIR_SHIFT, - PHYREG32); + val = RK3568_PHYREG32_SSC_DOWNWARD << RK3568_PHYREG32_SSC_DIR_SHIFT; + rockchip_combphy_updatel(priv, RK3568_PHYREG32_SSC_MASK, val, RK3568_PHYREG32); /* Enable adaptive CTLE for USB3.0 Rx. */ - val = readl(priv->mmio + PHYREG15); - val |= PHYREG15_CTLE_EN; - writel(val, priv->mmio + PHYREG15); + val = readl(priv->mmio + RK3568_PHYREG15); + val |= RK3568_PHYREG15_CTLE_EN; + writel(val, priv->mmio + RK3568_PHYREG15); /* Set PLL KVCO fine tuning signals. */ - rockchip_combphy_updatel(priv, PHYREG33_PLL_KVCO_MASK, - PHYREG33_PLL_KVCO_VALUE << PHYREG33_PLL_KVCO_SHIFT, - PHYREG33); + val = RK3568_PHYREG33_PLL_KVCO_VALUE << RK3568_PHYREG33_PLL_KVCO_SHIFT; + rockchip_combphy_updatel(priv, RK3568_PHYREG33_PLL_KVCO_MASK, val, RK3568_PHYREG33); /* Enable controlling random jitter. */ - writel(PHYREG12_PLL_LPF_ADJ_VALUE, priv->mmio + PHYREG12); + writel(RK3568_PHYREG12_PLL_LPF_ADJ_VALUE, priv->mmio + RK3568_PHYREG12); /* Set PLL input clock divider 1/2. */ - rockchip_combphy_updatel(priv, PHYREG6_PLL_DIV_MASK, - PHYREG6_PLL_DIV_2 << PHYREG6_PLL_DIV_SHIFT, - PHYREG6); + rockchip_combphy_updatel(priv, RK3568_PHYREG6_PLL_DIV_MASK, + RK3568_PHYREG6_PLL_DIV_2 << RK3568_PHYREG6_PLL_DIV_SHIFT, + RK3568_PHYREG6); - writel(PHYREG18_PLL_LOOP, priv->mmio + PHYREG18); - writel(PHYREG11_SU_TRIM_0_7, priv->mmio + PHYREG11); + writel(RK3568_PHYREG18_PLL_LOOP, priv->mmio + RK3568_PHYREG18); + writel(RK3568_PHYREG11_SU_TRIM_0_7, priv->mmio + RK3568_PHYREG11); rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_txcomp_sel, false); rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_txelec_sel, false); @@ -1064,16 +1272,16 @@ static int rk3588_combphy_cfg(struct rockchip_combphy_priv *priv) break; case PHY_TYPE_SATA: /* Enable adaptive CTLE for SATA Rx. */ - val = readl(priv->mmio + PHYREG15); - val |= PHYREG15_CTLE_EN; - writel(val, priv->mmio + PHYREG15); + val = readl(priv->mmio + RK3568_PHYREG15); + val |= RK3568_PHYREG15_CTLE_EN; + writel(val, priv->mmio + RK3568_PHYREG15); /* * Set tx_rterm=50ohm and rx_rterm=44ohm for SATA. * 0: 60ohm, 8: 50ohm 15: 44ohm (by step abort 1ohm) */ - val = PHYREG7_TX_RTERM_50OHM << PHYREG7_TX_RTERM_SHIFT; - val |= PHYREG7_RX_RTERM_44OHM << PHYREG7_RX_RTERM_SHIFT; - writel(val, priv->mmio + PHYREG7); + val = RK3568_PHYREG7_TX_RTERM_50OHM << RK3568_PHYREG7_TX_RTERM_SHIFT; + val |= RK3568_PHYREG7_RX_RTERM_44OHM << RK3568_PHYREG7_RX_RTERM_SHIFT; + writel(val, priv->mmio + RK3568_PHYREG7); rockchip_combphy_param_write(priv->phy_grf, &cfg->con0_for_sata, true); rockchip_combphy_param_write(priv->phy_grf, &cfg->con1_for_sata, true); @@ -1095,11 +1303,11 @@ static int rk3588_combphy_cfg(struct rockchip_combphy_priv *priv) case REF_CLOCK_24MHz: if (priv->type == PHY_TYPE_USB3 || priv->type == PHY_TYPE_SATA) { /* Set ssc_cnt[9:0]=0101111101 & 31.5KHz. */ - val = PHYREG15_SSC_CNT_VALUE << PHYREG15_SSC_CNT_SHIFT; - rockchip_combphy_updatel(priv, PHYREG15_SSC_CNT_MASK, - val, PHYREG15); + val = RK3568_PHYREG15_SSC_CNT_VALUE << RK3568_PHYREG15_SSC_CNT_SHIFT; + rockchip_combphy_updatel(priv, RK3568_PHYREG15_SSC_CNT_MASK, + val, RK3568_PHYREG15); - writel(PHYREG16_SSC_CNT_VALUE, priv->mmio + PHYREG16); + writel(RK3568_PHYREG16_SSC_CNT_VALUE, priv->mmio + RK3568_PHYREG16); } break; @@ -1110,23 +1318,25 @@ static int rk3588_combphy_cfg(struct rockchip_combphy_priv *priv) rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_clk_100m, true); if (priv->type == PHY_TYPE_PCIE) { /* PLL KVCO fine tuning. */ - val = 4 << PHYREG33_PLL_KVCO_SHIFT; - rockchip_combphy_updatel(priv, PHYREG33_PLL_KVCO_MASK, - val, PHYREG33); + val = 4 << RK3568_PHYREG33_PLL_KVCO_SHIFT; + rockchip_combphy_updatel(priv, RK3568_PHYREG33_PLL_KVCO_MASK, + val, RK3568_PHYREG33); /* Enable controlling random jitter. */ - writel(PHYREG12_PLL_LPF_ADJ_VALUE, priv->mmio + PHYREG12); + writel(RK3568_PHYREG12_PLL_LPF_ADJ_VALUE, priv->mmio + RK3568_PHYREG12); /* Set up rx_trim: PLL LPF C1 85pf R1 1.25kohm */ - writel(PHYREG27_RX_TRIM_RK3588, priv->mmio + PHYREG27); + writel(RK3588_PHYREG27_RX_TRIM, priv->mmio + RK3588_PHYREG27); /* Set up su_trim: */ - writel(PHYREG11_SU_TRIM_0_7, priv->mmio + PHYREG11); + writel(RK3568_PHYREG11_SU_TRIM_0_7, priv->mmio + RK3568_PHYREG11); } else if (priv->type == PHY_TYPE_SATA) { /* downward spread spectrum +500ppm */ - val = PHYREG32_SSC_DOWNWARD << PHYREG32_SSC_DIR_SHIFT; - val |= PHYREG32_SSC_OFFSET_500PPM << PHYREG32_SSC_OFFSET_SHIFT; - rockchip_combphy_updatel(priv, PHYREG32_SSC_MASK, val, PHYREG32); + val = RK3568_PHYREG32_SSC_DOWNWARD << RK3568_PHYREG32_SSC_DIR_SHIFT; + val |= RK3568_PHYREG32_SSC_OFFSET_500PPM << + RK3568_PHYREG32_SSC_OFFSET_SHIFT; + rockchip_combphy_updatel(priv, RK3568_PHYREG32_SSC_MASK, val, + RK3568_PHYREG32); } break; default: @@ -1137,20 +1347,21 @@ static int rk3588_combphy_cfg(struct rockchip_combphy_priv *priv) if (priv->ext_refclk) { rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_clk_ext, true); if (priv->type == PHY_TYPE_PCIE && rate == REF_CLOCK_100MHz) { - val = PHYREG13_RESISTER_HIGH_Z << PHYREG13_RESISTER_SHIFT; - val |= PHYREG13_CKRCV_AMP0; - rockchip_combphy_updatel(priv, PHYREG13_RESISTER_MASK, val, PHYREG13); - - val = readl(priv->mmio + PHYREG14); - val |= PHYREG14_CKRCV_AMP1; - writel(val, priv->mmio + PHYREG14); + val = RK3568_PHYREG13_RESISTER_HIGH_Z << RK3568_PHYREG13_RESISTER_SHIFT; + val |= RK3568_PHYREG13_CKRCV_AMP0; + rockchip_combphy_updatel(priv, RK3568_PHYREG13_RESISTER_MASK, val, + RK3568_PHYREG13); + + val = readl(priv->mmio + RK3568_PHYREG14); + val |= RK3568_PHYREG14_CKRCV_AMP1; + writel(val, priv->mmio + RK3568_PHYREG14); } } if (priv->enable_ssc) { - val = readl(priv->mmio + PHYREG8); - val |= PHYREG8_SSC_EN; - writel(val, priv->mmio + PHYREG8); + val = readl(priv->mmio + RK3568_PHYREG8); + val |= RK3568_PHYREG8_SSC_EN; + writel(val, priv->mmio + RK3568_PHYREG8); } return 0; @@ -1198,6 +1409,10 @@ static const struct rockchip_combphy_cfg rk3588_combphy_cfgs = { static const struct of_device_id rockchip_combphy_of_match[] = { { + .compatible = "rockchip,rk3528-naneng-combphy", + .data = &rk3528_combphy_cfgs, + }, + { .compatible = "rockchip,rk3562-naneng-combphy", .data = &rk3562_combphy_cfgs, }, diff --git a/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c b/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c index 79db57ee90d1..01bbf668e05e 100644 --- a/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c +++ b/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c @@ -795,7 +795,6 @@ static const struct regmap_config rk_hdptx_phy_regmap_config = { .val_bits = 32, .writeable_reg = rk_hdptx_phy_is_rw_reg, .readable_reg = rk_hdptx_phy_is_rw_reg, - .fast_io = true, .max_register = 0x18b4, }; diff --git a/drivers/phy/rockchip/phy-rockchip-usbdp.c b/drivers/phy/rockchip/phy-rockchip-usbdp.c index c066cc0a7b4f..fba35510d88c 100644 --- a/drivers/phy/rockchip/phy-rockchip-usbdp.c +++ b/drivers/phy/rockchip/phy-rockchip-usbdp.c @@ -666,7 +666,7 @@ static int rk_udphy_orien_sw_set(struct typec_switch_dev *sw, goto unlock_ret; } - udphy->flip = (orien == TYPEC_ORIENTATION_REVERSE) ? true : false; + udphy->flip = orien == TYPEC_ORIENTATION_REVERSE; rk_udphy_set_typec_default_mapping(udphy); rk_udphy_usb_bvalid_enable(udphy, true); @@ -1430,7 +1430,6 @@ static const struct regmap_config rk_udphy_pma_regmap_cfg = { .reg_bits = 32, .reg_stride = 4, .val_bits = 32, - .fast_io = true, .max_register = 0x20dc, }; diff --git a/drivers/phy/samsung/phy-exynos5-usbdrd.c b/drivers/phy/samsung/phy-exynos5-usbdrd.c index dd660ebe8045..a88ba95bdc8f 100644 --- a/drivers/phy/samsung/phy-exynos5-usbdrd.c +++ b/drivers/phy/samsung/phy-exynos5-usbdrd.c @@ -2417,4 +2417,3 @@ module_platform_driver(exynos5_usb3drd_phy); MODULE_DESCRIPTION("Samsung Exynos5 SoCs USB 3.0 DRD controller PHY driver"); MODULE_AUTHOR("Vivek Gautam <gautam.vivek@samsung.com>"); MODULE_LICENSE("GPL v2"); -MODULE_ALIAS("platform:exynos5_usb3drd_phy"); diff --git a/drivers/phy/samsung/phy-samsung-usb2.c b/drivers/phy/samsung/phy-samsung-usb2.c index 9de744cd6f39..d2749b67cf8f 100644 --- a/drivers/phy/samsung/phy-samsung-usb2.c +++ b/drivers/phy/samsung/phy-samsung-usb2.c @@ -258,4 +258,3 @@ module_platform_driver(samsung_usb2_phy_driver); MODULE_DESCRIPTION("Samsung S5P/Exynos SoC USB PHY driver"); MODULE_AUTHOR("Kamil Debski <k.debski@samsung.com>"); MODULE_LICENSE("GPL v2"); -MODULE_ALIAS("platform:samsung-usb2-phy"); diff --git a/drivers/phy/sophgo/Kconfig b/drivers/phy/sophgo/Kconfig new file mode 100644 index 000000000000..2c943bbe1f81 --- /dev/null +++ b/drivers/phy/sophgo/Kconfig @@ -0,0 +1,19 @@ +# SPDX-License-Identifier: GPL-2.0-only +# +# Phy drivers for Sophgo platforms +# + +if ARCH_SOPHGO || COMPILE_TEST + +config PHY_SOPHGO_CV1800_USB2 + tristate "Sophgo CV18XX/SG200X USB 2.0 PHY support" + depends on MFD_SYSCON + depends on USB_SUPPORT + select GENERIC_PHY + help + Enable this to support the USB 2.0 PHY used with + the DWC2 USB controller in Sophgo CV18XX/SG200X + series SoC. + If unsure, say N. + +endif # ARCH_SOPHGO || COMPILE_TEST diff --git a/drivers/phy/sophgo/Makefile b/drivers/phy/sophgo/Makefile new file mode 100644 index 000000000000..318060661759 --- /dev/null +++ b/drivers/phy/sophgo/Makefile @@ -0,0 +1,2 @@ +# SPDX-License-Identifier: GPL-2.0 +obj-$(CONFIG_PHY_SOPHGO_CV1800_USB2) += phy-cv1800-usb2.o diff --git a/drivers/phy/sophgo/phy-cv1800-usb2.c b/drivers/phy/sophgo/phy-cv1800-usb2.c new file mode 100644 index 000000000000..64f8e37b4b52 --- /dev/null +++ b/drivers/phy/sophgo/phy-cv1800-usb2.c @@ -0,0 +1,170 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2025 Inochi Amaoto <inochiama@outlook.com> + */ + +#include <linux/clk.h> +#include <linux/bitfield.h> +#include <linux/debugfs.h> +#include <linux/kernel.h> +#include <linux/mfd/syscon.h> +#include <linux/module.h> +#include <linux/of.h> +#include <linux/of_address.h> +#include <linux/of_gpio.h> +#include <linux/platform_device.h> +#include <linux/phy/phy.h> +#include <linux/regmap.h> +#include <linux/spinlock.h> + +#define REG_USB_PHY_CTRL 0x048 + +#define PHY_VBUS_POWER_EN BIT(0) +#define PHY_VBUS_POWER BIT(1) +#define PHY_ID_OVERWRITE_EN BIT(6) +#define PHY_ID_OVERWRITE_MODE BIT(7) +#define PHY_ID_OVERWRITE_MODE_HOST FIELD_PREP(BIT(7), 0) +#define PHY_ID_OVERWRITE_MODE_DEVICE FIELD_PREP(BIT(7), 1) + +#define PHY_APP_CLK_RATE 125000000 +#define PHY_LPM_CLK_RATE 12000000 +#define PHY_STB_CLK_RATE 333334 + +struct cv1800_usb_phy { + struct phy *phy; + struct regmap *syscon; + spinlock_t lock; + struct clk *usb_app_clk; + struct clk *usb_lpm_clk; + struct clk *usb_stb_clk; + bool support_otg; +}; + +static int cv1800_usb_phy_set_mode(struct phy *_phy, + enum phy_mode mode, int submode) +{ + struct cv1800_usb_phy *phy = phy_get_drvdata(_phy); + unsigned int regval = 0; + int ret; + + dev_info(&phy->phy->dev, "set mode %d", (int)mode); + + switch (mode) { + case PHY_MODE_USB_DEVICE: + regval = PHY_ID_OVERWRITE_EN | PHY_ID_OVERWRITE_MODE_DEVICE; + regmap_clear_bits(phy->syscon, REG_USB_PHY_CTRL, PHY_VBUS_POWER); + break; + case PHY_MODE_USB_HOST: + regval = PHY_ID_OVERWRITE_EN | PHY_ID_OVERWRITE_MODE_HOST; + regmap_set_bits(phy->syscon, REG_USB_PHY_CTRL, PHY_VBUS_POWER); + break; + case PHY_MODE_USB_OTG: + if (!phy->support_otg) + return 0; + + ret = regmap_read(phy->syscon, REG_USB_PHY_CTRL, ®val); + if (ret) + return ret; + + regval = FIELD_GET(PHY_ID_OVERWRITE_MODE, regval); + break; + default: + return -EINVAL; + } + + return regmap_update_bits(phy->syscon, REG_USB_PHY_CTRL, + PHY_ID_OVERWRITE_EN | PHY_ID_OVERWRITE_MODE, + regval); +} + +static int cv1800_usb_phy_set_clock(struct cv1800_usb_phy *phy) +{ + int ret; + + ret = clk_set_rate(phy->usb_app_clk, PHY_APP_CLK_RATE); + if (ret) + return ret; + + ret = clk_set_rate(phy->usb_lpm_clk, PHY_LPM_CLK_RATE); + if (ret) + return ret; + + return clk_set_rate(phy->usb_stb_clk, PHY_STB_CLK_RATE); +} + +static const struct phy_ops cv1800_usb_phy_ops = { + .set_mode = cv1800_usb_phy_set_mode, + .owner = THIS_MODULE, +}; + +static int cv1800_usb_phy_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct device *parent = dev->parent; + struct cv1800_usb_phy *phy; + struct phy_provider *phy_provider; + int ret; + + if (!parent) + return -ENODEV; + + phy = devm_kmalloc(dev, sizeof(*phy), GFP_KERNEL); + if (!phy) + return -ENOMEM; + + phy->syscon = syscon_node_to_regmap(parent->of_node); + if (IS_ERR_OR_NULL(phy->syscon)) + return -ENODEV; + + phy->support_otg = false; + + spin_lock_init(&phy->lock); + + phy->usb_app_clk = devm_clk_get_enabled(dev, "app"); + if (IS_ERR(phy->usb_app_clk)) + return dev_err_probe(dev, PTR_ERR(phy->usb_app_clk), + "Failed to get app clock\n"); + + phy->usb_lpm_clk = devm_clk_get_enabled(dev, "lpm"); + if (IS_ERR(phy->usb_lpm_clk)) + return dev_err_probe(dev, PTR_ERR(phy->usb_lpm_clk), + "Failed to get lpm clock\n"); + + phy->usb_stb_clk = devm_clk_get_enabled(dev, "stb"); + if (IS_ERR(phy->usb_stb_clk)) + return dev_err_probe(dev, PTR_ERR(phy->usb_stb_clk), + "Failed to get stb clock\n"); + + phy->phy = devm_phy_create(dev, NULL, &cv1800_usb_phy_ops); + if (IS_ERR(phy->phy)) + return dev_err_probe(dev, PTR_ERR(phy->phy), + "Failed to create phy\n"); + + ret = cv1800_usb_phy_set_clock(phy); + if (ret) + return ret; + + phy_set_drvdata(phy->phy, phy); + phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate); + + return PTR_ERR_OR_ZERO(phy_provider); +} + +static const struct of_device_id cv1800_usb_phy_ids[] = { + { .compatible = "sophgo,cv1800b-usb2-phy" }, + { }, +}; +MODULE_DEVICE_TABLE(of, cv1800_usb_phy_ids); + +static struct platform_driver cv1800_usb_phy_driver = { + .probe = cv1800_usb_phy_probe, + .driver = { + .name = "cv1800-usb2-phy", + .of_match_table = cv1800_usb_phy_ids, + }, +}; +module_platform_driver(cv1800_usb_phy_driver); + +MODULE_AUTHOR("Inochi Amaoto <inochiama@outlook.com>"); +MODULE_DESCRIPTION("CV1800/SG2000 SoC USB 2.0 PHY driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/phy/ti/Kconfig b/drivers/phy/ti/Kconfig index b905902d5750..b40f28019131 100644 --- a/drivers/phy/ti/Kconfig +++ b/drivers/phy/ti/Kconfig @@ -62,7 +62,7 @@ config OMAP_CONTROL_PHY config OMAP_USB2 tristate "OMAP USB2 PHY Driver" - depends on ARCH_OMAP2PLUS || ARCH_K3 + depends on ARCH_OMAP2PLUS || ARCH_K3 || COMPILE_TEST depends on USB_SUPPORT select GENERIC_PHY select USB_PHY diff --git a/drivers/phy/ti/phy-am654-serdes.c b/drivers/phy/ti/phy-am654-serdes.c index 431b223996e0..5b6c27aa7e8b 100644 --- a/drivers/phy/ti/phy-am654-serdes.c +++ b/drivers/phy/ti/phy-am654-serdes.c @@ -99,7 +99,6 @@ static const struct regmap_config serdes_am654_regmap_config = { .reg_bits = 32, .val_bits = 32, .reg_stride = 4, - .fast_io = true, .max_register = 0x1ffc, }; diff --git a/drivers/phy/ti/phy-dm816x-usb.c b/drivers/phy/ti/phy-dm816x-usb.c index e8f842d4e841..d274831b731c 100644 --- a/drivers/phy/ti/phy-dm816x-usb.c +++ b/drivers/phy/ti/phy-dm816x-usb.c @@ -269,7 +269,6 @@ static struct platform_driver dm816x_usb_phy_driver = { module_platform_driver(dm816x_usb_phy_driver); -MODULE_ALIAS("platform:dm816x_usb"); MODULE_AUTHOR("Tony Lindgren <tony@atomide.com>"); MODULE_DESCRIPTION("dm816x usb phy driver"); MODULE_LICENSE("GPL v2"); diff --git a/drivers/phy/ti/phy-j721e-wiz.c b/drivers/phy/ti/phy-j721e-wiz.c index ab2a4f2c0a5b..a8b440c6c46b 100644 --- a/drivers/phy/ti/phy-j721e-wiz.c +++ b/drivers/phy/ti/phy-j721e-wiz.c @@ -1319,7 +1319,6 @@ static const struct regmap_config wiz_regmap_config = { .reg_bits = 32, .val_bits = 32, .reg_stride = 4, - .fast_io = true, }; static struct wiz_data j721e_16g_data = { diff --git a/drivers/phy/ti/phy-omap-control.c b/drivers/phy/ti/phy-omap-control.c index 2fdb8f4241c7..4968434312f8 100644 --- a/drivers/phy/ti/phy-omap-control.c +++ b/drivers/phy/ti/phy-omap-control.c @@ -334,7 +334,6 @@ static void __exit omap_control_phy_exit(void) } module_exit(omap_control_phy_exit); -MODULE_ALIAS("platform:omap_control_phy"); MODULE_AUTHOR("Texas Instruments Inc."); MODULE_DESCRIPTION("OMAP Control Module PHY Driver"); MODULE_LICENSE("GPL v2"); diff --git a/drivers/phy/ti/phy-omap-usb2.c b/drivers/phy/ti/phy-omap-usb2.c index c444bb2530ca..1eb252604441 100644 --- a/drivers/phy/ti/phy-omap-usb2.c +++ b/drivers/phy/ti/phy-omap-usb2.c @@ -533,7 +533,6 @@ static struct platform_driver omap_usb2_driver = { module_platform_driver(omap_usb2_driver); -MODULE_ALIAS("platform:omap_usb2"); MODULE_AUTHOR("Texas Instruments Inc."); MODULE_DESCRIPTION("OMAP USB2 phy driver"); MODULE_LICENSE("GPL v2"); diff --git a/drivers/phy/ti/phy-ti-pipe3.c b/drivers/phy/ti/phy-ti-pipe3.c index ae764d6524c9..b5543b5c674c 100644 --- a/drivers/phy/ti/phy-ti-pipe3.c +++ b/drivers/phy/ti/phy-ti-pipe3.c @@ -942,7 +942,6 @@ static struct platform_driver ti_pipe3_driver = { module_platform_driver(ti_pipe3_driver); -MODULE_ALIAS("platform:ti_pipe3"); MODULE_AUTHOR("Texas Instruments Inc."); MODULE_DESCRIPTION("TI PIPE3 phy driver"); MODULE_LICENSE("GPL v2"); diff --git a/drivers/pinctrl/core.c b/drivers/pinctrl/core.c index 73b78d6eac67..c5dbf4e9db84 100644 --- a/drivers/pinctrl/core.c +++ b/drivers/pinctrl/core.c @@ -1656,6 +1656,19 @@ int pinctrl_pm_select_default_state(struct device *dev) EXPORT_SYMBOL_GPL(pinctrl_pm_select_default_state); /** + * pinctrl_pm_select_init_state() - select init pinctrl state for PM + * @dev: device to select init state for + */ +int pinctrl_pm_select_init_state(struct device *dev) +{ + if (!dev->pins) + return 0; + + return pinctrl_select_bound_state(dev, dev->pins->init_state); +} +EXPORT_SYMBOL_GPL(pinctrl_pm_select_init_state); + +/** * pinctrl_pm_select_sleep_state() - select sleep pinctrl state for PM * @dev: device to select sleep state for */ diff --git a/drivers/s390/crypto/vfio_ap_ops.c b/drivers/s390/crypto/vfio_ap_ops.c index 766557547f83..eb5ff49f6fe7 100644 --- a/drivers/s390/crypto/vfio_ap_ops.c +++ b/drivers/s390/crypto/vfio_ap_ops.c @@ -354,7 +354,7 @@ static int vfio_ap_validate_nib(struct kvm_vcpu *vcpu, dma_addr_t *nib) if (!*nib) return -EINVAL; - if (kvm_is_error_hva(gfn_to_hva(vcpu->kvm, *nib >> PAGE_SHIFT))) + if (!kvm_s390_is_gpa_in_memslot(vcpu->kvm, *nib)) return -EINVAL; return 0; diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig index 5522310bab8d..19d0884479a2 100644 --- a/drivers/scsi/Kconfig +++ b/drivers/scsi/Kconfig @@ -589,7 +589,7 @@ config XEN_SCSI_FRONTEND config HYPERV_STORAGE tristate "Microsoft Hyper-V virtual storage driver" - depends on SCSI && HYPERV + depends on SCSI && HYPERV_VMBUS depends on m || SCSI_FC_ATTRS != m default HYPERV help diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index 0ca7429d86b8..f206267d9ecd 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c @@ -14367,7 +14367,7 @@ lpfc_sli_prep_dev_for_perm_failure(struct lpfc_hba *phba) * as desired. * * Return codes - * PCI_ERS_RESULT_CAN_RECOVER - can be recovered with reset_link + * PCI_ERS_RESULT_CAN_RECOVER - can be recovered without reset * PCI_ERS_RESULT_NEED_RESET - need to reset before recovery * PCI_ERS_RESULT_DISCONNECT - device could not be recovered **/ diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index 98a5c105fdfd..cb56d2af6cfa 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c @@ -7884,11 +7884,6 @@ qla2xxx_pci_slot_reset(struct pci_dev *pdev) "Slot Reset.\n"); ha->pci_error_state = QLA_PCI_SLOT_RESET; - /* Workaround: qla2xxx driver which access hardware earlier - * needs error state to be pci_channel_io_online. - * Otherwise mailbox command timesout. - */ - pdev->error_state = pci_channel_io_normal; pci_restore_state(pdev); diff --git a/drivers/soundwire/bus_type.c b/drivers/soundwire/bus_type.c index bc1e653080d9..91e70cb46fb5 100644 --- a/drivers/soundwire/bus_type.c +++ b/drivers/soundwire/bus_type.c @@ -114,7 +114,6 @@ static int sdw_drv_probe(struct device *dev) ret = drv->probe(slave, id); if (ret) { - dev_pm_domain_detach(dev, false); ida_free(&slave->bus->slave_ida, slave->index); return ret; } @@ -180,8 +179,6 @@ static int sdw_drv_remove(struct device *dev) if (drv->remove) ret = drv->remove(slave); - dev_pm_domain_detach(dev, false); - ida_free(&slave->bus->slave_ida, slave->index); return ret; diff --git a/drivers/soundwire/debugfs.c b/drivers/soundwire/debugfs.c index 230a51489486..1e0f9318b616 100644 --- a/drivers/soundwire/debugfs.c +++ b/drivers/soundwire/debugfs.c @@ -91,6 +91,8 @@ static int sdw_slave_reg_show(struct seq_file *s_file, void *data) ret += sdw_sprintf(slave, buf, ret, i); for (i = SDW_SCP_DEVID_0; i <= SDW_SCP_DEVID_5; i++) ret += sdw_sprintf(slave, buf, ret, i); + for (i = SDW_SCP_SDCA_INT1; i <= SDW_SCP_SDCA_INTMASK4; i++) + ret += sdw_sprintf(slave, buf, ret, i); for (i = SDW_SCP_FRAMECTRL_B0; i <= SDW_SCP_BUSCLOCK_SCALE_B0; i++) ret += sdw_sprintf(slave, buf, ret, i); for (i = SDW_SCP_FRAMECTRL_B1; i <= SDW_SCP_BUSCLOCK_SCALE_B1; i++) diff --git a/drivers/soundwire/qcom.c b/drivers/soundwire/qcom.c index bd2b293b44f2..5b3078220189 100644 --- a/drivers/soundwire/qcom.c +++ b/drivers/soundwire/qcom.c @@ -924,10 +924,7 @@ static enum sdw_command_response qcom_swrm_xfer_msg(struct sdw_bus *bus, if (msg->flags == SDW_MSG_FLAG_READ) { for (i = 0; i < msg->len;) { - if ((msg->len - i) < QCOM_SWRM_MAX_RD_LEN) - len = msg->len - i; - else - len = QCOM_SWRM_MAX_RD_LEN; + len = min(msg->len - i, QCOM_SWRM_MAX_RD_LEN); ret = qcom_swrm_cmd_fifo_rd_cmd(ctrl, msg->dev_num, msg->addr + i, len, diff --git a/drivers/staging/axis-fifo/axis-fifo.c b/drivers/staging/axis-fifo/axis-fifo.c index e8aa632e0a31..811bfdc578d8 100644 --- a/drivers/staging/axis-fifo/axis-fifo.c +++ b/drivers/staging/axis-fifo/axis-fifo.c @@ -43,7 +43,6 @@ #define DRIVER_NAME "axis_fifo" #define READ_BUF_SIZE 128U /* read buffer length in words */ -#define WRITE_BUF_SIZE 128U /* write buffer length in words */ #define AXIS_FIFO_DEBUG_REG_NAME_MAX_LEN 4 @@ -231,6 +230,7 @@ static ssize_t axis_fifo_read(struct file *f, char __user *buf, } bytes_available = ioread32(fifo->base_addr + XLLF_RLR_OFFSET); + words_available = bytes_available / sizeof(u32); if (!bytes_available) { dev_err(fifo->dt_device, "received a packet of length 0\n"); ret = -EIO; @@ -241,7 +241,7 @@ static ssize_t axis_fifo_read(struct file *f, char __user *buf, dev_err(fifo->dt_device, "user read buffer too small (available bytes=%zu user buffer bytes=%zu)\n", bytes_available, len); ret = -EINVAL; - goto end_unlock; + goto err_flush_rx; } if (bytes_available % sizeof(u32)) { @@ -250,11 +250,9 @@ static ssize_t axis_fifo_read(struct file *f, char __user *buf, */ dev_err(fifo->dt_device, "received a packet that isn't word-aligned\n"); ret = -EIO; - goto end_unlock; + goto err_flush_rx; } - words_available = bytes_available / sizeof(u32); - /* read data into an intermediate buffer, copying the contents * to userspace when the buffer is full */ @@ -266,18 +264,23 @@ static ssize_t axis_fifo_read(struct file *f, char __user *buf, tmp_buf[i] = ioread32(fifo->base_addr + XLLF_RDFD_OFFSET); } + words_available -= copy; if (copy_to_user(buf + copied * sizeof(u32), tmp_buf, copy * sizeof(u32))) { ret = -EFAULT; - goto end_unlock; + goto err_flush_rx; } copied += copy; - words_available -= copy; } + mutex_unlock(&fifo->read_lock); + + return bytes_available; - ret = bytes_available; +err_flush_rx: + while (words_available--) + ioread32(fifo->base_addr + XLLF_RDFD_OFFSET); end_unlock: mutex_unlock(&fifo->read_lock); @@ -305,11 +308,8 @@ static ssize_t axis_fifo_write(struct file *f, const char __user *buf, { struct axis_fifo *fifo = (struct axis_fifo *)f->private_data; unsigned int words_to_write; - unsigned int copied; - unsigned int copy; - unsigned int i; + u32 *txbuf; int ret; - u32 tmp_buf[WRITE_BUF_SIZE]; if (len % sizeof(u32)) { dev_err(fifo->dt_device, @@ -325,11 +325,17 @@ static ssize_t axis_fifo_write(struct file *f, const char __user *buf, return -EINVAL; } - if (words_to_write > fifo->tx_fifo_depth) { - dev_err(fifo->dt_device, "tried to write more words [%u] than slots in the fifo buffer [%u]\n", - words_to_write, fifo->tx_fifo_depth); + /* + * In 'Store-and-Forward' mode, the maximum packet that can be + * transmitted is limited by the size of the FIFO, which is + * (C_TX_FIFO_DEPTH–4)*(data interface width/8) bytes. + * + * Do not attempt to send a packet larger than 'tx_fifo_depth - 4', + * otherwise a 'Transmit Packet Overrun Error' interrupt will be + * raised, which requires a reset of the TX circuit to recover. + */ + if (words_to_write > (fifo->tx_fifo_depth - 4)) return -EINVAL; - } if (fifo->write_flags & O_NONBLOCK) { /* @@ -368,32 +374,20 @@ static ssize_t axis_fifo_write(struct file *f, const char __user *buf, } } - /* write data from an intermediate buffer into the fifo IP, refilling - * the buffer with userspace data as needed - */ - copied = 0; - while (words_to_write > 0) { - copy = min(words_to_write, WRITE_BUF_SIZE); - - if (copy_from_user(tmp_buf, buf + copied * sizeof(u32), - copy * sizeof(u32))) { - ret = -EFAULT; - goto end_unlock; - } - - for (i = 0; i < copy; i++) - iowrite32(tmp_buf[i], fifo->base_addr + - XLLF_TDFD_OFFSET); - - copied += copy; - words_to_write -= copy; + txbuf = vmemdup_user(buf, len); + if (IS_ERR(txbuf)) { + ret = PTR_ERR(txbuf); + goto end_unlock; } - ret = copied * sizeof(u32); + for (int i = 0; i < words_to_write; ++i) + iowrite32(txbuf[i], fifo->base_addr + XLLF_TDFD_OFFSET); /* write packet size to fifo */ - iowrite32(ret, fifo->base_addr + XLLF_TLR_OFFSET); + iowrite32(len, fifo->base_addr + XLLF_TLR_OFFSET); + ret = len; + kvfree(txbuf); end_unlock: mutex_unlock(&fifo->write_lock); diff --git a/drivers/thermal/renesas/Kconfig b/drivers/thermal/renesas/Kconfig index c762c1c30d5a..5735c8728a31 100644 --- a/drivers/thermal/renesas/Kconfig +++ b/drivers/thermal/renesas/Kconfig @@ -27,6 +27,13 @@ config RZG2L_THERMAL Enable this to plug the RZ/G2L thermal sensor driver into the Linux thermal framework. +config RZG3E_THERMAL + tristate "Renesas RZ/G3E thermal driver" + depends on ARCH_RENESAS || COMPILE_TEST + help + Enable this to plug the RZ/G3E thermal sensor driver into the Linux + thermal framework. + config RZG3S_THERMAL tristate "Renesas RZ/G3S thermal driver" depends on ARCH_R9A08G045 || COMPILE_TEST @@ -34,10 +41,3 @@ config RZG3S_THERMAL help Enable this to plug the RZ/G3S thermal sensor driver into the Linux thermal framework. - -config RZG3E_THERMAL - tristate "Renesas RZ/G3E thermal driver" - depends on ARCH_RENESAS || COMPILE_TEST - help - Enable this to plug the RZ/G3E thermal sensor driver into the Linux - thermal framework. diff --git a/drivers/thermal/renesas/Makefile b/drivers/thermal/renesas/Makefile index 0ea592247572..8f5ae9af277c 100644 --- a/drivers/thermal/renesas/Makefile +++ b/drivers/thermal/renesas/Makefile @@ -5,4 +5,3 @@ obj-$(CONFIG_RCAR_THERMAL) += rcar_thermal.o obj-$(CONFIG_RZG2L_THERMAL) += rzg2l_thermal.o obj-$(CONFIG_RZG3E_THERMAL) += rzg3e_thermal.o obj-$(CONFIG_RZG3S_THERMAL) += rzg3s_thermal.o - diff --git a/drivers/tty/serial/qcom_geni_serial.c b/drivers/tty/serial/qcom_geni_serial.c index ce5cb97d60a7..8058b839b26c 100644 --- a/drivers/tty/serial/qcom_geni_serial.c +++ b/drivers/tty/serial/qcom_geni_serial.c @@ -14,7 +14,6 @@ #include <linux/irq.h> #include <linux/module.h> #include <linux/of.h> -#include <linux/pm_domain.h> #include <linux/pm_opp.h> #include <linux/platform_device.h> #include <linux/pm_runtime.h> @@ -102,16 +101,10 @@ #define DMA_RX_BUF_SIZE 2048 static DEFINE_IDA(port_ida); -#define DOMAIN_IDX_POWER 0 -#define DOMAIN_IDX_PERF 1 struct qcom_geni_device_data { bool console; enum geni_se_xfer_mode mode; - struct dev_pm_domain_attach_data pd_data; - int (*resources_init)(struct uart_port *uport); - int (*set_rate)(struct uart_port *uport, unsigned int baud); - int (*power_state)(struct uart_port *uport, bool state); }; struct qcom_geni_private_data { @@ -149,7 +142,6 @@ struct qcom_geni_serial_port { struct qcom_geni_private_data private_data; const struct qcom_geni_device_data *dev_data; - struct dev_pm_domain_list *pd_list; }; static const struct uart_ops qcom_geni_console_pops; @@ -1307,42 +1299,6 @@ static int geni_serial_set_rate(struct uart_port *uport, unsigned int baud) return 0; } -static int geni_serial_set_level(struct uart_port *uport, unsigned int baud) -{ - struct qcom_geni_serial_port *port = to_dev_port(uport); - struct device *perf_dev = port->pd_list->pd_devs[DOMAIN_IDX_PERF]; - - /* - * The performance protocol sets UART communication - * speeds by selecting different performance levels - * through the OPP framework. - * - * Supported perf levels for baudrates in firmware are below - * +---------------------+--------------------+ - * | Perf level value | Baudrate values | - * +---------------------+--------------------+ - * | 300 | 300 | - * | 1200 | 1200 | - * | 2400 | 2400 | - * | 4800 | 4800 | - * | 9600 | 9600 | - * | 19200 | 19200 | - * | 38400 | 38400 | - * | 57600 | 57600 | - * | 115200 | 115200 | - * | 230400 | 230400 | - * | 460800 | 460800 | - * | 921600 | 921600 | - * | 2000000 | 2000000 | - * | 3000000 | 3000000 | - * | 3200000 | 3200000 | - * | 4000000 | 4000000 | - * +---------------------+--------------------+ - */ - - return dev_pm_opp_set_level(perf_dev, baud); -} - static void qcom_geni_serial_set_termios(struct uart_port *uport, struct ktermios *termios, const struct ktermios *old) @@ -1361,7 +1317,7 @@ static void qcom_geni_serial_set_termios(struct uart_port *uport, /* baud rate */ baud = uart_get_baud_rate(uport, termios, old, 300, 8000000); - ret = port->dev_data->set_rate(uport, baud); + ret = geni_serial_set_rate(uport, baud); if (ret) return; @@ -1648,27 +1604,8 @@ static int geni_serial_resources_off(struct uart_port *uport) return 0; } -static int geni_serial_resource_state(struct uart_port *uport, bool power_on) -{ - return power_on ? geni_serial_resources_on(uport) : geni_serial_resources_off(uport); -} - -static int geni_serial_pwr_init(struct uart_port *uport) -{ - struct qcom_geni_serial_port *port = to_dev_port(uport); - int ret; - - ret = dev_pm_domain_attach_list(port->se.dev, - &port->dev_data->pd_data, &port->pd_list); - if (ret <= 0) - return -EINVAL; - - return 0; -} - -static int geni_serial_resource_init(struct uart_port *uport) +static int geni_serial_resource_init(struct qcom_geni_serial_port *port) { - struct qcom_geni_serial_port *port = to_dev_port(uport); int ret; port->se.clk = devm_clk_get(port->se.dev, "se"); @@ -1713,10 +1650,10 @@ static void qcom_geni_serial_pm(struct uart_port *uport, old_state = UART_PM_STATE_OFF; if (new_state == UART_PM_STATE_ON && old_state == UART_PM_STATE_OFF) - pm_runtime_resume_and_get(uport->dev); + geni_serial_resources_on(uport); else if (new_state == UART_PM_STATE_OFF && old_state == UART_PM_STATE_ON) - pm_runtime_put_sync(uport->dev); + geni_serial_resources_off(uport); } @@ -1819,16 +1756,13 @@ static int qcom_geni_serial_probe(struct platform_device *pdev) port->se.dev = &pdev->dev; port->se.wrapper = dev_get_drvdata(pdev->dev.parent); - ret = port->dev_data->resources_init(uport); + ret = geni_serial_resource_init(port); if (ret) return ret; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) { - ret = -EINVAL; - goto error; - } - + if (!res) + return -EINVAL; uport->mapbase = res->start; uport->rs485_config = qcom_geni_rs485_config; @@ -1840,26 +1774,19 @@ static int qcom_geni_serial_probe(struct platform_device *pdev) if (!data->console) { port->rx_buf = devm_kzalloc(uport->dev, DMA_RX_BUF_SIZE, GFP_KERNEL); - if (!port->rx_buf) { - ret = -ENOMEM; - goto error; - } + if (!port->rx_buf) + return -ENOMEM; } port->name = devm_kasprintf(uport->dev, GFP_KERNEL, "qcom_geni_serial_%s%d", uart_console(uport) ? "console" : "uart", uport->line); - if (!port->name) { - ret = -ENOMEM; - goto error; - } + if (!port->name) + return -ENOMEM; irq = platform_get_irq(pdev, 0); - if (irq < 0) { - ret = irq; - goto error; - } - + if (irq < 0) + return irq; uport->irq = irq; uport->has_sysrq = IS_ENABLED(CONFIG_SERIAL_QCOM_GENI_CONSOLE); @@ -1881,18 +1808,16 @@ static int qcom_geni_serial_probe(struct platform_device *pdev) IRQF_TRIGGER_HIGH, port->name, uport); if (ret) { dev_err(uport->dev, "Failed to get IRQ ret %d\n", ret); - goto error; + return ret; } ret = uart_get_rs485_mode(uport); if (ret) return ret; - devm_pm_runtime_enable(port->se.dev); - ret = uart_add_one_port(drv, uport); if (ret) - goto error; + return ret; if (port->wakeup_irq > 0) { device_init_wakeup(&pdev->dev, true); @@ -1902,15 +1827,11 @@ static int qcom_geni_serial_probe(struct platform_device *pdev) device_init_wakeup(&pdev->dev, false); ida_free(&port_ida, uport->line); uart_remove_one_port(drv, uport); - goto error; + return ret; } } return 0; - -error: - dev_pm_domain_detach_list(port->pd_list); - return ret; } static void qcom_geni_serial_remove(struct platform_device *pdev) @@ -1923,31 +1844,6 @@ static void qcom_geni_serial_remove(struct platform_device *pdev) device_init_wakeup(&pdev->dev, false); ida_free(&port_ida, uport->line); uart_remove_one_port(drv, &port->uport); - dev_pm_domain_detach_list(port->pd_list); -} - -static int __maybe_unused qcom_geni_serial_runtime_suspend(struct device *dev) -{ - struct qcom_geni_serial_port *port = dev_get_drvdata(dev); - struct uart_port *uport = &port->uport; - int ret = 0; - - if (port->dev_data->power_state) - ret = port->dev_data->power_state(uport, false); - - return ret; -} - -static int __maybe_unused qcom_geni_serial_runtime_resume(struct device *dev) -{ - struct qcom_geni_serial_port *port = dev_get_drvdata(dev); - struct uart_port *uport = &port->uport; - int ret = 0; - - if (port->dev_data->power_state) - ret = port->dev_data->power_state(uport, true); - - return ret; } static int qcom_geni_serial_suspend(struct device *dev) @@ -1985,46 +1881,14 @@ static int qcom_geni_serial_resume(struct device *dev) static const struct qcom_geni_device_data qcom_geni_console_data = { .console = true, .mode = GENI_SE_FIFO, - .resources_init = geni_serial_resource_init, - .set_rate = geni_serial_set_rate, - .power_state = geni_serial_resource_state, }; static const struct qcom_geni_device_data qcom_geni_uart_data = { .console = false, .mode = GENI_SE_DMA, - .resources_init = geni_serial_resource_init, - .set_rate = geni_serial_set_rate, - .power_state = geni_serial_resource_state, -}; - -static const struct qcom_geni_device_data sa8255p_qcom_geni_console_data = { - .console = true, - .mode = GENI_SE_FIFO, - .pd_data = { - .pd_flags = PD_FLAG_DEV_LINK_ON, - .pd_names = (const char*[]) { "power", "perf" }, - .num_pd_names = 2, - }, - .resources_init = geni_serial_pwr_init, - .set_rate = geni_serial_set_level, -}; - -static const struct qcom_geni_device_data sa8255p_qcom_geni_uart_data = { - .console = false, - .mode = GENI_SE_DMA, - .pd_data = { - .pd_flags = PD_FLAG_DEV_LINK_ON, - .pd_names = (const char*[]) { "power", "perf" }, - .num_pd_names = 2, - }, - .resources_init = geni_serial_pwr_init, - .set_rate = geni_serial_set_level, }; static const struct dev_pm_ops qcom_geni_serial_pm_ops = { - SET_RUNTIME_PM_OPS(qcom_geni_serial_runtime_suspend, - qcom_geni_serial_runtime_resume, NULL) SYSTEM_SLEEP_PM_OPS(qcom_geni_serial_suspend, qcom_geni_serial_resume) }; @@ -2034,17 +1898,9 @@ static const struct of_device_id qcom_geni_serial_match_table[] = { .data = &qcom_geni_console_data, }, { - .compatible = "qcom,sa8255p-geni-debug-uart", - .data = &sa8255p_qcom_geni_console_data, - }, - { .compatible = "qcom,geni-uart", .data = &qcom_geni_uart_data, }, - { - .compatible = "qcom,sa8255p-geni-uart", - .data = &sa8255p_qcom_geni_uart_data, - }, {} }; MODULE_DEVICE_TABLE(of, qcom_geni_serial_match_table); diff --git a/drivers/uio/Kconfig b/drivers/uio/Kconfig index b060dcd7c635..6f86a61231e6 100644 --- a/drivers/uio/Kconfig +++ b/drivers/uio/Kconfig @@ -140,7 +140,7 @@ config UIO_MF624 config UIO_HV_GENERIC tristate "Generic driver for Hyper-V VMBus" - depends on HYPERV + depends on HYPERV_VMBUS help Generic driver that you can bind, dynamically, to any Hyper-V VMBus device. It is useful to provide direct access diff --git a/drivers/video/fbdev/Kconfig b/drivers/video/fbdev/Kconfig index c21484d15f0c..c3b9954df804 100644 --- a/drivers/video/fbdev/Kconfig +++ b/drivers/video/fbdev/Kconfig @@ -1773,13 +1773,16 @@ config FB_BROADSHEET a bridge adapter. config FB_HYPERV - tristate "Microsoft Hyper-V Synthetic Video support" - depends on FB && HYPERV + tristate "Microsoft Hyper-V Synthetic Video support (DEPRECATED)" + depends on FB && HYPERV_VMBUS select DMA_CMA if HAVE_DMA_CONTIGUOUS && CMA select FB_IOMEM_HELPERS_DEFERRED help This framebuffer driver supports Microsoft Hyper-V Synthetic Video. + This driver is deprecated, please use the Hyper-V DRM driver at + drivers/gpu/drm/hyperv (CONFIG_DRM_HYPERV) instead. + config FB_SIMPLE tristate "Simple framebuffer support" depends on FB diff --git a/drivers/video/fbdev/hyperv_fb.c b/drivers/video/fbdev/hyperv_fb.c index 75338ffc703f..c99e2ea4b3de 100644 --- a/drivers/video/fbdev/hyperv_fb.c +++ b/drivers/video/fbdev/hyperv_fb.c @@ -1357,6 +1357,8 @@ static int __init hvfb_drv_init(void) { int ret; + pr_warn("Deprecated: use Hyper-V DRM driver instead\n"); + if (fb_modesetting_disabled("hyper_fb")) return -ENODEV; diff --git a/drivers/watchdog/intel_oc_wdt.c b/drivers/watchdog/intel_oc_wdt.c index 7c0551106981..a39892c10770 100644 --- a/drivers/watchdog/intel_oc_wdt.c +++ b/drivers/watchdog/intel_oc_wdt.c @@ -41,6 +41,7 @@ struct intel_oc_wdt { struct watchdog_device wdd; struct resource *ctrl_res; + struct watchdog_info info; bool locked; }; @@ -115,7 +116,6 @@ static const struct watchdog_ops intel_oc_wdt_ops = { static int intel_oc_wdt_setup(struct intel_oc_wdt *oc_wdt) { - struct watchdog_info *info; unsigned long val; val = inl(INTEL_OC_WDT_CTRL_REG(oc_wdt)); @@ -134,7 +134,6 @@ static int intel_oc_wdt_setup(struct intel_oc_wdt *oc_wdt) set_bit(WDOG_HW_RUNNING, &oc_wdt->wdd.status); if (oc_wdt->locked) { - info = (struct watchdog_info *)&intel_oc_wdt_info; /* * Set nowayout unconditionally as we cannot stop * the watchdog. @@ -145,7 +144,7 @@ static int intel_oc_wdt_setup(struct intel_oc_wdt *oc_wdt) * and inform the core we can't change it. */ oc_wdt->wdd.timeout = (val & INTEL_OC_WDT_TOV) + 1; - info->options &= ~WDIOF_SETTIMEOUT; + oc_wdt->info.options &= ~WDIOF_SETTIMEOUT; dev_info(oc_wdt->wdd.parent, "Register access locked, heartbeat fixed at: %u s\n", @@ -193,7 +192,8 @@ static int intel_oc_wdt_probe(struct platform_device *pdev) wdd->min_timeout = INTEL_OC_WDT_MIN_TOV; wdd->max_timeout = INTEL_OC_WDT_MAX_TOV; wdd->timeout = INTEL_OC_WDT_DEF_TOV; - wdd->info = &intel_oc_wdt_info; + oc_wdt->info = intel_oc_wdt_info; + wdd->info = &oc_wdt->info; wdd->ops = &intel_oc_wdt_ops; wdd->parent = dev; diff --git a/drivers/watchdog/mpc8xxx_wdt.c b/drivers/watchdog/mpc8xxx_wdt.c index 867f9f311379..a4b497ecfa20 100644 --- a/drivers/watchdog/mpc8xxx_wdt.c +++ b/drivers/watchdog/mpc8xxx_wdt.c @@ -100,6 +100,8 @@ static int mpc8xxx_wdt_start(struct watchdog_device *w) ddata->swtc = tmp >> 16; set_bit(WDOG_HW_RUNNING, &ddata->wdd.status); + mpc8xxx_wdt_keepalive(ddata); + return 0; } diff --git a/drivers/watchdog/rzg2l_wdt.c b/drivers/watchdog/rzg2l_wdt.c index 11bbe48160ec..1c9aa366d0a0 100644 --- a/drivers/watchdog/rzg2l_wdt.c +++ b/drivers/watchdog/rzg2l_wdt.c @@ -310,9 +310,7 @@ static int rzg2l_wdt_probe(struct platform_device *pdev) watchdog_set_nowayout(&priv->wdev, nowayout); watchdog_stop_on_unregister(&priv->wdev); - ret = watchdog_init_timeout(&priv->wdev, 0, dev); - if (ret) - dev_warn(dev, "Specified timeout invalid, using default"); + watchdog_init_timeout(&priv->wdev, 0, dev); return devm_watchdog_register_device(&pdev->dev, &priv->wdev); } diff --git a/drivers/watchdog/rzv2h_wdt.c b/drivers/watchdog/rzv2h_wdt.c index 8defd0241213..a694786837e1 100644 --- a/drivers/watchdog/rzv2h_wdt.c +++ b/drivers/watchdog/rzv2h_wdt.c @@ -21,11 +21,17 @@ #define WDTSR 0x04 /* WDT Status Register RW, 16 */ #define WDTRCR 0x06 /* WDT Reset Control Register RW, 8 */ +/* This register is only available on RZ/T2H and RZ/N2H SoCs */ +#define WDTDCR 0x00 /* WDT Debug Control Register RW, 32 */ + #define WDTCR_TOPS_1024 0x00 +#define WDTCR_TOPS_4096 0x01 #define WDTCR_TOPS_16384 0x03 #define WDTCR_CKS_CLK_1 0x00 +#define WDTCR_CKS_CLK_4 0x10 #define WDTCR_CKS_CLK_256 0x50 +#define WDTCR_CKS_CLK_8192 0x80 #define WDTCR_RPES_0 0x300 #define WDTCR_RPES_75 0x000 @@ -35,8 +41,7 @@ #define WDTRCR_RSTIRQS BIT(7) -#define MAX_TIMEOUT_CYCLES 16384 -#define CLOCK_DIV_BY_256 256 +#define WDTDCR_WDTSTOPCTRL BIT(0) #define WDT_DEFAULT_TIMEOUT 60U @@ -45,12 +50,29 @@ module_param(nowayout, bool, 0); MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); +enum rzv2h_wdt_count_source { + COUNT_SOURCE_LOCO, + COUNT_SOURCE_PCLK, +}; + +struct rzv2h_of_data { + u8 cks_min; + u8 cks_max; + u16 cks_div; + u8 tops; + u16 timeout_cycles; + enum rzv2h_wdt_count_source count_source; + bool wdtdcr; +}; + struct rzv2h_wdt_priv { void __iomem *base; + void __iomem *wdtdcr; struct clk *pclk; struct clk *oscclk; struct reset_control *rstc; struct watchdog_device wdev; + const struct rzv2h_of_data *of_data; }; static int rzv2h_wdt_ping(struct watchdog_device *wdev) @@ -67,6 +89,20 @@ static int rzv2h_wdt_ping(struct watchdog_device *wdev) return 0; } +static void rzt2h_wdt_wdtdcr_count_stop(struct rzv2h_wdt_priv *priv) +{ + u32 reg = readl(priv->wdtdcr + WDTDCR); + + writel(reg | WDTDCR_WDTSTOPCTRL, priv->wdtdcr + WDTDCR); +} + +static void rzt2h_wdt_wdtdcr_count_start(struct rzv2h_wdt_priv *priv) +{ + u32 reg = readl(priv->wdtdcr + WDTDCR); + + writel(reg & ~WDTDCR_WDTSTOPCTRL, priv->wdtdcr + WDTDCR); +} + static void rzv2h_wdt_setup(struct watchdog_device *wdev, u16 wdtcr) { struct rzv2h_wdt_priv *priv = watchdog_get_drvdata(wdev); @@ -84,6 +120,7 @@ static void rzv2h_wdt_setup(struct watchdog_device *wdev, u16 wdtcr) static int rzv2h_wdt_start(struct watchdog_device *wdev) { struct rzv2h_wdt_priv *priv = watchdog_get_drvdata(wdev); + const struct rzv2h_of_data *of_data = priv->of_data; int ret; ret = pm_runtime_resume_and_get(wdev->parent); @@ -101,13 +138,20 @@ static int rzv2h_wdt_start(struct watchdog_device *wdev) /* * WDTCR - * - CKS[7:4] - Clock Division Ratio Select - 0101b: oscclk/256 + * - CKS[7:4] - Clock Division Ratio Select + * - 0101b: oscclk/256 for RZ/V2H(P) + * - 1000b: pclkl/8192 for RZ/T2H * - RPSS[13:12] - Window Start Position Select - 11b: 100% * - RPES[9:8] - Window End Position Select - 11b: 0% - * - TOPS[1:0] - Timeout Period Select - 11b: 16384 cycles (3FFFh) + * - TOPS[1:0] - Timeout Period Select + * - 11b: 16384 cycles (3FFFh) for RZ/V2H(P) + * - 01b: 4096 cycles (0FFFh) for RZ/T2H */ - rzv2h_wdt_setup(wdev, WDTCR_CKS_CLK_256 | WDTCR_RPSS_100 | - WDTCR_RPES_0 | WDTCR_TOPS_16384); + rzv2h_wdt_setup(wdev, of_data->cks_max | WDTCR_RPSS_100 | + WDTCR_RPES_0 | of_data->tops); + + if (priv->of_data->wdtdcr) + rzt2h_wdt_wdtdcr_count_start(priv); /* * Down counting starts after writing the sequence 00h -> FFh to the @@ -127,6 +171,9 @@ static int rzv2h_wdt_stop(struct watchdog_device *wdev) if (ret) return ret; + if (priv->of_data->wdtdcr) + rzt2h_wdt_wdtdcr_count_stop(priv); + ret = pm_runtime_put(wdev->parent); if (ret < 0) return ret; @@ -179,14 +226,19 @@ static int rzv2h_wdt_restart(struct watchdog_device *wdev, /* * WDTCR - * - CKS[7:4] - Clock Division Ratio Select - 0000b: oscclk/1 + * - CKS[7:4] - Clock Division Ratio Select + * - 0000b: oscclk/1 for RZ/V2H(P) + * - 0100b: pclkl/4 for RZ/T2H * - RPSS[13:12] - Window Start Position Select - 00b: 25% * - RPES[9:8] - Window End Position Select - 00b: 75% * - TOPS[1:0] - Timeout Period Select - 00b: 1024 cycles (03FFh) */ - rzv2h_wdt_setup(wdev, WDTCR_CKS_CLK_1 | WDTCR_RPSS_25 | + rzv2h_wdt_setup(wdev, priv->of_data->cks_min | WDTCR_RPSS_25 | WDTCR_RPES_75 | WDTCR_TOPS_1024); + if (priv->of_data->wdtdcr) + rzt2h_wdt_wdtdcr_count_start(priv); + rzv2h_wdt_ping(wdev); /* wait for underflow to trigger... */ @@ -203,41 +255,83 @@ static const struct watchdog_ops rzv2h_wdt_ops = { .restart = rzv2h_wdt_restart, }; +static int rzt2h_wdt_wdtdcr_init(struct platform_device *pdev, + struct rzv2h_wdt_priv *priv) +{ + int ret; + + priv->wdtdcr = devm_platform_ioremap_resource(pdev, 1); + if (IS_ERR(priv->wdtdcr)) + return PTR_ERR(priv->wdtdcr); + + ret = pm_runtime_resume_and_get(&pdev->dev); + if (ret) + return ret; + + rzt2h_wdt_wdtdcr_count_stop(priv); + + ret = pm_runtime_put(&pdev->dev); + if (ret < 0) + return ret; + + return 0; +} + static int rzv2h_wdt_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct rzv2h_wdt_priv *priv; + struct clk *count_clk; int ret; priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); if (!priv) return -ENOMEM; + priv->of_data = of_device_get_match_data(dev); + priv->base = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(priv->base)) return PTR_ERR(priv->base); priv->pclk = devm_clk_get_prepared(dev, "pclk"); if (IS_ERR(priv->pclk)) - return dev_err_probe(dev, PTR_ERR(priv->pclk), "no pclk"); + return dev_err_probe(dev, PTR_ERR(priv->pclk), "Failed to get pclk\n"); - priv->oscclk = devm_clk_get_prepared(dev, "oscclk"); + priv->oscclk = devm_clk_get_optional_prepared(dev, "oscclk"); if (IS_ERR(priv->oscclk)) - return dev_err_probe(dev, PTR_ERR(priv->oscclk), "no oscclk"); + return dev_err_probe(dev, PTR_ERR(priv->oscclk), "Failed to get oscclk\n"); - priv->rstc = devm_reset_control_get_exclusive(dev, NULL); + priv->rstc = devm_reset_control_get_optional_exclusive(dev, NULL); if (IS_ERR(priv->rstc)) return dev_err_probe(dev, PTR_ERR(priv->rstc), - "failed to get cpg reset"); + "Failed to get cpg reset\n"); + + switch (priv->of_data->count_source) { + case COUNT_SOURCE_LOCO: + count_clk = priv->oscclk; + break; + case COUNT_SOURCE_PCLK: + count_clk = priv->pclk; + break; + default: + return dev_err_probe(dev, -EINVAL, "Invalid count source\n"); + } - priv->wdev.max_hw_heartbeat_ms = (MILLI * MAX_TIMEOUT_CYCLES * CLOCK_DIV_BY_256) / - clk_get_rate(priv->oscclk); + priv->wdev.max_hw_heartbeat_ms = (MILLI * priv->of_data->timeout_cycles * + priv->of_data->cks_div) / clk_get_rate(count_clk); dev_dbg(dev, "max hw timeout of %dms\n", priv->wdev.max_hw_heartbeat_ms); ret = devm_pm_runtime_enable(dev); if (ret) return ret; + if (priv->of_data->wdtdcr) { + ret = rzt2h_wdt_wdtdcr_init(pdev, priv); + if (ret) + return dev_err_probe(dev, ret, "WDTDCR init failed\n"); + } + priv->wdev.min_timeout = 1; priv->wdev.timeout = WDT_DEFAULT_TIMEOUT; priv->wdev.info = &rzv2h_wdt_ident; @@ -247,15 +341,33 @@ static int rzv2h_wdt_probe(struct platform_device *pdev) watchdog_set_nowayout(&priv->wdev, nowayout); watchdog_stop_on_unregister(&priv->wdev); - ret = watchdog_init_timeout(&priv->wdev, 0, dev); - if (ret) - dev_warn(dev, "Specified timeout invalid, using default"); + watchdog_init_timeout(&priv->wdev, 0, dev); return devm_watchdog_register_device(dev, &priv->wdev); } +static const struct rzv2h_of_data rzt2h_wdt_of_data = { + .cks_min = WDTCR_CKS_CLK_4, + .cks_max = WDTCR_CKS_CLK_8192, + .cks_div = 8192, + .tops = WDTCR_TOPS_4096, + .timeout_cycles = 4096, + .count_source = COUNT_SOURCE_PCLK, + .wdtdcr = true, +}; + +static const struct rzv2h_of_data rzv2h_wdt_of_data = { + .cks_min = WDTCR_CKS_CLK_1, + .cks_max = WDTCR_CKS_CLK_256, + .cks_div = 256, + .tops = WDTCR_TOPS_16384, + .timeout_cycles = 16384, + .count_source = COUNT_SOURCE_LOCO, +}; + static const struct of_device_id rzv2h_wdt_ids[] = { - { .compatible = "renesas,r9a09g057-wdt", }, + { .compatible = "renesas,r9a09g057-wdt", .data = &rzv2h_wdt_of_data }, + { .compatible = "renesas,r9a09g077-wdt", .data = &rzt2h_wdt_of_data }, { /* sentinel */ } }; MODULE_DEVICE_TABLE(of, rzv2h_wdt_ids); diff --git a/drivers/watchdog/s3c2410_wdt.c b/drivers/watchdog/s3c2410_wdt.c index 40901bdac426..b774477190b6 100644 --- a/drivers/watchdog/s3c2410_wdt.c +++ b/drivers/watchdog/s3c2410_wdt.c @@ -27,13 +27,15 @@ #include <linux/mfd/syscon.h> #include <linux/regmap.h> #include <linux/delay.h> +#include <linux/math64.h> #define S3C2410_WTCON 0x00 #define S3C2410_WTDAT 0x04 #define S3C2410_WTCNT 0x08 #define S3C2410_WTCLRINT 0x0c -#define S3C2410_WTCNT_MAXCNT 0xffff +#define S3C2410_WTCNT_MAXCNT_16 0xffff +#define S3C2410_WTCNT_MAXCNT_32 0xffffffff #define S3C2410_WTCON_RSTEN BIT(0) #define S3C2410_WTCON_INTEN BIT(2) @@ -123,6 +125,10 @@ * %QUIRK_HAS_DBGACK_BIT: WTCON register has DBGACK_MASK bit. Setting the * DBGACK_MASK bit disables the watchdog outputs when the SoC is in debug mode. * Debug mode is determined by the DBGACK CPU signal. + * + * %QUIRK_HAS_32BIT_CNT: WTDAT and WTCNT are 32-bit registers. With these + * 32-bit registers, larger values will be set, which means that larger timeouts + * value can be set. */ #define QUIRK_HAS_WTCLRINT_REG BIT(0) #define QUIRK_HAS_PMU_MASK_RESET BIT(1) @@ -130,6 +136,7 @@ #define QUIRK_HAS_PMU_AUTO_DISABLE BIT(3) #define QUIRK_HAS_PMU_CNT_EN BIT(4) #define QUIRK_HAS_DBGACK_BIT BIT(5) +#define QUIRK_HAS_32BIT_CNT BIT(6) /* These quirks require that we have a PMU register map */ #define QUIRKS_HAVE_PMUREG \ @@ -198,6 +205,7 @@ struct s3c2410_wdt { struct notifier_block freq_transition; const struct s3c2410_wdt_variant *drv_data; struct regmap *pmureg; + u32 max_cnt; }; static const struct s3c2410_wdt_variant drv_data_s3c2410 = { @@ -298,7 +306,8 @@ static const struct s3c2410_wdt_variant drv_data_exynosautov9_cl0 = { .cnt_en_reg = EXYNOS850_CLUSTER0_NONCPU_OUT, .cnt_en_bit = 7, .quirks = QUIRK_HAS_WTCLRINT_REG | QUIRK_HAS_PMU_MASK_RESET | - QUIRK_HAS_PMU_RST_STAT | QUIRK_HAS_PMU_CNT_EN, + QUIRK_HAS_PMU_RST_STAT | QUIRK_HAS_PMU_CNT_EN | + QUIRK_HAS_DBGACK_BIT | QUIRK_HAS_32BIT_CNT, }; static const struct s3c2410_wdt_variant drv_data_exynosautov9_cl1 = { @@ -310,7 +319,8 @@ static const struct s3c2410_wdt_variant drv_data_exynosautov9_cl1 = { .cnt_en_reg = EXYNOSAUTOV9_CLUSTER1_NONCPU_OUT, .cnt_en_bit = 7, .quirks = QUIRK_HAS_WTCLRINT_REG | QUIRK_HAS_PMU_MASK_RESET | - QUIRK_HAS_PMU_RST_STAT | QUIRK_HAS_PMU_CNT_EN, + QUIRK_HAS_PMU_RST_STAT | QUIRK_HAS_PMU_CNT_EN | + QUIRK_HAS_DBGACK_BIT | QUIRK_HAS_32BIT_CNT, }; static const struct s3c2410_wdt_variant drv_data_gs101_cl0 = { @@ -349,7 +359,7 @@ static const struct s3c2410_wdt_variant drv_data_exynosautov920_cl0 = { .cnt_en_bit = 8, .quirks = QUIRK_HAS_WTCLRINT_REG | QUIRK_HAS_PMU_MASK_RESET | QUIRK_HAS_PMU_RST_STAT | QUIRK_HAS_PMU_CNT_EN | - QUIRK_HAS_DBGACK_BIT, + QUIRK_HAS_DBGACK_BIT | QUIRK_HAS_32BIT_CNT, }; static const struct s3c2410_wdt_variant drv_data_exynosautov920_cl1 = { @@ -362,7 +372,7 @@ static const struct s3c2410_wdt_variant drv_data_exynosautov920_cl1 = { .cnt_en_bit = 8, .quirks = QUIRK_HAS_WTCLRINT_REG | QUIRK_HAS_PMU_MASK_RESET | QUIRK_HAS_PMU_RST_STAT | QUIRK_HAS_PMU_CNT_EN | - QUIRK_HAS_DBGACK_BIT, + QUIRK_HAS_DBGACK_BIT | QUIRK_HAS_32BIT_CNT, }; static const struct of_device_id s3c2410_wdt_match[] = { @@ -410,9 +420,14 @@ static inline unsigned long s3c2410wdt_get_freq(struct s3c2410_wdt *wdt) static inline unsigned int s3c2410wdt_max_timeout(struct s3c2410_wdt *wdt) { const unsigned long freq = s3c2410wdt_get_freq(wdt); + const u64 n_max = (u64)(S3C2410_WTCON_PRESCALE_MAX + 1) * + S3C2410_WTCON_MAXDIV * wdt->max_cnt; + u64 t_max = div64_ul(n_max, freq); - return S3C2410_WTCNT_MAXCNT / (freq / (S3C2410_WTCON_PRESCALE_MAX + 1) - / S3C2410_WTCON_MAXDIV); + if (t_max > UINT_MAX) + t_max = UINT_MAX; + + return t_max; } static int s3c2410wdt_disable_wdt_reset(struct s3c2410_wdt *wdt, bool mask) @@ -566,7 +581,7 @@ static int s3c2410wdt_set_heartbeat(struct watchdog_device *wdd, { struct s3c2410_wdt *wdt = watchdog_get_drvdata(wdd); unsigned long freq = s3c2410wdt_get_freq(wdt); - unsigned int count; + unsigned long count; unsigned int divisor = 1; unsigned long wtcon; @@ -576,7 +591,7 @@ static int s3c2410wdt_set_heartbeat(struct watchdog_device *wdd, freq = DIV_ROUND_UP(freq, 128); count = timeout * freq; - dev_dbg(wdt->dev, "Heartbeat: count=%d, timeout=%d, freq=%lu\n", + dev_dbg(wdt->dev, "Heartbeat: count=%lu, timeout=%d, freq=%lu\n", count, timeout, freq); /* if the count is bigger than the watchdog register, @@ -584,16 +599,16 @@ static int s3c2410wdt_set_heartbeat(struct watchdog_device *wdd, actually make this value */ - if (count >= 0x10000) { - divisor = DIV_ROUND_UP(count, 0xffff); + if (count > wdt->max_cnt) { + divisor = DIV_ROUND_UP(count, wdt->max_cnt); - if (divisor > 0x100) { + if (divisor > S3C2410_WTCON_PRESCALE_MAX + 1) { dev_err(wdt->dev, "timeout %d too big\n", timeout); return -EINVAL; } } - dev_dbg(wdt->dev, "Heartbeat: timeout=%d, divisor=%d, count=%d (%08x)\n", + dev_dbg(wdt->dev, "Heartbeat: timeout=%d, divisor=%d, count=%lu (%08lx)\n", timeout, divisor, count, DIV_ROUND_UP(count, divisor)); count = DIV_ROUND_UP(count, divisor); @@ -801,6 +816,11 @@ static int s3c2410wdt_probe(struct platform_device *pdev) if (IS_ERR(wdt->src_clk)) return dev_err_probe(dev, PTR_ERR(wdt->src_clk), "failed to get source clock\n"); + if (wdt->drv_data->quirks & QUIRK_HAS_32BIT_CNT) + wdt->max_cnt = S3C2410_WTCNT_MAXCNT_32; + else + wdt->max_cnt = S3C2410_WTCNT_MAXCNT_16; + wdt->wdt_device.min_timeout = 1; wdt->wdt_device.max_timeout = s3c2410wdt_max_timeout(wdt); diff --git a/drivers/watchdog/visconti_wdt.c b/drivers/watchdog/visconti_wdt.c index cef0794708e7..7795e7fbf67e 100644 --- a/drivers/watchdog/visconti_wdt.c +++ b/drivers/watchdog/visconti_wdt.c @@ -118,7 +118,6 @@ static int visconti_wdt_probe(struct platform_device *pdev) struct visconti_wdt_priv *priv; struct device *dev = &pdev->dev; struct clk *clk; - int ret; unsigned long clk_freq; priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); @@ -153,9 +152,7 @@ static int visconti_wdt_probe(struct platform_device *pdev) watchdog_stop_on_unregister(wdev); /* This overrides the default timeout only if DT configuration was found */ - ret = watchdog_init_timeout(wdev, 0, dev); - if (ret) - dev_warn(dev, "Specified timeout value invalid, using default\n"); + watchdog_init_timeout(wdev, 0, dev); return devm_watchdog_register_device(dev, wdev); } |