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

Merge tag 'arm-soc/for-5.5/drivers' of https://github.com/Broadcom/stblinux into arm/drivers

This pull request contains Broadcom ARM/ARM64/MIPS based SoCs drivers
updates for 5.5, please pull the following:

- Markus updates the DPFE driver so as to support deferring the firmware
loading process until the first sysfs attribute is accessed, in the
process he does a bunch of cleanups and minor fixes

- Florian adds support for the DPFE on 7211 which uses a "new style" API
v2 and makes necessary changes along the way

* tag 'arm-soc/for-5.5/drivers' of https://github.com/Broadcom/stblinux:
memory: brcmstb: dpfe: Fixup API version/commands for 7211
memory: brcmstb: dpfe: Compute checksum at __send_command() time
memory: brcmstb: dpfe: support for deferred firmware download
memory: brcmstb: dpfe: pass *priv as argument to brcmstb_dpfe_download_firmware()
memory: brcmstb: dpfe: move init_data into brcmstb_dpfe_download_firmware()
memory: brcmstb: dpfe: add locking around DCPU enable/disable
memory: brcmstb: dpfe: initialize priv->dev
memory: brcmstb: dpfe: rename struct private_data

Link: https://lore.kernel.org/r/20191023212814.30622-2-f.fainelli@gmail.com
Signed-off-by: Olof Johansson <olof@lixom.net>

