0001
0002
0003
0004
0005 #include <linux/irq.h>
0006 #include <linux/kernel.h>
0007 #include <linux/init.h>
0008 #include <linux/slab.h>
0009 #include <linux/interrupt.h>
0010 #include <linux/platform_device.h>
0011 #include <linux/dma-mapping.h>
0012 #include <linux/dmaengine.h>
0013 #include <linux/slimbus.h>
0014 #include <linux/delay.h>
0015 #include <linux/pm_runtime.h>
0016 #include <linux/mutex.h>
0017 #include <linux/notifier.h>
0018 #include <linux/remoteproc/qcom_rproc.h>
0019 #include <linux/of.h>
0020 #include <linux/io.h>
0021 #include <linux/soc/qcom/qmi.h>
0022 #include <linux/soc/qcom/pdr.h>
0023 #include <net/sock.h>
0024 #include "slimbus.h"
0025
0026
0027 #define NGD_CFG 0x0
0028 #define NGD_CFG_ENABLE BIT(0)
0029 #define NGD_CFG_RX_MSGQ_EN BIT(1)
0030 #define NGD_CFG_TX_MSGQ_EN BIT(2)
0031 #define NGD_STATUS 0x4
0032 #define NGD_LADDR BIT(1)
0033 #define NGD_RX_MSGQ_CFG 0x8
0034 #define NGD_INT_EN 0x10
0035 #define NGD_INT_RECFG_DONE BIT(24)
0036 #define NGD_INT_TX_NACKED_2 BIT(25)
0037 #define NGD_INT_MSG_BUF_CONTE BIT(26)
0038 #define NGD_INT_MSG_TX_INVAL BIT(27)
0039 #define NGD_INT_IE_VE_CHG BIT(28)
0040 #define NGD_INT_DEV_ERR BIT(29)
0041 #define NGD_INT_RX_MSG_RCVD BIT(30)
0042 #define NGD_INT_TX_MSG_SENT BIT(31)
0043 #define NGD_INT_STAT 0x14
0044 #define NGD_INT_CLR 0x18
0045 #define DEF_NGD_INT_MASK (NGD_INT_TX_NACKED_2 | NGD_INT_MSG_BUF_CONTE | \
0046 NGD_INT_MSG_TX_INVAL | NGD_INT_IE_VE_CHG | \
0047 NGD_INT_DEV_ERR | NGD_INT_TX_MSG_SENT | \
0048 NGD_INT_RX_MSG_RCVD)
0049
0050
0051 #define SLIMBUS_QMI_SVC_ID 0x0301
0052 #define SLIMBUS_QMI_SVC_V1 1
0053 #define SLIMBUS_QMI_INS_ID 0
0054 #define SLIMBUS_QMI_SELECT_INSTANCE_REQ_V01 0x0020
0055 #define SLIMBUS_QMI_SELECT_INSTANCE_RESP_V01 0x0020
0056 #define SLIMBUS_QMI_POWER_REQ_V01 0x0021
0057 #define SLIMBUS_QMI_POWER_RESP_V01 0x0021
0058 #define SLIMBUS_QMI_CHECK_FRAMER_STATUS_REQ 0x0022
0059 #define SLIMBUS_QMI_CHECK_FRAMER_STATUS_RESP 0x0022
0060 #define SLIMBUS_QMI_POWER_REQ_MAX_MSG_LEN 14
0061 #define SLIMBUS_QMI_POWER_RESP_MAX_MSG_LEN 7
0062 #define SLIMBUS_QMI_SELECT_INSTANCE_REQ_MAX_MSG_LEN 14
0063 #define SLIMBUS_QMI_SELECT_INSTANCE_RESP_MAX_MSG_LEN 7
0064 #define SLIMBUS_QMI_CHECK_FRAMER_STAT_RESP_MAX_MSG_LEN 7
0065
0066 #define SLIMBUS_QMI_RESP_TOUT 1000
0067
0068
0069 #define SLIM_USR_MC_GENERIC_ACK 0x25
0070 #define SLIM_USR_MC_MASTER_CAPABILITY 0x0
0071 #define SLIM_USR_MC_REPORT_SATELLITE 0x1
0072 #define SLIM_USR_MC_ADDR_QUERY 0xD
0073 #define SLIM_USR_MC_ADDR_REPLY 0xE
0074 #define SLIM_USR_MC_DEFINE_CHAN 0x20
0075 #define SLIM_USR_MC_DEF_ACT_CHAN 0x21
0076 #define SLIM_USR_MC_CHAN_CTRL 0x23
0077 #define SLIM_USR_MC_RECONFIG_NOW 0x24
0078 #define SLIM_USR_MC_REQ_BW 0x28
0079 #define SLIM_USR_MC_CONNECT_SRC 0x2C
0080 #define SLIM_USR_MC_CONNECT_SINK 0x2D
0081 #define SLIM_USR_MC_DISCONNECT_PORT 0x2E
0082 #define SLIM_USR_MC_REPEAT_CHANGE_VALUE 0x0
0083
0084 #define QCOM_SLIM_NGD_AUTOSUSPEND MSEC_PER_SEC
0085 #define SLIM_RX_MSGQ_TIMEOUT_VAL 0x10000
0086
0087 #define SLIM_LA_MGR 0xFF
0088 #define SLIM_ROOT_FREQ 24576000
0089 #define LADDR_RETRY 5
0090
0091
0092 #define SLIM_MSGQ_BUF_LEN 40
0093 #define QCOM_SLIM_NGD_DESC_NUM 32
0094
0095 #define SLIM_MSG_ASM_FIRST_WORD(l, mt, mc, dt, ad) \
0096 ((l) | ((mt) << 5) | ((mc) << 8) | ((dt) << 15) | ((ad) << 16))
0097
0098 #define INIT_MX_RETRIES 10
0099 #define DEF_RETRY_MS 10
0100 #define SAT_MAGIC_LSB 0xD9
0101 #define SAT_MAGIC_MSB 0xC5
0102 #define SAT_MSG_VER 0x1
0103 #define SAT_MSG_PROT 0x1
0104 #define to_ngd(d) container_of(d, struct qcom_slim_ngd, dev)
0105
0106 struct ngd_reg_offset_data {
0107 u32 offset, size;
0108 };
0109
0110 static const struct ngd_reg_offset_data ngd_v1_5_offset_info = {
0111 .offset = 0x1000,
0112 .size = 0x1000,
0113 };
0114
0115 enum qcom_slim_ngd_state {
0116 QCOM_SLIM_NGD_CTRL_AWAKE,
0117 QCOM_SLIM_NGD_CTRL_IDLE,
0118 QCOM_SLIM_NGD_CTRL_ASLEEP,
0119 QCOM_SLIM_NGD_CTRL_DOWN,
0120 };
0121
0122 struct qcom_slim_ngd_qmi {
0123 struct qmi_handle qmi;
0124 struct sockaddr_qrtr svc_info;
0125 struct qmi_handle svc_event_hdl;
0126 struct qmi_response_type_v01 resp;
0127 struct qmi_handle *handle;
0128 struct completion qmi_comp;
0129 };
0130
0131 struct qcom_slim_ngd_ctrl;
0132 struct qcom_slim_ngd;
0133
0134 struct qcom_slim_ngd_dma_desc {
0135 struct dma_async_tx_descriptor *desc;
0136 struct qcom_slim_ngd_ctrl *ctrl;
0137 struct completion *comp;
0138 dma_cookie_t cookie;
0139 dma_addr_t phys;
0140 void *base;
0141 };
0142
0143 struct qcom_slim_ngd {
0144 struct platform_device *pdev;
0145 void __iomem *base;
0146 int id;
0147 };
0148
0149 struct qcom_slim_ngd_ctrl {
0150 struct slim_framer framer;
0151 struct slim_controller ctrl;
0152 struct qcom_slim_ngd_qmi qmi;
0153 struct qcom_slim_ngd *ngd;
0154 struct device *dev;
0155 void __iomem *base;
0156 struct dma_chan *dma_rx_channel;
0157 struct dma_chan *dma_tx_channel;
0158 struct qcom_slim_ngd_dma_desc rx_desc[QCOM_SLIM_NGD_DESC_NUM];
0159 struct qcom_slim_ngd_dma_desc txdesc[QCOM_SLIM_NGD_DESC_NUM];
0160 struct completion reconf;
0161 struct work_struct m_work;
0162 struct work_struct ngd_up_work;
0163 struct workqueue_struct *mwq;
0164 struct completion qmi_up;
0165 spinlock_t tx_buf_lock;
0166 struct mutex tx_lock;
0167 struct mutex ssr_lock;
0168 struct notifier_block nb;
0169 void *notifier;
0170 struct pdr_handle *pdr;
0171 enum qcom_slim_ngd_state state;
0172 dma_addr_t rx_phys_base;
0173 dma_addr_t tx_phys_base;
0174 void *rx_base;
0175 void *tx_base;
0176 int tx_tail;
0177 int tx_head;
0178 u32 ver;
0179 };
0180
0181 enum slimbus_mode_enum_type_v01 {
0182
0183 SLIMBUS_MODE_ENUM_TYPE_MIN_ENUM_VAL_V01 = INT_MIN,
0184 SLIMBUS_MODE_SATELLITE_V01 = 1,
0185 SLIMBUS_MODE_MASTER_V01 = 2,
0186 SLIMBUS_MODE_ENUM_TYPE_MAX_ENUM_VAL_V01 = INT_MAX,
0187 };
0188
0189 enum slimbus_pm_enum_type_v01 {
0190
0191 SLIMBUS_PM_ENUM_TYPE_MIN_ENUM_VAL_V01 = INT_MIN,
0192 SLIMBUS_PM_INACTIVE_V01 = 1,
0193 SLIMBUS_PM_ACTIVE_V01 = 2,
0194 SLIMBUS_PM_ENUM_TYPE_MAX_ENUM_VAL_V01 = INT_MAX,
0195 };
0196
0197 enum slimbus_resp_enum_type_v01 {
0198 SLIMBUS_RESP_ENUM_TYPE_MIN_VAL_V01 = INT_MIN,
0199 SLIMBUS_RESP_SYNCHRONOUS_V01 = 1,
0200 SLIMBUS_RESP_ENUM_TYPE_MAX_VAL_V01 = INT_MAX,
0201 };
0202
0203 struct slimbus_select_inst_req_msg_v01 {
0204 uint32_t instance;
0205 uint8_t mode_valid;
0206 enum slimbus_mode_enum_type_v01 mode;
0207 };
0208
0209 struct slimbus_select_inst_resp_msg_v01 {
0210 struct qmi_response_type_v01 resp;
0211 };
0212
0213 struct slimbus_power_req_msg_v01 {
0214 enum slimbus_pm_enum_type_v01 pm_req;
0215 uint8_t resp_type_valid;
0216 enum slimbus_resp_enum_type_v01 resp_type;
0217 };
0218
0219 struct slimbus_power_resp_msg_v01 {
0220 struct qmi_response_type_v01 resp;
0221 };
0222
0223 static struct qmi_elem_info slimbus_select_inst_req_msg_v01_ei[] = {
0224 {
0225 .data_type = QMI_UNSIGNED_4_BYTE,
0226 .elem_len = 1,
0227 .elem_size = sizeof(uint32_t),
0228 .array_type = NO_ARRAY,
0229 .tlv_type = 0x01,
0230 .offset = offsetof(struct slimbus_select_inst_req_msg_v01,
0231 instance),
0232 .ei_array = NULL,
0233 },
0234 {
0235 .data_type = QMI_OPT_FLAG,
0236 .elem_len = 1,
0237 .elem_size = sizeof(uint8_t),
0238 .array_type = NO_ARRAY,
0239 .tlv_type = 0x10,
0240 .offset = offsetof(struct slimbus_select_inst_req_msg_v01,
0241 mode_valid),
0242 .ei_array = NULL,
0243 },
0244 {
0245 .data_type = QMI_UNSIGNED_4_BYTE,
0246 .elem_len = 1,
0247 .elem_size = sizeof(enum slimbus_mode_enum_type_v01),
0248 .array_type = NO_ARRAY,
0249 .tlv_type = 0x10,
0250 .offset = offsetof(struct slimbus_select_inst_req_msg_v01,
0251 mode),
0252 .ei_array = NULL,
0253 },
0254 {
0255 .data_type = QMI_EOTI,
0256 .elem_len = 0,
0257 .elem_size = 0,
0258 .array_type = NO_ARRAY,
0259 .tlv_type = 0x00,
0260 .offset = 0,
0261 .ei_array = NULL,
0262 },
0263 };
0264
0265 static struct qmi_elem_info slimbus_select_inst_resp_msg_v01_ei[] = {
0266 {
0267 .data_type = QMI_STRUCT,
0268 .elem_len = 1,
0269 .elem_size = sizeof(struct qmi_response_type_v01),
0270 .array_type = NO_ARRAY,
0271 .tlv_type = 0x02,
0272 .offset = offsetof(struct slimbus_select_inst_resp_msg_v01,
0273 resp),
0274 .ei_array = qmi_response_type_v01_ei,
0275 },
0276 {
0277 .data_type = QMI_EOTI,
0278 .elem_len = 0,
0279 .elem_size = 0,
0280 .array_type = NO_ARRAY,
0281 .tlv_type = 0x00,
0282 .offset = 0,
0283 .ei_array = NULL,
0284 },
0285 };
0286
0287 static struct qmi_elem_info slimbus_power_req_msg_v01_ei[] = {
0288 {
0289 .data_type = QMI_UNSIGNED_4_BYTE,
0290 .elem_len = 1,
0291 .elem_size = sizeof(enum slimbus_pm_enum_type_v01),
0292 .array_type = NO_ARRAY,
0293 .tlv_type = 0x01,
0294 .offset = offsetof(struct slimbus_power_req_msg_v01,
0295 pm_req),
0296 .ei_array = NULL,
0297 },
0298 {
0299 .data_type = QMI_OPT_FLAG,
0300 .elem_len = 1,
0301 .elem_size = sizeof(uint8_t),
0302 .array_type = NO_ARRAY,
0303 .tlv_type = 0x10,
0304 .offset = offsetof(struct slimbus_power_req_msg_v01,
0305 resp_type_valid),
0306 },
0307 {
0308 .data_type = QMI_SIGNED_4_BYTE_ENUM,
0309 .elem_len = 1,
0310 .elem_size = sizeof(enum slimbus_resp_enum_type_v01),
0311 .array_type = NO_ARRAY,
0312 .tlv_type = 0x10,
0313 .offset = offsetof(struct slimbus_power_req_msg_v01,
0314 resp_type),
0315 },
0316 {
0317 .data_type = QMI_EOTI,
0318 .elem_len = 0,
0319 .elem_size = 0,
0320 .array_type = NO_ARRAY,
0321 .tlv_type = 0x00,
0322 .offset = 0,
0323 .ei_array = NULL,
0324 },
0325 };
0326
0327 static struct qmi_elem_info slimbus_power_resp_msg_v01_ei[] = {
0328 {
0329 .data_type = QMI_STRUCT,
0330 .elem_len = 1,
0331 .elem_size = sizeof(struct qmi_response_type_v01),
0332 .array_type = NO_ARRAY,
0333 .tlv_type = 0x02,
0334 .offset = offsetof(struct slimbus_power_resp_msg_v01, resp),
0335 .ei_array = qmi_response_type_v01_ei,
0336 },
0337 {
0338 .data_type = QMI_EOTI,
0339 .elem_len = 0,
0340 .elem_size = 0,
0341 .array_type = NO_ARRAY,
0342 .tlv_type = 0x00,
0343 .offset = 0,
0344 .ei_array = NULL,
0345 },
0346 };
0347
0348 static int qcom_slim_qmi_send_select_inst_req(struct qcom_slim_ngd_ctrl *ctrl,
0349 struct slimbus_select_inst_req_msg_v01 *req)
0350 {
0351 struct slimbus_select_inst_resp_msg_v01 resp = { { 0, 0 } };
0352 struct qmi_txn txn;
0353 int rc;
0354
0355 rc = qmi_txn_init(ctrl->qmi.handle, &txn,
0356 slimbus_select_inst_resp_msg_v01_ei, &resp);
0357 if (rc < 0) {
0358 dev_err(ctrl->dev, "QMI TXN init fail: %d\n", rc);
0359 return rc;
0360 }
0361
0362 rc = qmi_send_request(ctrl->qmi.handle, NULL, &txn,
0363 SLIMBUS_QMI_SELECT_INSTANCE_REQ_V01,
0364 SLIMBUS_QMI_SELECT_INSTANCE_REQ_MAX_MSG_LEN,
0365 slimbus_select_inst_req_msg_v01_ei, req);
0366 if (rc < 0) {
0367 dev_err(ctrl->dev, "QMI send req fail %d\n", rc);
0368 qmi_txn_cancel(&txn);
0369 return rc;
0370 }
0371
0372 rc = qmi_txn_wait(&txn, SLIMBUS_QMI_RESP_TOUT);
0373 if (rc < 0) {
0374 dev_err(ctrl->dev, "QMI TXN wait fail: %d\n", rc);
0375 return rc;
0376 }
0377
0378 if (resp.resp.result != QMI_RESULT_SUCCESS_V01) {
0379 dev_err(ctrl->dev, "QMI request failed 0x%x\n",
0380 resp.resp.result);
0381 return -EREMOTEIO;
0382 }
0383
0384 return 0;
0385 }
0386
0387 static void qcom_slim_qmi_power_resp_cb(struct qmi_handle *handle,
0388 struct sockaddr_qrtr *sq,
0389 struct qmi_txn *txn, const void *data)
0390 {
0391 struct slimbus_power_resp_msg_v01 *resp;
0392
0393 resp = (struct slimbus_power_resp_msg_v01 *)data;
0394 if (resp->resp.result != QMI_RESULT_SUCCESS_V01)
0395 pr_err("QMI power request failed 0x%x\n",
0396 resp->resp.result);
0397
0398 complete(&txn->completion);
0399 }
0400
0401 static int qcom_slim_qmi_send_power_request(struct qcom_slim_ngd_ctrl *ctrl,
0402 struct slimbus_power_req_msg_v01 *req)
0403 {
0404 struct slimbus_power_resp_msg_v01 resp = { { 0, 0 } };
0405 struct qmi_txn txn;
0406 int rc;
0407
0408 rc = qmi_txn_init(ctrl->qmi.handle, &txn,
0409 slimbus_power_resp_msg_v01_ei, &resp);
0410
0411 rc = qmi_send_request(ctrl->qmi.handle, NULL, &txn,
0412 SLIMBUS_QMI_POWER_REQ_V01,
0413 SLIMBUS_QMI_POWER_REQ_MAX_MSG_LEN,
0414 slimbus_power_req_msg_v01_ei, req);
0415 if (rc < 0) {
0416 dev_err(ctrl->dev, "QMI send req fail %d\n", rc);
0417 qmi_txn_cancel(&txn);
0418 return rc;
0419 }
0420
0421 rc = qmi_txn_wait(&txn, SLIMBUS_QMI_RESP_TOUT);
0422 if (rc < 0) {
0423 dev_err(ctrl->dev, "QMI TXN wait fail: %d\n", rc);
0424 return rc;
0425 }
0426
0427
0428 if (resp.resp.result != QMI_RESULT_SUCCESS_V01) {
0429 dev_err(ctrl->dev, "QMI request failed 0x%x\n",
0430 resp.resp.result);
0431 return -EREMOTEIO;
0432 }
0433
0434 return 0;
0435 }
0436
0437 static const struct qmi_msg_handler qcom_slim_qmi_msg_handlers[] = {
0438 {
0439 .type = QMI_RESPONSE,
0440 .msg_id = SLIMBUS_QMI_POWER_RESP_V01,
0441 .ei = slimbus_power_resp_msg_v01_ei,
0442 .decoded_size = sizeof(struct slimbus_power_resp_msg_v01),
0443 .fn = qcom_slim_qmi_power_resp_cb,
0444 },
0445 {}
0446 };
0447
0448 static int qcom_slim_qmi_init(struct qcom_slim_ngd_ctrl *ctrl,
0449 bool apps_is_master)
0450 {
0451 struct slimbus_select_inst_req_msg_v01 req;
0452 struct qmi_handle *handle;
0453 int rc;
0454
0455 handle = devm_kzalloc(ctrl->dev, sizeof(*handle), GFP_KERNEL);
0456 if (!handle)
0457 return -ENOMEM;
0458
0459 rc = qmi_handle_init(handle, SLIMBUS_QMI_POWER_REQ_MAX_MSG_LEN,
0460 NULL, qcom_slim_qmi_msg_handlers);
0461 if (rc < 0) {
0462 dev_err(ctrl->dev, "QMI client init failed: %d\n", rc);
0463 goto qmi_handle_init_failed;
0464 }
0465
0466 rc = kernel_connect(handle->sock,
0467 (struct sockaddr *)&ctrl->qmi.svc_info,
0468 sizeof(ctrl->qmi.svc_info), 0);
0469 if (rc < 0) {
0470 dev_err(ctrl->dev, "Remote Service connect failed: %d\n", rc);
0471 goto qmi_connect_to_service_failed;
0472 }
0473
0474
0475 req.instance = (ctrl->ngd->id >> 1);
0476 req.mode_valid = 1;
0477
0478
0479 if (apps_is_master)
0480 req.mode = SLIMBUS_MODE_SATELLITE_V01;
0481 else
0482 req.mode = SLIMBUS_MODE_MASTER_V01;
0483
0484 ctrl->qmi.handle = handle;
0485
0486 rc = qcom_slim_qmi_send_select_inst_req(ctrl, &req);
0487 if (rc) {
0488 dev_err(ctrl->dev, "failed to select h/w instance\n");
0489 goto qmi_select_instance_failed;
0490 }
0491
0492 return 0;
0493
0494 qmi_select_instance_failed:
0495 ctrl->qmi.handle = NULL;
0496 qmi_connect_to_service_failed:
0497 qmi_handle_release(handle);
0498 qmi_handle_init_failed:
0499 devm_kfree(ctrl->dev, handle);
0500 return rc;
0501 }
0502
0503 static void qcom_slim_qmi_exit(struct qcom_slim_ngd_ctrl *ctrl)
0504 {
0505 if (!ctrl->qmi.handle)
0506 return;
0507
0508 qmi_handle_release(ctrl->qmi.handle);
0509 devm_kfree(ctrl->dev, ctrl->qmi.handle);
0510 ctrl->qmi.handle = NULL;
0511 }
0512
0513 static int qcom_slim_qmi_power_request(struct qcom_slim_ngd_ctrl *ctrl,
0514 bool active)
0515 {
0516 struct slimbus_power_req_msg_v01 req;
0517
0518 if (active)
0519 req.pm_req = SLIMBUS_PM_ACTIVE_V01;
0520 else
0521 req.pm_req = SLIMBUS_PM_INACTIVE_V01;
0522
0523 req.resp_type_valid = 0;
0524
0525 return qcom_slim_qmi_send_power_request(ctrl, &req);
0526 }
0527
0528 static u32 *qcom_slim_ngd_tx_msg_get(struct qcom_slim_ngd_ctrl *ctrl, int len,
0529 struct completion *comp)
0530 {
0531 struct qcom_slim_ngd_dma_desc *desc;
0532 unsigned long flags;
0533
0534 spin_lock_irqsave(&ctrl->tx_buf_lock, flags);
0535
0536 if ((ctrl->tx_tail + 1) % QCOM_SLIM_NGD_DESC_NUM == ctrl->tx_head) {
0537 spin_unlock_irqrestore(&ctrl->tx_buf_lock, flags);
0538 return NULL;
0539 }
0540 desc = &ctrl->txdesc[ctrl->tx_tail];
0541 desc->base = ctrl->tx_base + ctrl->tx_tail * SLIM_MSGQ_BUF_LEN;
0542 desc->comp = comp;
0543 ctrl->tx_tail = (ctrl->tx_tail + 1) % QCOM_SLIM_NGD_DESC_NUM;
0544
0545 spin_unlock_irqrestore(&ctrl->tx_buf_lock, flags);
0546
0547 return desc->base;
0548 }
0549
0550 static void qcom_slim_ngd_tx_msg_dma_cb(void *args)
0551 {
0552 struct qcom_slim_ngd_dma_desc *desc = args;
0553 struct qcom_slim_ngd_ctrl *ctrl = desc->ctrl;
0554 unsigned long flags;
0555
0556 spin_lock_irqsave(&ctrl->tx_buf_lock, flags);
0557
0558 if (desc->comp) {
0559 complete(desc->comp);
0560 desc->comp = NULL;
0561 }
0562
0563 ctrl->tx_head = (ctrl->tx_head + 1) % QCOM_SLIM_NGD_DESC_NUM;
0564 spin_unlock_irqrestore(&ctrl->tx_buf_lock, flags);
0565 }
0566
0567 static int qcom_slim_ngd_tx_msg_post(struct qcom_slim_ngd_ctrl *ctrl,
0568 void *buf, int len)
0569 {
0570 struct qcom_slim_ngd_dma_desc *desc;
0571 unsigned long flags;
0572 int index, offset;
0573
0574 spin_lock_irqsave(&ctrl->tx_buf_lock, flags);
0575 offset = buf - ctrl->tx_base;
0576 index = offset/SLIM_MSGQ_BUF_LEN;
0577
0578 desc = &ctrl->txdesc[index];
0579 desc->phys = ctrl->tx_phys_base + offset;
0580 desc->base = ctrl->tx_base + offset;
0581 desc->ctrl = ctrl;
0582 len = (len + 3) & 0xfc;
0583
0584 desc->desc = dmaengine_prep_slave_single(ctrl->dma_tx_channel,
0585 desc->phys, len,
0586 DMA_MEM_TO_DEV,
0587 DMA_PREP_INTERRUPT);
0588 if (!desc->desc) {
0589 dev_err(ctrl->dev, "unable to prepare channel\n");
0590 spin_unlock_irqrestore(&ctrl->tx_buf_lock, flags);
0591 return -EINVAL;
0592 }
0593
0594 desc->desc->callback = qcom_slim_ngd_tx_msg_dma_cb;
0595 desc->desc->callback_param = desc;
0596 desc->desc->cookie = dmaengine_submit(desc->desc);
0597 dma_async_issue_pending(ctrl->dma_tx_channel);
0598 spin_unlock_irqrestore(&ctrl->tx_buf_lock, flags);
0599
0600 return 0;
0601 }
0602
0603 static void qcom_slim_ngd_rx(struct qcom_slim_ngd_ctrl *ctrl, u8 *buf)
0604 {
0605 u8 mc, mt, len;
0606
0607 mt = SLIM_HEADER_GET_MT(buf[0]);
0608 len = SLIM_HEADER_GET_RL(buf[0]);
0609 mc = SLIM_HEADER_GET_MC(buf[1]);
0610
0611 if (mc == SLIM_USR_MC_MASTER_CAPABILITY &&
0612 mt == SLIM_MSG_MT_SRC_REFERRED_USER)
0613 queue_work(ctrl->mwq, &ctrl->m_work);
0614
0615 if (mc == SLIM_MSG_MC_REPLY_INFORMATION ||
0616 mc == SLIM_MSG_MC_REPLY_VALUE || (mc == SLIM_USR_MC_ADDR_REPLY &&
0617 mt == SLIM_MSG_MT_SRC_REFERRED_USER) ||
0618 (mc == SLIM_USR_MC_GENERIC_ACK &&
0619 mt == SLIM_MSG_MT_SRC_REFERRED_USER)) {
0620 slim_msg_response(&ctrl->ctrl, &buf[4], buf[3], len - 4);
0621 pm_runtime_mark_last_busy(ctrl->ctrl.dev);
0622 }
0623 }
0624
0625 static void qcom_slim_ngd_rx_msgq_cb(void *args)
0626 {
0627 struct qcom_slim_ngd_dma_desc *desc = args;
0628 struct qcom_slim_ngd_ctrl *ctrl = desc->ctrl;
0629
0630 qcom_slim_ngd_rx(ctrl, (u8 *)desc->base);
0631
0632 desc->desc = dmaengine_prep_slave_single(ctrl->dma_rx_channel,
0633 desc->phys, SLIM_MSGQ_BUF_LEN,
0634 DMA_DEV_TO_MEM,
0635 DMA_PREP_INTERRUPT);
0636 if (!desc->desc) {
0637 dev_err(ctrl->dev, "Unable to prepare rx channel\n");
0638 return;
0639 }
0640
0641 desc->desc->callback = qcom_slim_ngd_rx_msgq_cb;
0642 desc->desc->callback_param = desc;
0643 desc->desc->cookie = dmaengine_submit(desc->desc);
0644 dma_async_issue_pending(ctrl->dma_rx_channel);
0645 }
0646
0647 static int qcom_slim_ngd_post_rx_msgq(struct qcom_slim_ngd_ctrl *ctrl)
0648 {
0649 struct qcom_slim_ngd_dma_desc *desc;
0650 int i;
0651
0652 for (i = 0; i < QCOM_SLIM_NGD_DESC_NUM; i++) {
0653 desc = &ctrl->rx_desc[i];
0654 desc->phys = ctrl->rx_phys_base + i * SLIM_MSGQ_BUF_LEN;
0655 desc->ctrl = ctrl;
0656 desc->base = ctrl->rx_base + i * SLIM_MSGQ_BUF_LEN;
0657 desc->desc = dmaengine_prep_slave_single(ctrl->dma_rx_channel,
0658 desc->phys, SLIM_MSGQ_BUF_LEN,
0659 DMA_DEV_TO_MEM,
0660 DMA_PREP_INTERRUPT);
0661 if (!desc->desc) {
0662 dev_err(ctrl->dev, "Unable to prepare rx channel\n");
0663 return -EINVAL;
0664 }
0665
0666 desc->desc->callback = qcom_slim_ngd_rx_msgq_cb;
0667 desc->desc->callback_param = desc;
0668 desc->desc->cookie = dmaengine_submit(desc->desc);
0669 }
0670 dma_async_issue_pending(ctrl->dma_rx_channel);
0671
0672 return 0;
0673 }
0674
0675 static int qcom_slim_ngd_init_rx_msgq(struct qcom_slim_ngd_ctrl *ctrl)
0676 {
0677 struct device *dev = ctrl->dev;
0678 int ret, size;
0679
0680 ctrl->dma_rx_channel = dma_request_chan(dev, "rx");
0681 if (IS_ERR(ctrl->dma_rx_channel)) {
0682 dev_err(dev, "Failed to request RX dma channel");
0683 ret = PTR_ERR(ctrl->dma_rx_channel);
0684 ctrl->dma_rx_channel = NULL;
0685 return ret;
0686 }
0687
0688 size = QCOM_SLIM_NGD_DESC_NUM * SLIM_MSGQ_BUF_LEN;
0689 ctrl->rx_base = dma_alloc_coherent(dev, size, &ctrl->rx_phys_base,
0690 GFP_KERNEL);
0691 if (!ctrl->rx_base) {
0692 ret = -ENOMEM;
0693 goto rel_rx;
0694 }
0695
0696 ret = qcom_slim_ngd_post_rx_msgq(ctrl);
0697 if (ret) {
0698 dev_err(dev, "post_rx_msgq() failed 0x%x\n", ret);
0699 goto rx_post_err;
0700 }
0701
0702 return 0;
0703
0704 rx_post_err:
0705 dma_free_coherent(dev, size, ctrl->rx_base, ctrl->rx_phys_base);
0706 rel_rx:
0707 dma_release_channel(ctrl->dma_rx_channel);
0708 return ret;
0709 }
0710
0711 static int qcom_slim_ngd_init_tx_msgq(struct qcom_slim_ngd_ctrl *ctrl)
0712 {
0713 struct device *dev = ctrl->dev;
0714 unsigned long flags;
0715 int ret = 0;
0716 int size;
0717
0718 ctrl->dma_tx_channel = dma_request_chan(dev, "tx");
0719 if (IS_ERR(ctrl->dma_tx_channel)) {
0720 dev_err(dev, "Failed to request TX dma channel");
0721 ret = PTR_ERR(ctrl->dma_tx_channel);
0722 ctrl->dma_tx_channel = NULL;
0723 return ret;
0724 }
0725
0726 size = ((QCOM_SLIM_NGD_DESC_NUM + 1) * SLIM_MSGQ_BUF_LEN);
0727 ctrl->tx_base = dma_alloc_coherent(dev, size, &ctrl->tx_phys_base,
0728 GFP_KERNEL);
0729 if (!ctrl->tx_base) {
0730 ret = -EINVAL;
0731 goto rel_tx;
0732 }
0733
0734 spin_lock_irqsave(&ctrl->tx_buf_lock, flags);
0735 ctrl->tx_tail = 0;
0736 ctrl->tx_head = 0;
0737 spin_unlock_irqrestore(&ctrl->tx_buf_lock, flags);
0738
0739 return 0;
0740 rel_tx:
0741 dma_release_channel(ctrl->dma_tx_channel);
0742 return ret;
0743 }
0744
0745 static int qcom_slim_ngd_init_dma(struct qcom_slim_ngd_ctrl *ctrl)
0746 {
0747 int ret = 0;
0748
0749 ret = qcom_slim_ngd_init_rx_msgq(ctrl);
0750 if (ret) {
0751 dev_err(ctrl->dev, "rx dma init failed\n");
0752 return ret;
0753 }
0754
0755 ret = qcom_slim_ngd_init_tx_msgq(ctrl);
0756 if (ret)
0757 dev_err(ctrl->dev, "tx dma init failed\n");
0758
0759 return ret;
0760 }
0761
0762 static irqreturn_t qcom_slim_ngd_interrupt(int irq, void *d)
0763 {
0764 struct qcom_slim_ngd_ctrl *ctrl = d;
0765 void __iomem *base = ctrl->ngd->base;
0766 u32 stat = readl(base + NGD_INT_STAT);
0767
0768 if ((stat & NGD_INT_MSG_BUF_CONTE) ||
0769 (stat & NGD_INT_MSG_TX_INVAL) || (stat & NGD_INT_DEV_ERR) ||
0770 (stat & NGD_INT_TX_NACKED_2)) {
0771 dev_err(ctrl->dev, "Error Interrupt received 0x%x\n", stat);
0772 }
0773
0774 writel(stat, base + NGD_INT_CLR);
0775
0776 return IRQ_HANDLED;
0777 }
0778
0779 static int qcom_slim_ngd_xfer_msg(struct slim_controller *sctrl,
0780 struct slim_msg_txn *txn)
0781 {
0782 struct qcom_slim_ngd_ctrl *ctrl = dev_get_drvdata(sctrl->dev);
0783 DECLARE_COMPLETION_ONSTACK(tx_sent);
0784 DECLARE_COMPLETION_ONSTACK(done);
0785 int ret, timeout, i;
0786 u8 wbuf[SLIM_MSGQ_BUF_LEN];
0787 u8 rbuf[SLIM_MSGQ_BUF_LEN];
0788 u32 *pbuf;
0789 u8 *puc;
0790 u8 la = txn->la;
0791 bool usr_msg = false;
0792
0793 if (txn->mt == SLIM_MSG_MT_CORE &&
0794 (txn->mc >= SLIM_MSG_MC_BEGIN_RECONFIGURATION &&
0795 txn->mc <= SLIM_MSG_MC_RECONFIGURE_NOW))
0796 return 0;
0797
0798 if (txn->dt == SLIM_MSG_DEST_ENUMADDR)
0799 return -EPROTONOSUPPORT;
0800
0801 if (txn->msg->num_bytes > SLIM_MSGQ_BUF_LEN ||
0802 txn->rl > SLIM_MSGQ_BUF_LEN) {
0803 dev_err(ctrl->dev, "msg exceeds HW limit\n");
0804 return -EINVAL;
0805 }
0806
0807 pbuf = qcom_slim_ngd_tx_msg_get(ctrl, txn->rl, &tx_sent);
0808 if (!pbuf) {
0809 dev_err(ctrl->dev, "Message buffer unavailable\n");
0810 return -ENOMEM;
0811 }
0812
0813 if (txn->mt == SLIM_MSG_MT_CORE &&
0814 (txn->mc == SLIM_MSG_MC_CONNECT_SOURCE ||
0815 txn->mc == SLIM_MSG_MC_CONNECT_SINK ||
0816 txn->mc == SLIM_MSG_MC_DISCONNECT_PORT)) {
0817 txn->mt = SLIM_MSG_MT_DEST_REFERRED_USER;
0818 switch (txn->mc) {
0819 case SLIM_MSG_MC_CONNECT_SOURCE:
0820 txn->mc = SLIM_USR_MC_CONNECT_SRC;
0821 break;
0822 case SLIM_MSG_MC_CONNECT_SINK:
0823 txn->mc = SLIM_USR_MC_CONNECT_SINK;
0824 break;
0825 case SLIM_MSG_MC_DISCONNECT_PORT:
0826 txn->mc = SLIM_USR_MC_DISCONNECT_PORT;
0827 break;
0828 default:
0829 return -EINVAL;
0830 }
0831
0832 usr_msg = true;
0833 i = 0;
0834 wbuf[i++] = txn->la;
0835 la = SLIM_LA_MGR;
0836 wbuf[i++] = txn->msg->wbuf[0];
0837 if (txn->mc != SLIM_USR_MC_DISCONNECT_PORT)
0838 wbuf[i++] = txn->msg->wbuf[1];
0839
0840 txn->comp = &done;
0841 ret = slim_alloc_txn_tid(sctrl, txn);
0842 if (ret) {
0843 dev_err(ctrl->dev, "Unable to allocate TID\n");
0844 return ret;
0845 }
0846
0847 wbuf[i++] = txn->tid;
0848
0849 txn->msg->num_bytes = i;
0850 txn->msg->wbuf = wbuf;
0851 txn->msg->rbuf = rbuf;
0852 txn->rl = txn->msg->num_bytes + 4;
0853 }
0854
0855
0856 txn->rl--;
0857 puc = (u8 *)pbuf;
0858 *pbuf = 0;
0859 if (txn->dt == SLIM_MSG_DEST_LOGICALADDR) {
0860 *pbuf = SLIM_MSG_ASM_FIRST_WORD(txn->rl, txn->mt, txn->mc, 0,
0861 la);
0862 puc += 3;
0863 } else {
0864 *pbuf = SLIM_MSG_ASM_FIRST_WORD(txn->rl, txn->mt, txn->mc, 1,
0865 la);
0866 puc += 2;
0867 }
0868
0869 if (slim_tid_txn(txn->mt, txn->mc))
0870 *(puc++) = txn->tid;
0871
0872 if (slim_ec_txn(txn->mt, txn->mc)) {
0873 *(puc++) = (txn->ec & 0xFF);
0874 *(puc++) = (txn->ec >> 8) & 0xFF;
0875 }
0876
0877 if (txn->msg && txn->msg->wbuf)
0878 memcpy(puc, txn->msg->wbuf, txn->msg->num_bytes);
0879
0880 mutex_lock(&ctrl->tx_lock);
0881 ret = qcom_slim_ngd_tx_msg_post(ctrl, pbuf, txn->rl);
0882 if (ret) {
0883 mutex_unlock(&ctrl->tx_lock);
0884 return ret;
0885 }
0886
0887 timeout = wait_for_completion_timeout(&tx_sent, HZ);
0888 if (!timeout) {
0889 dev_err(sctrl->dev, "TX timed out:MC:0x%x,mt:0x%x", txn->mc,
0890 txn->mt);
0891 mutex_unlock(&ctrl->tx_lock);
0892 return -ETIMEDOUT;
0893 }
0894
0895 if (usr_msg) {
0896 timeout = wait_for_completion_timeout(&done, HZ);
0897 if (!timeout) {
0898 dev_err(sctrl->dev, "TX timed out:MC:0x%x,mt:0x%x",
0899 txn->mc, txn->mt);
0900 mutex_unlock(&ctrl->tx_lock);
0901 return -ETIMEDOUT;
0902 }
0903 }
0904
0905 mutex_unlock(&ctrl->tx_lock);
0906 return 0;
0907 }
0908
0909 static int qcom_slim_ngd_xfer_msg_sync(struct slim_controller *ctrl,
0910 struct slim_msg_txn *txn)
0911 {
0912 DECLARE_COMPLETION_ONSTACK(done);
0913 int ret, timeout;
0914
0915 pm_runtime_get_sync(ctrl->dev);
0916
0917 txn->comp = &done;
0918
0919 ret = qcom_slim_ngd_xfer_msg(ctrl, txn);
0920 if (ret)
0921 return ret;
0922
0923 timeout = wait_for_completion_timeout(&done, HZ);
0924 if (!timeout) {
0925 dev_err(ctrl->dev, "TX timed out:MC:0x%x,mt:0x%x", txn->mc,
0926 txn->mt);
0927 return -ETIMEDOUT;
0928 }
0929 return 0;
0930 }
0931
0932 static int qcom_slim_ngd_enable_stream(struct slim_stream_runtime *rt)
0933 {
0934 struct slim_device *sdev = rt->dev;
0935 struct slim_controller *ctrl = sdev->ctrl;
0936 struct slim_val_inf msg = {0};
0937 u8 wbuf[SLIM_MSGQ_BUF_LEN];
0938 u8 rbuf[SLIM_MSGQ_BUF_LEN];
0939 struct slim_msg_txn txn = {0,};
0940 int i, ret;
0941
0942 txn.mt = SLIM_MSG_MT_DEST_REFERRED_USER;
0943 txn.dt = SLIM_MSG_DEST_LOGICALADDR;
0944 txn.la = SLIM_LA_MGR;
0945 txn.ec = 0;
0946 txn.msg = &msg;
0947 txn.msg->num_bytes = 0;
0948 txn.msg->wbuf = wbuf;
0949 txn.msg->rbuf = rbuf;
0950
0951 for (i = 0; i < rt->num_ports; i++) {
0952 struct slim_port *port = &rt->ports[i];
0953
0954 if (txn.msg->num_bytes == 0) {
0955 int seg_interval = SLIM_SLOTS_PER_SUPERFRAME/rt->ratem;
0956 int exp;
0957
0958 wbuf[txn.msg->num_bytes++] = sdev->laddr;
0959 wbuf[txn.msg->num_bytes] = rt->bps >> 2 |
0960 (port->ch.aux_fmt << 6);
0961
0962
0963 exp = seg_interval % 3;
0964 if (exp)
0965 wbuf[txn.msg->num_bytes] |= BIT(5);
0966
0967 txn.msg->num_bytes++;
0968 wbuf[txn.msg->num_bytes++] = exp << 4 | rt->prot;
0969
0970 if (rt->prot == SLIM_PROTO_ISO)
0971 wbuf[txn.msg->num_bytes++] =
0972 port->ch.prrate |
0973 SLIM_CHANNEL_CONTENT_FL;
0974 else
0975 wbuf[txn.msg->num_bytes++] = port->ch.prrate;
0976
0977 ret = slim_alloc_txn_tid(ctrl, &txn);
0978 if (ret) {
0979 dev_err(&sdev->dev, "Fail to allocate TID\n");
0980 return -ENXIO;
0981 }
0982 wbuf[txn.msg->num_bytes++] = txn.tid;
0983 }
0984 wbuf[txn.msg->num_bytes++] = port->ch.id;
0985 }
0986
0987 txn.mc = SLIM_USR_MC_DEF_ACT_CHAN;
0988 txn.rl = txn.msg->num_bytes + 4;
0989 ret = qcom_slim_ngd_xfer_msg_sync(ctrl, &txn);
0990 if (ret) {
0991 slim_free_txn_tid(ctrl, &txn);
0992 dev_err(&sdev->dev, "TX timed out:MC:0x%x,mt:0x%x", txn.mc,
0993 txn.mt);
0994 return ret;
0995 }
0996
0997 txn.mc = SLIM_USR_MC_RECONFIG_NOW;
0998 txn.msg->num_bytes = 2;
0999 wbuf[1] = sdev->laddr;
1000 txn.rl = txn.msg->num_bytes + 4;
1001
1002 ret = slim_alloc_txn_tid(ctrl, &txn);
1003 if (ret) {
1004 dev_err(ctrl->dev, "Fail to allocate TID\n");
1005 return ret;
1006 }
1007
1008 wbuf[0] = txn.tid;
1009 ret = qcom_slim_ngd_xfer_msg_sync(ctrl, &txn);
1010 if (ret) {
1011 slim_free_txn_tid(ctrl, &txn);
1012 dev_err(&sdev->dev, "TX timed out:MC:0x%x,mt:0x%x", txn.mc,
1013 txn.mt);
1014 }
1015
1016 return ret;
1017 }
1018
1019 static int qcom_slim_ngd_get_laddr(struct slim_controller *ctrl,
1020 struct slim_eaddr *ea, u8 *laddr)
1021 {
1022 struct slim_val_inf msg = {0};
1023 u8 failed_ea[6] = {0, 0, 0, 0, 0, 0};
1024 struct slim_msg_txn txn;
1025 u8 wbuf[10] = {0};
1026 u8 rbuf[10] = {0};
1027 int ret;
1028
1029 txn.mt = SLIM_MSG_MT_DEST_REFERRED_USER;
1030 txn.dt = SLIM_MSG_DEST_LOGICALADDR;
1031 txn.la = SLIM_LA_MGR;
1032 txn.ec = 0;
1033
1034 txn.mc = SLIM_USR_MC_ADDR_QUERY;
1035 txn.rl = 11;
1036 txn.msg = &msg;
1037 txn.msg->num_bytes = 7;
1038 txn.msg->wbuf = wbuf;
1039 txn.msg->rbuf = rbuf;
1040
1041 ret = slim_alloc_txn_tid(ctrl, &txn);
1042 if (ret < 0)
1043 return ret;
1044
1045 wbuf[0] = (u8)txn.tid;
1046 memcpy(&wbuf[1], ea, sizeof(*ea));
1047
1048 ret = qcom_slim_ngd_xfer_msg_sync(ctrl, &txn);
1049 if (ret) {
1050 slim_free_txn_tid(ctrl, &txn);
1051 return ret;
1052 }
1053
1054 if (!memcmp(rbuf, failed_ea, 6))
1055 return -ENXIO;
1056
1057 *laddr = rbuf[6];
1058
1059 return ret;
1060 }
1061
1062 static int qcom_slim_ngd_exit_dma(struct qcom_slim_ngd_ctrl *ctrl)
1063 {
1064 if (ctrl->dma_rx_channel) {
1065 dmaengine_terminate_sync(ctrl->dma_rx_channel);
1066 dma_release_channel(ctrl->dma_rx_channel);
1067 }
1068
1069 if (ctrl->dma_tx_channel) {
1070 dmaengine_terminate_sync(ctrl->dma_tx_channel);
1071 dma_release_channel(ctrl->dma_tx_channel);
1072 }
1073
1074 ctrl->dma_tx_channel = ctrl->dma_rx_channel = NULL;
1075
1076 return 0;
1077 }
1078
1079 static void qcom_slim_ngd_setup(struct qcom_slim_ngd_ctrl *ctrl)
1080 {
1081 u32 cfg = readl_relaxed(ctrl->ngd->base);
1082
1083 if (ctrl->state == QCOM_SLIM_NGD_CTRL_DOWN ||
1084 ctrl->state == QCOM_SLIM_NGD_CTRL_ASLEEP)
1085 qcom_slim_ngd_init_dma(ctrl);
1086
1087
1088 cfg |= NGD_CFG_RX_MSGQ_EN;
1089 cfg |= NGD_CFG_TX_MSGQ_EN;
1090
1091
1092 if (!(cfg & NGD_CFG_ENABLE))
1093 cfg |= NGD_CFG_ENABLE;
1094
1095 writel_relaxed(cfg, ctrl->ngd->base);
1096 }
1097
1098 static int qcom_slim_ngd_power_up(struct qcom_slim_ngd_ctrl *ctrl)
1099 {
1100 enum qcom_slim_ngd_state cur_state = ctrl->state;
1101 struct qcom_slim_ngd *ngd = ctrl->ngd;
1102 u32 laddr, rx_msgq;
1103 int timeout, ret = 0;
1104
1105 if (ctrl->state == QCOM_SLIM_NGD_CTRL_DOWN) {
1106 timeout = wait_for_completion_timeout(&ctrl->qmi.qmi_comp, HZ);
1107 if (!timeout)
1108 return -EREMOTEIO;
1109 }
1110
1111 if (ctrl->state == QCOM_SLIM_NGD_CTRL_ASLEEP ||
1112 ctrl->state == QCOM_SLIM_NGD_CTRL_DOWN) {
1113 ret = qcom_slim_qmi_power_request(ctrl, true);
1114 if (ret) {
1115 dev_err(ctrl->dev, "SLIM QMI power request failed:%d\n",
1116 ret);
1117 return ret;
1118 }
1119 }
1120
1121 ctrl->ver = readl_relaxed(ctrl->base);
1122
1123 ctrl->ver >>= 16;
1124
1125 laddr = readl_relaxed(ngd->base + NGD_STATUS);
1126 if (laddr & NGD_LADDR) {
1127
1128
1129
1130
1131 if (cur_state == QCOM_SLIM_NGD_CTRL_AWAKE) {
1132 dev_info(ctrl->dev, "Subsys restart: ADSP active framer\n");
1133 return 0;
1134 }
1135 qcom_slim_ngd_setup(ctrl);
1136 return 0;
1137 }
1138
1139 writel_relaxed(DEF_NGD_INT_MASK, ngd->base + NGD_INT_EN);
1140 rx_msgq = readl_relaxed(ngd->base + NGD_RX_MSGQ_CFG);
1141
1142 writel_relaxed(rx_msgq|SLIM_RX_MSGQ_TIMEOUT_VAL,
1143 ngd->base + NGD_RX_MSGQ_CFG);
1144 qcom_slim_ngd_setup(ctrl);
1145
1146 timeout = wait_for_completion_timeout(&ctrl->reconf, HZ);
1147 if (!timeout) {
1148 dev_err(ctrl->dev, "capability exchange timed-out\n");
1149 return -ETIMEDOUT;
1150 }
1151
1152 return 0;
1153 }
1154
1155 static void qcom_slim_ngd_notify_slaves(struct qcom_slim_ngd_ctrl *ctrl)
1156 {
1157 struct slim_device *sbdev;
1158 struct device_node *node;
1159
1160 for_each_child_of_node(ctrl->ngd->pdev->dev.of_node, node) {
1161 sbdev = of_slim_get_device(&ctrl->ctrl, node);
1162 if (!sbdev)
1163 continue;
1164
1165 if (slim_get_logical_addr(sbdev))
1166 dev_err(ctrl->dev, "Failed to get logical address\n");
1167 }
1168 }
1169
1170 static void qcom_slim_ngd_master_worker(struct work_struct *work)
1171 {
1172 struct qcom_slim_ngd_ctrl *ctrl;
1173 struct slim_msg_txn txn;
1174 struct slim_val_inf msg = {0};
1175 int retries = 0;
1176 u8 wbuf[8];
1177 int ret = 0;
1178
1179 ctrl = container_of(work, struct qcom_slim_ngd_ctrl, m_work);
1180 txn.dt = SLIM_MSG_DEST_LOGICALADDR;
1181 txn.ec = 0;
1182 txn.mc = SLIM_USR_MC_REPORT_SATELLITE;
1183 txn.mt = SLIM_MSG_MT_SRC_REFERRED_USER;
1184 txn.la = SLIM_LA_MGR;
1185 wbuf[0] = SAT_MAGIC_LSB;
1186 wbuf[1] = SAT_MAGIC_MSB;
1187 wbuf[2] = SAT_MSG_VER;
1188 wbuf[3] = SAT_MSG_PROT;
1189 txn.msg = &msg;
1190 txn.msg->wbuf = wbuf;
1191 txn.msg->num_bytes = 4;
1192 txn.rl = 8;
1193
1194 dev_info(ctrl->dev, "SLIM SAT: Rcvd master capability\n");
1195
1196 capability_retry:
1197 ret = qcom_slim_ngd_xfer_msg(&ctrl->ctrl, &txn);
1198 if (!ret) {
1199 if (ctrl->state >= QCOM_SLIM_NGD_CTRL_ASLEEP)
1200 complete(&ctrl->reconf);
1201 else
1202 dev_err(ctrl->dev, "unexpected state:%d\n",
1203 ctrl->state);
1204
1205 if (ctrl->state == QCOM_SLIM_NGD_CTRL_DOWN)
1206 qcom_slim_ngd_notify_slaves(ctrl);
1207
1208 } else if (ret == -EIO) {
1209 dev_err(ctrl->dev, "capability message NACKed, retrying\n");
1210 if (retries < INIT_MX_RETRIES) {
1211 msleep(DEF_RETRY_MS);
1212 retries++;
1213 goto capability_retry;
1214 }
1215 } else {
1216 dev_err(ctrl->dev, "SLIM: capability TX failed:%d\n", ret);
1217 }
1218 }
1219
1220 static int qcom_slim_ngd_update_device_status(struct device *dev, void *null)
1221 {
1222 slim_report_absent(to_slim_device(dev));
1223
1224 return 0;
1225 }
1226
1227 static int qcom_slim_ngd_runtime_resume(struct device *dev)
1228 {
1229 struct qcom_slim_ngd_ctrl *ctrl = dev_get_drvdata(dev);
1230 int ret = 0;
1231
1232 if (!ctrl->qmi.handle)
1233 return 0;
1234
1235 if (ctrl->state >= QCOM_SLIM_NGD_CTRL_ASLEEP)
1236 ret = qcom_slim_ngd_power_up(ctrl);
1237 if (ret) {
1238
1239 if (ctrl->state != QCOM_SLIM_NGD_CTRL_DOWN)
1240 ctrl->state = QCOM_SLIM_NGD_CTRL_ASLEEP;
1241 else
1242 dev_err(ctrl->dev, "HW wakeup attempt during SSR\n");
1243 } else {
1244 ctrl->state = QCOM_SLIM_NGD_CTRL_AWAKE;
1245 }
1246
1247 return 0;
1248 }
1249
1250 static int qcom_slim_ngd_enable(struct qcom_slim_ngd_ctrl *ctrl, bool enable)
1251 {
1252 if (enable) {
1253 int ret = qcom_slim_qmi_init(ctrl, false);
1254
1255 if (ret) {
1256 dev_err(ctrl->dev, "qmi init fail, ret:%d, state:%d\n",
1257 ret, ctrl->state);
1258 return ret;
1259 }
1260
1261 complete(&ctrl->qmi.qmi_comp);
1262 if (!pm_runtime_enabled(ctrl->ctrl.dev) ||
1263 !pm_runtime_suspended(ctrl->ctrl.dev))
1264 qcom_slim_ngd_runtime_resume(ctrl->ctrl.dev);
1265 else
1266 pm_runtime_resume(ctrl->ctrl.dev);
1267
1268 pm_runtime_mark_last_busy(ctrl->ctrl.dev);
1269 pm_runtime_put(ctrl->ctrl.dev);
1270
1271 ret = slim_register_controller(&ctrl->ctrl);
1272 if (ret) {
1273 dev_err(ctrl->dev, "error adding slim controller\n");
1274 return ret;
1275 }
1276
1277 dev_info(ctrl->dev, "SLIM controller Registered\n");
1278 } else {
1279 qcom_slim_qmi_exit(ctrl);
1280 slim_unregister_controller(&ctrl->ctrl);
1281 }
1282
1283 return 0;
1284 }
1285
1286 static int qcom_slim_ngd_qmi_new_server(struct qmi_handle *hdl,
1287 struct qmi_service *service)
1288 {
1289 struct qcom_slim_ngd_qmi *qmi =
1290 container_of(hdl, struct qcom_slim_ngd_qmi, svc_event_hdl);
1291 struct qcom_slim_ngd_ctrl *ctrl =
1292 container_of(qmi, struct qcom_slim_ngd_ctrl, qmi);
1293
1294 qmi->svc_info.sq_family = AF_QIPCRTR;
1295 qmi->svc_info.sq_node = service->node;
1296 qmi->svc_info.sq_port = service->port;
1297
1298 complete(&ctrl->qmi_up);
1299
1300 return 0;
1301 }
1302
1303 static void qcom_slim_ngd_qmi_del_server(struct qmi_handle *hdl,
1304 struct qmi_service *service)
1305 {
1306 struct qcom_slim_ngd_qmi *qmi =
1307 container_of(hdl, struct qcom_slim_ngd_qmi, svc_event_hdl);
1308 struct qcom_slim_ngd_ctrl *ctrl =
1309 container_of(qmi, struct qcom_slim_ngd_ctrl, qmi);
1310
1311 reinit_completion(&ctrl->qmi_up);
1312 qmi->svc_info.sq_node = 0;
1313 qmi->svc_info.sq_port = 0;
1314 }
1315
1316 static const struct qmi_ops qcom_slim_ngd_qmi_svc_event_ops = {
1317 .new_server = qcom_slim_ngd_qmi_new_server,
1318 .del_server = qcom_slim_ngd_qmi_del_server,
1319 };
1320
1321 static int qcom_slim_ngd_qmi_svc_event_init(struct qcom_slim_ngd_ctrl *ctrl)
1322 {
1323 struct qcom_slim_ngd_qmi *qmi = &ctrl->qmi;
1324 int ret;
1325
1326 ret = qmi_handle_init(&qmi->svc_event_hdl, 0,
1327 &qcom_slim_ngd_qmi_svc_event_ops, NULL);
1328 if (ret < 0) {
1329 dev_err(ctrl->dev, "qmi_handle_init failed: %d\n", ret);
1330 return ret;
1331 }
1332
1333 ret = qmi_add_lookup(&qmi->svc_event_hdl, SLIMBUS_QMI_SVC_ID,
1334 SLIMBUS_QMI_SVC_V1, SLIMBUS_QMI_INS_ID);
1335 if (ret < 0) {
1336 dev_err(ctrl->dev, "qmi_add_lookup failed: %d\n", ret);
1337 qmi_handle_release(&qmi->svc_event_hdl);
1338 }
1339 return ret;
1340 }
1341
1342 static void qcom_slim_ngd_qmi_svc_event_deinit(struct qcom_slim_ngd_qmi *qmi)
1343 {
1344 qmi_handle_release(&qmi->svc_event_hdl);
1345 }
1346
1347 static struct platform_driver qcom_slim_ngd_driver;
1348 #define QCOM_SLIM_NGD_DRV_NAME "qcom,slim-ngd"
1349
1350 static const struct of_device_id qcom_slim_ngd_dt_match[] = {
1351 {
1352 .compatible = "qcom,slim-ngd-v1.5.0",
1353 .data = &ngd_v1_5_offset_info,
1354 },{
1355 .compatible = "qcom,slim-ngd-v2.1.0",
1356 .data = &ngd_v1_5_offset_info,
1357 },
1358 {}
1359 };
1360
1361 MODULE_DEVICE_TABLE(of, qcom_slim_ngd_dt_match);
1362
1363 static void qcom_slim_ngd_down(struct qcom_slim_ngd_ctrl *ctrl)
1364 {
1365 mutex_lock(&ctrl->ssr_lock);
1366 device_for_each_child(ctrl->ctrl.dev, NULL,
1367 qcom_slim_ngd_update_device_status);
1368 qcom_slim_ngd_enable(ctrl, false);
1369 mutex_unlock(&ctrl->ssr_lock);
1370 }
1371
1372 static void qcom_slim_ngd_up_worker(struct work_struct *work)
1373 {
1374 struct qcom_slim_ngd_ctrl *ctrl;
1375
1376 ctrl = container_of(work, struct qcom_slim_ngd_ctrl, ngd_up_work);
1377
1378
1379 wait_for_completion_interruptible(&ctrl->qmi_up);
1380
1381 mutex_lock(&ctrl->ssr_lock);
1382 qcom_slim_ngd_enable(ctrl, true);
1383 mutex_unlock(&ctrl->ssr_lock);
1384 }
1385
1386 static int qcom_slim_ngd_ssr_pdr_notify(struct qcom_slim_ngd_ctrl *ctrl,
1387 unsigned long action)
1388 {
1389 switch (action) {
1390 case QCOM_SSR_BEFORE_SHUTDOWN:
1391 case SERVREG_SERVICE_STATE_DOWN:
1392
1393 mutex_lock(&ctrl->tx_lock);
1394 if (ctrl->state != QCOM_SLIM_NGD_CTRL_DOWN) {
1395 pm_runtime_get_noresume(ctrl->ctrl.dev);
1396 ctrl->state = QCOM_SLIM_NGD_CTRL_DOWN;
1397 qcom_slim_ngd_down(ctrl);
1398 qcom_slim_ngd_exit_dma(ctrl);
1399 }
1400 mutex_unlock(&ctrl->tx_lock);
1401 break;
1402 case QCOM_SSR_AFTER_POWERUP:
1403 case SERVREG_SERVICE_STATE_UP:
1404 schedule_work(&ctrl->ngd_up_work);
1405 break;
1406 default:
1407 break;
1408 }
1409
1410 return NOTIFY_OK;
1411 }
1412
1413 static int qcom_slim_ngd_ssr_notify(struct notifier_block *nb,
1414 unsigned long action,
1415 void *data)
1416 {
1417 struct qcom_slim_ngd_ctrl *ctrl = container_of(nb,
1418 struct qcom_slim_ngd_ctrl, nb);
1419
1420 return qcom_slim_ngd_ssr_pdr_notify(ctrl, action);
1421 }
1422
1423 static void slim_pd_status(int state, char *svc_path, void *priv)
1424 {
1425 struct qcom_slim_ngd_ctrl *ctrl = (struct qcom_slim_ngd_ctrl *)priv;
1426
1427 qcom_slim_ngd_ssr_pdr_notify(ctrl, state);
1428 }
1429 static int of_qcom_slim_ngd_register(struct device *parent,
1430 struct qcom_slim_ngd_ctrl *ctrl)
1431 {
1432 const struct ngd_reg_offset_data *data;
1433 struct qcom_slim_ngd *ngd;
1434 const struct of_device_id *match;
1435 struct device_node *node;
1436 u32 id;
1437 int ret;
1438
1439 match = of_match_node(qcom_slim_ngd_dt_match, parent->of_node);
1440 data = match->data;
1441 for_each_available_child_of_node(parent->of_node, node) {
1442 if (of_property_read_u32(node, "reg", &id))
1443 continue;
1444
1445 ngd = kzalloc(sizeof(*ngd), GFP_KERNEL);
1446 if (!ngd) {
1447 of_node_put(node);
1448 return -ENOMEM;
1449 }
1450
1451 ngd->pdev = platform_device_alloc(QCOM_SLIM_NGD_DRV_NAME, id);
1452 if (!ngd->pdev) {
1453 kfree(ngd);
1454 of_node_put(node);
1455 return -ENOMEM;
1456 }
1457 ngd->id = id;
1458 ngd->pdev->dev.parent = parent;
1459
1460 ret = driver_set_override(&ngd->pdev->dev,
1461 &ngd->pdev->driver_override,
1462 QCOM_SLIM_NGD_DRV_NAME,
1463 strlen(QCOM_SLIM_NGD_DRV_NAME));
1464 if (ret) {
1465 platform_device_put(ngd->pdev);
1466 kfree(ngd);
1467 of_node_put(node);
1468 return ret;
1469 }
1470 ngd->pdev->dev.of_node = node;
1471 ctrl->ngd = ngd;
1472
1473 platform_device_add(ngd->pdev);
1474 ngd->base = ctrl->base + ngd->id * data->offset +
1475 (ngd->id - 1) * data->size;
1476
1477 return 0;
1478 }
1479
1480 return -ENODEV;
1481 }
1482
1483 static int qcom_slim_ngd_probe(struct platform_device *pdev)
1484 {
1485 struct device *dev = &pdev->dev;
1486 struct qcom_slim_ngd_ctrl *ctrl = dev_get_drvdata(dev->parent);
1487 int ret;
1488
1489 ctrl->ctrl.dev = dev;
1490
1491 platform_set_drvdata(pdev, ctrl);
1492 pm_runtime_use_autosuspend(dev);
1493 pm_runtime_set_autosuspend_delay(dev, QCOM_SLIM_NGD_AUTOSUSPEND);
1494 pm_runtime_set_suspended(dev);
1495 pm_runtime_enable(dev);
1496 pm_runtime_get_noresume(dev);
1497 ret = qcom_slim_ngd_qmi_svc_event_init(ctrl);
1498 if (ret) {
1499 dev_err(&pdev->dev, "QMI service registration failed:%d", ret);
1500 return ret;
1501 }
1502
1503 INIT_WORK(&ctrl->m_work, qcom_slim_ngd_master_worker);
1504 INIT_WORK(&ctrl->ngd_up_work, qcom_slim_ngd_up_worker);
1505 ctrl->mwq = create_singlethread_workqueue("ngd_master");
1506 if (!ctrl->mwq) {
1507 dev_err(&pdev->dev, "Failed to start master worker\n");
1508 ret = -ENOMEM;
1509 goto wq_err;
1510 }
1511
1512 return 0;
1513 wq_err:
1514 qcom_slim_ngd_qmi_svc_event_deinit(&ctrl->qmi);
1515 if (ctrl->mwq)
1516 destroy_workqueue(ctrl->mwq);
1517
1518 return ret;
1519 }
1520
1521 static int qcom_slim_ngd_ctrl_probe(struct platform_device *pdev)
1522 {
1523 struct device *dev = &pdev->dev;
1524 struct qcom_slim_ngd_ctrl *ctrl;
1525 struct resource *res;
1526 int ret;
1527 struct pdr_service *pds;
1528
1529 ctrl = devm_kzalloc(dev, sizeof(*ctrl), GFP_KERNEL);
1530 if (!ctrl)
1531 return -ENOMEM;
1532
1533 dev_set_drvdata(dev, ctrl);
1534
1535 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1536 ctrl->base = devm_ioremap_resource(dev, res);
1537 if (IS_ERR(ctrl->base))
1538 return PTR_ERR(ctrl->base);
1539
1540 ret = platform_get_irq(pdev, 0);
1541 if (ret < 0)
1542 return ret;
1543
1544 ret = devm_request_irq(dev, ret, qcom_slim_ngd_interrupt,
1545 IRQF_TRIGGER_HIGH, "slim-ngd", ctrl);
1546 if (ret) {
1547 dev_err(&pdev->dev, "request IRQ failed\n");
1548 return ret;
1549 }
1550
1551 ctrl->nb.notifier_call = qcom_slim_ngd_ssr_notify;
1552 ctrl->notifier = qcom_register_ssr_notifier("lpass", &ctrl->nb);
1553 if (IS_ERR(ctrl->notifier))
1554 return PTR_ERR(ctrl->notifier);
1555
1556 ctrl->dev = dev;
1557 ctrl->framer.rootfreq = SLIM_ROOT_FREQ >> 3;
1558 ctrl->framer.superfreq =
1559 ctrl->framer.rootfreq / SLIM_CL_PER_SUPERFRAME_DIV8;
1560
1561 ctrl->ctrl.a_framer = &ctrl->framer;
1562 ctrl->ctrl.clkgear = SLIM_MAX_CLK_GEAR;
1563 ctrl->ctrl.get_laddr = qcom_slim_ngd_get_laddr;
1564 ctrl->ctrl.enable_stream = qcom_slim_ngd_enable_stream;
1565 ctrl->ctrl.xfer_msg = qcom_slim_ngd_xfer_msg;
1566 ctrl->ctrl.wakeup = NULL;
1567 ctrl->state = QCOM_SLIM_NGD_CTRL_DOWN;
1568
1569 mutex_init(&ctrl->tx_lock);
1570 mutex_init(&ctrl->ssr_lock);
1571 spin_lock_init(&ctrl->tx_buf_lock);
1572 init_completion(&ctrl->reconf);
1573 init_completion(&ctrl->qmi.qmi_comp);
1574 init_completion(&ctrl->qmi_up);
1575
1576 ctrl->pdr = pdr_handle_alloc(slim_pd_status, ctrl);
1577 if (IS_ERR(ctrl->pdr)) {
1578 dev_err(dev, "Failed to init PDR handle\n");
1579 return PTR_ERR(ctrl->pdr);
1580 }
1581
1582 pds = pdr_add_lookup(ctrl->pdr, "avs/audio", "msm/adsp/audio_pd");
1583 if (IS_ERR(pds) && PTR_ERR(pds) != -EALREADY) {
1584 dev_err(dev, "pdr add lookup failed: %d\n", ret);
1585 return PTR_ERR(pds);
1586 }
1587
1588 platform_driver_register(&qcom_slim_ngd_driver);
1589 return of_qcom_slim_ngd_register(dev, ctrl);
1590 }
1591
1592 static int qcom_slim_ngd_ctrl_remove(struct platform_device *pdev)
1593 {
1594 platform_driver_unregister(&qcom_slim_ngd_driver);
1595
1596 return 0;
1597 }
1598
1599 static int qcom_slim_ngd_remove(struct platform_device *pdev)
1600 {
1601 struct qcom_slim_ngd_ctrl *ctrl = platform_get_drvdata(pdev);
1602
1603 pm_runtime_disable(&pdev->dev);
1604 pdr_handle_release(ctrl->pdr);
1605 qcom_unregister_ssr_notifier(ctrl->notifier, &ctrl->nb);
1606 qcom_slim_ngd_enable(ctrl, false);
1607 qcom_slim_ngd_exit_dma(ctrl);
1608 qcom_slim_ngd_qmi_svc_event_deinit(&ctrl->qmi);
1609 if (ctrl->mwq)
1610 destroy_workqueue(ctrl->mwq);
1611
1612 kfree(ctrl->ngd);
1613 ctrl->ngd = NULL;
1614 return 0;
1615 }
1616
1617 static int __maybe_unused qcom_slim_ngd_runtime_idle(struct device *dev)
1618 {
1619 struct qcom_slim_ngd_ctrl *ctrl = dev_get_drvdata(dev);
1620
1621 if (ctrl->state == QCOM_SLIM_NGD_CTRL_AWAKE)
1622 ctrl->state = QCOM_SLIM_NGD_CTRL_IDLE;
1623 pm_request_autosuspend(dev);
1624 return -EAGAIN;
1625 }
1626
1627 static int __maybe_unused qcom_slim_ngd_runtime_suspend(struct device *dev)
1628 {
1629 struct qcom_slim_ngd_ctrl *ctrl = dev_get_drvdata(dev);
1630 int ret = 0;
1631
1632 qcom_slim_ngd_exit_dma(ctrl);
1633 if (!ctrl->qmi.handle)
1634 return 0;
1635
1636 ret = qcom_slim_qmi_power_request(ctrl, false);
1637 if (ret && ret != -EBUSY)
1638 dev_info(ctrl->dev, "slim resource not idle:%d\n", ret);
1639 if (!ret || ret == -ETIMEDOUT)
1640 ctrl->state = QCOM_SLIM_NGD_CTRL_ASLEEP;
1641
1642 return ret;
1643 }
1644
1645 static const struct dev_pm_ops qcom_slim_ngd_dev_pm_ops = {
1646 SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
1647 pm_runtime_force_resume)
1648 SET_RUNTIME_PM_OPS(
1649 qcom_slim_ngd_runtime_suspend,
1650 qcom_slim_ngd_runtime_resume,
1651 qcom_slim_ngd_runtime_idle
1652 )
1653 };
1654
1655 static struct platform_driver qcom_slim_ngd_ctrl_driver = {
1656 .probe = qcom_slim_ngd_ctrl_probe,
1657 .remove = qcom_slim_ngd_ctrl_remove,
1658 .driver = {
1659 .name = "qcom,slim-ngd-ctrl",
1660 .of_match_table = qcom_slim_ngd_dt_match,
1661 },
1662 };
1663
1664 static struct platform_driver qcom_slim_ngd_driver = {
1665 .probe = qcom_slim_ngd_probe,
1666 .remove = qcom_slim_ngd_remove,
1667 .driver = {
1668 .name = QCOM_SLIM_NGD_DRV_NAME,
1669 .pm = &qcom_slim_ngd_dev_pm_ops,
1670 },
1671 };
1672
1673 module_platform_driver(qcom_slim_ngd_ctrl_driver);
1674 MODULE_LICENSE("GPL v2");
1675 MODULE_DESCRIPTION("Qualcomm SLIMBus NGD controller");