disp: snapshot of offline rotator
This snapshot includes updates to offline rotator and supporting files. Snapshot was taken from msm-4.14 as of commit 0f8fb25421ff ("cnss2: Add device version to SOC info structure"). Change-Id: I58674ba880de3d8722ed9119bfc2bee34b444917 Signed-off-by: Samantha Tran <samtran@codeaurora.org>
This commit is contained in:
@@ -10,6 +10,7 @@
|
|||||||
#include "sde_vbif.h"
|
#include "sde_vbif.h"
|
||||||
#include "sde_hw_vbif.h"
|
#include "sde_hw_vbif.h"
|
||||||
#include "sde_trace.h"
|
#include "sde_trace.h"
|
||||||
|
#include "sde_rotator_vbif.h"
|
||||||
|
|
||||||
#define MAX_XIN_CLIENT 16
|
#define MAX_XIN_CLIENT 16
|
||||||
|
|
||||||
@@ -286,6 +287,41 @@ exit:
|
|||||||
mutex_unlock(&vbif->mutex);
|
mutex_unlock(&vbif->mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void mdp_vbif_lock(struct platform_device *parent_pdev, bool enable)
|
||||||
|
{
|
||||||
|
struct drm_device *ddev;
|
||||||
|
struct sde_kms *sde_kms;
|
||||||
|
struct sde_hw_vbif *vbif = NULL;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
ddev = platform_get_drvdata(parent_pdev);
|
||||||
|
if (!ddev || !ddev_to_msm_kms(ddev)) {
|
||||||
|
SDE_ERROR("invalid drm device\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
sde_kms = to_sde_kms(ddev_to_msm_kms(ddev));
|
||||||
|
|
||||||
|
for (i = 0; i < ARRAY_SIZE(sde_kms->hw_vbif); i++) {
|
||||||
|
if (sde_kms->hw_vbif[i] &&
|
||||||
|
sde_kms->hw_vbif[i]->idx == VBIF_RT) {
|
||||||
|
vbif = sde_kms->hw_vbif[i];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!vbif) {
|
||||||
|
SDE_DEBUG("invalid vbif structure\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (enable)
|
||||||
|
mutex_lock(&vbif->mutex);
|
||||||
|
else
|
||||||
|
mutex_unlock(&vbif->mutex);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
bool sde_vbif_set_xin_halt(struct sde_kms *sde_kms,
|
bool sde_vbif_set_xin_halt(struct sde_kms *sde_kms,
|
||||||
struct sde_vbif_set_xin_halt_params *params)
|
struct sde_vbif_set_xin_halt_params *params)
|
||||||
{
|
{
|
||||||
|
@@ -24,6 +24,7 @@
|
|||||||
#include "sde_rotator_trace.h"
|
#include "sde_rotator_trace.h"
|
||||||
#include "sde_rotator_debug.h"
|
#include "sde_rotator_debug.h"
|
||||||
#include "sde_rotator_dev.h"
|
#include "sde_rotator_dev.h"
|
||||||
|
#include "sde_rotator_vbif.h"
|
||||||
|
|
||||||
static inline u64 fudge_factor(u64 val, u32 numer, u32 denom)
|
static inline u64 fudge_factor(u64 val, u32 numer, u32 denom)
|
||||||
{
|
{
|
||||||
@@ -70,6 +71,7 @@ u32 sde_apply_comp_ratio_factor(u32 quota,
|
|||||||
|
|
||||||
#define RES_1080p (1088*1920)
|
#define RES_1080p (1088*1920)
|
||||||
#define RES_UHD (3840*2160)
|
#define RES_UHD (3840*2160)
|
||||||
|
#define RES_WQXGA (2560*1600)
|
||||||
#define XIN_HALT_TIMEOUT_US 0x4000
|
#define XIN_HALT_TIMEOUT_US 0x4000
|
||||||
|
|
||||||
static int sde_mdp_wait_for_xin_halt(u32 xin_id)
|
static int sde_mdp_wait_for_xin_halt(u32 xin_id)
|
||||||
@@ -132,18 +134,36 @@ static bool force_on_xin_clk(u32 bit_off, u32 clk_ctl_reg_off, bool enable)
|
|||||||
return clk_forced_on;
|
return clk_forced_on;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void vbif_lock(struct platform_device *parent_pdev)
|
||||||
|
{
|
||||||
|
if (!parent_pdev)
|
||||||
|
return;
|
||||||
|
|
||||||
|
mdp_vbif_lock(parent_pdev, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void vbif_unlock(struct platform_device *parent_pdev)
|
||||||
|
{
|
||||||
|
if (!parent_pdev)
|
||||||
|
return;
|
||||||
|
|
||||||
|
mdp_vbif_lock(parent_pdev, false);
|
||||||
|
}
|
||||||
|
|
||||||
void sde_mdp_halt_vbif_xin(struct sde_mdp_vbif_halt_params *params)
|
void sde_mdp_halt_vbif_xin(struct sde_mdp_vbif_halt_params *params)
|
||||||
{
|
{
|
||||||
struct sde_rot_data_type *mdata = sde_rot_get_mdata();
|
struct sde_rot_data_type *mdata = sde_rot_get_mdata();
|
||||||
u32 reg_val;
|
u32 reg_val;
|
||||||
bool forced_on;
|
bool forced_on;
|
||||||
|
int rc = 0;
|
||||||
|
|
||||||
if (!mdata || !params || !params->reg_off_mdp_clk_ctrl) {
|
if (!mdata || !params || !params->reg_off_mdp_clk_ctrl) {
|
||||||
SDEROT_ERR("null input parameter\n");
|
SDEROT_ERR("null input parameter\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (params->xin_id > MMSS_VBIF_NRT_VBIF_CLK_FORCE_CTRL0_XIN1) {
|
if (!mdata->parent_pdev &&
|
||||||
|
params->xin_id > MMSS_VBIF_NRT_VBIF_CLK_FORCE_CTRL0_XIN1) {
|
||||||
SDEROT_ERR("xin_id:%d exceed max limit\n", params->xin_id);
|
SDEROT_ERR("xin_id:%d exceed max limit\n", params->xin_id);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -151,6 +171,8 @@ void sde_mdp_halt_vbif_xin(struct sde_mdp_vbif_halt_params *params)
|
|||||||
forced_on = force_on_xin_clk(params->bit_off_mdp_clk_ctrl,
|
forced_on = force_on_xin_clk(params->bit_off_mdp_clk_ctrl,
|
||||||
params->reg_off_mdp_clk_ctrl, true);
|
params->reg_off_mdp_clk_ctrl, true);
|
||||||
|
|
||||||
|
vbif_lock(mdata->parent_pdev);
|
||||||
|
|
||||||
SDEROT_EVTLOG(forced_on, params->xin_id);
|
SDEROT_EVTLOG(forced_on, params->xin_id);
|
||||||
|
|
||||||
reg_val = SDE_VBIF_READ(mdata, MMSS_VBIF_XIN_HALT_CTRL0);
|
reg_val = SDE_VBIF_READ(mdata, MMSS_VBIF_XIN_HALT_CTRL0);
|
||||||
@@ -158,12 +180,16 @@ void sde_mdp_halt_vbif_xin(struct sde_mdp_vbif_halt_params *params)
|
|||||||
reg_val | BIT(params->xin_id));
|
reg_val | BIT(params->xin_id));
|
||||||
|
|
||||||
/* this is a polling operation */
|
/* this is a polling operation */
|
||||||
sde_mdp_wait_for_xin_halt(params->xin_id);
|
rc = sde_mdp_wait_for_xin_halt(params->xin_id);
|
||||||
|
if (rc == -ETIMEDOUT)
|
||||||
|
params->xin_timeout = BIT(params->xin_id);
|
||||||
|
|
||||||
reg_val = SDE_VBIF_READ(mdata, MMSS_VBIF_XIN_HALT_CTRL0);
|
reg_val = SDE_VBIF_READ(mdata, MMSS_VBIF_XIN_HALT_CTRL0);
|
||||||
SDE_VBIF_WRITE(mdata, MMSS_VBIF_XIN_HALT_CTRL0,
|
SDE_VBIF_WRITE(mdata, MMSS_VBIF_XIN_HALT_CTRL0,
|
||||||
reg_val & ~BIT(params->xin_id));
|
reg_val & ~BIT(params->xin_id));
|
||||||
|
|
||||||
|
vbif_unlock(mdata->parent_pdev);
|
||||||
|
|
||||||
if (forced_on)
|
if (forced_on)
|
||||||
force_on_xin_clk(params->bit_off_mdp_clk_ctrl,
|
force_on_xin_clk(params->bit_off_mdp_clk_ctrl,
|
||||||
params->reg_off_mdp_clk_ctrl, false);
|
params->reg_off_mdp_clk_ctrl, false);
|
||||||
@@ -209,18 +235,36 @@ u32 sde_mdp_get_ot_limit(u32 width, u32 height, u32 pixfmt, u32 fps, u32 is_rd)
|
|||||||
SDEROT_DBG("w:%d h:%d fps:%d pixfmt:%8.8x yuv:%d res:%llu rd:%d\n",
|
SDEROT_DBG("w:%d h:%d fps:%d pixfmt:%8.8x yuv:%d res:%llu rd:%d\n",
|
||||||
width, height, fps, pixfmt, is_yuv, res, is_rd);
|
width, height, fps, pixfmt, is_yuv, res, is_rd);
|
||||||
|
|
||||||
if (!is_yuv)
|
|
||||||
goto exit;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If (total_source_pixels <= 62208000 && YUV) -> RD/WROT=2 //1080p30
|
* If (total_source_pixels <= 62208000 && YUV) -> RD/WROT=2 //1080p30
|
||||||
* If (total_source_pixels <= 124416000 && YUV) -> RD/WROT=4 //1080p60
|
* If (total_source_pixels <= 124416000 && YUV) -> RD/WROT=4 //1080p60
|
||||||
* If (total_source_pixels <= 2160p && YUV && FPS <= 30) -> RD/WROT = 32
|
* If (total_source_pixels <= 2160p && YUV && FPS <= 30) -> RD/WROT = 32
|
||||||
*/
|
*/
|
||||||
if (res <= (RES_1080p * 30))
|
switch (mdata->mdss_version) {
|
||||||
ot_lim = 2;
|
case SDE_MDP_HW_REV_540:
|
||||||
else if (res <= (RES_1080p * 60))
|
if (is_yuv) {
|
||||||
ot_lim = 4;
|
if (res <= (RES_1080p * 30))
|
||||||
|
ot_lim = 2;
|
||||||
|
else if (res <= (RES_1080p * 60))
|
||||||
|
ot_lim = 4;
|
||||||
|
else if (res <= (RES_WQXGA * 60))
|
||||||
|
ot_lim = 4;
|
||||||
|
else if (res <= (RES_UHD * 30))
|
||||||
|
ot_lim = 8;
|
||||||
|
} else if (fmt->bpp == 4 && res <= (RES_WQXGA * 60)) {
|
||||||
|
ot_lim = 16;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
if (is_yuv) {
|
||||||
|
if (res <= (RES_1080p * 30))
|
||||||
|
ot_lim = 2;
|
||||||
|
else if (res <= (RES_1080p * 60))
|
||||||
|
ot_lim = 4;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
exit:
|
exit:
|
||||||
SDEROT_DBG("ot_lim=%d\n", ot_lim);
|
SDEROT_DBG("ot_lim=%d\n", ot_lim);
|
||||||
@@ -274,6 +318,8 @@ void sde_mdp_set_ot_limit(struct sde_mdp_set_ot_params *params)
|
|||||||
u32 sts;
|
u32 sts;
|
||||||
bool forced_on;
|
bool forced_on;
|
||||||
|
|
||||||
|
vbif_lock(mdata->parent_pdev);
|
||||||
|
|
||||||
ot_lim = get_ot_limit(
|
ot_lim = get_ot_limit(
|
||||||
reg_off_vbif_lim_conf,
|
reg_off_vbif_lim_conf,
|
||||||
bit_off_vbif_lim_conf,
|
bit_off_vbif_lim_conf,
|
||||||
@@ -319,6 +365,7 @@ void sde_mdp_set_ot_limit(struct sde_mdp_set_ot_params *params)
|
|||||||
|
|
||||||
SDEROT_EVTLOG(params->num, params->xin_id, ot_lim);
|
SDEROT_EVTLOG(params->num, params->xin_id, ot_lim);
|
||||||
exit:
|
exit:
|
||||||
|
vbif_unlock(mdata->parent_pdev);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -465,7 +512,7 @@ static int sde_mdp_parse_dt_handler(struct platform_device *pdev,
|
|||||||
rc = of_property_read_u32_array(pdev->dev.of_node, prop_name,
|
rc = of_property_read_u32_array(pdev->dev.of_node, prop_name,
|
||||||
offsets, len);
|
offsets, len);
|
||||||
if (rc) {
|
if (rc) {
|
||||||
SDEROT_ERR("Error from prop %s : u32 array read\n", prop_name);
|
SDEROT_DBG("Error from prop %s : u32 array read\n", prop_name);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -499,7 +546,7 @@ static void sde_mdp_parse_vbif_memtype(struct platform_device *pdev,
|
|||||||
"qcom,mdss-rot-vbif-memtype");
|
"qcom,mdss-rot-vbif-memtype");
|
||||||
mdata->vbif_memtype = kcalloc(mdata->vbif_memtype_count,
|
mdata->vbif_memtype = kcalloc(mdata->vbif_memtype_count,
|
||||||
sizeof(u32), GFP_KERNEL);
|
sizeof(u32), GFP_KERNEL);
|
||||||
if (!mdata->vbif_memtype) {
|
if (!mdata->vbif_memtype || !mdata->vbif_memtype_count) {
|
||||||
mdata->vbif_memtype_count = 0;
|
mdata->vbif_memtype_count = 0;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -527,7 +574,7 @@ static void sde_mdp_parse_vbif_qos(struct platform_device *pdev,
|
|||||||
"qcom,mdss-rot-vbif-qos-setting");
|
"qcom,mdss-rot-vbif-qos-setting");
|
||||||
mdata->vbif_nrt_qos = kcalloc(mdata->npriority_lvl,
|
mdata->vbif_nrt_qos = kcalloc(mdata->npriority_lvl,
|
||||||
sizeof(u32), GFP_KERNEL);
|
sizeof(u32), GFP_KERNEL);
|
||||||
if (!mdata->vbif_nrt_qos) {
|
if (!mdata->vbif_nrt_qos || !mdata->npriority_lvl) {
|
||||||
mdata->npriority_lvl = 0;
|
mdata->npriority_lvl = 0;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -544,6 +591,16 @@ static void sde_mdp_parse_vbif_qos(struct platform_device *pdev,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void sde_mdp_parse_vbif_xin_id(struct platform_device *pdev,
|
||||||
|
struct sde_rot_data_type *mdata)
|
||||||
|
{
|
||||||
|
mdata->vbif_xin_id[XIN_SSPP] = XIN_SSPP;
|
||||||
|
mdata->vbif_xin_id[XIN_WRITEBACK] = XIN_WRITEBACK;
|
||||||
|
|
||||||
|
sde_mdp_parse_dt_handler(pdev, "qcom,mdss-rot-xin-id",
|
||||||
|
mdata->vbif_xin_id, MAX_XIN);
|
||||||
|
}
|
||||||
|
|
||||||
static void sde_mdp_parse_cdp_setting(struct platform_device *pdev,
|
static void sde_mdp_parse_cdp_setting(struct platform_device *pdev,
|
||||||
struct sde_rot_data_type *mdata)
|
struct sde_rot_data_type *mdata)
|
||||||
{
|
{
|
||||||
@@ -674,6 +731,35 @@ static void sde_mdp_parse_inline_rot_lut_setting(struct platform_device *pdev,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void sde_mdp_parse_rt_rotator(struct device_node *np)
|
||||||
|
{
|
||||||
|
struct sde_rot_data_type *mdata = sde_rot_get_mdata();
|
||||||
|
struct platform_device *pdev;
|
||||||
|
struct of_phandle_args phargs;
|
||||||
|
int rc = 0;
|
||||||
|
|
||||||
|
rc = of_parse_phandle_with_args(np,
|
||||||
|
"qcom,mdss-rot-parent", "#list-cells", 0, &phargs);
|
||||||
|
|
||||||
|
if (rc)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!phargs.np || !phargs.args_count) {
|
||||||
|
SDEROT_ERR("invalid args\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
pdev = of_find_device_by_node(phargs.np);
|
||||||
|
if (pdev) {
|
||||||
|
mdata->parent_pdev = pdev;
|
||||||
|
} else {
|
||||||
|
mdata->parent_pdev = NULL;
|
||||||
|
SDEROT_ERR("Parent mdp node not available\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
of_node_put(phargs.np);
|
||||||
|
}
|
||||||
|
|
||||||
static int sde_mdp_parse_dt_misc(struct platform_device *pdev,
|
static int sde_mdp_parse_dt_misc(struct platform_device *pdev,
|
||||||
struct sde_rot_data_type *mdata)
|
struct sde_rot_data_type *mdata)
|
||||||
{
|
{
|
||||||
@@ -702,6 +788,8 @@ static int sde_mdp_parse_dt_misc(struct platform_device *pdev,
|
|||||||
|
|
||||||
sde_mdp_parse_vbif_qos(pdev, mdata);
|
sde_mdp_parse_vbif_qos(pdev, mdata);
|
||||||
|
|
||||||
|
sde_mdp_parse_vbif_xin_id(pdev, mdata);
|
||||||
|
|
||||||
sde_mdp_parse_vbif_memtype(pdev, mdata);
|
sde_mdp_parse_vbif_memtype(pdev, mdata);
|
||||||
|
|
||||||
sde_mdp_parse_rot_lut_setting(pdev, mdata);
|
sde_mdp_parse_rot_lut_setting(pdev, mdata);
|
||||||
@@ -820,6 +908,13 @@ int sde_rotator_base_init(struct sde_rot_data_type **pmdata,
|
|||||||
int rc;
|
int rc;
|
||||||
struct sde_rot_data_type *mdata;
|
struct sde_rot_data_type *mdata;
|
||||||
|
|
||||||
|
|
||||||
|
/* if probe deferral happened, return early*/
|
||||||
|
if (sde_rot_res) {
|
||||||
|
SDEROT_ERR("Rotator data already initialized, skip init\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
mdata = devm_kzalloc(&pdev->dev, sizeof(*mdata), GFP_KERNEL);
|
mdata = devm_kzalloc(&pdev->dev, sizeof(*mdata), GFP_KERNEL);
|
||||||
if (mdata == NULL)
|
if (mdata == NULL)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
@@ -846,6 +941,8 @@ int sde_rotator_base_init(struct sde_rot_data_type **pmdata,
|
|||||||
SDEROT_DBG("SDE ROT VBIF HW Base addr=%pK len=0x%x\n",
|
SDEROT_DBG("SDE ROT VBIF HW Base addr=%pK len=0x%x\n",
|
||||||
mdata->vbif_nrt_io.base, mdata->vbif_nrt_io.len);
|
mdata->vbif_nrt_io.base, mdata->vbif_nrt_io.len);
|
||||||
|
|
||||||
|
sde_mdp_parse_rt_rotator(pdev->dev.of_node);
|
||||||
|
|
||||||
rc = sde_mdp_parse_dt_misc(pdev, mdata);
|
rc = sde_mdp_parse_dt_misc(pdev, mdata);
|
||||||
if (rc) {
|
if (rc) {
|
||||||
SDEROT_ERR("Error in device tree : misc\n");
|
SDEROT_ERR("Error in device tree : misc\n");
|
||||||
|
@@ -11,6 +11,8 @@
|
|||||||
#include <linux/kref.h>
|
#include <linux/kref.h>
|
||||||
#include <linux/kernel.h>
|
#include <linux/kernel.h>
|
||||||
#include <linux/regulator/consumer.h>
|
#include <linux/regulator/consumer.h>
|
||||||
|
#include <linux/of_platform.h>
|
||||||
|
#include <linux/platform_device.h>
|
||||||
|
|
||||||
#include "sde_rotator_hwio.h"
|
#include "sde_rotator_hwio.h"
|
||||||
#include "sde_rotator_io_util.h"
|
#include "sde_rotator_io_util.h"
|
||||||
@@ -41,11 +43,17 @@
|
|||||||
#define SDE_MDP_HW_REV_500 SDE_MDP_REV(5, 0, 0) /* sm8150 v1.0 */
|
#define SDE_MDP_HW_REV_500 SDE_MDP_REV(5, 0, 0) /* sm8150 v1.0 */
|
||||||
#define SDE_MDP_HW_REV_520 SDE_MDP_REV(5, 2, 0) /* sdmmagpie v1.0 */
|
#define SDE_MDP_HW_REV_520 SDE_MDP_REV(5, 2, 0) /* sdmmagpie v1.0 */
|
||||||
#define SDE_MDP_HW_REV_530 SDE_MDP_REV(5, 3, 0) /* sm6150 v1.0 */
|
#define SDE_MDP_HW_REV_530 SDE_MDP_REV(5, 3, 0) /* sm6150 v1.0 */
|
||||||
|
#define SDE_MDP_HW_REV_540 SDE_MDP_REV(5, 4, 0) /* sdmtrinket v1.0 */
|
||||||
#define SDE_MDP_HW_REV_600 SDE_MDP_REV(6, 0, 0) /* msmnile+ v1.0 */
|
#define SDE_MDP_HW_REV_600 SDE_MDP_REV(6, 0, 0) /* msmnile+ v1.0 */
|
||||||
|
|
||||||
#define SDE_MDP_VBIF_4_LEVEL_REMAPPER 4
|
#define SDE_MDP_VBIF_4_LEVEL_REMAPPER 4
|
||||||
#define SDE_MDP_VBIF_8_LEVEL_REMAPPER 8
|
#define SDE_MDP_VBIF_8_LEVEL_REMAPPER 8
|
||||||
|
|
||||||
|
/* XIN mapping */
|
||||||
|
#define XIN_SSPP 0
|
||||||
|
#define XIN_WRITEBACK 1
|
||||||
|
#define MAX_XIN 2
|
||||||
|
|
||||||
struct sde_mult_factor {
|
struct sde_mult_factor {
|
||||||
uint32_t numer;
|
uint32_t numer;
|
||||||
uint32_t denom;
|
uint32_t denom;
|
||||||
@@ -70,11 +78,13 @@ struct sde_mdp_set_ot_params {
|
|||||||
* @xin_id: xin port number of vbif
|
* @xin_id: xin port number of vbif
|
||||||
* @reg_off_mdp_clk_ctrl: reg offset for vbif clock control
|
* @reg_off_mdp_clk_ctrl: reg offset for vbif clock control
|
||||||
* @bit_off_mdp_clk_ctrl: bit offset for vbif clock control
|
* @bit_off_mdp_clk_ctrl: bit offset for vbif clock control
|
||||||
|
* @xin_timeout: bit position indicates timeout on corresponding xin id
|
||||||
*/
|
*/
|
||||||
struct sde_mdp_vbif_halt_params {
|
struct sde_mdp_vbif_halt_params {
|
||||||
u32 xin_id;
|
u32 xin_id;
|
||||||
u32 reg_off_mdp_clk_ctrl;
|
u32 reg_off_mdp_clk_ctrl;
|
||||||
u32 bit_off_mdp_clk_ctrl;
|
u32 bit_off_mdp_clk_ctrl;
|
||||||
|
u32 xin_timeout;
|
||||||
};
|
};
|
||||||
|
|
||||||
enum sde_bus_vote_type {
|
enum sde_bus_vote_type {
|
||||||
@@ -220,6 +230,7 @@ struct sde_rot_data_type {
|
|||||||
u32 mdss_version;
|
u32 mdss_version;
|
||||||
|
|
||||||
struct platform_device *pdev;
|
struct platform_device *pdev;
|
||||||
|
struct platform_device *parent_pdev;
|
||||||
struct sde_io_data sde_io;
|
struct sde_io_data sde_io;
|
||||||
struct sde_io_data vbif_nrt_io;
|
struct sde_io_data vbif_nrt_io;
|
||||||
char __iomem *mdp_base;
|
char __iomem *mdp_base;
|
||||||
@@ -248,6 +259,8 @@ struct sde_rot_data_type {
|
|||||||
u32 *vbif_nrt_qos;
|
u32 *vbif_nrt_qos;
|
||||||
u32 npriority_lvl;
|
u32 npriority_lvl;
|
||||||
|
|
||||||
|
u32 vbif_xin_id[MAX_XIN];
|
||||||
|
|
||||||
struct pm_qos_request pm_qos_rot_cpu_req;
|
struct pm_qos_request pm_qos_rot_cpu_req;
|
||||||
u32 rot_pm_qos_cpu_count;
|
u32 rot_pm_qos_cpu_count;
|
||||||
u32 rot_pm_qos_cpu_mask;
|
u32 rot_pm_qos_cpu_mask;
|
||||||
@@ -300,6 +313,9 @@ u32 sde_mdp_get_ot_limit(u32 width, u32 height, u32 pixfmt, u32 fps, u32 is_rd);
|
|||||||
|
|
||||||
void sde_mdp_set_ot_limit(struct sde_mdp_set_ot_params *params);
|
void sde_mdp_set_ot_limit(struct sde_mdp_set_ot_params *params);
|
||||||
|
|
||||||
|
void vbif_lock(struct platform_device *parent_pdev);
|
||||||
|
void vbif_unlock(struct platform_device *parent_pdev);
|
||||||
|
|
||||||
void sde_mdp_halt_vbif_xin(struct sde_mdp_vbif_halt_params *params);
|
void sde_mdp_halt_vbif_xin(struct sde_mdp_vbif_halt_params *params);
|
||||||
|
|
||||||
int sde_mdp_init_vbif(void);
|
int sde_mdp_init_vbif(void);
|
||||||
|
@@ -574,26 +574,6 @@ static ssize_t sde_rot_evtlog_dump_read(struct file *file, char __user *buff,
|
|||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* sde_rot_evtlog_dump_write - debugfs write handler for evtlog dump
|
|
||||||
* @file: file handler
|
|
||||||
* @user_buf: user buffer content from debugfs
|
|
||||||
* @count: size of user buffer
|
|
||||||
* @ppos: position offset of user buffer
|
|
||||||
*/
|
|
||||||
static ssize_t sde_rot_evtlog_dump_write(struct file *file,
|
|
||||||
const char __user *user_buf, size_t count, loff_t *ppos)
|
|
||||||
{
|
|
||||||
sde_rot_evtlog_dump_all();
|
|
||||||
|
|
||||||
sde_rot_dump_reg_all();
|
|
||||||
|
|
||||||
if (sde_rot_dbg_evtlog.panic_on_err)
|
|
||||||
panic("evtlog_dump_write");
|
|
||||||
|
|
||||||
return count;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* sde_rot_evtlog_dump_helper - helper function for evtlog dump
|
* sde_rot_evtlog_dump_helper - helper function for evtlog dump
|
||||||
* @dead: boolean indicates panic after dump
|
* @dead: boolean indicates panic after dump
|
||||||
@@ -959,7 +939,6 @@ static int sde_rotator_core_create_debugfs(
|
|||||||
static const struct file_operations sde_rot_evtlog_fops = {
|
static const struct file_operations sde_rot_evtlog_fops = {
|
||||||
.open = sde_rot_evtlog_dump_open,
|
.open = sde_rot_evtlog_dump_open,
|
||||||
.read = sde_rot_evtlog_dump_read,
|
.read = sde_rot_evtlog_dump_read,
|
||||||
.write = sde_rot_evtlog_dump_write,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static int sde_rotator_evtlog_create_debugfs(
|
static int sde_rotator_evtlog_create_debugfs(
|
||||||
|
@@ -26,6 +26,7 @@
|
|||||||
#include "sde_rotator_r3_debug.h"
|
#include "sde_rotator_r3_debug.h"
|
||||||
#include "sde_rotator_trace.h"
|
#include "sde_rotator_trace.h"
|
||||||
#include "sde_rotator_debug.h"
|
#include "sde_rotator_debug.h"
|
||||||
|
#include "sde_rotator_vbif.h"
|
||||||
|
|
||||||
#define RES_UHD (3840*2160)
|
#define RES_UHD (3840*2160)
|
||||||
#define MS_TO_US(t) ((t) * USEC_PER_MSEC)
|
#define MS_TO_US(t) ((t) * USEC_PER_MSEC)
|
||||||
@@ -35,10 +36,6 @@
|
|||||||
#define TRAFFIC_SHAPE_CLKTICK_12MS 230400
|
#define TRAFFIC_SHAPE_CLKTICK_12MS 230400
|
||||||
#define TRAFFIC_SHAPE_VSYNC_CLK 19200000
|
#define TRAFFIC_SHAPE_VSYNC_CLK 19200000
|
||||||
|
|
||||||
/* XIN mapping */
|
|
||||||
#define XIN_SSPP 0
|
|
||||||
#define XIN_WRITEBACK 1
|
|
||||||
|
|
||||||
/* wait for at most 2 vsync for lowest refresh rate (24hz) */
|
/* wait for at most 2 vsync for lowest refresh rate (24hz) */
|
||||||
#define KOFF_TIMEOUT (42 * 8)
|
#define KOFF_TIMEOUT (42 * 8)
|
||||||
|
|
||||||
@@ -748,23 +745,29 @@ static void sde_hw_rotator_disable_irq(struct sde_hw_rotator *rot)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void sde_hw_rotator_halt_vbif_xin_client(void)
|
static int sde_hw_rotator_halt_vbif_xin_client(void)
|
||||||
{
|
{
|
||||||
struct sde_mdp_vbif_halt_params halt_params;
|
struct sde_mdp_vbif_halt_params halt_params;
|
||||||
|
int rc = 0;
|
||||||
|
struct sde_rot_data_type *mdata = sde_rot_get_mdata();
|
||||||
|
|
||||||
memset(&halt_params, 0, sizeof(struct sde_mdp_vbif_halt_params));
|
memset(&halt_params, 0, sizeof(struct sde_mdp_vbif_halt_params));
|
||||||
halt_params.xin_id = XIN_SSPP;
|
halt_params.xin_id = mdata->vbif_xin_id[XIN_SSPP];
|
||||||
halt_params.reg_off_mdp_clk_ctrl = MMSS_VBIF_NRT_VBIF_CLK_FORCE_CTRL0;
|
halt_params.reg_off_mdp_clk_ctrl = MMSS_VBIF_NRT_VBIF_CLK_FORCE_CTRL0;
|
||||||
halt_params.bit_off_mdp_clk_ctrl =
|
halt_params.bit_off_mdp_clk_ctrl =
|
||||||
MMSS_VBIF_NRT_VBIF_CLK_FORCE_CTRL0_XIN0;
|
MMSS_VBIF_NRT_VBIF_CLK_FORCE_CTRL0_XIN0;
|
||||||
sde_mdp_halt_vbif_xin(&halt_params);
|
sde_mdp_halt_vbif_xin(&halt_params);
|
||||||
|
rc |= halt_params.xin_timeout;
|
||||||
|
|
||||||
memset(&halt_params, 0, sizeof(struct sde_mdp_vbif_halt_params));
|
memset(&halt_params, 0, sizeof(struct sde_mdp_vbif_halt_params));
|
||||||
halt_params.xin_id = XIN_WRITEBACK;
|
halt_params.xin_id = mdata->vbif_xin_id[XIN_WRITEBACK];
|
||||||
halt_params.reg_off_mdp_clk_ctrl = MMSS_VBIF_NRT_VBIF_CLK_FORCE_CTRL0;
|
halt_params.reg_off_mdp_clk_ctrl = MMSS_VBIF_NRT_VBIF_CLK_FORCE_CTRL0;
|
||||||
halt_params.bit_off_mdp_clk_ctrl =
|
halt_params.bit_off_mdp_clk_ctrl =
|
||||||
MMSS_VBIF_NRT_VBIF_CLK_FORCE_CTRL0_XIN1;
|
MMSS_VBIF_NRT_VBIF_CLK_FORCE_CTRL0_XIN1;
|
||||||
sde_mdp_halt_vbif_xin(&halt_params);
|
sde_mdp_halt_vbif_xin(&halt_params);
|
||||||
|
rc |= halt_params.xin_timeout;
|
||||||
|
|
||||||
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1025,6 +1028,47 @@ static void sde_hw_rotator_unmap_vaddr(struct sde_dbg_buf *dbgbuf)
|
|||||||
dbgbuf->height = 0;
|
dbgbuf->height = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void sde_hw_rotator_vbif_rt_setting(void)
|
||||||
|
{
|
||||||
|
u32 reg_high, reg_shift, reg_val, reg_val_lvl, mask, vbif_qos;
|
||||||
|
struct sde_rot_data_type *mdata = sde_rot_get_mdata();
|
||||||
|
int i, j;
|
||||||
|
|
||||||
|
vbif_lock(mdata->parent_pdev);
|
||||||
|
|
||||||
|
for (i = 0; i < mdata->npriority_lvl; i++) {
|
||||||
|
for (j = 0; j < MAX_XIN; j++) {
|
||||||
|
reg_high = ((mdata->vbif_xin_id[j]
|
||||||
|
& 0x8) >> 3) * 4 + (i * 8);
|
||||||
|
reg_shift = mdata->vbif_xin_id[j] * 4;
|
||||||
|
|
||||||
|
reg_val = SDE_VBIF_READ(mdata,
|
||||||
|
MMSS_VBIF_NRT_VBIF_QOS_RP_REMAP_000 + reg_high);
|
||||||
|
reg_val_lvl = SDE_VBIF_READ(mdata,
|
||||||
|
MMSS_VBIF_NRT_VBIF_QOS_LVL_REMAP_000 + reg_high);
|
||||||
|
|
||||||
|
mask = 0x7 << (mdata->vbif_xin_id[j] * 4);
|
||||||
|
|
||||||
|
vbif_qos = mdata->vbif_nrt_qos[i];
|
||||||
|
|
||||||
|
reg_val &= ~mask;
|
||||||
|
reg_val |= (vbif_qos << reg_shift) & mask;
|
||||||
|
|
||||||
|
reg_val_lvl &= ~mask;
|
||||||
|
reg_val_lvl |= (vbif_qos << reg_shift) & mask;
|
||||||
|
|
||||||
|
SDE_VBIF_WRITE(mdata,
|
||||||
|
MMSS_VBIF_NRT_VBIF_QOS_RP_REMAP_000 + reg_high,
|
||||||
|
reg_val);
|
||||||
|
SDE_VBIF_WRITE(mdata,
|
||||||
|
MMSS_VBIF_NRT_VBIF_QOS_LVL_REMAP_000 + reg_high,
|
||||||
|
reg_val_lvl);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
vbif_unlock(mdata->parent_pdev);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* sde_hw_rotator_vbif_setting - helper function to set vbif QoS remapper
|
* sde_hw_rotator_vbif_setting - helper function to set vbif QoS remapper
|
||||||
* levels, enable write gather enable and avoid clk gating setting for
|
* levels, enable write gather enable and avoid clk gating setting for
|
||||||
@@ -2095,7 +2139,10 @@ static u32 sde_hw_rotator_wait_done_regdma(
|
|||||||
__sde_hw_rotator_get_timestamp(rot,
|
__sde_hw_rotator_get_timestamp(rot,
|
||||||
ROT_QUEUE_LOW_PRIORITY);
|
ROT_QUEUE_LOW_PRIORITY);
|
||||||
|
|
||||||
if (ubwcerr || abort) {
|
spin_unlock_irqrestore(&rot->rotisr_lock, flags);
|
||||||
|
|
||||||
|
if (ubwcerr || abort ||
|
||||||
|
sde_hw_rotator_halt_vbif_xin_client()) {
|
||||||
/*
|
/*
|
||||||
* Perform recovery for ROT SSPP UBWC decode
|
* Perform recovery for ROT SSPP UBWC decode
|
||||||
* error.
|
* error.
|
||||||
@@ -2103,16 +2150,15 @@ static u32 sde_hw_rotator_wait_done_regdma(
|
|||||||
* - reset TS logic so all pending rotation
|
* - reset TS logic so all pending rotation
|
||||||
* in hw queue got done signalled
|
* in hw queue got done signalled
|
||||||
*/
|
*/
|
||||||
spin_unlock_irqrestore(&rot->rotisr_lock,
|
|
||||||
flags);
|
|
||||||
if (!sde_hw_rotator_reset(rot, ctx))
|
if (!sde_hw_rotator_reset(rot, ctx))
|
||||||
status = REGDMA_INCOMPLETE_CMD;
|
status = REGDMA_INCOMPLETE_CMD;
|
||||||
else
|
else
|
||||||
status = ROT_ERROR_BIT;
|
status = ROT_ERROR_BIT;
|
||||||
spin_lock_irqsave(&rot->rotisr_lock, flags);
|
|
||||||
} else {
|
} else {
|
||||||
status = ROT_ERROR_BIT;
|
status = ROT_ERROR_BIT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
spin_lock_irqsave(&rot->rotisr_lock, flags);
|
||||||
} else {
|
} else {
|
||||||
if (rc == 1)
|
if (rc == 1)
|
||||||
SDEROT_WARN(
|
SDEROT_WARN(
|
||||||
@@ -2829,7 +2875,7 @@ static int sde_hw_rotator_config(struct sde_rot_hw_resource *hw,
|
|||||||
struct sde_mdp_set_ot_params ot_params;
|
struct sde_mdp_set_ot_params ot_params;
|
||||||
|
|
||||||
memset(&ot_params, 0, sizeof(struct sde_mdp_set_ot_params));
|
memset(&ot_params, 0, sizeof(struct sde_mdp_set_ot_params));
|
||||||
ot_params.xin_id = XIN_SSPP;
|
ot_params.xin_id = mdata->vbif_xin_id[XIN_SSPP];
|
||||||
ot_params.num = 0; /* not used */
|
ot_params.num = 0; /* not used */
|
||||||
ot_params.width = entry->perf->config.input.width;
|
ot_params.width = entry->perf->config.input.width;
|
||||||
ot_params.height = entry->perf->config.input.height;
|
ot_params.height = entry->perf->config.input.height;
|
||||||
@@ -2851,7 +2897,7 @@ static int sde_hw_rotator_config(struct sde_rot_hw_resource *hw,
|
|||||||
struct sde_mdp_set_ot_params ot_params;
|
struct sde_mdp_set_ot_params ot_params;
|
||||||
|
|
||||||
memset(&ot_params, 0, sizeof(struct sde_mdp_set_ot_params));
|
memset(&ot_params, 0, sizeof(struct sde_mdp_set_ot_params));
|
||||||
ot_params.xin_id = XIN_WRITEBACK;
|
ot_params.xin_id = mdata->vbif_xin_id[XIN_WRITEBACK];
|
||||||
ot_params.num = 0; /* not used */
|
ot_params.num = 0; /* not used */
|
||||||
ot_params.width = entry->perf->config.input.width;
|
ot_params.width = entry->perf->config.input.width;
|
||||||
ot_params.height = entry->perf->config.input.height;
|
ot_params.height = entry->perf->config.input.height;
|
||||||
@@ -2872,15 +2918,20 @@ static int sde_hw_rotator_config(struct sde_rot_hw_resource *hw,
|
|||||||
if (test_bit(SDE_QOS_PER_PIPE_LUT, mdata->sde_qos_map)) {
|
if (test_bit(SDE_QOS_PER_PIPE_LUT, mdata->sde_qos_map)) {
|
||||||
u32 qos_lut = 0; /* low priority for nrt read client */
|
u32 qos_lut = 0; /* low priority for nrt read client */
|
||||||
|
|
||||||
trace_rot_perf_set_qos_luts(XIN_SSPP, sspp_cfg.fmt->format,
|
trace_rot_perf_set_qos_luts(mdata->vbif_xin_id[XIN_SSPP],
|
||||||
qos_lut, sde_mdp_is_linear_format(sspp_cfg.fmt));
|
sspp_cfg.fmt->format, qos_lut,
|
||||||
|
sde_mdp_is_linear_format(sspp_cfg.fmt));
|
||||||
|
|
||||||
SDE_ROTREG_WRITE(rot->mdss_base, ROT_SSPP_CREQ_LUT, qos_lut);
|
SDE_ROTREG_WRITE(rot->mdss_base, ROT_SSPP_CREQ_LUT, qos_lut);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* VBIF QoS and other settings */
|
/* VBIF QoS and other settings */
|
||||||
if (!ctx->sbuf_mode)
|
if (!ctx->sbuf_mode) {
|
||||||
sde_hw_rotator_vbif_setting(rot);
|
if (mdata->parent_pdev)
|
||||||
|
sde_hw_rotator_vbif_rt_setting();
|
||||||
|
else
|
||||||
|
sde_hw_rotator_vbif_setting(rot);
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
@@ -3178,6 +3229,22 @@ static int sde_rotator_hw_rev_init(struct sde_hw_rotator *rot)
|
|||||||
ARRAY_SIZE(sde_hw_rotator_v4_outpixfmts_sbuf);
|
ARRAY_SIZE(sde_hw_rotator_v4_outpixfmts_sbuf);
|
||||||
rot->downscale_caps =
|
rot->downscale_caps =
|
||||||
"LINEAR/1.5/2/4/8/16/32/64 TILE/1.5/2/4 TP10/1.5/2";
|
"LINEAR/1.5/2/4/8/16/32/64 TILE/1.5/2/4 TP10/1.5/2";
|
||||||
|
} else if (IS_SDE_MAJOR_MINOR_SAME(mdata->mdss_version,
|
||||||
|
SDE_MDP_HW_REV_540)) {
|
||||||
|
SDEROT_DBG("Sys cache inline rotation not supported\n");
|
||||||
|
set_bit(SDE_CAPS_UBWC_2, mdata->sde_caps_map);
|
||||||
|
set_bit(SDE_CAPS_PARTIALWR, mdata->sde_caps_map);
|
||||||
|
set_bit(SDE_CAPS_HW_TIMESTAMP, mdata->sde_caps_map);
|
||||||
|
rot->inpixfmts[SDE_ROTATOR_MODE_OFFLINE] =
|
||||||
|
sde_hw_rotator_v4_inpixfmts;
|
||||||
|
rot->num_inpixfmt[SDE_ROTATOR_MODE_OFFLINE] =
|
||||||
|
ARRAY_SIZE(sde_hw_rotator_v4_inpixfmts);
|
||||||
|
rot->outpixfmts[SDE_ROTATOR_MODE_OFFLINE] =
|
||||||
|
sde_hw_rotator_v4_outpixfmts;
|
||||||
|
rot->num_outpixfmt[SDE_ROTATOR_MODE_OFFLINE] =
|
||||||
|
ARRAY_SIZE(sde_hw_rotator_v4_outpixfmts);
|
||||||
|
rot->downscale_caps =
|
||||||
|
"LINEAR/1.5/2/4/8/16/32/64 TILE/1.5/2/4 TP10/1.5/2";
|
||||||
} else if (IS_SDE_MAJOR_MINOR_SAME(mdata->mdss_version,
|
} else if (IS_SDE_MAJOR_MINOR_SAME(mdata->mdss_version,
|
||||||
SDE_MDP_HW_REV_400) ||
|
SDE_MDP_HW_REV_400) ||
|
||||||
IS_SDE_MAJOR_MINOR_SAME(mdata->mdss_version,
|
IS_SDE_MAJOR_MINOR_SAME(mdata->mdss_version,
|
||||||
|
10
rotator/sde_rotator_vbif.h
Normal file
10
rotator/sde_rotator_vbif.h
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2019, The Linux Foundation. All rights reserved.
|
||||||
|
*/
|
||||||
|
#ifndef __SDE_ROTATOR_VBIF_H__
|
||||||
|
#define __SDE_ROTATOR_VBIF_H__
|
||||||
|
|
||||||
|
void mdp_vbif_lock(struct platform_device *parent_pdev, bool enable);
|
||||||
|
|
||||||
|
#endif /* __SDE_ROTATOR_VBIF_H__ */
|
Reference in New Issue
Block a user