1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Copyright (c) 2019, Linaro Ltd 4 */ 5 #include <dt-bindings/power/qcom-aoss-qmp.h> 6 #include <linux/clk-provider.h> 7 #include <linux/interrupt.h> 8 #include <linux/io.h> 9 #include <linux/mailbox_client.h> 10 #include <linux/module.h> 11 #include <linux/platform_device.h> 12 #include <linux/pm_domain.h> 13 14 #define QMP_DESC_MAGIC 0x0 15 #define QMP_DESC_VERSION 0x4 16 #define QMP_DESC_FEATURES 0x8 17 18 /* AOP-side offsets */ 19 #define QMP_DESC_UCORE_LINK_STATE 0xc 20 #define QMP_DESC_UCORE_LINK_STATE_ACK 0x10 21 #define QMP_DESC_UCORE_CH_STATE 0x14 22 #define QMP_DESC_UCORE_CH_STATE_ACK 0x18 23 #define QMP_DESC_UCORE_MBOX_SIZE 0x1c 24 #define QMP_DESC_UCORE_MBOX_OFFSET 0x20 25 26 /* Linux-side offsets */ 27 #define QMP_DESC_MCORE_LINK_STATE 0x24 28 #define QMP_DESC_MCORE_LINK_STATE_ACK 0x28 29 #define QMP_DESC_MCORE_CH_STATE 0x2c 30 #define QMP_DESC_MCORE_CH_STATE_ACK 0x30 31 #define QMP_DESC_MCORE_MBOX_SIZE 0x34 32 #define QMP_DESC_MCORE_MBOX_OFFSET 0x38 33 34 #define QMP_STATE_UP GENMASK(15, 0) 35 #define QMP_STATE_DOWN GENMASK(31, 16) 36 37 #define QMP_MAGIC 0x4d41494c /* mail */ 38 #define QMP_VERSION 1 39 40 /* 64 bytes is enough to store the requests and provides padding to 4 bytes */ 41 #define QMP_MSG_LEN 64 42 43 /** 44 * struct qmp - driver state for QMP implementation 45 * @msgram: iomem referencing the message RAM used for communication 46 * @dev: reference to QMP device 47 * @mbox_client: mailbox client used to ring the doorbell on transmit 48 * @mbox_chan: mailbox channel used to ring the doorbell on transmit 49 * @offset: offset within @msgram where messages should be written 50 * @size: maximum size of the messages to be transmitted 51 * @event: wait_queue for synchronization with the IRQ 52 * @tx_lock: provides synchronization between multiple callers of qmp_send() 53 * @qdss_clk: QDSS clock hw struct 54 * @pd_data: genpd data 55 */ 56 struct qmp { 57 void __iomem *msgram; 58 struct device *dev; 59 60 struct mbox_client mbox_client; 61 struct mbox_chan *mbox_chan; 62 63 size_t offset; 64 size_t size; 65 66 wait_queue_head_t event; 67 68 struct mutex tx_lock; 69 70 struct clk_hw qdss_clk; 71 struct genpd_onecell_data pd_data; 72 }; 73 74 struct qmp_pd { 75 struct qmp *qmp; 76 struct generic_pm_domain pd; 77 }; 78 79 #define to_qmp_pd_resource(res) container_of(res, struct qmp_pd, pd) 80 81 static void qmp_kick(struct qmp *qmp) 82 { 83 mbox_send_message(qmp->mbox_chan, NULL); 84 mbox_client_txdone(qmp->mbox_chan, 0); 85 } 86 87 static bool qmp_magic_valid(struct qmp *qmp) 88 { 89 return readl(qmp->msgram + QMP_DESC_MAGIC) == QMP_MAGIC; 90 } 91 92 static bool qmp_link_acked(struct qmp *qmp) 93 { 94 return readl(qmp->msgram + QMP_DESC_MCORE_LINK_STATE_ACK) == QMP_STATE_UP; 95 } 96 97 static bool qmp_mcore_channel_acked(struct qmp *qmp) 98 { 99 return readl(qmp->msgram + QMP_DESC_MCORE_CH_STATE_ACK) == QMP_STATE_UP; 100 } 101 102 static bool qmp_ucore_channel_up(struct qmp *qmp) 103 { 104 return readl(qmp->msgram + QMP_DESC_UCORE_CH_STATE) == QMP_STATE_UP; 105 } 106 107 static int qmp_open(struct qmp *qmp) 108 { 109 int ret; 110 u32 val; 111 112 if (!qmp_magic_valid(qmp)) { 113 dev_err(qmp->dev, "QMP magic doesn't match\n"); 114 return -EINVAL; 115 } 116 117 val = readl(qmp->msgram + QMP_DESC_VERSION); 118 if (val != QMP_VERSION) { 119 dev_err(qmp->dev, "unsupported QMP version %d\n", val); 120 return -EINVAL; 121 } 122 123 qmp->offset = readl(qmp->msgram + QMP_DESC_MCORE_MBOX_OFFSET); 124 qmp->size = readl(qmp->msgram + QMP_DESC_MCORE_MBOX_SIZE); 125 if (!qmp->size) { 126 dev_err(qmp->dev, "invalid mailbox size\n"); 127 return -EINVAL; 128 } 129 130 /* Ack remote core's link state */ 131 val = readl(qmp->msgram + QMP_DESC_UCORE_LINK_STATE); 132 writel(val, qmp->msgram + QMP_DESC_UCORE_LINK_STATE_ACK); 133 134 /* Set local core's link state to up */ 135 writel(QMP_STATE_UP, qmp->msgram + QMP_DESC_MCORE_LINK_STATE); 136 137 qmp_kick(qmp); 138 139 ret = wait_event_timeout(qmp->event, qmp_link_acked(qmp), HZ); 140 if (!ret) { 141 dev_err(qmp->dev, "ucore didn't ack link\n"); 142 goto timeout_close_link; 143 } 144 145 writel(QMP_STATE_UP, qmp->msgram + QMP_DESC_MCORE_CH_STATE); 146 147 qmp_kick(qmp); 148 149 ret = wait_event_timeout(qmp->event, qmp_ucore_channel_up(qmp), HZ); 150 if (!ret) { 151 dev_err(qmp->dev, "ucore didn't open channel\n"); 152 goto timeout_close_channel; 153 } 154 155 /* Ack remote core's channel state */ 156 writel(QMP_STATE_UP, qmp->msgram + QMP_DESC_UCORE_CH_STATE_ACK); 157 158 qmp_kick(qmp); 159 160 ret = wait_event_timeout(qmp->event, qmp_mcore_channel_acked(qmp), HZ); 161 if (!ret) { 162 dev_err(qmp->dev, "ucore didn't ack channel\n"); 163 goto timeout_close_channel; 164 } 165 166 return 0; 167 168 timeout_close_channel: 169 writel(QMP_STATE_DOWN, qmp->msgram + QMP_DESC_MCORE_CH_STATE); 170 171 timeout_close_link: 172 writel(QMP_STATE_DOWN, qmp->msgram + QMP_DESC_MCORE_LINK_STATE); 173 qmp_kick(qmp); 174 175 return -ETIMEDOUT; 176 } 177 178 static void qmp_close(struct qmp *qmp) 179 { 180 writel(QMP_STATE_DOWN, qmp->msgram + QMP_DESC_MCORE_CH_STATE); 181 writel(QMP_STATE_DOWN, qmp->msgram + QMP_DESC_MCORE_LINK_STATE); 182 qmp_kick(qmp); 183 } 184 185 static irqreturn_t qmp_intr(int irq, void *data) 186 { 187 struct qmp *qmp = data; 188 189 wake_up_interruptible_all(&qmp->event); 190 191 return IRQ_HANDLED; 192 } 193 194 static bool qmp_message_empty(struct qmp *qmp) 195 { 196 return readl(qmp->msgram + qmp->offset) == 0; 197 } 198 199 /** 200 * qmp_send() - send a message to the AOSS 201 * @qmp: qmp context 202 * @data: message to be sent 203 * @len: length of the message 204 * 205 * Transmit @data to AOSS and wait for the AOSS to acknowledge the message. 206 * @len must be a multiple of 4 and not longer than the mailbox size. Access is 207 * synchronized by this implementation. 208 * 209 * Return: 0 on success, negative errno on failure 210 */ 211 static int qmp_send(struct qmp *qmp, const void *data, size_t len) 212 { 213 long time_left; 214 int ret; 215 216 if (WARN_ON(len + sizeof(u32) > qmp->size)) 217 return -EINVAL; 218 219 if (WARN_ON(len % sizeof(u32))) 220 return -EINVAL; 221 222 mutex_lock(&qmp->tx_lock); 223 224 /* The message RAM only implements 32-bit accesses */ 225 __iowrite32_copy(qmp->msgram + qmp->offset + sizeof(u32), 226 data, len / sizeof(u32)); 227 writel(len, qmp->msgram + qmp->offset); 228 qmp_kick(qmp); 229 230 time_left = wait_event_interruptible_timeout(qmp->event, 231 qmp_message_empty(qmp), HZ); 232 if (!time_left) { 233 dev_err(qmp->dev, "ucore did not ack channel\n"); 234 ret = -ETIMEDOUT; 235 236 /* Clear message from buffer */ 237 writel(0, qmp->msgram + qmp->offset); 238 } else { 239 ret = 0; 240 } 241 242 mutex_unlock(&qmp->tx_lock); 243 244 return ret; 245 } 246 247 static int qmp_qdss_clk_prepare(struct clk_hw *hw) 248 { 249 static const char buf[QMP_MSG_LEN] = "{class: clock, res: qdss, val: 1}"; 250 struct qmp *qmp = container_of(hw, struct qmp, qdss_clk); 251 252 return qmp_send(qmp, buf, sizeof(buf)); 253 } 254 255 static void qmp_qdss_clk_unprepare(struct clk_hw *hw) 256 { 257 static const char buf[QMP_MSG_LEN] = "{class: clock, res: qdss, val: 0}"; 258 struct qmp *qmp = container_of(hw, struct qmp, qdss_clk); 259 260 qmp_send(qmp, buf, sizeof(buf)); 261 } 262 263 static const struct clk_ops qmp_qdss_clk_ops = { 264 .prepare = qmp_qdss_clk_prepare, 265 .unprepare = qmp_qdss_clk_unprepare, 266 }; 267 268 static int qmp_qdss_clk_add(struct qmp *qmp) 269 { 270 static const struct clk_init_data qdss_init = { 271 .ops = &qmp_qdss_clk_ops, 272 .name = "qdss", 273 }; 274 int ret; 275 276 qmp->qdss_clk.init = &qdss_init; 277 ret = clk_hw_register(qmp->dev, &qmp->qdss_clk); 278 if (ret < 0) { 279 dev_err(qmp->dev, "failed to register qdss clock\n"); 280 return ret; 281 } 282 283 ret = of_clk_add_hw_provider(qmp->dev->of_node, of_clk_hw_simple_get, 284 &qmp->qdss_clk); 285 if (ret < 0) { 286 dev_err(qmp->dev, "unable to register of clk hw provider\n"); 287 clk_hw_unregister(&qmp->qdss_clk); 288 } 289 290 return ret; 291 } 292 293 static void qmp_qdss_clk_remove(struct qmp *qmp) 294 { 295 of_clk_del_provider(qmp->dev->of_node); 296 clk_hw_unregister(&qmp->qdss_clk); 297 } 298 299 static int qmp_pd_power_toggle(struct qmp_pd *res, bool enable) 300 { 301 char buf[QMP_MSG_LEN] = {}; 302 303 snprintf(buf, sizeof(buf), 304 "{class: image, res: load_state, name: %s, val: %s}", 305 res->pd.name, enable ? "on" : "off"); 306 return qmp_send(res->qmp, buf, sizeof(buf)); 307 } 308 309 static int qmp_pd_power_on(struct generic_pm_domain *domain) 310 { 311 return qmp_pd_power_toggle(to_qmp_pd_resource(domain), true); 312 } 313 314 static int qmp_pd_power_off(struct generic_pm_domain *domain) 315 { 316 return qmp_pd_power_toggle(to_qmp_pd_resource(domain), false); 317 } 318 319 static const char * const sdm845_resources[] = { 320 [AOSS_QMP_LS_CDSP] = "cdsp", 321 [AOSS_QMP_LS_LPASS] = "adsp", 322 [AOSS_QMP_LS_MODEM] = "modem", 323 [AOSS_QMP_LS_SLPI] = "slpi", 324 [AOSS_QMP_LS_SPSS] = "spss", 325 [AOSS_QMP_LS_VENUS] = "venus", 326 }; 327 328 static int qmp_pd_add(struct qmp *qmp) 329 { 330 struct genpd_onecell_data *data = &qmp->pd_data; 331 struct device *dev = qmp->dev; 332 struct qmp_pd *res; 333 size_t num = ARRAY_SIZE(sdm845_resources); 334 int ret; 335 int i; 336 337 res = devm_kcalloc(dev, num, sizeof(*res), GFP_KERNEL); 338 if (!res) 339 return -ENOMEM; 340 341 data->domains = devm_kcalloc(dev, num, sizeof(*data->domains), 342 GFP_KERNEL); 343 if (!data->domains) 344 return -ENOMEM; 345 346 for (i = 0; i < num; i++) { 347 res[i].qmp = qmp; 348 res[i].pd.name = sdm845_resources[i]; 349 res[i].pd.power_on = qmp_pd_power_on; 350 res[i].pd.power_off = qmp_pd_power_off; 351 352 ret = pm_genpd_init(&res[i].pd, NULL, true); 353 if (ret < 0) { 354 dev_err(dev, "failed to init genpd\n"); 355 goto unroll_genpds; 356 } 357 358 data->domains[i] = &res[i].pd; 359 } 360 361 data->num_domains = i; 362 363 ret = of_genpd_add_provider_onecell(dev->of_node, data); 364 if (ret < 0) 365 goto unroll_genpds; 366 367 return 0; 368 369 unroll_genpds: 370 for (i--; i >= 0; i--) 371 pm_genpd_remove(data->domains[i]); 372 373 return ret; 374 } 375 376 static void qmp_pd_remove(struct qmp *qmp) 377 { 378 struct genpd_onecell_data *data = &qmp->pd_data; 379 struct device *dev = qmp->dev; 380 int i; 381 382 of_genpd_del_provider(dev->of_node); 383 384 for (i = 0; i < data->num_domains; i++) 385 pm_genpd_remove(data->domains[i]); 386 } 387 388 static int qmp_probe(struct platform_device *pdev) 389 { 390 struct resource *res; 391 struct qmp *qmp; 392 int irq; 393 int ret; 394 395 qmp = devm_kzalloc(&pdev->dev, sizeof(*qmp), GFP_KERNEL); 396 if (!qmp) 397 return -ENOMEM; 398 399 qmp->dev = &pdev->dev; 400 init_waitqueue_head(&qmp->event); 401 mutex_init(&qmp->tx_lock); 402 403 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 404 qmp->msgram = devm_ioremap_resource(&pdev->dev, res); 405 if (IS_ERR(qmp->msgram)) 406 return PTR_ERR(qmp->msgram); 407 408 qmp->mbox_client.dev = &pdev->dev; 409 qmp->mbox_client.knows_txdone = true; 410 qmp->mbox_chan = mbox_request_channel(&qmp->mbox_client, 0); 411 if (IS_ERR(qmp->mbox_chan)) { 412 dev_err(&pdev->dev, "failed to acquire ipc mailbox\n"); 413 return PTR_ERR(qmp->mbox_chan); 414 } 415 416 irq = platform_get_irq(pdev, 0); 417 ret = devm_request_irq(&pdev->dev, irq, qmp_intr, IRQF_ONESHOT, 418 "aoss-qmp", qmp); 419 if (ret < 0) { 420 dev_err(&pdev->dev, "failed to request interrupt\n"); 421 goto err_free_mbox; 422 } 423 424 ret = qmp_open(qmp); 425 if (ret < 0) 426 goto err_free_mbox; 427 428 ret = qmp_qdss_clk_add(qmp); 429 if (ret) 430 goto err_close_qmp; 431 432 ret = qmp_pd_add(qmp); 433 if (ret) 434 goto err_remove_qdss_clk; 435 436 platform_set_drvdata(pdev, qmp); 437 438 return 0; 439 440 err_remove_qdss_clk: 441 qmp_qdss_clk_remove(qmp); 442 err_close_qmp: 443 qmp_close(qmp); 444 err_free_mbox: 445 mbox_free_channel(qmp->mbox_chan); 446 447 return ret; 448 } 449 450 static int qmp_remove(struct platform_device *pdev) 451 { 452 struct qmp *qmp = platform_get_drvdata(pdev); 453 454 qmp_qdss_clk_remove(qmp); 455 qmp_pd_remove(qmp); 456 457 qmp_close(qmp); 458 mbox_free_channel(qmp->mbox_chan); 459 460 return 0; 461 } 462 463 static const struct of_device_id qmp_dt_match[] = { 464 { .compatible = "qcom,sdm845-aoss-qmp", }, 465 {} 466 }; 467 MODULE_DEVICE_TABLE(of, qmp_dt_match); 468 469 static struct platform_driver qmp_driver = { 470 .driver = { 471 .name = "qcom_aoss_qmp", 472 .of_match_table = qmp_dt_match, 473 }, 474 .probe = qmp_probe, 475 .remove = qmp_remove, 476 }; 477 module_platform_driver(qmp_driver); 478 479 MODULE_DESCRIPTION("Qualcomm AOSS QMP driver"); 480 MODULE_LICENSE("GPL v2"); 481