blob: efdcefc62e1a4d9bf45f61b2aae2819d2e9ba47d [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>
5#include <linux/mod_devicetable.h>
Vinod Koul9d715fa2017-12-14 11:19:37 +05306#include <linux/pm_runtime.h>
7#include <linux/soundwire/sdw_registers.h>
Vinod Koul7c3cd182017-12-14 11:19:34 +05308#include <linux/soundwire/sdw.h>
9#include "bus.h"
10
11/**
12 * sdw_add_bus_master() - add a bus Master instance
13 * @bus: bus instance
14 *
15 * Initializes the bus instance, read properties and create child
16 * devices.
17 */
18int sdw_add_bus_master(struct sdw_bus *bus)
19{
Sanyog Kale5c3eb9f2018-04-26 18:38:33 +053020 struct sdw_master_prop *prop = NULL;
Vinod Koul7c3cd182017-12-14 11:19:34 +053021 int ret;
22
23 if (!bus->dev) {
24 pr_err("SoundWire bus has no device");
25 return -ENODEV;
26 }
27
Vinod Koul9d715fa2017-12-14 11:19:37 +053028 if (!bus->ops) {
29 dev_err(bus->dev, "SoundWire Bus ops are not set");
30 return -EINVAL;
31 }
32
33 mutex_init(&bus->msg_lock);
Vinod Koul7c3cd182017-12-14 11:19:34 +053034 mutex_init(&bus->bus_lock);
35 INIT_LIST_HEAD(&bus->slaves);
Sanyog Kale89e59052018-04-26 18:38:08 +053036 INIT_LIST_HEAD(&bus->m_rt_list);
Vinod Koul7c3cd182017-12-14 11:19:34 +053037
Shreyas NCce6e74d2018-07-27 14:44:16 +053038 /*
39 * Initialize multi_link flag
40 * TODO: populate this flag by reading property from FW node
41 */
42 bus->multi_link = false;
Vinod Koul56d4fe32017-12-14 11:19:35 +053043 if (bus->ops->read_prop) {
44 ret = bus->ops->read_prop(bus);
45 if (ret < 0) {
46 dev_err(bus->dev, "Bus read properties failed:%d", ret);
47 return ret;
48 }
49 }
50
Vinod Koul7c3cd182017-12-14 11:19:34 +053051 /*
Pierre-Louis Bossart21c2de22019-05-01 10:57:28 -050052 * Device numbers in SoundWire are 0 through 15. Enumeration device
Vinod Koul7c3cd182017-12-14 11:19:34 +053053 * number (0), Broadcast device number (15), Group numbers (12 and
54 * 13) and Master device number (14) are not used for assignment so
55 * mask these and other higher bits.
56 */
57
58 /* Set higher order bits */
59 *bus->assigned = ~GENMASK(SDW_BROADCAST_DEV_NUM, SDW_ENUM_DEV_NUM);
60
61 /* Set enumuration device number and broadcast device number */
62 set_bit(SDW_ENUM_DEV_NUM, bus->assigned);
63 set_bit(SDW_BROADCAST_DEV_NUM, bus->assigned);
64
65 /* Set group device numbers and master device number */
66 set_bit(SDW_GROUP12_DEV_NUM, bus->assigned);
67 set_bit(SDW_GROUP13_DEV_NUM, bus->assigned);
68 set_bit(SDW_MASTER_DEV_NUM, bus->assigned);
69
70 /*
71 * SDW is an enumerable bus, but devices can be powered off. So,
72 * they won't be able to report as present.
73 *
74 * Create Slave devices based on Slaves described in
75 * the respective firmware (ACPI/DT)
76 */
77 if (IS_ENABLED(CONFIG_ACPI) && ACPI_HANDLE(bus->dev))
78 ret = sdw_acpi_find_slaves(bus);
79 else
80 ret = -ENOTSUPP; /* No ACPI/DT so error out */
81
82 if (ret) {
83 dev_err(bus->dev, "Finding slaves failed:%d\n", ret);
84 return ret;
85 }
86
Sanyog Kale99b8a5d2018-04-26 18:38:28 +053087 /*
Sanyog Kale5c3eb9f2018-04-26 18:38:33 +053088 * Initialize clock values based on Master properties. The max
89 * frequency is read from max_freq property. Current assumption
90 * is that the bus will start at highest clock frequency when
91 * powered on.
92 *
Sanyog Kale99b8a5d2018-04-26 18:38:28 +053093 * Default active bank will be 0 as out of reset the Slaves have
94 * to start with bank 0 (Table 40 of Spec)
95 */
Sanyog Kale5c3eb9f2018-04-26 18:38:33 +053096 prop = &bus->prop;
97 bus->params.max_dr_freq = prop->max_freq * SDW_DOUBLE_RATE_FACTOR;
98 bus->params.curr_dr_freq = bus->params.max_dr_freq;
Sanyog Kale99b8a5d2018-04-26 18:38:28 +053099 bus->params.curr_bank = SDW_BANK0;
100 bus->params.next_bank = SDW_BANK1;
101
Vinod Koul7c3cd182017-12-14 11:19:34 +0530102 return 0;
103}
104EXPORT_SYMBOL(sdw_add_bus_master);
105
106static int sdw_delete_slave(struct device *dev, void *data)
107{
108 struct sdw_slave *slave = dev_to_sdw_dev(dev);
109 struct sdw_bus *bus = slave->bus;
110
111 mutex_lock(&bus->bus_lock);
112
113 if (slave->dev_num) /* clear dev_num if assigned */
114 clear_bit(slave->dev_num, bus->assigned);
115
116 list_del_init(&slave->node);
117 mutex_unlock(&bus->bus_lock);
118
119 device_unregister(dev);
120 return 0;
121}
122
123/**
124 * sdw_delete_bus_master() - delete the bus master instance
125 * @bus: bus to be deleted
126 *
127 * Remove the instance, delete the child devices.
128 */
129void sdw_delete_bus_master(struct sdw_bus *bus)
130{
131 device_for_each_child(bus->dev, NULL, sdw_delete_slave);
132}
133EXPORT_SYMBOL(sdw_delete_bus_master);
134
Vinod Koul9d715fa2017-12-14 11:19:37 +0530135/*
136 * SDW IO Calls
137 */
138
139static inline int find_response_code(enum sdw_command_response resp)
140{
141 switch (resp) {
142 case SDW_CMD_OK:
143 return 0;
144
145 case SDW_CMD_IGNORED:
146 return -ENODATA;
147
148 case SDW_CMD_TIMEOUT:
149 return -ETIMEDOUT;
150
151 default:
152 return -EIO;
153 }
154}
155
156static inline int do_transfer(struct sdw_bus *bus, struct sdw_msg *msg)
157{
158 int retry = bus->prop.err_threshold;
159 enum sdw_command_response resp;
160 int ret = 0, i;
161
162 for (i = 0; i <= retry; i++) {
163 resp = bus->ops->xfer_msg(bus, msg);
164 ret = find_response_code(resp);
165
166 /* if cmd is ok or ignored return */
167 if (ret == 0 || ret == -ENODATA)
168 return ret;
169 }
170
171 return ret;
172}
173
174static inline int do_transfer_defer(struct sdw_bus *bus,
Pierre-Louis Bossart73ede042019-05-01 10:57:27 -0500175 struct sdw_msg *msg,
176 struct sdw_defer *defer)
Vinod Koul9d715fa2017-12-14 11:19:37 +0530177{
178 int retry = bus->prop.err_threshold;
179 enum sdw_command_response resp;
180 int ret = 0, i;
181
182 defer->msg = msg;
183 defer->length = msg->len;
Shreyas NCa306a0e2018-07-27 14:44:12 +0530184 init_completion(&defer->complete);
Vinod Koul9d715fa2017-12-14 11:19:37 +0530185
186 for (i = 0; i <= retry; i++) {
187 resp = bus->ops->xfer_msg_defer(bus, msg, defer);
188 ret = find_response_code(resp);
189 /* if cmd is ok or ignored return */
190 if (ret == 0 || ret == -ENODATA)
191 return ret;
192 }
193
194 return ret;
195}
196
197static int sdw_reset_page(struct sdw_bus *bus, u16 dev_num)
198{
199 int retry = bus->prop.err_threshold;
200 enum sdw_command_response resp;
201 int ret = 0, i;
202
203 for (i = 0; i <= retry; i++) {
204 resp = bus->ops->reset_page_addr(bus, dev_num);
205 ret = find_response_code(resp);
206 /* if cmd is ok or ignored return */
207 if (ret == 0 || ret == -ENODATA)
208 return ret;
209 }
210
211 return ret;
212}
213
214/**
215 * sdw_transfer() - Synchronous transfer message to a SDW Slave device
216 * @bus: SDW bus
217 * @msg: SDW message to be xfered
218 */
219int sdw_transfer(struct sdw_bus *bus, struct sdw_msg *msg)
220{
221 int ret;
222
223 mutex_lock(&bus->msg_lock);
224
225 ret = do_transfer(bus, msg);
226 if (ret != 0 && ret != -ENODATA)
227 dev_err(bus->dev, "trf on Slave %d failed:%d\n",
Pierre-Louis Bossart73ede042019-05-01 10:57:27 -0500228 msg->dev_num, ret);
Vinod Koul9d715fa2017-12-14 11:19:37 +0530229
230 if (msg->page)
231 sdw_reset_page(bus, msg->dev_num);
232
233 mutex_unlock(&bus->msg_lock);
234
235 return ret;
236}
237
238/**
239 * sdw_transfer_defer() - Asynchronously transfer message to a SDW Slave device
240 * @bus: SDW bus
241 * @msg: SDW message to be xfered
242 * @defer: Defer block for signal completion
243 *
244 * Caller needs to hold the msg_lock lock while calling this
245 */
246int sdw_transfer_defer(struct sdw_bus *bus, struct sdw_msg *msg,
Pierre-Louis Bossart73ede042019-05-01 10:57:27 -0500247 struct sdw_defer *defer)
Vinod Koul9d715fa2017-12-14 11:19:37 +0530248{
249 int ret;
250
251 if (!bus->ops->xfer_msg_defer)
252 return -ENOTSUPP;
253
254 ret = do_transfer_defer(bus, msg, defer);
255 if (ret != 0 && ret != -ENODATA)
256 dev_err(bus->dev, "Defer trf on Slave %d failed:%d\n",
Pierre-Louis Bossart73ede042019-05-01 10:57:27 -0500257 msg->dev_num, ret);
Vinod Koul9d715fa2017-12-14 11:19:37 +0530258
259 if (msg->page)
260 sdw_reset_page(bus, msg->dev_num);
261
262 return ret;
263}
264
Vinod Koul9d715fa2017-12-14 11:19:37 +0530265int sdw_fill_msg(struct sdw_msg *msg, struct sdw_slave *slave,
Pierre-Louis Bossart73ede042019-05-01 10:57:27 -0500266 u32 addr, size_t count, u16 dev_num, u8 flags, u8 *buf)
Vinod Koul9d715fa2017-12-14 11:19:37 +0530267{
268 memset(msg, 0, sizeof(*msg));
269 msg->addr = addr; /* addr is 16 bit and truncated here */
270 msg->len = count;
271 msg->dev_num = dev_num;
272 msg->flags = flags;
273 msg->buf = buf;
Vinod Koul9d715fa2017-12-14 11:19:37 +0530274
275 if (addr < SDW_REG_NO_PAGE) { /* no paging area */
276 return 0;
277 } else if (addr >= SDW_REG_MAX) { /* illegal addr */
278 pr_err("SDW: Invalid address %x passed\n", addr);
279 return -EINVAL;
280 }
281
282 if (addr < SDW_REG_OPTIONAL_PAGE) { /* 32k but no page */
283 if (slave && !slave->prop.paging_support)
284 return 0;
Pierre-Louis Bossart21c2de22019-05-01 10:57:28 -0500285 /* no need for else as that will fall-through to paging */
Vinod Koul9d715fa2017-12-14 11:19:37 +0530286 }
287
288 /* paging mandatory */
289 if (dev_num == SDW_ENUM_DEV_NUM || dev_num == SDW_BROADCAST_DEV_NUM) {
290 pr_err("SDW: Invalid device for paging :%d\n", dev_num);
291 return -EINVAL;
292 }
293
294 if (!slave) {
295 pr_err("SDW: No slave for paging addr\n");
296 return -EINVAL;
297 } else if (!slave->prop.paging_support) {
298 dev_err(&slave->dev,
299 "address %x needs paging but no support", addr);
300 return -EINVAL;
301 }
302
303 msg->addr_page1 = (addr >> SDW_REG_SHIFT(SDW_SCP_ADDRPAGE1_MASK));
304 msg->addr_page2 = (addr >> SDW_REG_SHIFT(SDW_SCP_ADDRPAGE2_MASK));
305 msg->addr |= BIT(15);
306 msg->page = true;
307
308 return 0;
309}
310
311/**
312 * sdw_nread() - Read "n" contiguous SDW Slave registers
313 * @slave: SDW Slave
314 * @addr: Register address
315 * @count: length
316 * @val: Buffer for values to be read
317 */
318int sdw_nread(struct sdw_slave *slave, u32 addr, size_t count, u8 *val)
319{
320 struct sdw_msg msg;
321 int ret;
322
323 ret = sdw_fill_msg(&msg, slave, addr, count,
Pierre-Louis Bossart73ede042019-05-01 10:57:27 -0500324 slave->dev_num, SDW_MSG_FLAG_READ, val);
Vinod Koul9d715fa2017-12-14 11:19:37 +0530325 if (ret < 0)
326 return ret;
327
328 ret = pm_runtime_get_sync(slave->bus->dev);
Shreyas NCc22c0ae2018-01-09 10:15:46 +0530329 if (ret < 0)
Vinod Koul9d715fa2017-12-14 11:19:37 +0530330 return ret;
331
332 ret = sdw_transfer(slave->bus, &msg);
333 pm_runtime_put(slave->bus->dev);
334
335 return ret;
336}
337EXPORT_SYMBOL(sdw_nread);
338
339/**
340 * sdw_nwrite() - Write "n" contiguous SDW Slave registers
341 * @slave: SDW Slave
342 * @addr: Register address
343 * @count: length
344 * @val: Buffer for values to be read
345 */
346int sdw_nwrite(struct sdw_slave *slave, u32 addr, size_t count, u8 *val)
347{
348 struct sdw_msg msg;
349 int ret;
350
351 ret = sdw_fill_msg(&msg, slave, addr, count,
Pierre-Louis Bossart73ede042019-05-01 10:57:27 -0500352 slave->dev_num, SDW_MSG_FLAG_WRITE, val);
Vinod Koul9d715fa2017-12-14 11:19:37 +0530353 if (ret < 0)
354 return ret;
355
356 ret = pm_runtime_get_sync(slave->bus->dev);
Shreyas NCc22c0ae2018-01-09 10:15:46 +0530357 if (ret < 0)
Vinod Koul9d715fa2017-12-14 11:19:37 +0530358 return ret;
359
360 ret = sdw_transfer(slave->bus, &msg);
361 pm_runtime_put(slave->bus->dev);
362
363 return ret;
364}
365EXPORT_SYMBOL(sdw_nwrite);
366
367/**
368 * sdw_read() - Read a SDW Slave register
369 * @slave: SDW Slave
370 * @addr: Register address
371 */
372int sdw_read(struct sdw_slave *slave, u32 addr)
373{
374 u8 buf;
375 int ret;
376
377 ret = sdw_nread(slave, addr, 1, &buf);
378 if (ret < 0)
379 return ret;
380 else
381 return buf;
382}
383EXPORT_SYMBOL(sdw_read);
384
385/**
386 * sdw_write() - Write a SDW Slave register
387 * @slave: SDW Slave
388 * @addr: Register address
389 * @value: Register value
390 */
391int sdw_write(struct sdw_slave *slave, u32 addr, u8 value)
392{
393 return sdw_nwrite(slave, addr, 1, &value);
394
395}
396EXPORT_SYMBOL(sdw_write);
397
Sanyog Kaled52d7a12017-12-14 11:19:39 +0530398/*
399 * SDW alert handling
400 */
401
402/* called with bus_lock held */
403static struct sdw_slave *sdw_get_slave(struct sdw_bus *bus, int i)
404{
405 struct sdw_slave *slave = NULL;
406
407 list_for_each_entry(slave, &bus->slaves, node) {
408 if (slave->dev_num == i)
409 return slave;
410 }
411
412 return NULL;
413}
414
415static int sdw_compare_devid(struct sdw_slave *slave, struct sdw_slave_id id)
416{
417
418 if ((slave->id.unique_id != id.unique_id) ||
419 (slave->id.mfg_id != id.mfg_id) ||
420 (slave->id.part_id != id.part_id) ||
421 (slave->id.class_id != id.class_id))
422 return -ENODEV;
423
424 return 0;
425}
426
427/* called with bus_lock held */
428static int sdw_get_device_num(struct sdw_slave *slave)
429{
430 int bit;
431
432 bit = find_first_zero_bit(slave->bus->assigned, SDW_MAX_DEVICES);
433 if (bit == SDW_MAX_DEVICES) {
434 bit = -ENODEV;
435 goto err;
436 }
437
438 /*
439 * Do not update dev_num in Slave data structure here,
440 * Update once program dev_num is successful
441 */
442 set_bit(bit, slave->bus->assigned);
443
444err:
445 return bit;
446}
447
448static int sdw_assign_device_num(struct sdw_slave *slave)
449{
450 int ret, dev_num;
451
452 /* check first if device number is assigned, if so reuse that */
453 if (!slave->dev_num) {
454 mutex_lock(&slave->bus->bus_lock);
455 dev_num = sdw_get_device_num(slave);
456 mutex_unlock(&slave->bus->bus_lock);
457 if (dev_num < 0) {
458 dev_err(slave->bus->dev, "Get dev_num failed: %d",
Pierre-Louis Bossart73ede042019-05-01 10:57:27 -0500459 dev_num);
Sanyog Kaled52d7a12017-12-14 11:19:39 +0530460 return dev_num;
461 }
462 } else {
463 dev_info(slave->bus->dev,
Pierre-Louis Bossart73ede042019-05-01 10:57:27 -0500464 "Slave already registered dev_num:%d",
465 slave->dev_num);
Sanyog Kaled52d7a12017-12-14 11:19:39 +0530466
467 /* Clear the slave->dev_num to transfer message on device 0 */
468 dev_num = slave->dev_num;
469 slave->dev_num = 0;
470
471 }
472
473 ret = sdw_write(slave, SDW_SCP_DEVNUMBER, dev_num);
474 if (ret < 0) {
475 dev_err(&slave->dev, "Program device_num failed: %d", ret);
476 return ret;
477 }
478
479 /* After xfer of msg, restore dev_num */
480 slave->dev_num = dev_num;
481
482 return 0;
483}
484
Vinod Koul7c3cd182017-12-14 11:19:34 +0530485void sdw_extract_slave_id(struct sdw_bus *bus,
Pierre-Louis Bossart73ede042019-05-01 10:57:27 -0500486 u64 addr, struct sdw_slave_id *id)
Vinod Koul7c3cd182017-12-14 11:19:34 +0530487{
488 dev_dbg(bus->dev, "SDW Slave Addr: %llx", addr);
489
490 /*
491 * Spec definition
492 * Register Bit Contents
493 * DevId_0 [7:4] 47:44 sdw_version
494 * DevId_0 [3:0] 43:40 unique_id
495 * DevId_1 39:32 mfg_id [15:8]
496 * DevId_2 31:24 mfg_id [7:0]
497 * DevId_3 23:16 part_id [15:8]
498 * DevId_4 15:08 part_id [7:0]
499 * DevId_5 07:00 class_id
500 */
501 id->sdw_version = (addr >> 44) & GENMASK(3, 0);
502 id->unique_id = (addr >> 40) & GENMASK(3, 0);
503 id->mfg_id = (addr >> 24) & GENMASK(15, 0);
504 id->part_id = (addr >> 8) & GENMASK(15, 0);
505 id->class_id = addr & GENMASK(7, 0);
506
507 dev_dbg(bus->dev,
508 "SDW Slave class_id %x, part_id %x, mfg_id %x, unique_id %x, version %x",
509 id->class_id, id->part_id, id->mfg_id,
510 id->unique_id, id->sdw_version);
511
512}
Sanyog Kaled52d7a12017-12-14 11:19:39 +0530513
514static int sdw_program_device_num(struct sdw_bus *bus)
515{
516 u8 buf[SDW_NUM_DEV_ID_REGISTERS] = {0};
517 struct sdw_slave *slave, *_s;
518 struct sdw_slave_id id;
519 struct sdw_msg msg;
520 bool found = false;
521 int count = 0, ret;
522 u64 addr;
523
524 /* No Slave, so use raw xfer api */
525 ret = sdw_fill_msg(&msg, NULL, SDW_SCP_DEVID_0,
Pierre-Louis Bossart73ede042019-05-01 10:57:27 -0500526 SDW_NUM_DEV_ID_REGISTERS, 0, SDW_MSG_FLAG_READ, buf);
Sanyog Kaled52d7a12017-12-14 11:19:39 +0530527 if (ret < 0)
528 return ret;
529
530 do {
531 ret = sdw_transfer(bus, &msg);
532 if (ret == -ENODATA) { /* end of device id reads */
533 ret = 0;
534 break;
535 }
536 if (ret < 0) {
537 dev_err(bus->dev, "DEVID read fail:%d\n", ret);
538 break;
539 }
540
541 /*
542 * Construct the addr and extract. Cast the higher shift
543 * bits to avoid truncation due to size limit.
544 */
545 addr = buf[5] | (buf[4] << 8) | (buf[3] << 16) |
Colin Ian King0132af052018-01-08 22:22:42 +0530546 ((u64)buf[2] << 24) | ((u64)buf[1] << 32) |
547 ((u64)buf[0] << 40);
Sanyog Kaled52d7a12017-12-14 11:19:39 +0530548
549 sdw_extract_slave_id(bus, addr, &id);
550
551 /* Now compare with entries */
552 list_for_each_entry_safe(slave, _s, &bus->slaves, node) {
553 if (sdw_compare_devid(slave, id) == 0) {
554 found = true;
555
556 /*
557 * Assign a new dev_num to this Slave and
558 * not mark it present. It will be marked
559 * present after it reports ATTACHED on new
560 * dev_num
561 */
562 ret = sdw_assign_device_num(slave);
563 if (ret) {
564 dev_err(slave->bus->dev,
565 "Assign dev_num failed:%d",
566 ret);
567 return ret;
568 }
569
570 break;
571 }
572 }
573
574 if (found == false) {
575 /* TODO: Park this device in Group 13 */
576 dev_err(bus->dev, "Slave Entry not found");
577 }
578
579 count++;
580
581 /*
582 * Check till error out or retry (count) exhausts.
583 * Device can drop off and rejoin during enumeration
584 * so count till twice the bound.
585 */
586
587 } while (ret == 0 && count < (SDW_MAX_DEVICES * 2));
588
589 return ret;
590}
591
592static void sdw_modify_slave_status(struct sdw_slave *slave,
Pierre-Louis Bossart73ede042019-05-01 10:57:27 -0500593 enum sdw_slave_status status)
Sanyog Kaled52d7a12017-12-14 11:19:39 +0530594{
595 mutex_lock(&slave->bus->bus_lock);
596 slave->status = status;
597 mutex_unlock(&slave->bus->bus_lock);
598}
599
Sanyog Kale79df15b2018-04-26 18:38:23 +0530600int sdw_configure_dpn_intr(struct sdw_slave *slave,
Pierre-Louis Bossart73ede042019-05-01 10:57:27 -0500601 int port, bool enable, int mask)
Sanyog Kale79df15b2018-04-26 18:38:23 +0530602{
603 u32 addr;
604 int ret;
605 u8 val = 0;
606
607 addr = SDW_DPN_INTMASK(port);
608
609 /* Set/Clear port ready interrupt mask */
610 if (enable) {
611 val |= mask;
612 val |= SDW_DPN_INT_PORT_READY;
613 } else {
614 val &= ~(mask);
615 val &= ~SDW_DPN_INT_PORT_READY;
616 }
617
618 ret = sdw_update(slave, addr, (mask | SDW_DPN_INT_PORT_READY), val);
619 if (ret < 0)
620 dev_err(slave->bus->dev,
Pierre-Louis Bossart73ede042019-05-01 10:57:27 -0500621 "SDW_DPN_INTMASK write failed:%d", val);
Sanyog Kale79df15b2018-04-26 18:38:23 +0530622
623 return ret;
624}
625
Sanyog Kaled52d7a12017-12-14 11:19:39 +0530626static int sdw_initialize_slave(struct sdw_slave *slave)
627{
628 struct sdw_slave_prop *prop = &slave->prop;
629 int ret;
630 u8 val;
631
632 /*
633 * Set bus clash, parity and SCP implementation
634 * defined interrupt mask
635 * TODO: Read implementation defined interrupt mask
636 * from Slave property
637 */
638 val = SDW_SCP_INT1_IMPL_DEF | SDW_SCP_INT1_BUS_CLASH |
639 SDW_SCP_INT1_PARITY;
640
641 /* Enable SCP interrupts */
642 ret = sdw_update(slave, SDW_SCP_INTMASK1, val, val);
643 if (ret < 0) {
644 dev_err(slave->bus->dev,
Pierre-Louis Bossart73ede042019-05-01 10:57:27 -0500645 "SDW_SCP_INTMASK1 write failed:%d", ret);
Sanyog Kaled52d7a12017-12-14 11:19:39 +0530646 return ret;
647 }
648
649 /* No need to continue if DP0 is not present */
650 if (!slave->prop.dp0_prop)
651 return 0;
652
653 /* Enable DP0 interrupts */
654 val = prop->dp0_prop->device_interrupts;
655 val |= SDW_DP0_INT_PORT_READY | SDW_DP0_INT_BRA_FAILURE;
656
657 ret = sdw_update(slave, SDW_DP0_INTMASK, val, val);
658 if (ret < 0) {
659 dev_err(slave->bus->dev,
Pierre-Louis Bossart73ede042019-05-01 10:57:27 -0500660 "SDW_DP0_INTMASK read failed:%d", ret);
Sanyog Kaled52d7a12017-12-14 11:19:39 +0530661 return val;
662 }
663
664 return 0;
665}
Vinod Koulb0a9c372017-12-14 11:19:40 +0530666
667static int sdw_handle_dp0_interrupt(struct sdw_slave *slave, u8 *slave_status)
668{
669 u8 clear = 0, impl_int_mask;
670 int status, status2, ret, count = 0;
671
672 status = sdw_read(slave, SDW_DP0_INT);
673 if (status < 0) {
674 dev_err(slave->bus->dev,
Pierre-Louis Bossart73ede042019-05-01 10:57:27 -0500675 "SDW_DP0_INT read failed:%d", status);
Vinod Koulb0a9c372017-12-14 11:19:40 +0530676 return status;
677 }
678
679 do {
680
681 if (status & SDW_DP0_INT_TEST_FAIL) {
682 dev_err(&slave->dev, "Test fail for port 0");
683 clear |= SDW_DP0_INT_TEST_FAIL;
684 }
685
686 /*
687 * Assumption: PORT_READY interrupt will be received only for
688 * ports implementing Channel Prepare state machine (CP_SM)
689 */
690
691 if (status & SDW_DP0_INT_PORT_READY) {
692 complete(&slave->port_ready[0]);
693 clear |= SDW_DP0_INT_PORT_READY;
694 }
695
696 if (status & SDW_DP0_INT_BRA_FAILURE) {
697 dev_err(&slave->dev, "BRA failed");
698 clear |= SDW_DP0_INT_BRA_FAILURE;
699 }
700
701 impl_int_mask = SDW_DP0_INT_IMPDEF1 |
702 SDW_DP0_INT_IMPDEF2 | SDW_DP0_INT_IMPDEF3;
703
704 if (status & impl_int_mask) {
705 clear |= impl_int_mask;
706 *slave_status = clear;
707 }
708
709 /* clear the interrupt */
710 ret = sdw_write(slave, SDW_DP0_INT, clear);
711 if (ret < 0) {
712 dev_err(slave->bus->dev,
713 "SDW_DP0_INT write failed:%d", ret);
714 return ret;
715 }
716
717 /* Read DP0 interrupt again */
718 status2 = sdw_read(slave, SDW_DP0_INT);
719 if (status2 < 0) {
720 dev_err(slave->bus->dev,
Wei Yongjun80cd8f02018-01-08 22:22:44 +0530721 "SDW_DP0_INT read failed:%d", status2);
722 return status2;
Vinod Koulb0a9c372017-12-14 11:19:40 +0530723 }
724 status &= status2;
725
726 count++;
727
728 /* we can get alerts while processing so keep retrying */
729 } while (status != 0 && count < SDW_READ_INTR_CLEAR_RETRY);
730
731 if (count == SDW_READ_INTR_CLEAR_RETRY)
732 dev_warn(slave->bus->dev, "Reached MAX_RETRY on DP0 read");
733
734 return ret;
735}
736
737static int sdw_handle_port_interrupt(struct sdw_slave *slave,
Pierre-Louis Bossart73ede042019-05-01 10:57:27 -0500738 int port, u8 *slave_status)
Vinod Koulb0a9c372017-12-14 11:19:40 +0530739{
740 u8 clear = 0, impl_int_mask;
741 int status, status2, ret, count = 0;
742 u32 addr;
743
744 if (port == 0)
745 return sdw_handle_dp0_interrupt(slave, slave_status);
746
747 addr = SDW_DPN_INT(port);
748 status = sdw_read(slave, addr);
749 if (status < 0) {
750 dev_err(slave->bus->dev,
Pierre-Louis Bossart73ede042019-05-01 10:57:27 -0500751 "SDW_DPN_INT read failed:%d", status);
Vinod Koulb0a9c372017-12-14 11:19:40 +0530752
753 return status;
754 }
755
756 do {
757
758 if (status & SDW_DPN_INT_TEST_FAIL) {
759 dev_err(&slave->dev, "Test fail for port:%d", port);
760 clear |= SDW_DPN_INT_TEST_FAIL;
761 }
762
763 /*
764 * Assumption: PORT_READY interrupt will be received only
765 * for ports implementing CP_SM.
766 */
767 if (status & SDW_DPN_INT_PORT_READY) {
768 complete(&slave->port_ready[port]);
769 clear |= SDW_DPN_INT_PORT_READY;
770 }
771
772 impl_int_mask = SDW_DPN_INT_IMPDEF1 |
773 SDW_DPN_INT_IMPDEF2 | SDW_DPN_INT_IMPDEF3;
774
775
776 if (status & impl_int_mask) {
777 clear |= impl_int_mask;
778 *slave_status = clear;
779 }
780
781 /* clear the interrupt */
782 ret = sdw_write(slave, addr, clear);
783 if (ret < 0) {
784 dev_err(slave->bus->dev,
Pierre-Louis Bossart73ede042019-05-01 10:57:27 -0500785 "SDW_DPN_INT write failed:%d", ret);
Vinod Koulb0a9c372017-12-14 11:19:40 +0530786 return ret;
787 }
788
789 /* Read DPN interrupt again */
790 status2 = sdw_read(slave, addr);
Wei Yongjun80cd8f02018-01-08 22:22:44 +0530791 if (status2 < 0) {
Vinod Koulb0a9c372017-12-14 11:19:40 +0530792 dev_err(slave->bus->dev,
Pierre-Louis Bossart73ede042019-05-01 10:57:27 -0500793 "SDW_DPN_INT read failed:%d", status2);
Wei Yongjun80cd8f02018-01-08 22:22:44 +0530794 return status2;
Vinod Koulb0a9c372017-12-14 11:19:40 +0530795 }
796 status &= status2;
797
798 count++;
799
800 /* we can get alerts while processing so keep retrying */
801 } while (status != 0 && count < SDW_READ_INTR_CLEAR_RETRY);
802
803 if (count == SDW_READ_INTR_CLEAR_RETRY)
804 dev_warn(slave->bus->dev, "Reached MAX_RETRY on port read");
805
806 return ret;
807}
808
809static int sdw_handle_slave_alerts(struct sdw_slave *slave)
810{
811 struct sdw_slave_intr_status slave_intr;
812 u8 clear = 0, bit, port_status[15];
813 int port_num, stat, ret, count = 0;
814 unsigned long port;
815 bool slave_notify = false;
816 u8 buf, buf2[2], _buf, _buf2[2];
817
818 sdw_modify_slave_status(slave, SDW_SLAVE_ALERT);
819
820 /* Read Instat 1, Instat 2 and Instat 3 registers */
Dan Carpenter51c26652018-01-21 10:26:31 +0530821 buf = ret = sdw_read(slave, SDW_SCP_INT1);
Vinod Koulb0a9c372017-12-14 11:19:40 +0530822 if (ret < 0) {
823 dev_err(slave->bus->dev,
Pierre-Louis Bossart73ede042019-05-01 10:57:27 -0500824 "SDW_SCP_INT1 read failed:%d", ret);
Vinod Koulb0a9c372017-12-14 11:19:40 +0530825 return ret;
826 }
827
828 ret = sdw_nread(slave, SDW_SCP_INTSTAT2, 2, buf2);
829 if (ret < 0) {
830 dev_err(slave->bus->dev,
Pierre-Louis Bossart73ede042019-05-01 10:57:27 -0500831 "SDW_SCP_INT2/3 read failed:%d", ret);
Vinod Koulb0a9c372017-12-14 11:19:40 +0530832 return ret;
833 }
834
835 do {
836 /*
837 * Check parity, bus clash and Slave (impl defined)
838 * interrupt
839 */
840 if (buf & SDW_SCP_INT1_PARITY) {
841 dev_err(&slave->dev, "Parity error detected");
842 clear |= SDW_SCP_INT1_PARITY;
843 }
844
845 if (buf & SDW_SCP_INT1_BUS_CLASH) {
846 dev_err(&slave->dev, "Bus clash error detected");
847 clear |= SDW_SCP_INT1_BUS_CLASH;
848 }
849
850 /*
851 * When bus clash or parity errors are detected, such errors
852 * are unlikely to be recoverable errors.
853 * TODO: In such scenario, reset bus. Make this configurable
854 * via sysfs property with bus reset being the default.
855 */
856
857 if (buf & SDW_SCP_INT1_IMPL_DEF) {
858 dev_dbg(&slave->dev, "Slave impl defined interrupt\n");
859 clear |= SDW_SCP_INT1_IMPL_DEF;
860 slave_notify = true;
861 }
862
863 /* Check port 0 - 3 interrupts */
864 port = buf & SDW_SCP_INT1_PORT0_3;
865
866 /* To get port number corresponding to bits, shift it */
867 port = port >> SDW_REG_SHIFT(SDW_SCP_INT1_PORT0_3);
868 for_each_set_bit(bit, &port, 8) {
869 sdw_handle_port_interrupt(slave, bit,
Pierre-Louis Bossart73ede042019-05-01 10:57:27 -0500870 &port_status[bit]);
Vinod Koulb0a9c372017-12-14 11:19:40 +0530871
872 }
873
874 /* Check if cascade 2 interrupt is present */
875 if (buf & SDW_SCP_INT1_SCP2_CASCADE) {
876 port = buf2[0] & SDW_SCP_INTSTAT2_PORT4_10;
877 for_each_set_bit(bit, &port, 8) {
878 /* scp2 ports start from 4 */
879 port_num = bit + 3;
880 sdw_handle_port_interrupt(slave,
881 port_num,
882 &port_status[port_num]);
883 }
884 }
885
886 /* now check last cascade */
887 if (buf2[0] & SDW_SCP_INTSTAT2_SCP3_CASCADE) {
888 port = buf2[1] & SDW_SCP_INTSTAT3_PORT11_14;
889 for_each_set_bit(bit, &port, 8) {
890 /* scp3 ports start from 11 */
891 port_num = bit + 10;
892 sdw_handle_port_interrupt(slave,
893 port_num,
894 &port_status[port_num]);
895 }
896 }
897
898 /* Update the Slave driver */
899 if (slave_notify && (slave->ops) &&
900 (slave->ops->interrupt_callback)) {
901 slave_intr.control_port = clear;
902 memcpy(slave_intr.port, &port_status,
Pierre-Louis Bossart73ede042019-05-01 10:57:27 -0500903 sizeof(slave_intr.port));
Vinod Koulb0a9c372017-12-14 11:19:40 +0530904
905 slave->ops->interrupt_callback(slave, &slave_intr);
906 }
907
908 /* Ack interrupt */
909 ret = sdw_write(slave, SDW_SCP_INT1, clear);
910 if (ret < 0) {
911 dev_err(slave->bus->dev,
Pierre-Louis Bossart73ede042019-05-01 10:57:27 -0500912 "SDW_SCP_INT1 write failed:%d", ret);
Vinod Koulb0a9c372017-12-14 11:19:40 +0530913 return ret;
914 }
915
916 /*
917 * Read status again to ensure no new interrupts arrived
918 * while servicing interrupts.
919 */
Dan Carpenter51c26652018-01-21 10:26:31 +0530920 _buf = ret = sdw_read(slave, SDW_SCP_INT1);
Vinod Koulb0a9c372017-12-14 11:19:40 +0530921 if (ret < 0) {
922 dev_err(slave->bus->dev,
Pierre-Louis Bossart73ede042019-05-01 10:57:27 -0500923 "SDW_SCP_INT1 read failed:%d", ret);
Vinod Koulb0a9c372017-12-14 11:19:40 +0530924 return ret;
925 }
926
927 ret = sdw_nread(slave, SDW_SCP_INTSTAT2, 2, _buf2);
928 if (ret < 0) {
929 dev_err(slave->bus->dev,
Pierre-Louis Bossart73ede042019-05-01 10:57:27 -0500930 "SDW_SCP_INT2/3 read failed:%d", ret);
Vinod Koulb0a9c372017-12-14 11:19:40 +0530931 return ret;
932 }
933
934 /* Make sure no interrupts are pending */
935 buf &= _buf;
936 buf2[0] &= _buf2[0];
937 buf2[1] &= _buf2[1];
938 stat = buf || buf2[0] || buf2[1];
939
940 /*
941 * Exit loop if Slave is continuously in ALERT state even
942 * after servicing the interrupt multiple times.
943 */
944 count++;
945
946 /* we can get alerts while processing so keep retrying */
947 } while (stat != 0 && count < SDW_READ_INTR_CLEAR_RETRY);
948
949 if (count == SDW_READ_INTR_CLEAR_RETRY)
950 dev_warn(slave->bus->dev, "Reached MAX_RETRY on alert read");
951
952 return ret;
953}
954
955static int sdw_update_slave_status(struct sdw_slave *slave,
Pierre-Louis Bossart73ede042019-05-01 10:57:27 -0500956 enum sdw_slave_status status)
Vinod Koulb0a9c372017-12-14 11:19:40 +0530957{
958 if ((slave->ops) && (slave->ops->update_status))
959 return slave->ops->update_status(slave, status);
960
961 return 0;
962}
963
964/**
965 * sdw_handle_slave_status() - Handle Slave status
966 * @bus: SDW bus instance
967 * @status: Status for all Slave(s)
968 */
969int sdw_handle_slave_status(struct sdw_bus *bus,
Pierre-Louis Bossart73ede042019-05-01 10:57:27 -0500970 enum sdw_slave_status status[])
Vinod Koulb0a9c372017-12-14 11:19:40 +0530971{
972 enum sdw_slave_status prev_status;
973 struct sdw_slave *slave;
974 int i, ret = 0;
975
976 if (status[0] == SDW_SLAVE_ATTACHED) {
977 ret = sdw_program_device_num(bus);
978 if (ret)
979 dev_err(bus->dev, "Slave attach failed: %d", ret);
980 }
981
982 /* Continue to check other slave statuses */
983 for (i = 1; i <= SDW_MAX_DEVICES; i++) {
984 mutex_lock(&bus->bus_lock);
985 if (test_bit(i, bus->assigned) == false) {
986 mutex_unlock(&bus->bus_lock);
987 continue;
988 }
989 mutex_unlock(&bus->bus_lock);
990
991 slave = sdw_get_slave(bus, i);
992 if (!slave)
993 continue;
994
995 switch (status[i]) {
996 case SDW_SLAVE_UNATTACHED:
997 if (slave->status == SDW_SLAVE_UNATTACHED)
998 break;
999
1000 sdw_modify_slave_status(slave, SDW_SLAVE_UNATTACHED);
1001 break;
1002
1003 case SDW_SLAVE_ALERT:
1004 ret = sdw_handle_slave_alerts(slave);
1005 if (ret)
1006 dev_err(bus->dev,
1007 "Slave %d alert handling failed: %d",
1008 i, ret);
1009 break;
1010
1011 case SDW_SLAVE_ATTACHED:
1012 if (slave->status == SDW_SLAVE_ATTACHED)
1013 break;
1014
1015 prev_status = slave->status;
1016 sdw_modify_slave_status(slave, SDW_SLAVE_ATTACHED);
1017
1018 if (prev_status == SDW_SLAVE_ALERT)
1019 break;
1020
1021 ret = sdw_initialize_slave(slave);
1022 if (ret)
1023 dev_err(bus->dev,
1024 "Slave %d initialization failed: %d",
1025 i, ret);
1026
1027 break;
1028
1029 default:
1030 dev_err(bus->dev, "Invalid slave %d status:%d",
Pierre-Louis Bossart73ede042019-05-01 10:57:27 -05001031 i, status[i]);
Vinod Koulb0a9c372017-12-14 11:19:40 +05301032 break;
1033 }
1034
1035 ret = sdw_update_slave_status(slave, status[i]);
1036 if (ret)
1037 dev_err(slave->bus->dev,
1038 "Update Slave status failed:%d", ret);
1039
1040 }
1041
1042 return ret;
1043}
1044EXPORT_SYMBOL(sdw_handle_slave_status);