Merge branch 'mdss-final-replay' into msm-4.4
This merge brings all display changes from msm-3.18 kernel.
* (58 commits)
msm: mdss: add support for additional DMA pipes
msm: mdss: refactor device tree pipe parsing logic
msm: mdss: refactor mixer configuration code
msm: mdss: add support for secure display on msm8953.
msm: mdss: disable ECG feature on 28nm PHY platform
msm: mdss: send DSI command using TPG when in secure session
msm: mdss: Update histogram and PA LUT in mdss V3
msm: mdss: validate layer count before copying userdata
msm: mdss: Fix potential NULL pointer dereferences
Revert "msm: mdss: Remove redundant handoff pending check"
msm: mdss: hdmi: Do not treat intermediate ddc error as failure
msm: mdss: revisit igc pipe enumeration logic
msm: mdss: Add PA support for mdss V3
msm: mdss: Add support for mdss v3 ops
msm: mdss: Update the postprocessing ops using mdss revision
msm: mdss: update the caching payload based on mdss version
msm: clk: hdmi: add support for atomic update
msm: sde: Add v4l2 rotator driver to enable multi-context usecase
msm: mdss: refactor pipe type checks
msm: mdss: add proper layer zorder validation
msm: mdss: stub bus scaling functions if driver is disabled
msm: mdss: avoid failure if primary panel pref is not enabled
msm: adv7533: add support for clients to read audio block
msm: mdss: add lineptr interrupt support for command mode panels
msm: mdss: update rotator frame rate in the pipe configuration
mdss: msm: Avoid excessive failure logs in igc config
msm: mdss: delay dma commands for split-dsi cmd mode panels
msm: mdss: enable GDSC before enabling clocks in MDP3 probe
mdss: dsi: turn off phy power supply during static screen
mdss: dsi: read dsi and phy revision during dsi ctrl probe
msm: mdss: Fix memory leak in MDP3 driver
msm: mdss: delay overlay start until first update for external
msm: mdss: free splash memory for MSM8909w after splash done
msm: mdss: hdmi: separate audio from transmitter core
msm: mdss: disable dsi burst mode when idle is enabled
msm: mdss: remove invalid csc initialization during hw init
msm: mdss: dsi: increase dsi error count only for valid errors
msm: mdss: remove HIST LUT programming in mdss_hw_init
msm: mdss: dsi: ignore error interrupt when mask not set
msm: mdss: add support to configure bus scale vectors from dt
msm: mdss: unstage the pipe if there is z_order mismatch
msm: mdss: squash MDP3 driver changes and SMMU change
msm: mdss: Read the bridge chip name and instance id from DTSI
msm: mdss: Enable continuous splash on bridge chip
msm: mdss: Fix multiple bridge chip usecase
msm: mdss: Enable export of mdss interrupt to external driver
msm: mdss: rotator: turn off rotator clock in wq release
msm: mdss: fix ulps during suspend feature logic
clk: msm: mdss: program correct divider for PLL configuration
msm: mdss: fix DSI PHY timing configuration logic
msm: mdss: hdmi: add support for hdmi simulation
msm: mdss: handle race condition in pingpong done counter
clk: qcom: mdss: calculate pixel clock for HDMI during handoff
msm: mdss: ensure proper dynamic refresh programming for dual DSI
msm: mdss: Add fps flag and update blit request version
msm: mdss: initialize fb split values during fb probe
mdss: mdp: fix rotator compat layer copy
msm: mdss: handle DSI ctrl/PHY regulator control properly
Conflicts:
Documentation/devicetree/bindings/fb/mdss-dsi-panel.txt
Documentation/devicetree/bindings/fb/mdss-dsi.txt
Documentation/devicetree/bindings/fb/mdss-mdp.txt
arch/arm/boot/dts/qcom/dsi-adv7533-1080p.dtsi
arch/arm/boot/dts/qcom/dsi-adv7533-720p.dtsi
arch/arm/boot/dts/qcom/msm8996-agave-adp.dtsi
drivers/media/platform/msm/Kconfig
drivers/media/platform/msm/Makefile
drivers/misc/hdcp.c
drivers/video/fbdev/msm/Makefile
drivers/video/fbdev/msm/mdp3.c
drivers/video/fbdev/msm/mdp3.h
drivers/video/fbdev/msm/mdp3_ctrl.c
drivers/video/fbdev/msm/mdp3_ctrl.h
drivers/video/fbdev/msm/mdp3_dma.c
drivers/video/fbdev/msm/mdp3_dma.h
drivers/video/fbdev/msm/mdp3_hwio.h
drivers/video/fbdev/msm/mdp3_ppp.c
drivers/video/fbdev/msm/mdp3_ppp.h
drivers/video/fbdev/msm/mdp3_ppp_hwio.c
drivers/video/fbdev/msm/mdss.h
drivers/video/fbdev/msm/mdss_compat_utils.c
drivers/video/fbdev/msm/mdss_dba_utils.c
drivers/video/fbdev/msm/mdss_dba_utils.h
drivers/video/fbdev/msm/mdss_debug.c
drivers/video/fbdev/msm/mdss_dsi.c
drivers/video/fbdev/msm/mdss_dsi.h
drivers/video/fbdev/msm/mdss_dsi_clk.c
drivers/video/fbdev/msm/mdss_dsi_host.c
drivers/video/fbdev/msm/mdss_dsi_panel.c
drivers/video/fbdev/msm/mdss_fb.c
drivers/video/fbdev/msm/mdss_fb.h
drivers/video/fbdev/msm/mdss_hdmi_edid.c
drivers/video/fbdev/msm/mdss_hdmi_hdcp2p2.c
drivers/video/fbdev/msm/mdss_hdmi_tx.c
drivers/video/fbdev/msm/mdss_hdmi_tx.h
drivers/video/fbdev/msm/mdss_hdmi_util.c
drivers/video/fbdev/msm/mdss_mdp.c
drivers/video/fbdev/msm/mdss_mdp.h
drivers/video/fbdev/msm/mdss_mdp_ctl.c
drivers/video/fbdev/msm/mdss_mdp_hwio.h
drivers/video/fbdev/msm/mdss_mdp_intf_cmd.c
drivers/video/fbdev/msm/mdss_mdp_intf_writeback.c
drivers/video/fbdev/msm/mdss_mdp_layer.c
drivers/video/fbdev/msm/mdss_mdp_overlay.c
drivers/video/fbdev/msm/mdss_mdp_pipe.c
drivers/video/fbdev/msm/mdss_mdp_pp.c
drivers/video/fbdev/msm/mdss_mdp_pp.h
drivers/video/fbdev/msm/mdss_mdp_pp_cache_config.c
drivers/video/fbdev/msm/mdss_mdp_pp_v1_7.c
drivers/video/fbdev/msm/mdss_mdp_util.c
drivers/video/fbdev/msm/mdss_panel.h
drivers/video/fbdev/msm/mdss_rotator.c
drivers/video/fbdev/msm/mdss_rotator_internal.h
drivers/video/fbdev/msm/mdss_smmu.c
drivers/video/fbdev/msm/msm_dba/adv7533.c
drivers/video/fbdev/msm/msm_mdss_io_8974.c
include/uapi/linux/msm_mdp.h
include/video/msm_dba.h
CRs-Fixed: 1000197
Change-Id: I521519c8abe8eed6924e2fbe3e1a026126582b77
Signed-off-by: Adrian Salido-Moreno <adrianm@codeaurora.org>
Signed-off-by: Narendra Muppalla <narendram@codeaurora.org>
diff --git a/drivers/media/platform/msm/sde/rotator/sde_rotator_core.h b/drivers/media/platform/msm/sde/rotator/sde_rotator_core.h
new file mode 100644
index 0000000..5052ea1
--- /dev/null
+++ b/drivers/media/platform/msm/sde/rotator/sde_rotator_core.h
@@ -0,0 +1,411 @@
+/* Copyright (c) 2015-2016, 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
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef SDE_ROTATOR_CORE_H
+#define SDE_ROTATOR_CORE_H
+
+#include <linux/list.h>
+#include <linux/file.h>
+#include <linux/ktime.h>
+#include <linux/mutex.h>
+#include <linux/types.h>
+#include <linux/cdev.h>
+#include <linux/pm_runtime.h>
+
+#include "sde_rotator_base.h"
+#include "sde_rotator_util.h"
+#include "sde_rotator_sync.h"
+
+/**********************************************************************
+ * Rotation request flag
+ **********************************************************************/
+/* no rotation flag */
+#define SDE_ROTATION_NOP 0x01
+
+/* left/right flip */
+#define SDE_ROTATION_FLIP_LR 0x02
+
+/* up/down flip */
+#define SDE_ROTATION_FLIP_UD 0x04
+
+/* rotate 90 degree */
+#define SDE_ROTATION_90 0x08
+
+/* rotate 180 degre */
+#define SDE_ROTATION_180 (SDE_ROTATION_FLIP_LR | SDE_ROTATION_FLIP_UD)
+
+/* rotate 270 degree */
+#define SDE_ROTATION_270 (SDE_ROTATION_90 | SDE_ROTATION_180)
+
+/* format is interlaced */
+#define SDE_ROTATION_DEINTERLACE 0x10
+
+/* secure data */
+#define SDE_ROTATION_SECURE 0x80
+
+/* verify input configuration only */
+#define SDE_ROTATION_VERIFY_INPUT_ONLY 0x10000
+
+/* use client provided dma buf instead of ion fd */
+#define SDE_ROTATION_EXT_DMA_BUF 0x20000
+
+/*********************************************************************
+ *configuration structures
+ *********************************************************************/
+
+struct sde_rotation_buf_info {
+ uint32_t width;
+ uint32_t height;
+ uint32_t format;
+ struct sde_mult_factor comp_ratio;
+};
+
+struct sde_rotation_config {
+ uint32_t session_id;
+ struct sde_rotation_buf_info input;
+ struct sde_rotation_buf_info output;
+ uint32_t frame_rate;
+ uint32_t flags;
+};
+
+enum sde_rotator_ts {
+ SDE_ROTATOR_TS_SRCQB, /* enqueue source buffer */
+ SDE_ROTATOR_TS_DSTQB, /* enqueue destination buffer */
+ SDE_ROTATOR_TS_FENCE, /* wait for source buffer fence */
+ SDE_ROTATOR_TS_QUEUE, /* wait for h/w resource */
+ SDE_ROTATOR_TS_COMMIT, /* prepare h/w command */
+ SDE_ROTATOR_TS_FLUSH, /* initiate h/w processing */
+ SDE_ROTATOR_TS_DONE, /* receive h/w completion */
+ SDE_ROTATOR_TS_RETIRE, /* signal destination buffer fence */
+ SDE_ROTATOR_TS_SRCDQB, /* dequeue source buffer */
+ SDE_ROTATOR_TS_DSTDQB, /* dequeue destination buffer */
+ SDE_ROTATOR_TS_MAX
+};
+
+struct sde_rotation_item {
+ /* rotation request flag */
+ uint32_t flags;
+
+ /* Source crop rectangle */
+ struct sde_rect src_rect;
+
+ /* Destination rectangle */
+ struct sde_rect dst_rect;
+
+ /* Input buffer for the request */
+ struct sde_layer_buffer input;
+
+ /* The output buffer for the request */
+ struct sde_layer_buffer output;
+
+ /*
+ * DMA pipe selection for this request by client:
+ * 0: DMA pipe 0
+ * 1: DMA pipe 1
+ * or SDE_ROTATION_HW_ANY if client wants
+ * driver to allocate any that is available
+ *
+ * OR
+ *
+ * Reserved
+ */
+ uint32_t pipe_idx;
+
+ /*
+ * Write-back block selection for this request by client:
+ * 0: Write-back block 0
+ * 1: Write-back block 1
+ * or SDE_ROTATION_HW_ANY if client wants
+ * driver to allocate any that is available
+ *
+ * OR
+ *
+ * Priority selection for this request by client:
+ * 0: Highest
+ * 1..n: Limited by the lowest available priority
+ */
+ uint32_t wb_idx;
+
+ /*
+ * Sequence ID of this request within the session
+ */
+ uint32_t sequence_id;
+
+ /* Which session ID is this request scheduled on */
+ uint32_t session_id;
+
+ /* Time stamp for profiling purposes */
+ ktime_t *ts;
+};
+
+/*
+ * Defining characteristics about rotation work, that has corresponding
+ * fmt and roi checks in open session
+ */
+#define SDE_ROT_DEFINING_FLAG_BITS SDE_ROTATION_90
+
+struct sde_rot_entry;
+struct sde_rot_perf;
+
+struct sde_rot_clk {
+ struct clk *clk;
+ char clk_name[32];
+ unsigned long rate;
+};
+
+struct sde_rot_hw_resource {
+ u32 wb_id;
+ u32 pending_count;
+ atomic_t num_active;
+ int max_active;
+ wait_queue_head_t wait_queue;
+ struct sde_rot_entry *workload;
+};
+
+struct sde_rot_queue {
+ struct workqueue_struct *rot_work_queue;
+ struct sde_rot_timeline *timeline;
+ struct sde_rot_hw_resource *hw;
+};
+
+struct sde_rot_entry_container {
+ struct list_head list;
+ u32 flags;
+ u32 count;
+ atomic_t pending_count;
+ atomic_t failed_count;
+ struct workqueue_struct *retireq;
+ struct work_struct *retire_work;
+ struct sde_rot_entry *entries;
+};
+
+struct sde_rot_mgr;
+struct sde_rot_file_private;
+
+struct sde_rot_entry {
+ struct sde_rotation_item item;
+ struct work_struct commit_work;
+ struct work_struct done_work;
+ struct sde_rot_queue *commitq;
+ struct sde_rot_queue *fenceq;
+ struct sde_rot_queue *doneq;
+ struct sde_rot_entry_container *request;
+
+ struct sde_mdp_data src_buf;
+ struct sde_mdp_data dst_buf;
+
+ struct sde_rot_sync_fence *input_fence;
+
+ struct sde_rot_sync_fence *output_fence;
+ bool output_signaled;
+
+ u32 dnsc_factor_w;
+ u32 dnsc_factor_h;
+
+ struct sde_rot_perf *perf;
+ bool work_assigned; /* Used when cleaning up work_distribution */
+ struct sde_rot_file_private *private;
+};
+
+struct sde_rot_perf {
+ struct list_head list;
+ struct sde_rotation_config config;
+ unsigned long clk_rate;
+ u64 bw;
+ struct mutex work_dis_lock;
+ u32 *work_distribution;
+ int last_wb_idx; /* last known wb index, used when above count is 0 */
+};
+
+struct sde_rot_file_private {
+ struct list_head list;
+ struct list_head req_list;
+ struct list_head perf_list;
+ struct sde_rot_mgr *mgr;
+ struct sde_rot_queue *fenceq;
+};
+
+struct sde_rot_bus_data_type {
+ struct msm_bus_scale_pdata *bus_scale_pdata;
+ u32 bus_hdl;
+ u32 curr_bw_uc_idx;
+ u64 curr_quota_val;
+};
+
+struct sde_rot_mgr {
+ struct mutex lock;
+ atomic_t device_suspended;
+ struct platform_device *pdev;
+ struct device *device;
+
+ /*
+ * Managing rotation queues, depends on
+ * how many hw pipes available on the system
+ */
+ int queue_count;
+ struct sde_rot_queue *commitq;
+ struct sde_rot_queue *doneq;
+
+ /*
+ * managing all the open file sessions to bw calculations,
+ * and resource clean up during suspend
+ */
+ struct list_head file_list;
+
+ u64 pending_close_bw_vote;
+ struct sde_rot_bus_data_type data_bus;
+ struct sde_rot_bus_data_type reg_bus;
+
+ /* Module power is only used for regulator management */
+ struct sde_module_power module_power;
+ bool regulator_enable;
+
+ int res_ref_cnt;
+ int rot_enable_clk_cnt;
+ struct sde_rot_clk *rot_clk;
+ int num_rot_clk;
+ int core_clk_idx;
+
+ u32 hwacquire_timeout;
+ struct sde_mult_factor pixel_per_clk;
+
+ int (*ops_config_hw)(struct sde_rot_hw_resource *hw,
+ struct sde_rot_entry *entry);
+ int (*ops_kickoff_entry)(struct sde_rot_hw_resource *hw,
+ struct sde_rot_entry *entry);
+ int (*ops_wait_for_entry)(struct sde_rot_hw_resource *hw,
+ struct sde_rot_entry *entry);
+ struct sde_rot_hw_resource *(*ops_hw_alloc)(struct sde_rot_mgr *mgr,
+ u32 pipe_id, u32 wb_id);
+ void (*ops_hw_free)(struct sde_rot_mgr *mgr,
+ struct sde_rot_hw_resource *hw);
+ int (*ops_hw_init)(struct sde_rot_mgr *mgr);
+ void (*ops_hw_destroy)(struct sde_rot_mgr *mgr);
+ ssize_t (*ops_hw_show_caps)(struct sde_rot_mgr *mgr,
+ struct device_attribute *attr, char *buf, ssize_t len);
+ ssize_t (*ops_hw_show_state)(struct sde_rot_mgr *mgr,
+ struct device_attribute *attr, char *buf, ssize_t len);
+ int (*ops_hw_create_debugfs)(struct sde_rot_mgr *mgr,
+ struct dentry *debugfs_root);
+ int (*ops_hw_validate_entry)(struct sde_rot_mgr *mgr,
+ struct sde_rot_entry *entry);
+
+ void *hw_data;
+};
+
+static inline int __compare_session_item_rect(
+ struct sde_rotation_buf_info *s_rect,
+ struct sde_rect *i_rect, uint32_t i_fmt, bool src)
+{
+ if ((s_rect->width != i_rect->w) || (s_rect->height != i_rect->h) ||
+ (s_rect->format != i_fmt)) {
+ SDEROT_DBG(
+ "%s: session{%u,%u}f:%u mismatch from item{%u,%u}f:%u\n",
+ (src ? "src":"dst"), s_rect->width, s_rect->height,
+ s_rect->format, i_rect->w, i_rect->h, i_fmt);
+ return -EINVAL;
+ }
+ return 0;
+}
+
+/*
+ * Compare all important flag bits associated with rotation between session
+ * config and item request. Format and roi validation is done during open
+ * session and is based certain defining bits. If these defining bits are
+ * different in item request, there is a possibility that rotation item
+ * is not a valid configuration.
+ */
+static inline int __compare_session_rotations(uint32_t cfg_flag,
+ uint32_t item_flag)
+{
+ cfg_flag &= SDE_ROT_DEFINING_FLAG_BITS;
+ item_flag &= SDE_ROT_DEFINING_FLAG_BITS;
+ if (cfg_flag != item_flag) {
+ SDEROT_DBG(
+ "Rotation degree request different from open session\n");
+ return -EINVAL;
+ }
+ return 0;
+}
+
+int sde_rotator_core_init(struct sde_rot_mgr **pmgr,
+ struct platform_device *pdev);
+
+void sde_rotator_core_destroy(struct sde_rot_mgr *mgr);
+
+int sde_rotator_session_open(struct sde_rot_mgr *mgr,
+ struct sde_rot_file_private **pprivate, int session_id,
+ struct sde_rot_queue *queue);
+
+void sde_rotator_session_close(struct sde_rot_mgr *mgr,
+ struct sde_rot_file_private *private, int session_id);
+
+int sde_rotator_session_config(struct sde_rot_mgr *mgr,
+ struct sde_rot_file_private *private,
+ struct sde_rotation_config *config);
+
+struct sde_rot_entry_container *sde_rotator_req_init(
+ struct sde_rot_mgr *rot_dev,
+ struct sde_rot_file_private *private,
+ struct sde_rotation_item *items,
+ u32 count, u32 flags);
+
+int sde_rotator_handle_request_common(struct sde_rot_mgr *rot_dev,
+ struct sde_rot_file_private *ctx,
+ struct sde_rot_entry_container *req,
+ struct sde_rotation_item *items);
+
+void sde_rotator_queue_request(struct sde_rot_mgr *rot_dev,
+ struct sde_rot_file_private *ctx,
+ struct sde_rot_entry_container *req);
+
+void sde_rotator_remove_request(struct sde_rot_mgr *mgr,
+ struct sde_rot_file_private *private,
+ struct sde_rot_entry_container *req);
+
+int sde_rotator_verify_config(struct sde_rot_mgr *rot_dev,
+ struct sde_rotation_config *config);
+
+int sde_rotator_validate_request(struct sde_rot_mgr *rot_dev,
+ struct sde_rot_file_private *ctx,
+ struct sde_rot_entry_container *req);
+
+static inline void sde_rot_mgr_lock(struct sde_rot_mgr *mgr)
+{
+ mutex_lock(&mgr->lock);
+}
+
+static inline void sde_rot_mgr_unlock(struct sde_rot_mgr *mgr)
+{
+ mutex_unlock(&mgr->lock);
+}
+
+#if defined(CONFIG_PM_RUNTIME)
+int sde_rotator_runtime_resume(struct device *dev);
+int sde_rotator_runtime_suspend(struct device *dev);
+int sde_rotator_runtime_idle(struct device *dev);
+#endif
+
+#if defined(CONFIG_PM_SLEEP)
+int sde_rotator_pm_suspend(struct device *dev);
+int sde_rotator_pm_resume(struct device *dev);
+#endif
+
+#if defined(CONFIG_PM) && !defined(CONFIG_PM_SLEEP)
+int sde_rotator_suspend(struct platform_device *dev, pm_message_t state);
+int sde_rotator_resume(struct platform_device *dev);
+#else
+#define sde_rotator_suspend NULL
+#define sde_rotator_resume NULL
+#endif
+#endif /* __SDE_ROTATOR_CORE_H__ */