Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

spmi: mtk-pmif: Add multi-bus support for SPMI 2.0

In preparation for adding support for MT8196/MT6991 SoCs having
multiple SPMI busses, move the bus specific parameters into a new
pmif_bus structure and keep the SoC-specific data in the already
existing struct pmif, and add means to register multiple SPMI
controllers.

While this needs a different devicetree node structure, where each
of the controllers are in subnodes of a main SPMI node, and where
each has its own resources (iospaces and clocks), support for the
legacy single-controller was retained and doesn't require any DT
change in the currently supported SoCs.

Reviewed-by: Nícolas F. R. A. Prado <nfraprado@collabora.com>
Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
Signed-off-by: Stephen Boyd <sboyd@kernel.org>
Link: https://patch.msgid.link/20260123182039.224314-3-sboyd@kernel.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

authored by

AngeloGioacchino Del Regno and committed by
Greg Kroah-Hartman
07811796 5abb6c7a

+164 -85
+164 -85
drivers/spmi/spmi-mtk-pmif.c
··· 1 1 // SPDX-License-Identifier: GPL-2.0 2 2 // 3 3 // Copyright (c) 2021 MediaTek Inc. 4 + // Copyright (c) 2025 Collabora Ltd 5 + // AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com> 4 6 5 7 #include <linux/clk.h> 6 8 #include <linux/iopoll.h> ··· 27 25 28 26 #define PMIF_CHAN_OFFSET 0x5 29 27 28 + #define PMIF_MAX_BUSES 2 30 29 #define PMIF_MAX_CLKS 3 31 30 32 31 #define SPMI_OP_ST_BUSY 1 ··· 44 41 const u32 *regs; 45 42 const u32 *spmimst_regs; 46 43 u32 soc_chan; 44 + u32 num_spmi_buses; 45 + }; 46 + 47 + struct pmif_bus { 48 + void __iomem *base; 49 + void __iomem *spmimst_base; 50 + struct spmi_controller *ctrl; 51 + struct clk_bulk_data clks[PMIF_MAX_CLKS]; 52 + size_t nclks; 53 + raw_spinlock_t lock; 47 54 }; 48 55 49 56 struct pmif { 50 - void __iomem *base; 51 - void __iomem *spmimst_base; 57 + struct pmif_bus bus[PMIF_MAX_BUSES]; 52 58 struct ch_reg chan; 53 - struct clk_bulk_data clks[PMIF_MAX_CLKS]; 54 - size_t nclks; 55 59 const struct pmif_data *data; 56 - raw_spinlock_t lock; 57 60 }; 58 61 59 62 static const char * const pmif_clock_names[] = { ··· 271 262 [SPMI_MST_DBG] = 0x00FC, 272 263 }; 273 264 274 - static u32 pmif_readl(struct pmif *arb, enum pmif_regs reg) 265 + static inline struct pmif *to_mtk_pmif(struct spmi_controller *ctrl) 275 266 { 276 - return readl(arb->base + arb->data->regs[reg]); 267 + return dev_get_drvdata(ctrl->dev.parent); 277 268 } 278 269 279 - static void pmif_writel(struct pmif *arb, u32 val, enum pmif_regs reg) 270 + static u32 pmif_readl(struct pmif *arb, struct pmif_bus *pbus, enum pmif_regs reg) 280 271 { 281 - writel(val, arb->base + arb->data->regs[reg]); 272 + return readl(pbus->base + arb->data->regs[reg]); 282 273 } 283 274 284 - static void mtk_spmi_writel(struct pmif *arb, u32 val, enum spmi_regs reg) 275 + static void pmif_writel(struct pmif *arb, struct pmif_bus *pbus, 276 + u32 val, enum pmif_regs reg) 285 277 { 286 - writel(val, arb->spmimst_base + arb->data->spmimst_regs[reg]); 278 + writel(val, pbus->base + arb->data->regs[reg]); 287 279 } 288 280 289 - static bool pmif_is_fsm_vldclr(struct pmif *arb) 281 + static void mtk_spmi_writel(struct pmif *arb, struct pmif_bus *pbus, 282 + u32 val, enum spmi_regs reg) 283 + { 284 + writel(val, pbus->spmimst_base + arb->data->spmimst_regs[reg]); 285 + } 286 + 287 + static bool pmif_is_fsm_vldclr(struct pmif *arb, struct pmif_bus *pbus) 290 288 { 291 289 u32 reg_rdata; 292 290 293 - reg_rdata = pmif_readl(arb, arb->chan.ch_sta); 291 + reg_rdata = pmif_readl(arb, pbus, arb->chan.ch_sta); 294 292 295 293 return GET_SWINF(reg_rdata) == SWINF_WFVLDCLR; 296 294 } 297 295 298 296 static int pmif_arb_cmd(struct spmi_controller *ctrl, u8 opc, u8 sid) 299 297 { 300 - struct pmif *arb = spmi_controller_get_drvdata(ctrl); 298 + struct pmif_bus *pbus = spmi_controller_get_drvdata(ctrl); 299 + struct pmif *arb = to_mtk_pmif(ctrl); 301 300 u32 rdata, cmd; 302 301 int ret; 303 302 ··· 315 298 316 299 cmd = opc - SPMI_CMD_RESET; 317 300 318 - mtk_spmi_writel(arb, (cmd << 0x4) | sid, SPMI_OP_ST_CTRL); 319 - ret = readl_poll_timeout_atomic(arb->spmimst_base + arb->data->spmimst_regs[SPMI_OP_ST_STA], 301 + mtk_spmi_writel(arb, pbus, (cmd << 0x4) | sid, SPMI_OP_ST_CTRL); 302 + ret = readl_poll_timeout_atomic(pbus->spmimst_base + arb->data->spmimst_regs[SPMI_OP_ST_STA], 320 303 rdata, (rdata & SPMI_OP_ST_BUSY) == SPMI_OP_ST_BUSY, 321 304 PMIF_DELAY_US, PMIF_TIMEOUT_US); 322 305 if (ret < 0) ··· 328 311 static int pmif_spmi_read_cmd(struct spmi_controller *ctrl, u8 opc, u8 sid, 329 312 u16 addr, u8 *buf, size_t len) 330 313 { 331 - struct pmif *arb = spmi_controller_get_drvdata(ctrl); 314 + struct pmif_bus *pbus = spmi_controller_get_drvdata(ctrl); 315 + struct pmif *arb = to_mtk_pmif(ctrl); 332 316 struct ch_reg *inf_reg; 333 317 int ret; 334 318 u32 data, cmd; ··· 354 336 else 355 337 return -EINVAL; 356 338 357 - raw_spin_lock_irqsave(&arb->lock, flags); 339 + raw_spin_lock_irqsave(&pbus->lock, flags); 358 340 /* Wait for Software Interface FSM state to be IDLE. */ 359 341 inf_reg = &arb->chan; 360 - ret = readl_poll_timeout_atomic(arb->base + arb->data->regs[inf_reg->ch_sta], 342 + ret = readl_poll_timeout_atomic(pbus->base + arb->data->regs[inf_reg->ch_sta], 361 343 data, GET_SWINF(data) == SWINF_IDLE, 362 344 PMIF_DELAY_US, PMIF_TIMEOUT_US); 363 345 if (ret < 0) { 364 346 /* set channel ready if the data has transferred */ 365 - if (pmif_is_fsm_vldclr(arb)) 366 - pmif_writel(arb, 1, inf_reg->ch_rdy); 367 - raw_spin_unlock_irqrestore(&arb->lock, flags); 347 + if (pmif_is_fsm_vldclr(arb, pbus)) 348 + pmif_writel(arb, pbus, 1, inf_reg->ch_rdy); 349 + raw_spin_unlock_irqrestore(&pbus->lock, flags); 368 350 dev_err(&ctrl->dev, "failed to wait for SWINF_IDLE\n"); 369 351 return ret; 370 352 } 371 353 372 354 /* Send the command. */ 373 355 cmd = (opc << 30) | (sid << 24) | ((len - 1) << 16) | addr; 374 - pmif_writel(arb, cmd, inf_reg->ch_send); 375 - raw_spin_unlock_irqrestore(&arb->lock, flags); 356 + pmif_writel(arb, pbus, cmd, inf_reg->ch_send); 357 + raw_spin_unlock_irqrestore(&pbus->lock, flags); 376 358 377 359 /* 378 360 * Wait for Software Interface FSM state to be WFVLDCLR, 379 361 * read the data and clear the valid flag. 380 362 */ 381 - ret = readl_poll_timeout_atomic(arb->base + arb->data->regs[inf_reg->ch_sta], 363 + ret = readl_poll_timeout_atomic(pbus->base + arb->data->regs[inf_reg->ch_sta], 382 364 data, GET_SWINF(data) == SWINF_WFVLDCLR, 383 365 PMIF_DELAY_US, PMIF_TIMEOUT_US); 384 366 if (ret < 0) { ··· 386 368 return ret; 387 369 } 388 370 389 - data = pmif_readl(arb, inf_reg->rdata); 371 + data = pmif_readl(arb, pbus, inf_reg->rdata); 390 372 memcpy(buf, &data, len); 391 - pmif_writel(arb, 1, inf_reg->ch_rdy); 373 + pmif_writel(arb, pbus, 1, inf_reg->ch_rdy); 392 374 393 375 return 0; 394 376 } ··· 396 378 static int pmif_spmi_write_cmd(struct spmi_controller *ctrl, u8 opc, u8 sid, 397 379 u16 addr, const u8 *buf, size_t len) 398 380 { 399 - struct pmif *arb = spmi_controller_get_drvdata(ctrl); 381 + struct pmif_bus *pbus = spmi_controller_get_drvdata(ctrl); 382 + struct pmif *arb = to_mtk_pmif(ctrl); 400 383 struct ch_reg *inf_reg; 401 384 int ret; 402 385 u32 data, wdata, cmd; ··· 428 409 /* Set the write data. */ 429 410 memcpy(&wdata, buf, len); 430 411 431 - raw_spin_lock_irqsave(&arb->lock, flags); 412 + raw_spin_lock_irqsave(&pbus->lock, flags); 432 413 /* Wait for Software Interface FSM state to be IDLE. */ 433 414 inf_reg = &arb->chan; 434 - ret = readl_poll_timeout_atomic(arb->base + arb->data->regs[inf_reg->ch_sta], 415 + ret = readl_poll_timeout_atomic(pbus->base + arb->data->regs[inf_reg->ch_sta], 435 416 data, GET_SWINF(data) == SWINF_IDLE, 436 417 PMIF_DELAY_US, PMIF_TIMEOUT_US); 437 418 if (ret < 0) { 438 419 /* set channel ready if the data has transferred */ 439 - if (pmif_is_fsm_vldclr(arb)) 440 - pmif_writel(arb, 1, inf_reg->ch_rdy); 441 - raw_spin_unlock_irqrestore(&arb->lock, flags); 420 + if (pmif_is_fsm_vldclr(arb, pbus)) 421 + pmif_writel(arb, pbus, 1, inf_reg->ch_rdy); 422 + raw_spin_unlock_irqrestore(&pbus->lock, flags); 442 423 dev_err(&ctrl->dev, "failed to wait for SWINF_IDLE\n"); 443 424 return ret; 444 425 } 445 426 446 - pmif_writel(arb, wdata, inf_reg->wdata); 427 + pmif_writel(arb, pbus, wdata, inf_reg->wdata); 447 428 448 429 /* Send the command. */ 449 430 cmd = (opc << 30) | BIT(29) | (sid << 24) | ((len - 1) << 16) | addr; 450 - pmif_writel(arb, cmd, inf_reg->ch_send); 451 - raw_spin_unlock_irqrestore(&arb->lock, flags); 431 + pmif_writel(arb, pbus, cmd, inf_reg->ch_send); 432 + raw_spin_unlock_irqrestore(&pbus->lock, flags); 452 433 453 434 return 0; 454 435 } ··· 465 446 .soc_chan = 2, 466 447 }; 467 448 468 - static int mtk_spmi_probe(struct platform_device *pdev) 449 + static int mtk_spmi_bus_probe(struct platform_device *pdev, 450 + struct device_node *node, 451 + const struct pmif_data *pdata, 452 + struct pmif_bus *pbus) 469 453 { 470 - struct pmif *arb; 471 454 struct spmi_controller *ctrl; 472 - int err, i; 473 - u32 chan_offset; 455 + int err, idx, bus_id, i; 474 456 475 - ctrl = devm_spmi_controller_alloc(&pdev->dev, sizeof(*arb)); 457 + if (pdata->num_spmi_buses > 1) 458 + bus_id = of_alias_get_id(node, "spmi"); 459 + else 460 + bus_id = 0; 461 + 462 + if (bus_id < 0) 463 + return dev_err_probe(&pdev->dev, bus_id, 464 + "Cannot find SPMI Bus alias ID\n"); 465 + 466 + ctrl = devm_spmi_controller_alloc(&pdev->dev, sizeof(*pbus)); 476 467 if (IS_ERR(ctrl)) 477 468 return PTR_ERR(ctrl); 478 469 479 - arb = spmi_controller_get_drvdata(ctrl); 470 + pbus = spmi_controller_get_drvdata(ctrl); 471 + pbus->ctrl = ctrl; 472 + 473 + idx = of_property_match_string(node, "reg-names", "pmif"); 474 + if (idx < 0) 475 + return -EINVAL; 476 + 477 + pbus->base = devm_of_iomap(&pdev->dev, node, idx, NULL); 478 + if (IS_ERR(pbus->base)) 479 + return PTR_ERR(pbus->base); 480 + 481 + idx = of_property_match_string(node, "reg-names", "spmimst"); 482 + if (idx < 0) 483 + return -EINVAL; 484 + 485 + pbus->spmimst_base = devm_of_iomap(&pdev->dev, node, idx, NULL); 486 + if (IS_ERR(pbus->spmimst_base)) 487 + return PTR_ERR(pbus->spmimst_base); 488 + 489 + pbus->nclks = ARRAY_SIZE(pmif_clock_names); 490 + for (i = 0; i < pbus->nclks; i++) { 491 + pbus->clks[i].id = pmif_clock_names[i]; 492 + pbus->clks[i].clk = of_clk_get_by_name(node, pbus->clks[i].id); 493 + if (IS_ERR(pbus->clks[i].clk)) 494 + return PTR_ERR(pbus->clks[i].clk); 495 + } 496 + 497 + err = clk_bulk_prepare_enable(pbus->nclks, pbus->clks); 498 + if (err) 499 + goto err_put_clks; 500 + 501 + ctrl->cmd = pmif_arb_cmd; 502 + ctrl->read_cmd = pmif_spmi_read_cmd; 503 + ctrl->write_cmd = pmif_spmi_write_cmd; 504 + ctrl->dev.of_node = node; 505 + dev_set_name(&ctrl->dev, "spmi-%d", bus_id); 506 + 507 + raw_spin_lock_init(&pbus->lock); 508 + 509 + err = spmi_controller_add(ctrl); 510 + if (err) 511 + goto err_domain_remove; 512 + 513 + pbus->ctrl = ctrl; 514 + 515 + return 0; 516 + 517 + err_domain_remove: 518 + clk_bulk_disable_unprepare(pbus->nclks, pbus->clks); 519 + err_put_clks: 520 + clk_bulk_put(pbus->nclks, pbus->clks); 521 + return err; 522 + } 523 + 524 + static int mtk_spmi_probe(struct platform_device *pdev) 525 + { 526 + struct device_node *node = pdev->dev.of_node; 527 + struct pmif *arb; 528 + u32 chan_offset; 529 + u8 cur_bus = 0; 530 + int ret; 531 + 532 + arb = devm_kzalloc(&pdev->dev, sizeof(*arb), GFP_KERNEL); 533 + if (!arb) 534 + return -ENOMEM; 535 + 480 536 arb->data = device_get_match_data(&pdev->dev); 481 537 if (!arb->data) { 482 538 dev_err(&pdev->dev, "Cannot get drv_data\n"); 483 539 return -EINVAL; 484 540 } 485 541 486 - arb->base = devm_platform_ioremap_resource_byname(pdev, "pmif"); 487 - if (IS_ERR(arb->base)) 488 - return PTR_ERR(arb->base); 542 + platform_set_drvdata(pdev, arb); 489 543 490 - arb->spmimst_base = devm_platform_ioremap_resource_byname(pdev, "spmimst"); 491 - if (IS_ERR(arb->spmimst_base)) 492 - return PTR_ERR(arb->spmimst_base); 544 + if (!arb->data->num_spmi_buses) { 545 + ret = mtk_spmi_bus_probe(pdev, node, arb->data, &arb->bus[cur_bus]); 546 + if (ret) 547 + return ret; 548 + } else { 549 + for_each_available_child_of_node_scoped(node, child) { 550 + if (!of_node_name_eq(child, "spmi")) 551 + continue; 493 552 494 - arb->nclks = ARRAY_SIZE(pmif_clock_names); 495 - for (i = 0; i < arb->nclks; i++) 496 - arb->clks[i].id = pmif_clock_names[i]; 497 - 498 - err = clk_bulk_get(&pdev->dev, arb->nclks, arb->clks); 499 - if (err) { 500 - dev_err(&pdev->dev, "Failed to get clocks: %d\n", err); 501 - return err; 553 + ret = mtk_spmi_bus_probe(pdev, child, arb->data, 554 + &arb->bus[cur_bus]); 555 + if (ret) 556 + return ret; 557 + cur_bus++; 558 + } 502 559 } 503 - 504 - err = clk_bulk_prepare_enable(arb->nclks, arb->clks); 505 - if (err) { 506 - dev_err(&pdev->dev, "Failed to enable clocks: %d\n", err); 507 - goto err_put_clks; 508 - } 509 - 510 - ctrl->cmd = pmif_arb_cmd; 511 - ctrl->read_cmd = pmif_spmi_read_cmd; 512 - ctrl->write_cmd = pmif_spmi_write_cmd; 513 560 514 561 chan_offset = PMIF_CHAN_OFFSET * arb->data->soc_chan; 515 562 arb->chan.ch_sta = PMIF_SWINF_0_STA + chan_offset; ··· 584 499 arb->chan.ch_send = PMIF_SWINF_0_ACC + chan_offset; 585 500 arb->chan.ch_rdy = PMIF_SWINF_0_VLD_CLR + chan_offset; 586 501 587 - raw_spin_lock_init(&arb->lock); 588 - 589 - platform_set_drvdata(pdev, ctrl); 590 - 591 - err = spmi_controller_add(ctrl); 592 - if (err) 593 - goto err_domain_remove; 594 - 595 502 return 0; 596 - 597 - err_domain_remove: 598 - clk_bulk_disable_unprepare(arb->nclks, arb->clks); 599 - err_put_clks: 600 - clk_bulk_put(arb->nclks, arb->clks); 601 - return err; 602 503 } 603 504 604 505 static void mtk_spmi_remove(struct platform_device *pdev) 605 506 { 606 - struct spmi_controller *ctrl = platform_get_drvdata(pdev); 607 - struct pmif *arb = spmi_controller_get_drvdata(ctrl); 507 + struct pmif *arb = platform_get_drvdata(pdev); 508 + int i; 608 509 609 - spmi_controller_remove(ctrl); 610 - clk_bulk_disable_unprepare(arb->nclks, arb->clks); 611 - clk_bulk_put(arb->nclks, arb->clks); 510 + for (i = 0; i < PMIF_MAX_BUSES; i++) { 511 + struct pmif_bus *pbus = &arb->bus[i]; 512 + 513 + if (!pbus->ctrl) 514 + continue; 515 + 516 + spmi_controller_remove(pbus->ctrl); 517 + clk_bulk_disable_unprepare(pbus->nclks, pbus->clks); 518 + clk_bulk_put(pbus->nclks, pbus->clks); 519 + } 612 520 } 613 521 614 522 static const struct of_device_id mtk_spmi_match_table[] = { ··· 627 549 }; 628 550 module_platform_driver(mtk_spmi_driver); 629 551 552 + MODULE_AUTHOR("AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>"); 630 553 MODULE_AUTHOR("Hsin-Hsiung Wang <hsin-hsiung.wang@mediatek.com>"); 631 554 MODULE_DESCRIPTION("MediaTek SPMI Driver"); 632 555 MODULE_LICENSE("GPL");