clk/qcom: introduce debugcc

debugcc is a tool for debugging the clock controllers on Qualcomm SoCs.
It uses the built-in clock debugging registers to measure clock rates by
muxing clocks to a special debug mux.

This is a port of the userspace tool [1], as it is plain C and only
depends on getopt, only minimal changes are necessary to integrate it
into u-boot. The main addition is a substring search to filter which
clocks are measured as this is quite useful when running on-device.

Import debugcc and plumb it up to the "clk debug" command.

[1]: https://github.com/andersson/debugcc

Signed-off-by: Caleb Connolly <caleb.connolly@linaro.org>
diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig
index 6f84800..6580c18 100644
--- a/drivers/clk/qcom/Kconfig
+++ b/drivers/clk/qcom/Kconfig
@@ -73,4 +73,15 @@
 
 endmenu
 
+config CLK_QCOM_DEBUG
+	bool "Enable Qualcomm clock debugging"
+	depends on ARCH_SNAPDRAGON
+	select CMD_CLK
+	help
+	  Enable support for debugging the Qualcomm Global Clock
+	  Controller on supported platforms. The hardware implements
+	  the ability to measure the output rates of most clocks, so
+	  that clock configurations can be validated. Use the "clk debug"
+	  command.
+
 endif
diff --git a/drivers/clk/qcom/Makefile b/drivers/clk/qcom/Makefile
index f7fc8b9..a2dd6b8 100644
--- a/drivers/clk/qcom/Makefile
+++ b/drivers/clk/qcom/Makefile
@@ -11,3 +11,5 @@
 obj-$(CONFIG_CLK_QCOM_QCS404) += clock-qcs404.o
 obj-$(CONFIG_CLK_QCOM_SM6115) += clock-sm6115.o
 obj-$(CONFIG_CLK_QCOM_SM8250) += clock-sm8250.o
+
+obj-$(CONFIG_CLK_QCOM_DEBUG) += debugcc/
diff --git a/drivers/clk/qcom/clock-qcom.c b/drivers/clk/qcom/clock-qcom.c
index c880df2..3081763 100644
--- a/drivers/clk/qcom/clock-qcom.c
+++ b/drivers/clk/qcom/clock-qcom.c
@@ -26,6 +26,8 @@
 
 #include "clock-qcom.h"
 
+#include "debugcc/debugcc.h"
+
 /* CBCR register fields */
 #define CBCR_BRANCH_ENABLE_BIT  BIT(0)
 #define CBCR_BRANCH_OFF_BIT     BIT(31)
@@ -365,10 +367,21 @@
 	dump_rcgs();
 }
 
