diff --git a/arch/arm/configs/rv1106-recovery.config b/arch/arm/configs/rv1106-recovery.config index a49e5b0c05de..73ccfebabee2 100644 --- a/arch/arm/configs/rv1106-recovery.config +++ b/arch/arm/configs/rv1106-recovery.config @@ -175,6 +175,7 @@ CONFIG_CRYPTO_MANAGER_DISABLE_TESTS=y # CONFIG_CRYPTO_XTS is not set # CONFIG_CRYPTO_XXHASH is not set # CONFIG_CRYPTO_ZSTD is not set +CONFIG_DECOMPRESS_GZIP=y # CONFIG_EEPROM_93XX46 is not set # CONFIG_EEPROM_AT25 is not set # CONFIG_EXT4_DEBUG is not set @@ -290,7 +291,7 @@ CONFIG_MTD_UBI_WL_THRESHOLD=4096 CONFIG_PWRSEQ_EMMC=y CONFIG_PWRSEQ_SIMPLE=y # CONFIG_RD_BZIP2 is not set -# CONFIG_RD_GZIP is not set +CONFIG_RD_GZIP=y # CONFIG_RD_LZ4 is not set # CONFIG_RD_LZMA is not set # CONFIG_RD_LZO is not set diff --git a/drivers/clk/rockchip/clk-rv1106.c b/drivers/clk/rockchip/clk-rv1106.c index 0833bf2adb8b..f61cbbf2e81d 100644 --- a/drivers/clk/rockchip/clk-rv1106.c +++ b/drivers/clk/rockchip/clk-rv1106.c @@ -1135,7 +1135,7 @@ static void rockchip_rv1106_pvtpll_init(struct rockchip_clk_provider *ctx) writel_relaxed(0xffff0004, ctx->reg_base + CRU_PVTPLL1_CON2_H); writel_relaxed(0x00030003, ctx->reg_base + CRU_PVTPLL1_CON0_L); - schedule_delayed_work(&pvtpll_calibrate_work, msecs_to_jiffies(3000)); + queue_delayed_work(system_freezable_wq, &pvtpll_calibrate_work, msecs_to_jiffies(300)); } static int rv1106_clk_panic(struct notifier_block *this, diff --git a/drivers/rknpu/include/rknpu_drv.h b/drivers/rknpu/include/rknpu_drv.h index 98fba97c4af2..0e7ad2d7ddb0 100644 --- a/drivers/rknpu/include/rknpu_drv.h +++ b/drivers/rknpu/include/rknpu_drv.h @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -28,10 +29,10 @@ #define DRIVER_NAME "rknpu" #define DRIVER_DESC "RKNPU driver" -#define DRIVER_DATE "20231121" +#define DRIVER_DATE "20240129" #define DRIVER_MAJOR 0 #define DRIVER_MINOR 9 -#define DRIVER_PATCHLEVEL 3 +#define DRIVER_PATCHLEVEL 4 #define LOG_TAG "RKNPU" @@ -52,11 +53,23 @@ #define LOG_DEV_DEBUG(dev, fmt, args...) dev_dbg(dev, LOG_TAG ": " fmt, ##args) #define LOG_DEV_ERROR(dev, fmt, args...) dev_err(dev, LOG_TAG ": " fmt, ##args) +struct rknpu_irqs_data { + const char *name; + irqreturn_t (*irq_hdl)(int irq, void *ctx); +}; + struct rknpu_reset_data { const char *srst_a_name; const char *srst_h_name; }; +struct rknpu_amount_data { + uint16_t offset_clr_all; + uint16_t offset_dt_wr; + uint16_t offset_dt_rd; + uint16_t offset_wt_rd; +}; + struct rknpu_config { __u32 bw_priority_addr; __u32 bw_priority_length; @@ -66,7 +79,6 @@ struct rknpu_config { __u32 pc_task_number_mask; __u32 pc_task_status_offset; __u32 pc_dma_ctrl; - __u32 bw_enable; const struct rknpu_irqs_data *irqs; const struct rknpu_reset_data *resets; int num_irqs; @@ -75,6 +87,8 @@ struct rknpu_config { __u64 nbuf_size; __u64 max_submit_number; __u32 core_mask; + const struct rknpu_amount_data *amount_top; + const struct rknpu_amount_data *amount_core; }; struct rknpu_timer { diff --git a/drivers/rknpu/include/rknpu_ioctl.h b/drivers/rknpu/include/rknpu_ioctl.h index 35b46701c789..803caf0c9247 100644 --- a/drivers/rknpu/include/rknpu_ioctl.h +++ b/drivers/rknpu/include/rknpu_ioctl.h @@ -31,11 +31,6 @@ #define RKNPU_OFFSET_INT_STATUS 0x28 #define RKNPU_OFFSET_INT_RAW_STATUS 0x2c -#define RKNPU_OFFSET_CLR_ALL_RW_AMOUNT 0x8010 -#define RKNPU_OFFSET_DT_WR_AMOUNT 0x8034 -#define RKNPU_OFFSET_DT_RD_AMOUNT 0x8038 -#define RKNPU_OFFSET_WT_RD_AMOUNT 0x803c - #define RKNPU_OFFSET_ENABLE_MASK 0xf008 #define RKNPU_INT_CLEAR 0x1ffff diff --git a/drivers/rknpu/rknpu_drv.c b/drivers/rknpu/rknpu_drv.c index 1df364f28316..c5c41fef5678 100644 --- a/drivers/rknpu/rknpu_drv.c +++ b/drivers/rknpu/rknpu_drv.c @@ -8,7 +8,6 @@ #include #include #include -#include #include #include #include @@ -72,11 +71,6 @@ module_param(bypass_soft_reset, int, 0644); MODULE_PARM_DESC(bypass_soft_reset, "bypass RKNPU soft reset if set it to 1, disabled by default"); -struct rknpu_irqs_data { - const char *name; - irqreturn_t (*irq_hdl)(int irq, void *ctx); -}; - static const struct rknpu_irqs_data rknpu_irqs[] = { { "npu_irq", rknpu_core0_irq_handler } }; @@ -96,6 +90,27 @@ static const struct rknpu_reset_data rk3588_npu_resets[] = { { "srst_a2", "srst_h2" } }; +static const struct rknpu_amount_data rknpu_old_top_amount = { + .offset_clr_all = 0x8010, + .offset_dt_wr = 0x8034, + .offset_dt_rd = 0x8038, + .offset_wt_rd = 0x803c, +}; + +static const struct rknpu_amount_data rknpu_top_amount = { + .offset_clr_all = 0x2210, + .offset_dt_wr = 0x2234, + .offset_dt_rd = 0x2238, + .offset_wt_rd = 0x223c +}; + +static const struct rknpu_amount_data rknpu_core_amount = { + .offset_clr_all = 0x2410, + .offset_dt_wr = 0x2434, + .offset_dt_rd = 0x2438, + .offset_wt_rd = 0x243c, +}; + static const struct rknpu_config rk356x_rknpu_config = { .bw_priority_addr = 0xfe180008, .bw_priority_length = 0x10, @@ -105,7 +120,6 @@ static const struct rknpu_config rk356x_rknpu_config = { .pc_task_number_mask = 0xfff, .pc_task_status_offset = 0x3c, .pc_dma_ctrl = 0, - .bw_enable = 1, .irqs = rknpu_irqs, .resets = rknpu_resets, .num_irqs = ARRAY_SIZE(rknpu_irqs), @@ -114,6 +128,8 @@ static const struct rknpu_config rk356x_rknpu_config = { .nbuf_size = 0, .max_submit_number = (1 << 12) - 1, .core_mask = 0x1, + .amount_top = &rknpu_old_top_amount, + .amount_core = NULL, }; static const struct rknpu_config rk3588_rknpu_config = { @@ -125,7 +141,6 @@ static const struct rknpu_config rk3588_rknpu_config = { .pc_task_number_mask = 0xfff, .pc_task_status_offset = 0x3c, .pc_dma_ctrl = 0, - .bw_enable = 0, .irqs = rk3588_npu_irqs, .resets = rk3588_npu_resets, .num_irqs = ARRAY_SIZE(rk3588_npu_irqs), @@ -134,6 +149,8 @@ static const struct rknpu_config rk3588_rknpu_config = { .nbuf_size = 0, .max_submit_number = (1 << 12) - 1, .core_mask = 0x7, + .amount_top = NULL, + .amount_core = NULL, }; static const struct rknpu_config rk3583_rknpu_config = { @@ -145,7 +162,6 @@ static const struct rknpu_config rk3583_rknpu_config = { .pc_task_number_mask = 0xfff, .pc_task_status_offset = 0x3c, .pc_dma_ctrl = 0, - .bw_enable = 0, .irqs = rk3588_npu_irqs, .resets = rk3588_npu_resets, .num_irqs = 2, @@ -154,6 +170,8 @@ static const struct rknpu_config rk3583_rknpu_config = { .nbuf_size = 0, .max_submit_number = (1 << 12) - 1, .core_mask = 0x3, + .amount_top = NULL, + .amount_core = NULL, }; static const struct rknpu_config rv1106_rknpu_config = { @@ -165,7 +183,6 @@ static const struct rknpu_config rv1106_rknpu_config = { .pc_task_number_mask = 0xffff, .pc_task_status_offset = 0x3c, .pc_dma_ctrl = 0, - .bw_enable = 1, .irqs = rknpu_irqs, .resets = rknpu_resets, .num_irqs = ARRAY_SIZE(rknpu_irqs), @@ -174,6 +191,8 @@ static const struct rknpu_config rv1106_rknpu_config = { .nbuf_size = 0, .max_submit_number = (1 << 16) - 1, .core_mask = 0x1, + .amount_top = &rknpu_old_top_amount, + .amount_core = NULL, }; static const struct rknpu_config rk3562_rknpu_config = { @@ -185,7 +204,6 @@ static const struct rknpu_config rk3562_rknpu_config = { .pc_task_number_mask = 0xffff, .pc_task_status_offset = 0x48, .pc_dma_ctrl = 1, - .bw_enable = 1, .irqs = rknpu_irqs, .resets = rknpu_resets, .num_irqs = ARRAY_SIZE(rknpu_irqs), @@ -194,6 +212,8 @@ static const struct rknpu_config rk3562_rknpu_config = { .nbuf_size = 256 * 1024, .max_submit_number = (1 << 16) - 1, .core_mask = 0x1, + .amount_top = &rknpu_old_top_amount, + .amount_core = NULL, }; /* driver probe and init */ @@ -952,9 +972,12 @@ static int rknpu_register_irq(struct platform_device *pdev, { const struct rknpu_config *config = rknpu_dev->config; struct device *dev = &pdev->dev; +#if KERNEL_VERSION(6, 1, 0) > LINUX_VERSION_CODE struct resource *res; +#endif int i, ret, irq; +#if KERNEL_VERSION(6, 1, 0) > LINUX_VERSION_CODE res = platform_get_resource_byname(pdev, IORESOURCE_IRQ, config->irqs[0].name); if (res) { @@ -993,6 +1016,28 @@ static int rknpu_register_irq(struct platform_device *pdev, return ret; } } +#else + /* there are irq names in dts */ + for (i = 0; i < config->num_irqs; i++) { + irq = platform_get_irq_byname(pdev, config->irqs[i].name); + if (irq < 0) { + irq = platform_get_irq(pdev, i); + if (irq < 0) { + LOG_DEV_ERROR(dev, "no npu %s in dts\n", + config->irqs[i].name); + return irq; + } + } + + ret = devm_request_irq(dev, irq, config->irqs[i].irq_hdl, + IRQF_SHARED, dev_name(dev), rknpu_dev); + if (ret < 0) { + LOG_DEV_ERROR(dev, "request %s failed: %d\n", + config->irqs[i].name, ret); + return ret; + } + } +#endif return 0; } diff --git a/drivers/rknpu/rknpu_gem.c b/drivers/rknpu/rknpu_gem.c index 6f790a6368f3..60ad44804a5e 100644 --- a/drivers/rknpu/rknpu_gem.c +++ b/drivers/rknpu/rknpu_gem.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #if KERNEL_VERSION(5, 10, 0) <= LINUX_VERSION_CODE @@ -1336,7 +1337,7 @@ int rknpu_gem_prime_vmap(struct drm_gem_object *obj, struct iosys_map *map) return -EINVAL; vaddr = vmap(rknpu_obj->pages, rknpu_obj->num_pages, VM_MAP, - PAGE_KERNEL); + PAGE_KERNEL); if (!vaddr) return -ENOMEM; diff --git a/drivers/rknpu/rknpu_job.c b/drivers/rknpu/rknpu_job.c index 6dc94b59b3dd..fadd8e3b2413 100644 --- a/drivers/rknpu/rknpu_job.c +++ b/drivers/rknpu/rknpu_job.c @@ -885,11 +885,6 @@ int rknpu_get_bw_priority(struct rknpu_device *rknpu_dev, uint32_t *priority, { void __iomem *base = rknpu_dev->bw_priority_base; - if (!rknpu_dev->config->bw_enable) { - LOG_WARN("Get bw_priority is not supported on this device!\n"); - return 0; - } - if (!base) return -EINVAL; @@ -914,11 +909,6 @@ int rknpu_set_bw_priority(struct rknpu_device *rknpu_dev, uint32_t priority, { void __iomem *base = rknpu_dev->bw_priority_base; - if (!rknpu_dev->config->bw_enable) { - LOG_WARN("Set bw_priority is not supported on this device!\n"); - return 0; - } - if (!base) return -EINVAL; @@ -941,28 +931,41 @@ int rknpu_set_bw_priority(struct rknpu_device *rknpu_dev, uint32_t priority, int rknpu_clear_rw_amount(struct rknpu_device *rknpu_dev) { void __iomem *rknpu_core_base = rknpu_dev->base[0]; + const struct rknpu_config *config = rknpu_dev->config; unsigned long flags; - if (!rknpu_dev->config->bw_enable) { + if (config->amount_top == NULL) { LOG_WARN("Clear rw_amount is not supported on this device!\n"); return 0; } - if (rknpu_dev->config->pc_dma_ctrl) { + if (config->pc_dma_ctrl) { uint32_t pc_data_addr = 0; spin_lock_irqsave(&rknpu_dev->irq_lock, flags); pc_data_addr = REG_READ(RKNPU_OFFSET_PC_DATA_ADDR); REG_WRITE(0x1, RKNPU_OFFSET_PC_DATA_ADDR); - REG_WRITE(0x80000101, RKNPU_OFFSET_CLR_ALL_RW_AMOUNT); - REG_WRITE(0x00000101, RKNPU_OFFSET_CLR_ALL_RW_AMOUNT); + REG_WRITE(0x80000101, config->amount_top->offset_clr_all); + REG_WRITE(0x00000101, config->amount_top->offset_clr_all); + if (config->amount_core) { + REG_WRITE(0x80000101, + config->amount_core->offset_clr_all); + REG_WRITE(0x00000101, + config->amount_core->offset_clr_all); + } REG_WRITE(pc_data_addr, RKNPU_OFFSET_PC_DATA_ADDR); spin_unlock_irqrestore(&rknpu_dev->irq_lock, flags); } else { spin_lock(&rknpu_dev->lock); - REG_WRITE(0x80000101, RKNPU_OFFSET_CLR_ALL_RW_AMOUNT); - REG_WRITE(0x00000101, RKNPU_OFFSET_CLR_ALL_RW_AMOUNT); + REG_WRITE(0x80000101, config->amount_top->offset_clr_all); + REG_WRITE(0x00000101, config->amount_top->offset_clr_all); + if (config->amount_core) { + REG_WRITE(0x80000101, + config->amount_core->offset_clr_all); + REG_WRITE(0x00000101, + config->amount_core->offset_clr_all); + } spin_unlock(&rknpu_dev->lock); } @@ -973,23 +976,42 @@ int rknpu_get_rw_amount(struct rknpu_device *rknpu_dev, uint32_t *dt_wr, uint32_t *dt_rd, uint32_t *wd_rd) { void __iomem *rknpu_core_base = rknpu_dev->base[0]; - int amount_scale = rknpu_dev->config->pc_data_amount_scale; + const struct rknpu_config *config = rknpu_dev->config; + int amount_scale = config->pc_data_amount_scale; - if (!rknpu_dev->config->bw_enable) { + if (config->amount_top == NULL) { LOG_WARN("Get rw_amount is not supported on this device!\n"); return 0; } spin_lock(&rknpu_dev->lock); - if (dt_wr != NULL) - *dt_wr = REG_READ(RKNPU_OFFSET_DT_WR_AMOUNT) * amount_scale; + if (dt_wr != NULL) { + *dt_wr = REG_READ(config->amount_top->offset_dt_wr) * + amount_scale; + if (config->amount_core) { + *dt_wr += REG_READ(config->amount_core->offset_dt_wr) * + amount_scale; + } + } - if (dt_rd != NULL) - *dt_rd = REG_READ(RKNPU_OFFSET_DT_RD_AMOUNT) * amount_scale; + if (dt_rd != NULL) { + *dt_rd = REG_READ(config->amount_top->offset_dt_rd) * + amount_scale; + if (config->amount_core) { + *dt_rd += REG_READ(config->amount_core->offset_dt_rd) * + amount_scale; + } + } - if (wd_rd != NULL) - *wd_rd = REG_READ(RKNPU_OFFSET_WT_RD_AMOUNT) * amount_scale; + if (wd_rd != NULL) { + *wd_rd = REG_READ(config->amount_top->offset_wt_rd) * + amount_scale; + if (config->amount_core) { + *wd_rd += REG_READ(config->amount_core->offset_wt_rd) * + amount_scale; + } + } spin_unlock(&rknpu_dev->lock); @@ -998,12 +1020,13 @@ int rknpu_get_rw_amount(struct rknpu_device *rknpu_dev, uint32_t *dt_wr, int rknpu_get_total_rw_amount(struct rknpu_device *rknpu_dev, uint32_t *amount) { + const struct rknpu_config *config = rknpu_dev->config; uint32_t dt_wr = 0; uint32_t dt_rd = 0; uint32_t wd_rd = 0; int ret = -EINVAL; - if (!rknpu_dev->config->bw_enable) { + if (config->amount_top == NULL) { LOG_WARN( "Get total_rw_amount is not supported on this device!\n"); return 0; diff --git a/drivers/video/rockchip/mpp/mpp_rkvenc2.c b/drivers/video/rockchip/mpp/mpp_rkvenc2.c index c132b53e4752..4f10e080da2e 100644 --- a/drivers/video/rockchip/mpp/mpp_rkvenc2.c +++ b/drivers/video/rockchip/mpp/mpp_rkvenc2.c @@ -1272,12 +1272,25 @@ static int rkvenc_run(struct mpp_dev *mpp, struct mpp_task *mpp_task) } static void rkvenc2_read_slice_len(struct mpp_dev *mpp, struct rkvenc_task *task, - u32 last) + u32 *irq_status) { + struct rkvenc_dev *enc = to_rkvenc_dev(mpp); + struct rkvenc_hw_info *hw = enc->hw_info; u32 sli_num = mpp_read_relaxed(mpp, RKVENC2_REG_SLICE_NUM_BASE); + u32 new_irq_status = mpp_read(mpp, hw->int_sta_base); union rkvenc2_slice_len_info slice_info; u32 task_id = task->mpp_task.task_id; u32 i; + u32 last = 0; + + /* Need update irq status and slice number when enc done ready with new status*/ + if ((new_irq_status != *irq_status) && (new_irq_status & INT_STA_ENC_DONE_STA)) { + *irq_status |= new_irq_status; + sli_num = mpp_read_relaxed(mpp, RKVENC2_REG_SLICE_NUM_BASE); + mpp_write(mpp, hw->int_clr_base, new_irq_status); + } + + last = *irq_status & INT_STA_ENC_DONE_STA; mpp_dbg_slice("task %d wr %3d len start %s\n", task_id, sli_num, last ? "last" : ""); @@ -1346,7 +1359,7 @@ static int rkvenc_irq(struct mpp_dev *mpp) if (task && task->task_split && (irq_status & (INT_STA_SLC_DONE_STA | INT_STA_ENC_DONE_STA))) { mpp_time_part_diff(mpp_task); - rkvenc2_read_slice_len(mpp, task, irq_status & INT_STA_ENC_DONE_STA); + rkvenc2_read_slice_len(mpp, task, &irq_status); wake_up(&mpp_task->wait); }