18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci *
48c2ecf20Sopenharmony_ci *  Copyright (C) 2011-2012 John Crispin <john@phrozen.org>
58c2ecf20Sopenharmony_ci *  Copyright (C) 2013-2015 Lantiq Beteiligungs-GmbH & Co.KG
68c2ecf20Sopenharmony_ci */
78c2ecf20Sopenharmony_ci
88c2ecf20Sopenharmony_ci#include <linux/ioport.h>
98c2ecf20Sopenharmony_ci#include <linux/export.h>
108c2ecf20Sopenharmony_ci#include <linux/clkdev.h>
118c2ecf20Sopenharmony_ci#include <linux/spinlock.h>
128c2ecf20Sopenharmony_ci#include <linux/of.h>
138c2ecf20Sopenharmony_ci#include <linux/of_platform.h>
148c2ecf20Sopenharmony_ci#include <linux/of_address.h>
158c2ecf20Sopenharmony_ci
168c2ecf20Sopenharmony_ci#include <lantiq_soc.h>
178c2ecf20Sopenharmony_ci
188c2ecf20Sopenharmony_ci#include "../clk.h"
198c2ecf20Sopenharmony_ci#include "../prom.h"
208c2ecf20Sopenharmony_ci
218c2ecf20Sopenharmony_ci/* clock control register for legacy */
228c2ecf20Sopenharmony_ci#define CGU_IFCCR	0x0018
238c2ecf20Sopenharmony_ci#define CGU_IFCCR_VR9	0x0024
248c2ecf20Sopenharmony_ci/* system clock register for legacy */
258c2ecf20Sopenharmony_ci#define CGU_SYS		0x0010
268c2ecf20Sopenharmony_ci/* pci control register */
278c2ecf20Sopenharmony_ci#define CGU_PCICR	0x0034
288c2ecf20Sopenharmony_ci#define CGU_PCICR_VR9	0x0038
298c2ecf20Sopenharmony_ci/* ephy configuration register */
308c2ecf20Sopenharmony_ci#define CGU_EPHY	0x10
318c2ecf20Sopenharmony_ci
328c2ecf20Sopenharmony_ci/* Legacy PMU register for ar9, ase, danube */
338c2ecf20Sopenharmony_ci/* power control register */
348c2ecf20Sopenharmony_ci#define PMU_PWDCR	0x1C
358c2ecf20Sopenharmony_ci/* power status register */
368c2ecf20Sopenharmony_ci#define PMU_PWDSR	0x20
378c2ecf20Sopenharmony_ci/* power control register */
388c2ecf20Sopenharmony_ci#define PMU_PWDCR1	0x24
398c2ecf20Sopenharmony_ci/* power status register */
408c2ecf20Sopenharmony_ci#define PMU_PWDSR1	0x28
418c2ecf20Sopenharmony_ci/* power control register */
428c2ecf20Sopenharmony_ci#define PWDCR(x) ((x) ? (PMU_PWDCR1) : (PMU_PWDCR))
438c2ecf20Sopenharmony_ci/* power status register */
448c2ecf20Sopenharmony_ci#define PWDSR(x) ((x) ? (PMU_PWDSR1) : (PMU_PWDSR))
458c2ecf20Sopenharmony_ci
468c2ecf20Sopenharmony_ci
478c2ecf20Sopenharmony_ci/* PMU register for ar10 and grx390 */
488c2ecf20Sopenharmony_ci
498c2ecf20Sopenharmony_ci/* First register set */
508c2ecf20Sopenharmony_ci#define PMU_CLK_SR	0x20 /* status */
518c2ecf20Sopenharmony_ci#define PMU_CLK_CR_A	0x24 /* Enable */
528c2ecf20Sopenharmony_ci#define PMU_CLK_CR_B	0x28 /* Disable */
538c2ecf20Sopenharmony_ci/* Second register set */
548c2ecf20Sopenharmony_ci#define PMU_CLK_SR1	0x30 /* status */
558c2ecf20Sopenharmony_ci#define PMU_CLK_CR1_A	0x34 /* Enable */
568c2ecf20Sopenharmony_ci#define PMU_CLK_CR1_B	0x38 /* Disable */
578c2ecf20Sopenharmony_ci/* Third register set */
588c2ecf20Sopenharmony_ci#define PMU_ANA_SR	0x40 /* status */
598c2ecf20Sopenharmony_ci#define PMU_ANA_CR_A	0x44 /* Enable */
608c2ecf20Sopenharmony_ci#define PMU_ANA_CR_B	0x48 /* Disable */
618c2ecf20Sopenharmony_ci
628c2ecf20Sopenharmony_ci/* Status */
638c2ecf20Sopenharmony_cistatic u32 pmu_clk_sr[] = {
648c2ecf20Sopenharmony_ci	PMU_CLK_SR,
658c2ecf20Sopenharmony_ci	PMU_CLK_SR1,
668c2ecf20Sopenharmony_ci	PMU_ANA_SR,
678c2ecf20Sopenharmony_ci};
688c2ecf20Sopenharmony_ci
698c2ecf20Sopenharmony_ci/* Enable */
708c2ecf20Sopenharmony_cistatic u32 pmu_clk_cr_a[] = {
718c2ecf20Sopenharmony_ci	PMU_CLK_CR_A,
728c2ecf20Sopenharmony_ci	PMU_CLK_CR1_A,
738c2ecf20Sopenharmony_ci	PMU_ANA_CR_A,
748c2ecf20Sopenharmony_ci};
758c2ecf20Sopenharmony_ci
768c2ecf20Sopenharmony_ci/* Disable */
778c2ecf20Sopenharmony_cistatic u32 pmu_clk_cr_b[] = {
788c2ecf20Sopenharmony_ci	PMU_CLK_CR_B,
798c2ecf20Sopenharmony_ci	PMU_CLK_CR1_B,
808c2ecf20Sopenharmony_ci	PMU_ANA_CR_B,
818c2ecf20Sopenharmony_ci};
828c2ecf20Sopenharmony_ci
838c2ecf20Sopenharmony_ci#define PWDCR_EN_XRX(x)		(pmu_clk_cr_a[(x)])
848c2ecf20Sopenharmony_ci#define PWDCR_DIS_XRX(x)	(pmu_clk_cr_b[(x)])
858c2ecf20Sopenharmony_ci#define PWDSR_XRX(x)		(pmu_clk_sr[(x)])
868c2ecf20Sopenharmony_ci
878c2ecf20Sopenharmony_ci/* clock gates that we can en/disable */
888c2ecf20Sopenharmony_ci#define PMU_USB0_P	BIT(0)
898c2ecf20Sopenharmony_ci#define PMU_ASE_SDIO	BIT(2) /* ASE special */
908c2ecf20Sopenharmony_ci#define PMU_PCI		BIT(4)
918c2ecf20Sopenharmony_ci#define PMU_DMA		BIT(5)
928c2ecf20Sopenharmony_ci#define PMU_USB0	BIT(6)
938c2ecf20Sopenharmony_ci#define PMU_ASC0	BIT(7)
948c2ecf20Sopenharmony_ci#define PMU_EPHY	BIT(7)	/* ase */
958c2ecf20Sopenharmony_ci#define PMU_USIF	BIT(7) /* from vr9 until grx390 */
968c2ecf20Sopenharmony_ci#define PMU_SPI		BIT(8)
978c2ecf20Sopenharmony_ci#define PMU_DFE		BIT(9)
988c2ecf20Sopenharmony_ci#define PMU_EBU		BIT(10)
998c2ecf20Sopenharmony_ci#define PMU_STP		BIT(11)
1008c2ecf20Sopenharmony_ci#define PMU_GPT		BIT(12)
1018c2ecf20Sopenharmony_ci#define PMU_AHBS	BIT(13) /* vr9 */
1028c2ecf20Sopenharmony_ci#define PMU_FPI		BIT(14)
1038c2ecf20Sopenharmony_ci#define PMU_AHBM	BIT(15)
1048c2ecf20Sopenharmony_ci#define PMU_SDIO	BIT(16) /* danube, ar9, vr9 */
1058c2ecf20Sopenharmony_ci#define PMU_ASC1	BIT(17)
1068c2ecf20Sopenharmony_ci#define PMU_PPE_QSB	BIT(18)
1078c2ecf20Sopenharmony_ci#define PMU_PPE_SLL01	BIT(19)
1088c2ecf20Sopenharmony_ci#define PMU_DEU		BIT(20)
1098c2ecf20Sopenharmony_ci#define PMU_PPE_TC	BIT(21)
1108c2ecf20Sopenharmony_ci#define PMU_PPE_EMA	BIT(22)
1118c2ecf20Sopenharmony_ci#define PMU_PPE_DPLUM	BIT(23)
1128c2ecf20Sopenharmony_ci#define PMU_PPE_DP	BIT(23)
1138c2ecf20Sopenharmony_ci#define PMU_PPE_DPLUS	BIT(24)
1148c2ecf20Sopenharmony_ci#define PMU_USB1_P	BIT(26)
1158c2ecf20Sopenharmony_ci#define PMU_GPHY3	BIT(26) /* grx390 */
1168c2ecf20Sopenharmony_ci#define PMU_USB1	BIT(27)
1178c2ecf20Sopenharmony_ci#define PMU_SWITCH	BIT(28)
1188c2ecf20Sopenharmony_ci#define PMU_PPE_TOP	BIT(29)
1198c2ecf20Sopenharmony_ci#define PMU_GPHY0	BIT(29) /* ar10, xrx390 */
1208c2ecf20Sopenharmony_ci#define PMU_GPHY	BIT(30)
1218c2ecf20Sopenharmony_ci#define PMU_GPHY1	BIT(30) /* ar10, xrx390 */
1228c2ecf20Sopenharmony_ci#define PMU_PCIE_CLK	BIT(31)
1238c2ecf20Sopenharmony_ci#define PMU_GPHY2	BIT(31) /* ar10, xrx390 */
1248c2ecf20Sopenharmony_ci
1258c2ecf20Sopenharmony_ci#define PMU1_PCIE_PHY	BIT(0)	/* vr9-specific,moved in ar10/grx390 */
1268c2ecf20Sopenharmony_ci#define PMU1_PCIE_CTL	BIT(1)
1278c2ecf20Sopenharmony_ci#define PMU1_PCIE_PDI	BIT(4)
1288c2ecf20Sopenharmony_ci#define PMU1_PCIE_MSI	BIT(5)
1298c2ecf20Sopenharmony_ci#define PMU1_CKE	BIT(6)
1308c2ecf20Sopenharmony_ci#define PMU1_PCIE1_CTL	BIT(17)
1318c2ecf20Sopenharmony_ci#define PMU1_PCIE1_PDI	BIT(20)
1328c2ecf20Sopenharmony_ci#define PMU1_PCIE1_MSI	BIT(21)
1338c2ecf20Sopenharmony_ci#define PMU1_PCIE2_CTL	BIT(25)
1348c2ecf20Sopenharmony_ci#define PMU1_PCIE2_PDI	BIT(26)
1358c2ecf20Sopenharmony_ci#define PMU1_PCIE2_MSI	BIT(27)
1368c2ecf20Sopenharmony_ci
1378c2ecf20Sopenharmony_ci#define PMU_ANALOG_USB0_P	BIT(0)
1388c2ecf20Sopenharmony_ci#define PMU_ANALOG_USB1_P	BIT(1)
1398c2ecf20Sopenharmony_ci#define PMU_ANALOG_PCIE0_P	BIT(8)
1408c2ecf20Sopenharmony_ci#define PMU_ANALOG_PCIE1_P	BIT(9)
1418c2ecf20Sopenharmony_ci#define PMU_ANALOG_PCIE2_P	BIT(10)
1428c2ecf20Sopenharmony_ci#define PMU_ANALOG_DSL_AFE	BIT(16)
1438c2ecf20Sopenharmony_ci#define PMU_ANALOG_DCDC_2V5	BIT(17)
1448c2ecf20Sopenharmony_ci#define PMU_ANALOG_DCDC_1VX	BIT(18)
1458c2ecf20Sopenharmony_ci#define PMU_ANALOG_DCDC_1V0	BIT(19)
1468c2ecf20Sopenharmony_ci
1478c2ecf20Sopenharmony_ci#define pmu_w32(x, y)	ltq_w32((x), pmu_membase + (y))
1488c2ecf20Sopenharmony_ci#define pmu_r32(x)	ltq_r32(pmu_membase + (x))
1498c2ecf20Sopenharmony_ci
1508c2ecf20Sopenharmony_cistatic void __iomem *pmu_membase;
1518c2ecf20Sopenharmony_civoid __iomem *ltq_cgu_membase;
1528c2ecf20Sopenharmony_civoid __iomem *ltq_ebu_membase;
1538c2ecf20Sopenharmony_ci
1548c2ecf20Sopenharmony_cistatic u32 ifccr = CGU_IFCCR;
1558c2ecf20Sopenharmony_cistatic u32 pcicr = CGU_PCICR;
1568c2ecf20Sopenharmony_ci
1578c2ecf20Sopenharmony_cistatic DEFINE_SPINLOCK(g_pmu_lock);
1588c2ecf20Sopenharmony_ci
1598c2ecf20Sopenharmony_ci/* legacy function kept alive to ease clkdev transition */
1608c2ecf20Sopenharmony_civoid ltq_pmu_enable(unsigned int module)
1618c2ecf20Sopenharmony_ci{
1628c2ecf20Sopenharmony_ci	int retry = 1000000;
1638c2ecf20Sopenharmony_ci
1648c2ecf20Sopenharmony_ci	spin_lock(&g_pmu_lock);
1658c2ecf20Sopenharmony_ci	pmu_w32(pmu_r32(PMU_PWDCR) & ~module, PMU_PWDCR);
1668c2ecf20Sopenharmony_ci	do {} while (--retry && (pmu_r32(PMU_PWDSR) & module));
1678c2ecf20Sopenharmony_ci	spin_unlock(&g_pmu_lock);
1688c2ecf20Sopenharmony_ci
1698c2ecf20Sopenharmony_ci	if (!retry)
1708c2ecf20Sopenharmony_ci		panic("activating PMU module failed!");
1718c2ecf20Sopenharmony_ci}
1728c2ecf20Sopenharmony_ciEXPORT_SYMBOL(ltq_pmu_enable);
1738c2ecf20Sopenharmony_ci
1748c2ecf20Sopenharmony_ci/* legacy function kept alive to ease clkdev transition */
1758c2ecf20Sopenharmony_civoid ltq_pmu_disable(unsigned int module)
1768c2ecf20Sopenharmony_ci{
1778c2ecf20Sopenharmony_ci	int retry = 1000000;
1788c2ecf20Sopenharmony_ci
1798c2ecf20Sopenharmony_ci	spin_lock(&g_pmu_lock);
1808c2ecf20Sopenharmony_ci	pmu_w32(pmu_r32(PMU_PWDCR) | module, PMU_PWDCR);
1818c2ecf20Sopenharmony_ci	do {} while (--retry && (!(pmu_r32(PMU_PWDSR) & module)));
1828c2ecf20Sopenharmony_ci	spin_unlock(&g_pmu_lock);
1838c2ecf20Sopenharmony_ci
1848c2ecf20Sopenharmony_ci	if (!retry)
1858c2ecf20Sopenharmony_ci		pr_warn("deactivating PMU module failed!");
1868c2ecf20Sopenharmony_ci}
1878c2ecf20Sopenharmony_ciEXPORT_SYMBOL(ltq_pmu_disable);
1888c2ecf20Sopenharmony_ci
1898c2ecf20Sopenharmony_ci/* enable a hw clock */
1908c2ecf20Sopenharmony_cistatic int cgu_enable(struct clk *clk)
1918c2ecf20Sopenharmony_ci{
1928c2ecf20Sopenharmony_ci	ltq_cgu_w32(ltq_cgu_r32(ifccr) | clk->bits, ifccr);
1938c2ecf20Sopenharmony_ci	return 0;
1948c2ecf20Sopenharmony_ci}
1958c2ecf20Sopenharmony_ci
1968c2ecf20Sopenharmony_ci/* disable a hw clock */
1978c2ecf20Sopenharmony_cistatic void cgu_disable(struct clk *clk)
1988c2ecf20Sopenharmony_ci{
1998c2ecf20Sopenharmony_ci	ltq_cgu_w32(ltq_cgu_r32(ifccr) & ~clk->bits, ifccr);
2008c2ecf20Sopenharmony_ci}
2018c2ecf20Sopenharmony_ci
2028c2ecf20Sopenharmony_ci/* enable a clock gate */
2038c2ecf20Sopenharmony_cistatic int pmu_enable(struct clk *clk)
2048c2ecf20Sopenharmony_ci{
2058c2ecf20Sopenharmony_ci	int retry = 1000000;
2068c2ecf20Sopenharmony_ci
2078c2ecf20Sopenharmony_ci	if (of_machine_is_compatible("lantiq,ar10")
2088c2ecf20Sopenharmony_ci	    || of_machine_is_compatible("lantiq,grx390")) {
2098c2ecf20Sopenharmony_ci		pmu_w32(clk->bits, PWDCR_EN_XRX(clk->module));
2108c2ecf20Sopenharmony_ci		do {} while (--retry &&
2118c2ecf20Sopenharmony_ci			     (!(pmu_r32(PWDSR_XRX(clk->module)) & clk->bits)));
2128c2ecf20Sopenharmony_ci
2138c2ecf20Sopenharmony_ci	} else {
2148c2ecf20Sopenharmony_ci		spin_lock(&g_pmu_lock);
2158c2ecf20Sopenharmony_ci		pmu_w32(pmu_r32(PWDCR(clk->module)) & ~clk->bits,
2168c2ecf20Sopenharmony_ci				PWDCR(clk->module));
2178c2ecf20Sopenharmony_ci		do {} while (--retry &&
2188c2ecf20Sopenharmony_ci			     (pmu_r32(PWDSR(clk->module)) & clk->bits));
2198c2ecf20Sopenharmony_ci		spin_unlock(&g_pmu_lock);
2208c2ecf20Sopenharmony_ci	}
2218c2ecf20Sopenharmony_ci
2228c2ecf20Sopenharmony_ci	if (!retry)
2238c2ecf20Sopenharmony_ci		panic("activating PMU module failed!");
2248c2ecf20Sopenharmony_ci
2258c2ecf20Sopenharmony_ci	return 0;
2268c2ecf20Sopenharmony_ci}
2278c2ecf20Sopenharmony_ci
2288c2ecf20Sopenharmony_ci/* disable a clock gate */
2298c2ecf20Sopenharmony_cistatic void pmu_disable(struct clk *clk)
2308c2ecf20Sopenharmony_ci{
2318c2ecf20Sopenharmony_ci	int retry = 1000000;
2328c2ecf20Sopenharmony_ci
2338c2ecf20Sopenharmony_ci	if (of_machine_is_compatible("lantiq,ar10")
2348c2ecf20Sopenharmony_ci	    || of_machine_is_compatible("lantiq,grx390")) {
2358c2ecf20Sopenharmony_ci		pmu_w32(clk->bits, PWDCR_DIS_XRX(clk->module));
2368c2ecf20Sopenharmony_ci		do {} while (--retry &&
2378c2ecf20Sopenharmony_ci			     (pmu_r32(PWDSR_XRX(clk->module)) & clk->bits));
2388c2ecf20Sopenharmony_ci	} else {
2398c2ecf20Sopenharmony_ci		spin_lock(&g_pmu_lock);
2408c2ecf20Sopenharmony_ci		pmu_w32(pmu_r32(PWDCR(clk->module)) | clk->bits,
2418c2ecf20Sopenharmony_ci				PWDCR(clk->module));
2428c2ecf20Sopenharmony_ci		do {} while (--retry &&
2438c2ecf20Sopenharmony_ci			     (!(pmu_r32(PWDSR(clk->module)) & clk->bits)));
2448c2ecf20Sopenharmony_ci		spin_unlock(&g_pmu_lock);
2458c2ecf20Sopenharmony_ci	}
2468c2ecf20Sopenharmony_ci
2478c2ecf20Sopenharmony_ci	if (!retry)
2488c2ecf20Sopenharmony_ci		pr_warn("deactivating PMU module failed!");
2498c2ecf20Sopenharmony_ci}
2508c2ecf20Sopenharmony_ci
2518c2ecf20Sopenharmony_ci/* the pci enable helper */
2528c2ecf20Sopenharmony_cistatic int pci_enable(struct clk *clk)
2538c2ecf20Sopenharmony_ci{
2548c2ecf20Sopenharmony_ci	unsigned int val = ltq_cgu_r32(ifccr);
2558c2ecf20Sopenharmony_ci	/* set bus clock speed */
2568c2ecf20Sopenharmony_ci	if (of_machine_is_compatible("lantiq,ar9") ||
2578c2ecf20Sopenharmony_ci			of_machine_is_compatible("lantiq,vr9")) {
2588c2ecf20Sopenharmony_ci		val &= ~0x1f00000;
2598c2ecf20Sopenharmony_ci		if (clk->rate == CLOCK_33M)
2608c2ecf20Sopenharmony_ci			val |= 0xe00000;
2618c2ecf20Sopenharmony_ci		else
2628c2ecf20Sopenharmony_ci			val |= 0x700000; /* 62.5M */
2638c2ecf20Sopenharmony_ci	} else {
2648c2ecf20Sopenharmony_ci		val &= ~0xf00000;
2658c2ecf20Sopenharmony_ci		if (clk->rate == CLOCK_33M)
2668c2ecf20Sopenharmony_ci			val |= 0x800000;
2678c2ecf20Sopenharmony_ci		else
2688c2ecf20Sopenharmony_ci			val |= 0x400000; /* 62.5M */
2698c2ecf20Sopenharmony_ci	}
2708c2ecf20Sopenharmony_ci	ltq_cgu_w32(val, ifccr);
2718c2ecf20Sopenharmony_ci	pmu_enable(clk);
2728c2ecf20Sopenharmony_ci	return 0;
2738c2ecf20Sopenharmony_ci}
2748c2ecf20Sopenharmony_ci
2758c2ecf20Sopenharmony_ci/* enable the external clock as a source */
2768c2ecf20Sopenharmony_cistatic int pci_ext_enable(struct clk *clk)
2778c2ecf20Sopenharmony_ci{
2788c2ecf20Sopenharmony_ci	ltq_cgu_w32(ltq_cgu_r32(ifccr) & ~(1 << 16), ifccr);
2798c2ecf20Sopenharmony_ci	ltq_cgu_w32((1 << 30), pcicr);
2808c2ecf20Sopenharmony_ci	return 0;
2818c2ecf20Sopenharmony_ci}
2828c2ecf20Sopenharmony_ci
2838c2ecf20Sopenharmony_ci/* disable the external clock as a source */
2848c2ecf20Sopenharmony_cistatic void pci_ext_disable(struct clk *clk)
2858c2ecf20Sopenharmony_ci{
2868c2ecf20Sopenharmony_ci	ltq_cgu_w32(ltq_cgu_r32(ifccr) | (1 << 16), ifccr);
2878c2ecf20Sopenharmony_ci	ltq_cgu_w32((1 << 31) | (1 << 30), pcicr);
2888c2ecf20Sopenharmony_ci}
2898c2ecf20Sopenharmony_ci
2908c2ecf20Sopenharmony_ci/* enable a clockout source */
2918c2ecf20Sopenharmony_cistatic int clkout_enable(struct clk *clk)
2928c2ecf20Sopenharmony_ci{
2938c2ecf20Sopenharmony_ci	int i;
2948c2ecf20Sopenharmony_ci
2958c2ecf20Sopenharmony_ci	/* get the correct rate */
2968c2ecf20Sopenharmony_ci	for (i = 0; i < 4; i++) {
2978c2ecf20Sopenharmony_ci		if (clk->rates[i] == clk->rate) {
2988c2ecf20Sopenharmony_ci			int shift = 14 - (2 * clk->module);
2998c2ecf20Sopenharmony_ci			int enable = 7 - clk->module;
3008c2ecf20Sopenharmony_ci			unsigned int val = ltq_cgu_r32(ifccr);
3018c2ecf20Sopenharmony_ci
3028c2ecf20Sopenharmony_ci			val &= ~(3 << shift);
3038c2ecf20Sopenharmony_ci			val |= i << shift;
3048c2ecf20Sopenharmony_ci			val |= enable;
3058c2ecf20Sopenharmony_ci			ltq_cgu_w32(val, ifccr);
3068c2ecf20Sopenharmony_ci			return 0;
3078c2ecf20Sopenharmony_ci		}
3088c2ecf20Sopenharmony_ci	}
3098c2ecf20Sopenharmony_ci	return -1;
3108c2ecf20Sopenharmony_ci}
3118c2ecf20Sopenharmony_ci
3128c2ecf20Sopenharmony_ci/* manage the clock gates via PMU */
3138c2ecf20Sopenharmony_cistatic void clkdev_add_pmu(const char *dev, const char *con, bool deactivate,
3148c2ecf20Sopenharmony_ci			   unsigned int module, unsigned int bits)
3158c2ecf20Sopenharmony_ci{
3168c2ecf20Sopenharmony_ci	struct clk *clk = kzalloc(sizeof(struct clk), GFP_KERNEL);
3178c2ecf20Sopenharmony_ci
3188c2ecf20Sopenharmony_ci	if (!clk)
3198c2ecf20Sopenharmony_ci		return;
3208c2ecf20Sopenharmony_ci	clk->cl.dev_id = dev;
3218c2ecf20Sopenharmony_ci	clk->cl.con_id = con;
3228c2ecf20Sopenharmony_ci	clk->cl.clk = clk;
3238c2ecf20Sopenharmony_ci	clk->enable = pmu_enable;
3248c2ecf20Sopenharmony_ci	clk->disable = pmu_disable;
3258c2ecf20Sopenharmony_ci	clk->module = module;
3268c2ecf20Sopenharmony_ci	clk->bits = bits;
3278c2ecf20Sopenharmony_ci	if (deactivate) {
3288c2ecf20Sopenharmony_ci		/*
3298c2ecf20Sopenharmony_ci		 * Disable it during the initialization. Module should enable
3308c2ecf20Sopenharmony_ci		 * when used
3318c2ecf20Sopenharmony_ci		 */
3328c2ecf20Sopenharmony_ci		pmu_disable(clk);
3338c2ecf20Sopenharmony_ci	}
3348c2ecf20Sopenharmony_ci	clkdev_add(&clk->cl);
3358c2ecf20Sopenharmony_ci}
3368c2ecf20Sopenharmony_ci
3378c2ecf20Sopenharmony_ci/* manage the clock generator */
3388c2ecf20Sopenharmony_cistatic void clkdev_add_cgu(const char *dev, const char *con,
3398c2ecf20Sopenharmony_ci					unsigned int bits)
3408c2ecf20Sopenharmony_ci{
3418c2ecf20Sopenharmony_ci	struct clk *clk = kzalloc(sizeof(struct clk), GFP_KERNEL);
3428c2ecf20Sopenharmony_ci
3438c2ecf20Sopenharmony_ci	if (!clk)
3448c2ecf20Sopenharmony_ci		return;
3458c2ecf20Sopenharmony_ci	clk->cl.dev_id = dev;
3468c2ecf20Sopenharmony_ci	clk->cl.con_id = con;
3478c2ecf20Sopenharmony_ci	clk->cl.clk = clk;
3488c2ecf20Sopenharmony_ci	clk->enable = cgu_enable;
3498c2ecf20Sopenharmony_ci	clk->disable = cgu_disable;
3508c2ecf20Sopenharmony_ci	clk->bits = bits;
3518c2ecf20Sopenharmony_ci	clkdev_add(&clk->cl);
3528c2ecf20Sopenharmony_ci}
3538c2ecf20Sopenharmony_ci
3548c2ecf20Sopenharmony_ci/* pci needs its own enable function as the setup is a bit more complex */
3558c2ecf20Sopenharmony_cistatic unsigned long valid_pci_rates[] = {CLOCK_33M, CLOCK_62_5M, 0};
3568c2ecf20Sopenharmony_ci
3578c2ecf20Sopenharmony_cistatic void clkdev_add_pci(void)
3588c2ecf20Sopenharmony_ci{
3598c2ecf20Sopenharmony_ci	struct clk *clk = kzalloc(sizeof(struct clk), GFP_KERNEL);
3608c2ecf20Sopenharmony_ci	struct clk *clk_ext = kzalloc(sizeof(struct clk), GFP_KERNEL);
3618c2ecf20Sopenharmony_ci
3628c2ecf20Sopenharmony_ci	/* main pci clock */
3638c2ecf20Sopenharmony_ci	if (clk) {
3648c2ecf20Sopenharmony_ci		clk->cl.dev_id = "17000000.pci";
3658c2ecf20Sopenharmony_ci		clk->cl.con_id = NULL;
3668c2ecf20Sopenharmony_ci		clk->cl.clk = clk;
3678c2ecf20Sopenharmony_ci		clk->rate = CLOCK_33M;
3688c2ecf20Sopenharmony_ci		clk->rates = valid_pci_rates;
3698c2ecf20Sopenharmony_ci		clk->enable = pci_enable;
3708c2ecf20Sopenharmony_ci		clk->disable = pmu_disable;
3718c2ecf20Sopenharmony_ci		clk->module = 0;
3728c2ecf20Sopenharmony_ci		clk->bits = PMU_PCI;
3738c2ecf20Sopenharmony_ci		clkdev_add(&clk->cl);
3748c2ecf20Sopenharmony_ci	}
3758c2ecf20Sopenharmony_ci
3768c2ecf20Sopenharmony_ci	/* use internal/external bus clock */
3778c2ecf20Sopenharmony_ci	if (clk_ext) {
3788c2ecf20Sopenharmony_ci		clk_ext->cl.dev_id = "17000000.pci";
3798c2ecf20Sopenharmony_ci		clk_ext->cl.con_id = "external";
3808c2ecf20Sopenharmony_ci		clk_ext->cl.clk = clk_ext;
3818c2ecf20Sopenharmony_ci		clk_ext->enable = pci_ext_enable;
3828c2ecf20Sopenharmony_ci		clk_ext->disable = pci_ext_disable;
3838c2ecf20Sopenharmony_ci		clkdev_add(&clk_ext->cl);
3848c2ecf20Sopenharmony_ci	}
3858c2ecf20Sopenharmony_ci}
3868c2ecf20Sopenharmony_ci
3878c2ecf20Sopenharmony_ci/* xway socs can generate clocks on gpio pins */
3888c2ecf20Sopenharmony_cistatic unsigned long valid_clkout_rates[4][5] = {
3898c2ecf20Sopenharmony_ci	{CLOCK_32_768K, CLOCK_1_536M, CLOCK_2_5M, CLOCK_12M, 0},
3908c2ecf20Sopenharmony_ci	{CLOCK_40M, CLOCK_12M, CLOCK_24M, CLOCK_48M, 0},
3918c2ecf20Sopenharmony_ci	{CLOCK_25M, CLOCK_40M, CLOCK_30M, CLOCK_60M, 0},
3928c2ecf20Sopenharmony_ci	{CLOCK_12M, CLOCK_50M, CLOCK_32_768K, CLOCK_25M, 0},
3938c2ecf20Sopenharmony_ci};
3948c2ecf20Sopenharmony_ci
3958c2ecf20Sopenharmony_cistatic void clkdev_add_clkout(void)
3968c2ecf20Sopenharmony_ci{
3978c2ecf20Sopenharmony_ci	int i;
3988c2ecf20Sopenharmony_ci
3998c2ecf20Sopenharmony_ci	for (i = 0; i < 4; i++) {
4008c2ecf20Sopenharmony_ci		struct clk *clk;
4018c2ecf20Sopenharmony_ci		char *name;
4028c2ecf20Sopenharmony_ci
4038c2ecf20Sopenharmony_ci		name = kzalloc(sizeof("clkout0"), GFP_KERNEL);
4048c2ecf20Sopenharmony_ci		if (!name)
4058c2ecf20Sopenharmony_ci			continue;
4068c2ecf20Sopenharmony_ci		sprintf(name, "clkout%d", i);
4078c2ecf20Sopenharmony_ci
4088c2ecf20Sopenharmony_ci		clk = kzalloc(sizeof(struct clk), GFP_KERNEL);
4098c2ecf20Sopenharmony_ci		if (!clk) {
4108c2ecf20Sopenharmony_ci			kfree(name);
4118c2ecf20Sopenharmony_ci			continue;
4128c2ecf20Sopenharmony_ci		}
4138c2ecf20Sopenharmony_ci		clk->cl.dev_id = "1f103000.cgu";
4148c2ecf20Sopenharmony_ci		clk->cl.con_id = name;
4158c2ecf20Sopenharmony_ci		clk->cl.clk = clk;
4168c2ecf20Sopenharmony_ci		clk->rate = 0;
4178c2ecf20Sopenharmony_ci		clk->rates = valid_clkout_rates[i];
4188c2ecf20Sopenharmony_ci		clk->enable = clkout_enable;
4198c2ecf20Sopenharmony_ci		clk->module = i;
4208c2ecf20Sopenharmony_ci		clkdev_add(&clk->cl);
4218c2ecf20Sopenharmony_ci	}
4228c2ecf20Sopenharmony_ci}
4238c2ecf20Sopenharmony_ci
4248c2ecf20Sopenharmony_ci/* bring up all register ranges that we need for basic system control */
4258c2ecf20Sopenharmony_civoid __init ltq_soc_init(void)
4268c2ecf20Sopenharmony_ci{
4278c2ecf20Sopenharmony_ci	struct resource res_pmu, res_cgu, res_ebu;
4288c2ecf20Sopenharmony_ci	struct device_node *np_pmu =
4298c2ecf20Sopenharmony_ci			of_find_compatible_node(NULL, NULL, "lantiq,pmu-xway");
4308c2ecf20Sopenharmony_ci	struct device_node *np_cgu =
4318c2ecf20Sopenharmony_ci			of_find_compatible_node(NULL, NULL, "lantiq,cgu-xway");
4328c2ecf20Sopenharmony_ci	struct device_node *np_ebu =
4338c2ecf20Sopenharmony_ci			of_find_compatible_node(NULL, NULL, "lantiq,ebu-xway");
4348c2ecf20Sopenharmony_ci
4358c2ecf20Sopenharmony_ci	/* check if all the core register ranges are available */
4368c2ecf20Sopenharmony_ci	if (!np_pmu || !np_cgu || !np_ebu)
4378c2ecf20Sopenharmony_ci		panic("Failed to load core nodes from devicetree");
4388c2ecf20Sopenharmony_ci
4398c2ecf20Sopenharmony_ci	if (of_address_to_resource(np_pmu, 0, &res_pmu) ||
4408c2ecf20Sopenharmony_ci			of_address_to_resource(np_cgu, 0, &res_cgu) ||
4418c2ecf20Sopenharmony_ci			of_address_to_resource(np_ebu, 0, &res_ebu))
4428c2ecf20Sopenharmony_ci		panic("Failed to get core resources");
4438c2ecf20Sopenharmony_ci
4448c2ecf20Sopenharmony_ci	if (!request_mem_region(res_pmu.start, resource_size(&res_pmu),
4458c2ecf20Sopenharmony_ci				res_pmu.name) ||
4468c2ecf20Sopenharmony_ci		!request_mem_region(res_cgu.start, resource_size(&res_cgu),
4478c2ecf20Sopenharmony_ci				res_cgu.name) ||
4488c2ecf20Sopenharmony_ci		!request_mem_region(res_ebu.start, resource_size(&res_ebu),
4498c2ecf20Sopenharmony_ci				res_ebu.name))
4508c2ecf20Sopenharmony_ci		pr_err("Failed to request core resources");
4518c2ecf20Sopenharmony_ci
4528c2ecf20Sopenharmony_ci	pmu_membase = ioremap(res_pmu.start, resource_size(&res_pmu));
4538c2ecf20Sopenharmony_ci	ltq_cgu_membase = ioremap(res_cgu.start,
4548c2ecf20Sopenharmony_ci						resource_size(&res_cgu));
4558c2ecf20Sopenharmony_ci	ltq_ebu_membase = ioremap(res_ebu.start,
4568c2ecf20Sopenharmony_ci						resource_size(&res_ebu));
4578c2ecf20Sopenharmony_ci	if (!pmu_membase || !ltq_cgu_membase || !ltq_ebu_membase)
4588c2ecf20Sopenharmony_ci		panic("Failed to remap core resources");
4598c2ecf20Sopenharmony_ci
4608c2ecf20Sopenharmony_ci	/* make sure to unprotect the memory region where flash is located */
4618c2ecf20Sopenharmony_ci	ltq_ebu_w32(ltq_ebu_r32(LTQ_EBU_BUSCON0) & ~EBU_WRDIS, LTQ_EBU_BUSCON0);
4628c2ecf20Sopenharmony_ci
4638c2ecf20Sopenharmony_ci	/* add our generic xway clocks */
4648c2ecf20Sopenharmony_ci	clkdev_add_pmu("10000000.fpi", NULL, 0, 0, PMU_FPI);
4658c2ecf20Sopenharmony_ci	clkdev_add_pmu("1e100a00.gptu", NULL, 1, 0, PMU_GPT);
4668c2ecf20Sopenharmony_ci	clkdev_add_pmu("1e100bb0.stp", NULL, 1, 0, PMU_STP);
4678c2ecf20Sopenharmony_ci	clkdev_add_pmu("1e100c00.serial", NULL, 0, 0, PMU_ASC1);
4688c2ecf20Sopenharmony_ci	clkdev_add_pmu("1e104100.dma", NULL, 1, 0, PMU_DMA);
4698c2ecf20Sopenharmony_ci	clkdev_add_pmu("1e100800.spi", NULL, 1, 0, PMU_SPI);
4708c2ecf20Sopenharmony_ci	clkdev_add_pmu("1e105300.ebu", NULL, 0, 0, PMU_EBU);
4718c2ecf20Sopenharmony_ci	clkdev_add_clkout();
4728c2ecf20Sopenharmony_ci
4738c2ecf20Sopenharmony_ci	/* add the soc dependent clocks */
4748c2ecf20Sopenharmony_ci	if (of_machine_is_compatible("lantiq,vr9")) {
4758c2ecf20Sopenharmony_ci		ifccr = CGU_IFCCR_VR9;
4768c2ecf20Sopenharmony_ci		pcicr = CGU_PCICR_VR9;
4778c2ecf20Sopenharmony_ci	} else {
4788c2ecf20Sopenharmony_ci		clkdev_add_pmu("1e180000.etop", NULL, 1, 0, PMU_PPE);
4798c2ecf20Sopenharmony_ci	}
4808c2ecf20Sopenharmony_ci
4818c2ecf20Sopenharmony_ci	if (!of_machine_is_compatible("lantiq,ase"))
4828c2ecf20Sopenharmony_ci		clkdev_add_pci();
4838c2ecf20Sopenharmony_ci
4848c2ecf20Sopenharmony_ci	if (of_machine_is_compatible("lantiq,grx390") ||
4858c2ecf20Sopenharmony_ci	    of_machine_is_compatible("lantiq,ar10")) {
4868c2ecf20Sopenharmony_ci		clkdev_add_pmu("1e108000.switch", "gphy0", 0, 0, PMU_GPHY0);
4878c2ecf20Sopenharmony_ci		clkdev_add_pmu("1e108000.switch", "gphy1", 0, 0, PMU_GPHY1);
4888c2ecf20Sopenharmony_ci		clkdev_add_pmu("1e108000.switch", "gphy2", 0, 0, PMU_GPHY2);
4898c2ecf20Sopenharmony_ci		clkdev_add_pmu("1f203018.usb2-phy", "phy", 1, 2, PMU_ANALOG_USB0_P);
4908c2ecf20Sopenharmony_ci		clkdev_add_pmu("1f203034.usb2-phy", "phy", 1, 2, PMU_ANALOG_USB1_P);
4918c2ecf20Sopenharmony_ci		/* rc 0 */
4928c2ecf20Sopenharmony_ci		clkdev_add_pmu("1f106800.phy", "phy", 1, 2, PMU_ANALOG_PCIE0_P);
4938c2ecf20Sopenharmony_ci		clkdev_add_pmu("1d900000.pcie", "msi", 1, 1, PMU1_PCIE_MSI);
4948c2ecf20Sopenharmony_ci		clkdev_add_pmu("1f106800.phy", "pdi", 1, 1, PMU1_PCIE_PDI);
4958c2ecf20Sopenharmony_ci		clkdev_add_pmu("1d900000.pcie", "ctl", 1, 1, PMU1_PCIE_CTL);
4968c2ecf20Sopenharmony_ci		/* rc 1 */
4978c2ecf20Sopenharmony_ci		clkdev_add_pmu("1f700400.phy", "phy", 1, 2, PMU_ANALOG_PCIE1_P);
4988c2ecf20Sopenharmony_ci		clkdev_add_pmu("19000000.pcie", "msi", 1, 1, PMU1_PCIE1_MSI);
4998c2ecf20Sopenharmony_ci		clkdev_add_pmu("1f700400.phy", "pdi", 1, 1, PMU1_PCIE1_PDI);
5008c2ecf20Sopenharmony_ci		clkdev_add_pmu("19000000.pcie", "ctl", 1, 1, PMU1_PCIE1_CTL);
5018c2ecf20Sopenharmony_ci	}
5028c2ecf20Sopenharmony_ci
5038c2ecf20Sopenharmony_ci	if (of_machine_is_compatible("lantiq,ase")) {
5048c2ecf20Sopenharmony_ci		if (ltq_cgu_r32(CGU_SYS) & (1 << 5))
5058c2ecf20Sopenharmony_ci			clkdev_add_static(CLOCK_266M, CLOCK_133M,
5068c2ecf20Sopenharmony_ci						CLOCK_133M, CLOCK_266M);
5078c2ecf20Sopenharmony_ci		else
5088c2ecf20Sopenharmony_ci			clkdev_add_static(CLOCK_133M, CLOCK_133M,
5098c2ecf20Sopenharmony_ci						CLOCK_133M, CLOCK_133M);
5108c2ecf20Sopenharmony_ci		clkdev_add_pmu("1e101000.usb", "otg", 1, 0, PMU_USB0);
5118c2ecf20Sopenharmony_ci		clkdev_add_pmu("1f203018.usb2-phy", "phy", 1, 0, PMU_USB0_P);
5128c2ecf20Sopenharmony_ci		clkdev_add_pmu("1e180000.etop", "ppe", 1, 0, PMU_PPE);
5138c2ecf20Sopenharmony_ci		clkdev_add_cgu("1e180000.etop", "ephycgu", CGU_EPHY);
5148c2ecf20Sopenharmony_ci		clkdev_add_pmu("1e180000.etop", "ephy", 1, 0, PMU_EPHY);
5158c2ecf20Sopenharmony_ci		clkdev_add_pmu("1e103000.sdio", NULL, 1, 0, PMU_ASE_SDIO);
5168c2ecf20Sopenharmony_ci		clkdev_add_pmu("1e116000.mei", "dfe", 1, 0, PMU_DFE);
5178c2ecf20Sopenharmony_ci	} else if (of_machine_is_compatible("lantiq,grx390")) {
5188c2ecf20Sopenharmony_ci		clkdev_add_static(ltq_grx390_cpu_hz(), ltq_grx390_fpi_hz(),
5198c2ecf20Sopenharmony_ci				  ltq_grx390_fpi_hz(), ltq_grx390_pp32_hz());
5208c2ecf20Sopenharmony_ci		clkdev_add_pmu("1e108000.switch", "gphy3", 0, 0, PMU_GPHY3);
5218c2ecf20Sopenharmony_ci		clkdev_add_pmu("1e101000.usb", "otg", 1, 0, PMU_USB0);
5228c2ecf20Sopenharmony_ci		clkdev_add_pmu("1e106000.usb", "otg", 1, 0, PMU_USB1);
5238c2ecf20Sopenharmony_ci		/* rc 2 */
5248c2ecf20Sopenharmony_ci		clkdev_add_pmu("1f106a00.pcie", "phy", 1, 2, PMU_ANALOG_PCIE2_P);
5258c2ecf20Sopenharmony_ci		clkdev_add_pmu("1a800000.pcie", "msi", 1, 1, PMU1_PCIE2_MSI);
5268c2ecf20Sopenharmony_ci		clkdev_add_pmu("1f106a00.pcie", "pdi", 1, 1, PMU1_PCIE2_PDI);
5278c2ecf20Sopenharmony_ci		clkdev_add_pmu("1a800000.pcie", "ctl", 1, 1, PMU1_PCIE2_CTL);
5288c2ecf20Sopenharmony_ci		clkdev_add_pmu("1e10b308.eth", NULL, 0, 0, PMU_SWITCH | PMU_PPE_DP);
5298c2ecf20Sopenharmony_ci		clkdev_add_pmu("1da00000.usif", "NULL", 1, 0, PMU_USIF);
5308c2ecf20Sopenharmony_ci		clkdev_add_pmu("1e103100.deu", NULL, 1, 0, PMU_DEU);
5318c2ecf20Sopenharmony_ci	} else if (of_machine_is_compatible("lantiq,ar10")) {
5328c2ecf20Sopenharmony_ci		clkdev_add_static(ltq_ar10_cpu_hz(), ltq_ar10_fpi_hz(),
5338c2ecf20Sopenharmony_ci				  ltq_ar10_fpi_hz(), ltq_ar10_pp32_hz());
5348c2ecf20Sopenharmony_ci		clkdev_add_pmu("1e101000.usb", "otg", 1, 0, PMU_USB0);
5358c2ecf20Sopenharmony_ci		clkdev_add_pmu("1e106000.usb", "otg", 1, 0, PMU_USB1);
5368c2ecf20Sopenharmony_ci		clkdev_add_pmu("1e10b308.eth", NULL, 0, 0, PMU_SWITCH |
5378c2ecf20Sopenharmony_ci			       PMU_PPE_DP | PMU_PPE_TC);
5388c2ecf20Sopenharmony_ci		clkdev_add_pmu("1da00000.usif", "NULL", 1, 0, PMU_USIF);
5398c2ecf20Sopenharmony_ci		clkdev_add_pmu("1e103100.deu", NULL, 1, 0, PMU_DEU);
5408c2ecf20Sopenharmony_ci		clkdev_add_pmu("1e116000.mei", "afe", 1, 2, PMU_ANALOG_DSL_AFE);
5418c2ecf20Sopenharmony_ci		clkdev_add_pmu("1e116000.mei", "dfe", 1, 0, PMU_DFE);
5428c2ecf20Sopenharmony_ci	} else if (of_machine_is_compatible("lantiq,vr9")) {
5438c2ecf20Sopenharmony_ci		clkdev_add_static(ltq_vr9_cpu_hz(), ltq_vr9_fpi_hz(),
5448c2ecf20Sopenharmony_ci				ltq_vr9_fpi_hz(), ltq_vr9_pp32_hz());
5458c2ecf20Sopenharmony_ci		clkdev_add_pmu("1f203018.usb2-phy", "phy", 1, 0, PMU_USB0_P);
5468c2ecf20Sopenharmony_ci		clkdev_add_pmu("1e101000.usb", "otg", 1, 0, PMU_USB0 | PMU_AHBM);
5478c2ecf20Sopenharmony_ci		clkdev_add_pmu("1f203034.usb2-phy", "phy", 1, 0, PMU_USB1_P);
5488c2ecf20Sopenharmony_ci		clkdev_add_pmu("1e106000.usb", "otg", 1, 0, PMU_USB1 | PMU_AHBM);
5498c2ecf20Sopenharmony_ci		clkdev_add_pmu("1f106800.phy", "phy", 1, 1, PMU1_PCIE_PHY);
5508c2ecf20Sopenharmony_ci		clkdev_add_pmu("1d900000.pcie", "bus", 1, 0, PMU_PCIE_CLK);
5518c2ecf20Sopenharmony_ci		clkdev_add_pmu("1d900000.pcie", "msi", 1, 1, PMU1_PCIE_MSI);
5528c2ecf20Sopenharmony_ci		clkdev_add_pmu("1f106800.phy", "pdi", 1, 1, PMU1_PCIE_PDI);
5538c2ecf20Sopenharmony_ci		clkdev_add_pmu("1d900000.pcie", "ctl", 1, 1, PMU1_PCIE_CTL);
5548c2ecf20Sopenharmony_ci		clkdev_add_pmu(NULL, "ahb", 1, 0, PMU_AHBM | PMU_AHBS);
5558c2ecf20Sopenharmony_ci
5568c2ecf20Sopenharmony_ci		clkdev_add_pmu("1da00000.usif", "NULL", 1, 0, PMU_USIF);
5578c2ecf20Sopenharmony_ci		clkdev_add_pmu("1e10b308.eth", NULL, 0, 0,
5588c2ecf20Sopenharmony_ci				PMU_SWITCH | PMU_PPE_DPLUS | PMU_PPE_DPLUM |
5598c2ecf20Sopenharmony_ci				PMU_PPE_EMA | PMU_PPE_TC | PMU_PPE_SLL01 |
5608c2ecf20Sopenharmony_ci				PMU_PPE_QSB | PMU_PPE_TOP);
5618c2ecf20Sopenharmony_ci		clkdev_add_pmu("1e108000.switch", "gphy0", 0, 0, PMU_GPHY);
5628c2ecf20Sopenharmony_ci		clkdev_add_pmu("1e108000.switch", "gphy1", 0, 0, PMU_GPHY);
5638c2ecf20Sopenharmony_ci		clkdev_add_pmu("1e103000.sdio", NULL, 1, 0, PMU_SDIO);
5648c2ecf20Sopenharmony_ci		clkdev_add_pmu("1e103100.deu", NULL, 1, 0, PMU_DEU);
5658c2ecf20Sopenharmony_ci		clkdev_add_pmu("1e116000.mei", "dfe", 1, 0, PMU_DFE);
5668c2ecf20Sopenharmony_ci	} else if (of_machine_is_compatible("lantiq,ar9")) {
5678c2ecf20Sopenharmony_ci		clkdev_add_static(ltq_ar9_cpu_hz(), ltq_ar9_fpi_hz(),
5688c2ecf20Sopenharmony_ci				ltq_ar9_fpi_hz(), CLOCK_250M);
5698c2ecf20Sopenharmony_ci		clkdev_add_pmu("1f203018.usb2-phy", "phy", 1, 0, PMU_USB0_P);
5708c2ecf20Sopenharmony_ci		clkdev_add_pmu("1e101000.usb", "otg", 1, 0, PMU_USB0 | PMU_AHBM);
5718c2ecf20Sopenharmony_ci		clkdev_add_pmu("1f203034.usb2-phy", "phy", 1, 0, PMU_USB1_P);
5728c2ecf20Sopenharmony_ci		clkdev_add_pmu("1e106000.usb", "otg", 1, 0, PMU_USB1 | PMU_AHBM);
5738c2ecf20Sopenharmony_ci		clkdev_add_pmu("1e180000.etop", "switch", 1, 0, PMU_SWITCH);
5748c2ecf20Sopenharmony_ci		clkdev_add_pmu("1e103000.sdio", NULL, 1, 0, PMU_SDIO);
5758c2ecf20Sopenharmony_ci		clkdev_add_pmu("1e103100.deu", NULL, 1, 0, PMU_DEU);
5768c2ecf20Sopenharmony_ci		clkdev_add_pmu("1e116000.mei", "dfe", 1, 0, PMU_DFE);
5778c2ecf20Sopenharmony_ci		clkdev_add_pmu("1e100400.serial", NULL, 1, 0, PMU_ASC0);
5788c2ecf20Sopenharmony_ci	} else {
5798c2ecf20Sopenharmony_ci		clkdev_add_static(ltq_danube_cpu_hz(), ltq_danube_fpi_hz(),
5808c2ecf20Sopenharmony_ci				ltq_danube_fpi_hz(), ltq_danube_pp32_hz());
5818c2ecf20Sopenharmony_ci		clkdev_add_pmu("1e101000.usb", "otg", 1, 0, PMU_USB0 | PMU_AHBM);
5828c2ecf20Sopenharmony_ci		clkdev_add_pmu("1f203018.usb2-phy", "phy", 1, 0, PMU_USB0_P);
5838c2ecf20Sopenharmony_ci		clkdev_add_pmu("1e103000.sdio", NULL, 1, 0, PMU_SDIO);
5848c2ecf20Sopenharmony_ci		clkdev_add_pmu("1e103100.deu", NULL, 1, 0, PMU_DEU);
5858c2ecf20Sopenharmony_ci		clkdev_add_pmu("1e116000.mei", "dfe", 1, 0, PMU_DFE);
5868c2ecf20Sopenharmony_ci		clkdev_add_pmu("1e100400.serial", NULL, 1, 0, PMU_ASC0);
5878c2ecf20Sopenharmony_ci	}
5888c2ecf20Sopenharmony_ci}
589