+101 -63
+101 -63
drivers/memory/brcmstb_dpfe.c
··· 127 127 MSG_COMMAND, 128 128 MSG_ARG_COUNT, 129 129 MSG_ARG0, 130 - MSG_CHKSUM, 131 130 MSG_FIELD_MAX = 16 /* Max number of arguments */ 132 131 }; 133 132 ··· 179 180 }; 180 181 181 182 /* Things we need for as long as we are active. */ 182 - struct private_data { 183 + struct brcmstb_dpfe_priv { 183 184 void __iomem *regs; 184 185 void __iomem *dmem; 185 186 void __iomem *imem; ··· 231 232 }; 232 233 ATTRIBUTE_GROUPS(dpfe_v3); 233 234 234 - /* API v2 firmware commands */ 235 - static const struct dpfe_api dpfe_api_v2 = { 236 - .version = 2, 235 + /* 236 + * Old API v2 firmware commands, as defined in the rev 0.61 specification, we 237 + * use a version set to 1 to denote that it is not compatible with the new API 238 + * v2 and onwards. 239 + */ 240 + static const struct dpfe_api dpfe_api_old_v2 = { 241 + .version = 1, 237 242 .fw_name = "dpfe.bin", 238 243 .sysfs_attrs = dpfe_v2_groups, 239 244 .command = { ··· 246 243 [MSG_COMMAND] = 1, 247 244 [MSG_ARG_COUNT] = 1, 248 245 [MSG_ARG0] = 1, 249 - [MSG_CHKSUM] = 4, 250 246 }, 251 247 [DPFE_CMD_GET_REFRESH] = { 252 248 [MSG_HEADER] = DPFE_MSG_TYPE_COMMAND, 253 249 [MSG_COMMAND] = 2, 254 250 [MSG_ARG_COUNT] = 1, 255 251 [MSG_ARG0] = 1, 256 - [MSG_CHKSUM] = 5, 257 252 }, 258 253 [DPFE_CMD_GET_VENDOR] = { 259 254 [MSG_HEADER] = DPFE_MSG_TYPE_COMMAND, 260 255 [MSG_COMMAND] = 2, 261 256 [MSG_ARG_COUNT] = 1, 262 257 [MSG_ARG0] = 2, 263 - [MSG_CHKSUM] = 6, 258 + }, 259 + } 260 + }; 261 + 262 + /* 263 + * API v2 firmware commands, as defined in the rev 0.8 specification, named new 264 + * v2 here 265 + */ 266 + static const struct dpfe_api dpfe_api_new_v2 = { 267 + .version = 2, 268 + .fw_name = NULL, /* We expect the firmware to have been downloaded! */ 269 + .sysfs_attrs = dpfe_v2_groups, 270 + .command = { 271 + [DPFE_CMD_GET_INFO] = { 272 + [MSG_HEADER] = DPFE_MSG_TYPE_COMMAND, 273 + [MSG_COMMAND] = 0x101, 274 + }, 275 + [DPFE_CMD_GET_REFRESH] = { 276 + [MSG_HEADER] = DPFE_MSG_TYPE_COMMAND, 277 + [MSG_COMMAND] = 0x201, 278 + }, 279 + [DPFE_CMD_GET_VENDOR] = { 280 + [MSG_HEADER] = DPFE_MSG_TYPE_COMMAND, 281 + [MSG_COMMAND] = 0x202, 264 282 }, 265 283 } 266 284 }; ··· 297 273 [MSG_COMMAND] = 0x0101, 298 274 [MSG_ARG_COUNT] = 1, 299 275 [MSG_ARG0] = 1, 300 - [MSG_CHKSUM] = 0x104, 301 276 }, 302 277 [DPFE_CMD_GET_REFRESH] = { 303 278 [MSG_HEADER] = DPFE_MSG_TYPE_COMMAND, 304 279 [MSG_COMMAND] = 0x0202, 305 280 [MSG_ARG_COUNT] = 0, 306 - /* 307 - * This is a bit ugly. Without arguments, the checksum 308 - * follows right after the argument count and not at 309 - * offset MSG_CHKSUM. 310 - */ 311 - [MSG_ARG0] = 0x203, 312 281 }, 313 282 /* There's no GET_VENDOR command in API v3. */ 314 283 }, 315 284 }; 316 285 317 - static bool is_dcpu_enabled(void __iomem *regs) 286 + static bool is_dcpu_enabled(struct brcmstb_dpfe_priv *priv) 318 287 { 319 288 u32 val; 320 289 321 - val = readl_relaxed(regs + REG_DCPU_RESET); 290 + mutex_lock(&priv->lock); 291 + val = readl_relaxed(priv->regs + REG_DCPU_RESET); 292 + mutex_unlock(&priv->lock); 322 293 323 294 return !(val & DCPU_RESET_MASK); 324 295 } 325 296 326 - static void __disable_dcpu(void __iomem *regs) 297 + static void __disable_dcpu(struct brcmstb_dpfe_priv *priv) 327 298 { 328 299 u32 val; 329 300 330 - if (!is_dcpu_enabled(regs)) 301 + if (!is_dcpu_enabled(priv)) 331 302 return; 332 303 304 + mutex_lock(&priv->lock); 305 + 333 306 /* Put DCPU in reset if it's running. */ 334 - val = readl_relaxed(regs + REG_DCPU_RESET); 307 + val = readl_relaxed(priv->regs + REG_DCPU_RESET); 335 308 val |= (1 << DCPU_RESET_SHIFT); 336 - writel_relaxed(val, regs + REG_DCPU_RESET); 309 + writel_relaxed(val, priv->regs + REG_DCPU_RESET); 310 + 311 + mutex_unlock(&priv->lock); 337 312 } 338 313 339 - static void __enable_dcpu(void __iomem *regs) 314 + static void __enable_dcpu(struct brcmstb_dpfe_priv *priv) 340 315 { 316 + void __iomem *regs = priv->regs; 341 317 u32 val; 318 + 319 + mutex_lock(&priv->lock); 342 320 343 321 /* Clear mailbox registers. */ 344 322 writel_relaxed(0, regs + REG_TO_DCPU_MBOX); ··· 355 329 val = readl_relaxed(regs + REG_DCPU_RESET); 356 330 val &= ~(1 << DCPU_RESET_SHIFT); 357 331 writel_relaxed(val, regs + REG_DCPU_RESET); 332 + 333 + mutex_unlock(&priv->lock); 358 334 } 359 335 360 336 static unsigned int get_msg_chksum(const u32 msg[], unsigned int max) ··· 371 343 return sum; 372 344 } 373 345 374 - static void __iomem *get_msg_ptr(struct private_data *priv, u32 response, 346 + static void __iomem *get_msg_ptr(struct brcmstb_dpfe_priv *priv, u32 response, 375 347 char *buf, ssize_t *size) 376 348 { 377 349 unsigned int msg_type; ··· 410 382 return ptr; 411 383 } 412 384 413 - static void __finalize_command(struct private_data *priv) 385 + static void __finalize_command(struct brcmstb_dpfe_priv *priv) 414 386 { 415 387 unsigned int release_mbox; 416 388 ··· 418 390 * It depends on the API version which MBOX register we have to write to 419 391 * to signal we are done. 420 392 */ 421 - release_mbox = (priv->dpfe_api->version < 3) 393 + release_mbox = (priv->dpfe_api->version < 2) 422 394 ? REG_TO_HOST_MBOX : REG_TO_DCPU_MBOX; 423 395 writel_relaxed(0, priv->regs + release_mbox); 424 396 } 425 397 426 - static int __send_command(struct private_data *priv, unsigned int cmd, 398 + static int __send_command(struct brcmstb_dpfe_priv *priv, unsigned int cmd, 427 399 u32 result[]) 428 400 { 429 401 const u32 *msg = priv->dpfe_api->command[cmd]; ··· 449 421 return -ETIMEDOUT; 450 422 } 451 423 424 + /* Compute checksum over the message */ 425 + chksum_idx = msg[MSG_ARG_COUNT] + MSG_ARG_COUNT + 1; 426 + chksum = get_msg_chksum(msg, chksum_idx); 427 + 452 428 /* Write command and arguments to message area */ 453 - for (i = 0; i < MSG_FIELD_MAX; i++) 454 - writel_relaxed(msg[i], regs + DCPU_MSG_RAM(i)); 429 + for (i = 0; i < MSG_FIELD_MAX; i++) { 430 + if (i == chksum_idx) 431 + writel_relaxed(chksum, regs + DCPU_MSG_RAM(i)); 432 + else 433 + writel_relaxed(msg[i], regs + DCPU_MSG_RAM(i)); 434 + } 455 435 456 436 /* Tell DCPU there is a command waiting */ 457 437 writel_relaxed(1, regs + REG_TO_DCPU_MBOX); ··· 553 517 554 518 /* Verify checksum by reading back the firmware from co-processor RAM. */ 555 519 static int __verify_fw_checksum(struct init_data *init, 556 - struct private_data *priv, 520 + struct brcmstb_dpfe_priv *priv, 557 521 const struct dpfe_firmware_header *header, 558 522 u32 checksum) 559 523 { ··· 607 571 return 0; 608 572 } 609 573 610 - static int brcmstb_dpfe_download_firmware(struct platform_device *pdev, 611 - struct init_data *init) 574 + static int brcmstb_dpfe_download_firmware(struct brcmstb_dpfe_priv *priv) 612 575 { 613 576 const struct dpfe_firmware_header *header; 614 577 unsigned int dmem_size, imem_size; 615 - struct device *dev = &pdev->dev; 578 + struct device *dev = priv->dev; 616 579 bool is_big_endian = false; 617 - struct private_data *priv; 618 580 const struct firmware *fw; 619 581 const u32 *dmem, *imem; 582 + struct init_data init; 620 583 const void *fw_blob; 621 584 int ret; 622 - 623 - priv = platform_get_drvdata(pdev); 624 585 625 586 /* 626 587 * Skip downloading the firmware if the DCPU is already running and 627 588 * responding to commands. 628 589 */ 629 - if (is_dcpu_enabled(priv->regs)) { 590 + if (is_dcpu_enabled(priv)) { 630 591 u32 response[MSG_FIELD_MAX]; 631 592 632 593 ret = __send_command(priv, DPFE_CMD_GET_INFO, response); ··· 639 606 if (!priv->dpfe_api->fw_name) 640 607 return -ENODEV; 641 608 642 - ret = request_firmware(&fw, priv->dpfe_api->fw_name, dev); 643 - /* request_firmware() prints its own error messages. */ 609 + ret = firmware_request_nowarn(&fw, priv->dpfe_api->fw_name, dev); 610 + /* 611 + * Defer the firmware download if the firmware file couldn't be found. 612 + * The root file system may not be available yet. 613 + */ 644 614 if (ret) 645 - return ret; 615 + return (ret == -ENOENT) ? -EPROBE_DEFER : ret; 646 616 647 - ret = __verify_firmware(init, fw); 617 + ret = __verify_firmware(&init, fw); 648 618 if (ret) 649 619 return -EFAULT; 650 620 651 - __disable_dcpu(priv->regs); 621 + __disable_dcpu(priv); 652 622 653 - is_big_endian = init->is_big_endian; 654 - dmem_size = init->dmem_len; 655 - imem_size = init->imem_len; 623 + is_big_endian = init.is_big_endian; 624 + dmem_size = init.dmem_len; 625 + imem_size = init.imem_len; 656 626 657 627 /* At the beginning of the firmware blob is a header. */ 658 628 header = (struct dpfe_firmware_header *)fw->data; ··· 673 637 if (ret) 674 638 return ret; 675 639 676 - ret = __verify_fw_checksum(init, priv, header, init->chksum); 640 + ret = __verify_fw_checksum(&init, priv, header, init.chksum); 677 641 if (ret) 678 642 return ret; 679 643 680 - __enable_dcpu(priv->regs); 644 + __enable_dcpu(priv); 681 645 682 646 return 0; 683 647 } 684 648 685 649 static ssize_t generic_show(unsigned int command, u32 response[], 686 - struct private_data *priv, char *buf) 650 + struct brcmstb_dpfe_priv *priv, char *buf) 687 651 { 688 652 int ret; 689 653 ··· 701 665 char *buf) 702 666 { 703 667 u32 response[MSG_FIELD_MAX]; 704 - struct private_data *priv; 668 + struct brcmstb_dpfe_priv *priv; 705 669 unsigned int info; 706 670 ssize_t ret; 707 671 ··· 724 688 { 725 689 u32 response[MSG_FIELD_MAX]; 726 690 void __iomem *info; 727 - struct private_data *priv; 691 + struct brcmstb_dpfe_priv *priv; 728 692 u8 refresh, sr_abort, ppre, thermal_offs, tuf; 729 693 u32 mr4; 730 694 ssize_t ret; ··· 757 721 const char *buf, size_t count) 758 722 { 759 723 u32 response[MSG_FIELD_MAX]; 760 - struct private_data *priv; 724 + struct brcmstb_dpfe_priv *priv; 761 725 void __iomem *info; 762 726 unsigned long val; 763 727 int ret; ··· 783 747 char *buf) 784 748 { 785 749 u32 response[MSG_FIELD_MAX]; 786 - struct private_data *priv; 750 + struct brcmstb_dpfe_priv *priv; 787 751 void __iomem *info; 788 752 ssize_t ret; 789 753 u32 mr5, mr6, mr7, mr8, err; ··· 814 778 char *buf) 815 779 { 816 780 u32 response[MSG_FIELD_MAX]; 817 - struct private_data *priv; 781 + struct brcmstb_dpfe_priv *priv; 818 782 ssize_t ret; 819 783 u32 mr4, mr5, mr6, mr7, mr8, err; 820 784 ··· 836 800 837 801 static int brcmstb_dpfe_resume(struct platform_device *pdev) 838 802 { 839 - struct init_data init; 803 + struct brcmstb_dpfe_priv *priv = platform_get_drvdata(pdev); 840 804 841 - return brcmstb_dpfe_download_firmware(pdev, &init); 805 + return brcmstb_dpfe_download_firmware(priv); 842 806 } 843 807 844 808 static int brcmstb_dpfe_probe(struct platform_device *pdev) 845 809 { 846 810 struct device *dev = &pdev->dev; 847 - struct private_data *priv; 848 - struct init_data init; 811 + struct brcmstb_dpfe_priv *priv; 849 812 struct resource *res; 850 813 int ret; 851 814 852 815 priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); 853 816 if (!priv) 854 817 return -ENOMEM; 818 + 819 + priv->dev = dev; 855 820 856 821 mutex_init(&priv->lock); 857 822 platform_set_drvdata(pdev, priv); ··· 888 851 return -ENOENT; 889 852 } 890 853 891 - ret = brcmstb_dpfe_download_firmware(pdev, &init); 854 + ret = brcmstb_dpfe_download_firmware(priv); 892 855 if (ret) { 893 - dev_err(dev, "Couldn't download firmware -- %d\n", ret); 856 + if (ret != -EPROBE_DEFER) 857 + dev_err(dev, "Couldn't download firmware -- %d\n", ret); 894 858 return ret; 895 859 } 896 860 ··· 905 867 906 868 static int brcmstb_dpfe_remove(struct platform_device *pdev) 907 869 { 908 - struct private_data *priv = dev_get_drvdata(&pdev->dev); 870 + struct brcmstb_dpfe_priv *priv = dev_get_drvdata(&pdev->dev); 909 871 910 872 sysfs_remove_groups(&pdev->dev.kobj, priv->dpfe_api->sysfs_attrs); 911 873 ··· 914 876 915 877 static const struct of_device_id brcmstb_dpfe_of_match[] = { 916 878 /* Use legacy API v2 for a select number of chips */ 917 - { .compatible = "brcm,bcm7268-dpfe-cpu", .data = &dpfe_api_v2 }, 918 - { .compatible = "brcm,bcm7271-dpfe-cpu", .data = &dpfe_api_v2 }, 919 - { .compatible = "brcm,bcm7278-dpfe-cpu", .data = &dpfe_api_v2 }, 920 - { .compatible = "brcm,bcm7211-dpfe-cpu", .data = &dpfe_api_v2 }, 879 + { .compatible = "brcm,bcm7268-dpfe-cpu", .data = &dpfe_api_old_v2 }, 880 + { .compatible = "brcm,bcm7271-dpfe-cpu", .data = &dpfe_api_old_v2 }, 881 + { .compatible = "brcm,bcm7278-dpfe-cpu", .data = &dpfe_api_old_v2 }, 882 + { .compatible = "brcm,bcm7211-dpfe-cpu", .data = &dpfe_api_new_v2 }, 921 883 /* API v3 is the default going forward */ 922 884 { .compatible = "brcm,dpfe-cpu", .data = &dpfe_api_v3 }, 923 885 {}