blob: 60f53a77b0c544c29f621c578f5d1d439b277534 [file] [log] [blame]
Yuchen Huangec39cb32020-09-23 20:41:19 +08001/* SPDX-License-Identifier: GPL-2.0-only */
2
3#include <console/console.h>
4#include <delay.h>
5#include <device/mmio.h>
6#include <soc/clkbuf.h>
7#include <soc/pmif.h>
Yuchen Huang6a6e58c2021-04-11 15:28:20 +08008#if CONFIG(SRCLKEN_RC_SUPPORT)
Yuchen Huangec39cb32020-09-23 20:41:19 +08009#include <soc/srclken_rc.h>
Yuchen Huang6a6e58c2021-04-11 15:28:20 +080010#endif
Yuchen Huangec39cb32020-09-23 20:41:19 +080011
12#define BUFTAG "[CLKBUF]"
13#define buf_info(fmt, arg ...) printk(BIOS_INFO, BUFTAG "%s,%d: " fmt, \
14 __func__, __LINE__, ## arg)
15
16#define _buf_clrset32_impl(addr, clear, set) \
17 buf_write(addr, (buf_read(addr) & ~((uint32_t)(clear))) | (set))
18
19#define BUF_SET_FIELDS(addr, ...) \
20 _BF_IMPL(_buf_clrset32_impl, addr, __VA_ARGS__)
21#define BUF_READ_FIELD(addr, name) \
22 EXTRACT_BITFIELD(buf_read(addr), name)
23
24#define PMIC_CW00_INIT_VAL 0x4005 /* 0100 0000 0000 0101 */
25#define PMIC_CW09_INIT_VAL 0x01F0 /* 0000 0001 1111 0000 */
26
27static struct pmif *pmif_arb;
28
29static u32 buf_read(u32 addr)
30{
31 u32 rdata;
32
Elyes Haouas0f1fb8a2022-09-13 09:57:30 +020033 if (!pmif_arb)
Yuchen Huangec39cb32020-09-23 20:41:19 +080034 pmif_arb = get_pmif_controller(PMIF_SPI, 0);
35 pmif_arb->read(pmif_arb, 0, addr, &rdata);
36
37 return rdata;
38}
39
40static void buf_write(u32 addr, u32 wdata)
41{
Elyes Haouas0f1fb8a2022-09-13 09:57:30 +020042 if (!pmif_arb)
Yuchen Huangec39cb32020-09-23 20:41:19 +080043 pmif_arb = get_pmif_controller(PMIF_SPI, 0);
44 pmif_arb->write(pmif_arb, 0, addr, wdata);
45}
46
47static void dump_clkbuf_log(void)
48{
49 u32 pmic_cw00, pmic_cw09, pmic_cw12, pmic_cw13, pmic_cw15, pmic_cw19,
50 top_spi_con1, ldo_vrfck_op_en, ldo_vbbck_op_en, ldo_vrfck_en,
51 ldo_vbbck_en, vrfck_hv_en;
52
53 pmic_cw00 = BUF_READ_FIELD(PMIC_RG_DCXO_CW00, PMIC_REG_COMMON);
54 pmic_cw09 = BUF_READ_FIELD(PMIC_RG_DCXO_CW09, PMIC_REG_COMMON);
55 pmic_cw12 = BUF_READ_FIELD(PMIC_RG_DCXO_CW12, PMIC_REG_COMMON);
56 pmic_cw13 = BUF_READ_FIELD(PMIC_RG_DCXO_CW13, PMIC_REG_COMMON);
57 pmic_cw15 = BUF_READ_FIELD(PMIC_RG_DCXO_CW15, PMIC_REG_COMMON);
58 pmic_cw19 = BUF_READ_FIELD(PMIC_RG_DCXO_CW19, PMIC_REG_COMMON);
59 buf_info("DCXO_CW00/09/12/13/15/19=%#x %#x %#x %#x %#x %#x\n",
60 pmic_cw00, pmic_cw09, pmic_cw12,
61 pmic_cw13, pmic_cw15, pmic_cw19);
62
63 top_spi_con1 = BUF_READ_FIELD(PMIC_RG_TOP_SPI_CON1, PMIC_RG_SRCLKEN_IN3_EN);
64 ldo_vrfck_op_en = BUF_READ_FIELD(PMIC_RG_LDO_VRFCK_OP_EN,
65 PMIC_RG_LDO_VRFCK_HW14_OP_EN);
66 ldo_vbbck_op_en = BUF_READ_FIELD(PMIC_RG_LDO_VBBCK_OP_EN,
67 PMIC_RG_LDO_VBBCK_HW14_OP_EN);
68 ldo_vrfck_en = BUF_READ_FIELD(PMIC_RG_LDO_VRFCK_CON0, PMIC_RG_LDO_VRFCK_EN);
69 ldo_vbbck_en = BUF_READ_FIELD(PMIC_RG_LDO_VBBCK_CON0, PMIC_RG_LDO_VBBCK_EN);
70 buf_info("spi_con1/ldo_rf_op/ldo_bb_op/ldo_rf_en/ldo_bb_en=%#x %#x %#x %#x %#x\n",
71 top_spi_con1, ldo_vrfck_op_en, ldo_vbbck_op_en,
72 ldo_vrfck_en, ldo_vbbck_en);
73
74 vrfck_hv_en = BUF_READ_FIELD(PMIC_RG_DCXO_ADLDO_BIAS_ELR_0, PMIC_RG_VRFCK_HV_EN);
75 buf_info("clk buf vrfck_hv_en=%#x\n", vrfck_hv_en);
76}
77
78int clk_buf_init(void)
79{
80 /* Dump registers before setting */
81 dump_clkbuf_log();
82
83 /* Unlock pmic key */
84 BUF_SET_FIELDS(PMIC_TOP_TMA_KEY, PMIC_REG_COMMON, PMIC_TOP_TMA_KEY_UNLOCK);
85
86 /* 1.1 Set VRFCK input supply(11.ac mode) */
87 BUF_SET_FIELDS(PMIC_RG_DCXO_ADLDO_BIAS_ELR_0, PMIC_RG_VRFCK_HV_EN, 0x0);
88
89 /* 1.2.0 Set VRFCK En = 0 */
90 BUF_SET_FIELDS(PMIC_RG_LDO_VRFCK_CON0, PMIC_RG_LDO_VRFCK_EN, 0x0);
91 /* 1.2.1 Set VRFCK1 as power src */
92 BUF_SET_FIELDS(PMIC_RG_LDO_VRFCK_ELR, PMIC_RG_LDO_VRFCK_ANA_SEL, 0x1);
93
94 /* 1.2.2 Switch LDO-RFCK to LDO-RFCK1 */
95 BUF_SET_FIELDS(PMIC_RG_DCXO_ADLDO_BIAS_ELR_0, PMIC_RG_VRFCK_NDIS_EN, 0x0);
96 BUF_SET_FIELDS(PMIC_RG_DCXO_ADLDO_BIAS_ELR_1, PMIC_RG_VRFCK_1_NDIS_EN, 0x1);
97
98 /* 1.2.0 Set VRFCK En = 1 */
99 BUF_SET_FIELDS(PMIC_RG_LDO_VRFCK_CON0, PMIC_RG_LDO_VRFCK_EN, 0x1);
100
101 /* 1.2.3 Lock pmic key */
102 BUF_SET_FIELDS(PMIC_TOP_TMA_KEY, PMIC_REG_COMMON, 0x0);
103
104 /* Enable XO LDO */
105 BUF_SET_FIELDS(PMIC_RG_LDO_VRFCK_OP_EN_SET, PMIC_RG_LDO_VRFCK_HW14_OP_EN, 0x1);
106 BUF_SET_FIELDS(PMIC_RG_LDO_VBBCK_OP_EN_SET, PMIC_RG_LDO_VBBCK_HW14_OP_EN, 0x1);
107 BUF_SET_FIELDS(PMIC_RG_LDO_VRFCK_CON0, PMIC_RG_LDO_VRFCK_EN, 0x0);
108 BUF_SET_FIELDS(PMIC_RG_LDO_VBBCK_CON0, PMIC_RG_LDO_VBBCK_EN, 0x0);
109
110 /* Enable 26M control */
111 if (!CONFIG(SRCLKEN_RC_SUPPORT)) {
112 /* Legacy co-clock mode */
113 BUF_SET_FIELDS(PMIC_RG_TOP_SPI_CON1, PMIC_RG_SRCLKEN_IN3_EN, 0x0);
114
115 BUF_SET_FIELDS(PMIC_RG_DCXO_CW00, PMIC_REG_COMMON, PMIC_CW00_INIT_VAL);
116 BUF_SET_FIELDS(PMIC_RG_DCXO_CW09, PMIC_REG_COMMON, PMIC_CW09_INIT_VAL);
117 } else {
118 /* New co-clock mode */
119 /* All XO mode should set to 2'b01 */
120 BUF_SET_FIELDS(PMIC_RG_DCXO_CW00, PMIC_REG_COMMON, PMIC_CW00_INIT_VAL);
121 BUF_SET_FIELDS(PMIC_RG_DCXO_CW09, PMIC_REG_COMMON, PMIC_CW09_INIT_VAL);
122
123 /* 1. Update control mapping table */
124 BUF_SET_FIELDS(PMIC_RG_XO_BUF_CTL0, PMIC_RG_XO_VOTE, 0x005);
125 BUF_SET_FIELDS(PMIC_RG_XO_BUF_CTL1, PMIC_RG_XO_VOTE, 0x0);
126 BUF_SET_FIELDS(PMIC_RG_XO_BUF_CTL2, PMIC_RG_XO_VOTE, 0x0);
127 BUF_SET_FIELDS(PMIC_RG_XO_BUF_CTL3, PMIC_RG_XO_VOTE, 0x0);
128 BUF_SET_FIELDS(PMIC_RG_XO_BUF_CTL4, PMIC_RG_XO_VOTE, 0x0);
129 /* Wait 100us */
130 udelay(100);
131
132 /* 2. Switch to new control mode */
133 BUF_SET_FIELDS(PMIC_RG_DCXO_CW08, PMIC_RG_XO_PMIC_TOP_DIG_SW, 0x0);
134 }
135
136 /* Check if the setting is ok */
137 dump_clkbuf_log();
138
139 return 0;
140}