blob: 488c3c9e494775dc8281ce69345596bc5124c400 [file] [log] [blame]
Vinod Koul7c3cd182017-12-14 11:19:34 +05301// SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause)
2// Copyright(c) 2015-17 Intel Corporation.
3
4#include <linux/acpi.h>
Rander Wang02314532020-01-14 18:08:43 -06005#include <linux/delay.h>
Vinod Koul7c3cd182017-12-14 11:19:34 +05306#include <linux/mod_devicetable.h>
Vinod Koul9d715fa2017-12-14 11:19:37 +05307#include <linux/pm_runtime.h>
8#include <linux/soundwire/sdw_registers.h>
Vinod Koul7c3cd182017-12-14 11:19:34 +05309#include <linux/soundwire/sdw.h>
10#include "bus.h"
11
12/**
13 * sdw_add_bus_master() - add a bus Master instance
14 * @bus: bus instance
15 *
16 * Initializes the bus instance, read properties and create child
17 * devices.
18 */
19int sdw_add_bus_master(struct sdw_bus *bus)
20{
Sanyog Kale5c3eb9f2018-04-26 18:38:33 +053021 struct sdw_master_prop *prop = NULL;
Vinod Koul7c3cd182017-12-14 11:19:34 +053022 int ret;
23
24 if (!bus->dev) {
Pierre-Louis Bossart17ed5be2019-05-01 10:57:45 -050025 pr_err("SoundWire bus has no device\n");
Vinod Koul7c3cd182017-12-14 11:19:34 +053026 return -ENODEV;
27 }
28
Vinod Koul9d715fa2017-12-14 11:19:37 +053029 if (!bus->ops) {
Pierre-Louis Bossart17ed5be2019-05-01 10:57:45 -050030 dev_err(bus->dev, "SoundWire Bus ops are not set\n");
Vinod Koul9d715fa2017-12-14 11:19:37 +053031 return -EINVAL;
32 }
33
34 mutex_init(&bus->msg_lock);
Vinod Koul7c3cd182017-12-14 11:19:34 +053035 mutex_init(&bus->bus_lock);
36 INIT_LIST_HEAD(&bus->slaves);
Sanyog Kale89e59052018-04-26 18:38:08 +053037 INIT_LIST_HEAD(&bus->m_rt_list);
Vinod Koul7c3cd182017-12-14 11:19:34 +053038
Shreyas NCce6e74d2018-07-27 14:44:16 +053039 /*
40 * Initialize multi_link flag
41 * TODO: populate this flag by reading property from FW node
42 */
43 bus->multi_link = false;
Vinod Koul56d4fe32017-12-14 11:19:35 +053044 if (bus->ops->read_prop) {
45 ret = bus->ops->read_prop(bus);
46 if (ret < 0) {
Vinod Koul62f0cec2019-05-02 16:29:24 +053047 dev_err(bus->dev,
48 "Bus read properties failed:%d\n", ret);
Vinod Koul56d4fe32017-12-14 11:19:35 +053049 return ret;
50 }
51 }
52
Pierre-Louis Bossartbf034732019-08-21 13:58:18 -050053 sdw_bus_debugfs_init(bus);
54
Vinod Koul7c3cd182017-12-14 11:19:34 +053055 /*
Pierre-Louis Bossart21c2de22019-05-01 10:57:28 -050056 * Device numbers in SoundWire are 0 through 15. Enumeration device
Vinod Koul7c3cd182017-12-14 11:19:34 +053057 * number (0), Broadcast device number (15), Group numbers (12 and
58 * 13) and Master device number (14) are not used for assignment so
59 * mask these and other higher bits.
60 */
61
62 /* Set higher order bits */
63 *bus->assigned = ~GENMASK(SDW_BROADCAST_DEV_NUM, SDW_ENUM_DEV_NUM);
64
65 /* Set enumuration device number and broadcast device number */
66 set_bit(SDW_ENUM_DEV_NUM, bus->assigned);
67 set_bit(SDW_BROADCAST_DEV_NUM, bus->assigned);
68
69 /* Set group device numbers and master device number */
70 set_bit(SDW_GROUP12_DEV_NUM, bus->assigned);
71 set_bit(SDW_GROUP13_DEV_NUM, bus->assigned);
72 set_bit(SDW_MASTER_DEV_NUM, bus->assigned);
73
74 /*
75 * SDW is an enumerable bus, but devices can be powered off. So,
76 * they won't be able to report as present.
77 *
78 * Create Slave devices based on Slaves described in
79 * the respective firmware (ACPI/DT)
80 */
81 if (IS_ENABLED(CONFIG_ACPI) && ACPI_HANDLE(bus->dev))
82 ret = sdw_acpi_find_slaves(bus);
Srinivas Kandagatlaa2e48452019-08-29 17:35:12 +010083 else if (IS_ENABLED(CONFIG_OF) && bus->dev->of_node)
84 ret = sdw_of_find_slaves(bus);
Vinod Koul7c3cd182017-12-14 11:19:34 +053085 else
86 ret = -ENOTSUPP; /* No ACPI/DT so error out */
87
88 if (ret) {
89 dev_err(bus->dev, "Finding slaves failed:%d\n", ret);
90 return ret;
91 }
92
Sanyog Kale99b8a5d2018-04-26 18:38:28 +053093 /*
Sanyog Kale5c3eb9f2018-04-26 18:38:33 +053094 * Initialize clock values based on Master properties. The max
Pierre-Louis Bossart34243052019-05-22 14:47:22 -050095 * frequency is read from max_clk_freq property. Current assumption
Sanyog Kale5c3eb9f2018-04-26 18:38:33 +053096 * is that the bus will start at highest clock frequency when
97 * powered on.
98 *
Sanyog Kale99b8a5d2018-04-26 18:38:28 +053099 * Default active bank will be 0 as out of reset the Slaves have
100 * to start with bank 0 (Table 40 of Spec)
101 */
Sanyog Kale5c3eb9f2018-04-26 18:38:33 +0530102 prop = &bus->prop;
Pierre-Louis Bossart34243052019-05-22 14:47:22 -0500103 bus->params.max_dr_freq = prop->max_clk_freq * SDW_DOUBLE_RATE_FACTOR;
Sanyog Kale5c3eb9f2018-04-26 18:38:33 +0530104 bus->params.curr_dr_freq = bus->params.max_dr_freq;
Sanyog Kale99b8a5d2018-04-26 18:38:28 +0530105 bus->params.curr_bank = SDW_BANK0;
106 bus->params.next_bank = SDW_BANK1;
107
Vinod Koul7c3cd182017-12-14 11:19:34 +0530108 return 0;
109}
110EXPORT_SYMBOL(sdw_add_bus_master);
111
112static int sdw_delete_slave(struct device *dev, void *data)
113{
114 struct sdw_slave *slave = dev_to_sdw_dev(dev);
115 struct sdw_bus *bus = slave->bus;
116
Pierre-Louis Bossartdff70572020-01-14 18:08:41 -0600117 pm_runtime_disable(dev);
118
Pierre-Louis Bossartbf034732019-08-21 13:58:18 -0500119 sdw_slave_debugfs_exit(slave);
120
Vinod Koul7c3cd182017-12-14 11:19:34 +0530121 mutex_lock(&bus->bus_lock);
122
123 if (slave->dev_num) /* clear dev_num if assigned */
124 clear_bit(slave->dev_num, bus->assigned);
125
126 list_del_init(&slave->node);
127 mutex_unlock(&bus->bus_lock);
128
129 device_unregister(dev);
130 return 0;
131}
132
133/**
134 * sdw_delete_bus_master() - delete the bus master instance
135 * @bus: bus to be deleted
136 *
137 * Remove the instance, delete the child devices.
138 */
139void sdw_delete_bus_master(struct sdw_bus *bus)
140{
141 device_for_each_child(bus->dev, NULL, sdw_delete_slave);
Pierre-Louis Bossartbf034732019-08-21 13:58:18 -0500142
143 sdw_bus_debugfs_exit(bus);
Vinod Koul7c3cd182017-12-14 11:19:34 +0530144}
145EXPORT_SYMBOL(sdw_delete_bus_master);
146
Vinod Koul9d715fa2017-12-14 11:19:37 +0530147/*
148 * SDW IO Calls
149 */
150
151static inline int find_response_code(enum sdw_command_response resp)
152{
153 switch (resp) {
154 case SDW_CMD_OK:
155 return 0;
156
157 case SDW_CMD_IGNORED:
158 return -ENODATA;
159
160 case SDW_CMD_TIMEOUT:
161 return -ETIMEDOUT;
162
163 default:
164 return -EIO;
165 }
166}
167
168static inline int do_transfer(struct sdw_bus *bus, struct sdw_msg *msg)
169{
170 int retry = bus->prop.err_threshold;
171 enum sdw_command_response resp;
172 int ret = 0, i;
173
174 for (i = 0; i <= retry; i++) {
175 resp = bus->ops->xfer_msg(bus, msg);
176 ret = find_response_code(resp);
177
178 /* if cmd is ok or ignored return */
179 if (ret == 0 || ret == -ENODATA)
180 return ret;
181 }
182
183 return ret;
184}
185
186static inline int do_transfer_defer(struct sdw_bus *bus,
Pierre-Louis Bossart73ede042019-05-01 10:57:27 -0500187 struct sdw_msg *msg,
188 struct sdw_defer *defer)
Vinod Koul9d715fa2017-12-14 11:19:37 +0530189{
190 int retry = bus->prop.err_threshold;
191 enum sdw_command_response resp;
192 int ret = 0, i;
193
194 defer->msg = msg;
195 defer->length = msg->len;
Shreyas NCa306a0e2018-07-27 14:44:12 +0530196 init_completion(&defer->complete);
Vinod Koul9d715fa2017-12-14 11:19:37 +0530197
198 for (i = 0; i <= retry; i++) {
199 resp = bus->ops->xfer_msg_defer(bus, msg, defer);
200 ret = find_response_code(resp);
201 /* if cmd is ok or ignored return */
202 if (ret == 0 || ret == -ENODATA)
203 return ret;
204 }
205
206 return ret;
207}
208
209static int sdw_reset_page(struct sdw_bus *bus, u16 dev_num)
210{
211 int retry = bus->prop.err_threshold;
212 enum sdw_command_response resp;
213 int ret = 0, i;
214
215 for (i = 0; i <= retry; i++) {
216 resp = bus->ops->reset_page_addr(bus, dev_num);
217 ret = find_response_code(resp);
218 /* if cmd is ok or ignored return */
219 if (ret == 0 || ret == -ENODATA)
220 return ret;
221 }
222
223 return ret;
224}
225
226/**
227 * sdw_transfer() - Synchronous transfer message to a SDW Slave device
228 * @bus: SDW bus
229 * @msg: SDW message to be xfered
230 */
231int sdw_transfer(struct sdw_bus *bus, struct sdw_msg *msg)
232{
233 int ret;
234
235 mutex_lock(&bus->msg_lock);
236
237 ret = do_transfer(bus, msg);
238 if (ret != 0 && ret != -ENODATA)
239 dev_err(bus->dev, "trf on Slave %d failed:%d\n",
Pierre-Louis Bossart73ede042019-05-01 10:57:27 -0500240 msg->dev_num, ret);
Vinod Koul9d715fa2017-12-14 11:19:37 +0530241
242 if (msg->page)
243 sdw_reset_page(bus, msg->dev_num);
244
245 mutex_unlock(&bus->msg_lock);
246
247 return ret;
248}
249
250/**
251 * sdw_transfer_defer() - Asynchronously transfer message to a SDW Slave device
252 * @bus: SDW bus
253 * @msg: SDW message to be xfered
254 * @defer: Defer block for signal completion
255 *
256 * Caller needs to hold the msg_lock lock while calling this
257 */
258int sdw_transfer_defer(struct sdw_bus *bus, struct sdw_msg *msg,
Pierre-Louis Bossart73ede042019-05-01 10:57:27 -0500259 struct sdw_defer *defer)
Vinod Koul9d715fa2017-12-14 11:19:37 +0530260{
261 int ret;
262
263 if (!bus->ops->xfer_msg_defer)
264 return -ENOTSUPP;
265
266 ret = do_transfer_defer(bus, msg, defer);
267 if (ret != 0 && ret != -ENODATA)
268 dev_err(bus->dev, "Defer trf on Slave %d failed:%d\n",
Pierre-Louis Bossart73ede042019-05-01 10:57:27 -0500269 msg->dev_num, ret);
Vinod Koul9d715fa2017-12-14 11:19:37 +0530270
271 if (msg->page)
272 sdw_reset_page(bus, msg->dev_num);
273
274 return ret;
275}
276
Vinod Koul9d715fa2017-12-14 11:19:37 +0530277int sdw_fill_msg(struct sdw_msg *msg, struct sdw_slave *slave,
Pierre-Louis Bossart73ede042019-05-01 10:57:27 -0500278 u32 addr, size_t count, u16 dev_num, u8 flags, u8 *buf)
Vinod Koul9d715fa2017-12-14 11:19:37 +0530279{
280 memset(msg, 0, sizeof(*msg));
281 msg->addr = addr; /* addr is 16 bit and truncated here */
282 msg->len = count;
283 msg->dev_num = dev_num;
284 msg->flags = flags;
285 msg->buf = buf;
Vinod Koul9d715fa2017-12-14 11:19:37 +0530286
287 if (addr < SDW_REG_NO_PAGE) { /* no paging area */
288 return 0;
289 } else if (addr >= SDW_REG_MAX) { /* illegal addr */
290 pr_err("SDW: Invalid address %x passed\n", addr);
291 return -EINVAL;
292 }
293
294 if (addr < SDW_REG_OPTIONAL_PAGE) { /* 32k but no page */
295 if (slave && !slave->prop.paging_support)
296 return 0;
Pierre-Louis Bossart21c2de22019-05-01 10:57:28 -0500297 /* no need for else as that will fall-through to paging */
Vinod Koul9d715fa2017-12-14 11:19:37 +0530298 }
299
300 /* paging mandatory */
301 if (dev_num == SDW_ENUM_DEV_NUM || dev_num == SDW_BROADCAST_DEV_NUM) {
302 pr_err("SDW: Invalid device for paging :%d\n", dev_num);
303 return -EINVAL;
304 }
305
306 if (!slave) {
307 pr_err("SDW: No slave for paging addr\n");
308 return -EINVAL;
309 } else if (!slave->prop.paging_support) {
310 dev_err(&slave->dev,
Pierre-Louis Bossart17ed5be2019-05-01 10:57:45 -0500311 "address %x needs paging but no support\n", addr);
Vinod Koul9d715fa2017-12-14 11:19:37 +0530312 return -EINVAL;
313 }
314
315 msg->addr_page1 = (addr >> SDW_REG_SHIFT(SDW_SCP_ADDRPAGE1_MASK));
316 msg->addr_page2 = (addr >> SDW_REG_SHIFT(SDW_SCP_ADDRPAGE2_MASK));
317 msg->addr |= BIT(15);
318 msg->page = true;
319
320 return 0;
321}
322
Pierre-Louis Bossart60ee9be2020-01-14 18:08:38 -0600323/*
324 * Read/Write IO functions.
325 * no_pm versions can only be called by the bus, e.g. while enumerating or
326 * handling suspend-resume sequences.
327 * all clients need to use the pm versions
Vinod Koul9d715fa2017-12-14 11:19:37 +0530328 */
Pierre-Louis Bossart60ee9be2020-01-14 18:08:38 -0600329
330static int
331sdw_nread_no_pm(struct sdw_slave *slave, u32 addr, size_t count, u8 *val)
Vinod Koul9d715fa2017-12-14 11:19:37 +0530332{
333 struct sdw_msg msg;
334 int ret;
335
336 ret = sdw_fill_msg(&msg, slave, addr, count,
Pierre-Louis Bossart73ede042019-05-01 10:57:27 -0500337 slave->dev_num, SDW_MSG_FLAG_READ, val);
Vinod Koul9d715fa2017-12-14 11:19:37 +0530338 if (ret < 0)
339 return ret;
340
Pierre-Louis Bossart60ee9be2020-01-14 18:08:38 -0600341 return sdw_transfer(slave->bus, &msg);
342}
343
344static int
345sdw_nwrite_no_pm(struct sdw_slave *slave, u32 addr, size_t count, u8 *val)
346{
347 struct sdw_msg msg;
348 int ret;
349
350 ret = sdw_fill_msg(&msg, slave, addr, count,
351 slave->dev_num, SDW_MSG_FLAG_WRITE, val);
Shreyas NCc22c0ae2018-01-09 10:15:46 +0530352 if (ret < 0)
Vinod Koul9d715fa2017-12-14 11:19:37 +0530353 return ret;
354
Pierre-Louis Bossart60ee9be2020-01-14 18:08:38 -0600355 return sdw_transfer(slave->bus, &msg);
356}
357
358static int sdw_write_no_pm(struct sdw_slave *slave, u32 addr, u8 value)
359{
360 return sdw_nwrite_no_pm(slave, addr, 1, &value);
361}
362
Rander Wang02314532020-01-14 18:08:43 -0600363static int
364sdw_bread_no_pm(struct sdw_bus *bus, u16 dev_num, u32 addr)
365{
366 struct sdw_msg msg;
367 u8 buf;
368 int ret;
369
370 ret = sdw_fill_msg(&msg, NULL, addr, 1, dev_num,
371 SDW_MSG_FLAG_READ, &buf);
372 if (ret)
373 return ret;
374
375 ret = sdw_transfer(bus, &msg);
376 if (ret < 0)
377 return ret;
378 else
379 return buf;
380}
381
382static int
383sdw_bwrite_no_pm(struct sdw_bus *bus, u16 dev_num, u32 addr, u8 value)
384{
385 struct sdw_msg msg;
386 int ret;
387
388 ret = sdw_fill_msg(&msg, NULL, addr, 1, dev_num,
389 SDW_MSG_FLAG_WRITE, &value);
390 if (ret)
391 return ret;
392
393 return sdw_transfer(bus, &msg);
394}
395
396static int
397sdw_read_no_pm(struct sdw_slave *slave, u32 addr)
398{
399 u8 buf;
400 int ret;
401
402 ret = sdw_nread_no_pm(slave, addr, 1, &buf);
403 if (ret < 0)
404 return ret;
405 else
406 return buf;
407}
408
Pierre-Louis Bossart60ee9be2020-01-14 18:08:38 -0600409/**
410 * sdw_nread() - Read "n" contiguous SDW Slave registers
411 * @slave: SDW Slave
412 * @addr: Register address
413 * @count: length
414 * @val: Buffer for values to be read
415 */
416int sdw_nread(struct sdw_slave *slave, u32 addr, size_t count, u8 *val)
417{
418 int ret;
419
420 ret = pm_runtime_get_sync(slave->bus->dev);
421 if (ret < 0 && ret != -EACCES) {
422 pm_runtime_put_noidle(slave->bus->dev);
423 return ret;
424 }
425
426 ret = sdw_nread_no_pm(slave, addr, count, val);
427
428 pm_runtime_mark_last_busy(slave->bus->dev);
Vinod Koul9d715fa2017-12-14 11:19:37 +0530429 pm_runtime_put(slave->bus->dev);
430
431 return ret;
432}
433EXPORT_SYMBOL(sdw_nread);
434
435/**
436 * sdw_nwrite() - Write "n" contiguous SDW Slave registers
437 * @slave: SDW Slave
438 * @addr: Register address
439 * @count: length
440 * @val: Buffer for values to be read
441 */
442int sdw_nwrite(struct sdw_slave *slave, u32 addr, size_t count, u8 *val)
443{
Vinod Koul9d715fa2017-12-14 11:19:37 +0530444 int ret;
445
Vinod Koul9d715fa2017-12-14 11:19:37 +0530446 ret = pm_runtime_get_sync(slave->bus->dev);
Pierre-Louis Bossart60ee9be2020-01-14 18:08:38 -0600447 if (ret < 0 && ret != -EACCES) {
448 pm_runtime_put_noidle(slave->bus->dev);
Vinod Koul9d715fa2017-12-14 11:19:37 +0530449 return ret;
Pierre-Louis Bossart60ee9be2020-01-14 18:08:38 -0600450 }
Vinod Koul9d715fa2017-12-14 11:19:37 +0530451
Pierre-Louis Bossart60ee9be2020-01-14 18:08:38 -0600452 ret = sdw_nwrite_no_pm(slave, addr, count, val);
453
454 pm_runtime_mark_last_busy(slave->bus->dev);
Vinod Koul9d715fa2017-12-14 11:19:37 +0530455 pm_runtime_put(slave->bus->dev);
456
457 return ret;
458}
459EXPORT_SYMBOL(sdw_nwrite);
460
461/**
462 * sdw_read() - Read a SDW Slave register
463 * @slave: SDW Slave
464 * @addr: Register address
465 */
466int sdw_read(struct sdw_slave *slave, u32 addr)
467{
468 u8 buf;
469 int ret;
470
471 ret = sdw_nread(slave, addr, 1, &buf);
472 if (ret < 0)
473 return ret;
474 else
475 return buf;
476}
477EXPORT_SYMBOL(sdw_read);
478
479/**
480 * sdw_write() - Write a SDW Slave register
481 * @slave: SDW Slave
482 * @addr: Register address
483 * @value: Register value
484 */
485int sdw_write(struct sdw_slave *slave, u32 addr, u8 value)
486{
487 return sdw_nwrite(slave, addr, 1, &value);
Vinod Koul9d715fa2017-12-14 11:19:37 +0530488}
489EXPORT_SYMBOL(sdw_write);
490
Sanyog Kaled52d7a12017-12-14 11:19:39 +0530491/*
492 * SDW alert handling
493 */
494
495/* called with bus_lock held */
496static struct sdw_slave *sdw_get_slave(struct sdw_bus *bus, int i)
497{
498 struct sdw_slave *slave = NULL;
499
500 list_for_each_entry(slave, &bus->slaves, node) {
501 if (slave->dev_num == i)
502 return slave;
503 }
504
505 return NULL;
506}
507
508static int sdw_compare_devid(struct sdw_slave *slave, struct sdw_slave_id id)
509{
Pierre-Louis Bossart2e8c4ad2019-10-22 18:48:08 -0500510 if (slave->id.mfg_id != id.mfg_id ||
Pierre-Louis Bossart09830d52019-05-01 10:57:29 -0500511 slave->id.part_id != id.part_id ||
Pierre-Louis Bossart2e8c4ad2019-10-22 18:48:08 -0500512 slave->id.class_id != id.class_id ||
513 (slave->id.unique_id != SDW_IGNORED_UNIQUE_ID &&
514 slave->id.unique_id != id.unique_id))
Sanyog Kaled52d7a12017-12-14 11:19:39 +0530515 return -ENODEV;
516
517 return 0;
518}
519
520/* called with bus_lock held */
521static int sdw_get_device_num(struct sdw_slave *slave)
522{
523 int bit;
524
525 bit = find_first_zero_bit(slave->bus->assigned, SDW_MAX_DEVICES);
526 if (bit == SDW_MAX_DEVICES) {
527 bit = -ENODEV;
528 goto err;
529 }
530
531 /*
532 * Do not update dev_num in Slave data structure here,
533 * Update once program dev_num is successful
534 */
535 set_bit(bit, slave->bus->assigned);
536
537err:
538 return bit;
539}
540
541static int sdw_assign_device_num(struct sdw_slave *slave)
542{
543 int ret, dev_num;
Pierre-Louis Bossartfd6a3ac2020-01-13 16:56:37 -0600544 bool new_device = false;
Sanyog Kaled52d7a12017-12-14 11:19:39 +0530545
546 /* check first if device number is assigned, if so reuse that */
547 if (!slave->dev_num) {
Pierre-Louis Bossartfd6a3ac2020-01-13 16:56:37 -0600548 if (!slave->dev_num_sticky) {
549 mutex_lock(&slave->bus->bus_lock);
550 dev_num = sdw_get_device_num(slave);
551 mutex_unlock(&slave->bus->bus_lock);
552 if (dev_num < 0) {
553 dev_err(slave->bus->dev, "Get dev_num failed: %d\n",
554 dev_num);
555 return dev_num;
556 }
557 slave->dev_num = dev_num;
558 slave->dev_num_sticky = dev_num;
559 new_device = true;
560 } else {
561 slave->dev_num = slave->dev_num_sticky;
Sanyog Kaled52d7a12017-12-14 11:19:39 +0530562 }
Pierre-Louis Bossartfd6a3ac2020-01-13 16:56:37 -0600563 }
564
565 if (!new_device)
Sanyog Kaled52d7a12017-12-14 11:19:39 +0530566 dev_info(slave->bus->dev,
Pierre-Louis Bossartfd6a3ac2020-01-13 16:56:37 -0600567 "Slave already registered, reusing dev_num:%d\n",
Pierre-Louis Bossart73ede042019-05-01 10:57:27 -0500568 slave->dev_num);
Sanyog Kaled52d7a12017-12-14 11:19:39 +0530569
Pierre-Louis Bossartfd6a3ac2020-01-13 16:56:37 -0600570 /* Clear the slave->dev_num to transfer message on device 0 */
571 dev_num = slave->dev_num;
572 slave->dev_num = 0;
Sanyog Kaled52d7a12017-12-14 11:19:39 +0530573
Pierre-Louis Bossartd300de4f2020-01-14 18:08:39 -0600574 ret = sdw_write_no_pm(slave, SDW_SCP_DEVNUMBER, dev_num);
Sanyog Kaled52d7a12017-12-14 11:19:39 +0530575 if (ret < 0) {
Pierre-Louis Bossart6e0ac6a2019-08-05 19:55:09 -0500576 dev_err(&slave->dev, "Program device_num %d failed: %d\n",
577 dev_num, ret);
Sanyog Kaled52d7a12017-12-14 11:19:39 +0530578 return ret;
579 }
580
581 /* After xfer of msg, restore dev_num */
Pierre-Louis Bossartfd6a3ac2020-01-13 16:56:37 -0600582 slave->dev_num = slave->dev_num_sticky;
Sanyog Kaled52d7a12017-12-14 11:19:39 +0530583
584 return 0;
585}
586
Vinod Koul7c3cd182017-12-14 11:19:34 +0530587void sdw_extract_slave_id(struct sdw_bus *bus,
Pierre-Louis Bossart73ede042019-05-01 10:57:27 -0500588 u64 addr, struct sdw_slave_id *id)
Vinod Koul7c3cd182017-12-14 11:19:34 +0530589{
Pierre-Louis Bossart17ed5be2019-05-01 10:57:45 -0500590 dev_dbg(bus->dev, "SDW Slave Addr: %llx\n", addr);
Vinod Koul7c3cd182017-12-14 11:19:34 +0530591
Pierre-Louis Bossart2c6cff62020-02-25 11:00:41 -0600592 id->sdw_version = SDW_VERSION(addr);
593 id->unique_id = SDW_UNIQUE_ID(addr);
594 id->mfg_id = SDW_MFG_ID(addr);
595 id->part_id = SDW_PART_ID(addr);
596 id->class_id = SDW_CLASS_ID(addr);
Vinod Koul7c3cd182017-12-14 11:19:34 +0530597
598 dev_dbg(bus->dev,
Pierre-Louis Bossart17ed5be2019-05-01 10:57:45 -0500599 "SDW Slave class_id %x, part_id %x, mfg_id %x, unique_id %x, version %x\n",
Vinod Koul7c3cd182017-12-14 11:19:34 +0530600 id->class_id, id->part_id, id->mfg_id,
601 id->unique_id, id->sdw_version);
Vinod Koul7c3cd182017-12-14 11:19:34 +0530602}
Sanyog Kaled52d7a12017-12-14 11:19:39 +0530603
604static int sdw_program_device_num(struct sdw_bus *bus)
605{
606 u8 buf[SDW_NUM_DEV_ID_REGISTERS] = {0};
607 struct sdw_slave *slave, *_s;
608 struct sdw_slave_id id;
609 struct sdw_msg msg;
610 bool found = false;
611 int count = 0, ret;
612 u64 addr;
613
614 /* No Slave, so use raw xfer api */
615 ret = sdw_fill_msg(&msg, NULL, SDW_SCP_DEVID_0,
Pierre-Louis Bossart73ede042019-05-01 10:57:27 -0500616 SDW_NUM_DEV_ID_REGISTERS, 0, SDW_MSG_FLAG_READ, buf);
Sanyog Kaled52d7a12017-12-14 11:19:39 +0530617 if (ret < 0)
618 return ret;
619
620 do {
621 ret = sdw_transfer(bus, &msg);
622 if (ret == -ENODATA) { /* end of device id reads */
Pierre-Louis Bossart6e0ac6a2019-08-05 19:55:09 -0500623 dev_dbg(bus->dev, "No more devices to enumerate\n");
Sanyog Kaled52d7a12017-12-14 11:19:39 +0530624 ret = 0;
625 break;
626 }
627 if (ret < 0) {
628 dev_err(bus->dev, "DEVID read fail:%d\n", ret);
629 break;
630 }
631
632 /*
633 * Construct the addr and extract. Cast the higher shift
634 * bits to avoid truncation due to size limit.
635 */
636 addr = buf[5] | (buf[4] << 8) | (buf[3] << 16) |
Colin Ian King0132af052018-01-08 22:22:42 +0530637 ((u64)buf[2] << 24) | ((u64)buf[1] << 32) |
638 ((u64)buf[0] << 40);
Sanyog Kaled52d7a12017-12-14 11:19:39 +0530639
640 sdw_extract_slave_id(bus, addr, &id);
641
642 /* Now compare with entries */
643 list_for_each_entry_safe(slave, _s, &bus->slaves, node) {
644 if (sdw_compare_devid(slave, id) == 0) {
645 found = true;
646
647 /*
648 * Assign a new dev_num to this Slave and
649 * not mark it present. It will be marked
650 * present after it reports ATTACHED on new
651 * dev_num
652 */
653 ret = sdw_assign_device_num(slave);
654 if (ret) {
655 dev_err(slave->bus->dev,
Pierre-Louis Bossart17ed5be2019-05-01 10:57:45 -0500656 "Assign dev_num failed:%d\n",
Sanyog Kaled52d7a12017-12-14 11:19:39 +0530657 ret);
658 return ret;
659 }
660
661 break;
662 }
663 }
664
Pierre-Louis Bossartd7b956b2019-05-01 10:57:30 -0500665 if (!found) {
Sanyog Kaled52d7a12017-12-14 11:19:39 +0530666 /* TODO: Park this device in Group 13 */
Pierre-Louis Bossart17ed5be2019-05-01 10:57:45 -0500667 dev_err(bus->dev, "Slave Entry not found\n");
Sanyog Kaled52d7a12017-12-14 11:19:39 +0530668 }
669
670 count++;
671
672 /*
673 * Check till error out or retry (count) exhausts.
674 * Device can drop off and rejoin during enumeration
675 * so count till twice the bound.
676 */
677
678 } while (ret == 0 && count < (SDW_MAX_DEVICES * 2));
679
680 return ret;
681}
682
683static void sdw_modify_slave_status(struct sdw_slave *slave,
Pierre-Louis Bossart73ede042019-05-01 10:57:27 -0500684 enum sdw_slave_status status)
Sanyog Kaled52d7a12017-12-14 11:19:39 +0530685{
686 mutex_lock(&slave->bus->bus_lock);
Pierre-Louis Bossartfb9469e2020-01-14 18:08:36 -0600687
688 dev_vdbg(&slave->dev,
689 "%s: changing status slave %d status %d new status %d\n",
690 __func__, slave->dev_num, slave->status, status);
691
692 if (status == SDW_SLAVE_UNATTACHED) {
693 dev_dbg(&slave->dev,
694 "%s: initializing completion for Slave %d\n",
695 __func__, slave->dev_num);
696
697 init_completion(&slave->enumeration_complete);
Pierre-Louis Bossarta90def02020-01-14 18:08:37 -0600698 init_completion(&slave->initialization_complete);
Pierre-Louis Bossartfb9469e2020-01-14 18:08:36 -0600699
700 } else if ((status == SDW_SLAVE_ATTACHED) &&
701 (slave->status == SDW_SLAVE_UNATTACHED)) {
702 dev_dbg(&slave->dev,
703 "%s: signaling completion for Slave %d\n",
704 __func__, slave->dev_num);
705
706 complete(&slave->enumeration_complete);
707 }
Sanyog Kaled52d7a12017-12-14 11:19:39 +0530708 slave->status = status;
709 mutex_unlock(&slave->bus->bus_lock);
710}
711
Rander Wang02314532020-01-14 18:08:43 -0600712static enum sdw_clk_stop_mode sdw_get_clk_stop_mode(struct sdw_slave *slave)
713{
714 enum sdw_clk_stop_mode mode;
715
716 /*
717 * Query for clock stop mode if Slave implements
718 * ops->get_clk_stop_mode, else read from property.
719 */
720 if (slave->ops && slave->ops->get_clk_stop_mode) {
721 mode = slave->ops->get_clk_stop_mode(slave);
722 } else {
723 if (slave->prop.clk_stop_mode1)
724 mode = SDW_CLK_STOP_MODE1;
725 else
726 mode = SDW_CLK_STOP_MODE0;
727 }
728
729 return mode;
730}
731
732static int sdw_slave_clk_stop_callback(struct sdw_slave *slave,
733 enum sdw_clk_stop_mode mode,
734 enum sdw_clk_stop_type type)
735{
736 int ret;
737
738 if (slave->ops && slave->ops->clk_stop) {
739 ret = slave->ops->clk_stop(slave, mode, type);
740 if (ret < 0) {
741 dev_err(&slave->dev,
742 "Clk Stop type =%d failed: %d\n", type, ret);
743 return ret;
744 }
745 }
746
747 return 0;
748}
749
750static int sdw_slave_clk_stop_prepare(struct sdw_slave *slave,
751 enum sdw_clk_stop_mode mode,
752 bool prepare)
753{
754 bool wake_en;
755 u32 val = 0;
756 int ret;
757
758 wake_en = slave->prop.wake_capable;
759
760 if (prepare) {
761 val = SDW_SCP_SYSTEMCTRL_CLK_STP_PREP;
762
763 if (mode == SDW_CLK_STOP_MODE1)
764 val |= SDW_SCP_SYSTEMCTRL_CLK_STP_MODE1;
765
766 if (wake_en)
767 val |= SDW_SCP_SYSTEMCTRL_WAKE_UP_EN;
768 } else {
769 val = sdw_read_no_pm(slave, SDW_SCP_SYSTEMCTRL);
770
771 val &= ~(SDW_SCP_SYSTEMCTRL_CLK_STP_PREP);
772 }
773
774 ret = sdw_write_no_pm(slave, SDW_SCP_SYSTEMCTRL, val);
775
776 if (ret != 0)
777 dev_err(&slave->dev,
778 "Clock Stop prepare failed for slave: %d", ret);
779
780 return ret;
781}
782
783static int sdw_bus_wait_for_clk_prep_deprep(struct sdw_bus *bus, u16 dev_num)
784{
785 int retry = bus->clk_stop_timeout;
786 int val;
787
788 do {
789 val = sdw_bread_no_pm(bus, dev_num, SDW_SCP_STAT) &
790 SDW_SCP_STAT_CLK_STP_NF;
791 if (!val) {
792 dev_info(bus->dev, "clock stop prep/de-prep done slave:%d",
793 dev_num);
794 return 0;
795 }
796
797 usleep_range(1000, 1500);
798 retry--;
799 } while (retry);
800
801 dev_err(bus->dev, "clock stop prep/de-prep failed slave:%d",
802 dev_num);
803
804 return -ETIMEDOUT;
805}
806
807/**
808 * sdw_bus_prep_clk_stop: prepare Slave(s) for clock stop
809 *
810 * @bus: SDW bus instance
811 *
812 * Query Slave for clock stop mode and prepare for that mode.
813 */
814int sdw_bus_prep_clk_stop(struct sdw_bus *bus)
815{
816 enum sdw_clk_stop_mode slave_mode;
817 bool simple_clk_stop = true;
818 struct sdw_slave *slave;
819 bool is_slave = false;
820 int ret = 0;
821
822 /*
823 * In order to save on transition time, prepare
824 * each Slave and then wait for all Slave(s) to be
825 * prepared for clock stop.
826 */
827 list_for_each_entry(slave, &bus->slaves, node) {
828 if (!slave->dev_num)
829 continue;
830
831 /* Identify if Slave(s) are available on Bus */
832 is_slave = true;
833
834 if (slave->status != SDW_SLAVE_ATTACHED &&
835 slave->status != SDW_SLAVE_ALERT)
836 continue;
837
838 slave_mode = sdw_get_clk_stop_mode(slave);
839 slave->curr_clk_stop_mode = slave_mode;
840
841 ret = sdw_slave_clk_stop_callback(slave, slave_mode,
842 SDW_CLK_PRE_PREPARE);
843 if (ret < 0) {
844 dev_err(&slave->dev,
845 "pre-prepare failed:%d", ret);
846 return ret;
847 }
848
849 ret = sdw_slave_clk_stop_prepare(slave,
850 slave_mode, true);
851 if (ret < 0) {
852 dev_err(&slave->dev,
853 "pre-prepare failed:%d", ret);
854 return ret;
855 }
856
857 if (slave_mode == SDW_CLK_STOP_MODE1)
858 simple_clk_stop = false;
859 }
860
861 if (is_slave && !simple_clk_stop) {
862 ret = sdw_bus_wait_for_clk_prep_deprep(bus,
863 SDW_BROADCAST_DEV_NUM);
864 if (ret < 0)
865 return ret;
866 }
867
868 /* Inform slaves that prep is done */
869 list_for_each_entry(slave, &bus->slaves, node) {
870 if (!slave->dev_num)
871 continue;
872
873 if (slave->status != SDW_SLAVE_ATTACHED &&
874 slave->status != SDW_SLAVE_ALERT)
875 continue;
876
877 slave_mode = slave->curr_clk_stop_mode;
878
879 if (slave_mode == SDW_CLK_STOP_MODE1) {
880 ret = sdw_slave_clk_stop_callback(slave,
881 slave_mode,
882 SDW_CLK_POST_PREPARE);
883
884 if (ret < 0) {
885 dev_err(&slave->dev,
886 "post-prepare failed:%d", ret);
887 }
888 }
889 }
890
891 return ret;
892}
893EXPORT_SYMBOL(sdw_bus_prep_clk_stop);
894
895/**
896 * sdw_bus_clk_stop: stop bus clock
897 *
898 * @bus: SDW bus instance
899 *
900 * After preparing the Slaves for clock stop, stop the clock by broadcasting
901 * write to SCP_CTRL register.
902 */
903int sdw_bus_clk_stop(struct sdw_bus *bus)
904{
905 int ret;
906
907 /*
908 * broadcast clock stop now, attached Slaves will ACK this,
909 * unattached will ignore
910 */
911 ret = sdw_bwrite_no_pm(bus, SDW_BROADCAST_DEV_NUM,
912 SDW_SCP_CTRL, SDW_SCP_CTRL_CLK_STP_NOW);
913 if (ret < 0) {
Pierre-Louis Bossartdde73532020-01-14 18:08:44 -0600914 if (ret == -ENODATA)
915 dev_dbg(bus->dev,
916 "ClockStopNow Broadcast msg ignored %d", ret);
917 else
918 dev_err(bus->dev,
919 "ClockStopNow Broadcast msg failed %d", ret);
Rander Wang02314532020-01-14 18:08:43 -0600920 return ret;
921 }
922
923 return 0;
924}
925EXPORT_SYMBOL(sdw_bus_clk_stop);
926
927/**
928 * sdw_bus_exit_clk_stop: Exit clock stop mode
929 *
930 * @bus: SDW bus instance
931 *
932 * This De-prepares the Slaves by exiting Clock Stop Mode 0. For the Slaves
933 * exiting Clock Stop Mode 1, they will be de-prepared after they enumerate
934 * back.
935 */
936int sdw_bus_exit_clk_stop(struct sdw_bus *bus)
937{
938 enum sdw_clk_stop_mode mode;
939 bool simple_clk_stop = true;
940 struct sdw_slave *slave;
941 bool is_slave = false;
942 int ret;
943
944 /*
945 * In order to save on transition time, de-prepare
946 * each Slave and then wait for all Slave(s) to be
947 * de-prepared after clock resume.
948 */
949 list_for_each_entry(slave, &bus->slaves, node) {
950 if (!slave->dev_num)
951 continue;
952
953 /* Identify if Slave(s) are available on Bus */
954 is_slave = true;
955
956 if (slave->status != SDW_SLAVE_ATTACHED &&
957 slave->status != SDW_SLAVE_ALERT)
958 continue;
959
960 mode = slave->curr_clk_stop_mode;
961
962 if (mode == SDW_CLK_STOP_MODE1) {
963 simple_clk_stop = false;
964 continue;
965 }
966
967 ret = sdw_slave_clk_stop_callback(slave, mode,
968 SDW_CLK_PRE_DEPREPARE);
969 if (ret < 0)
970 dev_warn(&slave->dev,
971 "clk stop deprep failed:%d", ret);
972
973 ret = sdw_slave_clk_stop_prepare(slave, mode,
974 false);
975
976 if (ret < 0)
977 dev_warn(&slave->dev,
978 "clk stop deprep failed:%d", ret);
979 }
980
981 if (is_slave && !simple_clk_stop)
982 sdw_bus_wait_for_clk_prep_deprep(bus, SDW_BROADCAST_DEV_NUM);
983
984 list_for_each_entry(slave, &bus->slaves, node) {
985 if (!slave->dev_num)
986 continue;
987
988 if (slave->status != SDW_SLAVE_ATTACHED &&
989 slave->status != SDW_SLAVE_ALERT)
990 continue;
991
992 mode = slave->curr_clk_stop_mode;
993 sdw_slave_clk_stop_callback(slave, mode,
994 SDW_CLK_POST_DEPREPARE);
995 }
996
997 return 0;
998}
999EXPORT_SYMBOL(sdw_bus_exit_clk_stop);
1000
Sanyog Kale79df15b2018-04-26 18:38:23 +05301001int sdw_configure_dpn_intr(struct sdw_slave *slave,
Pierre-Louis Bossart73ede042019-05-01 10:57:27 -05001002 int port, bool enable, int mask)
Sanyog Kale79df15b2018-04-26 18:38:23 +05301003{
1004 u32 addr;
1005 int ret;
1006 u8 val = 0;
1007
1008 addr = SDW_DPN_INTMASK(port);
1009
1010 /* Set/Clear port ready interrupt mask */
1011 if (enable) {
1012 val |= mask;
1013 val |= SDW_DPN_INT_PORT_READY;
1014 } else {
1015 val &= ~(mask);
1016 val &= ~SDW_DPN_INT_PORT_READY;
1017 }
1018
1019 ret = sdw_update(slave, addr, (mask | SDW_DPN_INT_PORT_READY), val);
1020 if (ret < 0)
1021 dev_err(slave->bus->dev,
Pierre-Louis Bossart17ed5be2019-05-01 10:57:45 -05001022 "SDW_DPN_INTMASK write failed:%d\n", val);
Sanyog Kale79df15b2018-04-26 18:38:23 +05301023
1024 return ret;
1025}
1026
Sanyog Kaled52d7a12017-12-14 11:19:39 +05301027static int sdw_initialize_slave(struct sdw_slave *slave)
1028{
1029 struct sdw_slave_prop *prop = &slave->prop;
1030 int ret;
1031 u8 val;
1032
1033 /*
1034 * Set bus clash, parity and SCP implementation
1035 * defined interrupt mask
1036 * TODO: Read implementation defined interrupt mask
1037 * from Slave property
1038 */
1039 val = SDW_SCP_INT1_IMPL_DEF | SDW_SCP_INT1_BUS_CLASH |
1040 SDW_SCP_INT1_PARITY;
1041
1042 /* Enable SCP interrupts */
1043 ret = sdw_update(slave, SDW_SCP_INTMASK1, val, val);
1044 if (ret < 0) {
1045 dev_err(slave->bus->dev,
Pierre-Louis Bossart17ed5be2019-05-01 10:57:45 -05001046 "SDW_SCP_INTMASK1 write failed:%d\n", ret);
Sanyog Kaled52d7a12017-12-14 11:19:39 +05301047 return ret;
1048 }
1049
1050 /* No need to continue if DP0 is not present */
1051 if (!slave->prop.dp0_prop)
1052 return 0;
1053
1054 /* Enable DP0 interrupts */
Pierre-Louis Bossart8acbbfe2019-05-22 14:47:25 -05001055 val = prop->dp0_prop->imp_def_interrupts;
Sanyog Kaled52d7a12017-12-14 11:19:39 +05301056 val |= SDW_DP0_INT_PORT_READY | SDW_DP0_INT_BRA_FAILURE;
1057
1058 ret = sdw_update(slave, SDW_DP0_INTMASK, val, val);
Bard Liao5de79ba2020-02-27 16:09:49 -06001059 if (ret < 0)
Sanyog Kaled52d7a12017-12-14 11:19:39 +05301060 dev_err(slave->bus->dev,
Pierre-Louis Bossart17ed5be2019-05-01 10:57:45 -05001061 "SDW_DP0_INTMASK read failed:%d\n", ret);
Bard Liao5de79ba2020-02-27 16:09:49 -06001062 return ret;
Sanyog Kaled52d7a12017-12-14 11:19:39 +05301063}
Vinod Koulb0a9c372017-12-14 11:19:40 +05301064
1065static int sdw_handle_dp0_interrupt(struct sdw_slave *slave, u8 *slave_status)
1066{
1067 u8 clear = 0, impl_int_mask;
1068 int status, status2, ret, count = 0;
1069
1070 status = sdw_read(slave, SDW_DP0_INT);
1071 if (status < 0) {
1072 dev_err(slave->bus->dev,
Pierre-Louis Bossart17ed5be2019-05-01 10:57:45 -05001073 "SDW_DP0_INT read failed:%d\n", status);
Vinod Koulb0a9c372017-12-14 11:19:40 +05301074 return status;
1075 }
1076
1077 do {
Vinod Koulb0a9c372017-12-14 11:19:40 +05301078 if (status & SDW_DP0_INT_TEST_FAIL) {
Pierre-Louis Bossart17ed5be2019-05-01 10:57:45 -05001079 dev_err(&slave->dev, "Test fail for port 0\n");
Vinod Koulb0a9c372017-12-14 11:19:40 +05301080 clear |= SDW_DP0_INT_TEST_FAIL;
1081 }
1082
1083 /*
1084 * Assumption: PORT_READY interrupt will be received only for
1085 * ports implementing Channel Prepare state machine (CP_SM)
1086 */
1087
1088 if (status & SDW_DP0_INT_PORT_READY) {
1089 complete(&slave->port_ready[0]);
1090 clear |= SDW_DP0_INT_PORT_READY;
1091 }
1092
1093 if (status & SDW_DP0_INT_BRA_FAILURE) {
Pierre-Louis Bossart17ed5be2019-05-01 10:57:45 -05001094 dev_err(&slave->dev, "BRA failed\n");
Vinod Koulb0a9c372017-12-14 11:19:40 +05301095 clear |= SDW_DP0_INT_BRA_FAILURE;
1096 }
1097
1098 impl_int_mask = SDW_DP0_INT_IMPDEF1 |
1099 SDW_DP0_INT_IMPDEF2 | SDW_DP0_INT_IMPDEF3;
1100
1101 if (status & impl_int_mask) {
1102 clear |= impl_int_mask;
1103 *slave_status = clear;
1104 }
1105
1106 /* clear the interrupt */
1107 ret = sdw_write(slave, SDW_DP0_INT, clear);
1108 if (ret < 0) {
1109 dev_err(slave->bus->dev,
Pierre-Louis Bossart17ed5be2019-05-01 10:57:45 -05001110 "SDW_DP0_INT write failed:%d\n", ret);
Vinod Koulb0a9c372017-12-14 11:19:40 +05301111 return ret;
1112 }
1113
1114 /* Read DP0 interrupt again */
1115 status2 = sdw_read(slave, SDW_DP0_INT);
1116 if (status2 < 0) {
1117 dev_err(slave->bus->dev,
Pierre-Louis Bossart17ed5be2019-05-01 10:57:45 -05001118 "SDW_DP0_INT read failed:%d\n", status2);
Wei Yongjun80cd8f02018-01-08 22:22:44 +05301119 return status2;
Vinod Koulb0a9c372017-12-14 11:19:40 +05301120 }
1121 status &= status2;
1122
1123 count++;
1124
1125 /* we can get alerts while processing so keep retrying */
1126 } while (status != 0 && count < SDW_READ_INTR_CLEAR_RETRY);
1127
1128 if (count == SDW_READ_INTR_CLEAR_RETRY)
Pierre-Louis Bossart17ed5be2019-05-01 10:57:45 -05001129 dev_warn(slave->bus->dev, "Reached MAX_RETRY on DP0 read\n");
Vinod Koulb0a9c372017-12-14 11:19:40 +05301130
1131 return ret;
1132}
1133
1134static int sdw_handle_port_interrupt(struct sdw_slave *slave,
Pierre-Louis Bossart73ede042019-05-01 10:57:27 -05001135 int port, u8 *slave_status)
Vinod Koulb0a9c372017-12-14 11:19:40 +05301136{
1137 u8 clear = 0, impl_int_mask;
1138 int status, status2, ret, count = 0;
1139 u32 addr;
1140
1141 if (port == 0)
1142 return sdw_handle_dp0_interrupt(slave, slave_status);
1143
1144 addr = SDW_DPN_INT(port);
1145 status = sdw_read(slave, addr);
1146 if (status < 0) {
1147 dev_err(slave->bus->dev,
Pierre-Louis Bossart17ed5be2019-05-01 10:57:45 -05001148 "SDW_DPN_INT read failed:%d\n", status);
Vinod Koulb0a9c372017-12-14 11:19:40 +05301149
1150 return status;
1151 }
1152
1153 do {
Vinod Koulb0a9c372017-12-14 11:19:40 +05301154 if (status & SDW_DPN_INT_TEST_FAIL) {
Pierre-Louis Bossart17ed5be2019-05-01 10:57:45 -05001155 dev_err(&slave->dev, "Test fail for port:%d\n", port);
Vinod Koulb0a9c372017-12-14 11:19:40 +05301156 clear |= SDW_DPN_INT_TEST_FAIL;
1157 }
1158
1159 /*
1160 * Assumption: PORT_READY interrupt will be received only
1161 * for ports implementing CP_SM.
1162 */
1163 if (status & SDW_DPN_INT_PORT_READY) {
1164 complete(&slave->port_ready[port]);
1165 clear |= SDW_DPN_INT_PORT_READY;
1166 }
1167
1168 impl_int_mask = SDW_DPN_INT_IMPDEF1 |
1169 SDW_DPN_INT_IMPDEF2 | SDW_DPN_INT_IMPDEF3;
1170
Vinod Koulb0a9c372017-12-14 11:19:40 +05301171 if (status & impl_int_mask) {
1172 clear |= impl_int_mask;
1173 *slave_status = clear;
1174 }
1175
1176 /* clear the interrupt */
1177 ret = sdw_write(slave, addr, clear);
1178 if (ret < 0) {
1179 dev_err(slave->bus->dev,
Pierre-Louis Bossart17ed5be2019-05-01 10:57:45 -05001180 "SDW_DPN_INT write failed:%d\n", ret);
Vinod Koulb0a9c372017-12-14 11:19:40 +05301181 return ret;
1182 }
1183
1184 /* Read DPN interrupt again */
1185 status2 = sdw_read(slave, addr);
Wei Yongjun80cd8f02018-01-08 22:22:44 +05301186 if (status2 < 0) {
Vinod Koulb0a9c372017-12-14 11:19:40 +05301187 dev_err(slave->bus->dev,
Pierre-Louis Bossart17ed5be2019-05-01 10:57:45 -05001188 "SDW_DPN_INT read failed:%d\n", status2);
Wei Yongjun80cd8f02018-01-08 22:22:44 +05301189 return status2;
Vinod Koulb0a9c372017-12-14 11:19:40 +05301190 }
1191 status &= status2;
1192
1193 count++;
1194
1195 /* we can get alerts while processing so keep retrying */
1196 } while (status != 0 && count < SDW_READ_INTR_CLEAR_RETRY);
1197
1198 if (count == SDW_READ_INTR_CLEAR_RETRY)
1199 dev_warn(slave->bus->dev, "Reached MAX_RETRY on port read");
1200
1201 return ret;
1202}
1203
1204static int sdw_handle_slave_alerts(struct sdw_slave *slave)
1205{
1206 struct sdw_slave_intr_status slave_intr;
Bard Liaof1fac632019-08-30 02:11:35 +08001207 u8 clear = 0, bit, port_status[15] = {0};
Vinod Koulb0a9c372017-12-14 11:19:40 +05301208 int port_num, stat, ret, count = 0;
1209 unsigned long port;
1210 bool slave_notify = false;
1211 u8 buf, buf2[2], _buf, _buf2[2];
1212
1213 sdw_modify_slave_status(slave, SDW_SLAVE_ALERT);
1214
Rander Wangaa792932020-01-14 18:08:42 -06001215 ret = pm_runtime_get_sync(&slave->dev);
1216 if (ret < 0 && ret != -EACCES) {
1217 dev_err(&slave->dev, "Failed to resume device: %d\n", ret);
1218 pm_runtime_put_noidle(slave->bus->dev);
1219 return ret;
1220 }
1221
Vinod Koulb0a9c372017-12-14 11:19:40 +05301222 /* Read Instat 1, Instat 2 and Instat 3 registers */
Vinod Koul72b16d4a2019-05-02 16:29:26 +05301223 ret = sdw_read(slave, SDW_SCP_INT1);
Vinod Koulb0a9c372017-12-14 11:19:40 +05301224 if (ret < 0) {
1225 dev_err(slave->bus->dev,
Pierre-Louis Bossart17ed5be2019-05-01 10:57:45 -05001226 "SDW_SCP_INT1 read failed:%d\n", ret);
Rander Wangaa792932020-01-14 18:08:42 -06001227 goto io_err;
Vinod Koulb0a9c372017-12-14 11:19:40 +05301228 }
Vinod Koul72b16d4a2019-05-02 16:29:26 +05301229 buf = ret;
Vinod Koulb0a9c372017-12-14 11:19:40 +05301230
1231 ret = sdw_nread(slave, SDW_SCP_INTSTAT2, 2, buf2);
1232 if (ret < 0) {
1233 dev_err(slave->bus->dev,
Pierre-Louis Bossart17ed5be2019-05-01 10:57:45 -05001234 "SDW_SCP_INT2/3 read failed:%d\n", ret);
Rander Wangaa792932020-01-14 18:08:42 -06001235 goto io_err;
Vinod Koulb0a9c372017-12-14 11:19:40 +05301236 }
1237
1238 do {
1239 /*
1240 * Check parity, bus clash and Slave (impl defined)
1241 * interrupt
1242 */
1243 if (buf & SDW_SCP_INT1_PARITY) {
Pierre-Louis Bossart17ed5be2019-05-01 10:57:45 -05001244 dev_err(&slave->dev, "Parity error detected\n");
Vinod Koulb0a9c372017-12-14 11:19:40 +05301245 clear |= SDW_SCP_INT1_PARITY;
1246 }
1247
1248 if (buf & SDW_SCP_INT1_BUS_CLASH) {
Pierre-Louis Bossart17ed5be2019-05-01 10:57:45 -05001249 dev_err(&slave->dev, "Bus clash error detected\n");
Vinod Koulb0a9c372017-12-14 11:19:40 +05301250 clear |= SDW_SCP_INT1_BUS_CLASH;
1251 }
1252
1253 /*
1254 * When bus clash or parity errors are detected, such errors
1255 * are unlikely to be recoverable errors.
1256 * TODO: In such scenario, reset bus. Make this configurable
1257 * via sysfs property with bus reset being the default.
1258 */
1259
1260 if (buf & SDW_SCP_INT1_IMPL_DEF) {
1261 dev_dbg(&slave->dev, "Slave impl defined interrupt\n");
1262 clear |= SDW_SCP_INT1_IMPL_DEF;
1263 slave_notify = true;
1264 }
1265
1266 /* Check port 0 - 3 interrupts */
1267 port = buf & SDW_SCP_INT1_PORT0_3;
1268
1269 /* To get port number corresponding to bits, shift it */
1270 port = port >> SDW_REG_SHIFT(SDW_SCP_INT1_PORT0_3);
1271 for_each_set_bit(bit, &port, 8) {
1272 sdw_handle_port_interrupt(slave, bit,
Pierre-Louis Bossart73ede042019-05-01 10:57:27 -05001273 &port_status[bit]);
Vinod Koulb0a9c372017-12-14 11:19:40 +05301274 }
1275
1276 /* Check if cascade 2 interrupt is present */
1277 if (buf & SDW_SCP_INT1_SCP2_CASCADE) {
1278 port = buf2[0] & SDW_SCP_INTSTAT2_PORT4_10;
1279 for_each_set_bit(bit, &port, 8) {
1280 /* scp2 ports start from 4 */
1281 port_num = bit + 3;
1282 sdw_handle_port_interrupt(slave,
1283 port_num,
1284 &port_status[port_num]);
1285 }
1286 }
1287
1288 /* now check last cascade */
1289 if (buf2[0] & SDW_SCP_INTSTAT2_SCP3_CASCADE) {
1290 port = buf2[1] & SDW_SCP_INTSTAT3_PORT11_14;
1291 for_each_set_bit(bit, &port, 8) {
1292 /* scp3 ports start from 11 */
1293 port_num = bit + 10;
1294 sdw_handle_port_interrupt(slave,
1295 port_num,
1296 &port_status[port_num]);
1297 }
1298 }
1299
1300 /* Update the Slave driver */
Pierre-Louis Bossart09830d52019-05-01 10:57:29 -05001301 if (slave_notify && slave->ops &&
1302 slave->ops->interrupt_callback) {
Vinod Koulb0a9c372017-12-14 11:19:40 +05301303 slave_intr.control_port = clear;
1304 memcpy(slave_intr.port, &port_status,
Pierre-Louis Bossart73ede042019-05-01 10:57:27 -05001305 sizeof(slave_intr.port));
Vinod Koulb0a9c372017-12-14 11:19:40 +05301306
1307 slave->ops->interrupt_callback(slave, &slave_intr);
1308 }
1309
1310 /* Ack interrupt */
1311 ret = sdw_write(slave, SDW_SCP_INT1, clear);
1312 if (ret < 0) {
1313 dev_err(slave->bus->dev,
Pierre-Louis Bossart17ed5be2019-05-01 10:57:45 -05001314 "SDW_SCP_INT1 write failed:%d\n", ret);
Rander Wangaa792932020-01-14 18:08:42 -06001315 goto io_err;
Vinod Koulb0a9c372017-12-14 11:19:40 +05301316 }
1317
1318 /*
1319 * Read status again to ensure no new interrupts arrived
1320 * while servicing interrupts.
1321 */
Vinod Koul72b16d4a2019-05-02 16:29:26 +05301322 ret = sdw_read(slave, SDW_SCP_INT1);
Vinod Koulb0a9c372017-12-14 11:19:40 +05301323 if (ret < 0) {
1324 dev_err(slave->bus->dev,
Pierre-Louis Bossart17ed5be2019-05-01 10:57:45 -05001325 "SDW_SCP_INT1 read failed:%d\n", ret);
Rander Wangaa792932020-01-14 18:08:42 -06001326 goto io_err;
Vinod Koulb0a9c372017-12-14 11:19:40 +05301327 }
Vinod Koul72b16d4a2019-05-02 16:29:26 +05301328 _buf = ret;
Vinod Koulb0a9c372017-12-14 11:19:40 +05301329
1330 ret = sdw_nread(slave, SDW_SCP_INTSTAT2, 2, _buf2);
1331 if (ret < 0) {
1332 dev_err(slave->bus->dev,
Pierre-Louis Bossart17ed5be2019-05-01 10:57:45 -05001333 "SDW_SCP_INT2/3 read failed:%d\n", ret);
Rander Wangaa792932020-01-14 18:08:42 -06001334 goto io_err;
Vinod Koulb0a9c372017-12-14 11:19:40 +05301335 }
1336
1337 /* Make sure no interrupts are pending */
1338 buf &= _buf;
1339 buf2[0] &= _buf2[0];
1340 buf2[1] &= _buf2[1];
1341 stat = buf || buf2[0] || buf2[1];
1342
1343 /*
1344 * Exit loop if Slave is continuously in ALERT state even
1345 * after servicing the interrupt multiple times.
1346 */
1347 count++;
1348
1349 /* we can get alerts while processing so keep retrying */
1350 } while (stat != 0 && count < SDW_READ_INTR_CLEAR_RETRY);
1351
1352 if (count == SDW_READ_INTR_CLEAR_RETRY)
Pierre-Louis Bossart17ed5be2019-05-01 10:57:45 -05001353 dev_warn(slave->bus->dev, "Reached MAX_RETRY on alert read\n");
Vinod Koulb0a9c372017-12-14 11:19:40 +05301354
Rander Wangaa792932020-01-14 18:08:42 -06001355io_err:
1356 pm_runtime_mark_last_busy(&slave->dev);
1357 pm_runtime_put_autosuspend(&slave->dev);
1358
Vinod Koulb0a9c372017-12-14 11:19:40 +05301359 return ret;
1360}
1361
1362static int sdw_update_slave_status(struct sdw_slave *slave,
Pierre-Louis Bossart73ede042019-05-01 10:57:27 -05001363 enum sdw_slave_status status)
Vinod Koulb0a9c372017-12-14 11:19:40 +05301364{
Pierre-Louis Bossart2140b662020-01-14 18:08:35 -06001365 unsigned long time;
Vinod Koulb0a9c372017-12-14 11:19:40 +05301366
Pierre-Louis Bossart2140b662020-01-14 18:08:35 -06001367 if (!slave->probed) {
1368 /*
1369 * the slave status update is typically handled in an
1370 * interrupt thread, which can race with the driver
1371 * probe, e.g. when a module needs to be loaded.
1372 *
1373 * make sure the probe is complete before updating
1374 * status.
1375 */
1376 time = wait_for_completion_timeout(&slave->probe_complete,
1377 msecs_to_jiffies(DEFAULT_PROBE_TIMEOUT));
1378 if (!time) {
1379 dev_err(&slave->dev, "Probe not complete, timed out\n");
1380 return -ETIMEDOUT;
1381 }
1382 }
1383
1384 if (!slave->ops || !slave->ops->update_status)
1385 return 0;
1386
1387 return slave->ops->update_status(slave, status);
Vinod Koulb0a9c372017-12-14 11:19:40 +05301388}
1389
1390/**
1391 * sdw_handle_slave_status() - Handle Slave status
1392 * @bus: SDW bus instance
1393 * @status: Status for all Slave(s)
1394 */
1395int sdw_handle_slave_status(struct sdw_bus *bus,
Pierre-Louis Bossart73ede042019-05-01 10:57:27 -05001396 enum sdw_slave_status status[])
Vinod Koulb0a9c372017-12-14 11:19:40 +05301397{
1398 enum sdw_slave_status prev_status;
1399 struct sdw_slave *slave;
Pierre-Louis Bossarta90def02020-01-14 18:08:37 -06001400 bool attached_initializing;
Vinod Koulb0a9c372017-12-14 11:19:40 +05301401 int i, ret = 0;
1402
Pierre-Louis Bossart61061902020-01-10 15:57:31 -06001403 /* first check if any Slaves fell off the bus */
1404 for (i = 1; i <= SDW_MAX_DEVICES; i++) {
1405 mutex_lock(&bus->bus_lock);
1406 if (test_bit(i, bus->assigned) == false) {
1407 mutex_unlock(&bus->bus_lock);
1408 continue;
1409 }
1410 mutex_unlock(&bus->bus_lock);
1411
1412 slave = sdw_get_slave(bus, i);
1413 if (!slave)
1414 continue;
1415
1416 if (status[i] == SDW_SLAVE_UNATTACHED &&
1417 slave->status != SDW_SLAVE_UNATTACHED)
1418 sdw_modify_slave_status(slave, SDW_SLAVE_UNATTACHED);
1419 }
1420
Vinod Koulb0a9c372017-12-14 11:19:40 +05301421 if (status[0] == SDW_SLAVE_ATTACHED) {
Pierre-Louis Bossart6e0ac6a2019-08-05 19:55:09 -05001422 dev_dbg(bus->dev, "Slave attached, programming device number\n");
Vinod Koulb0a9c372017-12-14 11:19:40 +05301423 ret = sdw_program_device_num(bus);
1424 if (ret)
Pierre-Louis Bossart17ed5be2019-05-01 10:57:45 -05001425 dev_err(bus->dev, "Slave attach failed: %d\n", ret);
Pierre-Louis Bossart15ed3ea2019-07-25 18:40:10 -05001426 /*
1427 * programming a device number will have side effects,
1428 * so we deal with other devices at a later time
1429 */
1430 return ret;
Vinod Koulb0a9c372017-12-14 11:19:40 +05301431 }
1432
1433 /* Continue to check other slave statuses */
1434 for (i = 1; i <= SDW_MAX_DEVICES; i++) {
1435 mutex_lock(&bus->bus_lock);
1436 if (test_bit(i, bus->assigned) == false) {
1437 mutex_unlock(&bus->bus_lock);
1438 continue;
1439 }
1440 mutex_unlock(&bus->bus_lock);
1441
1442 slave = sdw_get_slave(bus, i);
1443 if (!slave)
1444 continue;
1445
Pierre-Louis Bossarta90def02020-01-14 18:08:37 -06001446 attached_initializing = false;
1447
Vinod Koulb0a9c372017-12-14 11:19:40 +05301448 switch (status[i]) {
1449 case SDW_SLAVE_UNATTACHED:
1450 if (slave->status == SDW_SLAVE_UNATTACHED)
1451 break;
1452
1453 sdw_modify_slave_status(slave, SDW_SLAVE_UNATTACHED);
1454 break;
1455
1456 case SDW_SLAVE_ALERT:
1457 ret = sdw_handle_slave_alerts(slave);
1458 if (ret)
1459 dev_err(bus->dev,
Pierre-Louis Bossart17ed5be2019-05-01 10:57:45 -05001460 "Slave %d alert handling failed: %d\n",
Vinod Koulb0a9c372017-12-14 11:19:40 +05301461 i, ret);
1462 break;
1463
1464 case SDW_SLAVE_ATTACHED:
1465 if (slave->status == SDW_SLAVE_ATTACHED)
1466 break;
1467
1468 prev_status = slave->status;
1469 sdw_modify_slave_status(slave, SDW_SLAVE_ATTACHED);
1470
1471 if (prev_status == SDW_SLAVE_ALERT)
1472 break;
1473
Pierre-Louis Bossarta90def02020-01-14 18:08:37 -06001474 attached_initializing = true;
1475
Vinod Koulb0a9c372017-12-14 11:19:40 +05301476 ret = sdw_initialize_slave(slave);
1477 if (ret)
1478 dev_err(bus->dev,
Pierre-Louis Bossart17ed5be2019-05-01 10:57:45 -05001479 "Slave %d initialization failed: %d\n",
Vinod Koulb0a9c372017-12-14 11:19:40 +05301480 i, ret);
1481
1482 break;
1483
1484 default:
Pierre-Louis Bossart17ed5be2019-05-01 10:57:45 -05001485 dev_err(bus->dev, "Invalid slave %d status:%d\n",
Pierre-Louis Bossart73ede042019-05-01 10:57:27 -05001486 i, status[i]);
Vinod Koulb0a9c372017-12-14 11:19:40 +05301487 break;
1488 }
1489
1490 ret = sdw_update_slave_status(slave, status[i]);
1491 if (ret)
1492 dev_err(slave->bus->dev,
Pierre-Louis Bossart17ed5be2019-05-01 10:57:45 -05001493 "Update Slave status failed:%d\n", ret);
Pierre-Louis Bossarta90def02020-01-14 18:08:37 -06001494 if (attached_initializing)
1495 complete(&slave->initialization_complete);
Vinod Koulb0a9c372017-12-14 11:19:40 +05301496 }
1497
1498 return ret;
1499}
1500EXPORT_SYMBOL(sdw_handle_slave_status);
Pierre-Louis Bossart3ab2ca42020-01-14 18:08:40 -06001501
1502void sdw_clear_slave_status(struct sdw_bus *bus, u32 request)
1503{
1504 struct sdw_slave *slave;
1505 int i;
1506
1507 /* Check all non-zero devices */
1508 for (i = 1; i <= SDW_MAX_DEVICES; i++) {
1509 mutex_lock(&bus->bus_lock);
1510 if (test_bit(i, bus->assigned) == false) {
1511 mutex_unlock(&bus->bus_lock);
1512 continue;
1513 }
1514 mutex_unlock(&bus->bus_lock);
1515
1516 slave = sdw_get_slave(bus, i);
1517 if (!slave)
1518 continue;
1519
1520 if (slave->status != SDW_SLAVE_UNATTACHED)
1521 sdw_modify_slave_status(slave, SDW_SLAVE_UNATTACHED);
1522
1523 /* keep track of request, used in pm_runtime resume */
1524 slave->unattach_request = request;
1525 }
1526}
1527EXPORT_SYMBOL(sdw_clear_slave_status);