1 // SPDX-License-Identifier: BSD-3-Clause
2 /*
3  * Qualcomm SPMI bus driver
4  *
5  * (C) Copyright 2015 Mateusz Kulikowski <mateusz.kulikowski@gmail.com>
6  *
7  * Loosely based on Little Kernel driver
8  */
9 
10 #include <dm.h>
11 #include <errno.h>
12 #include <fdtdec.h>
13 #include <asm/global_data.h>
14 #include <asm/io.h>
15 #include <dm/device_compat.h>
16 #include <spmi/spmi.h>
17 
18 DECLARE_GLOBAL_DATA_PTR;
19 
20 /* PMIC Arbiter configuration registers */
21 #define PMIC_ARB_VERSION 0x0000
22 #define PMIC_ARB_VERSION_V2_MIN 0x20010000
23 #define PMIC_ARB_VERSION_V3_MIN 0x30000000
24 #define PMIC_ARB_VERSION_V5_MIN 0x50000000
25 #define PMIC_ARB_VERSION_V7_MIN	0x70000000
26 
27 #define PMIC_ARB_FEATURES		0x0004
28 #define PMIC_ARB_FEATURES_PERIPH_MASK	GENMASK(10, 0)
29 
30 #define APID_MAP_OFFSET_V1_V2_V3 (0x800)
31 #define APID_MAP_OFFSET_V5 (0x900)
32 #define APID_MAP_OFFSET_V7 (0x2000)
33 #define ARB_CHANNEL_OFFSET(n) (0x4 * (n))
34 #define SPMI_CH_OFFSET(chnl) ((chnl) * 0x8000)
35 #define SPMI_V5_OBS_CH_OFFSET(chnl) ((chnl) * 0x80)
36 #define SPMI_V7_OBS_CH_OFFSET(chnl) ((chnl) * 0x20)
37 #define SPMI_V5_RW_CH_OFFSET(chnl) ((chnl) * 0x10000)
38 #define SPMI_V7_RW_CH_OFFSET(chnl) ((chnl) * 0x1000)
39 
40 #define SPMI_OWNERSHIP_PERIPH2OWNER(x)	((x) & 0x7)
41 
42 #define SPMI_REG_CMD0 0x0
43 #define SPMI_REG_CONFIG 0x4
44 #define SPMI_REG_STATUS 0x8
45 #define SPMI_REG_WDATA 0x10
46 #define SPMI_REG_RDATA 0x18
47 
48 #define SPMI_CMD_OPCODE_SHIFT 27
49 #define SPMI_CMD_SLAVE_ID_SHIFT 20
50 #define SPMI_CMD_ADDR_SHIFT 12
51 #define SPMI_CMD_ADDR_OFFSET_SHIFT 4
52 #define SPMI_CMD_BYTE_CNT_SHIFT 0
53 
54 #define SPMI_CMD_EXT_REG_WRITE_LONG 0x00
55 #define SPMI_CMD_EXT_REG_READ_LONG 0x01
56 
57 #define SPMI_STATUS_DONE 0x1
58 
59 #define SPMI_MAX_CHANNELS 128
60 #define SPMI_MAX_CHANNELS_V5	512
61 #define SPMI_MAX_CHANNELS_V7	1024
62 #define SPMI_MAX_SLAVES 16
63 #define SPMI_MAX_PERIPH 256
64 
65 #define SPMI_CHANNEL_READ_ONLY	BIT(31)
66 #define SPMI_CHANNEL_VALID	BIT(30)
67 #define SPMI_CHANNEL_MASK	0xffff
68 
69 enum arb_ver {
70 	V1 = 1,
71 	V2,
72 	V3,
73 	V5 = 5,
74 	V7 = 7
75 };
76 
77 /*
78  * PMIC arbiter version 5 uses different register offsets for read/write vs
79  * observer channels.
80  */
81 enum pmic_arb_channel {
82 	PMIC_ARB_CHANNEL_RW,
83 	PMIC_ARB_CHANNEL_OBS,
84 };
85 
86 struct msm_spmi_priv {
87 	phys_addr_t arb_chnl;  /* ARB channel mapping base */
88 	phys_addr_t spmi_chnls; /* SPMI channels */
89 	phys_addr_t spmi_obs;  /* SPMI observer */
90 	phys_addr_t spmi_cnfg;  /* SPMI config */
91 	u32 owner;	/* Current owner */
92 	unsigned int max_channels; /* Max channels */
93 	/* SPMI channel map */
94 	uint32_t channel_map[SPMI_MAX_SLAVES][SPMI_MAX_PERIPH];
95 	/* SPMI bus arbiter version */
96 	u32 arb_ver;
97 };
98 
pmic_arb_fmt_cmd_v1(u8 opc,u8 sid,u8 pid,u8 off)99 static u32 pmic_arb_fmt_cmd_v1(u8 opc, u8 sid, u8 pid, u8 off)
100 {
101 	return (opc << 27) | (sid << 20) | (pid << 12) | (off << 4) | 1;
102 }
103 
pmic_arb_fmt_cmd_v2(u8 opc,u8 off)104 static u32 pmic_arb_fmt_cmd_v2(u8 opc, u8 off)
105 {
106 	return (opc << 27) | (off << 4) | 1;
107 }
108 
msm_spmi_write(struct udevice * dev,int usid,int pid,int off,uint8_t val)109 static int msm_spmi_write(struct udevice *dev, int usid, int pid, int off,
110 			  uint8_t val)
111 {
112 	struct msm_spmi_priv *priv = dev_get_priv(dev);
113 	unsigned channel;
114 	unsigned int ch_offset;
115 	uint32_t reg = 0;
116 
117 	if (usid >= SPMI_MAX_SLAVES)
118 		return -EIO;
119 	if (pid >= SPMI_MAX_PERIPH)
120 		return -EIO;
121 	if (!(priv->channel_map[usid][pid] & SPMI_CHANNEL_VALID))
122 		return -EINVAL;
123 	if (priv->channel_map[usid][pid] & SPMI_CHANNEL_READ_ONLY)
124 		return -EPERM;
125 
126 	channel = priv->channel_map[usid][pid] & SPMI_CHANNEL_MASK;
127 
128 	debug("%s: [%d:%d] %s: channel %d\n", dev->name, usid, pid, __func__, channel);
129 
130 	switch (priv->arb_ver) {
131 	case V1:
132 		ch_offset = SPMI_CH_OFFSET(channel);
133 
134 		reg = pmic_arb_fmt_cmd_v1(SPMI_CMD_EXT_REG_WRITE_LONG,
135 					  usid, pid, off);
136 		break;
137 
138 	case V2:
139 		ch_offset = SPMI_CH_OFFSET(channel);
140 
141 		reg = pmic_arb_fmt_cmd_v2(SPMI_CMD_EXT_REG_WRITE_LONG, off);
142 		break;
143 
144 	case V5:
145 		ch_offset = SPMI_V5_RW_CH_OFFSET(channel);
146 
147 		reg = pmic_arb_fmt_cmd_v2(SPMI_CMD_EXT_REG_WRITE_LONG, off);
148 		break;
149 
150 	case V7:
151 		ch_offset = SPMI_V7_RW_CH_OFFSET(channel);
152 
153 		reg = pmic_arb_fmt_cmd_v2(SPMI_CMD_EXT_REG_WRITE_LONG, off);
154 		break;
155 	}
156 
157 	/* Disable IRQ mode for the current channel*/
158 	writel(0x0, priv->spmi_chnls + ch_offset + SPMI_REG_CONFIG);
159 
160 	/* Write single byte */
161 	writel(val, priv->spmi_chnls + ch_offset + SPMI_REG_WDATA);
162 
163 	/* Send write command */
164 	writel(reg, priv->spmi_chnls + ch_offset + SPMI_REG_CMD0);
165 
166 	/* Wait till CMD DONE status */
167 	reg = 0;
168 	while (!reg) {
169 		reg = readl(priv->spmi_chnls + ch_offset +
170 			    SPMI_REG_STATUS);
171 	}
172 
173 	if (reg ^ SPMI_STATUS_DONE) {
174 		printf("SPMI write failure.\n");
175 		return -EIO;
176 	}
177 
178 	return 0;
179 }
180 
msm_spmi_read(struct udevice * dev,int usid,int pid,int off)181 static int msm_spmi_read(struct udevice *dev, int usid, int pid, int off)
182 {
183 	struct msm_spmi_priv *priv = dev_get_priv(dev);
184 	unsigned channel;
185 	unsigned int ch_offset;
186 	uint32_t reg = 0;
187 
188 	if (usid >= SPMI_MAX_SLAVES)
189 		return -EIO;
190 	if (pid >= SPMI_MAX_PERIPH)
191 		return -EIO;
192 	if (!(priv->channel_map[usid][pid] & SPMI_CHANNEL_VALID))
193 		return -EINVAL;
194 
195 	channel = priv->channel_map[usid][pid] & SPMI_CHANNEL_MASK;
196 
197 	debug("%s: [%d:%d] %s: channel %d\n", dev->name, usid, pid, __func__, channel);
198 
199 	switch (priv->arb_ver) {
200 	case V1:
201 		ch_offset = SPMI_CH_OFFSET(channel);
202 
203 		/* Prepare read command */
204 		reg = pmic_arb_fmt_cmd_v1(SPMI_CMD_EXT_REG_READ_LONG,
205 					  usid, pid, off);
206 		break;
207 
208 	case V2:
209 		ch_offset = SPMI_CH_OFFSET(channel);
210 
211 		/* Prepare read command */
212 		reg = pmic_arb_fmt_cmd_v2(SPMI_CMD_EXT_REG_READ_LONG, off);
213 		break;
214 
215 	case V5:
216 		ch_offset = SPMI_V5_OBS_CH_OFFSET(channel);
217 
218 		/* Prepare read command */
219 		reg = pmic_arb_fmt_cmd_v2(SPMI_CMD_EXT_REG_READ_LONG, off);
220 		break;
221 
222 	case V7:
223 		ch_offset = SPMI_V7_OBS_CH_OFFSET(channel);
224 
225 		/* Prepare read command */
226 		reg = pmic_arb_fmt_cmd_v2(SPMI_CMD_EXT_REG_READ_LONG, off);
227 		break;
228 	}
229 
230 	/* Disable IRQ mode for the current channel*/
231 	writel(0x0, priv->spmi_obs + ch_offset + SPMI_REG_CONFIG);
232 
233 	/* Request read */
234 	writel(reg, priv->spmi_obs + ch_offset + SPMI_REG_CMD0);
235 
236 	/* Wait till CMD DONE status */
237 	reg = 0;
238 	while (!reg) {
239 		reg = readl(priv->spmi_obs + ch_offset + SPMI_REG_STATUS);
240 	}
241 
242 	if (reg ^ SPMI_STATUS_DONE) {
243 		printf("SPMI read failure.\n");
244 		return -EIO;
245 	}
246 
247 	/* Read the data */
248 	return readl(priv->spmi_obs + ch_offset +
249 				SPMI_REG_RDATA) & 0xFF;
250 }
251 
252 static struct dm_spmi_ops msm_spmi_ops = {
253 	.read = msm_spmi_read,
254 	.write = msm_spmi_write,
255 };
256 
257 /*
258  * In order to allow multiple EEs to write to a single PPID in arbiter
259  * version 5 and 7, there is more than one APID mapped to each PPID.
260  * The owner field for each of these mappings specifies the EE which is
261  * allowed to write to the APID.
262  */
msm_spmi_channel_map_v5(struct msm_spmi_priv * priv,unsigned int i,uint8_t slave_id,uint8_t pid)263 static void msm_spmi_channel_map_v5(struct msm_spmi_priv *priv, unsigned int i,
264 				    uint8_t slave_id, uint8_t pid)
265 {
266 	/* Mark channels read-only when from different owner */
267 	uint32_t cnfg = readl(priv->spmi_cnfg + ARB_CHANNEL_OFFSET(i));
268 	uint8_t owner = SPMI_OWNERSHIP_PERIPH2OWNER(cnfg);
269 	bool prev_valid = priv->channel_map[slave_id][pid] & SPMI_CHANNEL_VALID;
270 	uint32_t prev_read_only = priv->channel_map[slave_id][pid] & SPMI_CHANNEL_READ_ONLY;
271 
272 	if (!prev_valid) {
273 		/* First PPID mapping */
274 		priv->channel_map[slave_id][pid] = i | SPMI_CHANNEL_VALID;
275 		if (owner != priv->owner)
276 			priv->channel_map[slave_id][pid] |= SPMI_CHANNEL_READ_ONLY;
277 	} else if ((owner == priv->owner) && prev_read_only) {
278 		/* Read only and we found one we own, switch */
279 		priv->channel_map[slave_id][pid] = i | SPMI_CHANNEL_VALID;
280 	}
281 }
282 
msm_spmi_probe(struct udevice * dev)283 static int msm_spmi_probe(struct udevice *dev)
284 {
285 	struct msm_spmi_priv *priv = dev_get_priv(dev);
286 	phys_addr_t core_addr;
287 	u32 hw_ver;
288 	int i;
289 
290 	core_addr = dev_read_addr_name(dev, "core");
291 	priv->spmi_chnls = dev_read_addr_name(dev, "chnls");
292 	priv->spmi_obs = dev_read_addr_name(dev, "obsrvr");
293 	dev_read_u32(dev, "qcom,ee", &priv->owner);
294 
295 	hw_ver = readl(core_addr + PMIC_ARB_VERSION);
296 
297 	if (hw_ver < PMIC_ARB_VERSION_V3_MIN) {
298 		priv->arb_ver = V2;
299 		priv->arb_chnl = core_addr + APID_MAP_OFFSET_V1_V2_V3;
300 		priv->max_channels = SPMI_MAX_CHANNELS;
301 	} else if (hw_ver < PMIC_ARB_VERSION_V5_MIN) {
302 		priv->arb_ver = V3;
303 		priv->arb_chnl = core_addr + APID_MAP_OFFSET_V1_V2_V3;
304 		priv->max_channels = SPMI_MAX_CHANNELS;
305 	} else if (hw_ver < PMIC_ARB_VERSION_V7_MIN) {
306 		priv->arb_ver = V5;
307 		priv->arb_chnl = core_addr + APID_MAP_OFFSET_V5;
308 		priv->max_channels = min_t(u32, readl(core_addr + PMIC_ARB_FEATURES) &
309 						PMIC_ARB_FEATURES_PERIPH_MASK,
310 					   SPMI_MAX_CHANNELS_V5);
311 		priv->spmi_cnfg = dev_read_addr_name(dev, "cnfg");
312 	} else {
313 		/* TOFIX: handle second bus */
314 		priv->arb_ver = V7;
315 		priv->arb_chnl = core_addr + APID_MAP_OFFSET_V7;
316 		priv->max_channels = min_t(u32, readl(core_addr + PMIC_ARB_FEATURES) &
317 						PMIC_ARB_FEATURES_PERIPH_MASK,
318 					   SPMI_MAX_CHANNELS_V7);
319 		priv->spmi_cnfg = dev_read_addr_name(dev, "cnfg");
320 	}
321 
322 	dev_dbg(dev, "PMIC Arb Version-%d (%#x)\n", hw_ver >> 28, hw_ver);
323 
324 	if (priv->arb_chnl == FDT_ADDR_T_NONE ||
325 	    priv->spmi_chnls == FDT_ADDR_T_NONE ||
326 	    priv->spmi_obs == FDT_ADDR_T_NONE)
327 		return -EINVAL;
328 
329 	dev_dbg(dev, "priv->arb_chnl address (%#08llx)\n", priv->arb_chnl);
330 	dev_dbg(dev, "priv->spmi_chnls address (%#08llx)\n", priv->spmi_chnls);
331 	dev_dbg(dev, "priv->spmi_obs address (%#08llx)\n", priv->spmi_obs);
332 	/* Scan peripherals connected to each SPMI channel */
333 	for (i = 0; i < priv->max_channels; i++) {
334 		uint32_t periph = readl(priv->arb_chnl + ARB_CHANNEL_OFFSET(i));
335 		uint8_t slave_id = (periph & 0xf0000) >> 16;
336 		uint8_t pid = (periph & 0xff00) >> 8;
337 
338 		switch (priv->arb_ver) {
339 		case V2:
340 		case V3:
341 			priv->channel_map[slave_id][pid] = i | SPMI_CHANNEL_VALID;
342 			break;
343 
344 		case V5:
345 		case V7:
346 			msm_spmi_channel_map_v5(priv, i, slave_id, pid);
347 			break;
348 		}
349 	}
350 	return 0;
351 }
352 
353 static const struct udevice_id msm_spmi_ids[] = {
354 	{ .compatible = "qcom,spmi-pmic-arb" },
355 	{ }
356 };
357 
358 U_BOOT_DRIVER(msm_spmi) = {
359 	.name = "msm_spmi",
360 	.id = UCLASS_SPMI,
361 	.of_match = msm_spmi_ids,
362 	.ops = &msm_spmi_ops,
363 	.probe = msm_spmi_probe,
364 	.priv_auto = sizeof(struct msm_spmi_priv),
365 };
366