Lines Matching +full:dpfe +full:- +full:imem
1 // SPDX-License-Identifier: GPL-2.0-only
3 * DDR PHY Front End (DPFE) driver for Broadcom set top box SoCs
9 * This driver provides access to the DPFE interface of Broadcom STB SoCs.
21 * - LE kernel + LE firmware image (the most common case)
22 * - LE kernel + BE firmware image
23 * - BE kernel + LE firmware image
24 * - BE kernel + BE firmware image
39 #define DRVNAME "brcmstb-dpfe"
49 #define DRAM_MSG_ADDR_MASK ((1UL << DRAM_MSG_TYPE_OFFSET) - 1)
51 (BITS_PER_LONG - DRAM_MSG_TYPE_OFFSET)) - 1)
67 #define DRAM_MR4_PPRE 0x4 /* Post-package repair entry/exit */
115 #define ERR_INVALID_MAGIC -1
116 #define ERR_INVALID_SIZE -2
117 #define ERR_INVALID_CHKSUM -3
151 * 3 IMEM byte size
153 * IMEM
185 void __iomem *imem; member
236 .fw_name = "dpfe.bin",
314 i = ARRAY_SIZE(error_text) - 1; in get_error_text()
323 mutex_lock(&priv->lock); in is_dcpu_enabled()
324 val = readl_relaxed(priv->regs + REG_DCPU_RESET); in is_dcpu_enabled()
325 mutex_unlock(&priv->lock); in is_dcpu_enabled()
337 mutex_lock(&priv->lock); in __disable_dcpu()
340 val = readl_relaxed(priv->regs + REG_DCPU_RESET); in __disable_dcpu()
342 writel_relaxed(val, priv->regs + REG_DCPU_RESET); in __disable_dcpu()
344 mutex_unlock(&priv->lock); in __disable_dcpu()
349 void __iomem *regs = priv->regs; in __enable_dcpu()
352 mutex_lock(&priv->lock); in __enable_dcpu()
368 mutex_unlock(&priv->lock); in __enable_dcpu()
391 if (unlikely(priv->dpfe_api->version >= 3)) in get_msg_ptr()
405 ptr = priv->regs + DCPU_MSG_RAM_START + offset; in get_msg_ptr()
408 ptr = priv->dmem + offset; in get_msg_ptr()
411 dev_emerg(priv->dev, "invalid message reply from DCPU: %#x\n", in get_msg_ptr()
429 release_mbox = (priv->dpfe_api->version < 2) in __finalize_command()
431 writel_relaxed(0, priv->regs + release_mbox); in __finalize_command()
437 const u32 *msg = priv->dpfe_api->command[cmd]; in __send_command()
438 void __iomem *regs = priv->regs; in __send_command()
444 return -1; in __send_command()
446 mutex_lock(&priv->lock); in __send_command()
456 mutex_unlock(&priv->lock); in __send_command()
457 return -ffs(DCPU_RET_ERR_TIMEDOUT); in __send_command()
486 ret = -ffs(resp); in __send_command()
497 mutex_unlock(&priv->lock); in __send_command()
509 ret = -ffs(resp); in __send_command()
519 const struct dpfe_firmware_header *header = (void *)fw->data; in __verify_firmware()
524 if (header->magic == DPFE_BE_MAGIC) in __verify_firmware()
526 else if (header->magic != DPFE_LE_MAGIC) in __verify_firmware()
530 dmem_size = be32_to_cpu(header->dmem_size); in __verify_firmware()
531 imem_size = be32_to_cpu(header->imem_size); in __verify_firmware()
533 dmem_size = le32_to_cpu(header->dmem_size); in __verify_firmware()
534 imem_size = le32_to_cpu(header->imem_size); in __verify_firmware()
547 if (total_size != fw->size) in __verify_firmware()
551 chksum_ptr = (void *)fw->data + sizeof(*header) + dmem_size + imem_size; in __verify_firmware()
553 init->is_big_endian = is_big_endian; in __verify_firmware()
554 init->dmem_len = dmem_size; in __verify_firmware()
555 init->imem_len = imem_size; in __verify_firmware()
556 init->chksum = (is_big_endian) in __verify_firmware()
562 /* Verify checksum by reading back the firmware from co-processor RAM. */
569 u32 __iomem *dmem = priv->dmem; in __verify_fw_checksum()
570 u32 __iomem *imem = priv->imem; in __verify_fw_checksum() local
573 if (init->is_big_endian) { in __verify_fw_checksum()
574 magic = be32_to_cpu(header->magic); in __verify_fw_checksum()
575 sequence = be32_to_cpu(header->sequence); in __verify_fw_checksum()
576 version = be32_to_cpu(header->version); in __verify_fw_checksum()
578 magic = le32_to_cpu(header->magic); in __verify_fw_checksum()
579 sequence = le32_to_cpu(header->sequence); in __verify_fw_checksum()
580 version = le32_to_cpu(header->version); in __verify_fw_checksum()
583 sum = magic + sequence + version + init->dmem_len + init->imem_len; in __verify_fw_checksum()
585 for (i = 0; i < init->dmem_len / sizeof(u32); i++) in __verify_fw_checksum()
588 for (i = 0; i < init->imem_len / sizeof(u32); i++) in __verify_fw_checksum()
589 sum += readl_relaxed(imem + i); in __verify_fw_checksum()
591 return (sum == checksum) ? 0 : -1; in __verify_fw_checksum()
599 /* Convert size to 32-bit words. */ in __write_firmware()
622 struct device *dev = priv->dev; in brcmstb_dpfe_download_firmware()
625 const u32 *dmem, *imem; in brcmstb_dpfe_download_firmware() local
647 if (!priv->dpfe_api->fw_name) in brcmstb_dpfe_download_firmware()
648 return -ENODEV; in brcmstb_dpfe_download_firmware()
650 ret = firmware_request_nowarn(&fw, priv->dpfe_api->fw_name, dev); in brcmstb_dpfe_download_firmware()
656 return (ret == -ENOENT) ? -EPROBE_DEFER : ret; in brcmstb_dpfe_download_firmware()
660 ret = -EFAULT; in brcmstb_dpfe_download_firmware()
671 header = (struct dpfe_firmware_header *)fw->data; in brcmstb_dpfe_download_firmware()
673 fw_blob = fw->data + sizeof(*header); in brcmstb_dpfe_download_firmware()
674 /* IMEM comes right after the header. */ in brcmstb_dpfe_download_firmware()
675 imem = fw_blob; in brcmstb_dpfe_download_firmware()
676 /* DMEM follows after IMEM. */ in brcmstb_dpfe_download_firmware()
679 ret = __write_firmware(priv->dmem, dmem, dmem_size, is_big_endian); in brcmstb_dpfe_download_firmware()
682 ret = __write_firmware(priv->imem, imem, imem_size, is_big_endian); in brcmstb_dpfe_download_firmware()
707 return sprintf(buf, "ERROR: %s\n", get_error_text(-ret)); in generic_show()
778 return -EINVAL; in store_refresh()
787 return -EIO; in store_refresh()
858 struct device *dev = &pdev->dev; in brcmstb_dpfe_probe()
864 return -ENOMEM; in brcmstb_dpfe_probe()
866 priv->dev = dev; in brcmstb_dpfe_probe()
868 mutex_init(&priv->lock); in brcmstb_dpfe_probe()
871 priv->regs = devm_platform_ioremap_resource_byname(pdev, "dpfe-cpu"); in brcmstb_dpfe_probe()
872 if (IS_ERR(priv->regs)) { in brcmstb_dpfe_probe()
874 return -ENODEV; in brcmstb_dpfe_probe()
877 priv->dmem = devm_platform_ioremap_resource_byname(pdev, "dpfe-dmem"); in brcmstb_dpfe_probe()
878 if (IS_ERR(priv->dmem)) { in brcmstb_dpfe_probe()
880 return -ENOENT; in brcmstb_dpfe_probe()
883 priv->imem = devm_platform_ioremap_resource_byname(pdev, "dpfe-imem"); in brcmstb_dpfe_probe()
884 if (IS_ERR(priv->imem)) { in brcmstb_dpfe_probe()
886 return -ENOENT; in brcmstb_dpfe_probe()
889 priv->dpfe_api = of_device_get_match_data(dev); in brcmstb_dpfe_probe()
890 if (unlikely(!priv->dpfe_api)) { in brcmstb_dpfe_probe()
896 return -ENOENT; in brcmstb_dpfe_probe()
903 ret = sysfs_create_groups(&pdev->dev.kobj, priv->dpfe_api->sysfs_attrs); in brcmstb_dpfe_probe()
906 priv->dpfe_api->version); in brcmstb_dpfe_probe()
913 struct brcmstb_dpfe_priv *priv = dev_get_drvdata(&pdev->dev); in brcmstb_dpfe_remove()
915 sysfs_remove_groups(&pdev->dev.kobj, priv->dpfe_api->sysfs_attrs); in brcmstb_dpfe_remove()
922 { .compatible = "brcm,bcm7268-dpfe-cpu", .data = &dpfe_api_old_v2 },
923 { .compatible = "brcm,bcm7271-dpfe-cpu", .data = &dpfe_api_old_v2 },
924 { .compatible = "brcm,bcm7278-dpfe-cpu", .data = &dpfe_api_old_v2 },
925 { .compatible = "brcm,bcm7211-dpfe-cpu", .data = &dpfe_api_new_v2 },
927 { .compatible = "brcm,dpfe-cpu", .data = &dpfe_api_v3 },