diff options
| -rw-r--r-- | Documentation/devicetree/bindings/fb/mdss-mdp.txt | 22 | ||||
| -rw-r--r-- | drivers/video/fbdev/msm/mdss.h | 1 | ||||
| -rw-r--r-- | drivers/video/fbdev/msm/mdss_mdp.c | 54 | ||||
| -rw-r--r-- | drivers/video/fbdev/msm/mdss_mdp.h | 10 | ||||
| -rw-r--r-- | drivers/video/fbdev/msm/mdss_mdp_hwio.h | 2 | ||||
| -rw-r--r-- | drivers/video/fbdev/msm/mdss_mdp_pipe.c | 33 | ||||
| -rw-r--r-- | include/uapi/linux/msm_mdp.h | 2 |
7 files changed, 122 insertions, 2 deletions
diff --git a/Documentation/devicetree/bindings/fb/mdss-mdp.txt b/Documentation/devicetree/bindings/fb/mdss-mdp.txt index 964d3060ac31..9c9cbbd49c41 100644 --- a/Documentation/devicetree/bindings/fb/mdss-mdp.txt +++ b/Documentation/devicetree/bindings/fb/mdss-mdp.txt @@ -338,6 +338,23 @@ Fudge Factors: Fudge factors are used to boost demand for command mode panels. - qcom,max-bandwidth-per-pipe-kbps: This value indicates the max bandwidth in KB that a single pipe can support without underflow. +- qcom,mdss-has-panic-ctrl: Boolean property to indicate if panic/robust signal + control feature is available or not. +- qcom,mdss-pipe-vig-panic-ctrl-offsets: Array of panic/robust signal offsets + corresponding to the respective VIG pipes. + Number of signal offsets should match the + number of offsets defined in property: + qcom,mdss-pipe-vig-off +- qcom,mdss-pipe-rgb-panic-ctrl-offsets: Array of panic/robust signal offsets + corresponding to the respective RGB pipes. + Number of signal offsets should match the + number of offsets defined in property: + qcom,mdss-pipe-rgb-off +- qcom,mdss-pipe-dma-panic-ctrl-offsets: Array of panic/robust signal offsets + corresponding to the respective DMA pipes. + Number of signal offsets should match the + number of offsets defined in property: + qcom,mdss-pipe-dma-off Optional subnodes: Child nodes representing the frame buffer virtual devices. @@ -464,6 +481,11 @@ Example: qcom,mdss-pipe-dma-clk-ctrl-offsets = <0x3AC 8 12>, <0x3B4 8 12>; + qcom,mdss-has-panic-ctrl; + qcom,mdss-pipe-vig-panic-ctrl-offsets = <0 1 2 3>; + qcom,mdss-pipe-rgb-panic-ctrl-offsets = <4 5 6 7>; + qcom,mdss-pipe-dma-panic-ctrl-offsets = <8 9>; + qcom,mdss-pipe-sw-reset-off = <0x0128>; qcom,mdss-pipe-vig-sw-reset-map = <5 6 7 8>; qcom,mdss-pipe-rgb-sw-reset-map = <9 10 11 12>; diff --git a/drivers/video/fbdev/msm/mdss.h b/drivers/video/fbdev/msm/mdss.h index 225fe345fffe..31f94e254e05 100644 --- a/drivers/video/fbdev/msm/mdss.h +++ b/drivers/video/fbdev/msm/mdss.h @@ -122,6 +122,7 @@ struct mdss_data_type { u32 irq_buzy; u32 has_bwc; u32 has_decimation; + bool has_panic_ctrl; u32 wfd_mode; u32 has_no_lut_read; u8 has_wb_ad; diff --git a/drivers/video/fbdev/msm/mdss_mdp.c b/drivers/video/fbdev/msm/mdss_mdp.c index 75f2e77a8c4d..307b3458b924 100644 --- a/drivers/video/fbdev/msm/mdss_mdp.c +++ b/drivers/video/fbdev/msm/mdss_mdp.c @@ -1726,6 +1726,46 @@ static int mdss_mdp_parse_dt_pipe_clk_ctrl(struct platform_device *pdev, return rc; } +static void mdss_mdp_parse_dt_pipe_panic_ctrl(struct platform_device *pdev, + char *prop_name, struct mdss_mdp_pipe *pipe_list, u32 npipes) +{ + int rc = 0; + int i, j; + size_t len; + const u32 *arr; + struct mdss_mdp_pipe *pipe = NULL; + struct mdss_data_type *mdata = platform_get_drvdata(pdev); + + arr = of_get_property(pdev->dev.of_node, prop_name, (int *) &len); + if (arr) { + len /= sizeof(u32); + for (i = 0, j = 0; i < len; j++) { + if (j >= npipes) { + pr_err("invalid panic ctrl enries for prop: %s\n", + prop_name); + goto error; + } + + pipe = &pipe_list[j]; + pipe->panic_ctrl_ndx = be32_to_cpu(arr[i++]); + } + if (j != npipes) { + pr_err("%s: %d entries found. required %d\n", + prop_name, j, npipes); + rc = -EINVAL; + goto error; + } + } else { + pr_debug("panic ctrl enabled but property '%s' not found\n", + prop_name); + rc = -EINVAL; + } + +error: + if (rc) + mdata->has_panic_ctrl = false; +} + static int mdss_mdp_parse_dt_pipe(struct platform_device *pdev) { u32 npipes, dma_off; @@ -1954,6 +1994,20 @@ static int mdss_mdp_parse_dt_pipe(struct platform_device *pdev) mdata->ndma_pipes); } + mdata->has_panic_ctrl = of_property_read_bool(pdev->dev.of_node, + "qcom,mdss-has-panic-ctrl"); + if (mdata->has_panic_ctrl) { + mdss_mdp_parse_dt_pipe_panic_ctrl(pdev, + "qcom,mdss-pipe-vig-panic-ctrl-offsets", + mdata->vig_pipes, mdata->nvig_pipes); + mdss_mdp_parse_dt_pipe_panic_ctrl(pdev, + "qcom,mdss-pipe-rgb-panic-ctrl-offsets", + mdata->rgb_pipes, mdata->nrgb_pipes); + mdss_mdp_parse_dt_pipe_panic_ctrl(pdev, + "qcom,mdss-pipe-dma-panic-ctrl-offsets", + mdata->dma_pipes, mdata->ndma_pipes); + } + goto parse_done; parse_fail: diff --git a/drivers/video/fbdev/msm/mdss_mdp.h b/drivers/video/fbdev/msm/mdss_mdp.h index 0ca1396b4d5b..398e34ad6310 100644 --- a/drivers/video/fbdev/msm/mdss_mdp.h +++ b/drivers/video/fbdev/msm/mdss_mdp.h @@ -368,6 +368,7 @@ struct mdss_mdp_pipe { char __iomem *base; u32 ftch_id; u32 xin_id; + u32 panic_ctrl_ndx; struct mdss_mdp_shared_reg_ctrl clk_ctrl; struct mdss_mdp_shared_reg_ctrl clk_status; struct mdss_mdp_shared_reg_ctrl sw_reset; @@ -554,6 +555,14 @@ static inline int mdss_mdp_line_buffer_width(void) return MAX_LINE_BUFFER_WIDTH; } +static inline int mdss_mdp_panic_signal_supported( + struct mdss_data_type *mdata, struct mdss_mdp_pipe *pipe) +{ + return (IS_MDSS_MAJOR_MINOR_SAME(mdata->mdp_rev, MDSS_MDP_HW_REV_105) && + pipe->mixer_left && + pipe->mixer_left->type == MDSS_MDP_MIXER_TYPE_INTF); +} + irqreturn_t mdss_mdp_isr(int irq, void *ptr); int mdss_iommu_attach(struct mdss_data_type *mdata); int mdss_iommu_dettach(struct mdss_data_type *mdata); @@ -726,6 +735,7 @@ int mdss_mdp_ctl_addr_setup(struct mdss_data_type *mdata, u32 *ctl_offsets, u32 *wb_offsets, u32 len); int mdss_mdp_pipe_fetch_halt(struct mdss_mdp_pipe *pipe); +int mdss_mdp_pipe_panic_signal_ctrl(struct mdss_mdp_pipe *pipe, bool enable); int mdss_mdp_pipe_destroy(struct mdss_mdp_pipe *pipe); int mdss_mdp_pipe_queue_data(struct mdss_mdp_pipe *pipe, struct mdss_mdp_data *src_data); diff --git a/drivers/video/fbdev/msm/mdss_mdp_hwio.h b/drivers/video/fbdev/msm/mdss_mdp_hwio.h index 02f21a4ab85e..7fc4818444c6 100644 --- a/drivers/video/fbdev/msm/mdss_mdp_hwio.h +++ b/drivers/video/fbdev/msm/mdss_mdp_hwio.h @@ -42,6 +42,8 @@ #define MDSS_MDP_REG_HIST_INTR_CLEAR 0x00024 #define MMSS_MDP_MDP_SSPP_SPARE_0 0x00028 +#define MMSS_MDP_PANIC_ROBUST_CTRL 0x00178 + #define MDSS_MDP_REG_VIDEO_INTF_UNDERFLOW_CTL 0x002E0 #define MDSS_MDP_REG_SPLIT_DISPLAY_EN 0x002F4 #define MDSS_MDP_REG_SPLIT_DISPLAY_UPPER_PIPE_CTRL 0x002F8 diff --git a/drivers/video/fbdev/msm/mdss_mdp_pipe.c b/drivers/video/fbdev/msm/mdss_mdp_pipe.c index f899c7f558bb..35689008bbf4 100644 --- a/drivers/video/fbdev/msm/mdss_mdp_pipe.c +++ b/drivers/video/fbdev/msm/mdss_mdp_pipe.c @@ -53,6 +53,27 @@ static inline u32 mdss_mdp_pipe_read(struct mdss_mdp_pipe *pipe, u32 reg) return readl_relaxed(pipe->base + reg); } +int mdss_mdp_pipe_panic_signal_ctrl(struct mdss_mdp_pipe *pipe, bool enable) +{ + uint32_t panic_robust_ctrl; + struct mdss_data_type *mdata = mdss_mdp_get_mdata(); + + if (!mdata->has_panic_ctrl) + goto end; + + panic_robust_ctrl = readl_relaxed(mdata->mdp_base + + MMSS_MDP_PANIC_ROBUST_CTRL); + if (enable) + panic_robust_ctrl |= BIT(pipe->panic_ctrl_ndx); + else + panic_robust_ctrl &= ~BIT(pipe->panic_ctrl_ndx); + writel_relaxed(panic_robust_ctrl, + mdata->mdp_base + MMSS_MDP_PANIC_ROBUST_CTRL); + +end: + return 0; +} + static u32 mdss_mdp_smp_mmb_reserve(struct mdss_mdp_pipe_smp_map *smp_map, size_t n) { @@ -609,6 +630,9 @@ static struct mdss_mdp_pipe *mdss_mdp_pipe_init(struct mdss_mdp_mixer *mixer, return NULL; } + if (pipe && mdss_mdp_pipe_panic_signal_ctrl(pipe, false)) + return NULL; + if (pipe && mdss_mdp_pipe_is_sw_reset_available(mdata)) { force_off_mask = BIT(pipe->clk_ctrl.bit_off + CLK_FORCE_OFF_OFFSET); @@ -759,15 +783,17 @@ static void mdss_mdp_pipe_free(struct kref *kref) pr_debug("ndx=%x pnum=%d\n", pipe->ndx, pipe->num); + mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_ON, false); + mdss_mdp_pipe_panic_signal_ctrl(pipe, false); + if (pipe->play_cnt) { - mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_ON, false); mdss_mdp_pipe_fetch_halt(pipe); mdss_mdp_pipe_sspp_term(pipe); mdss_mdp_smp_free(pipe); - mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_OFF, false); } else { mdss_mdp_smp_unreserve(pipe); } + mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_OFF, false); pipe->flags = 0; pipe->is_right_blend = false; @@ -1380,6 +1406,9 @@ int mdss_mdp_pipe_queue_data(struct mdss_mdp_pipe *pipe, if (pipe->type == MDSS_MDP_PIPE_TYPE_VIG) mdss_mdp_pipe_write(pipe, MDSS_MDP_REG_VIG_OP_MODE, opmode); + + if (mdss_mdp_panic_signal_supported(mdata, pipe)) + mdss_mdp_pipe_panic_signal_ctrl(pipe, true); } if ((pipe->flags & MDP_VPU_PIPE) && (src_data == NULL || diff --git a/include/uapi/linux/msm_mdp.h b/include/uapi/linux/msm_mdp.h index 0ea47d495353..8300297dec35 100644 --- a/include/uapi/linux/msm_mdp.h +++ b/include/uapi/linux/msm_mdp.h @@ -98,6 +98,8 @@ #define MDSS_MDP_HW_REV_102_1 MDSS_MDP_REV(1, 2, 1) /* 8974 v3.0 (Pro) */ #define MDSS_MDP_HW_REV_103 MDSS_MDP_REV(1, 3, 0) /* 8084 v1.0 */ #define MDSS_MDP_HW_REV_103_1 MDSS_MDP_REV(1, 3, 1) /* 8084 v1.1 */ +#define MDSS_MDP_HW_REV_105 MDSS_MDP_REV(1, 5, 0) /* 8994 v1.0 */ +#define MDSS_MDP_HW_REV_106 MDSS_MDP_REV(1, 6, 0) /* 8916 v1.0 */ #define MDSS_MDP_HW_REV_200 MDSS_MDP_REV(2, 0, 0) /* 8092 v1.0 */ enum { |
