Loading drivers/media/platform/msm/vidc/msm_vidc_platform.c +1 −1 Original line number Diff line number Diff line Loading @@ -153,7 +153,7 @@ static struct msm_vidc_common_data sdm855_common_data[] = { }, { .key = "qcom,power-collapse-delay", .value = 150000, .value = 1500, }, { .key = "qcom,hw-resp-timeout", Loading drivers/media/platform/msm/vidc/msm_vidc_res_parse.c +6 −0 Original line number Diff line number Diff line Loading @@ -29,6 +29,9 @@ enum clock_properties { #define PERF_GOV "performance" #define GCC_VIDEO_AXI_REG_START_ADDR 0x10B024 #define GCC_VIDEO_AXI_REG_SIZE 0xC static inline struct device *msm_iommu_get_ctx(const char *ctx_name) { return NULL; Loading Loading @@ -812,6 +815,9 @@ int read_platform_resources_from_dt( res->register_base = kres ? kres->start : -1; res->register_size = kres ? (kres->end + 1 - kres->start) : -1; res->gcc_register_base = GCC_VIDEO_AXI_REG_START_ADDR; res->gcc_register_size = GCC_VIDEO_AXI_REG_SIZE; kres = platform_get_resource(pdev, IORESOURCE_IRQ, 0); res->irq = kres ? kres->start : -1; Loading drivers/media/platform/msm/vidc/msm_vidc_resources.h +2 −0 Original line number Diff line number Diff line Loading @@ -146,7 +146,9 @@ struct subcache_set { struct msm_vidc_platform_resources { phys_addr_t firmware_base; phys_addr_t register_base; phys_addr_t gcc_register_base; uint32_t register_size; uint32_t gcc_register_size; uint32_t irq; uint32_t sku_version; struct allowed_clock_rates_table *allowed_clks_tbl; Loading drivers/media/platform/msm/vidc/venus_boot.c +16 −0 Original line number Diff line number Diff line Loading @@ -66,6 +66,7 @@ static struct { struct regulator *gdsc; const char *reg_name; void __iomem *reg_base; void __iomem *gcc_base; struct device *iommu_ctx_bank_dev; struct dma_iommu_mapping *mapping; dma_addr_t fw_iova; Loading Loading @@ -435,6 +436,8 @@ int venus_boot_init(struct msm_vidc_platform_resources *res, } venus_data->reg_base = ioremap_nocache(res->register_base, (unsigned long)res->register_size); dprintk(VIDC_DBG, "venus reg: base %x size %x\n", res->register_base, res->register_size); if (!venus_data->reg_base) { dprintk(VIDC_ERR, "could not map reg addr %pa of size %d\n", Loading @@ -442,6 +445,19 @@ int venus_boot_init(struct msm_vidc_platform_resources *res, rc = -ENOMEM; goto err_ioremap_fail; } venus_data->gcc_base = ioremap_nocache(res->gcc_register_base, (unsigned long)res->gcc_register_size); dprintk(VIDC_DBG, "gcc reg: base %x size %x\n", res->gcc_register_base, res->gcc_register_size); if (!venus_data->gcc_base) { dprintk(VIDC_ERR, "could not map reg addr %pa of size %d\n", &res->gcc_register_base, res->gcc_register_size); rc = -ENOMEM; goto err_ioremap_fail; } venus_data->venus_notif_hdle = subsys_notif_register_notifier("venus", &venus_notifier); if (IS_ERR(venus_data->venus_notif_hdle)) { Loading drivers/media/platform/msm/vidc/venus_hfi.c +138 −0 Original line number Diff line number Diff line Loading @@ -664,6 +664,33 @@ static void __write_register(struct venus_hfi_device *device, wmb(); } static void __write_gcc_register(struct venus_hfi_device *device, u32 reg, u32 value) { u32 hwiosymaddr = reg; u8 *base_addr; __strict_check(device); if (!device->power_enabled) { dprintk(VIDC_WARN, "HFI Write register failed : Power is OFF\n"); msm_vidc_res_handle_fatal_hw_error(device->res, true); return; } base_addr = device->hal_data->gcc_reg_base; dprintk(VIDC_DBG, "GCC Base addr: %pK, written to: %#x, Value: %#x.\n", base_addr, hwiosymaddr, value); base_addr += hwiosymaddr; writel_relaxed(value, base_addr); /* * Memory barrier to make sure value is written into the register. */ wmb(); } static int __read_register(struct venus_hfi_device *device, u32 reg) { int rc = 0; Loading Loading @@ -696,6 +723,33 @@ static int __read_register(struct venus_hfi_device *device, u32 reg) return rc; } static int __read_gcc_register(struct venus_hfi_device *device, u32 reg) { int rc = 0; u8 *base_addr; __strict_check(device); if (!device->power_enabled) { dprintk(VIDC_WARN, "HFI Read register failed : Power is OFF\n"); msm_vidc_res_handle_fatal_hw_error(device->res, true); return -EINVAL; } base_addr = device->hal_data->gcc_reg_base; rc = readl_relaxed(base_addr + reg); /* * Memory barrier to make sure value is read correctly from the * register. */ rmb(); dprintk(VIDC_DBG, "GCC Base addr: %pK, read from: %#x, value: %#x...\n", base_addr, reg, rc); return rc; } static void __set_registers(struct venus_hfi_device *device) { Loading Loading @@ -3389,6 +3443,16 @@ static int __init_regs_and_interrupts(struct venus_hfi_device *device, goto error_irq_fail; } hal->gcc_reg_base = devm_ioremap_nocache(&res->pdev->dev, res->gcc_register_base, res->gcc_register_size); hal->gcc_reg_size = res->gcc_register_size; if (!hal->gcc_reg_base) { dprintk(VIDC_ERR, "could not map gcc reg addr %pa of size %d\n", &res->gcc_register_base, res->gcc_register_size); goto error_irq_fail; } device->hal_data = hal; rc = request_irq(res->irq, venus_hfi_isr, IRQF_TRIGGER_HIGH, "msm_vidc", device); Loading @@ -3402,6 +3466,9 @@ static int __init_regs_and_interrupts(struct venus_hfi_device *device, "firmware_base = %pa, register_base = %pa, register_size = %d\n", &res->firmware_base, &res->register_base, res->register_size); dprintk(VIDC_INFO, "gcc_register_base = %pa, gcc_register_size = %d\n", &res->gcc_register_base, res->gcc_register_size); return rc; error_irq_fail: Loading Loading @@ -3490,6 +3557,70 @@ static inline void __disable_unprepare_clks(struct venus_hfi_device *device) } } static inline int __prepare_ahb2axi_bridge(struct venus_hfi_device *device) { u32 count = 0, axic_cbcr_status = 0, mvs_core_cbcr_status = 0; const u32 max_tries = 10; int rc = 0; if (!device) { dprintk(VIDC_ERR, "NULL device\n"); rc = -EINVAL; goto fail_ahb2axi_enable; } if (!device->hal_data->gcc_reg_base) { dprintk(VIDC_WARN, "Skip resetting ahb2axi bridge\n"); goto skip_reset_ahb2axi_bridge; } /* read registers */ axic_cbcr_status = __read_gcc_register(device, VIDEO_GCC_AXIC_CBCR); mvs_core_cbcr_status = __read_register(device, VIDEO_CC_MVSC_CORE_CBCR); /* write enable clk_ares */ __write_gcc_register(device, VIDEO_GCC_AXIC_CBCR, axic_cbcr_status|0x4); __write_register(device, VIDEO_CC_MVSC_CORE_CBCR, mvs_core_cbcr_status|0x4); /* wait for deassert */ usleep_range(150, 250); /* write disable clk_ares */ axic_cbcr_status = axic_cbcr_status & (~0x4); mvs_core_cbcr_status = mvs_core_cbcr_status & (~0x4); __write_gcc_register(device, VIDEO_GCC_AXIC_CBCR, axic_cbcr_status); __write_register(device, VIDEO_CC_MVSC_CORE_CBCR, mvs_core_cbcr_status); /* write enable clk */ axic_cbcr_status = __read_gcc_register(device, VIDEO_GCC_AXIC_CBCR); axic_cbcr_status = axic_cbcr_status | 0x1; __write_gcc_register(device, VIDEO_GCC_AXIC_CBCR, axic_cbcr_status); usleep_range(150, 250); while (count < max_tries) { axic_cbcr_status = __read_gcc_register(device, VIDEO_GCC_AXIC_CBCR); if (!(axic_cbcr_status & BIT(31))) break; usleep_range(150, 250); count++; } if (count == max_tries) { dprintk(VIDC_ERR, "Unable to enable gcc_axic_cbcr (%#x)\n", axic_cbcr_status); rc = -EINVAL; goto fail_ahb2axi_enable; } fail_ahb2axi_enable: skip_reset_ahb2axi_bridge: return rc; } static inline int __prepare_enable_clks(struct venus_hfi_device *device) { struct clock_info *cl = NULL, *cl_fail = NULL; Loading Loading @@ -4130,6 +4261,12 @@ static int __venus_power_on(struct venus_hfi_device *device) goto fail_enable_gdsc; } rc = __prepare_ahb2axi_bridge(device); if (rc) { dprintk(VIDC_ERR, "Failed to enable ahb2axi: %d\n", rc); goto fail_enable_clks; } rc = __prepare_enable_clks(device); if (rc) { dprintk(VIDC_ERR, "Failed to enable clocks: %d\n", rc); Loading Loading @@ -4668,6 +4805,7 @@ void venus_hfi_delete_device(void *device) destroy_workqueue(close->venus_pm_workq); free_irq(dev->hal_data->irq, close); iounmap(dev->hal_data->register_base); iounmap(dev->hal_data->gcc_reg_base); kfree(close->hal_data); kfree(close->response_pkt); kfree(close->raw_packet); Loading Loading
drivers/media/platform/msm/vidc/msm_vidc_platform.c +1 −1 Original line number Diff line number Diff line Loading @@ -153,7 +153,7 @@ static struct msm_vidc_common_data sdm855_common_data[] = { }, { .key = "qcom,power-collapse-delay", .value = 150000, .value = 1500, }, { .key = "qcom,hw-resp-timeout", Loading
drivers/media/platform/msm/vidc/msm_vidc_res_parse.c +6 −0 Original line number Diff line number Diff line Loading @@ -29,6 +29,9 @@ enum clock_properties { #define PERF_GOV "performance" #define GCC_VIDEO_AXI_REG_START_ADDR 0x10B024 #define GCC_VIDEO_AXI_REG_SIZE 0xC static inline struct device *msm_iommu_get_ctx(const char *ctx_name) { return NULL; Loading Loading @@ -812,6 +815,9 @@ int read_platform_resources_from_dt( res->register_base = kres ? kres->start : -1; res->register_size = kres ? (kres->end + 1 - kres->start) : -1; res->gcc_register_base = GCC_VIDEO_AXI_REG_START_ADDR; res->gcc_register_size = GCC_VIDEO_AXI_REG_SIZE; kres = platform_get_resource(pdev, IORESOURCE_IRQ, 0); res->irq = kres ? kres->start : -1; Loading
drivers/media/platform/msm/vidc/msm_vidc_resources.h +2 −0 Original line number Diff line number Diff line Loading @@ -146,7 +146,9 @@ struct subcache_set { struct msm_vidc_platform_resources { phys_addr_t firmware_base; phys_addr_t register_base; phys_addr_t gcc_register_base; uint32_t register_size; uint32_t gcc_register_size; uint32_t irq; uint32_t sku_version; struct allowed_clock_rates_table *allowed_clks_tbl; Loading
drivers/media/platform/msm/vidc/venus_boot.c +16 −0 Original line number Diff line number Diff line Loading @@ -66,6 +66,7 @@ static struct { struct regulator *gdsc; const char *reg_name; void __iomem *reg_base; void __iomem *gcc_base; struct device *iommu_ctx_bank_dev; struct dma_iommu_mapping *mapping; dma_addr_t fw_iova; Loading Loading @@ -435,6 +436,8 @@ int venus_boot_init(struct msm_vidc_platform_resources *res, } venus_data->reg_base = ioremap_nocache(res->register_base, (unsigned long)res->register_size); dprintk(VIDC_DBG, "venus reg: base %x size %x\n", res->register_base, res->register_size); if (!venus_data->reg_base) { dprintk(VIDC_ERR, "could not map reg addr %pa of size %d\n", Loading @@ -442,6 +445,19 @@ int venus_boot_init(struct msm_vidc_platform_resources *res, rc = -ENOMEM; goto err_ioremap_fail; } venus_data->gcc_base = ioremap_nocache(res->gcc_register_base, (unsigned long)res->gcc_register_size); dprintk(VIDC_DBG, "gcc reg: base %x size %x\n", res->gcc_register_base, res->gcc_register_size); if (!venus_data->gcc_base) { dprintk(VIDC_ERR, "could not map reg addr %pa of size %d\n", &res->gcc_register_base, res->gcc_register_size); rc = -ENOMEM; goto err_ioremap_fail; } venus_data->venus_notif_hdle = subsys_notif_register_notifier("venus", &venus_notifier); if (IS_ERR(venus_data->venus_notif_hdle)) { Loading
drivers/media/platform/msm/vidc/venus_hfi.c +138 −0 Original line number Diff line number Diff line Loading @@ -664,6 +664,33 @@ static void __write_register(struct venus_hfi_device *device, wmb(); } static void __write_gcc_register(struct venus_hfi_device *device, u32 reg, u32 value) { u32 hwiosymaddr = reg; u8 *base_addr; __strict_check(device); if (!device->power_enabled) { dprintk(VIDC_WARN, "HFI Write register failed : Power is OFF\n"); msm_vidc_res_handle_fatal_hw_error(device->res, true); return; } base_addr = device->hal_data->gcc_reg_base; dprintk(VIDC_DBG, "GCC Base addr: %pK, written to: %#x, Value: %#x.\n", base_addr, hwiosymaddr, value); base_addr += hwiosymaddr; writel_relaxed(value, base_addr); /* * Memory barrier to make sure value is written into the register. */ wmb(); } static int __read_register(struct venus_hfi_device *device, u32 reg) { int rc = 0; Loading Loading @@ -696,6 +723,33 @@ static int __read_register(struct venus_hfi_device *device, u32 reg) return rc; } static int __read_gcc_register(struct venus_hfi_device *device, u32 reg) { int rc = 0; u8 *base_addr; __strict_check(device); if (!device->power_enabled) { dprintk(VIDC_WARN, "HFI Read register failed : Power is OFF\n"); msm_vidc_res_handle_fatal_hw_error(device->res, true); return -EINVAL; } base_addr = device->hal_data->gcc_reg_base; rc = readl_relaxed(base_addr + reg); /* * Memory barrier to make sure value is read correctly from the * register. */ rmb(); dprintk(VIDC_DBG, "GCC Base addr: %pK, read from: %#x, value: %#x...\n", base_addr, reg, rc); return rc; } static void __set_registers(struct venus_hfi_device *device) { Loading Loading @@ -3389,6 +3443,16 @@ static int __init_regs_and_interrupts(struct venus_hfi_device *device, goto error_irq_fail; } hal->gcc_reg_base = devm_ioremap_nocache(&res->pdev->dev, res->gcc_register_base, res->gcc_register_size); hal->gcc_reg_size = res->gcc_register_size; if (!hal->gcc_reg_base) { dprintk(VIDC_ERR, "could not map gcc reg addr %pa of size %d\n", &res->gcc_register_base, res->gcc_register_size); goto error_irq_fail; } device->hal_data = hal; rc = request_irq(res->irq, venus_hfi_isr, IRQF_TRIGGER_HIGH, "msm_vidc", device); Loading @@ -3402,6 +3466,9 @@ static int __init_regs_and_interrupts(struct venus_hfi_device *device, "firmware_base = %pa, register_base = %pa, register_size = %d\n", &res->firmware_base, &res->register_base, res->register_size); dprintk(VIDC_INFO, "gcc_register_base = %pa, gcc_register_size = %d\n", &res->gcc_register_base, res->gcc_register_size); return rc; error_irq_fail: Loading Loading @@ -3490,6 +3557,70 @@ static inline void __disable_unprepare_clks(struct venus_hfi_device *device) } } static inline int __prepare_ahb2axi_bridge(struct venus_hfi_device *device) { u32 count = 0, axic_cbcr_status = 0, mvs_core_cbcr_status = 0; const u32 max_tries = 10; int rc = 0; if (!device) { dprintk(VIDC_ERR, "NULL device\n"); rc = -EINVAL; goto fail_ahb2axi_enable; } if (!device->hal_data->gcc_reg_base) { dprintk(VIDC_WARN, "Skip resetting ahb2axi bridge\n"); goto skip_reset_ahb2axi_bridge; } /* read registers */ axic_cbcr_status = __read_gcc_register(device, VIDEO_GCC_AXIC_CBCR); mvs_core_cbcr_status = __read_register(device, VIDEO_CC_MVSC_CORE_CBCR); /* write enable clk_ares */ __write_gcc_register(device, VIDEO_GCC_AXIC_CBCR, axic_cbcr_status|0x4); __write_register(device, VIDEO_CC_MVSC_CORE_CBCR, mvs_core_cbcr_status|0x4); /* wait for deassert */ usleep_range(150, 250); /* write disable clk_ares */ axic_cbcr_status = axic_cbcr_status & (~0x4); mvs_core_cbcr_status = mvs_core_cbcr_status & (~0x4); __write_gcc_register(device, VIDEO_GCC_AXIC_CBCR, axic_cbcr_status); __write_register(device, VIDEO_CC_MVSC_CORE_CBCR, mvs_core_cbcr_status); /* write enable clk */ axic_cbcr_status = __read_gcc_register(device, VIDEO_GCC_AXIC_CBCR); axic_cbcr_status = axic_cbcr_status | 0x1; __write_gcc_register(device, VIDEO_GCC_AXIC_CBCR, axic_cbcr_status); usleep_range(150, 250); while (count < max_tries) { axic_cbcr_status = __read_gcc_register(device, VIDEO_GCC_AXIC_CBCR); if (!(axic_cbcr_status & BIT(31))) break; usleep_range(150, 250); count++; } if (count == max_tries) { dprintk(VIDC_ERR, "Unable to enable gcc_axic_cbcr (%#x)\n", axic_cbcr_status); rc = -EINVAL; goto fail_ahb2axi_enable; } fail_ahb2axi_enable: skip_reset_ahb2axi_bridge: return rc; } static inline int __prepare_enable_clks(struct venus_hfi_device *device) { struct clock_info *cl = NULL, *cl_fail = NULL; Loading Loading @@ -4130,6 +4261,12 @@ static int __venus_power_on(struct venus_hfi_device *device) goto fail_enable_gdsc; } rc = __prepare_ahb2axi_bridge(device); if (rc) { dprintk(VIDC_ERR, "Failed to enable ahb2axi: %d\n", rc); goto fail_enable_clks; } rc = __prepare_enable_clks(device); if (rc) { dprintk(VIDC_ERR, "Failed to enable clocks: %d\n", rc); Loading Loading @@ -4668,6 +4805,7 @@ void venus_hfi_delete_device(void *device) destroy_workqueue(close->venus_pm_workq); free_irq(dev->hal_data->irq, close); iounmap(dev->hal_data->register_base); iounmap(dev->hal_data->gcc_reg_base); kfree(close->hal_data); kfree(close->response_pkt); kfree(close->raw_packet); Loading