1650 lines
49 KiB
C
1650 lines
49 KiB
C
/* SPDX-License-Identifier: GPL-2.0 */
|
|
/*
|
|
* Copyright (c) 2019 MediaTek Inc.
|
|
*/
|
|
|
|
#define LOG_TAG "RDMA"
|
|
#include "ddp_log.h"
|
|
#include "ddp_clkmgr.h"
|
|
#include <linux/delay.h>
|
|
#include "ddp_info.h"
|
|
#include "ddp_reg.h"
|
|
#include "ddp_matrix_para.h"
|
|
#include "ddp_rdma.h"
|
|
#include "ddp_rdma_ex.h"
|
|
#include "ddp_dump.h"
|
|
#include "lcm_drv.h"
|
|
#include "primary_display.h"
|
|
#include "ddp_m4u.h"
|
|
#include "disp_lowpower.h"
|
|
#include "ddp_mmp.h"
|
|
#include "debug.h"
|
|
|
|
#define MMSYS_CLK_LOW (0)
|
|
#define MMSYS_CLK_HIGH (1)
|
|
|
|
static unsigned int rdma_fps[RDMA_INSTANCES] = { 60, 60 };
|
|
static struct golden_setting_context *rdma_golden_setting;
|
|
|
|
int polling_rdma_output_line_enable = 1;
|
|
|
|
/*****************************************************************************/
|
|
unsigned int rdma_index(enum DISP_MODULE_ENUM module)
|
|
{
|
|
int idx = 0;
|
|
|
|
switch (module) {
|
|
case DISP_MODULE_RDMA0:
|
|
idx = 0;
|
|
break;
|
|
case DISP_MODULE_RDMA1:
|
|
idx = 1;
|
|
break;
|
|
default:
|
|
DDPERR("invalid rdma module=%d\n", module); /* invalid module */
|
|
ASSERT(0);
|
|
break;
|
|
}
|
|
ASSERT((idx >= 0) && (idx < RDMA_INSTANCES));
|
|
return idx;
|
|
}
|
|
|
|
void rdma_set_target_line(enum DISP_MODULE_ENUM module, unsigned int line,
|
|
void *handle)
|
|
{
|
|
unsigned int idx = rdma_index(module);
|
|
|
|
DISP_REG_SET(handle,
|
|
idx * DISP_RDMA_INDEX_OFFSET + DISP_REG_RDMA_TARGET_LINE,
|
|
line);
|
|
}
|
|
|
|
int rdma_init(enum DISP_MODULE_ENUM module, void *handle)
|
|
{
|
|
return rdma_clock_on(module, handle);
|
|
}
|
|
|
|
int rdma_deinit(enum DISP_MODULE_ENUM module, void *handle)
|
|
{
|
|
return rdma_clock_off(module, handle);
|
|
}
|
|
|
|
void rdma_get_address(enum DISP_MODULE_ENUM module, unsigned long *addr)
|
|
{
|
|
unsigned int idx = rdma_index(module);
|
|
|
|
*addr = DISP_REG_GET(
|
|
DISP_REG_RDMA_MEM_START_ADDR + DISP_RDMA_INDEX_OFFSET * idx);
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
|
|
static inline unsigned long rdma_to_cmdq_engine(enum DISP_MODULE_ENUM module)
|
|
{
|
|
switch (module) {
|
|
case DISP_MODULE_RDMA0:
|
|
return CMDQ_ENG_DISP_RDMA0;
|
|
case DISP_MODULE_RDMA1:
|
|
return CMDQ_ENG_DISP_RDMA1;
|
|
default:
|
|
DDPERR("invalid rdma module=%d,rdma to cmdq engine fail\n",
|
|
module);
|
|
ASSERT(0);
|
|
return DISP_MODULE_UNKNOWN;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
static inline unsigned long rdma_to_cmdq_event_nonsec_end(
|
|
enum DISP_MODULE_ENUM module)
|
|
{
|
|
switch (module) {
|
|
case DISP_MODULE_RDMA0:
|
|
return CMDQ_SYNC_DISP_RDMA0_2NONSEC_END;
|
|
case DISP_MODULE_RDMA1:
|
|
return CMDQ_SYNC_DISP_RDMA1_2NONSEC_END;
|
|
default:
|
|
DDPERR("invalid rdma module=%d,rmda to cmdq event fail\n",
|
|
module);
|
|
ASSERT(0);
|
|
return DISP_MODULE_UNKNOWN;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int rdma_enable_irq(enum DISP_MODULE_ENUM module, void *handle,
|
|
enum DDP_IRQ_LEVEL irq_level)
|
|
{
|
|
unsigned int idx = rdma_index(module);
|
|
|
|
ASSERT(idx <= RDMA_INSTANCES);
|
|
|
|
switch (irq_level) {
|
|
case DDP_IRQ_LEVEL_ALL:
|
|
DISP_REG_SET(handle,
|
|
idx * DISP_RDMA_INDEX_OFFSET + DISP_REG_RDMA_INT_ENABLE,
|
|
0x1E);
|
|
break;
|
|
case DDP_IRQ_LEVEL_ERROR:
|
|
DISP_REG_SET(handle,
|
|
idx * DISP_RDMA_INDEX_OFFSET + DISP_REG_RDMA_INT_ENABLE,
|
|
0x18);
|
|
break;
|
|
case DDP_IRQ_LEVEL_NONE:
|
|
DISP_REG_SET(handle,
|
|
idx * DISP_RDMA_INDEX_OFFSET + DISP_REG_RDMA_INT_ENABLE,
|
|
0x0);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int rdma_start(enum DISP_MODULE_ENUM module, void *handle)
|
|
{
|
|
unsigned int idx = rdma_index(module);
|
|
unsigned int regval;
|
|
|
|
ASSERT(idx <= RDMA_INSTANCES);
|
|
|
|
regval = REG_FLD_VAL(INT_STATUS_FLD_REG_UPDATE_INT_FLAG, 0) |
|
|
REG_FLD_VAL(INT_STATUS_FLD_FRAME_START_INT_FLAG, 1) |
|
|
REG_FLD_VAL(INT_STATUS_FLD_FRAME_END_INT_FLAG, 1) |
|
|
REG_FLD_VAL(INT_STATUS_FLD_EOF_ABNORMAL_INT_FLAG, 1) |
|
|
REG_FLD_VAL(INT_STATUS_FLD_FIFO_UNDERFLOW_INT_FLAG, 1) |
|
|
REG_FLD_VAL(INT_STATUS_FLD_TARGET_LINE_INT_FLAG, 0) |
|
|
REG_FLD_VAL(INT_STATUS_FLD_FIFO_EMPTY_INT_FLAG, 0);
|
|
|
|
DISP_REG_SET(handle,
|
|
idx * DISP_RDMA_INDEX_OFFSET + DISP_REG_RDMA_INT_ENABLE,
|
|
regval);
|
|
DISP_REG_SET_FIELD(handle, GLOBAL_CON_FLD_ENGINE_EN,
|
|
idx * DISP_RDMA_INDEX_OFFSET + DISP_REG_RDMA_GLOBAL_CON, 1);
|
|
|
|
return 0;
|
|
}
|
|
|
|
int rdma_stop(enum DISP_MODULE_ENUM module, void *handle)
|
|
{
|
|
unsigned int idx = rdma_index(module);
|
|
|
|
ASSERT(idx <= RDMA_INSTANCES);
|
|
|
|
DISP_REG_SET_FIELD(handle, GLOBAL_CON_FLD_ENGINE_EN,
|
|
idx * DISP_RDMA_INDEX_OFFSET + DISP_REG_RDMA_GLOBAL_CON, 0);
|
|
DISP_REG_SET(handle,
|
|
idx * DISP_RDMA_INDEX_OFFSET + DISP_REG_RDMA_INT_ENABLE, 0);
|
|
DISP_REG_SET(handle,
|
|
idx * DISP_RDMA_INDEX_OFFSET + DISP_REG_RDMA_INT_STATUS, 0);
|
|
return 0;
|
|
}
|
|
|
|
int rdma_reset_by_cmdq(enum DISP_MODULE_ENUM module, void *handle)
|
|
{
|
|
int ret = 0;
|
|
unsigned int idx = rdma_index(module);
|
|
|
|
ASSERT(idx <= RDMA_INSTANCES);
|
|
|
|
DISP_REG_SET_FIELD(handle, GLOBAL_CON_FLD_SOFT_RESET,
|
|
idx * DISP_RDMA_INDEX_OFFSET + DISP_REG_RDMA_GLOBAL_CON, 1);
|
|
|
|
DISP_REG_SET_FIELD(handle, GLOBAL_CON_FLD_SOFT_RESET,
|
|
idx * DISP_RDMA_INDEX_OFFSET + DISP_REG_RDMA_GLOBAL_CON, 0);
|
|
|
|
DISP_REG_CMDQ_POLLING(handle,
|
|
idx * DISP_RDMA_INDEX_OFFSET + DISP_REG_RDMA_GLOBAL_CON,
|
|
0x100, 0x700);
|
|
|
|
return ret;
|
|
}
|
|
|
|
int rdma_reset(enum DISP_MODULE_ENUM module, void *handle)
|
|
{
|
|
unsigned int delay_cnt = 0;
|
|
int ret = 0, offset = 0;
|
|
unsigned int idx = rdma_index(module);
|
|
|
|
ASSERT(idx <= RDMA_INSTANCES);
|
|
|
|
offset = idx * DISP_RDMA_INDEX_OFFSET;
|
|
DISP_REG_SET_FIELD(handle, GLOBAL_CON_FLD_SOFT_RESET,
|
|
offset + DISP_REG_RDMA_GLOBAL_CON, 1);
|
|
while ((DISP_REG_GET(offset + DISP_REG_RDMA_GLOBAL_CON) & 0x700) ==
|
|
0x100) {
|
|
delay_cnt++;
|
|
udelay(10);
|
|
if (delay_cnt > 10000) {
|
|
ret = -1;
|
|
DDPERR(
|
|
"rdma%d_reset timeout, stage 1! RDMA_GLO_CON_REG=0x%x\n",
|
|
idx,
|
|
DISP_REG_GET(offset + DISP_REG_RDMA_GLOBAL_CON));
|
|
break;
|
|
}
|
|
}
|
|
DISP_REG_SET_FIELD(handle, GLOBAL_CON_FLD_SOFT_RESET,
|
|
offset + DISP_REG_RDMA_GLOBAL_CON, 0);
|
|
delay_cnt = 0;
|
|
while ((DISP_REG_GET(offset + DISP_REG_RDMA_GLOBAL_CON) & 0x700) !=
|
|
0x100) {
|
|
delay_cnt++;
|
|
udelay(10);
|
|
if (delay_cnt <= 10000)
|
|
continue;
|
|
|
|
ret = -1;
|
|
DDPERR("rdma%d_reset timeout, stage 2! RDMA_GLO_CON_REG=0x%x\n",
|
|
idx,
|
|
DISP_REG_GET(offset + DISP_REG_RDMA_GLOBAL_CON));
|
|
break;
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
#if 0
|
|
/* old from vinson */
|
|
/* set ultra registers */
|
|
void rdma_set_ultra_l(unsigned int idx, unsigned int bpp, void *handle,
|
|
struct golden_setting_context *p_golden_setting)
|
|
{
|
|
/* rdma golden setting variables */
|
|
unsigned int mmsysclk = 230;
|
|
unsigned int is_wrot_sram = 0;
|
|
unsigned int is_rsz_sram = 0;
|
|
unsigned int fifo_mode = 1;
|
|
|
|
unsigned int ultra_low_us = 4;
|
|
unsigned int ultra_high_us = 6;
|
|
unsigned int preultra_low_us = ultra_high_us;
|
|
unsigned int preultra_high_us = 7;
|
|
/*
|
|
*
|
|
* unsigned int urgent_low_us = 4;
|
|
* unsigned int urgent_high_us = 45; 10 times
|
|
*/
|
|
|
|
unsigned long long fill_rate = 0;
|
|
unsigned long long consume_rate = 0;
|
|
|
|
unsigned int fifo_valid_size = 384;
|
|
unsigned int fifo_off_drs_enter = 0;
|
|
unsigned int fifo_off_drs_leave = 0;
|
|
unsigned int fifo_off_spm = 0; /* SPM latency */
|
|
unsigned int fifo_off_dvfs = 0;
|
|
|
|
/* working variables */
|
|
unsigned int preultra_low;
|
|
unsigned int preultra_high;
|
|
unsigned int ultra_low;
|
|
unsigned int ultra_high;
|
|
|
|
unsigned int drs_enter = 0;
|
|
unsigned int drs_leave = 0;
|
|
|
|
unsigned int issue_req_threshold;
|
|
unsigned int output_valid_fifo_threshold;
|
|
|
|
unsigned int sodi_threshold_high;
|
|
unsigned int sodi_threshold_low;
|
|
unsigned int dvfs_threshold_high;
|
|
unsigned int dvfs_threshold_low;
|
|
|
|
unsigned int frame_rate;
|
|
unsigned int Bytes_per_sec;
|
|
unsigned int offset;
|
|
long long temp;
|
|
long long temp_for_div;
|
|
|
|
if (!p_golden_setting) {
|
|
DDPERR("golden setting is null, %s,%d\n", __FILE__, __LINE__);
|
|
ASSERT(0);
|
|
return;
|
|
}
|
|
rdma_golden_setting = p_golden_setting;
|
|
|
|
frame_rate = 60;
|
|
if (idx == 1) {
|
|
/* hardcode bpp & frame_rate for rdma1 */
|
|
bpp = 24;
|
|
frame_rate = 60;
|
|
|
|
if ((rdma_golden_setting->ext_dst_width == 1920) &&
|
|
(rdma_golden_setting->ext_dst_height == 1080))
|
|
frame_rate = 30;
|
|
if ((rdma_golden_setting->ext_dst_width == 3840) &&
|
|
(rdma_golden_setting->ext_dst_height == 2160))
|
|
frame_rate = 30;
|
|
}
|
|
|
|
/* get fifo parameters */
|
|
switch (rdma_golden_setting->mmsys_clk) {
|
|
case MMSYS_CLK_LOW:
|
|
mmsysclk = 230;
|
|
break;
|
|
case MMSYS_CLK_HIGH:
|
|
mmsysclk = 457;
|
|
break;
|
|
default:
|
|
mmsysclk = 230; /* worse case */
|
|
break;
|
|
}
|
|
|
|
Bytes_per_sec = bpp / 8;
|
|
if (!Bytes_per_sec) {
|
|
DDPERR("bpp is invalid, bpp=%d\n", bpp);
|
|
return;
|
|
}
|
|
|
|
is_wrot_sram = rdma_golden_setting->is_wrot_sram;
|
|
is_rsz_sram = rdma_golden_setting->is_rsz_sram;
|
|
fifo_mode = rdma_golden_setting->fifo_mode;
|
|
|
|
if (rdma_golden_setting->is_dc)
|
|
fill_rate = 960 * mmsysclk; /* FIFO depth / us */
|
|
else
|
|
fill_rate = 960 * mmsysclk * 3 / 16; /* FIFO depth / us */
|
|
|
|
if (idx == 0) {
|
|
/* only for offset */
|
|
fifo_off_drs_enter = 4;
|
|
fifo_off_drs_leave = 2;
|
|
fifo_off_spm = 50; /* 10 times */
|
|
fifo_off_dvfs = 4;
|
|
consume_rate = rdma_golden_setting->dst_width *
|
|
rdma_golden_setting->dst_height *
|
|
frame_rate * Bytes_per_sec;
|
|
do_div(consume_rate, 1000);
|
|
} else {
|
|
fifo_off_drs_enter = 0;
|
|
fifo_off_drs_leave = 0;
|
|
fifo_off_spm = 14; /* 10 times */
|
|
fifo_off_dvfs = 2;
|
|
|
|
consume_rate = rdma_golden_setting->ext_dst_width *
|
|
rdma_golden_setting->ext_dst_height *
|
|
frame_rate * Bytes_per_sec;
|
|
do_div(consume_rate, 1000);
|
|
}
|
|
consume_rate *= 1250;
|
|
do_div(consume_rate, 16000/* 16 * 1000 */);
|
|
|
|
preultra_low = (preultra_low_us + fifo_off_drs_enter) * consume_rate;
|
|
preultra_low = DIV_ROUND_UP(preultra_low, 1000);
|
|
|
|
preultra_high = (preultra_high_us + fifo_off_drs_enter) * consume_rate;
|
|
preultra_high = DIV_ROUND_UP(preultra_high, 1000);
|
|
|
|
ultra_low = (ultra_low_us + fifo_off_drs_enter) * consume_rate;
|
|
ultra_low = DIV_ROUND_UP(ultra_low, 1000);
|
|
|
|
ultra_high = preultra_low;
|
|
|
|
if (idx == 0) {
|
|
/* only rdma0 can share sram */
|
|
if (is_wrot_sram)
|
|
fifo_valid_size = 2048;
|
|
else if (is_rsz_sram)
|
|
fifo_valid_size = 736;
|
|
else
|
|
fifo_valid_size = 384;
|
|
} else {
|
|
fifo_valid_size = 384;
|
|
}
|
|
|
|
issue_req_threshold =
|
|
min(fifo_valid_size - preultra_low, 256U);
|
|
|
|
/* output valid should < total rdma data size, or hang will happen */
|
|
temp = rdma_golden_setting->rdma_width *
|
|
rdma_golden_setting->rdma_height * Bytes_per_sec;
|
|
do_div(temp, 16);
|
|
temp -= 1;
|
|
output_valid_fifo_threshold = min(((long long)preultra_low), temp);
|
|
|
|
/* SODI threshold */
|
|
sodi_threshold_low = (ultra_low_us * 10 + fifo_off_spm) * consume_rate;
|
|
sodi_threshold_low = DIV_ROUND_UP(sodi_threshold_low, 10000);
|
|
|
|
temp_for_div = 1200 * (fill_rate - consume_rate);
|
|
WARN_ON(temp_for_div < 0);
|
|
do_div(temp_for_div, 1000000);
|
|
temp = fifo_valid_size - temp_for_div;
|
|
if (temp < 0)
|
|
sodi_threshold_high = preultra_high;
|
|
else
|
|
sodi_threshold_high = max(((long long)preultra_high), temp);
|
|
|
|
dvfs_threshold_low = preultra_low;
|
|
dvfs_threshold_high = preultra_low + 1;
|
|
|
|
offset = idx * DISP_RDMA_INDEX_OFFSET;
|
|
DISP_REG_SET(handle, offset + DISP_REG_RDMA_MEM_GMC_SETTING_0,
|
|
preultra_low | (preultra_high << 16));
|
|
|
|
DISP_REG_SET(handle, offset + DISP_REG_RDMA_MEM_GMC_SETTING_1,
|
|
ultra_low | (ultra_high << 16));
|
|
|
|
DISP_REG_SET(handle, offset + DISP_REG_RDMA_MEM_GMC_SETTING_2,
|
|
issue_req_threshold);
|
|
|
|
DISP_REG_SET(handle, offset + DISP_REG_RDMA_FIFO_CON,
|
|
REG_FLD_VAL(FIFO_CON_FLD_OUTPUT_VALID_FIFO_THRESHOLD,
|
|
output_valid_fifo_threshold) |
|
|
REG_FLD_VAL(FIFO_CON_FLD_FIFO_PSEUDO_SIZE, fifo_valid_size) |
|
|
REG_FLD_VAL(FIFO_CON_FLD_FIFO_UNDERFLOW_EN, 1));
|
|
|
|
DISP_REG_SET(handle, offset + DISP_REG_RDMA_THRESHOLD_FOR_SODI,
|
|
sodi_threshold_low | (sodi_threshold_high << 16));
|
|
|
|
DISP_REG_SET(handle, offset + DISP_REG_RDMA_THRESHOLD_FOR_DVFS,
|
|
dvfs_threshold_low | (dvfs_threshold_high << 16));
|
|
|
|
/* DISP_RDMA_DVFS_SETTING_PREULTRA */
|
|
preultra_low = (preultra_low_us + fifo_off_dvfs) * consume_rate;
|
|
preultra_low = DIV_ROUND_UP(preultra_low, 1000);
|
|
|
|
preultra_high = (preultra_high_us + fifo_off_dvfs) * consume_rate;
|
|
preultra_high = DIV_ROUND_UP(preultra_high, 1000);
|
|
|
|
ultra_low = (ultra_low_us + fifo_off_dvfs) * consume_rate;
|
|
ultra_low = DIV_ROUND_UP(ultra_low, 1000);
|
|
|
|
ultra_high = preultra_low;
|
|
|
|
DISP_REG_SET(handle, offset + DISP_REG_RDMA_DVFS_SETTING_PRE,
|
|
preultra_low | (preultra_high << 16));
|
|
|
|
DISP_REG_SET(handle, offset + DISP_REG_RDMA_DVFS_SETTING_ULTRA,
|
|
ultra_low | (ultra_high << 16));
|
|
|
|
/* DISP_REG_RDMA_LEAVE_DRS_SETTING */
|
|
drs_enter = (preultra_low_us + fifo_off_drs_enter) * consume_rate;
|
|
drs_enter = DIV_ROUND_UP(drs_enter, 1000);
|
|
|
|
drs_leave = (preultra_low_us + fifo_off_drs_leave) * consume_rate;
|
|
drs_leave = DIV_ROUND_UP(drs_leave, 1000);
|
|
|
|
DISP_REG_SET(handle, offset + DISP_REG_RDMA_LEAVE_DRS_SETTING,
|
|
drs_leave | (drs_leave << 16));
|
|
|
|
DISP_REG_SET(handle, offset + DISP_REG_RDMA_ENTER_DRS_SETTING,
|
|
drs_enter | (drs_enter << 16));
|
|
|
|
#if 0
|
|
if (idx == 0)
|
|
rdma_dump_golden_setting_context(DISP_MODULE_RDMA0);
|
|
else
|
|
rdma_dump_golden_setting_context(DISP_MODULE_RDMA1);
|
|
#endif
|
|
|
|
if (rdma_golden_setting->dst_width == 0 ||
|
|
rdma_golden_setting->dst_height == 0 ||
|
|
bpp == 0 || frame_rate == 0) {
|
|
DDPDUMP("==RDMA Golden Setting Value=============\n");
|
|
|
|
DDPDUMP("width = %d\n",
|
|
rdma_golden_setting->dst_width);
|
|
DDPDUMP("height = %d\n",
|
|
rdma_golden_setting->dst_height);
|
|
DDPDUMP("bpp = %d\n", bpp);
|
|
DDPDUMP("frame_rate = %d\n", frame_rate);
|
|
|
|
DDPDUMP("fill_rate = %lld\n", fill_rate);
|
|
DDPDUMP("consume_rate = %lld\n", consume_rate);
|
|
DDPDUMP("ultra_low_us = %d\n", ultra_low_us);
|
|
DDPDUMP("ultra_high_us = %d\n", ultra_high_us);
|
|
DDPDUMP("preultra_high_us= %d\n", preultra_high_us);
|
|
|
|
DDPDUMP("preultra_low = %d\n", preultra_low);
|
|
DDPDUMP("preultra_high = %d\n", preultra_high);
|
|
DDPDUMP("ultra_low = %d\n", ultra_low);
|
|
DDPDUMP("issue_req_threshold = %d\n",
|
|
issue_req_threshold);
|
|
DDPDUMP("output_valid_fifo_threshold = %d\n",
|
|
output_valid_fifo_threshold);
|
|
DDPDUMP("sodi_threshold_low = %d\n", sodi_threshold_low);
|
|
DDPDUMP("sodi_threshold_high = %d\n", sodi_threshold_high);
|
|
DDPDUMP("dvfs_threshold_low = %d\n", dvfs_threshold_low);
|
|
DDPDUMP("dvfs_threshold_high = %d\n", dvfs_threshold_high);
|
|
}
|
|
}
|
|
|
|
#else
|
|
|
|
/* set ultra registers */
|
|
void rdma_set_ultra_l(unsigned int idx, unsigned int bpp, void *handle,
|
|
struct golden_setting_context *p_golden_setting)
|
|
{
|
|
|
|
/* rdma golden setting variables */
|
|
unsigned int mmsysclk = 230;
|
|
unsigned int is_wrot_sram = 0;
|
|
unsigned int is_rsz_sram = 0;
|
|
unsigned int fifo_mode = 1;
|
|
|
|
unsigned int ultra_low_us = 4;
|
|
unsigned int ultra_high_us = 6;
|
|
unsigned int preultra_low_us = ultra_high_us;
|
|
unsigned int preultra_high_us = 7;
|
|
unsigned int urgent_low_us = 30; /* 10 times */
|
|
unsigned int urgent_high_us = 35; /* 10 times */
|
|
|
|
unsigned long long fill_rate = 0;
|
|
unsigned long long consume_rate = 0;
|
|
unsigned long long consume_rate_div_tmp = 0;
|
|
unsigned long long consume_rate_div = 0;
|
|
unsigned int fifo_valid_size = 384;
|
|
unsigned int fifo_off_drs_enter = 0;
|
|
unsigned int fifo_off_drs_leave = 0;
|
|
unsigned int fifo_off_spm = 0; /*SPM latency*/
|
|
unsigned int fifo_off_dvfs = 0;
|
|
unsigned int fifo_off_ultra = 0;
|
|
|
|
/* working variables */
|
|
unsigned int preultra_low;
|
|
unsigned int preultra_high;
|
|
unsigned int ultra_low;
|
|
unsigned int ultra_high;
|
|
unsigned int urgent_low;
|
|
unsigned int urgent_high;
|
|
unsigned int dvfs_preultra_low;
|
|
unsigned int dvfs_preultra_high;
|
|
unsigned int dvfs_ultra_low;
|
|
unsigned int dvfs_ultra_high;
|
|
unsigned int drs_enter = 0;
|
|
unsigned int drs_leave = 0;
|
|
|
|
unsigned int issue_req_threshold;
|
|
unsigned int output_valid_fifo_threshold;
|
|
|
|
unsigned int sodi_threshold_high;
|
|
unsigned int sodi_threshold_low;
|
|
unsigned int dvfs_threshold_high;
|
|
unsigned int dvfs_threshold_low;
|
|
|
|
unsigned int frame_rate;
|
|
unsigned int Bytes_per_sec;
|
|
unsigned long long temp;
|
|
unsigned long long temp_for_div;
|
|
|
|
/* setup threshold for debug */
|
|
if (dbg_ultlow)
|
|
ultra_low_us = dbg_ultlow;
|
|
if (dbg_ulthigh) {
|
|
ultra_high_us = dbg_ulthigh;
|
|
preultra_low_us = ultra_high_us;
|
|
}
|
|
if (dbg_prehigh)
|
|
preultra_high_us = dbg_prehigh;
|
|
if (dbg_urg_low)
|
|
urgent_low_us = dbg_urg_low;
|
|
if (dbg_urg_high)
|
|
urgent_high_us = dbg_urg_high;
|
|
|
|
if (!p_golden_setting) {
|
|
DDPERR("golden setting is null, %s,%d\n", __FILE__, __LINE__);
|
|
ASSERT(0);
|
|
return;
|
|
}
|
|
rdma_golden_setting = p_golden_setting;
|
|
|
|
frame_rate = rdma_golden_setting->fps;
|
|
if (idx == 1) {
|
|
/* hardcode bpp & frame_rate for rdma1 */
|
|
bpp = 24;
|
|
frame_rate = 60;
|
|
|
|
if ((rdma_golden_setting->ext_dst_width == 1920) &&
|
|
(rdma_golden_setting->ext_dst_height == 1080))
|
|
frame_rate = 30;
|
|
|
|
if ((rdma_golden_setting->ext_dst_width == 3840) &&
|
|
(rdma_golden_setting->ext_dst_height == 2160))
|
|
frame_rate = 30;
|
|
}
|
|
|
|
DDPMSG("%s, frame_rate=%u\n", __func__, frame_rate);
|
|
|
|
/* get fifo parameters */
|
|
switch (rdma_golden_setting->mmsys_clk) {
|
|
case MMSYS_CLK_LOW:
|
|
#ifdef CONFIG_MTK_HIGH_FRAME_RATE
|
|
mmsysclk = 312;
|
|
#else
|
|
mmsysclk = 230;
|
|
#endif
|
|
break;
|
|
case MMSYS_CLK_HIGH:
|
|
mmsysclk = 457;
|
|
break;
|
|
default:
|
|
mmsysclk = 230; /* worse case */
|
|
break;
|
|
}
|
|
|
|
Bytes_per_sec = bpp / 8;
|
|
if (!Bytes_per_sec) {
|
|
DDPERR("bpp is invalid, bpp=%d\n", bpp);
|
|
return;
|
|
}
|
|
|
|
is_wrot_sram = rdma_golden_setting->is_wrot_sram;
|
|
is_rsz_sram = rdma_golden_setting->is_rsz_sram;
|
|
fifo_mode = rdma_golden_setting->fifo_mode;
|
|
|
|
|
|
if (rdma_golden_setting->is_dc)
|
|
fill_rate = 960 * mmsysclk; /* FIFO depth / us */
|
|
else
|
|
fill_rate = 960 * mmsysclk * 3 / 16; /* FIFO depth / us */
|
|
|
|
do_div(fill_rate, 100);
|
|
fill_rate = DIV_ROUND_UP((unsigned int)fill_rate, 10);
|
|
|
|
if (idx == 0) {
|
|
/* only for offset */
|
|
fifo_off_drs_enter = 4;
|
|
fifo_off_drs_leave = 1;
|
|
fifo_off_spm = 50; /* 10 times*/
|
|
fifo_off_dvfs = 2;
|
|
|
|
if (is_wrot_sram) {
|
|
if (rdma_golden_setting->dst_height > 2340)
|
|
fifo_off_ultra = 40;
|
|
else if (rdma_golden_setting->dst_height > 2400)
|
|
fifo_off_ultra = 30;
|
|
else
|
|
fifo_off_ultra = 50;
|
|
|
|
if (rdma_golden_setting->dst_height > 2340 &&
|
|
rdma_golden_setting->fps == 90)
|
|
fifo_off_ultra = 30;
|
|
} else if (is_rsz_sram)
|
|
fifo_off_ultra = 10;
|
|
else
|
|
fifo_off_ultra = 0;
|
|
consume_rate = rdma_golden_setting->dst_width;
|
|
consume_rate = consume_rate * rdma_golden_setting->dst_height
|
|
*frame_rate * Bytes_per_sec;
|
|
do_div(consume_rate, 1000);
|
|
|
|
} else {
|
|
fifo_off_drs_enter = 0;
|
|
fifo_off_drs_leave = 0;
|
|
fifo_off_spm = 14; /* 10 times*/
|
|
fifo_off_dvfs = 2;
|
|
fifo_off_ultra = 0;
|
|
consume_rate = rdma_golden_setting->ext_dst_width;
|
|
consume_rate = consume_rate *
|
|
rdma_golden_setting->ext_dst_height
|
|
* frame_rate * Bytes_per_sec;
|
|
|
|
do_div(consume_rate, 1000);
|
|
}
|
|
|
|
consume_rate *= 1250;
|
|
do_div(consume_rate, 16*1000);
|
|
consume_rate_div_tmp = consume_rate;
|
|
do_div(consume_rate_div_tmp, 100);
|
|
consume_rate_div = DIV_ROUND_UP((unsigned int)consume_rate_div_tmp, 10);
|
|
|
|
DDPMSG("%s, w=%d, h=%d, fps=%d, consume=%llu\n",
|
|
__func__,
|
|
rdma_golden_setting->dst_width,
|
|
rdma_golden_setting->dst_height,
|
|
rdma_golden_setting->fps,
|
|
consume_rate_div);
|
|
|
|
preultra_low = (preultra_low_us + fifo_off_ultra) * consume_rate_div;
|
|
|
|
preultra_high = (preultra_high_us + fifo_off_ultra) * consume_rate_div;
|
|
|
|
ultra_low = (ultra_low_us + fifo_off_ultra) * consume_rate_div;
|
|
|
|
ultra_high = preultra_low;
|
|
if (idx == 0) {
|
|
/* only rdma0 can share sram */
|
|
if (is_wrot_sram)
|
|
fifo_valid_size = 2048;
|
|
else if (is_rsz_sram)
|
|
fifo_valid_size = 736;
|
|
else
|
|
fifo_valid_size = 384;
|
|
} else {
|
|
fifo_valid_size = 128;
|
|
}
|
|
issue_req_threshold =
|
|
(fifo_valid_size - preultra_low) < 255
|
|
? (fifo_valid_size - preultra_low) : 255;
|
|
|
|
|
|
/* output valid should < total rdma data size, or hang will happen */
|
|
temp = rdma_golden_setting->rdma_width;
|
|
temp = temp * rdma_golden_setting->rdma_height * Bytes_per_sec;
|
|
do_div(temp, 16);
|
|
temp -= 1;
|
|
#if 0
|
|
output_valid_fifo_threshold =
|
|
(preultra_low_us * consume_rate_div) < temp
|
|
? (preultra_low_us * consume_rate_div) : temp;
|
|
#else
|
|
output_valid_fifo_threshold =
|
|
preultra_low < temp
|
|
? preultra_low : temp;
|
|
#endif
|
|
|
|
/* SODI threshold */
|
|
sodi_threshold_low = (ultra_low_us * 10 + fifo_off_spm)
|
|
* consume_rate_div;
|
|
sodi_threshold_low = DIV_ROUND_UP(sodi_threshold_low, 10);
|
|
|
|
temp_for_div = 5000 * (fill_rate - consume_rate_div);
|
|
WARN_ON((long long)temp_for_div < 0);
|
|
do_div(temp_for_div, 100);
|
|
temp_for_div = DIV_ROUND_UP((unsigned int)temp_for_div, 10);
|
|
temp = (long long)fifo_valid_size - temp_for_div;
|
|
|
|
if ((long long)temp < 0)
|
|
sodi_threshold_high = preultra_high;
|
|
else
|
|
sodi_threshold_high =
|
|
preultra_high > temp ? preultra_high : temp;
|
|
|
|
dvfs_threshold_low = preultra_low;
|
|
dvfs_threshold_high = preultra_low;
|
|
|
|
if (primary_display_is_video_mode()) {
|
|
/* video mode*/
|
|
DISP_REG_SET(handle, idx * DISP_RDMA_INDEX_OFFSET +
|
|
DISP_REG_RDMA_MEM_GMC_SETTING_0,
|
|
preultra_low | (preultra_high << 16) |
|
|
REG_FLD_VAL(
|
|
MEM_GMC_SETTING_0_FLD_RG_VALID_THRESHOLD_FORCE_PREULTRA,
|
|
0) |
|
|
REG_FLD_VAL(MEM_GMC_SETTING_0_FLD_RG_VDE_FORCE_PREULTRA,
|
|
1));
|
|
|
|
DISP_REG_SET(handle, idx * DISP_RDMA_INDEX_OFFSET +
|
|
DISP_REG_RDMA_MEM_GMC_SETTING_1,
|
|
ultra_low | (ultra_high << 16) |
|
|
REG_FLD_VAL(
|
|
MEM_GMC_SETTING_1_FLD_RG_VALID_THRESHOLD_BLOCK_ULTRA,
|
|
0) |
|
|
REG_FLD_VAL(MEM_GMC_SETTING_1_FLD_RG_VDE_BLOCK_ULTRA,
|
|
1));
|
|
|
|
DISP_REG_SET(handle, idx * DISP_RDMA_INDEX_OFFSET +
|
|
DISP_REG_RDMA_MEM_GMC_SETTING_2,
|
|
issue_req_threshold);
|
|
} else {
|
|
/* cmd mode */
|
|
DISP_REG_SET(handle, idx * DISP_RDMA_INDEX_OFFSET +
|
|
DISP_REG_RDMA_MEM_GMC_SETTING_0,
|
|
preultra_low | (preultra_high << 16) |
|
|
REG_FLD_VAL(
|
|
MEM_GMC_SETTING_0_FLD_RG_VALID_THRESHOLD_FORCE_PREULTRA,
|
|
1) |
|
|
REG_FLD_VAL(MEM_GMC_SETTING_0_FLD_RG_VDE_FORCE_PREULTRA,
|
|
0));
|
|
|
|
DISP_REG_SET(handle, idx * DISP_RDMA_INDEX_OFFSET +
|
|
DISP_REG_RDMA_MEM_GMC_SETTING_1,
|
|
ultra_low | (ultra_high << 16) |
|
|
REG_FLD_VAL(
|
|
MEM_GMC_SETTING_1_FLD_RG_VALID_THRESHOLD_BLOCK_ULTRA,
|
|
1) |
|
|
REG_FLD_VAL(MEM_GMC_SETTING_1_FLD_RG_VDE_BLOCK_ULTRA,
|
|
0));
|
|
|
|
DISP_REG_SET(handle, idx * DISP_RDMA_INDEX_OFFSET +
|
|
DISP_REG_RDMA_MEM_GMC_SETTING_2,
|
|
issue_req_threshold);
|
|
}
|
|
|
|
/* In video mode, output_valid_fifo_threshold = 0 */
|
|
if (primary_display_is_video_mode())
|
|
output_valid_fifo_threshold = 0;
|
|
|
|
if (output_valid_fifo_threshold > fifo_valid_size)
|
|
DDPERR(
|
|
"%s: RDMA golden setting is invalid!! output_valid_fifo_threshold=%d, fifo_valid_size=%d\n",
|
|
__func__, output_valid_fifo_threshold, fifo_valid_size);
|
|
|
|
DISP_REG_SET(handle, idx * DISP_RDMA_INDEX_OFFSET +
|
|
DISP_REG_RDMA_FIFO_CON,
|
|
REG_FLD_VAL(FIFO_CON_FLD_OUTPUT_VALID_FIFO_THRESHOLD,
|
|
output_valid_fifo_threshold) |
|
|
REG_FLD_VAL(FIFO_CON_FLD_FIFO_PSEUDO_SIZE,
|
|
fifo_valid_size) |
|
|
REG_FLD_VAL(FIFO_CON_FLD_FIFO_UNDERFLOW_EN,
|
|
1));
|
|
|
|
DISP_REG_SET(handle, idx * DISP_RDMA_INDEX_OFFSET +
|
|
DISP_REG_RDMA_THRESHOLD_FOR_SODI,
|
|
sodi_threshold_low | (sodi_threshold_high << 16));
|
|
|
|
DISP_REG_SET(handle, idx * DISP_RDMA_INDEX_OFFSET +
|
|
DISP_REG_RDMA_THRESHOLD_FOR_DVFS,
|
|
dvfs_threshold_low | (dvfs_threshold_high << 16));
|
|
|
|
/*DISP_REG_RDMA_DRAM_CON*/
|
|
DISP_REG_SET(handle, idx * DISP_RDMA_INDEX_OFFSET +
|
|
DISP_REG_RDMA_DRAM_CON,
|
|
REG_FLD_VAL(DRAM_CON_FLD_FORCE_GCLAST_0, 0) |
|
|
REG_FLD_VAL(DRAM_CON_FLD_BANK_BOUNDARY_SEL, 1));
|
|
|
|
/*DISP_RDMA_DVFS_SETTING_PREULTRA*/
|
|
dvfs_preultra_low = (preultra_low_us + fifo_off_ultra + fifo_off_dvfs)
|
|
* consume_rate_div;
|
|
|
|
dvfs_preultra_high = (preultra_high_us + fifo_off_ultra + fifo_off_dvfs)
|
|
* consume_rate_div;
|
|
|
|
dvfs_ultra_low = (ultra_low_us + fifo_off_ultra + fifo_off_dvfs)
|
|
* consume_rate_div;
|
|
|
|
dvfs_ultra_high = dvfs_preultra_low;
|
|
DISP_REG_SET(handle, idx * DISP_RDMA_INDEX_OFFSET +
|
|
DISP_REG_RDMA_DVFS_SETTING_PRE,
|
|
dvfs_preultra_low | (dvfs_preultra_high << 16));
|
|
|
|
DISP_REG_SET(handle, idx * DISP_RDMA_INDEX_OFFSET +
|
|
DISP_REG_RDMA_DVFS_SETTING_ULTRA,
|
|
dvfs_ultra_low | (dvfs_ultra_high << 16));
|
|
|
|
/*DISP_REG_RDMA_LEAVE_DRS_SETTING*/
|
|
urgent_low = urgent_low_us * consume_rate_div;
|
|
urgent_low = DIV_ROUND_UP(urgent_low, 10);
|
|
|
|
urgent_high = urgent_high_us * consume_rate_div;
|
|
urgent_high = DIV_ROUND_UP(urgent_high, 10);
|
|
|
|
DISP_REG_SET(handle, idx * DISP_RDMA_INDEX_OFFSET +
|
|
DISP_REG_RDMA_LEAVE_DRS_SETTING,
|
|
urgent_low | (urgent_high << 16));
|
|
|
|
DISP_REG_SET(handle, idx * DISP_RDMA_INDEX_OFFSET +
|
|
DISP_REG_RDMA_ENTER_DRS_SETTING,
|
|
urgent_low | (urgent_high << 16));
|
|
|
|
DISP_REG_SET(handle, idx * DISP_RDMA_INDEX_OFFSET +
|
|
DISP_REG_RDMA_MEM_GMC_SETTING_3,
|
|
urgent_low | (urgent_high << 16));
|
|
|
|
/* only config RDMA0 SRAM_SEL */
|
|
if (idx == 0) {
|
|
if (is_wrot_sram)
|
|
DISP_REG_SET(handle, DISP_REG_RDMA_SRAM_SEL, 1);
|
|
else if (is_rsz_sram)
|
|
DISP_REG_SET(handle, DISP_REG_RDMA_SRAM_SEL, 2);
|
|
else
|
|
DISP_REG_SET(handle, DISP_REG_RDMA_SRAM_SEL, 0);
|
|
}
|
|
|
|
#if 0
|
|
if (idx == 0)
|
|
rdma_dump_golden_setting_context(DISP_MODULE_RDMA0);
|
|
else
|
|
rdma_dump_golden_setting_context(DISP_MODULE_RDMA1);
|
|
#endif
|
|
/* dump golden settings info */
|
|
{
|
|
DDPDBG("==RDMA Golden Setting Value=============\n");
|
|
DDPDBG("width = %d\n",
|
|
rdma_golden_setting->dst_width);
|
|
DDPDBG("height = %d\n",
|
|
rdma_golden_setting->dst_height);
|
|
DDPDBG("bpp = %d\n", bpp);
|
|
DDPDBG("frame_rate = %d\n", frame_rate);
|
|
DDPDBG("fill_rate = %lld\n", fill_rate);
|
|
DDPDBG("consume_rate = %lld\n", consume_rate);
|
|
DDPDBG("ultra_low_us = %d\n", ultra_low_us);
|
|
DDPDBG("ultra_high_us = %d\n", ultra_high_us);
|
|
DDPDBG("preultra_high_us = %d\n", preultra_high_us);
|
|
DDPDBG("urgent_low_us = %d\n", urgent_low_us);
|
|
DDPDBG("urgent_high_us = %d\n", urgent_high_us);
|
|
DDPDBG("preultra_threshold_low = %d\n", preultra_low);
|
|
DDPDBG("preultra_threshold_high = %d\n", preultra_high);
|
|
DDPDBG("ultra_threshold_low = %d\n", ultra_low);
|
|
DDPDBG("ultra_threshold_high = %d\n", ultra_low);
|
|
DDPDBG("issue_req_threshold = %d\n", issue_req_threshold);
|
|
DDPDBG("output_valid_fifo_threshold = %d\n",
|
|
output_valid_fifo_threshold);
|
|
DDPDBG("fifo_valid_size = %d\n", fifo_valid_size);
|
|
DDPDBG("sodi_threshold_low = %d\n", sodi_threshold_low);
|
|
DDPDBG("sodi_threshold_high = %d\n", sodi_threshold_high);
|
|
DDPDBG("dvfs_threshold_low = %d\n", dvfs_threshold_low);
|
|
DDPDBG("dvfs_threshold_high = %d\n", dvfs_threshold_high);
|
|
DDPDBG("dvfs_preultra_low = %d\n", dvfs_preultra_low);
|
|
DDPDBG("dvfs_preultra_high = %d\n", dvfs_preultra_high);
|
|
DDPDBG("dvfs_ultra_low = %d\n", dvfs_ultra_low);
|
|
DDPDBG("dvfs_ultra_high = %d\n", dvfs_ultra_high);
|
|
DDPDBG("drs_enter = %d\n", drs_enter);
|
|
DDPDBG("drs_leave = %d\n", drs_leave);
|
|
DDPDBG("urgent_low = %d\n", urgent_low);
|
|
DDPDBG("urgent_high = %d\n", urgent_high);
|
|
}
|
|
}
|
|
|
|
#endif
|
|
|
|
static int rdma_config(enum DISP_MODULE_ENUM module, enum RDMA_MODE mode,
|
|
unsigned long address, enum UNIFIED_COLOR_FMT inFormat,
|
|
unsigned int pitch, unsigned int width, unsigned int height,
|
|
unsigned int ufoe_enable, enum DISP_BUFFER_TYPE sec,
|
|
unsigned int yuv_range, struct rdma_bg_ctrl_t *bg_ctrl,
|
|
void *handle, struct golden_setting_context *p_golden_setting,
|
|
unsigned int bpp)
|
|
{
|
|
unsigned int output_is_yuv = 0;
|
|
unsigned int input_is_yuv = !UFMT_GET_RGB(inFormat);
|
|
unsigned int input_swap = UFMT_GET_BYTESWAP(inFormat);
|
|
unsigned int input_format_reg = UFMT_GET_FORMAT(inFormat);
|
|
unsigned int idx = rdma_index(module);
|
|
unsigned int color_matrix;
|
|
unsigned int regval, offset;
|
|
|
|
DDPDBG("%s:%s,mode:%s,addr:0x%lx,fmt:%s,pitch:%u,wxh(%ux%u),sec:%d\n",
|
|
__func__, ddp_get_module_name(module), mode ? "MEM" : "DL",
|
|
address, unified_color_fmt_name(inFormat), pitch,
|
|
width, height, sec);
|
|
|
|
ASSERT(idx <= RDMA_INSTANCES);
|
|
if ((width > RDMA_MAX_WIDTH) || (height > RDMA_MAX_HEIGHT))
|
|
DDPERR("RDMA input overflow, w=%d, h=%d, max_w=%d, max_h=%d\n",
|
|
width, height, RDMA_MAX_WIDTH, RDMA_MAX_HEIGHT);
|
|
|
|
offset = idx * DISP_RDMA_INDEX_OFFSET;
|
|
if (input_is_yuv == 1 && output_is_yuv == 0) {
|
|
switch (yuv_range) {
|
|
case 0:
|
|
color_matrix = 4;
|
|
break; /* BT601_full */
|
|
case 1:
|
|
color_matrix = 6;
|
|
break; /* BT601 */
|
|
case 2:
|
|
color_matrix = 7;
|
|
break; /* BT709 */
|
|
default:
|
|
DDPERR("%s,un-recognized yuv_range=%d!\n",
|
|
__func__, yuv_range);
|
|
color_matrix = 4;
|
|
break;
|
|
}
|
|
|
|
DISP_REG_SET_FIELD(handle, SIZE_CON_0_FLD_MATRIX_ENABLE,
|
|
offset + DISP_REG_RDMA_SIZE_CON_0, 1);
|
|
DISP_REG_SET_FIELD(handle, SIZE_CON_0_FLD_MATRIX_INT_MTX_SEL,
|
|
offset + DISP_REG_RDMA_SIZE_CON_0, color_matrix);
|
|
} else if (input_is_yuv == 0 && output_is_yuv == 1) {
|
|
color_matrix = 0x2; /* 0x0010, RGB_TO_BT601 */
|
|
DISP_REG_SET_FIELD(handle, SIZE_CON_0_FLD_MATRIX_ENABLE,
|
|
offset + DISP_REG_RDMA_SIZE_CON_0, 1);
|
|
DISP_REG_SET_FIELD(handle, SIZE_CON_0_FLD_MATRIX_INT_MTX_SEL,
|
|
offset + DISP_REG_RDMA_SIZE_CON_0, color_matrix);
|
|
} else {
|
|
DISP_REG_SET_FIELD(handle, SIZE_CON_0_FLD_MATRIX_ENABLE,
|
|
offset + DISP_REG_RDMA_SIZE_CON_0, 0);
|
|
DISP_REG_SET_FIELD(handle, SIZE_CON_0_FLD_MATRIX_INT_MTX_SEL,
|
|
offset + DISP_REG_RDMA_SIZE_CON_0, 0);
|
|
}
|
|
|
|
DISP_REG_SET_FIELD(handle, GLOBAL_CON_FLD_MODE_SEL,
|
|
offset + DISP_REG_RDMA_GLOBAL_CON, mode);
|
|
DISP_REG_SET_FIELD(handle, MEM_CON_FLD_MEM_MODE_INPUT_FORMAT,
|
|
offset + DISP_REG_RDMA_MEM_CON,
|
|
(mode == RDMA_MODE_DIRECT_LINK) ? 0 : input_format_reg & 0xf);
|
|
DISP_REG_SET_FIELD(handle, MEM_CON_FLD_MEM_MODE_INPUT_SWAP,
|
|
offset + DISP_REG_RDMA_MEM_CON,
|
|
((mode == RDMA_MODE_DIRECT_LINK) ? 0 : input_swap));
|
|
|
|
if (sec != DISP_SECURE_BUFFER) {
|
|
DISP_REG_SET(handle, offset + DISP_REG_RDMA_MEM_START_ADDR,
|
|
address);
|
|
} else {
|
|
int m4u_port;
|
|
unsigned int size = pitch * height;
|
|
|
|
m4u_port = DISP_M4U_PORT_DISP_RDMA0;
|
|
/*
|
|
* for sec layer, addr variable stores sec handle
|
|
* we need to pass this handle and offset to cmdq driver
|
|
* cmdq sec driver will help to convert handle to
|
|
* correct address
|
|
*/
|
|
cmdqRecWriteSecure(handle,
|
|
disp_addr_convert(
|
|
offset + DISP_REG_RDMA_MEM_START_ADDR),
|
|
CMDQ_SAM_H_2_MVA, address, 0, size, m4u_port);
|
|
}
|
|
|
|
DISP_REG_SET(handle, offset + DISP_REG_RDMA_MEM_SRC_PITCH, pitch);
|
|
DISP_REG_SET_FIELD(handle, SIZE_CON_0_FLD_OUTPUT_FRAME_WIDTH,
|
|
offset + DISP_REG_RDMA_SIZE_CON_0, width);
|
|
DISP_REG_SET_FIELD(handle, SIZE_CON_1_FLD_OUTPUT_FRAME_HEIGHT,
|
|
offset + DISP_REG_RDMA_SIZE_CON_1, height);
|
|
|
|
/* rdma bg control */
|
|
regval = REG_FLD_VAL(RDMA_BG_CON_0_LEFT, bg_ctrl->left);
|
|
regval |= REG_FLD_VAL(RDMA_BG_CON_0_RIGHT, bg_ctrl->right);
|
|
DISP_REG_SET(handle, offset + DISP_REG_RDMA_BG_CON_0, regval);
|
|
|
|
regval = REG_FLD_VAL(RDMA_BG_CON_1_TOP, bg_ctrl->top);
|
|
regval |= REG_FLD_VAL(RDMA_BG_CON_1_BOTTOM, bg_ctrl->bottom);
|
|
DISP_REG_SET(handle, offset + DISP_REG_RDMA_BG_CON_1, regval);
|
|
|
|
set_rdma_width_height(width, height);
|
|
rdma_set_ultra_l(idx, bpp, handle, p_golden_setting);
|
|
|
|
return 0;
|
|
}
|
|
|
|
int rdma_clock_on(enum DISP_MODULE_ENUM module, void *handle)
|
|
{
|
|
ddp_clk_prepare_enable(ddp_get_module_clk_id(module));
|
|
return 0;
|
|
}
|
|
|
|
int rdma_clock_off(enum DISP_MODULE_ENUM module, void *handle)
|
|
{
|
|
ddp_clk_disable_unprepare(ddp_get_module_clk_id(module));
|
|
return 0;
|
|
}
|
|
|
|
void rdma_dump_golden_setting_context(enum DISP_MODULE_ENUM module)
|
|
{
|
|
if (!rdma_golden_setting)
|
|
return;
|
|
|
|
DDPDUMP("-- RDMA Golden Setting Context --\n");
|
|
DDPDUMP("fifo_mode=%d\n", rdma_golden_setting->fifo_mode);
|
|
DDPDUMP("hrt_num=%d\n", rdma_golden_setting->hrt_num);
|
|
DDPDUMP("is_display_idle=%d\n",
|
|
rdma_golden_setting->is_display_idle);
|
|
DDPDUMP("is_wrot_sram=%d\n", rdma_golden_setting->is_wrot_sram);
|
|
DDPDUMP("is_rsz_sram=%d\n", rdma_golden_setting->is_rsz_sram);
|
|
DDPDUMP("is_dc=%d\n", rdma_golden_setting->is_dc);
|
|
DDPDUMP("mmsys_clk=%d\n", rdma_golden_setting->mmsys_clk);
|
|
DDPDUMP("fps=%d\n", rdma_golden_setting->fps);
|
|
DDPDUMP("is_one_layer=%d\n", rdma_golden_setting->is_one_layer);
|
|
DDPDUMP("rdma_width=%d\n", rdma_golden_setting->dst_width);
|
|
DDPDUMP("rdma_height=%d\n", rdma_golden_setting->dst_height);
|
|
}
|
|
|
|
void rdma_dump_reg(enum DISP_MODULE_ENUM module)
|
|
{
|
|
unsigned int idx = rdma_index(module);
|
|
unsigned int offset = DISP_RDMA_INDEX_OFFSET * idx;
|
|
|
|
DDPDUMP("== DISP RDMA%d REGS ==\n", idx);
|
|
DDPDUMP("(0x000)R_INTEN=0x%x\n",
|
|
DISP_REG_GET(DISP_REG_RDMA_INT_ENABLE + offset));
|
|
DDPDUMP("(0x004)R_INTS=0x%x\n",
|
|
DISP_REG_GET(DISP_REG_RDMA_INT_STATUS + offset));
|
|
DDPDUMP("(0x010)R_CON=0x%x\n",
|
|
DISP_REG_GET(DISP_REG_RDMA_GLOBAL_CON + offset));
|
|
DDPDUMP("(0x014)R_SIZE0=0x%x\n",
|
|
DISP_REG_GET(DISP_REG_RDMA_SIZE_CON_0 + offset));
|
|
DDPDUMP("(0x018)R_SIZE1=0x%x\n",
|
|
DISP_REG_GET(DISP_REG_RDMA_SIZE_CON_1 + offset));
|
|
DDPDUMP("(0x01c)R_TAR_LINE=0x%x\n",
|
|
DISP_REG_GET(DISP_REG_RDMA_TARGET_LINE + offset));
|
|
DDPDUMP("(0x024)R_M_CON=0x%x\n",
|
|
DISP_REG_GET(DISP_REG_RDMA_MEM_CON + offset));
|
|
DDPDUMP("(0xf00)R_M_S_ADDR=0x%x\n",
|
|
DISP_REG_GET(DISP_REG_RDMA_MEM_START_ADDR + offset));
|
|
DDPDUMP("(0x02c)R_M_SRC_PITCH=0x%x\n",
|
|
DISP_REG_GET(DISP_REG_RDMA_MEM_SRC_PITCH + offset));
|
|
DDPDUMP("(0x030)R_M_GMC_SET0=0x%x\n",
|
|
DISP_REG_GET(DISP_REG_RDMA_MEM_GMC_SETTING_0 + offset));
|
|
DDPDUMP("(0x034)R_M_GMC_SET1=0x%x\n",
|
|
DISP_REG_GET(DISP_REG_RDMA_MEM_GMC_SETTING_1 + offset));
|
|
DDPDUMP("(0x038)R_M_SLOW_CON=0x%x\n",
|
|
DISP_REG_GET(DISP_REG_RDMA_MEM_SLOW_CON + offset));
|
|
DDPDUMP("(0x03c)R_M_GMC_SET2=0x%x\n",
|
|
DISP_REG_GET(DISP_REG_RDMA_MEM_GMC_SETTING_2 + offset));
|
|
DDPDUMP("(0x040)R_FIFO_CON=0x%x\n",
|
|
DISP_REG_GET(DISP_REG_RDMA_FIFO_CON + offset));
|
|
DDPDUMP("(0x044)R_FIFO_LOG=0x%x\n",
|
|
DISP_REG_GET(DISP_REG_RDMA_FIFO_LOG + offset));
|
|
DDPDUMP("(0x078)R_PRE_ADD0=0x%x\n",
|
|
DISP_REG_GET(DISP_REG_RDMA_PRE_ADD_0 + offset));
|
|
DDPDUMP("(0x07c)R_PRE_ADD1=0x%x\n",
|
|
DISP_REG_GET(DISP_REG_RDMA_PRE_ADD_1 + offset));
|
|
DDPDUMP("(0x080)R_PRE_ADD2=0x%x\n",
|
|
DISP_REG_GET(DISP_REG_RDMA_PRE_ADD_2 + offset));
|
|
DDPDUMP("(0x084)R_POST_ADD0=0x%x\n",
|
|
DISP_REG_GET(DISP_REG_RDMA_POST_ADD_0 + offset));
|
|
DDPDUMP("(0x088)R_POST_ADD1=0x%x\n",
|
|
DISP_REG_GET(DISP_REG_RDMA_POST_ADD_1 + offset));
|
|
DDPDUMP("(0x08c)R_POST_ADD2=0x%x\n",
|
|
DISP_REG_GET(DISP_REG_RDMA_POST_ADD_2 + offset));
|
|
DDPDUMP("(0x090)R_DUMMY=0x%x\n",
|
|
DISP_REG_GET(DISP_REG_RDMA_DUMMY + offset));
|
|
DDPDUMP("(0x094)R_OUT_SEL=0x%x\n",
|
|
DISP_REG_GET(DISP_REG_RDMA_DEBUG_OUT_SEL + offset));
|
|
DDPDUMP("(0x094)R_M_START=0x%x\n",
|
|
DISP_REG_GET(DISP_REG_RDMA_MEM_START_ADDR + offset));
|
|
DDPDUMP("(0x0a0)R_BG_CON_0=0x%x\n",
|
|
DISP_REG_GET(DISP_REG_RDMA_BG_CON_0 + offset));
|
|
DDPDUMP("(0x0a4)R_BG_CON_1=0x%x\n",
|
|
DISP_REG_GET(DISP_REG_RDMA_BG_CON_1 + offset));
|
|
DDPDUMP("(0x0a8)R_FOR_SODI=0x%x\n",
|
|
DISP_REG_GET(DISP_REG_RDMA_THRESHOLD_FOR_SODI + offset));
|
|
DDPDUMP("(0x0ac)R_FOR_DVFS=0x%x\n",
|
|
DISP_REG_GET(DISP_REG_RDMA_THRESHOLD_FOR_DVFS + offset));
|
|
DDPDUMP("(0x0b0)R_FOR_SRAM=0x%x\n",
|
|
DISP_REG_GET(DISP_REG_RDMA_SRAM_SEL + offset));
|
|
DDPDUMP("(0x0b4)DISP_REG_RDMA_STALL_CG_CON=0x%x\n",
|
|
DISP_REG_GET(DISP_REG_RDMA_STALL_CG_CON + offset));
|
|
DDPDUMP("(0x0b8)DISP_REG_RDMA_SHADOW_UPDATE=0x%x\n",
|
|
DISP_REG_GET(DISP_REG_RDMA_SHADOW_UPDATE + offset));
|
|
DDPDUMP("(0x0c0)R_DRAM_CON=0x%x\n",
|
|
DISP_REG_GET(DISP_REG_RDMA_DRAM_CON + offset));
|
|
DDPDUMP("(0x0d0)R_DVFS_SETTING_PRE=0x%x\n",
|
|
DISP_REG_GET(DISP_REG_RDMA_DVFS_SETTING_PRE + offset));
|
|
DDPDUMP("(0x0d4)R_DVFS_SETTING_ULTRA=0x%x\n",
|
|
DISP_REG_GET(DISP_REG_RDMA_DVFS_SETTING_ULTRA + offset));
|
|
DDPDUMP("(0x0d8)R_LEAVE_DRS_SETTING=0x%x\n",
|
|
DISP_REG_GET(DISP_REG_RDMA_LEAVE_DRS_SETTING + offset));
|
|
DDPDUMP("(0x0dc)R_ENTER_DRS_SETTING=0x%x\n",
|
|
DISP_REG_GET(DISP_REG_RDMA_ENTER_DRS_SETTING + offset));
|
|
DDPDUMP("(0x0e8)R_M_GMC_SET3=0x%x\n",
|
|
DISP_REG_GET(DISP_REG_RDMA_MEM_GMC_SETTING_3 + offset));
|
|
DDPDUMP("(0x0f0)R_IN_PXL_CNT=0x%x\n",
|
|
DISP_REG_GET(DISP_REG_RDMA_IN_P_CNT + offset));
|
|
DDPDUMP("(0x0f4)R_IN_LINE_CNT=0x%x\n",
|
|
DISP_REG_GET(DISP_REG_RDMA_IN_LINE_CNT + offset));
|
|
DDPDUMP("(0x0f8)R_OUT_PXL_CNT=0x%x\n",
|
|
DISP_REG_GET(DISP_REG_RDMA_OUT_P_CNT + offset));
|
|
DDPDUMP("(0x0fc)R_OUT_LINE_CNT=0x%x\n",
|
|
DISP_REG_GET(DISP_REG_RDMA_OUT_LINE_CNT + offset));
|
|
}
|
|
|
|
void rdma_dump_analysis(enum DISP_MODULE_ENUM module)
|
|
{
|
|
unsigned int idx = rdma_index(module);
|
|
unsigned int offset = idx * DISP_RDMA_INDEX_OFFSET;
|
|
unsigned int global_ctrl;
|
|
unsigned int bg0 = DISP_REG_GET(offset + DISP_REG_RDMA_BG_CON_0);
|
|
unsigned int bg1 = DISP_REG_GET(offset + DISP_REG_RDMA_BG_CON_1);
|
|
|
|
global_ctrl = DISP_REG_GET(DISP_REG_RDMA_GLOBAL_CON + offset);
|
|
DDPDUMP("== DISP RDMA%d ANALYSIS ==\n", idx);
|
|
DDPDUMP("rdma%d: en=%d,memory_mode=%d,smi_busy=%d\n",
|
|
idx, REG_FLD_VAL_GET(GLOBAL_CON_FLD_ENGINE_EN + offset,
|
|
global_ctrl),
|
|
REG_FLD_VAL_GET(GLOBAL_CON_FLD_MODE_SEL + offset, global_ctrl),
|
|
REG_FLD_VAL_GET(GLOBAL_CON_FLD_SMI_BUSY + offset, global_ctrl));
|
|
DDPDUMP("rdma%d: w=%d,h=%d,pitch=%d,addr=0x%x,fmt=%s,fifo_min=%d\n",
|
|
idx, DISP_REG_GET(DISP_REG_RDMA_SIZE_CON_0 + offset) & 0xfff,
|
|
DISP_REG_GET(DISP_REG_RDMA_SIZE_CON_1 + offset) & 0xfffff,
|
|
DISP_REG_GET(DISP_REG_RDMA_MEM_SRC_PITCH + offset),
|
|
DISP_REG_GET(DISP_REG_RDMA_MEM_START_ADDR + offset),
|
|
unified_color_fmt_name(
|
|
display_fmt_reg_to_unified_fmt(
|
|
(DISP_REG_GET(DISP_REG_RDMA_MEM_CON +
|
|
offset) >> 4) & 0xf,
|
|
(DISP_REG_GET(DISP_REG_RDMA_MEM_CON +
|
|
offset) >> 8) & 0x1, 0)),
|
|
DISP_REG_GET(DISP_REG_RDMA_FIFO_LOG + offset));
|
|
DDPDUMP("in_p=%d,in_l=%d,out_p=%d,out_l=%d,bg(t%d,b%d,l%d,r%d)\n",
|
|
DISP_REG_GET(DISP_REG_RDMA_IN_P_CNT + offset),
|
|
DISP_REG_GET(DISP_REG_RDMA_IN_LINE_CNT + offset),
|
|
DISP_REG_GET(DISP_REG_RDMA_OUT_P_CNT + offset),
|
|
DISP_REG_GET(DISP_REG_RDMA_OUT_LINE_CNT + offset),
|
|
REG_FLD_VAL_GET(RDMA_BG_CON_1_TOP + offset, bg1),
|
|
REG_FLD_VAL_GET(RDMA_BG_CON_1_BOTTOM + offset, bg1),
|
|
REG_FLD_VAL_GET(RDMA_BG_CON_0_LEFT + offset, bg0),
|
|
REG_FLD_VAL_GET(RDMA_BG_CON_0_RIGHT + offset, bg0));
|
|
DDPDUMP("start=%lld ns,end=%lld ns\n",
|
|
rdma_start_time[idx], rdma_end_time[idx]);
|
|
DDPDUMP("irq cnt: start=%d, end=%d, underflow=%d, targetline=%d\n",
|
|
rdma_start_irq_cnt[idx], rdma_done_irq_cnt[idx],
|
|
rdma_underflow_irq_cnt[idx], rdma_targetline_irq_cnt[idx]);
|
|
|
|
rdma_dump_golden_setting_context(module);
|
|
}
|
|
|
|
static int rdma_dump(enum DISP_MODULE_ENUM module, int level)
|
|
{
|
|
rdma_dump_analysis(module);
|
|
rdma_dump_reg(module);
|
|
|
|
return 0;
|
|
}
|
|
|
|
void rdma_get_info(int idx, struct RDMA_BASIC_STRUCT *info)
|
|
{
|
|
struct RDMA_BASIC_STRUCT *p = info;
|
|
unsigned int offset = idx * DISP_RDMA_INDEX_OFFSET;
|
|
|
|
p->addr = DISP_REG_GET(DISP_REG_RDMA_MEM_START_ADDR + offset);
|
|
p->src_w = DISP_REG_GET(DISP_REG_RDMA_SIZE_CON_0 + offset) & 0xfff;
|
|
p->src_h = DISP_REG_GET(DISP_REG_RDMA_SIZE_CON_1 + offset) & 0xfffff;
|
|
p->bpp = UFMT_GET_bpp(display_fmt_reg_to_unified_fmt(
|
|
(DISP_REG_GET(DISP_REG_RDMA_MEM_CON +
|
|
offset) >> 4) & 0xf,
|
|
(DISP_REG_GET(DISP_REG_RDMA_MEM_CON +
|
|
offset) >> 8) & 0x1, 0)) / 8;
|
|
}
|
|
|
|
static inline enum RDMA_MODE get_rdma_mode(enum DISP_MODULE_ENUM module)
|
|
{
|
|
unsigned int idx = rdma_index(module);
|
|
|
|
return DISP_REG_GET_FIELD(GLOBAL_CON_FLD_MODE_SEL,
|
|
(DISP_RDMA_INDEX_OFFSET * idx) + DISP_REG_RDMA_GLOBAL_CON);
|
|
}
|
|
|
|
static inline enum RDMA_MODE rdma_config_mode(unsigned long address)
|
|
{
|
|
return address ? RDMA_MODE_MEMORY : RDMA_MODE_DIRECT_LINK;
|
|
}
|
|
|
|
static int do_rdma_config_l(enum DISP_MODULE_ENUM module,
|
|
struct disp_ddp_path_config *pConfig, void *handle)
|
|
{
|
|
struct RDMA_CONFIG_STRUCT *r_config = &pConfig->rdma_config;
|
|
enum RDMA_MODE mode = rdma_config_mode(r_config->address);
|
|
struct LCM_PARAMS *lcm_param = &(pConfig->dispif_config);
|
|
unsigned int width;
|
|
unsigned int height;
|
|
struct golden_setting_context *p_golden_setting;
|
|
enum UNIFIED_COLOR_FMT inFormat = r_config->inputFormat;
|
|
enum UNIFIED_COLOR_FMT bwFormat;
|
|
unsigned int bwBpp;
|
|
unsigned long long rdma_bw;
|
|
|
|
width = pConfig->dst_dirty ? pConfig->dst_w : r_config->width;
|
|
height = pConfig->dst_dirty ? pConfig->dst_h : r_config->height;
|
|
p_golden_setting = pConfig->p_golden_setting_context;
|
|
|
|
if (pConfig->fps)
|
|
rdma_fps[rdma_index(module)] = pConfig->fps / 100;
|
|
|
|
if (mode == RDMA_MODE_DIRECT_LINK &&
|
|
r_config->security != DISP_NORMAL_BUFFER)
|
|
DDPERR("%s: rdma directlink BUT is sec ??!!\n", __func__);
|
|
|
|
if (mode == RDMA_MODE_DIRECT_LINK) {
|
|
pConfig->rdma_config.bg_ctrl.top = 0;
|
|
pConfig->rdma_config.bg_ctrl.bottom = 0;
|
|
pConfig->rdma_config.bg_ctrl.left = 0;
|
|
pConfig->rdma_config.bg_ctrl.right = 0;
|
|
} else if (mode == RDMA_MODE_MEMORY) {
|
|
pConfig->rdma_config.bg_ctrl.top = r_config->dst_y;
|
|
pConfig->rdma_config.bg_ctrl.bottom = r_config->dst_h -
|
|
r_config->dst_y - height;
|
|
pConfig->rdma_config.bg_ctrl.left = r_config->dst_x;
|
|
pConfig->rdma_config.bg_ctrl.right = r_config->dst_w -
|
|
r_config->dst_x - width;
|
|
}
|
|
DDPDBG("top=%d,bottom=%d,left=%d,right=%d\n",
|
|
pConfig->rdma_config.bg_ctrl.top,
|
|
pConfig->rdma_config.bg_ctrl.bottom,
|
|
pConfig->rdma_config.bg_ctrl.left,
|
|
pConfig->rdma_config.bg_ctrl.right);
|
|
DDPDBG("r.dst_x=%d,r.dst_y=%d,r.dst_w=%d,r.dst_h=%d,w=%d,h=%d\n",
|
|
r_config->dst_x, r_config->dst_y,
|
|
r_config->dst_w,
|
|
r_config->dst_h, width, height);
|
|
/*PARGB,etc need convert ARGB,etc*/
|
|
ufmt_disable_P(r_config->inputFormat, &inFormat);
|
|
rdma_config(module,
|
|
mode,
|
|
(mode == RDMA_MODE_DIRECT_LINK) ? 0 : r_config->address,
|
|
(mode == RDMA_MODE_DIRECT_LINK) ? UFMT_RGB888 : inFormat,
|
|
(mode == RDMA_MODE_DIRECT_LINK) ? 0 : r_config->pitch,
|
|
width,
|
|
height,
|
|
lcm_param->dsi.ufoe_enable,
|
|
r_config->security, r_config->yuv_range, &(r_config->bg_ctrl),
|
|
handle, p_golden_setting, pConfig->lcm_bpp);
|
|
|
|
/* calculate bandwidth */
|
|
bwFormat = (mode == RDMA_MODE_DIRECT_LINK) ? UFMT_RGB888 : inFormat;
|
|
bwBpp = ufmt_get_Bpp(bwFormat);
|
|
rdma_bw = (unsigned long long)width * height * bwBpp;
|
|
do_div(rdma_bw, 1000);
|
|
rdma_bw *= 1250;
|
|
do_div(rdma_bw, 1000);
|
|
DDPDBG("R:width=%u,height=%u,Bpp:%u,bw:%llu\n",
|
|
width, height, bwBpp, rdma_bw);
|
|
|
|
/* bandwidth report */
|
|
if (module == DISP_MODULE_RDMA0)
|
|
DISP_SLOT_SET(handle, DISPSYS_SLOT_BASE,
|
|
DISP_SLOT_RDMA0_BW, (unsigned int)rdma_bw);
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int rdma_is_sec[2];
|
|
|
|
static inline int rdma_switch_to_sec(enum DISP_MODULE_ENUM module,
|
|
void *handle)
|
|
{
|
|
unsigned int rdma_idx = rdma_index(module);
|
|
enum CMDQ_ENG_ENUM cmdq_engine;
|
|
|
|
cmdq_engine = rdma_to_cmdq_engine(module);
|
|
cmdqRecSetSecure(handle, 1);
|
|
/* set engine as sec port */
|
|
cmdqRecSecureEnablePortSecurity(handle, (1LL << cmdq_engine));
|
|
/* cmdqRecSecureEnableDAPC(handle, (1LL << cmdq_engine)); */
|
|
if (rdma_is_sec[rdma_idx] == 0) {
|
|
DDPSVPMSG("[SVP] switch rdma%d to sec\n", rdma_idx);
|
|
mmprofile_log_ex(ddp_mmp_get_events()->svp_module[module],
|
|
MMPROFILE_FLAG_START, 0, 0);
|
|
}
|
|
rdma_is_sec[rdma_idx] = 1;
|
|
|
|
return 0;
|
|
}
|
|
|
|
int rdma_switch_to_nonsec(enum DISP_MODULE_ENUM module,
|
|
struct disp_ddp_path_config *pConfig, void *handle)
|
|
{
|
|
unsigned int rdma_idx = rdma_index(module);
|
|
|
|
enum CMDQ_ENG_ENUM cmdq_engine;
|
|
|
|
cmdq_engine = rdma_to_cmdq_engine(module);
|
|
if (rdma_is_sec[rdma_idx] == 1) {
|
|
/* rdma is in sec stat, we need to switch it to nonsec */
|
|
struct cmdqRecStruct *nonsec_switch_handle;
|
|
int ret;
|
|
|
|
ret = cmdqRecCreate(
|
|
CMDQ_SCENARIO_DISP_PRIMARY_DISABLE_SECURE_PATH,
|
|
&(nonsec_switch_handle));
|
|
if (ret)
|
|
DDPAEE("[SVP]fail to create disable handle %s ret=%d\n",
|
|
__func__, ret);
|
|
|
|
cmdqRecReset(nonsec_switch_handle);
|
|
|
|
if (rdma_idx == 0) {
|
|
/* Primary Decouple Mode */
|
|
_cmdq_insert_wait_frame_done_token_mira(
|
|
nonsec_switch_handle);
|
|
} else {
|
|
/* External Mode */
|
|
/* ovl1->Rdma1, do not used. */
|
|
_cmdq_insert_wait_frame_done_token_mira(
|
|
nonsec_switch_handle);
|
|
}
|
|
|
|
cmdqRecSetSecure(nonsec_switch_handle, 1);
|
|
/*
|
|
* will remove when cmdq delete disable scenario.
|
|
* To avoid translation fault like ovl (see notes in ovl.c)
|
|
* check the mode now, bypass the frame during DL->DC(),
|
|
* avoid hang when vdo mode.
|
|
*/
|
|
if (get_rdma_mode(module) == RDMA_MODE_MEMORY)
|
|
do_rdma_config_l(module, pConfig, nonsec_switch_handle);
|
|
|
|
/* in fact, dapc/port_sec will be disabled by cmdq */
|
|
cmdqRecSecureEnablePortSecurity(nonsec_switch_handle,
|
|
(1LL << cmdq_engine));
|
|
if (handle != NULL) {
|
|
/* Async Flush method */
|
|
enum CMDQ_EVENT_ENUM cmdq_event_nonsec_end;
|
|
|
|
cmdq_event_nonsec_end =
|
|
rdma_to_cmdq_event_nonsec_end(module);
|
|
cmdqRecSetEventToken(nonsec_switch_handle,
|
|
cmdq_event_nonsec_end);
|
|
cmdqRecFlushAsync(nonsec_switch_handle);
|
|
cmdqRecWait(handle, cmdq_event_nonsec_end);
|
|
} else {
|
|
/* Sync Flush method */
|
|
cmdqRecFlush(nonsec_switch_handle);
|
|
}
|
|
|
|
cmdqRecDestroy(nonsec_switch_handle);
|
|
DDPSVPMSG("[SVP] switch rdma%d to nonsec\n", rdma_idx);
|
|
mmprofile_log_ex(ddp_mmp_get_events()->svp_module[module],
|
|
MMPROFILE_FLAG_END, 0, 0);
|
|
}
|
|
|
|
rdma_is_sec[rdma_idx] = 0;
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int setup_rdma_sec(enum DISP_MODULE_ENUM module,
|
|
struct disp_ddp_path_config *pConfig, void *handle)
|
|
{
|
|
int ret;
|
|
int is_engine_sec = 0;
|
|
|
|
enum RDMA_MODE mode = rdma_config_mode(pConfig->rdma_config.address);
|
|
|
|
if (pConfig->rdma_config.security == DISP_SECURE_BUFFER)
|
|
is_engine_sec = 1;
|
|
|
|
if (!handle) {
|
|
DDPDBG("[SVP] bypass rdma sec setting sec=%d,handle=NULL\n",
|
|
is_engine_sec);
|
|
return 0;
|
|
}
|
|
|
|
/* sec setting make sence only in memory mode ! */
|
|
if (mode == RDMA_MODE_MEMORY) {
|
|
if (is_engine_sec == 1)
|
|
ret = rdma_switch_to_sec(module, handle);
|
|
else
|
|
/* hadle = NULL, use the sync flush method */
|
|
ret = rdma_switch_to_nonsec(module, pConfig, NULL);
|
|
if (ret)
|
|
DDPAEE("[SVP]fail to setup_ovl_sec: %s ret=%d\n",
|
|
__func__, ret);
|
|
}
|
|
|
|
return is_engine_sec;
|
|
}
|
|
|
|
static int rdma_config_l(enum DISP_MODULE_ENUM module,
|
|
struct disp_ddp_path_config *pConfig, void *handle)
|
|
{
|
|
if (pConfig->dst_dirty || pConfig->rdma_dirty) {
|
|
setup_rdma_sec(module, pConfig, handle);
|
|
do_rdma_config_l(module, pConfig, handle);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
void rdma_enable_color_transform(enum DISP_MODULE_ENUM module)
|
|
{
|
|
unsigned int idx = rdma_index(module);
|
|
unsigned int offset = DISP_RDMA_INDEX_OFFSET * idx;
|
|
UINT32 value = DISP_REG_GET(DISP_REG_RDMA_SIZE_CON_0 + offset);
|
|
|
|
value = value |
|
|
REG_FLD_VAL((SIZE_CON_0_FLD_MATRIX_EXT_MTX_EN), 1) |
|
|
REG_FLD_VAL((SIZE_CON_0_FLD_MATRIX_ENABLE), 1);
|
|
DISP_REG_SET(NULL, offset + DISP_REG_RDMA_SIZE_CON_0, value);
|
|
}
|
|
|
|
void rdma_disable_color_transform(enum DISP_MODULE_ENUM module)
|
|
{
|
|
unsigned int idx = rdma_index(module);
|
|
unsigned int offset = DISP_RDMA_INDEX_OFFSET * idx;
|
|
UINT32 value = DISP_REG_GET(DISP_REG_RDMA_SIZE_CON_0 + offset);
|
|
|
|
value = value &
|
|
~(REG_FLD_VAL((SIZE_CON_0_FLD_MATRIX_EXT_MTX_EN), 1) |
|
|
REG_FLD_VAL((SIZE_CON_0_FLD_MATRIX_ENABLE), 1));
|
|
DISP_REG_SET(NULL, offset + DISP_REG_RDMA_SIZE_CON_0, value);
|
|
}
|
|
|
|
void rdma_set_color_matrix(enum DISP_MODULE_ENUM module,
|
|
struct rdma_color_matrix *matrix, struct rdma_color_pre *pre,
|
|
struct rdma_color_post *post)
|
|
{
|
|
unsigned int idx = rdma_index(module);
|
|
unsigned int offset = DISP_RDMA_INDEX_OFFSET * idx;
|
|
|
|
DISP_REG_SET(NULL, offset + DISP_REG_RDMA_C00, matrix->C00);
|
|
DISP_REG_SET(NULL, offset + DISP_REG_RDMA_C01, matrix->C01);
|
|
DISP_REG_SET(NULL, offset + DISP_REG_RDMA_C02, matrix->C02);
|
|
DISP_REG_SET(NULL, offset + DISP_REG_RDMA_C10, matrix->C10);
|
|
DISP_REG_SET(NULL, offset + DISP_REG_RDMA_C11, matrix->C11);
|
|
DISP_REG_SET(NULL, offset + DISP_REG_RDMA_C12, matrix->C12);
|
|
DISP_REG_SET(NULL, offset + DISP_REG_RDMA_C20, matrix->C20);
|
|
DISP_REG_SET(NULL, offset + DISP_REG_RDMA_C21, matrix->C21);
|
|
DISP_REG_SET(NULL, offset + DISP_REG_RDMA_C22, matrix->C22);
|
|
|
|
DISP_REG_SET(NULL, offset + DISP_REG_RDMA_PRE_ADD_0, pre->ADD0);
|
|
DISP_REG_SET(NULL, offset + DISP_REG_RDMA_PRE_ADD_1, pre->ADD1);
|
|
DISP_REG_SET(NULL, offset + DISP_REG_RDMA_PRE_ADD_2, pre->ADD2);
|
|
|
|
DISP_REG_SET(NULL, offset + DISP_REG_RDMA_POST_ADD_0, post->ADD0);
|
|
DISP_REG_SET(NULL, offset + DISP_REG_RDMA_POST_ADD_1, post->ADD1);
|
|
DISP_REG_SET(NULL, offset + DISP_REG_RDMA_POST_ADD_2, post->ADD2);
|
|
}
|
|
|
|
static int _rdma_partial_update(enum DISP_MODULE_ENUM module, void *arg,
|
|
void *handle)
|
|
{
|
|
struct disp_rect *roi = (struct disp_rect *)arg;
|
|
int width = roi->width;
|
|
int height = roi->height;
|
|
unsigned int idx = rdma_index(module);
|
|
unsigned int offset = DISP_RDMA_INDEX_OFFSET * idx;
|
|
|
|
DISP_REG_SET_FIELD(handle, SIZE_CON_0_FLD_OUTPUT_FRAME_WIDTH,
|
|
offset + DISP_REG_RDMA_SIZE_CON_0, width);
|
|
DISP_REG_SET_FIELD(handle, SIZE_CON_1_FLD_OUTPUT_FRAME_HEIGHT,
|
|
offset + DISP_REG_RDMA_SIZE_CON_1, height);
|
|
return 0;
|
|
}
|
|
|
|
int rdma_ioctl(enum DISP_MODULE_ENUM module, void *cmdq_handle,
|
|
enum DDP_IOCTL_NAME ioctl, unsigned long *params)
|
|
{
|
|
int ret = 0;
|
|
unsigned int idx = rdma_index(module);
|
|
|
|
switch (ioctl) {
|
|
case DDP_RDMA_GOLDEN_SETTING:
|
|
{
|
|
struct disp_ddp_path_config *pConfig;
|
|
struct golden_setting_context *p_golden_setting;
|
|
|
|
pConfig = (struct disp_ddp_path_config *)params;
|
|
p_golden_setting = pConfig->p_golden_setting_context;
|
|
rdma_set_ultra_l(idx, pConfig->lcm_bpp, cmdq_handle,
|
|
p_golden_setting);
|
|
break;
|
|
}
|
|
case DDP_PARTIAL_UPDATE:
|
|
_rdma_partial_update(module, params, cmdq_handle);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
static int rdma_build_cmdq(enum DISP_MODULE_ENUM module, void *handle,
|
|
enum CMDQ_STATE state)
|
|
{
|
|
if (handle == NULL) {
|
|
DDPERR("cmdq_trigger_handle is NULL\n");
|
|
return -1;
|
|
}
|
|
if (state == CMDQ_RESET_AFTER_STREAM_EOF) {
|
|
/*
|
|
* if rdma frame done with underflow,
|
|
* rdma will hold dvfs request forever
|
|
* we reset here to solve this issue
|
|
*/
|
|
|
|
/*
|
|
* Because SPM DVFS isn't reference to RDMA.
|
|
* Revert this workaround.
|
|
*/
|
|
/* rdma_reset_by_cmdq(module, handle); */
|
|
;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
/* SW workaround.
|
|
* Polling RDMA output line isn't 0 && RDMA status is run,
|
|
* before switching mm clock mux in cmd mode.
|
|
*/
|
|
void polling_rdma_output_line_is_not_zero(void)
|
|
{
|
|
unsigned int idx = rdma_index(DISP_MODULE_RDMA0);
|
|
unsigned int offset = DISP_RDMA_INDEX_OFFSET * idx;
|
|
unsigned int loop_cnt = 0;
|
|
|
|
if (polling_rdma_output_line_enable &&
|
|
!primary_display_is_video_mode()) {
|
|
/* pr_info("%s start\n", __func__); */
|
|
|
|
while (loop_cnt < 1*1000) {
|
|
if (DISP_REG_GET(offset +
|
|
DISP_REG_RDMA_OUT_LINE_CNT) ||
|
|
!(DISP_REG_GET(offset +
|
|
DISP_REG_RDMA_DBG_OUT1) & 0x1))
|
|
break;
|
|
loop_cnt++;
|
|
udelay(1);
|
|
}
|
|
#if 0
|
|
if (loop_cnt)
|
|
pr_info(
|
|
"%s delay loop_cnt=%d, outline=0x%x\n",
|
|
__func__,
|
|
loop_cnt,
|
|
DISP_REG_GET(offset +
|
|
DISP_REG_RDMA_OUT_LINE_CNT));
|
|
#endif
|
|
|
|
if (loop_cnt == 1000)
|
|
DDPAEE(
|
|
"%s delay loop_cnt=%d, outline=0x%x\n",
|
|
__func__,
|
|
loop_cnt,
|
|
DISP_REG_GET(offset +
|
|
DISP_REG_RDMA_OUT_LINE_CNT));
|
|
|
|
/* pr_info("%s done\n", __func__); */
|
|
}
|
|
}
|
|
|
|
struct DDP_MODULE_DRIVER ddp_driver_rdma = {
|
|
.init = rdma_init,
|
|
.deinit = rdma_deinit,
|
|
.config = rdma_config_l,
|
|
.start = rdma_start,
|
|
.trigger = NULL,
|
|
.stop = rdma_stop,
|
|
.reset = rdma_reset,
|
|
.power_on = rdma_clock_on,
|
|
.power_off = rdma_clock_off,
|
|
.is_idle = NULL,
|
|
.is_busy = NULL,
|
|
.dump_info = rdma_dump,
|
|
.bypass = NULL,
|
|
.build_cmdq = rdma_build_cmdq,
|
|
.set_lcm_utils = NULL,
|
|
.enable_irq = rdma_enable_irq,
|
|
.ioctl = (int (*)(enum DISP_MODULE_ENUM, void *,
|
|
enum DDP_IOCTL_NAME, void *))rdma_ioctl,
|
|
.switch_to_nonsec = NULL,
|
|
};
|