blob: f7f02698cf56568a553b810a40debc165efc9415 [file] [log] [blame]
Sagar Dhariabe37c9c2016-11-28 23:06:58 -07001/* Copyright (c) 2011-2017, The Linux Foundation. All rights reserved.
2 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 */
12#include <linux/irq.h>
13#include <linux/kernel.h>
14#include <linux/init.h>
15#include <linux/slab.h>
16#include <linux/io.h>
17#include <linux/interrupt.h>
18#include <linux/platform_device.h>
19#include <linux/dma-mapping.h>
20#include <linux/slimbus/slimbus.h>
21#include <linux/delay.h>
22#include <linux/kthread.h>
23#include <linux/clk.h>
24#include <linux/pm_runtime.h>
25#include <linux/of.h>
26#include <linux/of_slimbus.h>
27#include <linux/timer.h>
28#include <linux/msm-sps.h>
29#include <soc/qcom/service-locator.h>
30#include <soc/qcom/service-notifier.h>
31#include <soc/qcom/subsystem_notif.h>
32#include "slim-msm.h"
33
34#define NGD_SLIM_NAME "ngd_msm_ctrl"
35#define SLIM_LA_MGR 0xFF
36#define SLIM_ROOT_FREQ 24576000
37#define LADDR_RETRY 5
38
39#define NGD_BASE_V1(r) (((r) % 2) ? 0x800 : 0xA00)
40#define NGD_BASE_V2(r) (((r) % 2) ? 0x1000 : 0x2000)
41#define NGD_BASE(r, v) ((v) ? NGD_BASE_V2(r) : NGD_BASE_V1(r))
42/* NGD (Non-ported Generic Device) registers */
43enum ngd_reg {
44 NGD_CFG = 0x0,
45 NGD_STATUS = 0x4,
46 NGD_RX_MSGQ_CFG = 0x8,
47 NGD_INT_EN = 0x10,
48 NGD_INT_STAT = 0x14,
49 NGD_INT_CLR = 0x18,
50 NGD_TX_MSG = 0x30,
51 NGD_RX_MSG = 0x70,
52 NGD_IE_STAT = 0xF0,
53 NGD_VE_STAT = 0x100,
54};
55
56enum ngd_msg_cfg {
57 NGD_CFG_ENABLE = 1,
58 NGD_CFG_RX_MSGQ_EN = 1 << 1,
59 NGD_CFG_TX_MSGQ_EN = 1 << 2,
60};
61
62enum ngd_intr {
63 NGD_INT_RECFG_DONE = 1 << 24,
64 NGD_INT_TX_NACKED_2 = 1 << 25,
65 NGD_INT_MSG_BUF_CONTE = 1 << 26,
66 NGD_INT_MSG_TX_INVAL = 1 << 27,
67 NGD_INT_IE_VE_CHG = 1 << 28,
68 NGD_INT_DEV_ERR = 1 << 29,
69 NGD_INT_RX_MSG_RCVD = 1 << 30,
70 NGD_INT_TX_MSG_SENT = 1 << 31,
71};
72
73enum ngd_offsets {
74 NGD_NACKED_MC = 0x7F00000,
75 NGD_ACKED_MC = 0xFE000,
76 NGD_ERROR = 0x1800,
77 NGD_MSGQ_SUPPORT = 0x400,
78 NGD_RX_MSGQ_TIME_OUT = 0x16,
79 NGD_ENUMERATED = 0x1,
80 NGD_TX_BUSY = 0x0,
81};
82
83enum ngd_status {
84 NGD_LADDR = 1 << 1,
85};
86
87static void ngd_slim_rx(struct msm_slim_ctrl *dev, u8 *buf);
88static int ngd_slim_runtime_resume(struct device *device);
89static int ngd_slim_power_up(struct msm_slim_ctrl *dev, bool mdm_restart);
90static void ngd_dom_down(struct msm_slim_ctrl *dev);
91static int dsp_domr_notify_cb(struct notifier_block *n, unsigned long code,
92 void *_cmd);
93
94static irqreturn_t ngd_slim_interrupt(int irq, void *d)
95{
96 struct msm_slim_ctrl *dev = (struct msm_slim_ctrl *)d;
97 void __iomem *ngd = dev->base + NGD_BASE(dev->ctrl.nr, dev->ver);
98 u32 stat = readl_relaxed(ngd + NGD_INT_STAT);
99 u32 pstat;
100
101 if ((stat & NGD_INT_MSG_BUF_CONTE) ||
102 (stat & NGD_INT_MSG_TX_INVAL) || (stat & NGD_INT_DEV_ERR) ||
103 (stat & NGD_INT_TX_NACKED_2)) {
104 writel_relaxed(stat, ngd + NGD_INT_CLR);
105 if (stat & NGD_INT_MSG_TX_INVAL)
106 dev->err = -EINVAL;
107 else
108 dev->err = -EIO;
109
110 SLIM_WARN(dev, "NGD interrupt error:0x%x, err:%d\n", stat,
111 dev->err);
112 /* Guarantee that error interrupts are cleared */
113 mb();
114 msm_slim_manage_tx_msgq(dev, false, NULL, dev->err);
115
116 } else if (stat & NGD_INT_TX_MSG_SENT) {
117 writel_relaxed(NGD_INT_TX_MSG_SENT, ngd + NGD_INT_CLR);
118 /* Make sure interrupt is cleared */
119 mb();
120 msm_slim_manage_tx_msgq(dev, false, NULL, 0);
121 }
122 if (stat & NGD_INT_RX_MSG_RCVD) {
123 u32 rx_buf[10];
124 u8 len, i;
125
126 rx_buf[0] = readl_relaxed(ngd + NGD_RX_MSG);
127 len = rx_buf[0] & 0x1F;
128 for (i = 1; i < ((len + 3) >> 2); i++) {
129 rx_buf[i] = readl_relaxed(ngd + NGD_RX_MSG +
130 (4 * i));
131 SLIM_DBG(dev, "REG-RX data: %x\n", rx_buf[i]);
132 }
133 writel_relaxed(NGD_INT_RX_MSG_RCVD,
134 ngd + NGD_INT_CLR);
135 /*
136 * Guarantee that CLR bit write goes through before
137 * queuing work
138 */
139 mb();
140 ngd_slim_rx(dev, (u8 *)rx_buf);
141 }
142 if (stat & NGD_INT_RECFG_DONE) {
143 writel_relaxed(NGD_INT_RECFG_DONE, ngd + NGD_INT_CLR);
144 /* Guarantee RECONFIG DONE interrupt is cleared */
145 mb();
146 /* In satellite mode, just log the reconfig done IRQ */
147 SLIM_DBG(dev, "reconfig done IRQ for NGD\n");
148 }
149 if (stat & NGD_INT_IE_VE_CHG) {
150 writel_relaxed(NGD_INT_IE_VE_CHG, ngd + NGD_INT_CLR);
151 /* Guarantee IE VE change interrupt is cleared */
152 mb();
153 SLIM_DBG(dev, "NGD IE VE change\n");
154 }
155
156 pstat = readl_relaxed(PGD_THIS_EE(PGD_PORT_INT_ST_EEn, dev->ver));
157 if (pstat != 0)
158 return msm_slim_port_irq_handler(dev, pstat);
159 return IRQ_HANDLED;
160}
161
162static int ngd_qmi_available(struct notifier_block *n, unsigned long code,
163 void *_cmd)
164{
165 struct msm_slim_qmi *qmi = container_of(n, struct msm_slim_qmi, nb);
166 struct msm_slim_ctrl *dev =
167 container_of(qmi, struct msm_slim_ctrl, qmi);
168 SLIM_INFO(dev, "Slimbus QMI NGD CB received event:%ld\n", code);
169 switch (code) {
170 case QMI_SERVER_ARRIVE:
171 atomic_set(&dev->ssr_in_progress, 0);
172 schedule_work(&dev->dsp.dom_up);
173 break;
174 default:
175 break;
176 }
177 return 0;
178}
179
180static void ngd_reg_ssr(struct msm_slim_ctrl *dev)
181{
182 int ret;
183 const char *subsys_name = NULL;
184
185 dev->dsp.dom_t = MSM_SLIM_DOM_NONE;
186 ret = of_property_read_string(dev->dev->of_node,
187 "qcom,subsys-name", &subsys_name);
188 if (ret)
189 subsys_name = "adsp";
190
191 dev->dsp.nb.notifier_call = dsp_domr_notify_cb;
192 dev->dsp.domr = subsys_notif_register_notifier(subsys_name,
193 &dev->dsp.nb);
194 if (IS_ERR_OR_NULL(dev->dsp.domr)) {
195 dev_err(dev->dev,
196 "subsys_notif_register_notifier failed %ld",
197 PTR_ERR(dev->dsp.domr));
198 return;
199 }
200 dev->dsp.dom_t = MSM_SLIM_DOM_SS;
201 SLIM_INFO(dev, "reg-SSR with:%s, PDR not available\n",
202 subsys_name);
203}
204
205static int dsp_domr_notify_cb(struct notifier_block *n, unsigned long code,
206 void *_cmd)
207{
208 int cur = -1;
209 struct msm_slim_ss *dsp = container_of(n, struct msm_slim_ss, nb);
210 struct msm_slim_ctrl *dev = container_of(dsp, struct msm_slim_ctrl,
211 dsp);
212 struct pd_qmi_client_data *reg;
213
214 SLIM_INFO(dev, "SLIM DSP SSR/PDR notify cb:0x%lx, type:%d\n",
215 code, dsp->dom_t);
216 switch (code) {
217 case SUBSYS_BEFORE_SHUTDOWN:
218 case SERVREG_NOTIF_SERVICE_STATE_DOWN_V01:
219 SLIM_INFO(dev, "SLIM DSP SSR notify cb:%lu\n", code);
220 atomic_set(&dev->ssr_in_progress, 1);
221 /* wait for current transaction */
222 mutex_lock(&dev->tx_lock);
223 /* make sure autosuspend is not called until ADSP comes up*/
224 pm_runtime_get_noresume(dev->dev);
225 dev->state = MSM_CTRL_DOWN;
226 msm_slim_sps_exit(dev, false);
227 ngd_dom_down(dev);
228 mutex_unlock(&dev->tx_lock);
229 break;
230 case LOCATOR_UP:
231 reg = _cmd;
232 if (!reg || reg->total_domains != 1) {
233 SLIM_WARN(dev, "error locating audio-PD\n");
234 if (reg)
235 SLIM_WARN(dev, "audio-PDs matched:%d\n",
236 reg->total_domains);
237
238 /* Fall back to SSR */
239 ngd_reg_ssr(dev);
240 return NOTIFY_DONE;
241 }
242 dev->dsp.domr = service_notif_register_notifier(
243 reg->domain_list->name,
244 reg->domain_list->instance_id,
245 &dev->dsp.nb,
246 &cur);
247 SLIM_INFO(dev, "reg-PD client:%s with service:%s\n",
248 reg->client_name, reg->service_name);
249 SLIM_INFO(dev, "reg-PD dom:%s instance:%d, cur:%d\n",
250 reg->domain_list->name,
251 reg->domain_list->instance_id, cur);
252 if (IS_ERR_OR_NULL(dev->dsp.domr))
253 ngd_reg_ssr(dev);
254 else
255 dev->dsp.dom_t = MSM_SLIM_DOM_PD;
256 break;
257 case LOCATOR_DOWN:
258 ngd_reg_ssr(dev);
259 default:
260 break;
261 }
262 return NOTIFY_DONE;
263}
264
265static void ngd_dom_init(struct msm_slim_ctrl *dev)
266{
267 struct pd_qmi_client_data reg;
268 int ret;
269
270 memset(&reg, 0, sizeof(struct pd_qmi_client_data));
271 dev->dsp.nb.priority = 4;
272 dev->dsp.nb.notifier_call = dsp_domr_notify_cb;
273 scnprintf(reg.client_name, QMI_SERVREG_LOC_NAME_LENGTH_V01, "appsngd%d",
274 dev->ctrl.nr);
275 scnprintf(reg.service_name, QMI_SERVREG_LOC_NAME_LENGTH_V01,
276 "avs/audio");
277 ret = get_service_location(reg.client_name, reg.service_name,
278 &dev->dsp.nb);
279 if (ret)
280 ngd_reg_ssr(dev);
281}
282
283static int mdm_ssr_notify_cb(struct notifier_block *n, unsigned long code,
284 void *_cmd)
285{
286 void __iomem *ngd;
287 struct msm_slim_ss *ext_mdm = container_of(n, struct msm_slim_ss, nb);
288 struct msm_slim_ctrl *dev = container_of(ext_mdm, struct msm_slim_ctrl,
289 ext_mdm);
290 struct slim_controller *ctrl = &dev->ctrl;
291 u32 laddr;
292 struct slim_device *sbdev;
293
294 switch (code) {
295 case SUBSYS_BEFORE_SHUTDOWN:
296 SLIM_INFO(dev, "SLIM %lu external_modem SSR notify cb\n", code);
297 /* vote for runtime-pm so that ADSP doesn't go down */
298 msm_slim_get_ctrl(dev);
299 /*
300 * checking framer here will wake-up ADSP and may avoid framer
301 * handover later
302 */
303 msm_slim_qmi_check_framer_request(dev);
304 dev->ext_mdm.state = MSM_CTRL_DOWN;
305 msm_slim_put_ctrl(dev);
306 break;
307 case SUBSYS_AFTER_POWERUP:
308 if (dev->ext_mdm.state != MSM_CTRL_DOWN)
309 return NOTIFY_DONE;
310 SLIM_INFO(dev,
311 "SLIM %lu external_modem SSR notify cb\n", code);
312 /* vote for runtime-pm so that ADSP doesn't go down */
313 msm_slim_get_ctrl(dev);
314 msm_slim_qmi_check_framer_request(dev);
315 /* If NGD enumeration is lost, we will need to power us up */
316 ngd = dev->base + NGD_BASE(dev->ctrl.nr, dev->ver);
317 laddr = readl_relaxed(ngd + NGD_STATUS);
318 if (!(laddr & NGD_LADDR)) {
319 mutex_lock(&dev->tx_lock);
320 /* runtime-pm state should be consistent with HW */
321 pm_runtime_disable(dev->dev);
322 pm_runtime_set_suspended(dev->dev);
323 dev->state = MSM_CTRL_DOWN;
324 mutex_unlock(&dev->tx_lock);
325 SLIM_INFO(dev,
326 "SLIM MDM SSR (active framer on MDM) dev-down\n");
327 list_for_each_entry(sbdev, &ctrl->devs, dev_list)
328 slim_report_absent(sbdev);
329 ngd_slim_runtime_resume(dev->dev);
330 pm_runtime_set_active(dev->dev);
331 pm_runtime_enable(dev->dev);
332 }
333 dev->ext_mdm.state = MSM_CTRL_AWAKE;
334 msm_slim_put_ctrl(dev);
335 break;
336 default:
337 break;
338 }
339 return NOTIFY_DONE;
340}
341
342static int ngd_get_tid(struct slim_controller *ctrl, struct slim_msg_txn *txn,
343 u8 *tid, struct completion *done)
344{
345 struct msm_slim_ctrl *dev = slim_get_ctrldata(ctrl);
346 unsigned long flags;
347
348 spin_lock_irqsave(&ctrl->txn_lock, flags);
349 if (ctrl->last_tid <= 255) {
350 dev->msg_cnt = ctrl->last_tid;
351 ctrl->last_tid++;
352 } else {
353 int i;
354
355 for (i = 0; i < 256; i++) {
356 dev->msg_cnt = ((dev->msg_cnt + 1) & 0xFF);
357 if (ctrl->txnt[dev->msg_cnt] == NULL)
358 break;
359 }
360 if (i >= 256) {
361 dev_err(&ctrl->dev, "out of TID");
362 spin_unlock_irqrestore(&ctrl->txn_lock, flags);
363 return -ENOMEM;
364 }
365 }
366 ctrl->txnt[dev->msg_cnt] = txn;
367 txn->tid = dev->msg_cnt;
368 txn->comp = done;
369 *tid = dev->msg_cnt;
370 spin_unlock_irqrestore(&ctrl->txn_lock, flags);
371 return 0;
372}
373
374static void slim_reinit_tx_msgq(struct msm_slim_ctrl *dev)
375{
376 /*
377 * disconnect/recoonect pipe so that subsequent
378 * transactions don't timeout due to unavailable
379 * descriptors
380 */
381 if (dev->state != MSM_CTRL_DOWN) {
382 msm_slim_disconnect_endp(dev, &dev->tx_msgq,
383 &dev->use_tx_msgqs);
384 msm_slim_connect_endp(dev, &dev->tx_msgq);
385 }
386}
387
388static int ngd_check_hw_status(struct msm_slim_ctrl *dev)
389{
390 void __iomem *ngd = dev->base + NGD_BASE(dev->ctrl.nr, dev->ver);
391 u32 laddr = readl_relaxed(ngd + NGD_STATUS);
392 int ret = 0;
393
394 /* Lost logical addr due to noise */
395 if (!(laddr & NGD_LADDR)) {
396 SLIM_WARN(dev, "NGD lost LADDR: status:0x%x\n", laddr);
397 ret = ngd_slim_power_up(dev, false);
398
399 if (ret) {
400 SLIM_WARN(dev, "slim resume ret:%d, state:%d\n",
401 ret, dev->state);
402 ret = -EREMOTEIO;
403 }
404 }
405 return ret;
406}
407
408static int ngd_xfer_msg(struct slim_controller *ctrl, struct slim_msg_txn *txn)
409{
410 DECLARE_COMPLETION_ONSTACK(done);
411 DECLARE_COMPLETION_ONSTACK(tx_sent);
412
413 struct msm_slim_ctrl *dev = slim_get_ctrldata(ctrl);
414 u32 *pbuf;
415 u8 *puc;
416 int ret = 0;
417 u8 la = txn->la;
418 u8 txn_mt;
419 u16 txn_mc = txn->mc;
420 u8 wbuf[SLIM_MSGQ_BUF_LEN];
421 bool report_sat = false;
422 bool sync_wr = true;
423
424 if (txn->mc & SLIM_MSG_CLK_PAUSE_SEQ_FLG)
425 return -EPROTONOSUPPORT;
426
427 if (txn->mt == SLIM_MSG_MT_CORE &&
428 (txn->mc >= SLIM_MSG_MC_BEGIN_RECONFIGURATION &&
429 txn->mc <= SLIM_MSG_MC_RECONFIGURE_NOW))
430 return 0;
431
432 if (txn->mc == SLIM_USR_MC_REPORT_SATELLITE &&
433 txn->mt == SLIM_MSG_MT_SRC_REFERRED_USER)
434 report_sat = true;
435 else
436 mutex_lock(&dev->tx_lock);
437
438 if (!report_sat && !pm_runtime_enabled(dev->dev) &&
439 dev->state == MSM_CTRL_ASLEEP) {
440 /*
441 * Counter-part of system-suspend when runtime-pm is not enabled
442 * This way, resume can be left empty and device will be put in
443 * active mode only if client requests anything on the bus
444 * If the state was DOWN, SSR UP notification will take
445 * care of putting the device in active state.
446 */
447 mutex_unlock(&dev->tx_lock);
448 ret = ngd_slim_runtime_resume(dev->dev);
449
450 if (ret) {
451 SLIM_ERR(dev, "slim resume failed ret:%d, state:%d",
452 ret, dev->state);
453 return -EREMOTEIO;
454 }
455 mutex_lock(&dev->tx_lock);
456 }
457
458 /* If txn is tried when controller is down, wait for ADSP to boot */
459 if (!report_sat) {
460 if (dev->state == MSM_CTRL_DOWN) {
461 u8 mc = (u8)txn->mc;
462 int timeout;
463
464 mutex_unlock(&dev->tx_lock);
465 SLIM_INFO(dev, "ADSP slimbus not up yet\n");
466 /*
467 * Messages related to data channel management can't
468 * wait since they are holding reconfiguration lock.
469 * clk_pause in resume (which can change state back to
470 * MSM_CTRL_AWAKE), will need that lock.
471 * Port disconnection, channel removal calls should pass
472 * through since there is no activity on the bus and
473 * those calls are triggered by clients due to
474 * device_down callback in that situation.
475 * Returning 0 on the disconnections and
476 * removals will ensure consistent state of channels,
477 * ports with the HW
478 * Remote requests to remove channel/port will be
479 * returned from the path where they wait on
480 * acknowledgment from ADSP
481 */
482 if ((txn->mt == SLIM_MSG_MT_DEST_REFERRED_USER) &&
483 ((mc == SLIM_USR_MC_CHAN_CTRL ||
484 mc == SLIM_USR_MC_DISCONNECT_PORT ||
485 mc == SLIM_USR_MC_RECONFIG_NOW)))
486 return -EREMOTEIO;
487 if ((txn->mt == SLIM_MSG_MT_CORE) &&
488 ((mc == SLIM_MSG_MC_DISCONNECT_PORT ||
489 mc == SLIM_MSG_MC_NEXT_REMOVE_CHANNEL ||
490 mc == SLIM_USR_MC_RECONFIG_NOW)))
491 return 0;
492 if ((txn->mt == SLIM_MSG_MT_CORE) &&
493 ((mc >= SLIM_MSG_MC_CONNECT_SOURCE &&
494 mc <= SLIM_MSG_MC_CHANGE_CONTENT) ||
495 (mc >= SLIM_MSG_MC_BEGIN_RECONFIGURATION &&
496 mc <= SLIM_MSG_MC_RECONFIGURE_NOW)))
497 return -EREMOTEIO;
498 if ((txn->mt == SLIM_MSG_MT_DEST_REFERRED_USER) &&
499 ((mc >= SLIM_USR_MC_DEFINE_CHAN &&
500 mc < SLIM_USR_MC_DISCONNECT_PORT)))
501 return -EREMOTEIO;
502 timeout = wait_for_completion_timeout(&dev->ctrl_up,
503 HZ);
504 if (!timeout)
505 return -ETIMEDOUT;
506 mutex_lock(&dev->tx_lock);
507 }
508
509 mutex_unlock(&dev->tx_lock);
510 ret = msm_slim_get_ctrl(dev);
511 mutex_lock(&dev->tx_lock);
512 /*
513 * Runtime-pm's callbacks are not called until runtime-pm's
514 * error status is cleared
515 * Setting runtime status to suspended clears the error
516 * It also makes HW status cosistent with what SW has it here
517 */
518 if ((pm_runtime_enabled(dev->dev) && ret < 0) ||
519 dev->state >= MSM_CTRL_ASLEEP) {
520 SLIM_ERR(dev, "slim ctrl vote failed ret:%d, state:%d",
521 ret, dev->state);
522 pm_runtime_set_suspended(dev->dev);
523 mutex_unlock(&dev->tx_lock);
524 msm_slim_put_ctrl(dev);
525 return -EREMOTEIO;
526 }
527 ret = ngd_check_hw_status(dev);
528 if (ret) {
529 mutex_unlock(&dev->tx_lock);
530 msm_slim_put_ctrl(dev);
531 return ret;
532 }
533 }
534
535 if (txn->mt == SLIM_MSG_MT_CORE &&
536 (txn->mc == SLIM_MSG_MC_CONNECT_SOURCE ||
537 txn->mc == SLIM_MSG_MC_CONNECT_SINK ||
538 txn->mc == SLIM_MSG_MC_DISCONNECT_PORT)) {
539 int i = 0;
540
541 if (txn->mc != SLIM_MSG_MC_DISCONNECT_PORT)
542 SLIM_INFO(dev,
543 "Connect port: laddr 0x%x port_num %d chan_num %d\n",
544 txn->la, txn->wbuf[0], txn->wbuf[1]);
545 else
546 SLIM_INFO(dev,
547 "Disconnect port: laddr 0x%x port_num %d\n",
548 txn->la, txn->wbuf[0]);
549 txn->mt = SLIM_MSG_MT_DEST_REFERRED_USER;
550 if (txn->mc == SLIM_MSG_MC_CONNECT_SOURCE)
551 txn->mc = SLIM_USR_MC_CONNECT_SRC;
552 else if (txn->mc == SLIM_MSG_MC_CONNECT_SINK)
553 txn->mc = SLIM_USR_MC_CONNECT_SINK;
554 else if (txn->mc == SLIM_MSG_MC_DISCONNECT_PORT)
555 txn->mc = SLIM_USR_MC_DISCONNECT_PORT;
556 if (txn->la == SLIM_LA_MGR) {
557 if (dev->pgdla == SLIM_LA_MGR) {
558 u8 ea[] = {0, QC_DEVID_PGD, 0, 0, QC_MFGID_MSB,
559 QC_MFGID_LSB};
560 ea[2] = (u8)(dev->pdata.eapc & 0xFF);
561 ea[3] = (u8)((dev->pdata.eapc & 0xFF00) >> 8);
562 mutex_unlock(&dev->tx_lock);
563 ret = dev->ctrl.get_laddr(&dev->ctrl, ea, 6,
564 &dev->pgdla);
565 SLIM_DBG(dev, "SLIM PGD LA:0x%x, ret:%d\n",
566 dev->pgdla, ret);
567 if (ret) {
568 SLIM_ERR(dev,
569 "Incorrect SLIM-PGD EAPC:0x%x\n",
570 dev->pdata.eapc);
571 return ret;
572 }
573 mutex_lock(&dev->tx_lock);
574 }
575 txn->la = dev->pgdla;
576 }
577 wbuf[i++] = txn->la;
578 la = SLIM_LA_MGR;
579 wbuf[i++] = txn->wbuf[0];
580 if (txn->mc != SLIM_USR_MC_DISCONNECT_PORT)
581 wbuf[i++] = txn->wbuf[1];
582 ret = ngd_get_tid(ctrl, txn, &wbuf[i++], &done);
583 if (ret) {
584 SLIM_ERR(dev, "TID for connect/disconnect fail:%d\n",
585 ret);
586 goto ngd_xfer_err;
587 }
588 txn->len = i;
589 txn->wbuf = wbuf;
590 txn->rl = txn->len + 4;
591 }
592 txn->rl--;
593
594 if (txn->len > SLIM_MSGQ_BUF_LEN || txn->rl > SLIM_MSGQ_BUF_LEN) {
595 SLIM_WARN(dev, "msg exeeds HW lim:%d, rl:%d, mc:0x%x, mt:0x%x",
596 txn->len, txn->rl, txn->mc, txn->mt);
597 ret = -EDQUOT;
598 goto ngd_xfer_err;
599 }
600
601 if (txn->mt == SLIM_MSG_MT_CORE && txn->comp &&
602 dev->use_tx_msgqs == MSM_MSGQ_ENABLED &&
603 (txn_mc != SLIM_MSG_MC_REQUEST_INFORMATION &&
604 txn_mc != SLIM_MSG_MC_REQUEST_VALUE &&
605 txn_mc != SLIM_MSG_MC_REQUEST_CHANGE_VALUE &&
606 txn_mc != SLIM_MSG_MC_REQUEST_CLEAR_INFORMATION)) {
607 sync_wr = false;
608 pbuf = msm_get_msg_buf(dev, txn->rl, txn->comp);
609 } else if (txn->mt == SLIM_MSG_MT_DEST_REFERRED_USER &&
610 dev->use_tx_msgqs == MSM_MSGQ_ENABLED &&
611 txn->mc == SLIM_USR_MC_REPEAT_CHANGE_VALUE &&
612 txn->comp) {
613 sync_wr = false;
614 pbuf = msm_get_msg_buf(dev, txn->rl, txn->comp);
615 } else {
616 pbuf = msm_get_msg_buf(dev, txn->rl, &tx_sent);
617 }
618
619 if (!pbuf) {
620 SLIM_ERR(dev, "Message buffer unavailable\n");
621 ret = -ENOMEM;
622 goto ngd_xfer_err;
623 }
624 dev->err = 0;
625
626 if (txn->dt == SLIM_MSG_DEST_ENUMADDR) {
627 ret = -EPROTONOSUPPORT;
628 goto ngd_xfer_err;
629 }
630 if (txn->dt == SLIM_MSG_DEST_LOGICALADDR)
631 *pbuf = SLIM_MSG_ASM_FIRST_WORD(txn->rl, txn->mt, txn->mc, 0,
632 la);
633 else
634 *pbuf = SLIM_MSG_ASM_FIRST_WORD(txn->rl, txn->mt, txn->mc, 1,
635 la);
636 if (txn->dt == SLIM_MSG_DEST_LOGICALADDR)
637 puc = ((u8 *)pbuf) + 3;
638 else
639 puc = ((u8 *)pbuf) + 2;
640 if (txn->rbuf)
641 *(puc++) = txn->tid;
642 if (((txn->mt == SLIM_MSG_MT_CORE) &&
643 ((txn->mc >= SLIM_MSG_MC_REQUEST_INFORMATION &&
644 txn->mc <= SLIM_MSG_MC_REPORT_INFORMATION) ||
645 (txn->mc >= SLIM_MSG_MC_REQUEST_VALUE &&
646 txn->mc <= SLIM_MSG_MC_CHANGE_VALUE))) ||
647 (txn->mc == SLIM_USR_MC_REPEAT_CHANGE_VALUE &&
648 txn->mt == SLIM_MSG_MT_DEST_REFERRED_USER)) {
649 *(puc++) = (txn->ec & 0xFF);
650 *(puc++) = (txn->ec >> 8)&0xFF;
651 }
652 if (txn->wbuf)
653 memcpy(puc, txn->wbuf, txn->len);
654 if (txn->mt == SLIM_MSG_MT_DEST_REFERRED_USER &&
655 (txn->mc == SLIM_USR_MC_CONNECT_SRC ||
656 txn->mc == SLIM_USR_MC_CONNECT_SINK ||
657 txn->mc == SLIM_USR_MC_DISCONNECT_PORT) && txn->wbuf &&
658 wbuf[0] == dev->pgdla) {
659 if (txn->mc != SLIM_USR_MC_DISCONNECT_PORT)
660 dev->err = msm_slim_connect_pipe_port(dev, wbuf[1]);
661 else
662 writel_relaxed(0, PGD_PORT(PGD_PORT_CFGn,
663 (dev->pipes[wbuf[1]].port_b),
664 dev->ver));
665 if (dev->err) {
666 SLIM_ERR(dev, "pipe-port connect err:%d\n", dev->err);
667 goto ngd_xfer_err;
668 }
669 /* Add port-base to port number if this is manager side port */
670 puc[1] = (u8)dev->pipes[wbuf[1]].port_b;
671 }
672 dev->err = 0;
673 /*
674 * If it's a read txn, it may be freed if a response is received by
675 * received thread before reaching end of this function.
676 * mc, mt may have changed to convert standard slimbus code/type to
677 * satellite user-defined message. Reinitialize again
678 */
679 txn_mc = txn->mc;
680 txn_mt = txn->mt;
681 ret = msm_send_msg_buf(dev, pbuf, txn->rl,
682 NGD_BASE(dev->ctrl.nr, dev->ver) + NGD_TX_MSG);
683 if (!ret && sync_wr) {
684 int i;
685 int timeout = wait_for_completion_timeout(&tx_sent, HZ);
686
687 if (!timeout && dev->use_tx_msgqs == MSM_MSGQ_ENABLED) {
688 struct msm_slim_endp *endpoint = &dev->tx_msgq;
689 struct sps_mem_buffer *mem = &endpoint->buf;
690 u32 idx = (u32) (((u8 *)pbuf - (u8 *)mem->base) /
691 SLIM_MSGQ_BUF_LEN);
692 phys_addr_t addr = mem->phys_base +
693 (idx * SLIM_MSGQ_BUF_LEN);
694 ret = -ETIMEDOUT;
695 SLIM_WARN(dev, "timeout, BAM desc_idx:%d, phys:%llx",
696 idx, (u64)addr);
697 for (i = 0; i < (SLIM_MSGQ_BUF_LEN >> 2) ; i++)
698 SLIM_WARN(dev, "timeout:bam-desc[%d]:0x%x",
699 i, *(pbuf + i));
700 if (idx < MSM_TX_BUFS)
701 dev->wr_comp[idx] = NULL;
702 slim_reinit_tx_msgq(dev);
703 } else if (!timeout) {
704 ret = -ETIMEDOUT;
705 SLIM_WARN(dev, "timeout non-BAM TX,len:%d", txn->rl);
706 for (i = 0; i < (SLIM_MSGQ_BUF_LEN >> 2) ; i++)
707 SLIM_WARN(dev, "timeout:txbuf[%d]:0x%x", i,
708 dev->tx_buf[i]);
709 } else {
710 ret = dev->err;
711 }
712 }
713 if (ret) {
714 u32 conf, stat, rx_msgq, int_stat, int_en, int_clr;
715 void __iomem *ngd = dev->base + NGD_BASE(dev->ctrl.nr,
716 dev->ver);
717 SLIM_WARN(dev, "TX failed :MC:0x%x,mt:0x%x, ret:%d, ver:%d\n",
718 txn_mc, txn_mt, ret, dev->ver);
719 conf = readl_relaxed(ngd);
720 stat = readl_relaxed(ngd + NGD_STATUS);
721 rx_msgq = readl_relaxed(ngd + NGD_RX_MSGQ_CFG);
722 int_stat = readl_relaxed(ngd + NGD_INT_STAT);
723 int_en = readl_relaxed(ngd + NGD_INT_EN);
724 int_clr = readl_relaxed(ngd + NGD_INT_CLR);
725
726 SLIM_WARN(dev, "conf:0x%x,stat:0x%x,rxmsgq:0x%x\n",
727 conf, stat, rx_msgq);
728 SLIM_ERR(dev, "int_stat:0x%x,int_en:0x%x,int_cll:0x%x\n",
729 int_stat, int_en, int_clr);
730 }
731
732 if (txn_mt == SLIM_MSG_MT_DEST_REFERRED_USER &&
733 (txn_mc == SLIM_USR_MC_CONNECT_SRC ||
734 txn_mc == SLIM_USR_MC_CONNECT_SINK ||
735 txn_mc == SLIM_USR_MC_DISCONNECT_PORT)) {
736 int timeout;
737 unsigned long flags;
738
739 mutex_unlock(&dev->tx_lock);
740 msm_slim_put_ctrl(dev);
741 if (!ret) {
742 timeout = wait_for_completion_timeout(txn->comp, HZ);
743 /* remote side did not acknowledge */
744 if (!timeout)
745 ret = -EREMOTEIO;
746 else
747 ret = txn->ec;
748 }
749 if (ret) {
750 SLIM_ERR(dev,
751 "connect/disconnect:0x%x,tid:%d err:%d\n",
752 txn->mc, txn->tid, ret);
753 spin_lock_irqsave(&ctrl->txn_lock, flags);
754 ctrl->txnt[txn->tid] = NULL;
755 spin_unlock_irqrestore(&ctrl->txn_lock, flags);
756 }
757 return ret ? ret : dev->err;
758 }
759ngd_xfer_err:
760 if (!report_sat) {
761 mutex_unlock(&dev->tx_lock);
762 msm_slim_put_ctrl(dev);
763 }
764 return ret ? ret : dev->err;
765}
766
767static int ngd_get_ec(u16 start_offset, u8 len, u16 *ec)
768{
769 if (len > SLIM_MAX_VE_SLC_BYTES ||
770 start_offset > MSM_SLIM_VE_MAX_MAP_ADDR)
771 return -EINVAL;
772 if (len <= 4) {
773 *ec = len - 1;
774 } else if (len <= 8) {
775 if (len & 0x1)
776 return -EINVAL;
777 *ec = ((len >> 1) + 1);
778 } else {
779 if (len & 0x3)
780 return -EINVAL;
781 *ec = ((len >> 2) + 3);
782 }
783 *ec |= (0x8 | ((start_offset & 0xF) << 4));
784 *ec |= ((start_offset & 0xFF0) << 4);
785 return 0;
786}
787
788static int ngd_user_msg(struct slim_controller *ctrl, u8 la, u8 mt, u8 mc,
789 struct slim_ele_access *msg, u8 *buf, u8 len)
790{
791 int ret;
792 struct slim_msg_txn txn;
793
794 if (mt != SLIM_MSG_MT_DEST_REFERRED_USER ||
795 mc != SLIM_USR_MC_REPEAT_CHANGE_VALUE) {
796 return -EPROTONOSUPPORT;
797 }
798
799 ret = ngd_get_ec(msg->start_offset, len, &txn.ec);
800 if (ret)
801 return ret;
802 txn.la = la;
803 txn.mt = mt;
804 txn.mc = mc;
805 txn.dt = SLIM_MSG_DEST_LOGICALADDR;
806 txn.len = len;
807 txn.rl = len + 6;
808 txn.wbuf = buf;
809 txn.rbuf = NULL;
810 txn.comp = msg->comp;
811 return ngd_xfer_msg(ctrl, &txn);
812}
813
814static int ngd_bulk_cb(void *ctx, int err)
815{
816 if (ctx)
817 complete(ctx);
818 return err;
819}
820
821static int ngd_bulk_wr(struct slim_controller *ctrl, u8 la, u8 mt, u8 mc,
822 struct slim_val_inf msgs[], int n,
823 int (*comp_cb)(void *ctx, int err), void *ctx)
824{
825 struct msm_slim_ctrl *dev = slim_get_ctrldata(ctrl);
826 int i, ret;
827 struct msm_slim_endp *endpoint = &dev->tx_msgq;
828 u32 *header;
829 DECLARE_COMPLETION_ONSTACK(done);
830
831 ret = msm_slim_get_ctrl(dev);
832 mutex_lock(&dev->tx_lock);
833
834 if ((pm_runtime_enabled(dev->dev) && ret < 0) ||
835 dev->state >= MSM_CTRL_ASLEEP) {
836 SLIM_WARN(dev, "vote failed/SSR in-progress ret:%d, state:%d",
837 ret, dev->state);
838 pm_runtime_set_suspended(dev->dev);
839 mutex_unlock(&dev->tx_lock);
840 msm_slim_put_ctrl(dev);
841 return -EREMOTEIO;
842 }
843 if (!pm_runtime_enabled(dev->dev) && dev->state == MSM_CTRL_ASLEEP) {
844 mutex_unlock(&dev->tx_lock);
845 ret = ngd_slim_runtime_resume(dev->dev);
846
847 if (ret) {
848 SLIM_ERR(dev, "slim resume failed ret:%d, state:%d",
849 ret, dev->state);
850 return -EREMOTEIO;
851 }
852 mutex_lock(&dev->tx_lock);
853 }
854
855 ret = ngd_check_hw_status(dev);
856 if (ret) {
857 mutex_unlock(&dev->tx_lock);
858 msm_slim_put_ctrl(dev);
859 return ret;
860 }
861
862 if (dev->use_tx_msgqs != MSM_MSGQ_ENABLED) {
863 SLIM_WARN(dev, "bulk wr not supported");
864 ret = -EPROTONOSUPPORT;
865 goto retpath;
866 }
867 if (dev->bulk.in_progress) {
868 SLIM_WARN(dev, "bulk wr in progress:");
869 ret = -EAGAIN;
870 goto retpath;
871 }
872 dev->bulk.in_progress = true;
873 /* every txn has 5 bytes of overhead: la, mc, mt, ec, len */
874 dev->bulk.size = n * 5;
875 for (i = 0; i < n; i++) {
876 dev->bulk.size += msgs[i].num_bytes;
877 dev->bulk.size += (4 - ((msgs[i].num_bytes + 1) & 0x3));
878 }
879
880 if (dev->bulk.size > 0xffff) {
881 SLIM_WARN(dev, "len exceeds limit, split bulk and retry");
882 ret = -EDQUOT;
883 goto retpath;
884 }
885 if (dev->bulk.size > dev->bulk.buf_sz) {
886 void *temp = krealloc(dev->bulk.base, dev->bulk.size,
887 GFP_KERNEL | GFP_DMA);
888 if (!temp) {
889 ret = -ENOMEM;
890 goto retpath;
891 }
892 dev->bulk.base = temp;
893 dev->bulk.buf_sz = dev->bulk.size;
894 }
895
896 header = dev->bulk.base;
897 for (i = 0; i < n; i++) {
898 u8 *buf = (u8 *)header;
899 int rl = msgs[i].num_bytes + 5;
900 u16 ec;
901
902 *header = SLIM_MSG_ASM_FIRST_WORD(rl, mt, mc, 0, la);
903 buf += 3;
904 ret = ngd_get_ec(msgs[i].start_offset, msgs[i].num_bytes, &ec);
905 if (ret)
906 goto retpath;
907 *(buf++) = (ec & 0xFF);
908 *(buf++) = (ec >> 8) & 0xFF;
909 memcpy(buf, msgs[i].wbuf, msgs[i].num_bytes);
910 buf += msgs[i].num_bytes;
911 header += (rl >> 2);
912 if (rl & 3) {
913 header++;
914 memset(buf, 0, ((u8 *)header - buf));
915 }
916 }
917 header = dev->bulk.base;
918 if (comp_cb) {
919 dev->bulk.cb = comp_cb;
920 dev->bulk.ctx = ctx;
921 } else {
922 dev->bulk.cb = ngd_bulk_cb;
923 dev->bulk.ctx = &done;
924 }
925 dev->bulk.wr_dma = dma_map_single(dev->dev, dev->bulk.base,
926 dev->bulk.size, DMA_TO_DEVICE);
927 if (dma_mapping_error(dev->dev, dev->bulk.wr_dma)) {
928 ret = -ENOMEM;
929 goto retpath;
930 }
931
932 ret = sps_transfer_one(endpoint->sps, dev->bulk.wr_dma, dev->bulk.size,
933 NULL, SPS_IOVEC_FLAG_EOT);
934 if (ret) {
935 SLIM_WARN(dev, "sps transfer one returned error:%d", ret);
936 goto retpath;
937 }
938 if (dev->bulk.cb == ngd_bulk_cb) {
939 int timeout = wait_for_completion_timeout(&done, HZ);
940
941 if (!timeout) {
942 SLIM_WARN(dev, "timeout for bulk wr");
943 dma_unmap_single(dev->dev, dev->bulk.wr_dma,
944 dev->bulk.size, DMA_TO_DEVICE);
945 ret = -ETIMEDOUT;
946 }
947 }
948retpath:
949 if (ret) {
950 dev->bulk.in_progress = false;
951 dev->bulk.ctx = NULL;
952 dev->bulk.wr_dma = 0;
953 slim_reinit_tx_msgq(dev);
954 }
955 mutex_unlock(&dev->tx_lock);
956 msm_slim_put_ctrl(dev);
957 return ret;
958}
959
960static int ngd_xferandwait_ack(struct slim_controller *ctrl,
961 struct slim_msg_txn *txn)
962{
963 struct msm_slim_ctrl *dev = slim_get_ctrldata(ctrl);
964 unsigned long flags;
965 int ret;
966
967 if (dev->state == MSM_CTRL_DOWN) {
968 /*
969 * no need to send anything to the bus due to SSR
970 * transactions related to channel removal marked as success
971 * since HW is down
972 */
973 if ((txn->mt == SLIM_MSG_MT_DEST_REFERRED_USER) &&
974 ((txn->mc >= SLIM_USR_MC_CHAN_CTRL &&
975 txn->mc <= SLIM_USR_MC_REQ_BW) ||
976 txn->mc == SLIM_USR_MC_DISCONNECT_PORT)) {
977 spin_lock_irqsave(&ctrl->txn_lock, flags);
978 ctrl->txnt[txn->tid] = NULL;
979 spin_unlock_irqrestore(&ctrl->txn_lock, flags);
980 return 0;
981 }
982 }
983
984 ret = ngd_xfer_msg(ctrl, txn);
985 if (!ret) {
986 int timeout;
987
988 timeout = wait_for_completion_timeout(txn->comp, HZ);
989 if (!timeout)
990 ret = -ETIMEDOUT;
991 else
992 ret = txn->ec;
993 }
994
995 if (ret) {
996 if (ret != -EREMOTEIO || txn->mc != SLIM_USR_MC_CHAN_CTRL)
997 SLIM_ERR(dev, "master msg:0x%x,tid:%d ret:%d\n",
998 txn->mc, txn->tid, ret);
999 spin_lock_irqsave(&ctrl->txn_lock, flags);
1000 ctrl->txnt[txn->tid] = NULL;
1001 spin_unlock_irqrestore(&ctrl->txn_lock, flags);
1002 }
1003
1004 return ret;
1005}
1006
1007static int ngd_allocbw(struct slim_device *sb, int *subfrmc, int *clkgear)
1008{
1009 int ret = 0, num_chan = 0;
1010 struct slim_pending_ch *pch;
1011 struct slim_msg_txn txn;
1012 struct slim_controller *ctrl = sb->ctrl;
1013 DECLARE_COMPLETION_ONSTACK(done);
1014 u8 wbuf[SLIM_MSGQ_BUF_LEN];
1015 struct msm_slim_ctrl *dev = slim_get_ctrldata(ctrl);
1016
1017 *clkgear = ctrl->clkgear;
1018 *subfrmc = 0;
1019 txn.mt = SLIM_MSG_MT_DEST_REFERRED_USER;
1020 txn.dt = SLIM_MSG_DEST_LOGICALADDR;
1021 txn.la = SLIM_LA_MGR;
1022 txn.len = 0;
1023 txn.ec = 0;
1024 txn.wbuf = wbuf;
1025 txn.rbuf = NULL;
1026
1027 if (ctrl->sched.msgsl != ctrl->sched.pending_msgsl) {
1028 SLIM_DBG(dev, "slim reserve BW for messaging: req: %d\n",
1029 ctrl->sched.pending_msgsl);
1030 txn.mc = SLIM_USR_MC_REQ_BW;
1031 wbuf[txn.len++] = ((sb->laddr & 0x1f) |
1032 ((u8)(ctrl->sched.pending_msgsl & 0x7) << 5));
1033 wbuf[txn.len++] = (u8)(ctrl->sched.pending_msgsl >> 3);
1034 ret = ngd_get_tid(ctrl, &txn, &wbuf[txn.len++], &done);
1035 if (ret)
1036 return ret;
1037 txn.rl = txn.len + 4;
1038 ret = ngd_xferandwait_ack(ctrl, &txn);
1039 if (ret)
1040 return ret;
1041
1042 txn.mc = SLIM_USR_MC_RECONFIG_NOW;
1043 txn.len = 2;
1044 wbuf[1] = sb->laddr;
1045 txn.rl = txn.len + 4;
1046 ret = ngd_get_tid(ctrl, &txn, &wbuf[0], &done);
1047 if (ret)
1048 return ret;
1049 ret = ngd_xferandwait_ack(ctrl, &txn);
1050 if (ret)
1051 return ret;
1052
1053 txn.len = 0;
1054 }
1055 list_for_each_entry(pch, &sb->mark_define, pending) {
1056 struct slim_ich *slc;
1057
1058 slc = &ctrl->chans[pch->chan];
1059 if (!slc) {
1060 SLIM_WARN(dev, "no channel in define?\n");
1061 return -ENXIO;
1062 }
1063 if (txn.len == 0) {
1064 /* Per protocol, only last 5 bits for client no. */
1065 wbuf[txn.len++] = (u8) (slc->prop.dataf << 5) |
1066 (sb->laddr & 0x1f);
1067 wbuf[txn.len] = slc->prop.sampleszbits >> 2;
1068 if (slc->srch && slc->prop.prot == SLIM_PUSH)
1069 slc->prop.prot = SLIM_PULL;
1070 if (slc->coeff == SLIM_COEFF_3)
1071 wbuf[txn.len] |= 1 << 5;
1072 wbuf[txn.len++] |= slc->prop.auxf << 6;
1073 wbuf[txn.len++] = slc->rootexp << 4 | slc->prop.prot;
1074 wbuf[txn.len++] = slc->prrate;
1075 ret = ngd_get_tid(ctrl, &txn, &wbuf[txn.len++], &done);
1076 if (ret) {
1077 SLIM_WARN(dev, "no tid for channel define?\n");
1078 return -ENXIO;
1079 }
1080 }
1081 num_chan++;
1082 wbuf[txn.len++] = slc->chan;
1083 SLIM_INFO(dev, "slim activate chan:%d, laddr: 0x%x\n",
1084 slc->chan, sb->laddr);
1085 }
1086 if (txn.len) {
1087 txn.mc = SLIM_USR_MC_DEF_ACT_CHAN;
1088 txn.rl = txn.len + 4;
1089 ret = ngd_xferandwait_ack(ctrl, &txn);
1090 if (ret)
1091 return ret;
1092
1093 txn.mc = SLIM_USR_MC_RECONFIG_NOW;
1094 txn.len = 2;
1095 wbuf[1] = sb->laddr;
1096 txn.rl = txn.len + 4;
1097 ret = ngd_get_tid(ctrl, &txn, &wbuf[0], &done);
1098 if (ret)
1099 return ret;
1100 ret = ngd_xferandwait_ack(ctrl, &txn);
1101 if (ret)
1102 return ret;
1103 }
1104 txn.len = 0;
1105 list_for_each_entry(pch, &sb->mark_removal, pending) {
1106 struct slim_ich *slc;
1107
1108 slc = &ctrl->chans[pch->chan];
1109 if (!slc) {
1110 SLIM_WARN(dev, "no channel in removal?\n");
1111 return -ENXIO;
1112 }
1113 if (txn.len == 0) {
1114 /* Per protocol, only last 5 bits for client no. */
1115 wbuf[txn.len++] = (u8) (SLIM_CH_REMOVE << 6) |
1116 (sb->laddr & 0x1f);
1117 ret = ngd_get_tid(ctrl, &txn, &wbuf[txn.len++], &done);
1118 if (ret) {
1119 SLIM_WARN(dev, "no tid for channel define?\n");
1120 return -ENXIO;
1121 }
1122 }
1123 wbuf[txn.len++] = slc->chan;
1124 SLIM_INFO(dev, "slim remove chan:%d, laddr: 0x%x\n",
1125 slc->chan, sb->laddr);
1126 }
1127 if (txn.len) {
1128 txn.mc = SLIM_USR_MC_CHAN_CTRL;
1129 txn.rl = txn.len + 4;
1130 ret = ngd_xferandwait_ack(ctrl, &txn);
1131 /* HW restarting, channel removal should succeed */
1132 if (ret == -EREMOTEIO)
1133 return 0;
1134 else if (ret)
1135 return ret;
1136
1137 txn.mc = SLIM_USR_MC_RECONFIG_NOW;
1138 txn.len = 2;
1139 wbuf[1] = sb->laddr;
1140 txn.rl = txn.len + 4;
1141 ret = ngd_get_tid(ctrl, &txn, &wbuf[0], &done);
1142 if (ret)
1143 return ret;
1144 ret = ngd_xferandwait_ack(ctrl, &txn);
1145 if (ret)
1146 return ret;
1147 txn.len = 0;
1148 }
1149 return 0;
1150}
1151
1152static int ngd_set_laddr(struct slim_controller *ctrl, const u8 *ea,
1153 u8 elen, u8 laddr)
1154{
1155 return 0;
1156}
1157
1158static int ngd_get_laddr(struct slim_controller *ctrl, const u8 *ea,
1159 u8 elen, u8 *laddr)
1160{
1161 int ret;
1162 u8 wbuf[10];
1163 struct slim_msg_txn txn;
1164 DECLARE_COMPLETION_ONSTACK(done);
1165
1166 txn.mt = SLIM_MSG_MT_DEST_REFERRED_USER;
1167 txn.dt = SLIM_MSG_DEST_LOGICALADDR;
1168 txn.la = SLIM_LA_MGR;
1169 txn.ec = 0;
1170 ret = ngd_get_tid(ctrl, &txn, &wbuf[0], &done);
1171 if (ret)
1172 return ret;
1173 memcpy(&wbuf[1], ea, elen);
1174 txn.mc = SLIM_USR_MC_ADDR_QUERY;
1175 txn.rl = 11;
1176 txn.len = 7;
1177 txn.wbuf = wbuf;
1178 txn.rbuf = NULL;
1179 ret = ngd_xferandwait_ack(ctrl, &txn);
1180 if (!ret && txn.la == 0xFF)
1181 ret = -ENXIO;
1182 else if (!ret)
1183 *laddr = txn.la;
1184 return ret;
1185}
1186
1187static void ngd_slim_setup(struct msm_slim_ctrl *dev)
1188{
1189 u32 new_cfg = NGD_CFG_ENABLE;
1190 u32 cfg = readl_relaxed(dev->base +
1191 NGD_BASE(dev->ctrl.nr, dev->ver));
1192 if (dev->state == MSM_CTRL_DOWN) {
1193 /* if called after SSR, cleanup and re-assign */
1194 if (dev->use_tx_msgqs != MSM_MSGQ_RESET)
1195 msm_slim_deinit_ep(dev, &dev->tx_msgq,
1196 &dev->use_tx_msgqs);
1197
1198 if (dev->use_rx_msgqs != MSM_MSGQ_RESET)
1199 msm_slim_deinit_ep(dev, &dev->rx_msgq,
1200 &dev->use_rx_msgqs);
1201
1202 msm_slim_sps_init(dev, dev->bam_mem,
1203 NGD_BASE(dev->ctrl.nr,
1204 dev->ver) + NGD_STATUS, true);
1205 } else {
1206 if (dev->use_rx_msgqs == MSM_MSGQ_DISABLED)
1207 goto setup_tx_msg_path;
1208
1209 if ((dev->use_rx_msgqs == MSM_MSGQ_ENABLED) &&
1210 (cfg & NGD_CFG_RX_MSGQ_EN))
1211 goto setup_tx_msg_path;
1212
1213 if (dev->use_rx_msgqs == MSM_MSGQ_ENABLED)
1214 msm_slim_disconnect_endp(dev, &dev->rx_msgq,
1215 &dev->use_rx_msgqs);
1216 msm_slim_connect_endp(dev, &dev->rx_msgq);
1217
1218setup_tx_msg_path:
1219 if (dev->use_tx_msgqs == MSM_MSGQ_DISABLED)
1220 goto ngd_enable;
1221 if (dev->use_tx_msgqs == MSM_MSGQ_ENABLED &&
1222 cfg & NGD_CFG_TX_MSGQ_EN)
1223 goto ngd_enable;
1224
1225 if (dev->use_tx_msgqs == MSM_MSGQ_ENABLED)
1226 msm_slim_disconnect_endp(dev, &dev->tx_msgq,
1227 &dev->use_tx_msgqs);
1228 msm_slim_connect_endp(dev, &dev->tx_msgq);
1229 }
1230ngd_enable:
1231
1232 if (dev->use_rx_msgqs == MSM_MSGQ_ENABLED)
1233 new_cfg |= NGD_CFG_RX_MSGQ_EN;
1234 if (dev->use_tx_msgqs == MSM_MSGQ_ENABLED)
1235 new_cfg |= NGD_CFG_TX_MSGQ_EN;
1236
1237 /* Enable NGD, and program MSGQs if not already */
1238 if (cfg == new_cfg)
1239 return;
1240
1241 writel_relaxed(new_cfg, dev->base + NGD_BASE(dev->ctrl.nr, dev->ver));
1242 /* make sure NGD MSG-Q config goes through */
1243 mb();
1244}
1245
1246static void ngd_slim_rx(struct msm_slim_ctrl *dev, u8 *buf)
1247{
1248 unsigned long flags;
1249 u8 mc, mt, len;
1250
1251 len = buf[0] & 0x1F;
1252 mt = (buf[0] >> 5) & 0x7;
1253 mc = buf[1];
1254 if (mc == SLIM_USR_MC_MASTER_CAPABILITY &&
1255 mt == SLIM_MSG_MT_SRC_REFERRED_USER)
1256 complete(&dev->rx_msgq_notify);
1257
1258 if (mc == SLIM_MSG_MC_REPLY_INFORMATION ||
1259 mc == SLIM_MSG_MC_REPLY_VALUE) {
1260 u8 tid = buf[3];
1261
1262 dev_dbg(dev->dev, "tid:%d, len:%d\n", tid, len);
1263 slim_msg_response(&dev->ctrl, &buf[4], tid,
1264 len - 4);
1265 pm_runtime_mark_last_busy(dev->dev);
1266 }
1267 if (mc == SLIM_USR_MC_ADDR_REPLY &&
1268 mt == SLIM_MSG_MT_SRC_REFERRED_USER) {
1269 struct slim_msg_txn *txn;
1270 u8 failed_ea[6] = {0, 0, 0, 0, 0, 0};
1271
1272 spin_lock_irqsave(&dev->ctrl.txn_lock, flags);
1273 txn = dev->ctrl.txnt[buf[3]];
1274 if (!txn) {
1275 spin_unlock_irqrestore(&dev->ctrl.txn_lock, flags);
1276 SLIM_WARN(dev,
1277 "LADDR response after timeout, tid:0x%x\n",
1278 buf[3]);
1279 return;
1280 }
1281 if (memcmp(&buf[4], failed_ea, 6))
1282 txn->la = buf[10];
1283 dev->ctrl.txnt[buf[3]] = NULL;
1284 complete(txn->comp);
1285 spin_unlock_irqrestore(&dev->ctrl.txn_lock, flags);
1286 }
1287 if (mc == SLIM_USR_MC_GENERIC_ACK &&
1288 mt == SLIM_MSG_MT_SRC_REFERRED_USER) {
1289 struct slim_msg_txn *txn;
1290
1291 spin_lock_irqsave(&dev->ctrl.txn_lock, flags);
1292 txn = dev->ctrl.txnt[buf[3]];
1293 if (!txn) {
1294 spin_unlock_irqrestore(&dev->ctrl.txn_lock, flags);
1295 SLIM_WARN(dev, "ACK received after timeout, tid:0x%x\n",
1296 buf[3]);
1297 return;
1298 }
1299 dev_dbg(dev->dev, "got response:tid:%d, response:0x%x",
1300 (int)buf[3], buf[4]);
1301 if (!(buf[4] & MSM_SAT_SUCCSS)) {
1302 SLIM_WARN(dev, "TID:%d, NACK code:0x%x\n", (int)buf[3],
1303 buf[4]);
1304 txn->ec = -EIO;
1305 }
1306 dev->ctrl.txnt[buf[3]] = NULL;
1307 complete(txn->comp);
1308 spin_unlock_irqrestore(&dev->ctrl.txn_lock, flags);
1309 }
1310}
1311
1312static int ngd_slim_power_up(struct msm_slim_ctrl *dev, bool mdm_restart)
1313{
1314 void __iomem *ngd;
1315 int timeout, retries = 0, ret = 0;
1316 enum msm_ctrl_state cur_state = dev->state;
1317 u32 laddr;
1318 u32 rx_msgq;
1319 u32 ngd_int = (NGD_INT_TX_NACKED_2 |
1320 NGD_INT_MSG_BUF_CONTE | NGD_INT_MSG_TX_INVAL |
1321 NGD_INT_IE_VE_CHG | NGD_INT_DEV_ERR |
1322 NGD_INT_TX_MSG_SENT);
1323
1324 if (!mdm_restart && cur_state == MSM_CTRL_DOWN) {
1325 int timeout = wait_for_completion_timeout(&dev->qmi.qmi_comp,
1326 HZ);
1327 if (!timeout) {
1328 SLIM_ERR(dev, "slimbus QMI init timed out\n");
1329 return -EREMOTEIO;
1330 }
1331 }
1332
1333hw_init_retry:
1334 /* No need to vote if contorller is not in low power mode */
1335 if (!mdm_restart &&
1336 (cur_state == MSM_CTRL_DOWN || cur_state == MSM_CTRL_ASLEEP)) {
1337 ret = msm_slim_qmi_power_request(dev, true);
1338 if (ret) {
1339 SLIM_WARN(dev, "SLIM power req failed:%d, retry:%d\n",
1340 ret, retries);
1341 if (!atomic_read(&dev->ssr_in_progress))
1342 msm_slim_qmi_power_request(dev, false);
1343 if (retries < INIT_MX_RETRIES &&
1344 !atomic_read(&dev->ssr_in_progress)) {
1345 retries++;
1346 goto hw_init_retry;
1347 }
1348 return ret;
1349 }
1350 }
1351 retries = 0;
1352
1353 if (!dev->ver) {
1354 dev->ver = readl_relaxed(dev->base);
1355 /* Version info in 16 MSbits */
1356 dev->ver >>= 16;
1357 }
1358 ngd = dev->base + NGD_BASE(dev->ctrl.nr, dev->ver);
1359 laddr = readl_relaxed(ngd + NGD_STATUS);
1360 if (laddr & NGD_LADDR) {
1361 u32 int_en = readl_relaxed(ngd + NGD_INT_EN);
1362
1363 /*
1364 * external MDM restart case where ADSP itself was active framer
1365 * For example, modem restarted when playback was active
1366 */
1367 if (cur_state == MSM_CTRL_AWAKE) {
1368 SLIM_INFO(dev, "Subsys restart: ADSP active framer\n");
1369 return 0;
1370 }
1371 /*
1372 * ADSP power collapse case, where HW wasn't reset.
1373 */
1374 if (int_en != 0)
1375 return 0;
1376
1377 /* Retention */
1378 if (dev->use_rx_msgqs == MSM_MSGQ_ENABLED)
1379 msm_slim_disconnect_endp(dev, &dev->rx_msgq,
1380 &dev->use_rx_msgqs);
1381 if (dev->use_tx_msgqs == MSM_MSGQ_ENABLED)
1382 msm_slim_disconnect_endp(dev, &dev->tx_msgq,
1383 &dev->use_tx_msgqs);
1384
1385 writel_relaxed(ngd_int, (dev->base + NGD_INT_EN +
1386 NGD_BASE(dev->ctrl.nr, dev->ver)));
1387
1388 rx_msgq = readl_relaxed(ngd + NGD_RX_MSGQ_CFG);
1389 /**
1390 * Program with minimum value so that signal get
1391 * triggered immediately after receiving the message
1392 */
1393 writel_relaxed((rx_msgq | SLIM_RX_MSGQ_TIMEOUT_VAL),
1394 (ngd + NGD_RX_MSGQ_CFG));
1395 /* reconnect BAM pipes if needed and enable NGD */
1396 ngd_slim_setup(dev);
1397 return 0;
1398 }
1399
1400 if (mdm_restart) {
1401 /*
1402 * external MDM SSR when MDM is active framer
1403 * ADSP will reset slimbus HW. disconnect BAM pipes so that
1404 * they can be connected after capability message is received.
1405 * Set device state to ASLEEP to be synchronous with the HW
1406 */
1407 /* make current state as DOWN */
1408 cur_state = MSM_CTRL_DOWN;
1409 SLIM_INFO(dev,
1410 "SLIM MDM restart: MDM active framer: reinit HW\n");
1411 /* disconnect BAM pipes */
1412 msm_slim_sps_exit(dev, false);
1413 dev->state = MSM_CTRL_DOWN;
1414 }
1415
1416capability_retry:
1417 /*
1418 * ADSP power collapse case (OR SSR), where HW was reset
1419 * BAM programming will happen when capability message is received
1420 */
1421 writel_relaxed(ngd_int, dev->base + NGD_INT_EN +
1422 NGD_BASE(dev->ctrl.nr, dev->ver));
1423
1424 rx_msgq = readl_relaxed(ngd + NGD_RX_MSGQ_CFG);
1425 /*
1426 * Program with minimum value so that signal get
1427 * triggered immediately after receiving the message
1428 */
1429 writel_relaxed(rx_msgq|SLIM_RX_MSGQ_TIMEOUT_VAL,
1430 ngd + NGD_RX_MSGQ_CFG);
1431 /* make sure register got updated */
1432 mb();
1433
1434 /* reconnect BAM pipes if needed and enable NGD */
1435 ngd_slim_setup(dev);
1436
1437 timeout = wait_for_completion_timeout(&dev->reconf, HZ);
1438 if (!timeout) {
1439 u32 cfg = readl_relaxed(dev->base +
1440 NGD_BASE(dev->ctrl.nr, dev->ver));
1441 laddr = readl_relaxed(ngd + NGD_STATUS);
1442 SLIM_WARN(dev,
1443 "slim capability time-out:%d, stat:0x%x,cfg:0x%x\n",
1444 retries, laddr, cfg);
1445 if ((retries < INIT_MX_RETRIES) &&
1446 !atomic_read(&dev->ssr_in_progress)) {
1447 retries++;
1448 goto capability_retry;
1449 }
1450 return -ETIMEDOUT;
1451 }
1452 /* mutliple transactions waiting on slimbus to power up? */
1453 if (cur_state == MSM_CTRL_DOWN)
1454 complete_all(&dev->ctrl_up);
1455 /* Resetting the log level */
1456 SLIM_RST_LOGLVL(dev);
1457 return 0;
1458}
1459
1460static int ngd_slim_enable(struct msm_slim_ctrl *dev, bool enable)
1461{
1462 int ret = 0;
1463
1464 if (enable) {
1465 ret = msm_slim_qmi_init(dev, false);
1466 /* controller state should be in sync with framework state */
1467 if (!ret) {
1468 complete(&dev->qmi.qmi_comp);
1469 if (!pm_runtime_enabled(dev->dev) ||
1470 !pm_runtime_suspended(dev->dev))
1471 ngd_slim_runtime_resume(dev->dev);
1472 else
1473 pm_runtime_resume(dev->dev);
1474 pm_runtime_mark_last_busy(dev->dev);
1475 pm_runtime_put(dev->dev);
1476 } else
1477 SLIM_ERR(dev, "qmi init fail, ret:%d, state:%d\n",
1478 ret, dev->state);
1479 } else {
1480 msm_slim_qmi_exit(dev);
1481 }
1482
1483 return ret;
1484}
1485
1486#ifdef CONFIG_PM
1487static int ngd_slim_power_down(struct msm_slim_ctrl *dev)
1488{
1489 unsigned long flags;
1490 int i;
1491 struct slim_controller *ctrl = &dev->ctrl;
1492
1493 spin_lock_irqsave(&ctrl->txn_lock, flags);
1494 /* Pending response for a message */
1495 for (i = 0; i < ctrl->last_tid; i++) {
1496 if (ctrl->txnt[i]) {
1497 spin_unlock_irqrestore(&ctrl->txn_lock, flags);
1498 SLIM_INFO(dev, "NGD down:txn-rsp for %d pending", i);
1499 return -EBUSY;
1500 }
1501 }
1502 spin_unlock_irqrestore(&ctrl->txn_lock, flags);
1503 return msm_slim_qmi_power_request(dev, false);
1504}
1505#endif
1506
1507static int ngd_slim_rx_msgq_thread(void *data)
1508{
1509 struct msm_slim_ctrl *dev = (struct msm_slim_ctrl *)data;
1510 struct completion *notify = &dev->rx_msgq_notify;
1511 int ret = 0;
1512
1513 while (!kthread_should_stop()) {
1514 struct slim_msg_txn txn;
1515 int retries = 0;
1516 u8 wbuf[8];
1517
1518 wait_for_completion_interruptible(notify);
1519
1520 txn.dt = SLIM_MSG_DEST_LOGICALADDR;
1521 txn.ec = 0;
1522 txn.rbuf = NULL;
1523 txn.mc = SLIM_USR_MC_REPORT_SATELLITE;
1524 txn.mt = SLIM_MSG_MT_SRC_REFERRED_USER;
1525 txn.la = SLIM_LA_MGR;
1526 wbuf[0] = SAT_MAGIC_LSB;
1527 wbuf[1] = SAT_MAGIC_MSB;
1528 wbuf[2] = SAT_MSG_VER;
1529 wbuf[3] = SAT_MSG_PROT;
1530 txn.wbuf = wbuf;
1531 txn.len = 4;
1532 SLIM_INFO(dev, "SLIM SAT: Rcvd master capability\n");
1533capability_retry:
1534 txn.rl = 8;
1535 ret = ngd_xfer_msg(&dev->ctrl, &txn);
1536 if (!ret) {
1537 enum msm_ctrl_state prev_state = dev->state;
1538
1539 SLIM_INFO(dev,
1540 "SLIM SAT: capability exchange successful\n");
1541 if (prev_state < MSM_CTRL_ASLEEP)
1542 SLIM_WARN(dev,
1543 "capability due to noise, state:%d\n",
1544 prev_state);
1545 complete(&dev->reconf);
1546 /* ADSP SSR, send device_up notifications */
1547 if (prev_state == MSM_CTRL_DOWN)
1548 complete(&dev->qmi.slave_notify);
1549 } else if (ret == -EIO) {
1550 SLIM_WARN(dev, "capability message NACKed, retrying\n");
1551 if (retries < INIT_MX_RETRIES) {
1552 msleep(DEF_RETRY_MS);
1553 retries++;
1554 goto capability_retry;
1555 }
1556 } else {
1557 SLIM_WARN(dev, "SLIM: capability TX failed:%d\n", ret);
1558 }
1559 }
1560 return 0;
1561}
1562
1563static int ngd_notify_slaves(void *data)
1564{
1565 struct msm_slim_ctrl *dev = (struct msm_slim_ctrl *)data;
1566 struct slim_controller *ctrl = &dev->ctrl;
1567 struct slim_device *sbdev;
1568 struct list_head *pos, *next;
1569 int ret, i = 0;
1570
1571 ret = qmi_svc_event_notifier_register(SLIMBUS_QMI_SVC_ID,
1572 SLIMBUS_QMI_SVC_V1,
1573 SLIMBUS_QMI_INS_ID, &dev->qmi.nb);
1574 if (ret) {
1575 pr_err("Slimbus QMI service registration failed:%d", ret);
1576 return ret;
1577 }
1578
1579 while (!kthread_should_stop()) {
1580 wait_for_completion_interruptible(&dev->qmi.slave_notify);
1581 /* Probe devices for first notification */
1582 if (!i) {
1583 i++;
1584 dev->err = 0;
1585 if (dev->dev->of_node)
1586 of_register_slim_devices(&dev->ctrl);
1587
1588 /*
1589 * Add devices registered with board-info now that
1590 * controller is up
1591 */
1592 slim_ctrl_add_boarddevs(&dev->ctrl);
1593 ngd_dom_init(dev);
1594 } else {
1595 slim_framer_booted(ctrl);
1596 }
1597 mutex_lock(&ctrl->m_ctrl);
1598 list_for_each_safe(pos, next, &ctrl->devs) {
1599 int j;
1600
1601 sbdev = list_entry(pos, struct slim_device, dev_list);
1602 mutex_unlock(&ctrl->m_ctrl);
1603 for (j = 0; j < LADDR_RETRY; j++) {
1604 ret = slim_get_logical_addr(sbdev,
1605 sbdev->e_addr,
1606 6, &sbdev->laddr);
1607 if (!ret)
1608 break;
1609 /* time for ADSP to assign LA */
1610 msleep(20);
1611 }
1612 mutex_lock(&ctrl->m_ctrl);
1613 }
1614 mutex_unlock(&ctrl->m_ctrl);
1615 }
1616 return 0;
1617}
1618
1619static void ngd_dom_down(struct msm_slim_ctrl *dev)
1620{
1621 struct slim_controller *ctrl = &dev->ctrl;
1622 struct slim_device *sbdev;
1623
1624 mutex_lock(&dev->ssr_lock);
1625 ngd_slim_enable(dev, false);
1626 /* device up should be called again after SSR */
1627 list_for_each_entry(sbdev, &ctrl->devs, dev_list)
1628 slim_report_absent(sbdev);
1629 SLIM_INFO(dev, "SLIM ADSP SSR (DOWN) done\n");
1630 mutex_unlock(&dev->ssr_lock);
1631}
1632
1633static void ngd_dom_up(struct work_struct *work)
1634{
1635 struct msm_slim_ss *dsp =
1636 container_of(work, struct msm_slim_ss, dom_up);
1637 struct msm_slim_ctrl *dev =
1638 container_of(dsp, struct msm_slim_ctrl, dsp);
1639 mutex_lock(&dev->ssr_lock);
1640 ngd_slim_enable(dev, true);
1641 mutex_unlock(&dev->ssr_lock);
1642}
1643
1644static ssize_t show_mask(struct device *device, struct device_attribute *attr,
1645 char *buf)
1646{
1647 struct platform_device *pdev = to_platform_device(device);
1648 struct msm_slim_ctrl *dev = platform_get_drvdata(pdev);
1649
1650 return snprintf(buf, sizeof(int), "%u\n", dev->ipc_log_mask);
1651}
1652
1653static ssize_t set_mask(struct device *device, struct device_attribute *attr,
1654 const char *buf, size_t count)
1655{
1656 struct platform_device *pdev = to_platform_device(device);
1657 struct msm_slim_ctrl *dev = platform_get_drvdata(pdev);
1658
1659 dev->ipc_log_mask = buf[0] - '0';
1660 if (dev->ipc_log_mask > DBG_LEV)
1661 dev->ipc_log_mask = DBG_LEV;
1662 return count;
1663}
1664
1665static DEVICE_ATTR(debug_mask, 0644, show_mask, set_mask);
1666
1667static int ngd_slim_probe(struct platform_device *pdev)
1668{
1669 struct msm_slim_ctrl *dev;
1670 int ret;
1671 struct resource *bam_mem;
1672 struct resource *slim_mem;
1673 struct resource *irq, *bam_irq;
1674 bool rxreg_access = false;
1675 bool slim_mdm = false;
1676 const char *ext_modem_id = NULL;
1677
1678 slim_mem = platform_get_resource_byname(pdev, IORESOURCE_MEM,
1679 "slimbus_physical");
1680 if (!slim_mem) {
1681 dev_err(&pdev->dev, "no slimbus physical memory resource\n");
1682 return -ENODEV;
1683 }
1684 bam_mem = platform_get_resource_byname(pdev, IORESOURCE_MEM,
1685 "slimbus_bam_physical");
1686 if (!bam_mem) {
1687 dev_err(&pdev->dev, "no slimbus BAM memory resource\n");
1688 return -ENODEV;
1689 }
1690 irq = platform_get_resource_byname(pdev, IORESOURCE_IRQ,
1691 "slimbus_irq");
1692 if (!irq) {
1693 dev_err(&pdev->dev, "no slimbus IRQ resource\n");
1694 return -ENODEV;
1695 }
1696 bam_irq = platform_get_resource_byname(pdev, IORESOURCE_IRQ,
1697 "slimbus_bam_irq");
1698 if (!bam_irq) {
1699 dev_err(&pdev->dev, "no slimbus BAM IRQ resource\n");
1700 return -ENODEV;
1701 }
1702
1703 dev = kzalloc(sizeof(struct msm_slim_ctrl), GFP_KERNEL);
1704 if (IS_ERR_OR_NULL(dev)) {
1705 dev_err(&pdev->dev, "no memory for MSM slimbus controller\n");
1706 return PTR_ERR(dev);
1707 }
1708 dev->wr_comp = kzalloc(sizeof(struct completion *) * MSM_TX_BUFS,
1709 GFP_KERNEL);
Karthikeyan Ramasubramanian26182ce2017-01-17 10:15:00 -07001710 if (!dev->wr_comp) {
1711 ret = -ENOMEM;
1712 goto err_nobulk;
1713 }
Sagar Dhariabe37c9c2016-11-28 23:06:58 -07001714
1715 /* typical txn numbers and size used in bulk operation */
1716 dev->bulk.buf_sz = SLIM_MAX_TXNS * 8;
1717 dev->bulk.base = kzalloc(dev->bulk.buf_sz, GFP_KERNEL | GFP_DMA);
1718 if (!dev->bulk.base) {
1719 ret = -ENOMEM;
1720 goto err_nobulk;
1721 }
1722
1723 dev->dev = &pdev->dev;
1724 platform_set_drvdata(pdev, dev);
1725 slim_set_ctrldata(&dev->ctrl, dev);
1726
1727 /* Create IPC log context */
1728 dev->ipc_slimbus_log = ipc_log_context_create(IPC_SLIMBUS_LOG_PAGES,
1729 dev_name(dev->dev), 0);
1730 if (!dev->ipc_slimbus_log)
1731 dev_err(&pdev->dev, "error creating ipc_logging context\n");
1732 else {
1733 /* Initialize the log mask */
1734 dev->ipc_log_mask = INFO_LEV;
1735 dev->default_ipc_log_mask = INFO_LEV;
1736 SLIM_INFO(dev, "start logging for slim dev %s\n",
1737 dev_name(dev->dev));
1738 }
1739 ret = sysfs_create_file(&dev->dev->kobj, &dev_attr_debug_mask.attr);
1740 if (ret) {
1741 dev_err(&pdev->dev, "Failed to create dev. attr\n");
1742 dev->sysfs_created = false;
1743 } else
1744 dev->sysfs_created = true;
1745
1746 dev->base = ioremap(slim_mem->start, resource_size(slim_mem));
1747 if (!dev->base) {
1748 dev_err(&pdev->dev, "IOremap failed\n");
1749 ret = -ENOMEM;
1750 goto err_ioremap_failed;
1751 }
1752 dev->bam.base = ioremap(bam_mem->start, resource_size(bam_mem));
1753 if (!dev->bam.base) {
1754 dev_err(&pdev->dev, "BAM IOremap failed\n");
1755 ret = -ENOMEM;
1756 goto err_ioremap_bam_failed;
1757 }
1758 if (pdev->dev.of_node) {
1759
1760 ret = of_property_read_u32(pdev->dev.of_node, "cell-index",
1761 &dev->ctrl.nr);
1762 if (ret) {
1763 dev_err(&pdev->dev, "Cell index not specified:%d", ret);
1764 goto err_ctrl_failed;
1765 }
1766 rxreg_access = of_property_read_bool(pdev->dev.of_node,
1767 "qcom,rxreg-access");
1768 of_property_read_u32(pdev->dev.of_node, "qcom,apps-ch-pipes",
1769 &dev->pdata.apps_pipes);
1770 of_property_read_u32(pdev->dev.of_node, "qcom,ea-pc",
1771 &dev->pdata.eapc);
1772 ret = of_property_read_string(pdev->dev.of_node,
1773 "qcom,slim-mdm", &ext_modem_id);
1774 if (!ret)
1775 slim_mdm = true;
1776 } else {
1777 dev->ctrl.nr = pdev->id;
1778 }
1779 /*
1780 * Keep PGD's logical address as manager's. Query it when first data
1781 * channel request comes in
1782 */
1783 dev->pgdla = SLIM_LA_MGR;
1784 dev->ctrl.nchans = MSM_SLIM_NCHANS;
1785 dev->ctrl.nports = MSM_SLIM_NPORTS;
1786 dev->framer.rootfreq = SLIM_ROOT_FREQ >> 3;
1787 dev->framer.superfreq =
1788 dev->framer.rootfreq / SLIM_CL_PER_SUPERFRAME_DIV8;
1789 dev->ctrl.a_framer = &dev->framer;
1790 dev->ctrl.clkgear = SLIM_MAX_CLK_GEAR;
1791 dev->ctrl.set_laddr = ngd_set_laddr;
1792 dev->ctrl.get_laddr = ngd_get_laddr;
1793 dev->ctrl.allocbw = ngd_allocbw;
1794 dev->ctrl.xfer_msg = ngd_xfer_msg;
1795 dev->ctrl.xfer_user_msg = ngd_user_msg;
1796 dev->ctrl.xfer_bulk_wr = ngd_bulk_wr;
1797 dev->ctrl.wakeup = NULL;
1798 dev->ctrl.alloc_port = msm_alloc_port;
1799 dev->ctrl.dealloc_port = msm_dealloc_port;
1800 dev->ctrl.port_xfer = msm_slim_port_xfer;
1801 dev->ctrl.port_xfer_status = msm_slim_port_xfer_status;
1802 dev->bam_mem = bam_mem;
1803 dev->rx_slim = ngd_slim_rx;
1804
1805 init_completion(&dev->reconf);
1806 init_completion(&dev->ctrl_up);
1807 mutex_init(&dev->tx_lock);
1808 mutex_init(&dev->ssr_lock);
1809 spin_lock_init(&dev->tx_buf_lock);
1810 spin_lock_init(&dev->rx_lock);
1811 dev->ee = 1;
1812 dev->irq = irq->start;
1813 dev->bam.irq = bam_irq->start;
1814 atomic_set(&dev->ssr_in_progress, 0);
1815
1816 if (rxreg_access)
1817 dev->use_rx_msgqs = MSM_MSGQ_DISABLED;
1818 else
1819 dev->use_rx_msgqs = MSM_MSGQ_RESET;
1820
1821 /* Enable TX message queues by default as recommended by HW */
1822 dev->use_tx_msgqs = MSM_MSGQ_RESET;
1823
1824 init_completion(&dev->rx_msgq_notify);
1825 init_completion(&dev->qmi.slave_notify);
1826
1827 /* Register with framework */
1828 ret = slim_add_numbered_controller(&dev->ctrl);
1829 if (ret) {
1830 dev_err(dev->dev, "error adding controller\n");
1831 goto err_ctrl_failed;
1832 }
1833
1834 dev->ctrl.dev.parent = &pdev->dev;
1835 dev->ctrl.dev.of_node = pdev->dev.of_node;
1836 dev->state = MSM_CTRL_DOWN;
1837
1838 /*
1839 * As this does not perform expensive
1840 * operations, it can execute in an
1841 * interrupt context. This avoids
1842 * context switches, provides
1843 * extensive benifits and performance
1844 * improvements.
1845 */
1846 ret = request_irq(dev->irq,
1847 ngd_slim_interrupt,
1848 IRQF_TRIGGER_HIGH,
1849 "ngd_slim_irq", dev);
1850
1851 if (ret) {
1852 dev_err(&pdev->dev, "request IRQ failed\n");
1853 goto err_request_irq_failed;
1854 }
1855
1856 init_completion(&dev->qmi.qmi_comp);
1857 dev->err = -EPROBE_DEFER;
1858 pm_runtime_use_autosuspend(dev->dev);
1859 pm_runtime_set_autosuspend_delay(dev->dev, MSM_SLIM_AUTOSUSPEND);
1860 pm_runtime_set_suspended(dev->dev);
1861 pm_runtime_enable(dev->dev);
1862
1863 if (slim_mdm) {
1864 dev->ext_mdm.nb.notifier_call = mdm_ssr_notify_cb;
1865 dev->ext_mdm.domr = subsys_notif_register_notifier(ext_modem_id,
1866 &dev->ext_mdm.nb);
1867 if (IS_ERR_OR_NULL(dev->ext_mdm.domr))
1868 dev_err(dev->dev,
1869 "subsys_notif_register_notifier failed %p",
1870 dev->ext_mdm.domr);
1871 }
1872
1873 INIT_WORK(&dev->dsp.dom_up, ngd_dom_up);
1874 dev->qmi.nb.notifier_call = ngd_qmi_available;
1875 pm_runtime_get_noresume(dev->dev);
1876
1877 /* Fire up the Rx message queue thread */
1878 dev->rx_msgq_thread = kthread_run(ngd_slim_rx_msgq_thread, dev,
1879 "ngd_rx_thread%d", dev->ctrl.nr);
1880 if (IS_ERR(dev->rx_msgq_thread)) {
1881 ret = PTR_ERR(dev->rx_msgq_thread);
1882 dev_err(dev->dev, "Failed to start Rx thread:%d\n", ret);
1883 goto err_rx_thread_create_failed;
1884 }
1885
1886 /* Start thread to probe, and notify slaves */
1887 dev->qmi.slave_thread = kthread_run(ngd_notify_slaves, dev,
1888 "ngd_notify_sl%d", dev->ctrl.nr);
1889 if (IS_ERR(dev->qmi.slave_thread)) {
1890 ret = PTR_ERR(dev->qmi.slave_thread);
1891 dev_err(dev->dev, "Failed to start notifier thread:%d\n", ret);
1892 goto err_notify_thread_create_failed;
1893 }
1894 SLIM_INFO(dev, "NGD SB controller is up!\n");
1895 return 0;
1896
1897err_notify_thread_create_failed:
1898 kthread_stop(dev->rx_msgq_thread);
1899err_rx_thread_create_failed:
1900 free_irq(dev->irq, dev);
1901err_request_irq_failed:
1902err_ctrl_failed:
1903 iounmap(dev->bam.base);
1904err_ioremap_bam_failed:
1905 iounmap(dev->base);
1906err_ioremap_failed:
1907 if (dev->sysfs_created)
1908 sysfs_remove_file(&dev->dev->kobj,
1909 &dev_attr_debug_mask.attr);
1910 kfree(dev->bulk.base);
1911err_nobulk:
1912 kfree(dev->wr_comp);
1913 kfree(dev);
1914 return ret;
1915}
1916
1917static int ngd_slim_remove(struct platform_device *pdev)
1918{
1919 struct msm_slim_ctrl *dev = platform_get_drvdata(pdev);
1920
1921 ngd_slim_enable(dev, false);
1922 if (dev->sysfs_created)
1923 sysfs_remove_file(&dev->dev->kobj,
1924 &dev_attr_debug_mask.attr);
1925 qmi_svc_event_notifier_unregister(SLIMBUS_QMI_SVC_ID,
1926 SLIMBUS_QMI_SVC_V1,
1927 SLIMBUS_QMI_INS_ID, &dev->qmi.nb);
1928 pm_runtime_disable(&pdev->dev);
1929 if (dev->dsp.dom_t == MSM_SLIM_DOM_SS)
1930 subsys_notif_unregister_notifier(dev->dsp.domr,
1931 &dev->dsp.nb);
1932 if (dev->dsp.dom_t == MSM_SLIM_DOM_PD)
1933 service_notif_unregister_notifier(dev->dsp.domr,
1934 &dev->dsp.nb);
1935 if (!IS_ERR_OR_NULL(dev->ext_mdm.domr))
1936 subsys_notif_unregister_notifier(dev->ext_mdm.domr,
1937 &dev->ext_mdm.nb);
1938 kfree(dev->bulk.base);
1939 free_irq(dev->irq, dev);
1940 slim_del_controller(&dev->ctrl);
1941 kthread_stop(dev->rx_msgq_thread);
1942 iounmap(dev->bam.base);
1943 iounmap(dev->base);
1944 kfree(dev->wr_comp);
1945 kfree(dev);
1946 return 0;
1947}
1948
1949#ifdef CONFIG_PM
1950static int ngd_slim_runtime_idle(struct device *device)
1951{
1952 struct platform_device *pdev = to_platform_device(device);
1953 struct msm_slim_ctrl *dev = platform_get_drvdata(pdev);
1954
1955 mutex_lock(&dev->tx_lock);
1956 if (dev->state == MSM_CTRL_AWAKE)
1957 dev->state = MSM_CTRL_IDLE;
1958 mutex_unlock(&dev->tx_lock);
1959 dev_dbg(device, "pm_runtime: idle...\n");
1960 pm_request_autosuspend(device);
1961 return -EAGAIN;
1962}
1963#endif
1964
1965/*
1966 * If PM_RUNTIME is not defined, these 2 functions become helper
1967 * functions to be called from system suspend/resume. So they are not
1968 * inside ifdef CONFIG_PM_RUNTIME
1969 */
1970static int ngd_slim_runtime_resume(struct device *device)
1971{
1972 struct platform_device *pdev = to_platform_device(device);
1973 struct msm_slim_ctrl *dev = platform_get_drvdata(pdev);
1974 int ret = 0;
1975
1976 mutex_lock(&dev->tx_lock);
1977 if (dev->state >= MSM_CTRL_ASLEEP)
1978 ret = ngd_slim_power_up(dev, false);
1979 if (ret) {
1980 /* Did SSR cause this power up failure */
1981 if (dev->state != MSM_CTRL_DOWN)
1982 dev->state = MSM_CTRL_ASLEEP;
1983 else
1984 SLIM_WARN(dev, "HW wakeup attempt during SSR\n");
1985 } else {
1986 dev->state = MSM_CTRL_AWAKE;
1987 }
1988 mutex_unlock(&dev->tx_lock);
1989 SLIM_INFO(dev, "Slim runtime resume: ret %d\n", ret);
1990 return ret;
1991}
1992
1993#ifdef CONFIG_PM
1994static int ngd_slim_runtime_suspend(struct device *device)
1995{
1996 struct platform_device *pdev = to_platform_device(device);
1997 struct msm_slim_ctrl *dev = platform_get_drvdata(pdev);
1998 int ret = 0;
1999
2000 mutex_lock(&dev->tx_lock);
2001 ret = ngd_slim_power_down(dev);
2002 if (ret && ret != -EBUSY)
2003 SLIM_INFO(dev, "slim resource not idle:%d\n", ret);
2004 if (!ret || ret == -ETIMEDOUT)
2005 dev->state = MSM_CTRL_ASLEEP;
2006 mutex_unlock(&dev->tx_lock);
2007 SLIM_INFO(dev, "Slim runtime suspend: ret %d\n", ret);
2008 return ret;
2009}
2010#endif
2011
2012#ifdef CONFIG_PM_SLEEP
2013static int ngd_slim_suspend(struct device *dev)
2014{
2015 int ret = -EBUSY;
2016 struct platform_device *pdev = to_platform_device(dev);
2017 struct msm_slim_ctrl *cdev = platform_get_drvdata(pdev);
2018
2019 if (!pm_runtime_enabled(dev) ||
2020 (!pm_runtime_suspended(dev) &&
2021 cdev->state == MSM_CTRL_IDLE)) {
2022 ret = ngd_slim_runtime_suspend(dev);
2023 /*
2024 * If runtime-PM still thinks it's active, then make sure its
2025 * status is in sync with HW status.
2026 * Since this suspend calls QMI api, it results in holding a
2027 * wakelock. That results in failure of first suspend.
2028 * Subsequent suspend should not call low-power transition
2029 * again since the HW is already in suspended state.
2030 */
2031 if (!ret) {
2032 pm_runtime_disable(dev);
2033 pm_runtime_set_suspended(dev);
2034 pm_runtime_enable(dev);
2035 }
2036 }
2037 if (ret == -EBUSY) {
2038 /*
2039 * There is a possibility that some audio stream is active
2040 * during suspend. We dont want to return suspend failure in
2041 * that case so that display and relevant components can still
2042 * go to suspend.
2043 * If there is some other error, then it should be passed-on
2044 * to system level suspend
2045 */
2046 ret = 0;
2047 }
2048 SLIM_INFO(cdev, "system suspend\n");
2049 return ret;
2050}
2051
2052static int ngd_slim_resume(struct device *dev)
2053{
2054 struct platform_device *pdev = to_platform_device(dev);
2055 struct msm_slim_ctrl *cdev = platform_get_drvdata(pdev);
2056 /*
2057 * Rely on runtime-PM to call resume in case it is enabled.
2058 * Even if it's not enabled, rely on 1st client transaction to do
2059 * clock/power on
2060 */
2061 SLIM_INFO(cdev, "system resume\n");
2062 return 0;
2063}
2064#endif /* CONFIG_PM_SLEEP */
2065
2066static const struct dev_pm_ops ngd_slim_dev_pm_ops = {
2067 SET_SYSTEM_SLEEP_PM_OPS(
2068 ngd_slim_suspend,
2069 ngd_slim_resume
2070 )
2071 SET_RUNTIME_PM_OPS(
2072 ngd_slim_runtime_suspend,
2073 ngd_slim_runtime_resume,
2074 ngd_slim_runtime_idle
2075 )
2076};
2077
2078static const struct of_device_id ngd_slim_dt_match[] = {
2079 {
2080 .compatible = "qcom,slim-ngd",
2081 },
2082 {}
2083};
2084
2085static struct platform_driver ngd_slim_driver = {
2086 .probe = ngd_slim_probe,
2087 .remove = ngd_slim_remove,
2088 .driver = {
2089 .name = NGD_SLIM_NAME,
2090 .owner = THIS_MODULE,
2091 .pm = &ngd_slim_dev_pm_ops,
2092 .of_match_table = ngd_slim_dt_match,
2093 },
2094};
2095
2096static int ngd_slim_init(void)
2097{
2098 return platform_driver_register(&ngd_slim_driver);
2099}
2100late_initcall(ngd_slim_init);
2101
2102static void ngd_slim_exit(void)
2103{
2104 platform_driver_unregister(&ngd_slim_driver);
2105}
2106module_exit(ngd_slim_exit);
2107
2108MODULE_LICENSE("GPL v2");
2109MODULE_DESCRIPTION("MSM Slimbus controller");
2110MODULE_ALIAS("platform:msm-slim-ngd");