summaryrefslogtreecommitdiff
path: root/drivers/gpu/ipu-v3/ipu-pre.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2017-10-13 18:10:35 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2017-10-13 18:10:35 -0700
commit9aa0d2dde6ebd14e9d16e28081a24721d5b41cc8 (patch)
tree643d0c8355939ea6a5755b72b1028474ace565c1 /drivers/gpu/ipu-v3/ipu-pre.c
parent06d97c58f65cc747573a3fa8569cca0169e5096e (diff)
parenta480f30846d19b50106b3243d9d48683d2966249 (diff)
Merge tag 'drm-fixes-for-v4.14-rc5' of git://people.freedesktop.org/~airlied/linux
Pull drm fixes from Dave Airlie: "Couple of the arm people seem to wake up so this has imx and msm fixes, along with a bunch of i915 stable bounds fixes and an amdgpu regression fix. All seems pretty okay for now" * tag 'drm-fixes-for-v4.14-rc5' of git://people.freedesktop.org/~airlied/linux: drm/msm: fix _NO_IMPLICIT fencing case drm/msm: fix error path cleanup drm/msm/mdp5: Remove extra pm_runtime_put call in mdp5_crtc_cursor_set() drm/msm/dsi: Use correct pm_runtime_put variant during host_init drm/msm: fix return value check in _msm_gem_kernel_new() drm/msm: use proper memory barriers for updating tail/head drm/msm/mdp5: add missing max size for 8x74 v1 drm/amdgpu: fix placement flags in amdgpu_ttm_bind drm/i915/bios: parse DDI ports also for CHV for HDMI DDC pin and DP AUX channel gpu: ipu-v3: pre: implement workaround for ERR009624 gpu: ipu-v3: prg: wait for double buffers to be filled on channel startup gpu: ipu-v3: Allow channel burst locking on i.MX6 only drm/i915: Read timings from the correct transcoder in intel_crtc_mode_get() drm/i915: Order two completing nop_submit_request drm/i915: Silence compiler warning for hsw_power_well_enable() drm/i915: Use crtc_state_is_legacy_gamma in intel_color_check drm/i915/edp: Increase the T12 delay quirk to 1300ms drm/i915/edp: Get the Panel Power Off timestamp after panel is off sync_file: Return consistent status in SYNC_IOC_FILE_INFO drm/atomic: Unref duplicated drm_atomic_state in drm_atomic_helper_resume()
Diffstat (limited to 'drivers/gpu/ipu-v3/ipu-pre.c')
-rw-r--r--drivers/gpu/ipu-v3/ipu-pre.c29
1 files changed, 29 insertions, 0 deletions
diff --git a/drivers/gpu/ipu-v3/ipu-pre.c b/drivers/gpu/ipu-v3/ipu-pre.c
index c35f74c83065..c860a7997cb5 100644
--- a/drivers/gpu/ipu-v3/ipu-pre.c
+++ b/drivers/gpu/ipu-v3/ipu-pre.c
@@ -73,6 +73,14 @@
#define IPU_PRE_STORE_ENG_CTRL_WR_NUM_BYTES(v) ((v & 0x7) << 1)
#define IPU_PRE_STORE_ENG_CTRL_OUTPUT_ACTIVE_BPP(v) ((v & 0x3) << 4)
+#define IPU_PRE_STORE_ENG_STATUS 0x120
+#define IPU_PRE_STORE_ENG_STATUS_STORE_BLOCK_X_MASK 0xffff
+#define IPU_PRE_STORE_ENG_STATUS_STORE_BLOCK_X_SHIFT 0
+#define IPU_PRE_STORE_ENG_STATUS_STORE_BLOCK_Y_MASK 0x3fff
+#define IPU_PRE_STORE_ENG_STATUS_STORE_BLOCK_Y_SHIFT 16
+#define IPU_PRE_STORE_ENG_STATUS_STORE_FIFO_FULL (1 << 30)
+#define IPU_PRE_STORE_ENG_STATUS_STORE_FIELD (1 << 31)
+
#define IPU_PRE_STORE_ENG_SIZE 0x130
#define IPU_PRE_STORE_ENG_SIZE_INPUT_WIDTH(v) ((v & 0xffff) << 0)
#define IPU_PRE_STORE_ENG_SIZE_INPUT_HEIGHT(v) ((v & 0xffff) << 16)
@@ -93,6 +101,7 @@ struct ipu_pre {
dma_addr_t buffer_paddr;
void *buffer_virt;
bool in_use;
+ unsigned int safe_window_end;
};
static DEFINE_MUTEX(ipu_pre_list_mutex);
@@ -160,6 +169,9 @@ void ipu_pre_configure(struct ipu_pre *pre, unsigned int width,
u32 active_bpp = info->cpp[0] >> 1;
u32 val;
+ /* calculate safe window for ctrl register updates */
+ pre->safe_window_end = height - 2;
+
writel(bufaddr, pre->regs + IPU_PRE_CUR_BUF);
writel(bufaddr, pre->regs + IPU_PRE_NEXT_BUF);
@@ -199,7 +211,24 @@ void ipu_pre_configure(struct ipu_pre *pre, unsigned int width,
void ipu_pre_update(struct ipu_pre *pre, unsigned int bufaddr)
{
+ unsigned long timeout = jiffies + msecs_to_jiffies(5);
+ unsigned short current_yblock;
+ u32 val;
+
writel(bufaddr, pre->regs + IPU_PRE_NEXT_BUF);
+
+ do {
+ if (time_after(jiffies, timeout)) {
+ dev_warn(pre->dev, "timeout waiting for PRE safe window\n");
+ return;
+ }
+
+ val = readl(pre->regs + IPU_PRE_STORE_ENG_STATUS);
+ current_yblock =
+ (val >> IPU_PRE_STORE_ENG_STATUS_STORE_BLOCK_Y_SHIFT) &
+ IPU_PRE_STORE_ENG_STATUS_STORE_BLOCK_Y_MASK;
+ } while (current_yblock == 0 || current_yblock >= pre->safe_window_end);
+
writel(IPU_PRE_CTRL_SDW_UPDATE, pre->regs + IPU_PRE_CTRL_SET);
}