drivers/mipi: Add support for KD_KD110N11_51IE panel
[coreboot2.git] / src / soc / mediatek / common / pmif.c
blob97da4157f11cf6d5171556d599aba903d6d23a5a
1 /* SPDX-License-Identifier: GPL-2.0-only */
3 #include <console/console.h>
4 #include <device/mmio.h>
5 #include <soc/addressmap.h>
6 #include <soc/pmif.h>
7 #include <soc/pmif_spi.h>
8 #include <soc/pmif_spmi.h>
9 #include <soc/pmif_sw.h>
10 #include <soc/spmi.h>
11 #include <timer.h>
13 static int pmif_check_swinf(struct pmif *arb, long timeout_us, u32 expected_status)
15 u32 reg_rdata;
16 struct stopwatch sw;
18 stopwatch_init_usecs_expire(&sw, timeout_us);
19 do {
20 reg_rdata = read32(&arb->ch->ch_sta);
21 if (stopwatch_expired(&sw))
22 return E_TIMEOUT;
23 } while (GET_SWINF_0_FSM(reg_rdata) != expected_status);
25 return 0;
28 static void pmif_send_cmd(struct pmif *arb, int write, u32 opc, u32 slvid,
29 u32 addr, u32 *rdata, u32 wdata, u32 len)
31 int ret;
32 u32 data, bc = len - 1;
34 /* Wait for Software Interface FSM state to be IDLE. */
35 ret = pmif_check_swinf(arb, PMIF_WAIT_IDLE_US, SWINF_FSM_IDLE);
36 if (ret) {
37 printk(BIOS_ERR, "[%s] idle timeout\n", __func__);
38 return;
41 /* Set the write data */
42 if (write)
43 write32(&arb->ch->wdata, wdata);
45 /* Send the command. */
46 write32(&arb->ch->ch_send,
47 (opc << 30) | (write << 29) | (slvid << 24) | (bc << 16) | addr);
49 if (!write) {
51 * Wait for Software Interface FSM state to be WFVLDCLR,
52 * read the data and clear the valid flag.
54 ret = pmif_check_swinf(arb, PMIF_READ_US, SWINF_FSM_WFVLDCLR);
55 if (ret) {
56 printk(BIOS_ERR, "[%s] read timeout\n", __func__);
57 return;
60 data = read32(&arb->ch->rdata);
61 *rdata = data;
62 write32(&arb->ch->ch_rdy, 0x1);
66 void pmif_spmi_read(struct pmif *arb, u32 slvid, u32 reg, u32 *data)
68 *data = 0;
69 pmif_send_cmd(arb, 0, PMIF_CMD_EXT_REG_LONG, slvid, reg, data, 0, 1);
72 void pmif_spmi_write(struct pmif *arb, u32 slvid, u32 reg, u32 data)
74 pmif_send_cmd(arb, 1, PMIF_CMD_EXT_REG_LONG, slvid, reg, NULL, data, 1);
77 void pmif_spmi_read16(struct pmif *arb, u32 slvid, u32 reg, u16 *data)
79 u32 rdata = 0;
80 pmif_send_cmd(arb, 0, PMIF_CMD_EXT_REG_LONG, slvid, reg, &rdata, 0, 2);
81 *data = (u16)rdata;
84 void pmif_spmi_write16(struct pmif *arb, u32 slvid, u32 reg, u16 data)
86 pmif_send_cmd(arb, 1, PMIF_CMD_EXT_REG_LONG, slvid, reg, NULL, data, 2);
89 u32 pmif_spmi_read_field(struct pmif *arb, u32 slvid, u32 reg, u32 mask, u32 shift)
91 u32 data;
93 pmif_spmi_read(arb, slvid, reg, &data);
94 data &= (mask << shift);
95 data >>= shift;
97 return data;
100 void pmif_spmi_write_field(struct pmif *arb, u32 slvid, u32 reg,
101 u32 val, u32 mask, u32 shift)
103 u32 old, new;
105 pmif_spmi_read(arb, slvid, reg, &old);
106 new = old & ~(mask << shift);
107 new |= (val << shift);
108 pmif_spmi_write(arb, slvid, reg, new);
111 void pmif_spi_read(struct pmif *arb, u32 slvid, u32 reg, u32 *data)
113 *data = 0;
114 pmif_send_cmd(arb, 0, PMIF_CMD_REG_0, slvid, reg, data, 0, 1);
117 void pmif_spi_write(struct pmif *arb, u32 slvid, u32 reg, u32 data)
119 pmif_send_cmd(arb, 1, PMIF_CMD_REG_0, slvid, reg, NULL, data, 1);
122 u32 pmif_spi_read_field(struct pmif *arb, u32 slvid, u32 reg, u32 mask, u32 shift)
124 u32 data;
126 pmif_spi_read(arb, slvid, reg, &data);
127 data &= (mask << shift);
128 data >>= shift;
130 return data;
133 void pmif_spi_write_field(struct pmif *arb, u32 slvid, u32 reg,
134 u32 val, u32 mask, u32 shift)
136 u32 old, new;
138 pmif_spi_read(arb, slvid, reg, &old);
139 new = old & ~(mask << shift);
140 new |= (val << shift);
141 pmif_spi_write(arb, slvid, reg, new);
144 int pmif_check_init_done(struct pmif *arb)
146 if (read32(&arb->mtk_pmif->init_done) & 0x1)
147 return 0;
149 return -E_NODEV;
152 struct pmif *get_pmif_controller(int inf, int mstid)
154 if (inf == PMIF_SPMI && mstid < pmif_spmi_arb_count)
155 return (struct pmif *)&pmif_spmi_arb[mstid];
156 else if (inf == PMIF_SPI)
157 return (struct pmif *)&pmif_spi_arb[0];
159 die("[%s] Failed to get pmif controller: inf = %d, mstid = %d\n", __func__, inf, mstid);
160 return NULL;
163 static void pmif_select(enum pmic_interface mode)
165 unsigned int spi_spm_sleep_req, spi_scp_sleep_req,
166 spmi_spm_sleep_req, spmi_scp_sleep_req,
167 spi_md_ctl_pmif_rdy, spi_md_ctl_srclk_en, spi_md_ctl_srvol_en,
168 spmi_md_ctl_pmif_rdy, spmi_md_ctl_srclk_en, spmi_md_ctl_srvol_en,
169 spi_inf_srclken_rc_en, spi_other_inf_dcxo0_en, spi_other_inf_dcxo1_en,
170 spi_arb_srclken_rc_en, spi_arb_dcxo_conn_en, spi_arb_dcxo_nfc_en;
172 switch (mode) {
173 case PMIF_VLD_RDY:
174 /* spm and scp sleep request disable spi and spmi */
175 spi_spm_sleep_req = 1;
176 spi_scp_sleep_req = 1;
177 spmi_spm_sleep_req = 1;
178 spmi_scp_sleep_req = 1;
181 * pmic vld/rdy control spi mode enable
182 * srclken control spi mode disable
183 * vreq control spi mode disable
185 spi_md_ctl_pmif_rdy = 1;
186 spi_md_ctl_srclk_en = 0;
187 spi_md_ctl_srvol_en = 0;
188 spmi_md_ctl_pmif_rdy = 1;
189 spmi_md_ctl_srclk_en = 0;
190 spmi_md_ctl_srvol_en = 0;
192 /* srclken rc interface enable */
193 spi_inf_srclken_rc_en = 1;
195 /* dcxo interface disable */
196 spi_other_inf_dcxo0_en = 0;
197 spi_other_inf_dcxo1_en = 0;
199 /* srclken enable, dcxo0,1 disable */
200 spi_arb_srclken_rc_en = 1;
201 spi_arb_dcxo_conn_en = 0;
202 spi_arb_dcxo_nfc_en = 0;
203 break;
205 case PMIF_SLP_REQ:
206 /* spm and scp sleep request enable spi and spmi */
207 spi_spm_sleep_req = 0;
208 spi_scp_sleep_req = 0;
209 spmi_spm_sleep_req = 0;
210 spmi_scp_sleep_req = 0;
213 * pmic vld/rdy control spi mode disable
214 * srclken control spi mode enable
215 * vreq control spi mode enable
217 spi_md_ctl_pmif_rdy = 0;
218 spi_md_ctl_srclk_en = 1;
219 spi_md_ctl_srvol_en = 1;
220 spmi_md_ctl_pmif_rdy = 0;
221 spmi_md_ctl_srclk_en = 1;
222 spmi_md_ctl_srvol_en = 1;
224 /* srclken rc interface disable */
225 spi_inf_srclken_rc_en = 0;
227 /* dcxo interface enable */
228 spi_other_inf_dcxo0_en = 1;
229 spi_other_inf_dcxo1_en = 1;
231 /* srclken disable, dcxo0,1 enable */
232 spi_arb_srclken_rc_en = 0;
233 spi_arb_dcxo_conn_en = 1;
234 spi_arb_dcxo_nfc_en = 1;
235 break;
237 default:
238 die("Can't support pmif mode %d\n", mode);
241 SET32_BITFIELDS(&pmif_spi_arb[0].mtk_pmif->sleep_protection_ctrl,
242 PMIFSPI_SPM_SLEEP_REQ_SEL, spi_spm_sleep_req,
243 PMIFSPI_SCP_SLEEP_REQ_SEL, spi_scp_sleep_req);
244 SET32_BITFIELDS(&pmif_spmi_arb[0].mtk_pmif->sleep_protection_ctrl,
245 PMIFSPMI_SPM_SLEEP_REQ_SEL, spmi_spm_sleep_req,
246 PMIFSPMI_SCP_SLEEP_REQ_SEL, spmi_scp_sleep_req);
247 SET32_BITFIELDS(&pmif_spi_arb[0].mtk_pmif->spi_mode_ctrl,
248 PMIFSPI_MD_CTL_PMIF_RDY, spi_md_ctl_pmif_rdy,
249 PMIFSPI_MD_CTL_SRCLK_EN, spi_md_ctl_srclk_en,
250 PMIFSPI_MD_CTL_SRVOL_EN, spi_md_ctl_srvol_en);
251 SET32_BITFIELDS(&pmif_spmi_arb[0].mtk_pmif->spi_mode_ctrl,
252 PMIFSPMI_MD_CTL_PMIF_RDY, spmi_md_ctl_pmif_rdy,
253 PMIFSPMI_MD_CTL_SRCLK_EN, spmi_md_ctl_srclk_en,
254 PMIFSPMI_MD_CTL_SRVOL_EN, spmi_md_ctl_srvol_en);
255 SET32_BITFIELDS(&pmif_spi_arb[0].mtk_pmif->inf_en,
256 PMIFSPI_INF_EN_SRCLKEN_RC_HW, spi_inf_srclken_rc_en);
257 SET32_BITFIELDS(&pmif_spi_arb[0].mtk_pmif->other_inf_en,
258 PMIFSPI_OTHER_INF_DXCO0_EN, spi_other_inf_dcxo0_en,
259 PMIFSPI_OTHER_INF_DXCO1_EN, spi_other_inf_dcxo1_en);
260 SET32_BITFIELDS(&pmif_spi_arb[0].mtk_pmif->arb_en,
261 PMIFSPI_ARB_EN_SRCLKEN_RC_HW, spi_arb_srclken_rc_en,
262 PMIFSPI_ARB_EN_DCXO_CONN, spi_arb_dcxo_conn_en,
263 PMIFSPI_ARB_EN_DCXO_NFC, spi_arb_dcxo_nfc_en);
266 void pmwrap_interface_init(void)
268 if (CONFIG(SRCLKEN_RC_SUPPORT)) {
269 printk(BIOS_INFO, "%s: Select PMIF_VLD_RDY\n", __func__);
270 pmif_select(PMIF_VLD_RDY);
271 } else {
272 printk(BIOS_INFO, "%s: Select PMIF_SLP_REQ\n", __func__);
273 pmif_select(PMIF_SLP_REQ);