summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinux Build Service Account <lnxbuild@localhost>2017-02-15 17:01:03 -0800
committerGerrit - the friendly Code Review server <code-review@localhost>2017-02-15 17:01:02 -0800
commitb24937b98d0d380ae2600ae7607c02ad4f525615 (patch)
tree9ec4e868da5d4bb18b3879ffa28dddad21aaad99
parentfcc0fdda2cf35828e5454e0e5e47a2cf02fa59b3 (diff)
parent4c8baa46841cf35816f19f041a9b33c4f4fc0d3b (diff)
Merge "msm: sde: Ensure mdp splash cleanup before initiating rotation request"
-rw-r--r--Documentation/devicetree/bindings/fb/mdss-mdp.txt3
-rw-r--r--drivers/media/platform/msm/sde/rotator/sde_rotator_base.c39
-rw-r--r--drivers/media/platform/msm/sde/rotator/sde_rotator_base.h12
-rw-r--r--drivers/media/platform/msm/sde/rotator/sde_rotator_core.c11
-rw-r--r--drivers/media/platform/msm/sde/rotator/sde_rotator_hwio.h4
-rw-r--r--drivers/media/platform/msm/sde/rotator/sde_rotator_r3.c67
-rw-r--r--drivers/media/platform/msm/sde/rotator/sde_rotator_smmu.c4
-rw-r--r--drivers/video/fbdev/msm/mdss.h3
-rw-r--r--drivers/video/fbdev/msm/mdss_mdp.c23
-rw-r--r--drivers/video/fbdev/msm/mdss_smmu.c3
-rw-r--r--include/linux/mdss_smmu_ext.h4
11 files changed, 151 insertions, 22 deletions
diff --git a/Documentation/devicetree/bindings/fb/mdss-mdp.txt b/Documentation/devicetree/bindings/fb/mdss-mdp.txt
index 7a98e4e8fdd2..0ab4d53f2663 100644
--- a/Documentation/devicetree/bindings/fb/mdss-mdp.txt
+++ b/Documentation/devicetree/bindings/fb/mdss-mdp.txt
@@ -92,6 +92,8 @@ Required properties
active in MDP for this configuration. Meant for
hardware that has hw cursors support as a
source pipe.
+- qcom,mdss-rot-xin-id: Array of VBIF clients ids (xins) corresponding
+ to the respective rotator pipes.
- qcom,mdss-pipe-cursor-xin-id: Array of VBIF clients ids (xins) corresponding
to the respective cursor pipes. Number of xin ids
defined should match the number of offsets
@@ -754,6 +756,7 @@ Example:
qcom,mdss-pipe-rgb-xin-id = <1 5 9>;
qcom,mdss-pipe-dma-xin-id = <2 10>;
qcom,mdss-pipe-cursor-xin-id = <7 7>;
+ qcom,mdss-rot-xin-id = <14 15>;
qcom,mdss-pipe-vig-clk-ctrl-offsets = <0x3AC 0 0>,
<0x3B4 0 0>,
diff --git a/drivers/media/platform/msm/sde/rotator/sde_rotator_base.c b/drivers/media/platform/msm/sde/rotator/sde_rotator_base.c
index b485af0ee561..92b6e8ffa92e 100644
--- a/drivers/media/platform/msm/sde/rotator/sde_rotator_base.c
+++ b/drivers/media/platform/msm/sde/rotator/sde_rotator_base.c
@@ -438,6 +438,40 @@ static void sde_mdp_parse_vbif_qos(struct platform_device *pdev,
}
}
+static int sde_mdp_parse_vbif_xin_id(struct platform_device *pdev,
+ struct sde_rot_data_type *mdata)
+{
+ int rc = 0;
+ bool default_xin_id = false;
+
+ mdata->nxid = sde_mdp_parse_dt_prop_len(pdev,
+ "qcom,mdss-rot-xin-id");
+ if (!mdata->nxid) {
+ mdata->nxid = 2;
+ default_xin_id = true;
+ }
+ mdata->vbif_xin_id = kzalloc(sizeof(u32) *
+ mdata->nxid, GFP_KERNEL);
+ if (!mdata->vbif_xin_id) {
+ SDEROT_ERR("xin alloc failure\n");
+ return -ENOMEM;
+ }
+ if (default_xin_id) {
+ mdata->vbif_xin_id[XIN_SSPP] = XIN_SSPP;
+ mdata->vbif_xin_id[XIN_WRITEBACK] = XIN_WRITEBACK;
+ } else {
+ rc = sde_mdp_parse_dt_handler(pdev,
+ "qcom,mdss-rot-xin-id", mdata->vbif_xin_id,
+ mdata->nxid);
+ if (rc) {
+ SDEROT_ERR("vbif xin id setting not found\n");
+ return rc;
+ }
+ }
+
+ return 0;
+}
+
static int sde_mdp_parse_dt_misc(struct platform_device *pdev,
struct sde_rot_data_type *mdata)
{
@@ -463,6 +497,11 @@ static int sde_mdp_parse_dt_misc(struct platform_device *pdev,
"Could not read optional property: highest bank bit\n");
sde_mdp_parse_vbif_qos(pdev, mdata);
+ rc = sde_mdp_parse_vbif_xin_id(pdev, mdata);
+ if (rc) {
+ SDEROT_DBG("vbif xin id dt parse failure\n");
+ return rc;
+ }
mdata->mdp_base = mdata->sde_io.base + SDE_MDP_OFFSET;
diff --git a/drivers/media/platform/msm/sde/rotator/sde_rotator_base.h b/drivers/media/platform/msm/sde/rotator/sde_rotator_base.h
index 92ea32d9e819..5cbdc03ced9d 100644
--- a/drivers/media/platform/msm/sde/rotator/sde_rotator_base.h
+++ b/drivers/media/platform/msm/sde/rotator/sde_rotator_base.h
@@ -27,6 +27,10 @@
#define MDSS_MDP_HW_REV_320 0x30020000 /* sdm660 */
#define MDSS_MDP_HW_REV_330 0x30030000 /* sdm630 */
+/* XIN mapping */
+#define XIN_SSPP 0
+#define XIN_WRITEBACK 1
+
struct sde_mult_factor {
uint32_t numer;
uint32_t denom;
@@ -167,11 +171,17 @@ struct sde_rot_data_type {
u32 *vbif_nrt_qos;
u32 npriority_lvl;
+ u32 *vbif_xin_id;
+ u32 nxid;
+
int iommu_attached;
int iommu_ref_cnt;
int (*iommu_ctrl)(int enable);
int (*secure_session_ctrl)(int enable);
int (*wait_for_transition)(int state, int request);
+ void (*vbif_reg_lock)(void);
+ void (*vbif_reg_unlock)(void);
+ bool (*handoff_pending)(void);
struct sde_rot_vbif_debug_bus *nrt_vbif_dbg_bus;
u32 nrt_vbif_dbg_bus_size;
@@ -182,6 +192,8 @@ struct sde_rot_data_type {
int sec_cam_en;
bool callback_request;
struct ion_client *iclient;
+
+ bool handoff_done;
};
int sde_rotator_base_init(struct sde_rot_data_type **pmdata,
diff --git a/drivers/media/platform/msm/sde/rotator/sde_rotator_core.c b/drivers/media/platform/msm/sde/rotator/sde_rotator_core.c
index b55bc905ea7a..a01a54fccb12 100644
--- a/drivers/media/platform/msm/sde/rotator/sde_rotator_core.c
+++ b/drivers/media/platform/msm/sde/rotator/sde_rotator_core.c
@@ -1818,6 +1818,17 @@ static int sde_rotator_validate_entry(struct sde_rot_mgr *mgr,
int ret;
struct sde_rotation_item *item;
struct sde_rot_perf *perf;
+ struct sde_rot_data_type *mdata = sde_rot_get_mdata();
+
+ /* Check to ensure handoff is completed before 1st rotation request */
+ if (!mdata->handoff_done && mdata->handoff_pending) {
+ mdata->handoff_done = !mdata->handoff_pending();
+ if (!mdata->handoff_done) {
+ SDEROT_INFO(
+ "Splash Still on, Reject Rotation Request\n");
+ return -EINVAL;
+ }
+ }
item = &entry->item;
diff --git a/drivers/media/platform/msm/sde/rotator/sde_rotator_hwio.h b/drivers/media/platform/msm/sde/rotator/sde_rotator_hwio.h
index 051db7863c54..8a8711ea468b 100644
--- a/drivers/media/platform/msm/sde/rotator/sde_rotator_hwio.h
+++ b/drivers/media/platform/msm/sde/rotator/sde_rotator_hwio.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2015-2016, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -65,6 +65,8 @@
#define MMSS_VBIF_NRT_VBIF_IN_WR_LIM_CONF2 0x00C8
#define MMSS_VBIF_NRT_VBIF_OUT_RD_LIM_CONF0 0x00D0
#define MMSS_VBIF_NRT_VBIF_OUT_WR_LIM_CONF0 0x00D4
+#define MDSS_VBIF_QOS_RP_REMAP_BASE 0x550
+#define MDSS_VBIF_QOS_LVL_REMAP_BASE 0x570
#define SDE_MDP_REG_TRAFFIC_SHAPER_EN BIT(31)
#define SDE_MDP_REG_TRAFFIC_SHAPER_RD_CLIENT(num) (0x030 + (num * 4))
diff --git a/drivers/media/platform/msm/sde/rotator/sde_rotator_r3.c b/drivers/media/platform/msm/sde/rotator/sde_rotator_r3.c
index d7fb167ab49f..7ea36c85738f 100644
--- a/drivers/media/platform/msm/sde/rotator/sde_rotator_r3.c
+++ b/drivers/media/platform/msm/sde/rotator/sde_rotator_r3.c
@@ -42,9 +42,6 @@
#define TRAFFIC_SHAPE_CLKTICK_14MS 268800
#define TRAFFIC_SHAPE_CLKTICK_12MS 230400
-/* XIN mapping */
-#define XIN_SSPP 0
-#define XIN_WRITEBACK 1
/* wait for at most 2 vsync for lowest refresh rate (24hz) */
#define KOFF_TIMEOUT msecs_to_jiffies(42 * 32)
@@ -1698,11 +1695,14 @@ static int sde_hw_rotator_config(struct sde_rot_hw_resource *hw,
item->input.format, item->output.format,
entry->perf->config.frame_rate);
+ if (mdata->vbif_reg_lock)
+ mdata->vbif_reg_lock();
+
if (mdata->default_ot_rd_limit) {
struct sde_mdp_set_ot_params 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.width = entry->perf->config.input.width;
ot_params.height = entry->perf->config.input.height;
@@ -1724,7 +1724,7 @@ static int sde_hw_rotator_config(struct sde_rot_hw_resource *hw,
struct sde_mdp_set_ot_params 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.width = entry->perf->config.input.width;
ot_params.height = entry->perf->config.input.height;
@@ -1745,36 +1745,61 @@ static int sde_hw_rotator_config(struct sde_rot_hw_resource *hw,
if (test_bit(SDE_QOS_PER_PIPE_LUT, mdata->sde_qos_map)) {
u32 qos_lut = 0; /* low priority for nrt read client */
- trace_rot_perf_set_qos_luts(XIN_SSPP, sspp_cfg.fmt->format,
- qos_lut, sde_mdp_is_linear_format(sspp_cfg.fmt));
+ trace_rot_perf_set_qos_luts(mdata->vbif_xin_id[XIN_SSPP],
+ 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);
}
if (mdata->npriority_lvl > 0) {
- u32 mask, reg_val, i, vbif_qos;
+ u32 mask, reg_val, i, j, vbif_qos, reg_val_lvl, reg_high;
for (i = 0; i < mdata->npriority_lvl; i++) {
- reg_val = SDE_VBIF_READ(mdata,
- MMSS_VBIF_NRT_VBIF_QOS_REMAP_00 + i*4);
- mask = 0x3 << (XIN_SSPP * 2);
- reg_val &= ~(mask);
- vbif_qos = mdata->vbif_nrt_qos[i];
- reg_val |= vbif_qos << (XIN_SSPP * 2);
- /* ensure write is issued after the read operation */
- mb();
- SDE_VBIF_WRITE(mdata,
- MMSS_VBIF_NRT_VBIF_QOS_REMAP_00 + i*4,
- reg_val);
+
+ for (j = 0; j < mdata->nxid; j++) {
+ reg_high = ((mdata->vbif_xin_id[j] &
+ 0x8) >> 3) * 4 + (i * 8);
+
+ reg_val = SDE_VBIF_READ(mdata,
+ MDSS_VBIF_QOS_RP_REMAP_BASE + reg_high);
+ reg_val_lvl = SDE_VBIF_READ(mdata,
+ MDSS_VBIF_QOS_LVL_REMAP_BASE + reg_high);
+
+ mask = 0x3 << (mdata->vbif_xin_id[j] * 4);
+ vbif_qos = mdata->vbif_nrt_qos[i];
+
+ reg_val &= ~(mask);
+ reg_val |= vbif_qos <<
+ (mdata->vbif_xin_id[j] * 4);
+
+ reg_val_lvl &= ~(mask);
+ reg_val_lvl |= vbif_qos <<
+ (mdata->vbif_xin_id[j] * 4);
+
+ pr_debug("idx:%d xin:%d reg:0x%x val:0x%x lvl:0x%x\n",
+ i, mdata->vbif_xin_id[j],
+ reg_high, reg_val, reg_val_lvl);
+ SDE_VBIF_WRITE(mdata,
+ MDSS_VBIF_QOS_RP_REMAP_BASE +
+ reg_high, reg_val);
+ SDE_VBIF_WRITE(mdata,
+ MDSS_VBIF_QOS_LVL_REMAP_BASE +
+ reg_high, reg_val_lvl);
+ }
}
}
/* Enable write gather for writeback to remove write gaps, which
* may hang AXI/BIMC/SDE.
*/
- SDE_VBIF_WRITE(mdata, MMSS_VBIF_NRT_VBIF_WRITE_GATHTER_EN,
- BIT(XIN_WRITEBACK));
+ if (!((mdata->mdss_version == MDSS_MDP_HW_REV_320) ||
+ (mdata->mdss_version == MDSS_MDP_HW_REV_330)))
+ SDE_VBIF_WRITE(mdata, MMSS_VBIF_NRT_VBIF_WRITE_GATHTER_EN,
+ BIT(mdata->vbif_xin_id[XIN_WRITEBACK]));
+ if (mdata->vbif_reg_unlock)
+ mdata->vbif_reg_unlock();
return 0;
}
diff --git a/drivers/media/platform/msm/sde/rotator/sde_rotator_smmu.c b/drivers/media/platform/msm/sde/rotator/sde_rotator_smmu.c
index 46001fa7b429..9b1175d8f4a6 100644
--- a/drivers/media/platform/msm/sde/rotator/sde_rotator_smmu.c
+++ b/drivers/media/platform/msm/sde/rotator/sde_rotator_smmu.c
@@ -381,8 +381,12 @@ static void sde_smmu_callback(struct mdss_smmu_intf *smmu)
/* Copy mmu device info into sde private structure */
mdata->iommu_ctrl = smmu->iommu_ctrl;
+ mdata->vbif_reg_lock = smmu->reg_lock;
+ mdata->vbif_reg_unlock = smmu->reg_unlock;
mdata->wait_for_transition = smmu->wait_for_transition;
mdata->secure_session_ctrl = smmu->secure_session_ctrl;
+ mdata->handoff_pending = smmu->handoff_pending;
+
if (smmu->is_secure) {
mdata->sde_smmu[SDE_IOMMU_DOMAIN_ROT_SECURE].dev = smmu->dev;
mdata->sde_smmu[SDE_IOMMU_DOMAIN_ROT_SECURE].domain =
diff --git a/drivers/video/fbdev/msm/mdss.h b/drivers/video/fbdev/msm/mdss.h
index 0ab6ae4bb38f..6182aa2c626e 100644
--- a/drivers/video/fbdev/msm/mdss.h
+++ b/drivers/video/fbdev/msm/mdss.h
@@ -576,12 +576,15 @@ struct mdss_util_intf {
int (*iommu_ctrl)(int enable);
void (*iommu_lock)(void);
void (*iommu_unlock)(void);
+ void (*vbif_reg_lock)(void);
+ void (*vbif_reg_unlock)(void);
int (*secure_session_ctrl)(int enable);
void (*bus_bandwidth_ctrl)(int enable);
int (*bus_scale_set_quota)(int client, u64 ab_quota, u64 ib_quota);
int (*panel_intf_status)(u32 disp_num, u32 intf_type);
struct mdss_panel_cfg* (*panel_intf_type)(int intf_val);
int (*dyn_clk_gating_ctrl)(int enable);
+ bool (*mdp_handoff_pending)(void);
};
struct mdss_util_intf *mdss_get_util_intf(void);
diff --git a/drivers/video/fbdev/msm/mdss_mdp.c b/drivers/video/fbdev/msm/mdss_mdp.c
index 4ee22abda4a2..7efa9674e6e4 100644
--- a/drivers/video/fbdev/msm/mdss_mdp.c
+++ b/drivers/video/fbdev/msm/mdss_mdp.c
@@ -784,6 +784,26 @@ int mdss_update_reg_bus_vote(struct reg_bus_client *bus_client, u32 usecase_ndx)
}
#endif
+void mdss_mdp_vbif_reg_lock(void)
+{
+ struct mdss_data_type *mdata = mdss_mdp_get_mdata();
+
+ mutex_lock(&mdata->reg_lock);
+}
+
+void mdss_mdp_vbif_reg_unlock(void)
+{
+ struct mdss_data_type *mdata = mdss_mdp_get_mdata();
+
+ mutex_unlock(&mdata->reg_lock);
+}
+
+bool mdss_mdp_handoff_pending(void)
+{
+ struct mdss_data_type *mdata = mdss_mdp_get_mdata();
+
+ return mdata->handoff_pending;
+}
static int mdss_mdp_intr2index(u32 intr_type, u32 intf_num)
{
@@ -2869,6 +2889,9 @@ static int mdss_mdp_probe(struct platform_device *pdev)
mdss_res->mdss_util->bus_bandwidth_ctrl = mdss_bus_bandwidth_ctrl;
mdss_res->mdss_util->panel_intf_type = mdss_panel_intf_type;
mdss_res->mdss_util->panel_intf_status = mdss_panel_get_intf_status;
+ mdss_res->mdss_util->vbif_reg_lock = mdss_mdp_vbif_reg_lock;
+ mdss_res->mdss_util->vbif_reg_unlock = mdss_mdp_vbif_reg_unlock;
+ mdss_res->mdss_util->mdp_handoff_pending = mdss_mdp_handoff_pending;
rc = msm_dss_ioremap_byname(pdev, &mdata->mdss_io, "mdp_phys");
if (rc) {
diff --git a/drivers/video/fbdev/msm/mdss_smmu.c b/drivers/video/fbdev/msm/mdss_smmu.c
index 7ca0cd37d43c..6930444118b6 100644
--- a/drivers/video/fbdev/msm/mdss_smmu.c
+++ b/drivers/video/fbdev/msm/mdss_smmu.c
@@ -845,9 +845,12 @@ int mdss_smmu_probe(struct platform_device *pdev)
}
mdss_smmu->base.iommu_ctrl = mdata->mdss_util->iommu_ctrl;
+ mdss_smmu->base.reg_lock = mdata->mdss_util->vbif_reg_lock;
+ mdss_smmu->base.reg_unlock = mdata->mdss_util->vbif_reg_unlock;
mdss_smmu->base.secure_session_ctrl =
mdata->mdss_util->secure_session_ctrl;
mdss_smmu->base.wait_for_transition = mdss_smmu_secure_wait;
+ mdss_smmu->base.handoff_pending = mdata->mdss_util->mdp_handoff_pending;
list_add(&mdss_smmu->_client, &prv->smmu_device_list);
diff --git a/include/linux/mdss_smmu_ext.h b/include/linux/mdss_smmu_ext.h
index 414ab055595a..12ad4305f145 100644
--- a/include/linux/mdss_smmu_ext.h
+++ b/include/linux/mdss_smmu_ext.h
@@ -22,6 +22,7 @@
* @iommu_ctrl: iommu ctrl function for enable/disable attach.
* @secure_session_ctrl: ctrl function for enable/disable session.
* @wait_for_transition:function to wait till secure transtion is complete.
+ * @reg_lock /reg_unlock: Lock to access shared registers.
*/
struct mdss_smmu_intf {
struct device *dev;
@@ -30,6 +31,9 @@ struct mdss_smmu_intf {
int (*iommu_ctrl)(int);
int (*secure_session_ctrl)(int);
int (*wait_for_transition)(int state, int request);
+ void (*reg_lock)(void);
+ void (*reg_unlock)(void);
+ bool (*handoff_pending)(void);
};
typedef void (*msm_smmu_handler_t) (struct mdss_smmu_intf *smmu);