+static void msm_debug_clks(struct udevice *dev, int argc, char *const argv[])
+{
+	if (!IS_ENABLED(CONFIG_CLK_QCOM_DEBUG)) {
+		printf("Enable CONFIG_CLK_QCOM_DEBUG to debug GCC\n");
+		return;
+	}
+
+	qcom_debugcc_run(argc, argv);
+}
+
 static struct clk_ops msm_clk_ops = {
 	.set_rate = msm_clk_set_rate,
 	.enable = msm_clk_enable,
 	.dump_clks = msm_dump_clks,
+	.debug_clks = msm_debug_clks,
 };
 
 U_BOOT_DRIVER(qcom_clk) = {
diff --git a/drivers/clk/qcom/debugcc/Makefile b/drivers/clk/qcom/debugcc/Makefile
new file mode 100644
index 0000000..d256968
--- /dev/null
+++ b/drivers/clk/qcom/debugcc/Makefile
@@ -0,0 +1,9 @@
+# SPDX-License-Identifier: GPL-2.0+
+#
+# (C) Copyright 2023 Linaro
+
+obj-y += debugcc.o
+obj-y += qcs404.o
+obj-y += sdm845.o
+obj-y += sm6115.o
+obj-y += sm8250.o
diff --git a/drivers/clk/qcom/debugcc/debugcc.c b/drivers/clk/qcom/debugcc/debugcc.c
new file mode 100644
index 0000000..6e2a277
--- /dev/null
+++ b/drivers/clk/qcom/debugcc/debugcc.c
@@ -0,0 +1,377 @@
+/*
+ * Copyright (c) 2019, Linaro Ltd.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its contributors
+ * may be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+#include <dm/device.h>
+#include <errno.h>
+#include <stdbool.h>
+#include <getopt.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <string.h>
+#include <asm/io.h>
+
+#include "debugcc.h"
+
+static const struct debugcc_platform *platforms[] = {
+	&qcs404_debugcc,
+	&sdm845_debugcc,
+	&sm6115_debugcc,
+	&sm8250_debugcc,
+	NULL
+};
+
+static unsigned int measure_ticks(struct debug_mux *gcc, unsigned int ticks)
+{
+	uint32_t val;
+
+	writel(ticks, gcc->base + gcc->debug_ctl_reg);
+	do {
+		val = readl(gcc->base + gcc->debug_status_reg);
+	} while (val & BIT(25));
+
+	writel(ticks | BIT(20), gcc->base + gcc->debug_ctl_reg);
+	do {
+		val = readl(gcc->base + gcc->debug_status_reg);
+	} while (!(val & BIT(25)));
+
+	val &= 0x1ffffff;
+
+	writel(ticks, gcc->base + gcc->debug_ctl_reg);
+
+	return val;
+}
+
+static void mux_prepare_enable(struct debug_mux *mux, int selector)
+{
+	uint32_t val;
+
+	if (mux->mux_mask) {
+		val = readl(mux->base + mux->mux_reg);
+		val &= ~mux->mux_mask;
+		val |= selector << mux->mux_shift;
+		writel(val, mux->base + mux->mux_reg);
+	}
+
+	if (mux->div_mask) {
+		val = readl(mux->base + mux->div_reg);
+		val &= ~mux->div_mask;
+		val |= (mux->div_val - 1) << mux->div_shift;
+		writel(val, mux->base + mux->div_reg);
+	}
+
+	mux_enable(mux);
+}
+
+void mux_enable(struct debug_mux *mux)
+{
+	uint32_t val;
+
+	if (mux->enable_mask) {
+		val = readl(mux->base + mux->enable_reg);
+		val |= mux->enable_mask;
+		writel(val, mux->base + mux->enable_reg);
+	}
+
+	if (mux->premeasure)
+		mux->premeasure(mux);
+}
+
+void mux_disable(struct debug_mux *mux)
+{
+	uint32_t val;
+
+	if (mux->postmeasure)
+		mux->postmeasure(mux);
+
+	if (mux->enable_mask) {
+		val = readl(mux->base + mux->enable_reg);
+		val &= ~mux->enable_mask;
+		writel(val, mux->base + mux->enable_reg);
+	}
+}
+
+static bool leaf_enabled(struct debug_mux *mux, struct debug_mux *leaf)
+{
+	uint32_t val;
+
+	/* If no AHB clock is specified, we assume it's clocked */
+	if (!leaf || !leaf->ahb_mask)
+		return true;
+
+	val = readl(mux->base + leaf->ahb_reg);
+	val &= leaf->ahb_mask;
+
+	/* CLK_OFF will be set if block is not clocked, so inverse */
+	return !val;
+}
+
+static unsigned long measure_default(const struct measure_clk *clk)
+{
+	unsigned long raw_count_short;
+	unsigned long raw_count_full;
+	struct debug_mux *gcc = clk->primary;
+	unsigned long xo_div4;
+
+	xo_div4 = readl(gcc->base + gcc->xo_div4_reg);
+	writel(xo_div4 | 1, gcc->base + gcc->xo_div4_reg);
+
+	raw_count_short = measure_ticks(gcc, 0x1000);
+	raw_count_full = measure_ticks(gcc, 0x10000);
+
+	writel(xo_div4, gcc->base + gcc->xo_div4_reg);
+
+	if (raw_count_full == raw_count_short) {
+		return 0;
+	}
+
+	raw_count_full = ((raw_count_full * 10) + 15) * 4800000;
+	raw_count_full = raw_count_full / ((0x10000 * 10) + 35);
+
+	if (clk->leaf && clk->leaf->div_val)
+		raw_count_full *= clk->leaf->div_val;
+
+	if (clk->primary->div_val)
+		raw_count_full *= clk->primary->div_val;
+
+	if (clk->fixed_div)
+		raw_count_full *= clk->fixed_div;
+
+
+	return raw_count_full;
+}
+
+unsigned long measure_mccc(const struct measure_clk *clk)
+{
+	/* MCCC is always on, just read the rate and return. */
+	return 1000000000000ULL / readl(clk->leaf->base + clk->leaf_mux);
+}
+
+static void measure(const struct measure_clk *clk)
+{
+	unsigned long clk_rate;
+	struct debug_mux *gcc = clk->primary;
+
+	if (clk->leaf)
+		printf("| %-8s ", clk->leaf->block_name);
+	else
+		printf("| %-8s ", "core");
+
+	if (!leaf_enabled(gcc, clk->leaf)) {
+		printf("| %-40s | %7s | %-13s |\n", clk->name, "SKIP", "");
+		return;
+	}
+
+	if (clk->leaf)
+		mux_prepare_enable(clk->leaf, clk->leaf_mux);
+
+	mux_prepare_enable(clk->primary, clk->mux);
+
+	if (clk->leaf && clk->leaf->measure)
+		clk_rate = clk->leaf->measure(clk);
+	else
+		clk_rate = measure_default(clk);
+
+	mux_disable(clk->primary);
+
+	if (clk->leaf) {
+		mux_disable(clk->leaf);
+	}
+
+	if (clk_rate == 0) {
+		printf("| %-40s | %7s | %-13s |\n", clk->name, "OFF", "");
+		return;
+	}
+
+	printf("| %-40s | %4luMHz | %11ldHz |\n", clk->name, DIV_ROUND_CLOSEST(clk_rate, 1000000), clk_rate);
+}
+
+static const struct debugcc_platform *find_platform(void)
+{
+	const struct debugcc_platform **p;
+	const char **compatibles, *name;
+
+	if (ofnode_read_string_list(ofnode_root(), "compatible", &compatibles) < 0) {
+		fprintf(stderr, "Can't get root compatible!\n");
+		return NULL;
+	}
+	/* Get the last compatible in the list */
+	while (compatibles[1]) compatibles++;
+	name = compatibles[0];
+	while (*name++ != ',') {
+		if (*name == '\0') {
+			fprintf(stderr, "Compatible '%s' doesn't match 'qcom,platform' format!\n", compatibles[0]);
+			return NULL;
+		}
+	}
+
+	for (p = platforms; *p; p++) {
+		if (!strcmp((*p)->name, name))
+			return *p;
+	}
+
+	return NULL;
+}
+
+static const struct measure_clk *find_clock(const struct debugcc_platform *platform,
+					    const char *name)
+{
+	const struct measure_clk *clk;
+
+	for (clk = platform->clocks; clk->name; clk++) {
+		if (!strcmp(clk->name, name))
+			return clk;
+	}
+
+	return NULL;
+}
+
+static bool clock_from_block(const struct measure_clk *clk, const char *block_name)
+{
+	return  !block_name ||
+		(!clk->leaf && !strcmp(block_name, CORE_CC_BLOCK)) ||
+		(clk->leaf && clk->leaf->block_name && !strcmp(block_name, clk->leaf->block_name));
+}
+
+static void list_clocks_block(const struct debugcc_platform *platform, const char *block_name)
+{
+	const struct measure_clk *clk;
+
+	for (clk = platform->clocks; clk->name; clk++) {
+		if (!clock_from_block(clk, block_name))
+			continue;
+
+		if (clk->leaf && clk->leaf->block_name)
+			printf("%-40s %s\n", clk->name, clk->leaf->block_name);
+		else
+			printf("%s\n", clk->name);
+	}
+}
+
+static void list_blocks(const struct debugcc_platform *platform)
+{
+	const struct debug_mux **mux;
+
+	printf("Available blocks:\n");
+	for (mux = platform->blocks; *mux; mux++) {
+		if (!(*mux)->block_name)
+			printf(" - core\n");
+		else
+			printf(" - %s\n", (*mux)->block_name);
+	}
+}
+
+static int usage(void)
+{
+
+	fprintf(stderr, "clk debug qcom_clk [-b blk] <-a | -l | -s needle | clk>\n");
+	fprintf(stderr, "\n");
+
+	return -EINVAL;
+}
+
+int qcom_debugcc_run(int argc, char *const argv[])
+{
+	const struct debugcc_platform *platform = NULL;
+	const struct measure_clk *clk = NULL;
+	bool do_list_clocks = false;
+	bool all_clocks = false;
+	const char *block_name = NULL;
+	const char *search = NULL;
+	struct getopt_state gs;
+	int opt;
+
+	platform = find_platform();
+	if (!platform) {
+		printf("Couldn't find platform for board\n");
+		return -ENODEV;
+	}
+
+	getopt_init_state(&gs);
+
+	while ((opt = getopt(&gs, argc, argv, "ab:ls:")) != -1) {
+		switch (opt) {
+		case 'a':
+			all_clocks = true;
+			break;
+		case 'b':
+			block_name = gs.arg;
+			break;
+		case 'l':
+			do_list_clocks = true;
+			break;
+		case 's':
+			search = gs.arg;
+			break;
+		case ':':
+			usage();
+			if (gs.opt == 'b') {
+				list_blocks(platform);
+			}
+			return 0;
+		default:
+			return usage();
+			/* NOTREACHED */
+		}
+	}
+
+	if (do_list_clocks) {
+		list_clocks_block(platform, block_name);
+		return 0;
+	}
+
+	if (!all_clocks && !search) {
+		if (gs.index >= argc) {
+			printf("index %d argc %d\n", gs.index, argc);
+			return usage();
+		}
+
+		for (; gs.index < argc; gs.index++) {
+			clk = find_clock(platform, argv[gs.index]);
+			if (!clk) {
+				fprintf(stderr, "no clock named \"%s\"\n", argv[gs.index]);
+				return -EINVAL;
+			}
+		}
+	}
+
+	printf("| %-8s | %-40s | %-7s | %-13s |\n", "BLOCK", "CLOCK", "MHz", "Hz");
+	printf("+----------+------------------------------------------+---------+---------------+\n");
+	if (clk) {
+		measure(clk);
+	} else {
+		for (clk = platform->clocks; clk->name; clk++) {
+			if (clock_from_block(clk, block_name) && (!search || strstr(clk->name, search))) {
+				measure(clk);
+			}
+		}
+	}
+
+	return 0;
+}
diff --git a/drivers/clk/qcom/debugcc/debugcc.h b/drivers/clk/qcom/debugcc/debugcc.h
new file mode 100644
index 0000000..f8fd6ac
--- /dev/null
+++ b/drivers/clk/qcom/debugcc/debugcc.h
@@ -0,0 +1,103 @@
+/*
+ * Copyright (c) 2019, Linaro Ltd.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its contributors
+ * may be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+#ifndef __DEBUGCC_H__
+#define __DEBUGCC_H__
+
+#include <linux/bitops.h>
+#include <linux/types.h>
+
+#define CORE_CC_BLOCK "core"
+
+struct measure_clk;
+
+struct debug_mux {
+	unsigned long base;
+	const char *block_name;
+	size_t size;
+
+	unsigned int enable_reg;
+	unsigned int enable_mask;
+
+	unsigned int mux_reg;
+	unsigned int mux_mask;
+	unsigned int mux_shift;
+
+	unsigned int div_reg;
+	unsigned int div_shift;
+	unsigned int div_mask;
+	unsigned int div_val;
+
+	unsigned int xo_div4_reg;
+	unsigned int debug_ctl_reg;
+	unsigned int debug_status_reg;
+
+	unsigned int ahb_reg;
+	unsigned int ahb_mask;
+
+	void (*premeasure)(struct debug_mux *mux);
+	unsigned long (*measure)(const struct measure_clk *clk);
+	void (*postmeasure)(struct debug_mux *mux);
+};
+
+struct measure_clk {
+	char *name;
+	struct debug_mux *primary;
+	int mux;
+
+	struct debug_mux *leaf;
+	int leaf_mux;
+
+	unsigned int fixed_div;
+};
+
+struct debugcc_platform {
+	const char *name;
+	const struct measure_clk *clocks;
+	const struct debug_mux **blocks;
+};
+
+#ifdef CONFIG_CLK_QCOM_DEBUG
+int qcom_debugcc_run(int argc, char *const argv[]);
+
+int mmap_mux(int devmem, struct debug_mux *mux);
+void mux_enable(struct debug_mux *mux);
+void mux_disable(struct debug_mux *mux);
+unsigned long measure_mccc(const struct measure_clk *clk);
+
+extern struct debugcc_platform qcs404_debugcc;
+extern struct debugcc_platform sdm845_debugcc;
+extern struct debugcc_platform sm6115_debugcc;
+extern struct debugcc_platform sm8250_debugcc;
+#else
+int qcom_debugcc_run(int argc, char *const argv[]) { return 0; }
+#endif
+
+#endif
diff --git a/drivers/clk/qcom/debugcc/qcs404.c b/drivers/clk/qcom/debugcc/qcs404.c
new file mode 100644
index 0000000..4a8ce92
--- /dev/null
+++ b/drivers/clk/qcom/debugcc/qcs404.c
@@ -0,0 +1,202 @@
+/*
+ * Copyright (c) 2019, Linaro Ltd.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its contributors
+ * may be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+#include <errno.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "debugcc.h"
+
+#define GCC_BASE	0x01800000
+#define GCC_SIZE	0x80000
+
+#define GCC_DEBUG_CLK_CTL		0x74000
+#define GCC_CLOCK_FREQ_MEASURE_CTL	0x74004
+#define GCC_CLOCK_FREQ_MEASURE_STATUS	0x74008
+#define GCC_XO_DIV4_CBCR		0x30034
+
+static struct debug_mux gcc;
+
+static struct debug_mux gcc = {
+	.base =	GCC_BASE,
+	.size = GCC_SIZE,
+
+	.enable_reg = GCC_DEBUG_CLK_CTL,
+	.enable_mask = BIT(16),
+
+	.mux_reg = GCC_DEBUG_CLK_CTL,
+	.mux_mask = 0x1ff,
+
+	.div_reg = GCC_DEBUG_CLK_CTL,
+	.div_shift = 12,
+	.div_mask = 0xf << 12,
+	.div_val = 4,
+
+	.xo_div4_reg = GCC_XO_DIV4_CBCR,
+	.debug_ctl_reg = GCC_CLOCK_FREQ_MEASURE_CTL,
+	.debug_status_reg = GCC_CLOCK_FREQ_MEASURE_STATUS,
+};
+
+static struct debug_mux turing = {
+	.base = 0x800000,
+	.size = 0x30000,
+
+	.enable_reg = 0x22008,
+	.enable_mask = BIT(0),
+
+	.mux_reg = 0x22000,
+	.mux_mask = 0xffff,
+
+	.div_mask = 0,
+
+	.ahb_reg = 0x5e004,
+	.ahb_mask = BIT(31),
+};
+
+static const struct debug_mux *qcs404_blocks[] = {
+	&gcc,
+	&turing,
+	NULL,
+};
+
+static struct measure_clk qcs404_clocks[] = {
+	{ "snoc_clk", &gcc, 0 },
+	{ "gcc_sys_noc_usb3_clk", &gcc, 1 },
+	{ "pnoc_clk", &gcc, 8 },
+	{ "gcc_pcnoc_usb2_clk", &gcc, 9 },
+	{ "gcc_pcnoc_usb3_clk", &gcc, 10 },
+	{ "gcc_gp1_clk", &gcc, 16 },
+	{ "gcc_gp2_clk", &gcc, 17 },
+	{ "gcc_gp3_clk", &gcc, 18 },
+	{ "gcc_bimc_gfx_clk", &gcc, 45 },
+	{ "aon_clk_src", &gcc, 50, &turing, 1},
+	{ "turing_wrapper_aon_clk", &gcc, 50, &turing, 2},
+	{ "turing_wrapper_cnoc_sway_aon_clk", &gcc, 50, &turing, 3},
+	{ "turing_wrapper_qos_ahbs_aon_clk", &gcc, 50, &turing, 4},
+	{ "q6ss_ahbm_aon_clk", &gcc, 50, &turing, 5},
+	{ "q6ss_ahbs_aon_clk", &gcc, 50, &turing, 6},
+	{ "turing_wrapper_bus_timeout_aon_clk", &gcc, 50, &turing, 7},
+	{ "turing_wrapper_rscc_aon_clk", &gcc, 50, &turing, 8},
+	{ "q6ss_alt_reset_aon_clk", &gcc, 50, &turing, 10},
+	{ "qos_fixed_lat_counter_clk_src", &gcc, 50, &turing, 11},
+	{ "turing_wrapper_qos_dmonitor_fixed_lat_counter_clk", &gcc, 50, &turing, 12},
+	{ "turing_wrapper_qos_danger_fixed_lat_counter_clk", &gcc, 50, &turing, 13},
+	{ "q6_xo_clk_src", &gcc, 50, &turing, 14},
+	{ "qos_xo_clk_src", &gcc, 50, &turing, 15},
+	{ "turing_wrapper_qos_xo_lat_counter_clk", &gcc, 50, &turing, 16},
+	{ "bcr_slp_clk_src", &gcc, 50, &turing, 19},
+	{ "q6ss_bcr_slp_clk", &gcc, 50, &turing, 20},
+	{ "turing_wrapper_cnoc_ahbs_clk", &gcc, 50, &turing, 28},
+	{ "q6ss_q6_axim_clk", &gcc, 50, &turing, 29},
+	{ "q6ss_sleep_clk_src", &gcc, 50, &turing, 33},
+	{ "qdsp6ss_xo_clk", &gcc, 50, &turing, 36},
+	{ "qdsp6ss_sleep_clk", &gcc, 50, &turing, 37},
+	{ "q6ss_dbg_in_clk", &gcc, 50, &turing, 39},
+	{ "gcc_usb_hs_system_clk", &gcc, 96 },
+	{ "gcc_usb_hs_inactivity_timers_clk", &gcc, 98 },
+	{ "gcc_usb2a_phy_sleep_clk", &gcc, 99 },
+	{ "gcc_usb_hs_phy_cfg_ahb_clk", &gcc, 100 },
+	{ "gcc_usb20_mock_utmi_clk", &gcc, 101 },
+	{ "gcc_sdcc1_apps_clk", &gcc, 104 },
+	{ "gcc_sdcc1_ahb_clk", &gcc, 105 },
+	{ "gcc_sdcc1_ice_core_clk", &gcc, 106 },
+	{ "gcc_sdcc2_apps_clk", &gcc, 112 },
+	{ "gcc_sdcc2_ahb_clk", &gcc, 113 },
+	{ "gcc_usb30_master_clk", &gcc, 120 },
+	{ "gcc_usb30_sleep_clk", &gcc, 121 },
+	{ "gcc_usb30_mock_utmi_clk", &gcc, 122 },
+	{ "gcc_usb3_phy_pipe_clk", &gcc, 123 },
+	{ "gcc_usb3_phy_aux_clk", &gcc, 124 },
+	{ "gcc_eth_axi_clk", &gcc, 128 },
+	{ "gcc_eth_rgmii_clk", &gcc, 129 },
+	{ "gcc_eth_slave_ahb_clk", &gcc, 130 },
+	{ "gcc_eth_ptp_clk", &gcc, 131 },
+	{ "gcc_blsp1_ahb_clk", &gcc, 136 },
+	{ "gcc_blsp1_qup1_spi_apps_clk", &gcc, 138 },
+	{ "wcnss_m_clk", &gcc, 138 },
+	{ "gcc_blsp1_qup1_i2c_apps_clk", &gcc, 139 },
+	{ "gcc_blsp1_uart1_apps_clk", &gcc, 140 },
+	{ "gcc_blsp1_qup2_spi_apps_clk", &gcc, 142 },
+	{ "gcc_blsp1_qup2_i2c_apps_clk", &gcc, 143 },
+	{ "gcc_blsp1_uart2_apps_clk", &gcc, 144 },
+	{ "gcc_blsp1_qup3_spi_apps_clk", &gcc, 146 },
+	{ "gcc_blsp1_qup3_i2c_apps_clk", &gcc, 147 },
+	{ "gcc_blsp1_qup4_spi_apps_clk", &gcc, 148 },
+	{ "gcc_blsp1_qup4_i2c_apps_clk", &gcc, 149 },
+	{ "gcc_blsp1_uart3_apps_clk", &gcc, 150 },
+	{ "gcc_blsp1_qup0_spi_apps_clk", &gcc, 152 },
+	{ "gcc_blsp1_qup0_i2c_apps_clk", &gcc, 153 },
+	{ "gcc_blsp1_uart0_apps_clk", &gcc, 154 },
+	{ "gcc_blsp2_ahb_clk", &gcc, 160 },
+	{ "gcc_blsp2_qup0_i2c_apps_clk", &gcc, 162 },
+	{ "gcc_blsp2_qup0_spi_apps_clk", &gcc, 163 },
+	{ "gcc_blsp2_uart0_apps_clk", &gcc, 164 },
+	{ "gcc_pcie_0_slv_axi_clk", &gcc, 168 },
+	{ "gcc_pcie_0_mstr_axi_clk", &gcc, 169 },
+	{ "gcc_pcie_0_cfg_ahb_clk", &gcc, 170 },
+	{ "gcc_pcie_0_aux_clk", &gcc, 171 },
+	{ "gcc_pcie_0_pipe_clk", &gcc, 172 },
+	//{ "pcie0_pipe_clk", &gcc, 173, 1 },
+	{ "qpic_clk", &gcc, 192 },
+	{ "gcc_pdm_ahb_clk", &gcc, 208 },
+	{ "gcc_pdm2_clk", &gcc, 210 },
+	{ "gcc_pwm0_xo512_clk", &gcc, 211 },
+	{ "gcc_pwm1_xo512_clk", &gcc, 212 },
+	{ "gcc_pwm2_xo512_clk", &gcc, 213 },
+	{ "gcc_prng_ahb_clk", &gcc, 216 },
+	{ "gcc_geni_ir_s_clk", &gcc, 238 },
+	{ "gcc_boot_rom_ahb_clk", &gcc, 248 },
+	{ "ce1_clk", &gcc, 312 },
+	{ "bimc_clk", &gcc, 346 },
+	//{ "bimc_fsm_ddr_clk", &gcc, 350, 1 },
+	{ "gcc_apss_ahb_clk", &gcc, 360 },
+	{ "gcc_dcc_clk", &gcc, 441 },
+	{ "gcc_oxili_gfx3d_clk", &gcc, 490 },
+	{ "gcc_oxili_ahb_clk", &gcc, 491 },
+	{ "gcc_mdss_hdmi_pclk_clk", &gcc, 497 },
+	{ "gcc_mdss_hdmi_app_clk", &gcc, 498 },
+	{ "gcc_mdss_ahb_clk", &gcc, 502 },
+	{ "gcc_mdss_axi_clk", &gcc, 503 },
+	{ "gcc_mdss_pclk0_clk", &gcc, 504 },
+	{ "gcc_mdss_mdp_clk", &gcc, 505 },
+	{ "gcc_mdss_vsync_clk", &gcc, 507 },
+	{ "gcc_mdss_byte0_clk", &gcc, 508 },
+	{ "gcc_mdss_esc0_clk", &gcc, 509 },
+	{}
+};
+
+struct debugcc_platform qcs404_debugcc = {
+	"qcs404",
+	qcs404_clocks,
+	qcs404_blocks,
+};
diff --git a/drivers/clk/qcom/debugcc/sdm845.c b/drivers/clk/qcom/debugcc/sdm845.c
new file mode 100644
index 0000000..7c28b0b
--- /dev/null
+++ b/drivers/clk/qcom/debugcc/sdm845.c
@@ -0,0 +1,408 @@
+/*
+ * Copyright (c) 2019, Linaro Ltd.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its contributors
+ * may be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "debugcc.h"
+
+#define GCC_BASE	0x100000
+#define GCC_SIZE	0x1f0000
+
+#define GCC_DEBUG_POST_DIV		0x62000
+#define GCC_DEBUG_CBCR			0x62004
+#define GCC_DEBUG_OFFSET		0x62008
+#define GCC_DEBUG_CTL			0x62024
+#define GCC_DEBUG_STATUS		0x62028
+#define GCC_XO_DIV4_CBCR		0x43008
+
+static struct debug_mux gcc = {
+	.base =	GCC_BASE,
+	.size = GCC_SIZE,
+
+	.enable_reg = GCC_DEBUG_CBCR,
+	.enable_mask = BIT(0),
+
+	.mux_reg = GCC_DEBUG_OFFSET,
+	.mux_mask = 0x3ff,
+
+	.div_reg = GCC_DEBUG_POST_DIV,
+	.div_mask = 0xf,
+	.div_val = 4,
+
+	.xo_div4_reg = GCC_XO_DIV4_CBCR,
+	.debug_ctl_reg = GCC_DEBUG_CTL,
+	.debug_status_reg = GCC_DEBUG_STATUS,
+};
+
+static struct debug_mux cam_cc = {
+	.base = 0xad00000,
+	.size = 0x10000,
+	.block_name = "cam",
+
+	.enable_reg = 0xc008,
+	.enable_mask = BIT(0),
+
+	.mux_reg = 0xc000,
+	.mux_mask = 0xff,
+
+	.div_reg = 0xc004,
+	.div_mask = 0x3,
+};
+
+static struct debug_mux cpu = {
+	.base = 0x17970000,
+	.size = 4096,
+	.block_name = "cpu",
+
+	.enable_reg = 0x18,
+	.enable_mask = BIT(0),
+
+	.mux_reg = 0x18,
+	.mux_mask = 0x7f << 4,
+	.mux_shift = 4,
+
+	.div_reg = 0x18,
+	.div_mask = 0xf << 11,
+	.div_shift = 11,
+};
+
+static struct debug_mux disp_cc = {
+	.base = 0xaf00000,
+	.size = 0x10000,
+	.block_name = "disp",
+
+	.enable_reg = 0x600c,
+	.enable_mask = BIT(0),
+
+	.mux_reg = 0x6000,
+	.mux_mask = 0xff,
+
+	.div_reg = 0x6008,
+	.div_mask = 0x3,
+};
+
+static struct debug_mux gpu_cc = {
+	.base = 0x5090000,
+	.size = 0x9000,
+	.block_name = "gpu",
+
+	.enable_reg = 0x1100,
+	.enable_mask = BIT(0),
+
+	.mux_reg = 0x1568,
+	.mux_mask = 0xff,
+
+	.div_reg = 0x10fc,
+	.div_mask = 0x3,
+};
+
+static struct debug_mux video_cc = {
+	.base = 0xab00000,
+	.size = 0x10000,
+	.block_name = "video",
+
+	.enable_reg = 0xa58,
+	.enable_mask = BIT(0),
+
+	.mux_reg = 0xa4c,
+	.mux_mask = 0x3f,
+
+	.div_reg = 0xa50,
+	.div_mask = 0x7,
+};
+
+static const struct debug_mux *sdm845_blocks[] = {
+	&gcc,
+	&cam_cc,
+	&cpu,
+	&disp_cc,
+	&gpu_cc,
+	&video_cc,
+	NULL,
+};
+
+static struct measure_clk sdm845_clocks[] = {
+	{ "measure_only_snoc_clk", &gcc, 7 },
+	{ "gcc_sys_noc_cpuss_ahb_clk", &gcc, 12 },
+	{ "measure_only_cnoc_clk", &gcc, 21 },
+	{ "gcc_cfg_noc_usb3_prim_axi_clk", &gcc, 29 },
+	{ "gcc_cfg_noc_usb3_sec_axi_clk", &gcc, 30 },
+	{ "gcc_aggre_noc_pcie_tbu_clk", &gcc, 45 },
+	{ "gcc_video_ahb_clk", &gcc, 57 },
+	{ "gcc_camera_ahb_clk", &gcc, 58 },
+	{ "gcc_disp_ahb_clk", &gcc, 59 },
+	{ "gcc_qmip_video_ahb_clk", &gcc, 60 },
+	{ "gcc_qmip_camera_ahb_clk", &gcc, 61 },
+	{ "gcc_qmip_disp_ahb_clk", &gcc, 62 },
+	{ "gcc_video_axi_clk", &gcc, 63 },
+	{ "gcc_camera_axi_clk", &gcc, 64 },
+	{ "gcc_disp_axi_clk", &gcc, 65 },
+	{ "gcc_video_xo_clk", &gcc, 66 },
+	{ "gcc_camera_xo_clk", &gcc, 67 },
+	{ "gcc_disp_xo_clk", &gcc, 68 },
+	{ "cam_cc_mclk0_clk", &gcc, 70, &cam_cc, 1 },
+	{ "cam_cc_mclk1_clk", &gcc, 70, &cam_cc, 2 },
+	{ "cam_cc_mclk2_clk", &gcc, 70, &cam_cc, 3 },
+	{ "cam_cc_mclk3_clk", &gcc, 70, &cam_cc, 4 },
+	{ "cam_cc_csi0phytimer_clk", &gcc, 70, &cam_cc, 5 },
+	{ "cam_cc_csiphy0_clk", &gcc, 70, &cam_cc, 6 },
+	{ "cam_cc_csi1phytimer_clk", &gcc, 70, &cam_cc, 7 },
+	{ "cam_cc_csiphy1_clk", &gcc, 70, &cam_cc, 8 },
+	{ "cam_cc_csi2phytimer_clk", &gcc, 70, &cam_cc, 9 },
+	{ "cam_cc_csiphy2_clk", &gcc, 70, &cam_cc, 10 },
+	{ "cam_cc_bps_clk", &gcc, 70, &cam_cc, 11 },
+	{ "cam_cc_bps_axi_clk", &gcc, 70, &cam_cc, 12 },
+	{ "cam_cc_bps_areg_clk", &gcc, 70, &cam_cc, 13 },
+	{ "cam_cc_bps_ahb_clk", &gcc, 70, &cam_cc, 14 },
+	{ "cam_cc_ipe_0_clk", &gcc, 70, &cam_cc, 15 },
+	{ "cam_cc_ipe_0_axi_clk", &gcc, 70, &cam_cc, 16 },
+	{ "cam_cc_ipe_0_areg_clk", &gcc, 70, &cam_cc, 17 },
+	{ "cam_cc_ipe_0_ahb_clk", &gcc, 70, &cam_cc, 18 },
+	{ "cam_cc_ipe_1_clk", &gcc, 70, &cam_cc, 19 },
+	{ "cam_cc_ipe_1_axi_clk", &gcc, 70, &cam_cc, 20 },
+	{ "cam_cc_ipe_1_areg_clk", &gcc, 70, &cam_cc, 21 },
+	{ "cam_cc_ipe_1_ahb_clk", &gcc, 70, &cam_cc, 22 },
+	{ "cam_cc_ife_0_clk", &gcc, 70, &cam_cc, 23 },
+	{ "cam_cc_ife_0_dsp_clk", &gcc, 70, &cam_cc, 24 },
+	{ "cam_cc_ife_0_csid_clk", &gcc, 70, &cam_cc, 25 },
+	{ "cam_cc_ife_0_cphy_rx_clk", &gcc, 70, &cam_cc, 26 },
+	{ "cam_cc_ife_0_axi_clk", &gcc, 70, &cam_cc, 27 },
+	{ "cam_cc_ife_1_clk", &gcc, 70, &cam_cc, 29 },
+	{ "cam_cc_ife_1_dsp_clk", &gcc, 70, &cam_cc, 30 },
+	{ "cam_cc_ife_1_csid_clk", &gcc, 70, &cam_cc, 31 },
+	{ "cam_cc_ife_1_cphy_rx_clk", &gcc, 70, &cam_cc, 32 },
+	{ "cam_cc_ife_1_axi_clk", &gcc, 70, &cam_cc, 33 },
+	{ "cam_cc_ife_lite_clk", &gcc, 70, &cam_cc, 34 },
+	{ "cam_cc_ife_lite_csid_clk", &gcc, 70, &cam_cc, 35 },
+	{ "cam_cc_ife_lite_cphy_rx_clk", &gcc, 70, &cam_cc, 36 },
+	{ "cam_cc_jpeg_clk", &gcc, 70, &cam_cc, 37 },
+	{ "cam_cc_icp_clk", &gcc, 70, &cam_cc, 38 },
+	{ "cam_cc_fd_core_clk", &gcc, 70, &cam_cc, 40 },
+	{ "cam_cc_fd_core_uar_clk", &gcc, 70, &cam_cc, 41 },
+	{ "cam_cc_cci_clk", &gcc, 70, &cam_cc, 42 },
+	{ "cam_cc_lrme_clk", &gcc, 70, &cam_cc, 43 },
+	{ "cam_cc_cpas_ahb_clk", &gcc, 70, &cam_cc, 44 },
+	{ "cam_cc_camnoc_axi_clk", &gcc, 70, &cam_cc, 45 },
+	{ "cam_cc_soc_ahb_clk", &gcc, 70, &cam_cc, 46 },
+	{ "cam_cc_icp_atb_clk", &gcc, 70, &cam_cc, 47 },
+	{ "cam_cc_icp_cti_clk", &gcc, 70, &cam_cc, 48 },
+	{ "cam_cc_icp_ts_clk", &gcc, 70, &cam_cc, 49 },
+	{ "cam_cc_icp_apb_clk", &gcc, 70, &cam_cc, 50 },
+	{ "cam_cc_sys_tmr_clk", &gcc, 70, &cam_cc, 51 },
+	{ "cam_cc_camnoc_atb_clk", &gcc, 70, &cam_cc, 52 },
+	{ "cam_cc_csiphy3_clk", &gcc, 70, &cam_cc, 54 },
+	{ "disp_cc_mdss_pclk0_clk", &gcc, 71, &disp_cc, 1 },
+	{ "disp_cc_mdss_pclk1_clk", &gcc, 71, &disp_cc, 2 },
+	{ "disp_cc_mdss_mdp_clk", &gcc, 71, &disp_cc, 3 },
+	{ "disp_cc_mdss_rot_clk", &gcc, 71, &disp_cc, 4 },
+	{ "disp_cc_mdss_mdp_lut_clk", &gcc, 71, &disp_cc, 5 },
+	{ "disp_cc_mdss_vsync_clk", &gcc, 71, &disp_cc, 6 },
+	{ "disp_cc_mdss_byte0_clk", &gcc, 71, &disp_cc, 7 },
+	{ "disp_cc_mdss_byte0_intf_clk", &gcc, 71, &disp_cc, 8 },
+	{ "disp_cc_mdss_byte1_clk", &gcc, 71, &disp_cc, 9 },
+	{ "disp_cc_mdss_byte1_intf_clk", &gcc, 71, &disp_cc, 10 },
+	{ "disp_cc_mdss_esc0_clk", &gcc, 71, &disp_cc, 11 },
+	{ "disp_cc_mdss_esc1_clk", &gcc, 71, &disp_cc, 12 },
+	{ "disp_cc_mdss_dp_link_clk", &gcc, 71, &disp_cc, 13 },
+	{ "disp_cc_mdss_dp_link_intf_clk", &gcc, 71, &disp_cc, 14 },
+	{ "disp_cc_mdss_dp_crypto_clk", &gcc, 71, &disp_cc, 15 },
+	{ "disp_cc_mdss_dp_pixel_clk", &gcc, 71, &disp_cc, 16 },
+	{ "disp_cc_mdss_dp_pixel1_clk", &gcc, 71, &disp_cc, 17 },
+	{ "disp_cc_mdss_dp_aux_clk", &gcc, 71, &disp_cc, 18 },
+	{ "disp_cc_mdss_ahb_clk", &gcc, 71, &disp_cc, 19 },
+	{ "disp_cc_mdss_axi_clk", &gcc, 71, &disp_cc, 20 },
+	{ "disp_cc_mdss_qdss_at_clk", &gcc, 71, &disp_cc, 21 },
+	{ "disp_cc_mdss_qdss_tsctr_div8_clk", &gcc, 71, &disp_cc, 22 },
+	{ "disp_cc_mdss_rscc_ahb_clk", &gcc, 71, &disp_cc, 23 },
+	{ "disp_cc_mdss_rscc_vsync_clk", &gcc, 71, &disp_cc, 24 },
+	{ "video_cc_venus_ctl_core_clk", &gcc, 72, &video_cc, 1 },
+	{ "video_cc_vcodec0_core_clk", &gcc, 72, &video_cc, 2 },
+	{ "video_cc_vcodec1_core_clk", &gcc, 72, &video_cc, 3 },
+	{ "video_cc_venus_ctl_axi_clk", &gcc, 72, &video_cc, 4 },
+	{ "video_cc_vcodec0_axi_clk", &gcc, 72, &video_cc, 5 },
+	{ "video_cc_vcodec1_axi_clk", &gcc, 72, &video_cc, 6 },
+	{ "video_cc_qdss_trig_clk", &gcc, 72, &video_cc, 7 },
+	{ "video_cc_apb_clk", &gcc, 72, &video_cc, 8 },
+	{ "video_cc_venus_ahb_clk", &gcc, 72, &video_cc, 9 },
+	{ "video_cc_qdss_tsctr_div8_clk", &gcc, 72, &video_cc, 10 },
+	{ "video_cc_at_clk", &gcc, 72, &video_cc, 11 },
+	{ "gcc_disp_gpll0_clk_src", &gcc, 76 },
+	{ "gcc_disp_gpll0_div_clk_src", &gcc, 77 },
+	{ "gcc_usb30_prim_master_clk", &gcc, 95 },
+	{ "gcc_usb30_prim_sleep_clk", &gcc, 96 },
+	{ "gcc_usb30_prim_mock_utmi_clk", &gcc, 97 },
+	{ "gcc_usb3_prim_phy_aux_clk", &gcc, 98 },
+	{ "gcc_usb3_prim_phy_com_aux_clk", &gcc, 99 },
+	{ "gcc_usb3_prim_phy_pipe_clk", &gcc, 100 },
+	{ "gcc_usb30_sec_master_clk", &gcc, 101 },
+	{ "gcc_usb30_sec_sleep_clk", &gcc, 102 },
+	{ "gcc_usb30_sec_mock_utmi_clk", &gcc, 103 },
+	{ "gcc_usb3_sec_phy_aux_clk", &gcc, 104 },
+	{ "gcc_usb3_sec_phy_com_aux_clk", &gcc, 105 },
+	{ "gcc_usb3_sec_phy_pipe_clk", &gcc, 106 },
+	{ "gcc_usb_phy_cfg_ahb2phy_clk", &gcc, 111 },
+	{ "gcc_sdcc2_apps_clk", &gcc, 112 },
+	{ "gcc_sdcc2_ahb_clk", &gcc, 113 },
+	{ "gcc_sdcc4_apps_clk", &gcc, 114 },
+	{ "gcc_sdcc4_ahb_clk", &gcc, 115 },
+	{ "gcc_qupv3_wrap_0_m_ahb_clk", &gcc, 116 },
+	{ "gcc_qupv3_wrap_0_s_ahb_clk", &gcc, 117 },
+	{ "gcc_qupv3_wrap0_core_clk", &gcc, 118 },
+	{ "gcc_qupv3_wrap0_core_2x_clk", &gcc, 119 },
+	{ "gcc_qupv3_wrap0_s0_clk", &gcc, 120 },
+	{ "gcc_qupv3_wrap0_s1_clk", &gcc, 121 },
+	{ "gcc_qupv3_wrap0_s2_clk", &gcc, 122 },
+	{ "gcc_qupv3_wrap0_s3_clk", &gcc, 123 },
+	{ "gcc_qupv3_wrap0_s4_clk", &gcc, 124 },
+	{ "gcc_qupv3_wrap0_s5_clk", &gcc, 125 },
+	{ "gcc_qupv3_wrap0_s6_clk", &gcc, 126 },
+	{ "gcc_qupv3_wrap0_s7_clk", &gcc, 127 },
+	{ "gcc_qupv3_wrap1_core_2x_clk", &gcc, 128 },
+	{ "gcc_qupv3_wrap1_core_clk", &gcc, 129 },
+	{ "gcc_qupv3_wrap_1_m_ahb_clk", &gcc, 130 },
+	{ "gcc_qupv3_wrap_1_s_ahb_clk", &gcc, 131 },
+	{ "gcc_qupv3_wrap1_s0_clk", &gcc, 132 },
+	{ "gcc_qupv3_wrap1_s1_clk", &gcc, 133 },
+	{ "gcc_qupv3_wrap1_s2_clk", &gcc, 134 },
+	{ "gcc_qupv3_wrap1_s3_clk", &gcc, 135 },
+	{ "gcc_qupv3_wrap1_s4_clk", &gcc, 136 },
+	{ "gcc_qupv3_wrap1_s5_clk", &gcc, 137 },
+	{ "gcc_qupv3_wrap1_s6_clk", &gcc, 138 },
+	{ "gcc_qupv3_wrap1_s7_clk", &gcc, 139 },
+	{ "gcc_pdm_ahb_clk", &gcc, 140 },
+	{ "gcc_pdm_xo4_clk", &gcc, 141 },
+	{ "gcc_pdm2_clk", &gcc, 142 },
+	{ "gcc_prng_ahb_clk", &gcc, 143 },
+	{ "gcc_tsif_ahb_clk", &gcc, 144 },
+	{ "gcc_tsif_ref_clk", &gcc, 145 },
+	{ "gcc_tsif_inactivity_timers_clk", &gcc, 146 },
+	{ "gcc_boot_rom_ahb_clk", &gcc, 148 },
+	{ "gcc_ce1_clk", &gcc, 167 },
+	{ "gcc_ce1_axi_clk", &gcc, 168 },
+	{ "gcc_ce1_ahb_clk", &gcc, 169 },
+	{ "gcc_ddrss_gpu_axi_clk", &gcc, 187 },
+	{ "measure_only_bimc_clk", &gcc, 194 },
+	{ "gcc_cpuss_ahb_clk", &gcc, 206 },
+	{ "gcc_cpuss_gnoc_clk", &gcc, 207 },
+	{ "gcc_cpuss_rbcpr_clk", &gcc, 208 },
+	{ "gcc_cpuss_dvm_bus_clk", &gcc, 211 },
+	{ "pwrcl_clk", &gcc, 214, &cpu, 68, 16 },
+	{ "perfcl_clk", &gcc, 214, &cpu, 69, 16 },
+	{ "l3_clk", &gcc, 214, &cpu, 70, 16 },
+	{ "gcc_gp1_clk", &gcc, 222 },
+	{ "gcc_gp2_clk", &gcc, 223 },
+	{ "gcc_gp3_clk", &gcc, 224 },
+	{ "gcc_pcie_0_slv_q2a_axi_clk", &gcc, 225 },
+	{ "gcc_pcie_0_slv_axi_clk", &gcc, 226 },
+	{ "gcc_pcie_0_mstr_axi_clk", &gcc, 227 },
+	{ "gcc_pcie_0_cfg_ahb_clk", &gcc, 228 },
+	{ "gcc_pcie_0_aux_clk", &gcc, 229 },
+	{ "gcc_pcie_0_pipe_clk", &gcc, 230 },
+	{ "gcc_pcie_1_slv_q2a_axi_clk", &gcc, 232 },
+	{ "gcc_pcie_1_slv_axi_clk", &gcc, 233 },
+	{ "gcc_pcie_1_mstr_axi_clk", &gcc, 234 },
+	{ "gcc_pcie_1_cfg_ahb_clk", &gcc, 235 },
+	{ "gcc_pcie_1_aux_clk", &gcc, 236 },
+	{ "gcc_pcie_1_pipe_clk", &gcc, 237 },
+	{ "gcc_pcie_phy_aux_clk", &gcc, 239 },
+	{ "gcc_ufs_card_axi_clk", &gcc, 240 },
+	{ "gcc_ufs_card_ahb_clk", &gcc, 241 },
+	{ "gcc_ufs_card_tx_symbol_0_clk", &gcc, 242 },
+	{ "gcc_ufs_card_rx_symbol_0_clk", &gcc, 243 },
+	{ "gcc_ufs_card_unipro_core_clk", &gcc, 246 },
+	{ "gcc_ufs_card_ice_core_clk", &gcc, 247 },
+	{ "gcc_ufs_card_phy_aux_clk", &gcc, 248 },
+	{ "gcc_ufs_card_rx_symbol_1_clk", &gcc, 249 },
+	{ "gcc_ufs_phy_axi_clk", &gcc, 251 },
+	{ "gcc_ufs_phy_ahb_clk", &gcc, 252 },
+	{ "gcc_ufs_phy_tx_symbol_0_clk", &gcc, 253 },
+	{ "gcc_ufs_phy_rx_symbol_0_clk", &gcc, 254 },
+	{ "gcc_ufs_phy_unipro_core_clk", &gcc, 257 },
+	{ "gcc_ufs_phy_ice_core_clk", &gcc, 258 },
+	{ "gcc_ufs_phy_phy_aux_clk", &gcc, 259 },
+	{ "gcc_ufs_phy_rx_symbol_1_clk", &gcc, 260 },
+	{ "gcc_vddcx_vs_clk", &gcc, 268 },
+	{ "gcc_vddmx_vs_clk", &gcc, 269 },
+	{ "gcc_vdda_vs_clk", &gcc, 270 },
+	{ "gcc_vs_ctrl_clk", &gcc, 271 },
+	{ "gcc_vs_ctrl_ahb_clk", &gcc, 272 },
+	{ "gcc_mss_vs_clk", &gcc, 273 },
+	{ "gcc_gpu_vs_clk", &gcc, 274 },
+	{ "gcc_apc_vs_clk", &gcc, 275 },
+	{ "gcc_aggre_usb3_prim_axi_clk", &gcc, 283 },
+	{ "gcc_aggre_usb3_sec_axi_clk", &gcc, 284 },
+	{ "gcc_aggre_ufs_phy_axi_clk", &gcc, 285 },
+	{ "gcc_aggre_ufs_card_axi_clk", &gcc, 286 },
+	{ "measure_only_ipa_2x_clk", &gcc, 296 },
+	{ "gcc_mss_cfg_ahb_clk", &gcc, 301 },
+	{ "gcc_mss_mfab_axis_clk", &gcc, 302 },
+	{ "gcc_mss_axis2_clk", &gcc, 303 },
+	{ "gcc_mss_gpll0_div_clk_src", &gcc, 307 },
+	{ "gcc_mss_snoc_axi_clk", &gcc, 308 },
+	{ "gcc_mss_q6_memnoc_axi_clk", &gcc, 309 },
+	{ "gcc_gpu_cfg_ahb_clk", &gcc, 322 },
+	{ "gpu_cc_cxo_clk", &gcc, 324, &gpu_cc, 10 },
+	{ "gpu_cc_cxo_aon_clk", &gcc, 324, &gpu_cc, 11 },
+	{ "gpu_cc_gx_gfx3d_clk", &gcc, 324, &gpu_cc, 12 },
+	{ "gpu_cc_gx_vsense_clk", &gcc, 324, &gpu_cc, 13 },
+	{ "gpu_cc_gx_qdss_tsctr_clk", &gcc, 324, &gpu_cc, 14 },
+	{ "gpu_cc_gx_gmu_clk", &gcc, 324, &gpu_cc, 16 },
+	{ "gpu_cc_crc_ahb_clk", &gcc, 324, &gpu_cc, 18 },
+	{ "gpu_cc_cx_qdss_at_clk", &gcc, 324, &gpu_cc, 19 },
+	{ "gpu_cc_cx_qdss_tsctr_clk", &gcc, 324, &gpu_cc, 20 },
+	{ "gpu_cc_cx_apb_clk", &gcc, 324, &gpu_cc, 21 },
+	{ "gpu_cc_cx_snoc_dvm_clk", &gcc, 324, &gpu_cc, 22 },
+	{ "gpu_cc_sleep_clk", &gcc, 324, &gpu_cc, 23 },
+	{ "gpu_cc_cx_qdss_trig_clk", &gcc, 324, &gpu_cc, 24 },
+	{ "gpu_cc_cx_gmu_clk", &gcc, 324, &gpu_cc, 25 },
+	{ "gpu_cc_cx_gfx3d_clk", &gcc, 324, &gpu_cc, 26 },
+	{ "gpu_cc_cx_gfx3d_slv_clk", &gcc, 324, &gpu_cc, 27 },
+	{ "gpu_cc_rbcpr_clk", &gcc, 324, &gpu_cc, 28 },
+	{ "gpu_cc_rbcpr_ahb_clk", &gcc, 324, &gpu_cc, 29 },
+	{ "gpu_cc_acd_cxo_clk", &gcc, 324, &gpu_cc, 31 },
+	{ "gcc_gpu_memnoc_gfx_clk", &gcc, 325 },
+	{ "gcc_gpu_snoc_dvm_gfx_clk", &gcc, 327 },
+	{ "gcc_gpu_gpll0_clk_src", &gcc, 328 },
+	{ "gcc_gpu_gpll0_div_clk_src", &gcc, 329 },
+	{ "gcc_sdcc1_apps_clk", &gcc, 347 },
+	{ "gcc_sdcc1_ahb_clk", &gcc, 348 },
+	{ "gcc_sdcc1_ice_core_clk", &gcc, 349 },
+	{ "gcc_pcie_phy_refgen_clk", &gcc, 352 },
+	{}
+};
+
+struct debugcc_platform sdm845_debugcc = {
+	"sdm845",
+	sdm845_clocks,
+	sdm845_blocks,
+};
diff --git a/drivers/clk/qcom/debugcc/sm6115.c b/drivers/clk/qcom/debugcc/sm6115.c
new file mode 100644
index 0000000..c19c24c
--- /dev/null
+++ b/drivers/clk/qcom/debugcc/sm6115.c
@@ -0,0 +1,222 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/* Copyright (c) 2022, Linaro Limited */
+
+#include <errno.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "debugcc.h"
+
+static struct debug_mux cpu_cc = {
+	.base = 0xf111000,
+	.size = 0x1000,
+	.block_name = "cpu",
+
+	.enable_reg = 0x1c,
+	.enable_mask = BIT(0),
+
+	.mux_reg = 0x1c,
+	.mux_mask = 0x3ff << 8,
+	.mux_shift = 8,
+
+	.div_reg = 0x1c,
+	.div_mask = 0xf << 28,
+	.div_shift = 28,
+};
+
+static struct debug_mux disp_cc = {
+	.base = 0x5f00000,
+	.size = 0x20000,
+	.block_name = "disp",
+
+	.enable_reg = 0x500c,
+	.enable_mask = BIT(0),
+
+	.mux_reg = 0x7000,
+	.mux_mask = 0xff,
+
+	.div_reg = 0x5008,
+	.div_mask = 0x3,
+	.div_val = 4,
+};
+
+static struct debug_mux gcc = {
+	.base = 0x1400000,
+	.size = 0x1f0000,
+
+	.enable_reg = 0x30004,
+	.enable_mask = BIT(0),
+
+	.mux_reg = 0x62000,
+	.mux_mask = 0x3ff,
+
+	.div_reg = 0x30000,
+	.div_mask = 0xf,
+	.div_val = 4,
+
+	.xo_div4_reg = 0x28008,
+	.debug_ctl_reg = 0x62038,
+	.debug_status_reg = 0x6203c,
+};
+
+static struct debug_mux gpu_cc = {
+	.base = 0x5990000,
+	.size = 0x9000,
+	.block_name = "gpu",
+
+	.enable_reg = 0x1100,
+	.enable_mask = BIT(0),
+
+	.mux_reg = 0x1568,
+	.mux_mask = 0xff,
+
+	.div_reg = 0x10fc,
+	.div_mask = 0x3,
+	.div_val = 2,
+};
+
+static const struct debug_mux *sm6115_blocks[] = {
+	&gcc,
+	&cpu_cc,
+	&disp_cc,
+	&gpu_cc,
+	NULL,
+};
+
+static struct measure_clk sm6115_clocks[] = {
+	{ "perfcl_clk", &gcc, 0xaf, &cpu_cc, 0x1 },
+	{ "pwrcl_clk", &gcc, 0xaf, &cpu_cc, 0x0 },
+	//{ "cpu_cc_debug_mux", &gcc, 0xaf },
+	//{ "disp_cc_debug_mux", &gcc, 0x42 },
+	{ "gcc_ahb2phy_csi_clk", &gcc, 0x63 },
+	{ "gcc_ahb2phy_usb_clk", &gcc, 0x64 },
+	{ "gcc_bimc_gpu_axi_clk", &gcc, 0x90 },
+	{ "gcc_boot_rom_ahb_clk", &gcc, 0x76 },
+	{ "gcc_cam_throttle_nrt_clk", &gcc, 0x4c },
+	{ "gcc_cam_throttle_rt_clk", &gcc, 0x4b },
+	{ "gcc_camera_ahb_clk", &gcc, 0x37 },
+	{ "gcc_camera_xo_clk", &gcc, 0x3f },
+	{ "gcc_camss_axi_clk", &gcc, 0x136 },
+	{ "gcc_camss_camnoc_atb_clk", &gcc, 0x138 },
+	{ "gcc_camss_camnoc_nts_xo_clk", &gcc, 0x139 },
+	{ "gcc_camss_cci_0_clk", &gcc, 0x134 },
+	{ "gcc_camss_cphy_0_clk", &gcc, 0x128 },
+	{ "gcc_camss_cphy_1_clk", &gcc, 0x129 },
+	{ "gcc_camss_cphy_2_clk", &gcc, 0x12a },
+	{ "gcc_camss_csi0phytimer_clk", &gcc, 0x11a },
+	{ "gcc_camss_csi1phytimer_clk", &gcc, 0x11b },
+	{ "gcc_camss_csi2phytimer_clk", &gcc, 0x11c },
+	{ "gcc_camss_mclk0_clk", &gcc, 0x11d },
+	{ "gcc_camss_mclk1_clk", &gcc, 0x11e },
+	{ "gcc_camss_mclk2_clk", &gcc, 0x11f },
+	{ "gcc_camss_mclk3_clk", &gcc, 0x120 },
+	{ "gcc_camss_nrt_axi_clk", &gcc, 0x13a },
+	{ "gcc_camss_ope_ahb_clk", &gcc, 0x133 },
+	{ "gcc_camss_ope_clk", &gcc, 0x131 },
+	{ "gcc_camss_rt_axi_clk", &gcc, 0x13c },
+	{ "gcc_camss_tfe_0_clk", &gcc, 0x121 },
+	{ "gcc_camss_tfe_0_cphy_rx_clk", &gcc, 0x125 },
+	{ "gcc_camss_tfe_0_csid_clk", &gcc, 0x12b },
+	{ "gcc_camss_tfe_1_clk", &gcc, 0x122 },
+	{ "gcc_camss_tfe_1_cphy_rx_clk", &gcc, 0x126 },
+	{ "gcc_camss_tfe_1_csid_clk", &gcc, 0x12d },
+	{ "gcc_camss_tfe_2_clk", &gcc, 0x123 },
+	{ "gcc_camss_tfe_2_cphy_rx_clk", &gcc, 0x127 },
+	{ "gcc_camss_tfe_2_csid_clk", &gcc, 0x12f },
+	{ "gcc_camss_top_ahb_clk", &gcc, 0x135 },
+	{ "gcc_cfg_noc_usb3_prim_axi_clk", &gcc, 0x1d },
+	{ "gcc_cpuss_gnoc_clk", &gcc, 0xaa },
+	{ "gcc_disp_ahb_clk", &gcc, 0x38 },
+	{ "gcc_disp_gpll0_div_clk_src", &gcc, 0x47 },
+	{ "gcc_disp_hf_axi_clk", &gcc, 0x3d },
+	{ "gcc_disp_throttle_core_clk", &gcc, 0x49 },
+	{ "gcc_disp_xo_clk", &gcc, 0x40 },
+	{ "gcc_gp1_clk", &gcc, 0xba },
+	{ "gcc_gp2_clk", &gcc, 0xbb },
+	{ "gcc_gp3_clk", &gcc, 0xbc },
+	{ "gcc_gpu_cfg_ahb_clk", &gcc, 0xe5 },
+	{ "gcc_gpu_gpll0_clk_src", &gcc, 0xeb },
+	{ "gcc_gpu_gpll0_div_clk_src", &gcc, 0xec },
+	{ "gcc_gpu_memnoc_gfx_clk", &gcc, 0xe8 },
+	{ "gcc_gpu_snoc_dvm_gfx_clk", &gcc, 0xea },
+	{ "gcc_gpu_throttle_core_clk", &gcc, 0xef },
+	{ "gcc_pdm2_clk", &gcc, 0x73 },
+	{ "gcc_pdm_ahb_clk", &gcc, 0x71 },
+	{ "gcc_pdm_xo4_clk", &gcc, 0x72 },
+	{ "gcc_prng_ahb_clk", &gcc, 0x74 },
+	{ "gcc_qmip_camera_nrt_ahb_clk", &gcc, 0x3a },
+	{ "gcc_qmip_camera_rt_ahb_clk", &gcc, 0x48 },
+	{ "gcc_qmip_disp_ahb_clk", &gcc, 0x3b },
+	{ "gcc_qmip_gpu_cfg_ahb_clk", &gcc, 0xed },
+	{ "gcc_qmip_video_vcodec_ahb_clk", &gcc, 0x39 },
+	{ "gcc_qupv3_wrap0_core_2x_clk", &gcc, 0x6a },
+	{ "gcc_qupv3_wrap0_core_clk", &gcc, 0x69 },
+	{ "gcc_qupv3_wrap_0_m_ahb_clk", &gcc, 0x67 },
+	{ "gcc_qupv3_wrap_0_s_ahb_clk", &gcc, 0x68 },
+	{ "gcc_sdcc1_ahb_clk", &gcc, 0xf3 },
+	{ "gcc_sdcc1_apps_clk", &gcc, 0xf2 },
+	{ "gcc_sdcc1_ice_core_clk", &gcc, 0xf4 },
+	{ "gcc_sdcc2_ahb_clk", &gcc, 0x66 },
+	{ "gcc_sdcc2_apps_clk", &gcc, 0x65 },
+	{ "gcc_sys_noc_cpuss_ahb_clk", &gcc, 0x9 },
+	{ "gcc_sys_noc_ufs_phy_axi_clk", &gcc, 0x19 },
+	{ "gcc_sys_noc_usb3_prim_axi_clk", &gcc, 0x18 },
+	{ "gcc_ufs_phy_ahb_clk", &gcc, 0x111 },
+	{ "gcc_ufs_phy_axi_clk", &gcc, 0x110 },
+	{ "gcc_ufs_phy_ice_core_clk", &gcc, 0x117 },
+	{ "gcc_ufs_phy_phy_aux_clk", &gcc, 0x118 },
+	{ "gcc_ufs_phy_rx_symbol_0_clk", &gcc, 0x113 },
+	{ "gcc_ufs_phy_tx_symbol_0_clk", &gcc, 0x112 },
+	{ "gcc_ufs_phy_unipro_core_clk", &gcc, 0x116 },
+	{ "gcc_usb30_prim_master_clk", &gcc, 0x5c },
+	{ "gcc_usb30_prim_mock_utmi_clk", &gcc, 0x5e },
+	{ "gcc_usb30_prim_sleep_clk", &gcc, 0x5d },
+	{ "gcc_usb3_prim_phy_com_aux_clk", &gcc, 0x5f },
+	{ "gcc_usb3_prim_phy_pipe_clk", &gcc, 0x60 },
+	{ "gcc_vcodec0_axi_clk", &gcc, 0x142 },
+	{ "gcc_venus_ahb_clk", &gcc, 0x143 },
+	{ "gcc_venus_ctl_axi_clk", &gcc, 0x141 },
+	{ "gcc_video_ahb_clk", &gcc, 0x36 },
+	{ "gcc_video_axi0_clk", &gcc, 0x3c },
+	{ "gcc_video_throttle_core_clk", &gcc, 0x4a },
+	{ "gcc_video_vcodec0_sys_clk", &gcc, 0x13f },
+	{ "gcc_video_venus_ctl_clk", &gcc, 0x13d },
+	{ "gcc_video_xo_clk", &gcc, 0x3e },
+	//{ "gpu_cc_debug_mux", &gcc, 0xe7 },
+	//{ "mc_cc_debug_mux", &gcc, 0x9e },
+	{ "measure_only_cnoc_clk", &gcc, 0x1a },
+	{ "measure_only_ipa_2x_clk", &gcc, 0xc6 },
+	{ "measure_only_snoc_clk", &gcc, 0x7 },
+	{ "disp_cc_mdss_ahb_clk", &gcc, 0x42, &disp_cc, 0x1a },
+	{ "disp_cc_mdss_byte0_clk", &gcc, 0x42, &disp_cc, 0x12 },
+	{ "disp_cc_mdss_byte0_intf_clk", &gcc, 0x42, &disp_cc, 0x13 },
+	{ "disp_cc_mdss_esc0_clk", &gcc, 0x42, &disp_cc, 0x14 },
+	{ "disp_cc_mdss_mdp_clk", &gcc, 0x42, &disp_cc, 0xe },
+	{ "disp_cc_mdss_mdp_lut_clk", &gcc, 0x42, &disp_cc, 0x10 },
+	{ "disp_cc_mdss_non_gdsc_ahb_clk", &gcc, 0x42, &disp_cc, 0x1b },
+	{ "disp_cc_mdss_pclk0_clk", &gcc, 0x42, &disp_cc, 0xd },
+	{ "disp_cc_mdss_rot_clk", &gcc, 0x42, &disp_cc, 0xf },
+	{ "disp_cc_mdss_vsync_clk", &gcc, 0x42, &disp_cc, 0x11 },
+	{ "disp_cc_sleep_clk", &gcc, 0x42, &disp_cc, 0x24 },
+	{ "disp_cc_xo_clk", &gcc, 0x42, &disp_cc, 0x23 },
+	{ "gpu_cc_ahb_clk", &gcc, 0xe7, &gpu_cc, 0x10 },
+	{ "gpu_cc_crc_ahb_clk", &gcc, 0xe7, &gpu_cc, 0x11 },
+	{ "gpu_cc_cx_gfx3d_clk", &gcc, 0xe7, &gpu_cc, 0x1a },
+	{ "gpu_cc_cx_gmu_clk", &gcc, 0xe7, &gpu_cc, 0x18 },
+	{ "gpu_cc_cx_snoc_dvm_clk", &gcc, 0xe7, &gpu_cc, 0x15 },
+	{ "gpu_cc_cxo_aon_clk", &gcc, 0xe7, &gpu_cc, 0xa },
+	{ "gpu_cc_cxo_clk", &gcc, 0xe7, &gpu_cc, 0x19 },
+	{ "gpu_cc_gx_cxo_clk", &gcc, 0xe7, &gpu_cc, 0xe },
+	{ "gpu_cc_gx_gfx3d_clk", &gcc, 0xe7, &gpu_cc, 0xb },
+	{ "gpu_cc_sleep_clk", &gcc, 0xe7, &gpu_cc, 0x16 },
+	{}
+};
+
+struct debugcc_platform sm6115_debugcc = {
+	"sm6115",
+	sm6115_clocks,
+	sm6115_blocks,
+};
diff --git a/drivers/clk/qcom/debugcc/sm8250.c b/drivers/clk/qcom/debugcc/sm8250.c
new file mode 100644
index 0000000..b252cf8
--- /dev/null
+++ b/drivers/clk/qcom/debugcc/sm8250.c
@@ -0,0 +1,504 @@
+/*
+ * Copyright (c) 2023, Marijn Suijten.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its contributors
+ * may be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+#include <errno.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "debugcc.h"
+
+static struct debug_mux gcc = {
+	.base =	0x100000,
+	.size = 0x1f0000,
+
+	.enable_reg = 0x62008,
+	.enable_mask = BIT(0),
+
+	.mux_reg = 0x62000,
+	.mux_mask = 0x3ff,
+
+	.div_reg = 0x62004,
+	.div_mask = 0xf,
+	.div_val = 2,
+
+	.xo_div4_reg = 0x4300c,
+	.debug_ctl_reg = 0x62038,
+	.debug_status_reg = 0x6203c,
+};
+
+static struct debug_mux cam_cc = {
+	.base = 0xad00000,
+	.size = 0x10000,
+	.block_name = "cam",
+
+	.enable_reg = 0xd008,
+	.enable_mask = BIT(0),
+
+	.mux_reg = 0xd000,
+	.mux_mask = 0xff,
+
+	.div_reg = 0xd004,
+	.div_mask = 0xf,
+	.div_val = 4,
+};
+
+static struct debug_mux disp_cc = {
+	.base = 0xaf00000,
+	.size = 0x20000,
+	.block_name = "disp",
+
+	.enable_reg = 0x500c,
+	.enable_mask = BIT(0),
+
+	.mux_reg = 0x7000,
+	.mux_mask = 0xff,
+
+	.div_reg = 0x5008,
+	.div_mask = 0x3,
+	.div_val = 4,
+};
+
+static struct debug_mux gpu_cc = {
+	.base = 0x3d90000,
+	.size = 0x9000,
+	.block_name = "gpu",
+
+	.enable_reg = 0x1100,
+	.enable_mask = BIT(0),
+
+	.mux_reg = 0x1568,
+	.mux_mask = 0xff,
+
+	.div_reg = 0x10fc,
+	.div_mask = 0x3,
+	.div_val = 2,
+};
+
+static struct debug_mux npu_cc = {
+	.base = 0x9980000,
+	.size = 0x10000,
+	.block_name = "npu",
+
+	.enable_reg = 0x3008,
+	.enable_mask = BIT(0),
+
+	.mux_reg = 0x3000,
+	.mux_mask = 0xff,
+
+	.div_reg = 0x3004,
+	.div_mask = 0x3,
+	.div_val = 2,
+};
+
+static struct debug_mux video_cc = {
+	.base = 0xabf0000,
+	.size = 0x10000,
+	.block_name = "video",
+
+	.enable_reg = 0xebc,
+	.enable_mask = BIT(0),
+
+	.mux_reg = 0xa4c,
+	.mux_mask = 0x3f,
+
+	.div_reg = 0x39c,
+	.div_mask = 0x7,
+	.div_val = 3,
+};
+
+static struct debug_mux mc_cc = {
+	.base =	0x90ba000,
+	.size = /* 0x54 */ 0x1000,
+	.block_name = "mc",
+
+	.measure = measure_mccc,
+};
+
+static struct debug_mux apss_cc = {
+	.base =	0x182a0000,
+	.size = /* 0x1c */ 0x1000,
+	.block_name = "apss",
+
+	.enable_reg = 0x0,
+	.enable_mask = BIT(0),
+
+	.mux_reg = 0x18,
+	.mux_mask = 0x7f << 4,
+	.mux_shift = 4,
+
+	.div_reg = 0x18,
+	.div_mask = 0xf << 11,
+	.div_shift = 11,
+	.div_val = 1,
+};
+
+static const struct debug_mux *sm8250_blocks[] = {
+	&gcc,
+	//&cam_cc,
+	&disp_cc,
+	&gpu_cc,
+	&npu_cc,
+	//&video_cc,
+	&mc_cc,
+	&apss_cc,
+	NULL,
+};
+
+static struct measure_clk sm8250_clocks[] = {
+	//{ "cam_cc_bps_ahb_clk", &gcc, 0x55, &cam_cc, 0x18 },
+	//{ "cam_cc_bps_areg_clk", &gcc, 0x55, &cam_cc, 0x17 },
+	//{ "cam_cc_bps_axi_clk", &gcc, 0x55, &cam_cc, 0x16 },
+	//{ "cam_cc_bps_clk", &gcc, 0x55, &cam_cc, 0x14 },
+	//{ "cam_cc_camnoc_axi_clk", &gcc, 0x55, &cam_cc, 0x3c },
+	//{ "cam_cc_camnoc_dcd_xo_clk", &gcc, 0x55, &cam_cc, 0x3d },
+	//{ "cam_cc_cci_0_clk", &gcc, 0x55, &cam_cc, 0x39 },
+	//{ "cam_cc_cci_1_clk", &gcc, 0x55, &cam_cc, 0x3a },
+	//{ "cam_cc_core_ahb_clk", &gcc, 0x55, &cam_cc, 0x40 },
+	//{ "cam_cc_cpas_ahb_clk", &gcc, 0x55, &cam_cc, 0x3b },
+	//{ "cam_cc_csi0phytimer_clk", &gcc, 0x55, &cam_cc, 0x8 },
+	//{ "cam_cc_csi1phytimer_clk", &gcc, 0x55, &cam_cc, 0xa },
+	//{ "cam_cc_csi2phytimer_clk", &gcc, 0x55, &cam_cc, 0xc },
+	//{ "cam_cc_csi3phytimer_clk", &gcc, 0x55, &cam_cc, 0xe },
+	//{ "cam_cc_csi4phytimer_clk", &gcc, 0x55, &cam_cc, 0x10 },
+	//{ "cam_cc_csi5phytimer_clk", &gcc, 0x55, &cam_cc, 0x12 },
+	//{ "cam_cc_csiphy0_clk", &gcc, 0x55, &cam_cc, 0x9 },
+	//{ "cam_cc_csiphy1_clk", &gcc, 0x55, &cam_cc, 0xb },
+	//{ "cam_cc_csiphy2_clk", &gcc, 0x55, &cam_cc, 0xd },
+	//{ "cam_cc_csiphy3_clk", &gcc, 0x55, &cam_cc, 0xf },
+	//{ "cam_cc_csiphy4_clk", &gcc, 0x55, &cam_cc, 0x11 },
+	//{ "cam_cc_csiphy5_clk", &gcc, 0x55, &cam_cc, 0x13 },
+	//{ "cam_cc_fd_core_clk", &gcc, 0x55, &cam_cc, 0x37 },
+	//{ "cam_cc_fd_core_uar_clk", &gcc, 0x55, &cam_cc, 0x38 },
+	//{ "cam_cc_gdsc_clk", &gcc, 0x55, &cam_cc, 0x41 },
+	//{ "cam_cc_icp_ahb_clk", &gcc, 0x55, &cam_cc, 0x36 },
+	//{ "cam_cc_icp_clk", &gcc, 0x55, &cam_cc, 0x35 },
+	//{ "cam_cc_ife_0_ahb_clk", &gcc, 0x55, &cam_cc, 0x26 },
+	//{ "cam_cc_ife_0_areg_clk", &gcc, 0x55, &cam_cc, 0x1f },
+	//{ "cam_cc_ife_0_axi_clk", &gcc, 0x55, &cam_cc, 0x25 },
+	//{ "cam_cc_ife_0_clk", &gcc, 0x55, &cam_cc, 0x1e },
+	//{ "cam_cc_ife_0_cphy_rx_clk", &gcc, 0x55, &cam_cc, 0x24 },
+	//{ "cam_cc_ife_0_csid_clk", &gcc, 0x55, &cam_cc, 0x22 },
+	//{ "cam_cc_ife_0_dsp_clk", &gcc, 0x55, &cam_cc, 0x21 },
+	//{ "cam_cc_ife_1_ahb_clk", &gcc, 0x55, &cam_cc, 0x2e },
+	//{ "cam_cc_ife_1_areg_clk", &gcc, 0x55, &cam_cc, 0x29 },
+	//{ "cam_cc_ife_1_axi_clk", &gcc, 0x55, &cam_cc, 0x2d },
+	//{ "cam_cc_ife_1_clk", &gcc, 0x55, &cam_cc, 0x27 },
+	//{ "cam_cc_ife_1_cphy_rx_clk", &gcc, 0x55, &cam_cc, 0x2c },
+	//{ "cam_cc_ife_1_csid_clk", &gcc, 0x55, &cam_cc, 0x2b },
+	//{ "cam_cc_ife_1_dsp_clk", &gcc, 0x55, &cam_cc, 0x2a },
+	//{ "cam_cc_ife_lite_ahb_clk", &gcc, 0x55, &cam_cc, 0x32 },
+	//{ "cam_cc_ife_lite_axi_clk", &gcc, 0x55, &cam_cc, 0x49 },
+	//{ "cam_cc_ife_lite_clk", &gcc, 0x55, &cam_cc, 0x2f },
+	//{ "cam_cc_ife_lite_cphy_rx_clk", &gcc, 0x55, &cam_cc, 0x31 },
+	//{ "cam_cc_ife_lite_csid_clk", &gcc, 0x55, &cam_cc, 0x30 },
+	//{ "cam_cc_ipe_0_ahb_clk", &gcc, 0x55, &cam_cc, 0x1d },
+	//{ "cam_cc_ipe_0_areg_clk", &gcc, 0x55, &cam_cc, 0x1c },
+	//{ "cam_cc_ipe_0_axi_clk", &gcc, 0x55, &cam_cc, 0x1b },
+	//{ "cam_cc_ipe_0_clk", &gcc, 0x55, &cam_cc, 0x19 },
+	//{ "cam_cc_jpeg_clk", &gcc, 0x55, &cam_cc, 0x33 },
+	//{ "cam_cc_mclk0_clk", &gcc, 0x55, &cam_cc, 0x1 },
+	//{ "cam_cc_mclk1_clk", &gcc, 0x55, &cam_cc, 0x2 },
+	//{ "cam_cc_mclk2_clk", &gcc, 0x55, &cam_cc, 0x3 },
+	//{ "cam_cc_mclk3_clk", &gcc, 0x55, &cam_cc, 0x4 },
+	//{ "cam_cc_mclk4_clk", &gcc, 0x55, &cam_cc, 0x5 },
+	//{ "cam_cc_mclk5_clk", &gcc, 0x55, &cam_cc, 0x6 },
+	//{ "cam_cc_mclk6_clk", &gcc, 0x55, &cam_cc, 0x7 },
+	//{ "cam_cc_sbi_ahb_clk", &gcc, 0x55, &cam_cc, 0x4e },
+	//{ "cam_cc_sbi_axi_clk", &gcc, 0x55, &cam_cc, 0x4d },
+	//{ "cam_cc_sbi_clk", &gcc, 0x55, &cam_cc, 0x4a },
+	//{ "cam_cc_sbi_cphy_rx_clk", &gcc, 0x55, &cam_cc, 0x4c },
+	//{ "cam_cc_sbi_csid_clk", &gcc, 0x55, &cam_cc, 0x4b },
+	//{ "cam_cc_sbi_ife_0_clk", &gcc, 0x55, &cam_cc, 0x4f },
+	//{ "cam_cc_sbi_ife_1_clk", &gcc, 0x55, &cam_cc, 0x50 },
+	//{ "cam_cc_sleep_clk", &gcc, 0x55, &cam_cc, 0x42 },
+
+	{ "disp_cc_mdss_ahb_clk", &gcc, 0x56, &disp_cc, 0x2b },
+	{ "disp_cc_mdss_byte0_clk", &gcc, 0x56, &disp_cc, 0x15 },
+	{ "disp_cc_mdss_byte0_intf_clk", &gcc, 0x56, &disp_cc, 0x16 },
+	{ "disp_cc_mdss_byte1_clk", &gcc, 0x56, &disp_cc, 0x17 },
+	{ "disp_cc_mdss_byte1_intf_clk", &gcc, 0x56, &disp_cc, 0x18 },
+	{ "disp_cc_mdss_dp_aux1_clk", &gcc, 0x56, &disp_cc, 0x25 },
+	{ "disp_cc_mdss_dp_aux_clk", &gcc, 0x56, &disp_cc, 0x20 },
+	{ "disp_cc_mdss_dp_link1_clk", &gcc, 0x56, &disp_cc, 0x22 },
+	{ "disp_cc_mdss_dp_link1_intf_clk", &gcc, 0x56, &disp_cc, 0x23 },
+	{ "disp_cc_mdss_dp_link_clk", &gcc, 0x56, &disp_cc, 0x1b },
+	{ "disp_cc_mdss_dp_link_intf_clk", &gcc, 0x56, &disp_cc, 0x1c },
+	{ "disp_cc_mdss_dp_pixel1_clk", &gcc, 0x56, &disp_cc, 0x1f },
+	{ "disp_cc_mdss_dp_pixel2_clk", &gcc, 0x56, &disp_cc, 0x21 },
+	{ "disp_cc_mdss_dp_pixel_clk", &gcc, 0x56, &disp_cc, 0x1e },
+	{ "disp_cc_mdss_edp_aux_clk", &gcc, 0x56, &disp_cc, 0x29 },
+	{ "disp_cc_mdss_edp_gtc_clk", &gcc, 0x56, &disp_cc, 0x2a },
+	{ "disp_cc_mdss_edp_link_clk", &gcc, 0x56, &disp_cc, 0x27 },
+	{ "disp_cc_mdss_edp_link_intf_clk", &gcc, 0x56, &disp_cc, 0x28 },
+	{ "disp_cc_mdss_edp_pixel_clk", &gcc, 0x56, &disp_cc, 0x26 },
+	{ "disp_cc_mdss_esc0_clk", &gcc, 0x56, &disp_cc, 0x19 },
+	{ "disp_cc_mdss_esc1_clk", &gcc, 0x56, &disp_cc, 0x1a },
+	{ "disp_cc_mdss_mdp_clk", &gcc, 0x56, &disp_cc, 0x11 },
+	{ "disp_cc_mdss_mdp_lut_clk", &gcc, 0x56, &disp_cc, 0x13 },
+	{ "disp_cc_mdss_non_gdsc_ahb_clk", &gcc, 0x56, &disp_cc, 0x2c },
+	{ "disp_cc_mdss_pclk0_clk", &gcc, 0x56, &disp_cc, 0xf },
+	{ "disp_cc_mdss_pclk1_clk", &gcc, 0x56, &disp_cc, 0x10 },
+	{ "disp_cc_mdss_rot_clk", &gcc, 0x56, &disp_cc, 0x12 },
+	{ "disp_cc_mdss_rscc_ahb_clk", &gcc, 0x56, &disp_cc, 0x2e },
+	{ "disp_cc_mdss_rscc_vsync_clk", &gcc, 0x56, &disp_cc, 0x2d },
+	{ "disp_cc_mdss_vsync_clk", &gcc, 0x56, &disp_cc, 0x14 },
+	{ "disp_cc_sleep_clk", &gcc, 0x56, &disp_cc, 0x37 },
+	{ "disp_cc_xo_clk", &gcc, 0x56, &disp_cc, 0x36 },
+
+	// { "apss_cc_debug_mux", &gcc, 0xe7 },
+	// { "cam_cc_debug_mux", &gcc, 0x55 },
+	// { "disp_cc_debug_mux", &gcc, 0x56 },
+	{ "gcc_aggre_noc_pcie_tbu_clk", &gcc, 0x36 },
+	{ "gcc_aggre_ufs_card_axi_clk", &gcc, 0x142 },
+	{ "gcc_aggre_ufs_phy_axi_clk", &gcc, 0x141 },
+	{ "gcc_aggre_usb3_prim_axi_clk", &gcc, 0x13f },
+	{ "gcc_aggre_usb3_sec_axi_clk", &gcc, 0x140 },
+	{ "gcc_boot_rom_ahb_clk", &gcc, 0xa3 },
+	{ "gcc_camera_ahb_clk", &gcc, 0x44 },
+	{ "gcc_camera_hf_axi_clk", &gcc, 0x4d },
+	{ "gcc_camera_sf_axi_clk", &gcc, 0x4e },
+	{ "gcc_camera_xo_clk", &gcc, 0x52 },
+	{ "gcc_cfg_noc_usb3_prim_axi_clk", &gcc, 0x21 },
+	{ "gcc_cfg_noc_usb3_sec_axi_clk", &gcc, 0x22 },
+	{ "gcc_cpuss_ahb_clk", &gcc, 0xe0 },
+	{ "gcc_cpuss_dvm_bus_clk", &gcc, 0xe4 },
+	{ "gcc_cpuss_rbcpr_clk", &gcc, 0xe1 },
+	{ "gcc_ddrss_gpu_axi_clk", &gcc, 0xc4 },
+	{ "gcc_ddrss_pcie_sf_tbu_clk", &gcc, 0xc5 },
+	{ "gcc_disp_ahb_clk", &gcc, 0x45 },
+	{ "gcc_disp_hf_axi_clk", &gcc, 0x4f },
+	{ "gcc_disp_sf_axi_clk", &gcc, 0x50 },
+	{ "gcc_disp_xo_clk", &gcc, 0x53 },
+	{ "gcc_gp1_clk", &gcc, 0xef },
+	{ "gcc_gp2_clk", &gcc, 0xf0 },
+	{ "gcc_gp3_clk", &gcc, 0xf1 },
+	{ "gcc_gpu_cfg_ahb_clk", &gcc, 0x161 },
+	{ "gcc_gpu_gpll0_clk_src", &gcc, 0x167 },
+	{ "gcc_gpu_gpll0_div_clk_src", &gcc, 0x168 },
+	{ "gcc_gpu_memnoc_gfx_clk", &gcc, 0x164 },
+	{ "gcc_gpu_snoc_dvm_gfx_clk", &gcc, 0x166 },
+	{ "gcc_npu_axi_clk", &gcc, 0x17a },
+	{ "gcc_npu_bwmon_axi_clk", &gcc, 0x19a },
+	{ "gcc_npu_bwmon_cfg_ahb_clk", &gcc, 0x199 },
+	{ "gcc_npu_cfg_ahb_clk", &gcc, 0x179 },
+	{ "gcc_npu_dma_clk", &gcc, 0x17b },
+	{ "gcc_npu_gpll0_clk_src", &gcc, 0x17e },
+	{ "gcc_npu_gpll0_div_clk_src", &gcc, 0x17f },
+	{ "gcc_pcie0_phy_refgen_clk", &gcc, 0x103 },
+	{ "gcc_pcie1_phy_refgen_clk", &gcc, 0x104 },
+	{ "gcc_pcie2_phy_refgen_clk", &gcc, 0x105 },
+	{ "gcc_pcie_0_aux_clk", &gcc, 0xf6 },
+	{ "gcc_pcie_0_cfg_ahb_clk", &gcc, 0xf5 },
+	{ "gcc_pcie_0_mstr_axi_clk", &gcc, 0xf4 },
+	{ "gcc_pcie_0_pipe_clk", &gcc, 0xf7 },
+	{ "gcc_pcie_0_slv_axi_clk", &gcc, 0xf3 },
+	{ "gcc_pcie_0_slv_q2a_axi_clk", &gcc, 0xf2 },
+	{ "gcc_pcie_1_aux_clk", &gcc, 0xfe },
+	{ "gcc_pcie_1_cfg_ahb_clk", &gcc, 0xfd },
+	{ "gcc_pcie_1_mstr_axi_clk", &gcc, 0xfc },
+	{ "gcc_pcie_1_pipe_clk", &gcc, 0xff },
+	{ "gcc_pcie_1_slv_axi_clk", &gcc, 0xfb },
+	{ "gcc_pcie_1_slv_q2a_axi_clk", &gcc, 0xfa },
+	{ "gcc_pcie_2_aux_clk", &gcc, 0x191 },
+	{ "gcc_pcie_2_cfg_ahb_clk", &gcc, 0x190 },
+	{ "gcc_pcie_2_mstr_axi_clk", &gcc, 0x18f },
+	{ "gcc_pcie_2_pipe_clk", &gcc, 0x192 },
+	{ "gcc_pcie_2_slv_axi_clk", &gcc, 0x18e },
+	{ "gcc_pcie_2_slv_q2a_axi_clk", &gcc, 0x18d },
+	{ "gcc_pcie_phy_aux_clk", &gcc, 0x102 },
+	{ "gcc_pdm2_clk", &gcc, 0x9d },
+	{ "gcc_pdm_ahb_clk", &gcc, 0x9b },
+	{ "gcc_pdm_xo4_clk", &gcc, 0x9c },
+	{ "gcc_prng_ahb_clk", &gcc, 0x9e },
+	{ "gcc_qmip_camera_nrt_ahb_clk", &gcc, 0x48 },
+	{ "gcc_qmip_camera_rt_ahb_clk", &gcc, 0x49 },
+	{ "gcc_qmip_disp_ahb_clk", &gcc, 0x4a },
+	{ "gcc_qmip_video_cvp_ahb_clk", &gcc, 0x46 },
+	{ "gcc_qmip_video_vcodec_ahb_clk", &gcc, 0x47 },
+	{ "gcc_qupv3_wrap0_core_2x_clk", &gcc, 0x88 },
+	{ "gcc_qupv3_wrap0_core_clk", &gcc, 0x87 },
+	{ "gcc_qupv3_wrap0_s0_clk", &gcc, 0x89 },
+	{ "gcc_qupv3_wrap0_s1_clk", &gcc, 0x8a },
+	{ "gcc_qupv3_wrap0_s2_clk", &gcc, 0x8b },
+	{ "gcc_qupv3_wrap0_s3_clk", &gcc, 0x8c },
+	{ "gcc_qupv3_wrap0_s4_clk", &gcc, 0x8d },
+	{ "gcc_qupv3_wrap0_s5_clk", &gcc, 0x8e },
+	{ "gcc_qupv3_wrap0_s6_clk", &gcc, 0x8f },
+	{ "gcc_qupv3_wrap0_s7_clk", &gcc, 0x90 },
+	{ "gcc_qupv3_wrap1_core_2x_clk", &gcc, 0x94 },
+	{ "gcc_qupv3_wrap1_core_clk", &gcc, 0x93 },
+	{ "gcc_qupv3_wrap1_s0_clk", &gcc, 0x95 },
+	{ "gcc_qupv3_wrap1_s1_clk", &gcc, 0x96 },
+	{ "gcc_qupv3_wrap1_s2_clk", &gcc, 0x97 },
+	{ "gcc_qupv3_wrap1_s3_clk", &gcc, 0x98 },
+	{ "gcc_qupv3_wrap1_s4_clk", &gcc, 0x99 },
+	{ "gcc_qupv3_wrap1_s5_clk", &gcc, 0x9a },
+	{ "gcc_qupv3_wrap2_core_2x_clk", &gcc, 0x184 },
+	{ "gcc_qupv3_wrap2_core_clk", &gcc, 0x183 },
+	{ "gcc_qupv3_wrap2_s0_clk", &gcc, 0x185 },
+	{ "gcc_qupv3_wrap2_s1_clk", &gcc, 0x186 },
+	{ "gcc_qupv3_wrap2_s2_clk", &gcc, 0x187 },
+	{ "gcc_qupv3_wrap2_s3_clk", &gcc, 0x188 },
+	{ "gcc_qupv3_wrap2_s4_clk", &gcc, 0x189 },
+	{ "gcc_qupv3_wrap2_s5_clk", &gcc, 0x18a },
+	{ "gcc_qupv3_wrap_0_m_ahb_clk", &gcc, 0x85 },
+	{ "gcc_qupv3_wrap_0_s_ahb_clk", &gcc, 0x86 },
+	{ "gcc_qupv3_wrap_1_m_ahb_clk", &gcc, 0x91 },
+	{ "gcc_qupv3_wrap_1_s_ahb_clk", &gcc, 0x92 },
+	{ "gcc_qupv3_wrap_2_m_ahb_clk", &gcc, 0x181 },
+	{ "gcc_qupv3_wrap_2_s_ahb_clk", &gcc, 0x182 },
+	{ "gcc_sdcc2_ahb_clk", &gcc, 0x82 },
+	{ "gcc_sdcc2_apps_clk", &gcc, 0x81 },
+	{ "gcc_sdcc4_ahb_clk", &gcc, 0x84 },
+	{ "gcc_sdcc4_apps_clk", &gcc, 0x83 },
+	{ "gcc_sys_noc_cpuss_ahb_clk", &gcc, 0xc },
+	{ "gcc_tsif_ahb_clk", &gcc, 0x9f },
+	{ "gcc_tsif_inactivity_timers_clk", &gcc, 0xa1 },
+	{ "gcc_tsif_ref_clk", &gcc, 0xa0 },
+	{ "gcc_ufs_card_ahb_clk", &gcc, 0x107 },
+	{ "gcc_ufs_card_axi_clk", &gcc, 0x106 },
+	{ "gcc_ufs_card_ice_core_clk", &gcc, 0x10d },
+	{ "gcc_ufs_card_phy_aux_clk", &gcc, 0x10e },
+	{ "gcc_ufs_card_rx_symbol_0_clk", &gcc, 0x109 },
+	{ "gcc_ufs_card_rx_symbol_1_clk", &gcc, 0x10f },
+	{ "gcc_ufs_card_tx_symbol_0_clk", &gcc, 0x108 },
+	{ "gcc_ufs_card_unipro_core_clk", &gcc, 0x10c },
+	{ "gcc_ufs_phy_ahb_clk", &gcc, 0x113 },
+	{ "gcc_ufs_phy_axi_clk", &gcc, 0x112 },
+	{ "gcc_ufs_phy_ice_core_clk", &gcc, 0x119 },
+	{ "gcc_ufs_phy_phy_aux_clk", &gcc, 0x11a },
+	{ "gcc_ufs_phy_rx_symbol_0_clk", &gcc, 0x115 },
+	{ "gcc_ufs_phy_rx_symbol_1_clk", &gcc, 0x11b },
+	{ "gcc_ufs_phy_tx_symbol_0_clk", &gcc, 0x114 },
+	{ "gcc_ufs_phy_unipro_core_clk", &gcc, 0x118 },
+	{ "gcc_usb30_prim_master_clk", &gcc, 0x6e },
+	{ "gcc_usb30_prim_mock_utmi_clk", &gcc, 0x70 },
+	{ "gcc_usb30_prim_sleep_clk", &gcc, 0x6f },
+	{ "gcc_usb30_sec_master_clk", &gcc, 0x75 },
+	{ "gcc_usb30_sec_mock_utmi_clk", &gcc, 0x77 },
+	{ "gcc_usb30_sec_sleep_clk", &gcc, 0x76 },
+	{ "gcc_usb3_prim_phy_aux_clk", &gcc, 0x71 },
+	{ "gcc_usb3_prim_phy_com_aux_clk", &gcc, 0x72 },
+	{ "gcc_usb3_prim_phy_pipe_clk", &gcc, 0x73 },
+	{ "gcc_usb3_sec_phy_aux_clk", &gcc, 0x78 },
+	{ "gcc_usb3_sec_phy_com_aux_clk", &gcc, 0x79 },
+	{ "gcc_usb3_sec_phy_pipe_clk", &gcc, 0x7a },
+	{ "gcc_video_ahb_clk", &gcc, 0x43 },
+	{ "gcc_video_axi0_clk", &gcc, 0x4b },
+	{ "gcc_video_axi1_clk", &gcc, 0x4c },
+	{ "gcc_video_xo_clk", &gcc, 0x51 },
+	// { "gpu_cc_debug_mux", &gcc, 0x163 },
+	// { "mc_cc_debug_mux", &gcc, 0xd1 },
+	{ "measure_only_cnoc_clk", &gcc, 0x19 },
+	{ "measure_only_ipa_2x_clk", &gcc, 0x147 },
+	{ "measure_only_memnoc_clk", &gcc, 0xcc },
+	{ "measure_only_snoc_clk", &gcc, 0x7 },
+	// { "npu_cc_debug_mux", &gcc, 0x180 },
+	// { "video_cc_debug_mux", &gcc, 0x57 },
+
+	{ "gpu_cc_ahb_clk", &gcc, 0x163, &gpu_cc, 0x10 },
+	{ "gpu_cc_crc_ahb_clk", &gcc, 0x163, &gpu_cc, 0x11 },
+	{ "gpu_cc_cx_apb_clk", &gcc, 0x163, &gpu_cc, 0x14 },
+	{ "gpu_cc_cx_gmu_clk", &gcc, 0x163, &gpu_cc, 0x18 },
+	{ "gpu_cc_cx_qdss_at_clk", &gcc, 0x163, &gpu_cc, 0x12 },
+	{ "gpu_cc_cx_qdss_trig_clk", &gcc, 0x163, &gpu_cc, 0x17 },
+	{ "gpu_cc_cx_qdss_tsctr_clk", &gcc, 0x163, &gpu_cc, 0x13 },
+	{ "gpu_cc_cx_snoc_dvm_clk", &gcc, 0x163, &gpu_cc, 0x15 },
+	{ "gpu_cc_cxo_aon_clk", &gcc, 0x163, &gpu_cc, 0xa },
+	{ "gpu_cc_cxo_clk", &gcc, 0x163, &gpu_cc, 0x19 },
+	{ "gpu_cc_gx_gmu_clk", &gcc, 0x163, &gpu_cc, 0xf },
+	{ "gpu_cc_gx_qdss_tsctr_clk", &gcc, 0x163, &gpu_cc, 0xd },
+	{ "gpu_cc_gx_vsense_clk", &gcc, 0x163, &gpu_cc, 0xc },
+	{ "gpu_cc_sleep_clk", &gcc, 0x163, &gpu_cc, 0x16 },
+	{ "measure_only_gpu_cc_cx_gfx3d_clk", &gcc, 0x163, &gpu_cc, 0x1a },
+	{ "measure_only_gpu_cc_cx_gfx3d_slv_clk", &gcc, 0x163, &gpu_cc, 0x1b },
+	{ "measure_only_gpu_cc_gx_gfx3d_clk", &gcc, 0x163, &gpu_cc, 0xb },
+
+	{ "npu_cc_atb_clk", &gcc, 0x180, &npu_cc, 0x17 },
+	{ "npu_cc_bto_core_clk", &gcc, 0x180, &npu_cc, 0x19 },
+	{ "npu_cc_bwmon_clk", &gcc, 0x180, &npu_cc, 0x18 },
+	{ "npu_cc_cal_hm0_cdc_clk", &gcc, 0x180, &npu_cc, 0xb },
+	{ "npu_cc_cal_hm0_clk", &gcc, 0x180, &npu_cc, 0x2 },
+	{ "npu_cc_cal_hm0_dpm_ip_clk", &gcc, 0x180, &npu_cc, 0xc },
+	{ "npu_cc_cal_hm0_perf_cnt_clk", &gcc, 0x180, &npu_cc, 0xd },
+	{ "npu_cc_cal_hm1_cdc_clk", &gcc, 0x180, &npu_cc, 0xe },
+	{ "npu_cc_cal_hm1_clk", &gcc, 0x180, &npu_cc, 0x3 },
+	{ "npu_cc_cal_hm1_dpm_ip_clk", &gcc, 0x180, &npu_cc, 0xf },
+	{ "npu_cc_cal_hm1_perf_cnt_clk", &gcc, 0x180, &npu_cc, 0x10 },
+	{ "npu_cc_core_clk", &gcc, 0x180, &npu_cc, 0x4 },
+	{ "npu_cc_dl_dpm_clk", &gcc, 0x180, &npu_cc, 0x23 },
+	{ "npu_cc_dl_llm_clk", &gcc, 0x180, &npu_cc, 0x22 },
+	{ "npu_cc_dpm_clk", &gcc, 0x180, &npu_cc, 0x8 },
+	{ "npu_cc_dpm_temp_clk", &gcc, 0x180, &npu_cc, 0x14 },
+	{ "npu_cc_dpm_xo_clk", &gcc, 0x180, &npu_cc, 0xa },
+	{ "npu_cc_dsp_ahbm_clk", &gcc, 0x180, &npu_cc, 0x1c },
+	{ "npu_cc_dsp_ahbs_clk", &gcc, 0x180, &npu_cc, 0x1b },
+	{ "npu_cc_dsp_axi_clk", &gcc, 0x180, &npu_cc, 0x1e },
+	{ "npu_cc_dsp_bwmon_ahb_clk", &gcc, 0x180, &npu_cc, 0x1d },
+	{ "npu_cc_dsp_bwmon_clk", &gcc, 0x180, &npu_cc, 0x1f },
+	{ "npu_cc_isense_clk", &gcc, 0x180, &npu_cc, 0x7 },
+	{ "npu_cc_llm_clk", &gcc, 0x180, &npu_cc, 0x6 },
+	{ "npu_cc_llm_curr_clk", &gcc, 0x180, &npu_cc, 0x21 },
+	{ "npu_cc_llm_temp_clk", &gcc, 0x180, &npu_cc, 0x15 },
+	{ "npu_cc_llm_xo_clk", &gcc, 0x180, &npu_cc, 0x9 },
+	{ "npu_cc_noc_ahb_clk", &gcc, 0x180, &npu_cc, 0x13 },
+	{ "npu_cc_noc_axi_clk", &gcc, 0x180, &npu_cc, 0x12 },
+	{ "npu_cc_noc_dma_clk", &gcc, 0x180, &npu_cc, 0x11 },
+	{ "npu_cc_rsc_xo_clk", &gcc, 0x180, &npu_cc, 0x1a },
+	{ "npu_cc_s2p_clk", &gcc, 0x180, &npu_cc, 0x16 },
+	{ "npu_cc_xo_clk", &gcc, 0x180, &npu_cc, 0x1 },
+
+	//{ "video_cc_ahb_clk", &gcc, 0x57, &video_cc, 0x7 },
+	//{ "video_cc_mvs0_clk", &gcc, 0x57, &video_cc, 0x3 },
+	//{ "video_cc_mvs0c_clk", &gcc, 0x57, &video_cc, 0x1 },
+	//{ "video_cc_mvs1_clk", &gcc, 0x57, &video_cc, 0x5 },
+	//{ "video_cc_mvs1_div2_clk", &gcc, 0x57, &video_cc, 0x8 },
+	//{ "video_cc_mvs1c_clk", &gcc, 0x57, &video_cc, 0x9 },
+	//{ "video_cc_sleep_clk", &gcc, 0x57, &video_cc, 0xc },
+	//{ "video_cc_xo_clk", &gcc, 0x57, &video_cc, 0xb },
+
+	{ "measure_only_mccc_clk", &gcc, 0xd1, &mc_cc, 0x50 },
+
+	{ "measure_only_apcs_gold_post_acd_clk", &gcc, 0xe7, &apss_cc, 0x25, /* TODO: Are these pre_div_vals? */ 8 },
+	{ "measure_only_apcs_goldplus_post_acd_clk", &gcc, 0xe7, &apss_cc, 0x61, /* TODO: Are these pre_div_vals? */ 8 },
+	{ "measure_only_apcs_l3_post_acd_clk", &gcc, 0xe7, &apss_cc, 0x41, /* TODO: Are these pre_div_vals? */ 4 },
+	{ "measure_only_apcs_silver_post_acd_clk", &gcc, 0xe7, &apss_cc, 0x21, /* TODO: Are these pre_div_vals? */ 4 },
+
+	{}
+};
+
+struct debugcc_platform sm8250_debugcc = {
+	"sm8250",
+	sm8250_clocks,
+	sm8250_blocks,
+};