mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-06 02:50:49 +09:00
video: rockchip: rga3: add fix for hardware issue with RK3576
1. Disable auto_rst to avoid false interrupt generation. 2. Reset core_clk before startup to avoid hardware runaway due to continuous scaling. 3. Configure auto_clean command count to avoid iommu access exception after command count from 4095->0. Update driver version to 1.3.4 Signed-off-by: Yu Qiaowei <cerf.yu@rock-chips.com> Change-Id: I12f312280429996c182952fbe8c8c4a20155dc4f
This commit is contained in:
@@ -123,6 +123,8 @@
|
||||
#define m_RGA2_CMD_CTRL_INCR_VALID_P (0x1 << 1)
|
||||
#define m_RGA2_CMD_CTRL_CMD_LINE_ST_P (0x1 << 0)
|
||||
|
||||
#define s_RGA2_CMD_CTRL_INCR_NUM(x) ((x & 0x3ff) << 3)
|
||||
|
||||
/* RGA_STATUS1 */
|
||||
#define m_RGA2_STATUS1_SW_CMD_TOTAL_NUM (0xfff << 8)
|
||||
#define m_RGA2_STATUS1_SW_CMD_CUR_NUM (0xfff << 8)
|
||||
|
||||
@@ -87,7 +87,7 @@
|
||||
|
||||
#define DRIVER_MAJOR_VERISON 1
|
||||
#define DRIVER_MINOR_VERSION 3
|
||||
#define DRIVER_REVISION_VERSION 3
|
||||
#define DRIVER_REVISION_VERSION 4
|
||||
#define DRIVER_PATCH_VERSION
|
||||
|
||||
#define DRIVER_VERSION (STR(DRIVER_MAJOR_VERISON) "." STR(DRIVER_MINOR_VERSION) \
|
||||
@@ -337,8 +337,11 @@ struct rga_scheduler_t {
|
||||
struct list_head todo_list;
|
||||
spinlock_t irq_lock;
|
||||
wait_queue_head_t job_done_wq;
|
||||
|
||||
const struct rga_backend_ops *ops;
|
||||
const struct rga_hw_data *data;
|
||||
unsigned long hw_issues_mask;
|
||||
|
||||
int job_count;
|
||||
int irq;
|
||||
struct rga_version_t version;
|
||||
|
||||
@@ -26,6 +26,10 @@ enum rga_hw_support_format_index {
|
||||
RGA_FORMAT_INDEX_BUTT,
|
||||
};
|
||||
|
||||
enum rga_hw_issue {
|
||||
RGA_HW_ISSUE_DIS_AUTO_RST,
|
||||
};
|
||||
|
||||
struct rga_win_data {
|
||||
const char *name;
|
||||
const uint32_t *formats[RGA_FORMAT_INDEX_BUTT];
|
||||
@@ -75,6 +79,9 @@ extern const struct rga_hw_data rga2e_1106_data;
|
||||
extern const struct rga_hw_data rga2e_iommu_data;
|
||||
extern const struct rga_hw_data rga2p_iommu_data;
|
||||
|
||||
#define rga_hw_has_issue(scheduler, issue) test_bit(issue, &((scheduler)->hw_issues_mask))
|
||||
#define rga_hw_set_issue_mask(scheduler, issue) set_bit(issue, &((scheduler)->hw_issues_mask))
|
||||
|
||||
/* Returns false if in range, true otherwise */
|
||||
static inline bool rga_hw_out_of_range(const struct rga_rect_range *range, int width, int height)
|
||||
{
|
||||
|
||||
@@ -2889,6 +2889,7 @@ static void rga2_set_reg_full_csc(struct rga_job *job, struct rga_scheduler_t *s
|
||||
static int rga2_set_reg(struct rga_job *job, struct rga_scheduler_t *scheduler)
|
||||
{
|
||||
int i;
|
||||
int cur_num;
|
||||
bool master_mode_en;
|
||||
uint32_t sys_ctrl;
|
||||
uint32_t *cmd;
|
||||
@@ -2917,12 +2918,25 @@ static int rga2_set_reg(struct rga_job *job, struct rga_scheduler_t *scheduler)
|
||||
cmd[2 + i * 4], cmd[3 + i * 4]);
|
||||
}
|
||||
|
||||
spin_lock_irqsave(&scheduler->irq_lock, flags);
|
||||
|
||||
/* sys_reg init */
|
||||
sys_ctrl = m_RGA2_SYS_CTRL_AUTO_CKG | m_RGA2_SYS_CTRL_AUTO_RST |
|
||||
m_RGA2_SYS_CTRL_RST_PROTECT_P | m_RGA2_SYS_CTRL_DST_WR_OPT_DIS |
|
||||
sys_ctrl = m_RGA2_SYS_CTRL_AUTO_CKG |
|
||||
m_RGA2_SYS_CTRL_DST_WR_OPT_DIS |
|
||||
m_RGA2_SYS_CTRL_SRC0YUV420SP_RD_OPT_DIS;
|
||||
|
||||
spin_lock_irqsave(&scheduler->irq_lock, flags);
|
||||
if (rga_hw_has_issue(scheduler, RGA_HW_ISSUE_DIS_AUTO_RST)) {
|
||||
/*
|
||||
* when RGA is running continuously, disabling auto_rst
|
||||
* requires resetting core_clk.
|
||||
*/
|
||||
cur_num = (rga_read(RGA2_STATUS1, scheduler) & m_RGA2_STATUS1_SW_CMD_CUR_NUM) >> 8;
|
||||
if (cur_num > 0)
|
||||
rga_write(m_RGA2_SYS_CTRL_AUTO_CKG | m_RGA2_SYS_CTRL_CCLK_SRESET_P,
|
||||
RGA2_SYS_CTRL, scheduler);
|
||||
} else {
|
||||
sys_ctrl |= m_RGA2_SYS_CTRL_AUTO_RST;
|
||||
}
|
||||
|
||||
if (job->pre_intr_info.enable)
|
||||
rga2_set_pre_intr_reg(job, scheduler);
|
||||
@@ -2942,7 +2956,8 @@ static int rga2_set_reg(struct rga_job *job, struct rga_scheduler_t *scheduler)
|
||||
/* set cmd_addr */
|
||||
rga_write(job->cmd_buf->dma_addr, RGA2_CMD_BASE, scheduler);
|
||||
rga_write(sys_ctrl, RGA2_SYS_CTRL, scheduler);
|
||||
rga_write(m_RGA2_CMD_CTRL_CMD_LINE_ST_P, RGA2_CMD_CTRL, scheduler);
|
||||
rga_write(rga_read(RGA2_CMD_CTRL, scheduler) | m_RGA2_CMD_CTRL_CMD_LINE_ST_P,
|
||||
RGA2_CMD_CTRL, scheduler);
|
||||
} else {
|
||||
/* slave mode */
|
||||
sys_ctrl |= s_RGA2_SYS_CTRL_CMD_MODE(0) | m_RGA2_SYS_CTRL_CMD_OP_ST_P;
|
||||
@@ -2951,6 +2966,8 @@ static int rga2_set_reg(struct rga_job *job, struct rga_scheduler_t *scheduler)
|
||||
for (i = 0; i <= 32; i++)
|
||||
rga_write(cmd[i], 0x100 + i * 4, scheduler);
|
||||
|
||||
rga_write(rga_read(RGA2_CMD_CTRL, scheduler) | m_RGA2_CMD_CTRL_CMD_LINE_ST_P,
|
||||
RGA2_CMD_CTRL, scheduler);
|
||||
rga_write(sys_ctrl, RGA2_SYS_CTRL, scheduler);
|
||||
}
|
||||
|
||||
|
||||
@@ -1366,15 +1366,17 @@ static int rga_drv_probe(struct platform_device *pdev)
|
||||
scheduler->data = &rga3_data;
|
||||
} else if (scheduler->core == RGA2_SCHEDULER_CORE0 ||
|
||||
scheduler->core == RGA2_SCHEDULER_CORE1) {
|
||||
if (!strcmp(scheduler->version.str, "3.3.87975"))
|
||||
if (!strcmp(scheduler->version.str, "3.3.87975")) {
|
||||
scheduler->data = &rga2e_1106_data;
|
||||
else if (!strcmp(scheduler->version.str, "3.6.92812") ||
|
||||
!strcmp(scheduler->version.str, "3.7.93215"))
|
||||
} else if (!strcmp(scheduler->version.str, "3.6.92812") ||
|
||||
!strcmp(scheduler->version.str, "3.7.93215")) {
|
||||
scheduler->data = &rga2e_iommu_data;
|
||||
else if (!strcmp(scheduler->version.str, "3.e.19357"))
|
||||
} else if (!strcmp(scheduler->version.str, "3.e.19357")) {
|
||||
scheduler->data = &rga2p_iommu_data;
|
||||
else
|
||||
rga_hw_set_issue_mask(scheduler, RGA_HW_ISSUE_DIS_AUTO_RST);
|
||||
} else {
|
||||
scheduler->data = &rga2e_data;
|
||||
}
|
||||
}
|
||||
|
||||
data->scheduler[data->num_of_scheduler] = scheduler;
|
||||
|
||||
Reference in New Issue
Block a user