blob: a2424178c6239d6a87566604eade4382990ccca7 [file] [log] [blame]
Mateusz Kulikowski08592132016-03-31 23:12:32 +02001/*
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>
Stephen Warren135aa952016-06-17 09:44:00 -060012#include <clk-uclass.h>
Mateusz Kulikowski08592132016-03-31 23:12:32 +020013#include <dm.h>
14#include <errno.h>
15#include <asm/io.h>
16#include <linux/bitops.h>
Jorge Ramirez-Ortiz7c75f7f2018-01-10 11:33:49 +010017#include "clock-snapdragon.h"
Mateusz Kulikowski08592132016-03-31 23:12:32 +020018
19/* GPLL0 clock control registers */
Mateusz Kulikowski08592132016-03-31 23:12:32 +020020#define GPLL0_STATUS_ACTIVE BIT(17)
Mateusz Kulikowski08592132016-03-31 23:12:32 +020021#define APCS_GPLL_ENA_VOTE_GPLL0 BIT(0)
22
Mateusz Kulikowski08592132016-03-31 23:12:32 +020023static 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
Jorge Ramirez-Ortiz7c75f7f2018-01-10 11:33:49 +010040static 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 */
Mateusz Kulikowski08592132016-03-31 23:12:32 +020048static 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);
Jorge Ramirez-Ortiz7c75f7f2018-01-10 11:33:49 +010059 clk_enable_gpll0(priv->base, &gpll0_ctrl);
Mateusz Kulikowski08592132016-03-31 23:12:32 +020060 clk_enable_cbc(priv->base + SDCC_APPS_CBCR(slot));
61
62 return rate;
63}
64
65static 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
Jorge Ramirez-Ortiz7c75f7f2018-01-10 11:33:49 +010073/* UART: 115200 */
Mateusz Kulikowski08592132016-03-31 23:12:32 +020074static 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);
Jorge Ramirez-Ortiz7c75f7f2018-01-10 11:33:49 +010081 clk_enable_gpll0(priv->base, &gpll0_ctrl);
Mateusz Kulikowski08592132016-03-31 23:12:32 +020082 /* Enable core clk */
83 clk_enable_cbc(priv->base + BLSP1_UART2_APPS_CBCR);
84
85 return 0;
86}
87
Stephen Warren135aa952016-06-17 09:44:00 -060088ulong msm_set_rate(struct clk *clk, ulong rate)
Mateusz Kulikowski08592132016-03-31 23:12:32 +020089{
Stephen Warren135aa952016-06-17 09:44:00 -060090 struct msm_clk_priv *priv = dev_get_priv(clk->dev);
Mateusz Kulikowski08592132016-03-31 23:12:32 +020091
Stephen Warren135aa952016-06-17 09:44:00 -060092 switch (clk->id) {
Mateusz Kulikowski08592132016-03-31 23:12:32 +020093 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}