1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Copyright (C) 2019 Linaro Ltd 4 */ 5 6 #include <dt-bindings/interconnect/qcom,qcs404.h> 7 #include <linux/device.h> 8 #include <linux/interconnect-provider.h> 9 #include <linux/io.h> 10 #include <linux/module.h> 11 #include <linux/mod_devicetable.h> 12 #include <linux/platform_device.h> 13 #include <linux/regmap.h> 14 15 16 #include "icc-rpm.h" 17 18 enum { 19 QCS404_MASTER_AMPSS_M0 = 1, 20 QCS404_MASTER_GRAPHICS_3D, 21 QCS404_MASTER_MDP_PORT0, 22 QCS404_SNOC_BIMC_1_MAS, 23 QCS404_MASTER_TCU_0, 24 QCS404_MASTER_SPDM, 25 QCS404_MASTER_BLSP_1, 26 QCS404_MASTER_BLSP_2, 27 QCS404_MASTER_XM_USB_HS1, 28 QCS404_MASTER_CRYPTO_CORE0, 29 QCS404_MASTER_SDCC_1, 30 QCS404_MASTER_SDCC_2, 31 QCS404_SNOC_PNOC_MAS, 32 QCS404_MASTER_QPIC, 33 QCS404_MASTER_QDSS_BAM, 34 QCS404_BIMC_SNOC_MAS, 35 QCS404_PNOC_SNOC_MAS, 36 QCS404_MASTER_QDSS_ETR, 37 QCS404_MASTER_EMAC, 38 QCS404_MASTER_PCIE, 39 QCS404_MASTER_USB3, 40 QCS404_PNOC_INT_0, 41 QCS404_PNOC_INT_2, 42 QCS404_PNOC_INT_3, 43 QCS404_PNOC_SLV_0, 44 QCS404_PNOC_SLV_1, 45 QCS404_PNOC_SLV_2, 46 QCS404_PNOC_SLV_3, 47 QCS404_PNOC_SLV_4, 48 QCS404_PNOC_SLV_6, 49 QCS404_PNOC_SLV_7, 50 QCS404_PNOC_SLV_8, 51 QCS404_PNOC_SLV_9, 52 QCS404_PNOC_SLV_10, 53 QCS404_PNOC_SLV_11, 54 QCS404_SNOC_QDSS_INT, 55 QCS404_SNOC_INT_0, 56 QCS404_SNOC_INT_1, 57 QCS404_SNOC_INT_2, 58 QCS404_SLAVE_EBI_CH0, 59 QCS404_BIMC_SNOC_SLV, 60 QCS404_SLAVE_SPDM_WRAPPER, 61 QCS404_SLAVE_PDM, 62 QCS404_SLAVE_PRNG, 63 QCS404_SLAVE_TCSR, 64 QCS404_SLAVE_SNOC_CFG, 65 QCS404_SLAVE_MESSAGE_RAM, 66 QCS404_SLAVE_DISPLAY_CFG, 67 QCS404_SLAVE_GRAPHICS_3D_CFG, 68 QCS404_SLAVE_BLSP_1, 69 QCS404_SLAVE_TLMM_NORTH, 70 QCS404_SLAVE_PCIE_1, 71 QCS404_SLAVE_EMAC_CFG, 72 QCS404_SLAVE_BLSP_2, 73 QCS404_SLAVE_TLMM_EAST, 74 QCS404_SLAVE_TCU, 75 QCS404_SLAVE_PMIC_ARB, 76 QCS404_SLAVE_SDCC_1, 77 QCS404_SLAVE_SDCC_2, 78 QCS404_SLAVE_TLMM_SOUTH, 79 QCS404_SLAVE_USB_HS, 80 QCS404_SLAVE_USB3, 81 QCS404_SLAVE_CRYPTO_0_CFG, 82 QCS404_PNOC_SNOC_SLV, 83 QCS404_SLAVE_APPSS, 84 QCS404_SLAVE_WCSS, 85 QCS404_SNOC_BIMC_1_SLV, 86 QCS404_SLAVE_OCIMEM, 87 QCS404_SNOC_PNOC_SLV, 88 QCS404_SLAVE_QDSS_STM, 89 QCS404_SLAVE_CATS_128, 90 QCS404_SLAVE_OCMEM_64, 91 QCS404_SLAVE_LPASS, 92 }; 93 94 static const u16 mas_apps_proc_links[] = { 95 QCS404_SLAVE_EBI_CH0, 96 QCS404_BIMC_SNOC_SLV 97 }; 98 99 static struct qcom_icc_node mas_apps_proc = { 100 .name = "mas_apps_proc", 101 .id = QCS404_MASTER_AMPSS_M0, 102 .buswidth = 8, 103 .mas_rpm_id = 0, 104 .slv_rpm_id = -1, 105 .qos.ap_owned = true, 106 .qos.qos_mode = NOC_QOS_MODE_FIXED, 107 .qos.areq_prio = 0, 108 .qos.prio_level = 0, 109 .qos.qos_port = 0, 110 .num_links = ARRAY_SIZE(mas_apps_proc_links), 111 .links = mas_apps_proc_links, 112 }; 113 114 static const u16 mas_oxili_links[] = { 115 QCS404_SLAVE_EBI_CH0, 116 QCS404_BIMC_SNOC_SLV 117 }; 118 119 static struct qcom_icc_node mas_oxili = { 120 .name = "mas_oxili", 121 .id = QCS404_MASTER_GRAPHICS_3D, 122 .buswidth = 8, 123 .mas_rpm_id = -1, 124 .slv_rpm_id = -1, 125 .qos.ap_owned = true, 126 .qos.qos_mode = NOC_QOS_MODE_FIXED, 127 .qos.areq_prio = 0, 128 .qos.prio_level = 0, 129 .qos.qos_port = 2, 130 .num_links = ARRAY_SIZE(mas_oxili_links), 131 .links = mas_oxili_links, 132 }; 133 134 static const u16 mas_mdp_links[] = { 135 QCS404_SLAVE_EBI_CH0, 136 QCS404_BIMC_SNOC_SLV 137 }; 138 139 static struct qcom_icc_node mas_mdp = { 140 .name = "mas_mdp", 141 .id = QCS404_MASTER_MDP_PORT0, 142 .buswidth = 8, 143 .mas_rpm_id = -1, 144 .slv_rpm_id = -1, 145 .qos.ap_owned = true, 146 .qos.qos_mode = NOC_QOS_MODE_FIXED, 147 .qos.areq_prio = 0, 148 .qos.prio_level = 1, 149 .qos.qos_port = 4, 150 .num_links = ARRAY_SIZE(mas_mdp_links), 151 .links = mas_mdp_links, 152 }; 153 154 static const u16 mas_snoc_bimc_1_links[] = { 155 QCS404_SLAVE_EBI_CH0 156 }; 157 158 static struct qcom_icc_node mas_snoc_bimc_1 = { 159 .name = "mas_snoc_bimc_1", 160 .id = QCS404_SNOC_BIMC_1_MAS, 161 .buswidth = 8, 162 .mas_rpm_id = 76, 163 .slv_rpm_id = -1, 164 .qos.qos_mode = NOC_QOS_MODE_BYPASS, 165 .qos.areq_prio = 0, 166 .qos.prio_level = 0, 167 .qos.qos_port = 5, 168 .num_links = ARRAY_SIZE(mas_snoc_bimc_1_links), 169 .links = mas_snoc_bimc_1_links, 170 }; 171 172 static const u16 mas_tcu_0_links[] = { 173 QCS404_SLAVE_EBI_CH0, 174 QCS404_BIMC_SNOC_SLV 175 }; 176 177 static struct qcom_icc_node mas_tcu_0 = { 178 .name = "mas_tcu_0", 179 .id = QCS404_MASTER_TCU_0, 180 .buswidth = 8, 181 .mas_rpm_id = -1, 182 .slv_rpm_id = -1, 183 .qos.ap_owned = true, 184 .qos.qos_mode = NOC_QOS_MODE_FIXED, 185 .qos.areq_prio = 0, 186 .qos.prio_level = 2, 187 .qos.qos_port = 6, 188 .num_links = ARRAY_SIZE(mas_tcu_0_links), 189 .links = mas_tcu_0_links, 190 }; 191 192 static const u16 mas_spdm_links[] = { 193 QCS404_PNOC_INT_3 194 }; 195 196 static struct qcom_icc_node mas_spdm = { 197 .name = "mas_spdm", 198 .id = QCS404_MASTER_SPDM, 199 .buswidth = 4, 200 .mas_rpm_id = -1, 201 .slv_rpm_id = -1, 202 .qos.ap_owned = true, 203 .qos.qos_mode = NOC_QOS_MODE_INVALID, 204 .num_links = ARRAY_SIZE(mas_spdm_links), 205 .links = mas_spdm_links, 206 }; 207 208 static const u16 mas_blsp_1_links[] = { 209 QCS404_PNOC_INT_3 210 }; 211 212 static struct qcom_icc_node mas_blsp_1 = { 213 .name = "mas_blsp_1", 214 .id = QCS404_MASTER_BLSP_1, 215 .buswidth = 4, 216 .mas_rpm_id = 41, 217 .slv_rpm_id = -1, 218 .num_links = ARRAY_SIZE(mas_blsp_1_links), 219 .links = mas_blsp_1_links, 220 }; 221 222 static const u16 mas_blsp_2_links[] = { 223 QCS404_PNOC_INT_3 224 }; 225 226 static struct qcom_icc_node mas_blsp_2 = { 227 .name = "mas_blsp_2", 228 .id = QCS404_MASTER_BLSP_2, 229 .buswidth = 4, 230 .mas_rpm_id = 39, 231 .slv_rpm_id = -1, 232 .num_links = ARRAY_SIZE(mas_blsp_2_links), 233 .links = mas_blsp_2_links, 234 }; 235 236 static const u16 mas_xi_usb_hs1_links[] = { 237 QCS404_PNOC_INT_0 238 }; 239 240 static struct qcom_icc_node mas_xi_usb_hs1 = { 241 .name = "mas_xi_usb_hs1", 242 .id = QCS404_MASTER_XM_USB_HS1, 243 .buswidth = 8, 244 .mas_rpm_id = 138, 245 .slv_rpm_id = -1, 246 .num_links = ARRAY_SIZE(mas_xi_usb_hs1_links), 247 .links = mas_xi_usb_hs1_links, 248 }; 249 250 static const u16 mas_crypto_links[] = { 251 QCS404_PNOC_SNOC_SLV, 252 QCS404_PNOC_INT_2 253 }; 254 255 static struct qcom_icc_node mas_crypto = { 256 .name = "mas_crypto", 257 .id = QCS404_MASTER_CRYPTO_CORE0, 258 .buswidth = 8, 259 .mas_rpm_id = 23, 260 .slv_rpm_id = -1, 261 .qos.ap_owned = true, 262 .qos.qos_mode = NOC_QOS_MODE_FIXED, 263 .qos.areq_prio = 1, 264 .qos.prio_level = 1, 265 .qos.qos_port = 0, 266 .num_links = ARRAY_SIZE(mas_crypto_links), 267 .links = mas_crypto_links, 268 }; 269 270 static const u16 mas_sdcc_1_links[] = { 271 QCS404_PNOC_INT_0 272 }; 273 274 static struct qcom_icc_node mas_sdcc_1 = { 275 .name = "mas_sdcc_1", 276 .id = QCS404_MASTER_SDCC_1, 277 .buswidth = 8, 278 .mas_rpm_id = 33, 279 .slv_rpm_id = -1, 280 .num_links = ARRAY_SIZE(mas_sdcc_1_links), 281 .links = mas_sdcc_1_links, 282 }; 283 284 static const u16 mas_sdcc_2_links[] = { 285 QCS404_PNOC_INT_0 286 }; 287 288 static struct qcom_icc_node mas_sdcc_2 = { 289 .name = "mas_sdcc_2", 290 .id = QCS404_MASTER_SDCC_2, 291 .buswidth = 8, 292 .mas_rpm_id = 35, 293 .slv_rpm_id = -1, 294 .num_links = ARRAY_SIZE(mas_sdcc_2_links), 295 .links = mas_sdcc_2_links, 296 }; 297 298 static const u16 mas_snoc_pcnoc_links[] = { 299 QCS404_PNOC_INT_2 300 }; 301 302 static struct qcom_icc_node mas_snoc_pcnoc = { 303 .name = "mas_snoc_pcnoc", 304 .id = QCS404_SNOC_PNOC_MAS, 305 .buswidth = 8, 306 .mas_rpm_id = 77, 307 .slv_rpm_id = -1, 308 .num_links = ARRAY_SIZE(mas_snoc_pcnoc_links), 309 .links = mas_snoc_pcnoc_links, 310 }; 311 312 static const u16 mas_qpic_links[] = { 313 QCS404_PNOC_INT_0 314 }; 315 316 static struct qcom_icc_node mas_qpic = { 317 .name = "mas_qpic", 318 .id = QCS404_MASTER_QPIC, 319 .buswidth = 4, 320 .mas_rpm_id = -1, 321 .slv_rpm_id = -1, 322 .qos.ap_owned = true, 323 .qos.qos_mode = NOC_QOS_MODE_FIXED, 324 .qos.areq_prio = 1, 325 .qos.prio_level = 1, 326 .qos.qos_port = 14, 327 .num_links = ARRAY_SIZE(mas_qpic_links), 328 .links = mas_qpic_links, 329 }; 330 331 static const u16 mas_qdss_bam_links[] = { 332 QCS404_SNOC_QDSS_INT 333 }; 334 335 static struct qcom_icc_node mas_qdss_bam = { 336 .name = "mas_qdss_bam", 337 .id = QCS404_MASTER_QDSS_BAM, 338 .buswidth = 4, 339 .mas_rpm_id = -1, 340 .slv_rpm_id = -1, 341 .qos.ap_owned = true, 342 .qos.qos_mode = NOC_QOS_MODE_FIXED, 343 .qos.areq_prio = 1, 344 .qos.prio_level = 1, 345 .qos.qos_port = 1, 346 .num_links = ARRAY_SIZE(mas_qdss_bam_links), 347 .links = mas_qdss_bam_links, 348 }; 349 350 static const u16 mas_bimc_snoc_links[] = { 351 QCS404_SLAVE_OCMEM_64, 352 QCS404_SLAVE_CATS_128, 353 QCS404_SNOC_INT_0, 354 QCS404_SNOC_INT_1 355 }; 356 357 static struct qcom_icc_node mas_bimc_snoc = { 358 .name = "mas_bimc_snoc", 359 .id = QCS404_BIMC_SNOC_MAS, 360 .buswidth = 8, 361 .mas_rpm_id = 21, 362 .slv_rpm_id = -1, 363 .num_links = ARRAY_SIZE(mas_bimc_snoc_links), 364 .links = mas_bimc_snoc_links, 365 }; 366 367 static const u16 mas_pcnoc_snoc_links[] = { 368 QCS404_SNOC_BIMC_1_SLV, 369 QCS404_SNOC_INT_2, 370 QCS404_SNOC_INT_0 371 }; 372 373 static struct qcom_icc_node mas_pcnoc_snoc = { 374 .name = "mas_pcnoc_snoc", 375 .id = QCS404_PNOC_SNOC_MAS, 376 .buswidth = 8, 377 .mas_rpm_id = 29, 378 .slv_rpm_id = -1, 379 .num_links = ARRAY_SIZE(mas_pcnoc_snoc_links), 380 .links = mas_pcnoc_snoc_links, 381 }; 382 383 static const u16 mas_qdss_etr_links[] = { 384 QCS404_SNOC_QDSS_INT 385 }; 386 387 static struct qcom_icc_node mas_qdss_etr = { 388 .name = "mas_qdss_etr", 389 .id = QCS404_MASTER_QDSS_ETR, 390 .buswidth = 8, 391 .mas_rpm_id = -1, 392 .slv_rpm_id = -1, 393 .qos.ap_owned = true, 394 .qos.qos_mode = NOC_QOS_MODE_FIXED, 395 .qos.areq_prio = 1, 396 .qos.prio_level = 1, 397 .qos.qos_port = 0, 398 .num_links = ARRAY_SIZE(mas_qdss_etr_links), 399 .links = mas_qdss_etr_links, 400 }; 401 402 static const u16 mas_emac_links[] = { 403 QCS404_SNOC_BIMC_1_SLV, 404 QCS404_SNOC_INT_1 405 }; 406 407 static struct qcom_icc_node mas_emac = { 408 .name = "mas_emac", 409 .id = QCS404_MASTER_EMAC, 410 .buswidth = 8, 411 .mas_rpm_id = -1, 412 .slv_rpm_id = -1, 413 .qos.ap_owned = true, 414 .qos.qos_mode = NOC_QOS_MODE_FIXED, 415 .qos.areq_prio = 1, 416 .qos.prio_level = 1, 417 .qos.qos_port = 17, 418 .num_links = ARRAY_SIZE(mas_emac_links), 419 .links = mas_emac_links, 420 }; 421 422 static const u16 mas_pcie_links[] = { 423 QCS404_SNOC_BIMC_1_SLV, 424 QCS404_SNOC_INT_1 425 }; 426 427 static struct qcom_icc_node mas_pcie = { 428 .name = "mas_pcie", 429 .id = QCS404_MASTER_PCIE, 430 .buswidth = 8, 431 .mas_rpm_id = -1, 432 .slv_rpm_id = -1, 433 .qos.ap_owned = true, 434 .qos.qos_mode = NOC_QOS_MODE_FIXED, 435 .qos.areq_prio = 1, 436 .qos.prio_level = 1, 437 .qos.qos_port = 8, 438 .num_links = ARRAY_SIZE(mas_pcie_links), 439 .links = mas_pcie_links, 440 }; 441 442 static const u16 mas_usb3_links[] = { 443 QCS404_SNOC_BIMC_1_SLV, 444 QCS404_SNOC_INT_1 445 }; 446 447 static struct qcom_icc_node mas_usb3 = { 448 .name = "mas_usb3", 449 .id = QCS404_MASTER_USB3, 450 .buswidth = 8, 451 .mas_rpm_id = -1, 452 .slv_rpm_id = -1, 453 .qos.ap_owned = true, 454 .qos.qos_mode = NOC_QOS_MODE_FIXED, 455 .qos.areq_prio = 1, 456 .qos.prio_level = 1, 457 .qos.qos_port = 16, 458 .num_links = ARRAY_SIZE(mas_usb3_links), 459 .links = mas_usb3_links, 460 }; 461 462 static const u16 pcnoc_int_0_links[] = { 463 QCS404_PNOC_SNOC_SLV, 464 QCS404_PNOC_INT_2 465 }; 466 467 static struct qcom_icc_node pcnoc_int_0 = { 468 .name = "pcnoc_int_0", 469 .id = QCS404_PNOC_INT_0, 470 .buswidth = 8, 471 .mas_rpm_id = 85, 472 .slv_rpm_id = 114, 473 .num_links = ARRAY_SIZE(pcnoc_int_0_links), 474 .links = pcnoc_int_0_links, 475 }; 476 477 static const u16 pcnoc_int_2_links[] = { 478 QCS404_PNOC_SLV_10, 479 QCS404_SLAVE_TCU, 480 QCS404_PNOC_SLV_11, 481 QCS404_PNOC_SLV_2, 482 QCS404_PNOC_SLV_3, 483 QCS404_PNOC_SLV_0, 484 QCS404_PNOC_SLV_1, 485 QCS404_PNOC_SLV_6, 486 QCS404_PNOC_SLV_7, 487 QCS404_PNOC_SLV_4, 488 QCS404_PNOC_SLV_8, 489 QCS404_PNOC_SLV_9 490 }; 491 492 static struct qcom_icc_node pcnoc_int_2 = { 493 .name = "pcnoc_int_2", 494 .id = QCS404_PNOC_INT_2, 495 .buswidth = 8, 496 .mas_rpm_id = 124, 497 .slv_rpm_id = 184, 498 .num_links = ARRAY_SIZE(pcnoc_int_2_links), 499 .links = pcnoc_int_2_links, 500 }; 501 502 static const u16 pcnoc_int_3_links[] = { 503 QCS404_PNOC_SNOC_SLV 504 }; 505 506 static struct qcom_icc_node pcnoc_int_3 = { 507 .name = "pcnoc_int_3", 508 .id = QCS404_PNOC_INT_3, 509 .buswidth = 8, 510 .mas_rpm_id = 125, 511 .slv_rpm_id = 185, 512 .num_links = ARRAY_SIZE(pcnoc_int_3_links), 513 .links = pcnoc_int_3_links, 514 }; 515 516 static const u16 pcnoc_s_0_links[] = { 517 QCS404_SLAVE_PRNG, 518 QCS404_SLAVE_SPDM_WRAPPER, 519 QCS404_SLAVE_PDM 520 }; 521 522 static struct qcom_icc_node pcnoc_s_0 = { 523 .name = "pcnoc_s_0", 524 .id = QCS404_PNOC_SLV_0, 525 .buswidth = 4, 526 .mas_rpm_id = 89, 527 .slv_rpm_id = 118, 528 .num_links = ARRAY_SIZE(pcnoc_s_0_links), 529 .links = pcnoc_s_0_links, 530 }; 531 532 static const u16 pcnoc_s_1_links[] = { 533 QCS404_SLAVE_TCSR 534 }; 535 536 static struct qcom_icc_node pcnoc_s_1 = { 537 .name = "pcnoc_s_1", 538 .id = QCS404_PNOC_SLV_1, 539 .buswidth = 4, 540 .mas_rpm_id = 90, 541 .slv_rpm_id = 119, 542 .num_links = ARRAY_SIZE(pcnoc_s_1_links), 543 .links = pcnoc_s_1_links, 544 }; 545 546 static const u16 pcnoc_s_2_links[] = { 547 QCS404_SLAVE_GRAPHICS_3D_CFG 548 }; 549 550 static struct qcom_icc_node pcnoc_s_2 = { 551 .name = "pcnoc_s_2", 552 .id = QCS404_PNOC_SLV_2, 553 .buswidth = 4, 554 .mas_rpm_id = -1, 555 .slv_rpm_id = -1, 556 .qos.ap_owned = true, 557 .qos.qos_mode = NOC_QOS_MODE_INVALID, 558 .num_links = ARRAY_SIZE(pcnoc_s_2_links), 559 .links = pcnoc_s_2_links, 560 }; 561 562 static const u16 pcnoc_s_3_links[] = { 563 QCS404_SLAVE_MESSAGE_RAM 564 }; 565 566 static struct qcom_icc_node pcnoc_s_3 = { 567 .name = "pcnoc_s_3", 568 .id = QCS404_PNOC_SLV_3, 569 .buswidth = 4, 570 .mas_rpm_id = 92, 571 .slv_rpm_id = 121, 572 .num_links = ARRAY_SIZE(pcnoc_s_3_links), 573 .links = pcnoc_s_3_links, 574 }; 575 576 static const u16 pcnoc_s_4_links[] = { 577 QCS404_SLAVE_SNOC_CFG 578 }; 579 580 static struct qcom_icc_node pcnoc_s_4 = { 581 .name = "pcnoc_s_4", 582 .id = QCS404_PNOC_SLV_4, 583 .buswidth = 4, 584 .mas_rpm_id = 93, 585 .slv_rpm_id = 122, 586 .num_links = ARRAY_SIZE(pcnoc_s_4_links), 587 .links = pcnoc_s_4_links, 588 }; 589 590 static const u16 pcnoc_s_6_links[] = { 591 QCS404_SLAVE_BLSP_1, 592 QCS404_SLAVE_TLMM_NORTH, 593 QCS404_SLAVE_EMAC_CFG 594 }; 595 596 static struct qcom_icc_node pcnoc_s_6 = { 597 .name = "pcnoc_s_6", 598 .id = QCS404_PNOC_SLV_6, 599 .buswidth = 4, 600 .mas_rpm_id = 94, 601 .slv_rpm_id = 123, 602 .num_links = ARRAY_SIZE(pcnoc_s_6_links), 603 .links = pcnoc_s_6_links, 604 }; 605 606 static const u16 pcnoc_s_7_links[] = { 607 QCS404_SLAVE_TLMM_SOUTH, 608 QCS404_SLAVE_DISPLAY_CFG, 609 QCS404_SLAVE_SDCC_1, 610 QCS404_SLAVE_PCIE_1, 611 QCS404_SLAVE_SDCC_2 612 }; 613 614 static struct qcom_icc_node pcnoc_s_7 = { 615 .name = "pcnoc_s_7", 616 .id = QCS404_PNOC_SLV_7, 617 .buswidth = 4, 618 .mas_rpm_id = 95, 619 .slv_rpm_id = 124, 620 .num_links = ARRAY_SIZE(pcnoc_s_7_links), 621 .links = pcnoc_s_7_links, 622 }; 623 624 static const u16 pcnoc_s_8_links[] = { 625 QCS404_SLAVE_CRYPTO_0_CFG 626 }; 627 628 static struct qcom_icc_node pcnoc_s_8 = { 629 .name = "pcnoc_s_8", 630 .id = QCS404_PNOC_SLV_8, 631 .buswidth = 4, 632 .mas_rpm_id = 96, 633 .slv_rpm_id = 125, 634 .num_links = ARRAY_SIZE(pcnoc_s_8_links), 635 .links = pcnoc_s_8_links, 636 }; 637 638 static const u16 pcnoc_s_9_links[] = { 639 QCS404_SLAVE_BLSP_2, 640 QCS404_SLAVE_TLMM_EAST, 641 QCS404_SLAVE_PMIC_ARB 642 }; 643 644 static struct qcom_icc_node pcnoc_s_9 = { 645 .name = "pcnoc_s_9", 646 .id = QCS404_PNOC_SLV_9, 647 .buswidth = 4, 648 .mas_rpm_id = 97, 649 .slv_rpm_id = 126, 650 .num_links = ARRAY_SIZE(pcnoc_s_9_links), 651 .links = pcnoc_s_9_links, 652 }; 653 654 static const u16 pcnoc_s_10_links[] = { 655 QCS404_SLAVE_USB_HS 656 }; 657 658 static struct qcom_icc_node pcnoc_s_10 = { 659 .name = "pcnoc_s_10", 660 .id = QCS404_PNOC_SLV_10, 661 .buswidth = 4, 662 .mas_rpm_id = 157, 663 .slv_rpm_id = -1, 664 .num_links = ARRAY_SIZE(pcnoc_s_10_links), 665 .links = pcnoc_s_10_links, 666 }; 667 668 static const u16 pcnoc_s_11_links[] = { 669 QCS404_SLAVE_USB3 670 }; 671 672 static struct qcom_icc_node pcnoc_s_11 = { 673 .name = "pcnoc_s_11", 674 .id = QCS404_PNOC_SLV_11, 675 .buswidth = 4, 676 .mas_rpm_id = 158, 677 .slv_rpm_id = 246, 678 .num_links = ARRAY_SIZE(pcnoc_s_11_links), 679 .links = pcnoc_s_11_links, 680 }; 681 682 static const u16 qdss_int_links[] = { 683 QCS404_SNOC_BIMC_1_SLV, 684 QCS404_SNOC_INT_1 685 }; 686 687 static struct qcom_icc_node qdss_int = { 688 .name = "qdss_int", 689 .id = QCS404_SNOC_QDSS_INT, 690 .buswidth = 8, 691 .mas_rpm_id = -1, 692 .slv_rpm_id = -1, 693 .qos.ap_owned = true, 694 .qos.qos_mode = NOC_QOS_MODE_INVALID, 695 .num_links = ARRAY_SIZE(qdss_int_links), 696 .links = qdss_int_links, 697 }; 698 699 static const u16 snoc_int_0_links[] = { 700 QCS404_SLAVE_LPASS, 701 QCS404_SLAVE_APPSS, 702 QCS404_SLAVE_WCSS 703 }; 704 705 static struct qcom_icc_node snoc_int_0 = { 706 .name = "snoc_int_0", 707 .id = QCS404_SNOC_INT_0, 708 .buswidth = 8, 709 .mas_rpm_id = 99, 710 .slv_rpm_id = 130, 711 .num_links = ARRAY_SIZE(snoc_int_0_links), 712 .links = snoc_int_0_links, 713 }; 714 715 static const u16 snoc_int_1_links[] = { 716 QCS404_SNOC_PNOC_SLV, 717 QCS404_SNOC_INT_2 718 }; 719 720 static struct qcom_icc_node snoc_int_1 = { 721 .name = "snoc_int_1", 722 .id = QCS404_SNOC_INT_1, 723 .buswidth = 8, 724 .mas_rpm_id = 100, 725 .slv_rpm_id = 131, 726 .num_links = ARRAY_SIZE(snoc_int_1_links), 727 .links = snoc_int_1_links, 728 }; 729 730 static const u16 snoc_int_2_links[] = { 731 QCS404_SLAVE_QDSS_STM, 732 QCS404_SLAVE_OCIMEM 733 }; 734 735 static struct qcom_icc_node snoc_int_2 = { 736 .name = "snoc_int_2", 737 .id = QCS404_SNOC_INT_2, 738 .buswidth = 8, 739 .mas_rpm_id = 134, 740 .slv_rpm_id = 197, 741 .num_links = ARRAY_SIZE(snoc_int_2_links), 742 .links = snoc_int_2_links, 743 }; 744 745 static struct qcom_icc_node slv_ebi = { 746 .name = "slv_ebi", 747 .id = QCS404_SLAVE_EBI_CH0, 748 .buswidth = 8, 749 .mas_rpm_id = -1, 750 .slv_rpm_id = 0, 751 }; 752 753 static const u16 slv_bimc_snoc_links[] = { 754 QCS404_BIMC_SNOC_MAS 755 }; 756 757 static struct qcom_icc_node slv_bimc_snoc = { 758 .name = "slv_bimc_snoc", 759 .id = QCS404_BIMC_SNOC_SLV, 760 .buswidth = 8, 761 .mas_rpm_id = -1, 762 .slv_rpm_id = 2, 763 .num_links = ARRAY_SIZE(slv_bimc_snoc_links), 764 .links = slv_bimc_snoc_links, 765 }; 766 767 static struct qcom_icc_node slv_spdm = { 768 .name = "slv_spdm", 769 .id = QCS404_SLAVE_SPDM_WRAPPER, 770 .buswidth = 4, 771 .mas_rpm_id = -1, 772 .slv_rpm_id = -1, 773 .qos.ap_owned = true, 774 .qos.qos_mode = NOC_QOS_MODE_INVALID, 775 }; 776 777 static struct qcom_icc_node slv_pdm = { 778 .name = "slv_pdm", 779 .id = QCS404_SLAVE_PDM, 780 .buswidth = 4, 781 .mas_rpm_id = -1, 782 .slv_rpm_id = 41, 783 }; 784 785 static struct qcom_icc_node slv_prng = { 786 .name = "slv_prng", 787 .id = QCS404_SLAVE_PRNG, 788 .buswidth = 4, 789 .mas_rpm_id = -1, 790 .slv_rpm_id = 44, 791 }; 792 793 static struct qcom_icc_node slv_tcsr = { 794 .name = "slv_tcsr", 795 .id = QCS404_SLAVE_TCSR, 796 .buswidth = 4, 797 .mas_rpm_id = -1, 798 .slv_rpm_id = 50, 799 }; 800 801 static struct qcom_icc_node slv_snoc_cfg = { 802 .name = "slv_snoc_cfg", 803 .id = QCS404_SLAVE_SNOC_CFG, 804 .buswidth = 4, 805 .mas_rpm_id = -1, 806 .slv_rpm_id = 70, 807 }; 808 809 static struct qcom_icc_node slv_message_ram = { 810 .name = "slv_message_ram", 811 .id = QCS404_SLAVE_MESSAGE_RAM, 812 .buswidth = 4, 813 .mas_rpm_id = -1, 814 .slv_rpm_id = 55, 815 }; 816 817 static struct qcom_icc_node slv_disp_ss_cfg = { 818 .name = "slv_disp_ss_cfg", 819 .id = QCS404_SLAVE_DISPLAY_CFG, 820 .buswidth = 4, 821 .mas_rpm_id = -1, 822 .slv_rpm_id = -1, 823 .qos.ap_owned = true, 824 .qos.qos_mode = NOC_QOS_MODE_INVALID, 825 }; 826 827 static struct qcom_icc_node slv_gpu_cfg = { 828 .name = "slv_gpu_cfg", 829 .id = QCS404_SLAVE_GRAPHICS_3D_CFG, 830 .buswidth = 4, 831 .mas_rpm_id = -1, 832 .slv_rpm_id = -1, 833 .qos.ap_owned = true, 834 .qos.qos_mode = NOC_QOS_MODE_INVALID, 835 }; 836 837 static struct qcom_icc_node slv_blsp_1 = { 838 .name = "slv_blsp_1", 839 .id = QCS404_SLAVE_BLSP_1, 840 .buswidth = 4, 841 .mas_rpm_id = -1, 842 .slv_rpm_id = 39, 843 }; 844 845 static struct qcom_icc_node slv_tlmm_north = { 846 .name = "slv_tlmm_north", 847 .id = QCS404_SLAVE_TLMM_NORTH, 848 .buswidth = 4, 849 .mas_rpm_id = -1, 850 .slv_rpm_id = 214, 851 }; 852 853 static struct qcom_icc_node slv_pcie = { 854 .name = "slv_pcie", 855 .id = QCS404_SLAVE_PCIE_1, 856 .buswidth = 4, 857 .mas_rpm_id = -1, 858 .slv_rpm_id = -1, 859 .qos.ap_owned = true, 860 .qos.qos_mode = NOC_QOS_MODE_INVALID, 861 }; 862 863 static struct qcom_icc_node slv_ethernet = { 864 .name = "slv_ethernet", 865 .id = QCS404_SLAVE_EMAC_CFG, 866 .buswidth = 4, 867 .mas_rpm_id = -1, 868 .slv_rpm_id = -1, 869 .qos.ap_owned = true, 870 .qos.qos_mode = NOC_QOS_MODE_INVALID, 871 }; 872 873 static struct qcom_icc_node slv_blsp_2 = { 874 .name = "slv_blsp_2", 875 .id = QCS404_SLAVE_BLSP_2, 876 .buswidth = 4, 877 .mas_rpm_id = -1, 878 .slv_rpm_id = 37, 879 }; 880 881 static struct qcom_icc_node slv_tlmm_east = { 882 .name = "slv_tlmm_east", 883 .id = QCS404_SLAVE_TLMM_EAST, 884 .buswidth = 4, 885 .mas_rpm_id = -1, 886 .slv_rpm_id = 213, 887 }; 888 889 static struct qcom_icc_node slv_tcu = { 890 .name = "slv_tcu", 891 .id = QCS404_SLAVE_TCU, 892 .buswidth = 8, 893 .mas_rpm_id = -1, 894 .slv_rpm_id = -1, 895 .qos.ap_owned = true, 896 .qos.qos_mode = NOC_QOS_MODE_INVALID, 897 }; 898 899 static struct qcom_icc_node slv_pmic_arb = { 900 .name = "slv_pmic_arb", 901 .id = QCS404_SLAVE_PMIC_ARB, 902 .buswidth = 4, 903 .mas_rpm_id = -1, 904 .slv_rpm_id = 59, 905 }; 906 907 static struct qcom_icc_node slv_sdcc_1 = { 908 .name = "slv_sdcc_1", 909 .id = QCS404_SLAVE_SDCC_1, 910 .buswidth = 4, 911 .mas_rpm_id = -1, 912 .slv_rpm_id = 31, 913 }; 914 915 static struct qcom_icc_node slv_sdcc_2 = { 916 .name = "slv_sdcc_2", 917 .id = QCS404_SLAVE_SDCC_2, 918 .buswidth = 4, 919 .mas_rpm_id = -1, 920 .slv_rpm_id = 33, 921 }; 922 923 static struct qcom_icc_node slv_tlmm_south = { 924 .name = "slv_tlmm_south", 925 .id = QCS404_SLAVE_TLMM_SOUTH, 926 .buswidth = 4, 927 .mas_rpm_id = -1, 928 .slv_rpm_id = -1, 929 }; 930 931 static struct qcom_icc_node slv_usb_hs = { 932 .name = "slv_usb_hs", 933 .id = QCS404_SLAVE_USB_HS, 934 .buswidth = 4, 935 .mas_rpm_id = -1, 936 .slv_rpm_id = 40, 937 }; 938 939 static struct qcom_icc_node slv_usb3 = { 940 .name = "slv_usb3", 941 .id = QCS404_SLAVE_USB3, 942 .buswidth = 4, 943 .mas_rpm_id = -1, 944 .slv_rpm_id = 22, 945 }; 946 947 static struct qcom_icc_node slv_crypto_0_cfg = { 948 .name = "slv_crypto_0_cfg", 949 .id = QCS404_SLAVE_CRYPTO_0_CFG, 950 .buswidth = 4, 951 .mas_rpm_id = -1, 952 .slv_rpm_id = 52, 953 }; 954 955 static const u16 slv_pcnoc_snoc_links[] = { 956 QCS404_PNOC_SNOC_MAS 957 }; 958 959 static struct qcom_icc_node slv_pcnoc_snoc = { 960 .name = "slv_pcnoc_snoc", 961 .id = QCS404_PNOC_SNOC_SLV, 962 .buswidth = 8, 963 .mas_rpm_id = -1, 964 .slv_rpm_id = 45, 965 .num_links = ARRAY_SIZE(slv_pcnoc_snoc_links), 966 .links = slv_pcnoc_snoc_links, 967 }; 968 969 static struct qcom_icc_node slv_kpss_ahb = { 970 .name = "slv_kpss_ahb", 971 .id = QCS404_SLAVE_APPSS, 972 .buswidth = 4, 973 .mas_rpm_id = -1, 974 .slv_rpm_id = -1, 975 .qos.ap_owned = true, 976 .qos.qos_mode = NOC_QOS_MODE_INVALID, 977 }; 978 979 static struct qcom_icc_node slv_wcss = { 980 .name = "slv_wcss", 981 .id = QCS404_SLAVE_WCSS, 982 .buswidth = 4, 983 .mas_rpm_id = -1, 984 .slv_rpm_id = 23, 985 }; 986 987 static const u16 slv_snoc_bimc_1_links[] = { 988 QCS404_SNOC_BIMC_1_MAS 989 }; 990 991 static struct qcom_icc_node slv_snoc_bimc_1 = { 992 .name = "slv_snoc_bimc_1", 993 .id = QCS404_SNOC_BIMC_1_SLV, 994 .buswidth = 8, 995 .mas_rpm_id = -1, 996 .slv_rpm_id = 104, 997 .num_links = ARRAY_SIZE(slv_snoc_bimc_1_links), 998 .links = slv_snoc_bimc_1_links, 999 }; 1000 1001 static struct qcom_icc_node slv_imem = { 1002 .name = "slv_imem", 1003 .id = QCS404_SLAVE_OCIMEM, 1004 .buswidth = 8, 1005 .mas_rpm_id = -1, 1006 .slv_rpm_id = 26, 1007 }; 1008 1009 static const u16 slv_snoc_pcnoc_links[] = { 1010 QCS404_SNOC_PNOC_MAS 1011 }; 1012 1013 static struct qcom_icc_node slv_snoc_pcnoc = { 1014 .name = "slv_snoc_pcnoc", 1015 .id = QCS404_SNOC_PNOC_SLV, 1016 .buswidth = 8, 1017 .mas_rpm_id = -1, 1018 .slv_rpm_id = 28, 1019 .num_links = ARRAY_SIZE(slv_snoc_pcnoc_links), 1020 .links = slv_snoc_pcnoc_links, 1021 }; 1022 1023 static struct qcom_icc_node slv_qdss_stm = { 1024 .name = "slv_qdss_stm", 1025 .id = QCS404_SLAVE_QDSS_STM, 1026 .buswidth = 4, 1027 .mas_rpm_id = -1, 1028 .slv_rpm_id = 30, 1029 }; 1030 1031 static struct qcom_icc_node slv_cats_0 = { 1032 .name = "slv_cats_0", 1033 .id = QCS404_SLAVE_CATS_128, 1034 .buswidth = 16, 1035 .mas_rpm_id = -1, 1036 .slv_rpm_id = -1, 1037 .qos.ap_owned = true, 1038 .qos.qos_mode = NOC_QOS_MODE_INVALID, 1039 }; 1040 1041 static struct qcom_icc_node slv_cats_1 = { 1042 .name = "slv_cats_1", 1043 .id = QCS404_SLAVE_OCMEM_64, 1044 .buswidth = 8, 1045 .mas_rpm_id = -1, 1046 .slv_rpm_id = -1, 1047 .qos.ap_owned = true, 1048 .qos.qos_mode = NOC_QOS_MODE_INVALID, 1049 }; 1050 1051 static struct qcom_icc_node slv_lpass = { 1052 .name = "slv_lpass", 1053 .id = QCS404_SLAVE_LPASS, 1054 .buswidth = 4, 1055 .mas_rpm_id = -1, 1056 .slv_rpm_id = -1, 1057 .qos.ap_owned = true, 1058 .qos.qos_mode = NOC_QOS_MODE_INVALID, 1059 }; 1060 1061 static struct qcom_icc_node * const qcs404_bimc_nodes[] = { 1062 [MASTER_AMPSS_M0] = &mas_apps_proc, 1063 [MASTER_OXILI] = &mas_oxili, 1064 [MASTER_MDP_PORT0] = &mas_mdp, 1065 [MASTER_SNOC_BIMC_1] = &mas_snoc_bimc_1, 1066 [MASTER_TCU_0] = &mas_tcu_0, 1067 [SLAVE_EBI_CH0] = &slv_ebi, 1068 [SLAVE_BIMC_SNOC] = &slv_bimc_snoc, 1069 }; 1070 1071 static const struct regmap_config qcs404_bimc_regmap_config = { 1072 .reg_bits = 32, 1073 .reg_stride = 4, 1074 .val_bits = 32, 1075 .max_register = 0x80000, 1076 .fast_io = true, 1077 }; 1078 1079 static const struct qcom_icc_desc qcs404_bimc = { 1080 .type = QCOM_ICC_BIMC, 1081 .nodes = qcs404_bimc_nodes, 1082 .num_nodes = ARRAY_SIZE(qcs404_bimc_nodes), 1083 .bus_clk_desc = &bimc_clk, 1084 .regmap_cfg = &qcs404_bimc_regmap_config, 1085 .qos_offset = 0x8000, 1086 .ab_coeff = 153, 1087 }; 1088 1089 static struct qcom_icc_node * const qcs404_pcnoc_nodes[] = { 1090 [MASTER_SPDM] = &mas_spdm, 1091 [MASTER_BLSP_1] = &mas_blsp_1, 1092 [MASTER_BLSP_2] = &mas_blsp_2, 1093 [MASTER_XI_USB_HS1] = &mas_xi_usb_hs1, 1094 [MASTER_CRYPT0] = &mas_crypto, 1095 [MASTER_SDCC_1] = &mas_sdcc_1, 1096 [MASTER_SDCC_2] = &mas_sdcc_2, 1097 [MASTER_SNOC_PCNOC] = &mas_snoc_pcnoc, 1098 [MASTER_QPIC] = &mas_qpic, 1099 [PCNOC_INT_0] = &pcnoc_int_0, 1100 [PCNOC_INT_2] = &pcnoc_int_2, 1101 [PCNOC_INT_3] = &pcnoc_int_3, 1102 [PCNOC_S_0] = &pcnoc_s_0, 1103 [PCNOC_S_1] = &pcnoc_s_1, 1104 [PCNOC_S_2] = &pcnoc_s_2, 1105 [PCNOC_S_3] = &pcnoc_s_3, 1106 [PCNOC_S_4] = &pcnoc_s_4, 1107 [PCNOC_S_6] = &pcnoc_s_6, 1108 [PCNOC_S_7] = &pcnoc_s_7, 1109 [PCNOC_S_8] = &pcnoc_s_8, 1110 [PCNOC_S_9] = &pcnoc_s_9, 1111 [PCNOC_S_10] = &pcnoc_s_10, 1112 [PCNOC_S_11] = &pcnoc_s_11, 1113 [SLAVE_SPDM] = &slv_spdm, 1114 [SLAVE_PDM] = &slv_pdm, 1115 [SLAVE_PRNG] = &slv_prng, 1116 [SLAVE_TCSR] = &slv_tcsr, 1117 [SLAVE_SNOC_CFG] = &slv_snoc_cfg, 1118 [SLAVE_MESSAGE_RAM] = &slv_message_ram, 1119 [SLAVE_DISP_SS_CFG] = &slv_disp_ss_cfg, 1120 [SLAVE_GPU_CFG] = &slv_gpu_cfg, 1121 [SLAVE_BLSP_1] = &slv_blsp_1, 1122 [SLAVE_BLSP_2] = &slv_blsp_2, 1123 [SLAVE_TLMM_NORTH] = &slv_tlmm_north, 1124 [SLAVE_PCIE] = &slv_pcie, 1125 [SLAVE_ETHERNET] = &slv_ethernet, 1126 [SLAVE_TLMM_EAST] = &slv_tlmm_east, 1127 [SLAVE_TCU] = &slv_tcu, 1128 [SLAVE_PMIC_ARB] = &slv_pmic_arb, 1129 [SLAVE_SDCC_1] = &slv_sdcc_1, 1130 [SLAVE_SDCC_2] = &slv_sdcc_2, 1131 [SLAVE_TLMM_SOUTH] = &slv_tlmm_south, 1132 [SLAVE_USB_HS] = &slv_usb_hs, 1133 [SLAVE_USB3] = &slv_usb3, 1134 [SLAVE_CRYPTO_0_CFG] = &slv_crypto_0_cfg, 1135 [SLAVE_PCNOC_SNOC] = &slv_pcnoc_snoc, 1136 }; 1137 1138 static const struct regmap_config qcs404_pcnoc_regmap_config = { 1139 .reg_bits = 32, 1140 .reg_stride = 4, 1141 .val_bits = 32, 1142 .max_register = 0x15080, 1143 .fast_io = true, 1144 }; 1145 1146 static const struct qcom_icc_desc qcs404_pcnoc = { 1147 .type = QCOM_ICC_NOC, 1148 .nodes = qcs404_pcnoc_nodes, 1149 .num_nodes = ARRAY_SIZE(qcs404_pcnoc_nodes), 1150 .bus_clk_desc = &bus_0_clk, 1151 .qos_offset = 0x7000, 1152 .keep_alive = true, 1153 .regmap_cfg = &qcs404_pcnoc_regmap_config, 1154 }; 1155 1156 static struct qcom_icc_node * const qcs404_snoc_nodes[] = { 1157 [MASTER_QDSS_BAM] = &mas_qdss_bam, 1158 [MASTER_BIMC_SNOC] = &mas_bimc_snoc, 1159 [MASTER_PCNOC_SNOC] = &mas_pcnoc_snoc, 1160 [MASTER_QDSS_ETR] = &mas_qdss_etr, 1161 [MASTER_EMAC] = &mas_emac, 1162 [MASTER_PCIE] = &mas_pcie, 1163 [MASTER_USB3] = &mas_usb3, 1164 [QDSS_INT] = &qdss_int, 1165 [SNOC_INT_0] = &snoc_int_0, 1166 [SNOC_INT_1] = &snoc_int_1, 1167 [SNOC_INT_2] = &snoc_int_2, 1168 [SLAVE_KPSS_AHB] = &slv_kpss_ahb, 1169 [SLAVE_WCSS] = &slv_wcss, 1170 [SLAVE_SNOC_BIMC_1] = &slv_snoc_bimc_1, 1171 [SLAVE_IMEM] = &slv_imem, 1172 [SLAVE_SNOC_PCNOC] = &slv_snoc_pcnoc, 1173 [SLAVE_QDSS_STM] = &slv_qdss_stm, 1174 [SLAVE_CATS_0] = &slv_cats_0, 1175 [SLAVE_CATS_1] = &slv_cats_1, 1176 [SLAVE_LPASS] = &slv_lpass, 1177 }; 1178 1179 static const struct regmap_config qcs404_snoc_regmap_config = { 1180 .reg_bits = 32, 1181 .reg_stride = 4, 1182 .val_bits = 32, 1183 .max_register = 0x23080, 1184 .fast_io = true, 1185 }; 1186 1187 static const struct qcom_icc_desc qcs404_snoc = { 1188 .type = QCOM_ICC_NOC, 1189 .nodes = qcs404_snoc_nodes, 1190 .num_nodes = ARRAY_SIZE(qcs404_snoc_nodes), 1191 .bus_clk_desc = &bus_1_clk, 1192 .qos_offset = 0x11000, 1193 .regmap_cfg = &qcs404_snoc_regmap_config, 1194 }; 1195 1196 1197 static const struct of_device_id qcs404_noc_of_match[] = { 1198 { .compatible = "qcom,qcs404-bimc", .data = &qcs404_bimc }, 1199 { .compatible = "qcom,qcs404-pcnoc", .data = &qcs404_pcnoc }, 1200 { .compatible = "qcom,qcs404-snoc", .data = &qcs404_snoc }, 1201 { }, 1202 }; 1203 MODULE_DEVICE_TABLE(of, qcs404_noc_of_match); 1204 1205 static struct platform_driver qcs404_noc_driver = { 1206 .probe = qnoc_probe, 1207 .remove_new = qnoc_remove, 1208 .driver = { 1209 .name = "qnoc-qcs404", 1210 .of_match_table = qcs404_noc_of_match, 1211 }, 1212 }; 1213 module_platform_driver(qcs404_noc_driver); 1214 MODULE_DESCRIPTION("Qualcomm QCS404 NoC driver"); 1215 MODULE_LICENSE("GPL v2"); 1216