1 /*
2  * Clock drivers for Qualcomm APQ8016
3  *
4  * (C) Copyright 2015 Mateusz Kulikowski <mateusz.kulikowski@gmail.com>
5  *
6  * Based on Little Kernel driver, simplified
7  *
8  * SPDX-License-Identifier:	BSD-3-Clause
9  */
10 
11 #include <common.h>
12 #include <clk-uclass.h>
13 #include <dm.h>
14 #include <errno.h>
15 #include <asm/io.h>
16 #include <linux/bitops.h>
17 #include "clock-snapdragon.h"
18 
19 /* GPLL0 clock control registers */
20 #define GPLL0_STATUS_ACTIVE BIT(17)
21 #define APCS_GPLL_ENA_VOTE_GPLL0 BIT(0)
22 
23 static const struct bcr_regs sdc_regs[] = {
24 	{
25 	.cfg_rcgr = SDCC_CFG_RCGR(1),
26 	.cmd_rcgr = SDCC_CMD_RCGR(1),
27 	.M = SDCC_M(1),
28 	.N = SDCC_N(1),
29 	.D = SDCC_D(1),
30 	},
31 	{
32 	.cfg_rcgr = SDCC_CFG_RCGR(2),
33 	.cmd_rcgr = SDCC_CMD_RCGR(2),
34 	.M = SDCC_M(2),
35 	.N = SDCC_N(2),
36 	.D = SDCC_D(2),
37 	}
38 };
39 
40 static struct gpll0_ctrl gpll0_ctrl = {
41 	.status = GPLL0_STATUS,
42 	.status_bit = GPLL0_STATUS_ACTIVE,
43 	.ena_vote = APCS_GPLL_ENA_VOTE,
44 	.vote_bit = APCS_GPLL_ENA_VOTE_GPLL0,
45 };
46 
47 /* SDHCI */
48 static int clk_init_sdc(struct msm_clk_priv *priv, int slot, uint rate)
49 {
50 	int div = 8; /* 100MHz default */
51 
52 	if (rate == 200000000)
53 		div = 4;
54 
55 	clk_enable_cbc(priv->base + SDCC_AHB_CBCR(slot));
56 	/* 800Mhz/div, gpll0 */
57 	clk_rcg_set_rate_mnd(priv->base, &sdc_regs[slot], div, 0, 0,
58 			     CFG_CLK_SRC_GPLL0);
59 	clk_enable_gpll0(priv->base, &gpll0_ctrl);
60 	clk_enable_cbc(priv->base + SDCC_APPS_CBCR(slot));
61 
62 	return rate;
63 }
64 
65 static const struct bcr_regs uart2_regs = {
66 	.cfg_rcgr = BLSP1_UART2_APPS_CFG_RCGR,
67 	.cmd_rcgr = BLSP1_UART2_APPS_CMD_RCGR,
68 	.M = BLSP1_UART2_APPS_M,
69 	.N = BLSP1_UART2_APPS_N,
70 	.D = BLSP1_UART2_APPS_D,
71 };
72 
73 /* UART: 115200 */
74 static int clk_init_uart(struct msm_clk_priv *priv)
75 {
76 	/* Enable iface clk */
77 	clk_enable_cbc(priv->base + BLSP1_AHB_CBCR);
78 	/* 7372800 uart block clock @ GPLL0 */
79 	clk_rcg_set_rate_mnd(priv->base, &uart2_regs, 1, 144, 15625,
80 			     CFG_CLK_SRC_GPLL0);
81 	clk_enable_gpll0(priv->base, &gpll0_ctrl);
82 	/* Enable core clk */
83 	clk_enable_cbc(priv->base + BLSP1_UART2_APPS_CBCR);
84 
85 	return 0;
86 }
87 
88 ulong msm_set_rate(struct clk *clk, ulong rate)
89 {
90 	struct msm_clk_priv *priv = dev_get_priv(clk->dev);
91 
92 	switch (clk->id) {
93 	case 0: /* SDC1 */
94 		return clk_init_sdc(priv, 0, rate);
95 		break;
96 	case 1: /* SDC2 */
97 		return clk_init_sdc(priv, 1, rate);
98 		break;
99 	case 4: /* UART2 */
100 		return clk_init_uart(priv);
101 		break;
102 	default:
103 		return 0;
104 	}
105 }
106