blob: 9c0cc1c22cca4958495a61a5eca47c83e4d98955 [file] [log] [blame]
Tom Rini10e47792018-05-06 17:58:06 -04001// SPDX-License-Identifier: BSD-3-Clause
Mateusz Kulikowski2507d822016-03-31 23:12:32 +02002/*
3 * Clock drivers for Qualcomm APQ8016
4 *
5 * (C) Copyright 2015 Mateusz Kulikowski <mateusz.kulikowski@gmail.com>
6 *
7 * Based on Little Kernel driver, simplified
Mateusz Kulikowski2507d822016-03-31 23:12:32 +02008 */
9
10#include <common.h>
Stephen Warrena9622432016-06-17 09:44:00 -060011#include <clk-uclass.h>
Mateusz Kulikowski2507d822016-03-31 23:12:32 +020012#include <dm.h>
13#include <errno.h>
14#include <asm/io.h>
15#include <linux/bitops.h>
Jorge Ramirez-Ortiz92c1eff2018-01-10 11:33:49 +010016#include "clock-snapdragon.h"
Mateusz Kulikowski2507d822016-03-31 23:12:32 +020017
18/* GPLL0 clock control registers */
Mateusz Kulikowski2507d822016-03-31 23:12:32 +020019#define GPLL0_STATUS_ACTIVE BIT(17)
Mateusz Kulikowski2507d822016-03-31 23:12:32 +020020#define APCS_GPLL_ENA_VOTE_GPLL0 BIT(0)
21
Mateusz Kulikowski2507d822016-03-31 23:12:32 +020022static const struct bcr_regs sdc_regs[] = {
23 {
24 .cfg_rcgr = SDCC_CFG_RCGR(1),
25 .cmd_rcgr = SDCC_CMD_RCGR(1),
26 .M = SDCC_M(1),
27 .N = SDCC_N(1),
28 .D = SDCC_D(1),
29 },
30 {
31 .cfg_rcgr = SDCC_CFG_RCGR(2),
32 .cmd_rcgr = SDCC_CMD_RCGR(2),
33 .M = SDCC_M(2),
34 .N = SDCC_N(2),
35 .D = SDCC_D(2),
36 }
37};
38
Jorge Ramirez-Ortiz92c1eff2018-01-10 11:33:49 +010039static struct gpll0_ctrl gpll0_ctrl = {
40 .status = GPLL0_STATUS,
41 .status_bit = GPLL0_STATUS_ACTIVE,
42 .ena_vote = APCS_GPLL_ENA_VOTE,
43 .vote_bit = APCS_GPLL_ENA_VOTE_GPLL0,
44};
45
46/* SDHCI */
Mateusz Kulikowski2507d822016-03-31 23:12:32 +020047static int clk_init_sdc(struct msm_clk_priv *priv, int slot, uint rate)
48{
49 int div = 8; /* 100MHz default */
50
51 if (rate == 200000000)
52 div = 4;
53
54 clk_enable_cbc(priv->base + SDCC_AHB_CBCR(slot));
55 /* 800Mhz/div, gpll0 */
56 clk_rcg_set_rate_mnd(priv->base, &sdc_regs[slot], div, 0, 0,
57 CFG_CLK_SRC_GPLL0);
Jorge Ramirez-Ortiz92c1eff2018-01-10 11:33:49 +010058 clk_enable_gpll0(priv->base, &gpll0_ctrl);
Mateusz Kulikowski2507d822016-03-31 23:12:32 +020059 clk_enable_cbc(priv->base + SDCC_APPS_CBCR(slot));
60
61 return rate;
62}
63
64static const struct bcr_regs uart2_regs = {
65 .cfg_rcgr = BLSP1_UART2_APPS_CFG_RCGR,
66 .cmd_rcgr = BLSP1_UART2_APPS_CMD_RCGR,
67 .M = BLSP1_UART2_APPS_M,
68 .N = BLSP1_UART2_APPS_N,
69 .D = BLSP1_UART2_APPS_D,
70};
71
Jorge Ramirez-Ortiz92c1eff2018-01-10 11:33:49 +010072/* UART: 115200 */
Mateusz Kulikowski2507d822016-03-31 23:12:32 +020073static int clk_init_uart(struct msm_clk_priv *priv)
74{
75 /* Enable iface clk */
76 clk_enable_cbc(priv->base + BLSP1_AHB_CBCR);
77 /* 7372800 uart block clock @ GPLL0 */
78 clk_rcg_set_rate_mnd(priv->base, &uart2_regs, 1, 144, 15625,
79 CFG_CLK_SRC_GPLL0);
Jorge Ramirez-Ortiz92c1eff2018-01-10 11:33:49 +010080 clk_enable_gpll0(priv->base, &gpll0_ctrl);
Mateusz Kulikowski2507d822016-03-31 23:12:32 +020081 /* Enable core clk */
82 clk_enable_cbc(priv->base + BLSP1_UART2_APPS_CBCR);
83
84 return 0;
85}
86
Stephen Warrena9622432016-06-17 09:44:00 -060087ulong msm_set_rate(struct clk *clk, ulong rate)
Mateusz Kulikowski2507d822016-03-31 23:12:32 +020088{
Stephen Warrena9622432016-06-17 09:44:00 -060089 struct msm_clk_priv *priv = dev_get_priv(clk->dev);
Mateusz Kulikowski2507d822016-03-31 23:12:32 +020090
Stephen Warrena9622432016-06-17 09:44:00 -060091 switch (clk->id) {
Mateusz Kulikowski2507d822016-03-31 23:12:32 +020092 case 0: /* SDC1 */
93 return clk_init_sdc(priv, 0, rate);
94 break;
95 case 1: /* SDC2 */
96 return clk_init_sdc(priv, 1, rate);
97 break;
98 case 4: /* UART2 */
99 return clk_init_uart(priv);
100 break;
101 default:
102 return 0;
103 }
104}