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

remoteproc/mediatek: Add support for mt8192 SCP

Add support for mt8192 SCP.

Signed-off-by: Pi-Hsun Shih <pihsun@chromium.org>
Reviewed-by: Tzung-Bi Shih <tzungbi@google.com>
Link: https://lore.kernel.org/r/20200921094847.2112399-1-pihsun@chromium.org
Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>

authored by

Pi-Hsun Shih and committed by
Bjorn Andersson
fd0b6c1f 18946226

+204 -36
+32
drivers/remoteproc/mtk_common.h
··· 32 32 #define MT8183_SCP_CACHESIZE_8KB BIT(8) 33 33 #define MT8183_SCP_CACHE_CON_WAYEN BIT(10) 34 34 35 + #define MT8192_L2TCM_SRAM_PD_0 0x210C0 36 + #define MT8192_L2TCM_SRAM_PD_1 0x210C4 37 + #define MT8192_L2TCM_SRAM_PD_2 0x210C8 38 + #define MT8192_L1TCM_SRAM_PDN 0x2102C 39 + #define MT8192_CPU0_SRAM_PD 0x21080 40 + 41 + #define MT8192_SCP2APMCU_IPC_SET 0x24080 42 + #define MT8192_SCP2APMCU_IPC_CLR 0x24084 43 + #define MT8192_SCP_IPC_INT_BIT BIT(0) 44 + #define MT8192_SCP2SPM_IPC_CLR 0x24094 45 + #define MT8192_GIPC_IN_SET 0x24098 46 + #define MT8192_HOST_IPC_INT_BIT BIT(0) 47 + 48 + #define MT8192_CORE0_SW_RSTN_CLR 0x30000 49 + #define MT8192_CORE0_SW_RSTN_SET 0x30004 50 + #define MT8192_CORE0_WDT_CFG 0x30034 51 + 35 52 #define SCP_FW_VER_LEN 32 36 53 #define SCP_SHARE_BUFFER_SIZE 288 37 54 ··· 67 50 void *priv; 68 51 }; 69 52 53 + struct mtk_scp; 54 + 55 + struct mtk_scp_of_data { 56 + int (*scp_before_load)(struct mtk_scp *scp); 57 + void (*scp_irq_handler)(struct mtk_scp *scp); 58 + void (*scp_reset_assert)(struct mtk_scp *scp); 59 + void (*scp_reset_deassert)(struct mtk_scp *scp); 60 + void (*scp_stop)(struct mtk_scp *scp); 61 + 62 + u32 host_to_scp_reg; 63 + u32 host_to_scp_int_bit; 64 + }; 65 + 70 66 struct mtk_scp { 71 67 struct device *dev; 72 68 struct rproc *rproc; ··· 87 57 void __iomem *reg_base; 88 58 void __iomem *sram_base; 89 59 size_t sram_size; 60 + 61 + const struct mtk_scp_of_data *data; 90 62 91 63 struct mtk_share_obj __iomem *recv_buf; 92 64 struct mtk_share_obj __iomem *send_buf;
+169 -34
drivers/remoteproc/mtk_scp.c
··· 124 124 size_t send_offset = SCP_FW_END - sizeof(struct mtk_share_obj); 125 125 size_t recv_offset = send_offset - sizeof(struct mtk_share_obj); 126 126 127 - /* Disable SCP to host interrupt */ 128 - writel(MT8183_SCP_IPC_INT_BIT, scp->reg_base + MT8183_SCP_TO_HOST); 129 - 130 127 /* shared buffer initialization */ 131 128 scp->recv_buf = 132 129 (struct mtk_share_obj __iomem *)(scp->sram_base + recv_offset); ··· 135 138 return 0; 136 139 } 137 140 138 - static void scp_reset_assert(const struct mtk_scp *scp) 141 + static void mt8183_scp_reset_assert(struct mtk_scp *scp) 139 142 { 140 143 u32 val; 141 144 ··· 144 147 writel(val, scp->reg_base + MT8183_SW_RSTN); 145 148 } 146 149 147 - static void scp_reset_deassert(const struct mtk_scp *scp) 150 + static void mt8183_scp_reset_deassert(struct mtk_scp *scp) 148 151 { 149 152 u32 val; 150 153 ··· 153 156 writel(val, scp->reg_base + MT8183_SW_RSTN); 154 157 } 155 158 156 - static irqreturn_t scp_irq_handler(int irq, void *priv) 159 + static void mt8192_scp_reset_assert(struct mtk_scp *scp) 157 160 { 158 - struct mtk_scp *scp = priv; 159 - u32 scp_to_host; 160 - int ret; 161 + writel(1, scp->reg_base + MT8192_CORE0_SW_RSTN_SET); 162 + } 161 163 162 - ret = clk_prepare_enable(scp->clk); 163 - if (ret) { 164 - dev_err(scp->dev, "failed to enable clocks\n"); 165 - return IRQ_NONE; 166 - } 164 + static void mt8192_scp_reset_deassert(struct mtk_scp *scp) 165 + { 166 + writel(1, scp->reg_base + MT8192_CORE0_SW_RSTN_CLR); 167 + } 168 + 169 + static void mt8183_scp_irq_handler(struct mtk_scp *scp) 170 + { 171 + u32 scp_to_host; 167 172 168 173 scp_to_host = readl(scp->reg_base + MT8183_SCP_TO_HOST); 169 174 if (scp_to_host & MT8183_SCP_IPC_INT_BIT) ··· 176 177 /* SCP won't send another interrupt until we set SCP_TO_HOST to 0. */ 177 178 writel(MT8183_SCP_IPC_INT_BIT | MT8183_SCP_WDT_INT_BIT, 178 179 scp->reg_base + MT8183_SCP_TO_HOST); 180 + } 181 + 182 + static void mt8192_scp_irq_handler(struct mtk_scp *scp) 183 + { 184 + u32 scp_to_host; 185 + 186 + scp_to_host = readl(scp->reg_base + MT8192_SCP2APMCU_IPC_SET); 187 + 188 + if (scp_to_host & MT8192_SCP_IPC_INT_BIT) 189 + scp_ipi_handler(scp); 190 + else 191 + scp_wdt_handler(scp, scp_to_host); 192 + 193 + /* 194 + * SCP won't send another interrupt until we clear 195 + * MT8192_SCP2APMCU_IPC. 196 + */ 197 + writel(MT8192_SCP_IPC_INT_BIT, 198 + scp->reg_base + MT8192_SCP2APMCU_IPC_CLR); 199 + } 200 + 201 + static irqreturn_t scp_irq_handler(int irq, void *priv) 202 + { 203 + struct mtk_scp *scp = priv; 204 + int ret; 205 + 206 + ret = clk_prepare_enable(scp->clk); 207 + if (ret) { 208 + dev_err(scp->dev, "failed to enable clocks\n"); 209 + return IRQ_NONE; 210 + } 211 + 212 + scp->data->scp_irq_handler(scp); 213 + 179 214 clk_disable_unprepare(scp->clk); 180 215 181 216 return IRQ_HANDLED; ··· 271 238 return ret; 272 239 } 273 240 274 - static int scp_load(struct rproc *rproc, const struct firmware *fw) 241 + static int mt8183_scp_before_load(struct mtk_scp *scp) 275 242 { 276 - const struct mtk_scp *scp = rproc->priv; 277 - struct device *dev = scp->dev; 278 - int ret; 279 - 280 - ret = clk_prepare_enable(scp->clk); 281 - if (ret) { 282 - dev_err(dev, "failed to enable clocks\n"); 283 - return ret; 284 - } 285 - 286 - /* Hold SCP in reset while loading FW. */ 287 - scp_reset_assert(scp); 243 + /* Clear SCP to host interrupt */ 244 + writel(MT8183_SCP_IPC_INT_BIT, scp->reg_base + MT8183_SCP_TO_HOST); 288 245 289 246 /* Reset clocks before loading FW */ 290 247 writel(0x0, scp->reg_base + MT8183_SCP_CLK_SW_SEL); ··· 294 271 writel(MT8183_SCP_CACHE_CON_WAYEN | MT8183_SCP_CACHESIZE_8KB, 295 272 scp->reg_base + MT8183_SCP_CACHE_CON); 296 273 writel(MT8183_SCP_CACHESIZE_8KB, scp->reg_base + MT8183_SCP_DCACHE_CON); 274 + 275 + return 0; 276 + } 277 + 278 + static void mt8192_power_on_sram(void *addr) 279 + { 280 + int i; 281 + 282 + for (i = 31; i >= 0; i--) 283 + writel(GENMASK(i, 0), addr); 284 + writel(0, addr); 285 + } 286 + 287 + static void mt8192_power_off_sram(void *addr) 288 + { 289 + int i; 290 + 291 + writel(0, addr); 292 + for (i = 0; i < 32; i++) 293 + writel(GENMASK(i, 0), addr); 294 + } 295 + 296 + static int mt8192_scp_before_load(struct mtk_scp *scp) 297 + { 298 + /* clear SPM interrupt, SCP2SPM_IPC_CLR */ 299 + writel(0xff, scp->reg_base + MT8192_SCP2SPM_IPC_CLR); 300 + 301 + writel(1, scp->reg_base + MT8192_CORE0_SW_RSTN_SET); 302 + 303 + dsb(sy); 304 + 305 + readl(scp->reg_base + MT8192_CORE0_SW_RSTN_SET); 306 + 307 + /* enable SRAM clock */ 308 + mt8192_power_on_sram(scp->reg_base + MT8192_L2TCM_SRAM_PD_0); 309 + mt8192_power_on_sram(scp->reg_base + MT8192_L2TCM_SRAM_PD_1); 310 + mt8192_power_on_sram(scp->reg_base + MT8192_L2TCM_SRAM_PD_2); 311 + mt8192_power_on_sram(scp->reg_base + MT8192_L1TCM_SRAM_PDN); 312 + mt8192_power_on_sram(scp->reg_base + MT8192_CPU0_SRAM_PD); 313 + 314 + return 0; 315 + } 316 + 317 + static int scp_load(struct rproc *rproc, const struct firmware *fw) 318 + { 319 + struct mtk_scp *scp = rproc->priv; 320 + struct device *dev = scp->dev; 321 + int ret; 322 + 323 + ret = clk_prepare_enable(scp->clk); 324 + if (ret) { 325 + dev_err(dev, "failed to enable clocks\n"); 326 + return ret; 327 + } 328 + 329 + /* Hold SCP in reset while loading FW. */ 330 + scp->data->scp_reset_assert(scp); 331 + 332 + ret = scp->data->scp_before_load(scp); 333 + if (ret < 0) 334 + return ret; 297 335 298 336 ret = scp_elf_load_segments(rproc, fw); 299 337 clk_disable_unprepare(scp->clk); ··· 377 293 378 294 run->signaled = false; 379 295 380 - scp_reset_deassert(scp); 296 + scp->data->scp_reset_deassert(scp); 381 297 382 298 ret = wait_event_interruptible_timeout( 383 299 run->wq, ··· 393 309 dev_err(dev, "wait SCP interrupted by a signal!\n"); 394 310 goto stop; 395 311 } 312 + 396 313 clk_disable_unprepare(scp->clk); 397 314 dev_info(dev, "SCP is ready. FW version %s\n", run->fw_ver); 398 315 399 316 return 0; 400 317 401 318 stop: 402 - scp_reset_assert(scp); 319 + scp->data->scp_reset_assert(scp); 403 320 clk_disable_unprepare(scp->clk); 404 321 return ret; 405 322 } ··· 414 329 offset = da; 415 330 if (offset >= 0 && (offset + len) < scp->sram_size) 416 331 return (void __force *)scp->sram_base + offset; 417 - } else { 332 + } else if (scp->dram_size) { 418 333 offset = da - scp->dma_addr; 419 334 if (offset >= 0 && (offset + len) < scp->dram_size) 420 335 return (void __force *)scp->cpu_addr + offset; 421 336 } 422 337 423 338 return NULL; 339 + } 340 + 341 + static void mt8183_scp_stop(struct mtk_scp *scp) 342 + { 343 + /* Disable SCP watchdog */ 344 + writel(0, scp->reg_base + MT8183_WDT_CFG); 345 + } 346 + 347 + static void mt8192_scp_stop(struct mtk_scp *scp) 348 + { 349 + /* Disable SRAM clock */ 350 + mt8192_power_off_sram(scp->reg_base + MT8192_L2TCM_SRAM_PD_0); 351 + mt8192_power_off_sram(scp->reg_base + MT8192_L2TCM_SRAM_PD_1); 352 + mt8192_power_off_sram(scp->reg_base + MT8192_L2TCM_SRAM_PD_2); 353 + mt8192_power_off_sram(scp->reg_base + MT8192_L1TCM_SRAM_PDN); 354 + mt8192_power_off_sram(scp->reg_base + MT8192_CPU0_SRAM_PD); 355 + 356 + /* Disable SCP watchdog */ 357 + writel(0, scp->reg_base + MT8192_CORE0_WDT_CFG); 424 358 } 425 359 426 360 static int scp_stop(struct rproc *rproc) ··· 453 349 return ret; 454 350 } 455 351 456 - scp_reset_assert(scp); 457 - /* Disable SCP watchdog */ 458 - writel(0, scp->reg_base + MT8183_WDT_CFG); 352 + scp->data->scp_reset_assert(scp); 353 + scp->data->scp_stop(scp); 459 354 clk_disable_unprepare(scp->clk); 460 355 461 356 return 0; ··· 546 443 int ret; 547 444 548 445 ret = of_reserved_mem_device_init(scp->dev); 446 + 447 + /* reserved memory is optional. */ 448 + if (ret == -ENODEV) { 449 + dev_info(scp->dev, "skipping reserved memory initialization."); 450 + return 0; 451 + } 452 + 549 453 if (ret) { 550 454 dev_err(scp->dev, "failed to assign memory-region: %d\n", ret); 551 455 return -ENOMEM; ··· 570 460 571 461 static void scp_unmap_memory_region(struct mtk_scp *scp) 572 462 { 463 + if (scp->dram_size == 0) 464 + return; 465 + 573 466 dma_free_coherent(scp->dev, scp->dram_size, scp->cpu_addr, 574 467 scp->dma_addr); 575 468 of_reserved_mem_device_release(scp->dev); ··· 649 536 scp = (struct mtk_scp *)rproc->priv; 650 537 scp->rproc = rproc; 651 538 scp->dev = dev; 539 + scp->data = of_device_get_match_data(dev); 652 540 platform_set_drvdata(pdev, scp); 653 541 654 542 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "sram"); ··· 756 642 return 0; 757 643 } 758 644 645 + static const struct mtk_scp_of_data mt8183_of_data = { 646 + .scp_before_load = mt8183_scp_before_load, 647 + .scp_irq_handler = mt8183_scp_irq_handler, 648 + .scp_reset_assert = mt8183_scp_reset_assert, 649 + .scp_reset_deassert = mt8183_scp_reset_deassert, 650 + .scp_stop = mt8183_scp_stop, 651 + .host_to_scp_reg = MT8183_HOST_TO_SCP, 652 + .host_to_scp_int_bit = MT8183_HOST_IPC_INT_BIT, 653 + }; 654 + 655 + static const struct mtk_scp_of_data mt8192_of_data = { 656 + .scp_before_load = mt8192_scp_before_load, 657 + .scp_irq_handler = mt8192_scp_irq_handler, 658 + .scp_reset_assert = mt8192_scp_reset_assert, 659 + .scp_reset_deassert = mt8192_scp_reset_deassert, 660 + .scp_stop = mt8192_scp_stop, 661 + .host_to_scp_reg = MT8192_GIPC_IN_SET, 662 + .host_to_scp_int_bit = MT8192_HOST_IPC_INT_BIT, 663 + }; 664 + 759 665 static const struct of_device_id mtk_scp_of_match[] = { 760 - { .compatible = "mediatek,mt8183-scp"}, 666 + { .compatible = "mediatek,mt8183-scp", .data = &mt8183_of_data }, 667 + { .compatible = "mediatek,mt8192-scp", .data = &mt8192_of_data }, 761 668 {}, 762 669 }; 763 670 MODULE_DEVICE_TABLE(of, mtk_scp_of_match);
+3 -2
drivers/remoteproc/mtk_scp_ipi.c
··· 180 180 ret = -ETIMEDOUT; 181 181 goto clock_disable; 182 182 } 183 - } while (readl(scp->reg_base + MT8183_HOST_TO_SCP)); 183 + } while (readl(scp->reg_base + scp->data->host_to_scp_reg)); 184 184 185 185 scp_memcpy_aligned(send_obj->share_buf, buf, len); 186 186 ··· 189 189 190 190 scp->ipi_id_ack[id] = false; 191 191 /* send the command to SCP */ 192 - writel(MT8183_HOST_IPC_INT_BIT, scp->reg_base + MT8183_HOST_TO_SCP); 192 + writel(scp->data->host_to_scp_int_bit, 193 + scp->reg_base + scp->data->host_to_scp_reg); 193 194 194 195 if (wait) { 195 196 /* wait for SCP's ACK */