diff options
| -rw-r--r-- | drivers/clk/qcom/clock-qcom.h | 26 | ||||
| -rw-r--r-- | drivers/clk/qcom/clock-sdm845.c | 87 | 
2 files changed, 101 insertions, 12 deletions
| diff --git a/drivers/clk/qcom/clock-qcom.h b/drivers/clk/qcom/clock-qcom.h index a9f895c2422..6d399db987b 100644 --- a/drivers/clk/qcom/clock-qcom.h +++ b/drivers/clk/qcom/clock-qcom.h @@ -5,6 +5,8 @@  #ifndef _CLOCK_QCOM_H  #define _CLOCK_QCOM_H +#include <asm/io.h> +  #define CFG_CLK_SRC_CXO   (0 << 8)  #define CFG_CLK_SRC_GPLL0 (1 << 8)  #define CFG_CLK_SRC_GPLL0_EVEN (6 << 8) @@ -30,6 +32,18 @@ struct bcr_regs {  	uintptr_t D;  }; +struct gate_clk { +	uintptr_t reg; +	u32 en_val; +	const char *name; +}; + +#ifdef DEBUG +#define GATE_CLK(clk, reg, val) [clk] = { reg, val, #clk } +#else +#define GATE_CLK(clk, reg, val) [clk] = { reg, val, NULL } +#endif +  struct qcom_reset_map {  	unsigned int reg;  	u8 bit; @@ -38,6 +52,8 @@ struct qcom_reset_map {  struct msm_clk_data {  	const struct qcom_reset_map	*resets;  	unsigned long			num_resets; +	const struct gate_clk		*clks; +	unsigned long			num_clks;  };  struct msm_clk_priv { @@ -55,4 +71,14 @@ void clk_rcg_set_rate_mnd(phys_addr_t base, const struct bcr_regs *regs,  void clk_rcg_set_rate(phys_addr_t base, const struct bcr_regs *regs, int div,  		      int source); +static inline void qcom_gate_clk_en(const struct msm_clk_priv *priv, unsigned long id) +{ +	u32 val; +	if (id >= priv->data->num_clks || priv->data->clks[id].reg == 0) +		return; + +	val = readl(priv->base + priv->data->clks[id].reg); +	writel(val | priv->data->clks[id].en_val, priv->base + priv->data->clks[id].reg); +} +  #endif diff --git a/drivers/clk/qcom/clock-sdm845.c b/drivers/clk/qcom/clock-sdm845.c index a7a43f69b9b..57124e2a661 100644 --- a/drivers/clk/qcom/clock-sdm845.c +++ b/drivers/clk/qcom/clock-sdm845.c @@ -11,6 +11,7 @@  #include <common.h>  #include <clk-uclass.h>  #include <dm.h> +#include <linux/delay.h>  #include <errno.h>  #include <asm/io.h>  #include <linux/bitops.h> @@ -71,30 +72,90 @@ const struct freq_tbl *qcom_find_freq(const struct freq_tbl *f, uint rate)  	return f - 1;  } -static int clk_init_uart(struct msm_clk_priv *priv, uint rate) -{ -	const struct freq_tbl *freq = qcom_find_freq(ftbl_gcc_qupv3_wrap0_s0_clk_src, rate); - -	clk_rcg_set_rate_mnd(priv->base, &uart2_regs, -						freq->pre_div, freq->m, freq->n, freq->src); - -	return 0; -} -  ulong msm_set_rate(struct clk *clk, ulong rate)  {  	struct msm_clk_priv *priv = dev_get_priv(clk->dev); +	const struct freq_tbl *freq;  	switch (clk->id) { -	case GCC_QUPV3_WRAP1_S1_CLK: /*UART2*/ -		return clk_init_uart(priv, rate); +	case GCC_QUPV3_WRAP1_S1_CLK: /* UART9 */ +		freq = qcom_find_freq(ftbl_gcc_qupv3_wrap0_s0_clk_src, rate); +		clk_rcg_set_rate_mnd(priv->base, &uart2_regs, +				     freq->pre_div, freq->m, freq->n, freq->src); + +		return freq->freq;  	default:  		return 0;  	}  } +static const struct gate_clk sdm845_clks[] = { +	GATE_CLK(GCC_QUPV3_WRAP0_S0_CLK,		0x5200c, 0x00000400), +	GATE_CLK(GCC_QUPV3_WRAP0_S1_CLK,		0x5200c, 0x00000800), +	GATE_CLK(GCC_QUPV3_WRAP0_S2_CLK,		0x5200c, 0x00001000), +	GATE_CLK(GCC_QUPV3_WRAP0_S3_CLK,		0x5200c, 0x00002000), +	GATE_CLK(GCC_QUPV3_WRAP0_S4_CLK,		0x5200c, 0x00004000), +	GATE_CLK(GCC_QUPV3_WRAP0_S5_CLK,		0x5200c, 0x00008000), +	GATE_CLK(GCC_QUPV3_WRAP0_S6_CLK,		0x5200c, 0x00010000), +	GATE_CLK(GCC_QUPV3_WRAP0_S7_CLK,		0x5200c, 0x00020000), +	GATE_CLK(GCC_QUPV3_WRAP1_S0_CLK,		0x5200c, 0x00400000), +	GATE_CLK(GCC_QUPV3_WRAP1_S1_CLK,		0x5200c, 0x00800000), +	GATE_CLK(GCC_QUPV3_WRAP1_S3_CLK,		0x5200c, 0x02000000), +	GATE_CLK(GCC_QUPV3_WRAP1_S4_CLK,		0x5200c, 0x04000000), +	GATE_CLK(GCC_QUPV3_WRAP1_S5_CLK,		0x5200c, 0x08000000), +	GATE_CLK(GCC_QUPV3_WRAP1_S6_CLK,		0x5200c, 0x10000000), +	GATE_CLK(GCC_QUPV3_WRAP1_S7_CLK,		0x5200c, 0x20000000), +	GATE_CLK(GCC_QUPV3_WRAP_0_M_AHB_CLK,		0x5200c, 0x00000040), +	GATE_CLK(GCC_QUPV3_WRAP_0_S_AHB_CLK,		0x5200c, 0x00000080), +	GATE_CLK(GCC_QUPV3_WRAP_1_M_AHB_CLK,		0x5200c, 0x00100000), +	GATE_CLK(GCC_QUPV3_WRAP_1_S_AHB_CLK,		0x5200c, 0x00200000), +	GATE_CLK(GCC_SDCC2_AHB_CLK,			0x14008, 0x00000001), +	GATE_CLK(GCC_SDCC2_APPS_CLK,			0x14004, 0x00000001), +	GATE_CLK(GCC_SDCC4_AHB_CLK,			0x16008, 0x00000001), +	GATE_CLK(GCC_SDCC4_APPS_CLK,			0x16004, 0x00000001), +	GATE_CLK(GCC_UFS_CARD_AHB_CLK,			0x75010, 0x00000001), +	GATE_CLK(GCC_UFS_CARD_AXI_CLK,			0x7500c, 0x00000001), +	GATE_CLK(GCC_UFS_CARD_CLKREF_CLK,		0x8c004, 0x00000001), +	GATE_CLK(GCC_UFS_CARD_ICE_CORE_CLK,		0x75058, 0x00000001), +	GATE_CLK(GCC_UFS_CARD_PHY_AUX_CLK,		0x7508c, 0x00000001), +	GATE_CLK(GCC_UFS_CARD_RX_SYMBOL_0_CLK,		0x75018, 0x00000001), +	GATE_CLK(GCC_UFS_CARD_RX_SYMBOL_1_CLK,		0x750a8, 0x00000001), +	GATE_CLK(GCC_UFS_CARD_TX_SYMBOL_0_CLK,		0x75014, 0x00000001), +	GATE_CLK(GCC_UFS_CARD_UNIPRO_CORE_CLK,		0x75054, 0x00000001), +	GATE_CLK(GCC_UFS_MEM_CLKREF_CLK,		0x8c000, 0x00000001), +	GATE_CLK(GCC_UFS_PHY_AHB_CLK,			0x77010, 0x00000001), +	GATE_CLK(GCC_UFS_PHY_AXI_CLK,			0x7700c, 0x00000001), +	GATE_CLK(GCC_UFS_PHY_ICE_CORE_CLK,		0x77058, 0x00000001), +	GATE_CLK(GCC_UFS_PHY_PHY_AUX_CLK,		0x7708c, 0x00000001), +	GATE_CLK(GCC_UFS_PHY_RX_SYMBOL_0_CLK,		0x77018, 0x00000001), +	GATE_CLK(GCC_UFS_PHY_RX_SYMBOL_1_CLK,		0x770a8, 0x00000001), +	GATE_CLK(GCC_UFS_PHY_TX_SYMBOL_0_CLK,		0x77014, 0x00000001), +	GATE_CLK(GCC_UFS_PHY_UNIPRO_CORE_CLK,		0x77054, 0x00000001), +	GATE_CLK(GCC_USB30_PRIM_MASTER_CLK,		0x0f00c, 0x00000001), +	GATE_CLK(GCC_USB30_PRIM_MOCK_UTMI_CLK,		0x0f014, 0x00000001), +	GATE_CLK(GCC_USB30_PRIM_SLEEP_CLK,		0x0f010, 0x00000001), +	GATE_CLK(GCC_USB30_SEC_MASTER_CLK,		0x1000c, 0x00000001), +	GATE_CLK(GCC_USB30_SEC_MOCK_UTMI_CLK,		0x10014, 0x00000001), +	GATE_CLK(GCC_USB30_SEC_SLEEP_CLK,		0x10010, 0x00000001), +	GATE_CLK(GCC_USB3_PRIM_CLKREF_CLK,		0x8c008, 0x00000001), +	GATE_CLK(GCC_USB3_PRIM_PHY_AUX_CLK,		0x0f04c, 0x00000001), +	GATE_CLK(GCC_USB3_PRIM_PHY_COM_AUX_CLK,		0x0f050, 0x00000001), +	GATE_CLK(GCC_USB3_PRIM_PHY_PIPE_CLK,		0x0f054, 0x00000001), +	GATE_CLK(GCC_USB3_SEC_CLKREF_CLK,		0x8c028, 0x00000001), +	GATE_CLK(GCC_USB3_SEC_PHY_AUX_CLK,		0x1004c, 0x00000001), +	GATE_CLK(GCC_USB3_SEC_PHY_PIPE_CLK,		0x10054, 0x00000001), +	GATE_CLK(GCC_USB3_SEC_PHY_COM_AUX_CLK,		0x10050, 0x00000001), +	GATE_CLK(GCC_USB_PHY_CFG_AHB2PHY_CLK,		0x6a004, 0x00000001), +}; +  int msm_enable(struct clk *clk)  { +	struct msm_clk_priv *priv = dev_get_priv(clk->dev); + +	debug("%s: clk %s\n", __func__, sdm845_clks[clk->id].name); + +	qcom_gate_clk_en(priv, clk->id); +  	return 0;  } @@ -121,6 +182,8 @@ static const struct qcom_reset_map sdm845_gcc_resets[] = {  static const struct msm_clk_data qcs404_gcc_data = {  	.resets = sdm845_gcc_resets,  	.num_resets = ARRAY_SIZE(sdm845_gcc_resets), +	.clks = sdm845_clks, +	.num_clks = ARRAY_SIZE(sdm845_clks),  };  static const struct udevice_id gcc_sdm845_of_match[] = { | 
