Commit 5866bec2 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'drm-fixes-for-v4.15-rc7' of git://people.freedesktop.org/~airlied/linux

Pull drm fixes from Dave Airlie:
 "Just collecting some fixes to finish my hoildays :-).

  A few fixes for i915 (one documentation build fix), one ttm fix, one
  AMD display fix, one omapdrm fix, and a set of armada fixes from
  Russell.

  All seem pretty small, you can now return to your latest security news
  site"

* tag 'drm-fixes-for-v4.15-rc7' of git://people.freedesktop.org/~airlied/linux:
  drm/i915: Apply Display WA #1183 on skl, kbl, and cfl
  drm/ttm: check the return value of kzalloc
  drm/amd/display: call set csc_default if enable adjustment is false
  docs: fix, intel_guc_loader.c has been moved to intel_guc_fw.c
  omapdrm/dss/hdmi4_cec: fix interrupt handling
  documentation/gpu/i915: fix docs build error after file rename
  drm/i915: Put all non-blocking modesets onto an ordered wq
  drm/i915: Disable DC states around GMBUS on GLK
  drm/i915/psr: Fix register name mess up.
  drm/armada: fix YUV planar format framebuffer offsets
  drm/armada: improve efficiency of armada_drm_plane_calc_addrs()
  drm/armada: fix UV swap code
  drm/armada: fix SRAM powerdown
  drm/armada: fix leak of crtc structure
parents e1915c81 bc6fe533
...@@ -341,10 +341,7 @@ GuC ...@@ -341,10 +341,7 @@ GuC
GuC-specific firmware loader GuC-specific firmware loader
---------------------------- ----------------------------
.. kernel-doc:: drivers/gpu/drm/i915/intel_guc_loader.c .. kernel-doc:: drivers/gpu/drm/i915/intel_guc_fw.c
:doc: GuC-specific firmware loader
.. kernel-doc:: drivers/gpu/drm/i915/intel_guc_loader.c
:internal: :internal:
GuC-based command submission GuC-based command submission
......
...@@ -1360,7 +1360,7 @@ void dpp1_cm_set_output_csc_adjustment( ...@@ -1360,7 +1360,7 @@ void dpp1_cm_set_output_csc_adjustment(
void dpp1_cm_set_output_csc_default( void dpp1_cm_set_output_csc_default(
struct dpp *dpp_base, struct dpp *dpp_base,
const struct default_adjustment *default_adjust); enum dc_color_space colorspace);
void dpp1_cm_set_gamut_remap( void dpp1_cm_set_gamut_remap(
struct dpp *dpp, struct dpp *dpp,
......
...@@ -225,14 +225,13 @@ void dpp1_cm_set_gamut_remap( ...@@ -225,14 +225,13 @@ void dpp1_cm_set_gamut_remap(
void dpp1_cm_set_output_csc_default( void dpp1_cm_set_output_csc_default(
struct dpp *dpp_base, struct dpp *dpp_base,
const struct default_adjustment *default_adjust) enum dc_color_space colorspace)
{ {
struct dcn10_dpp *dpp = TO_DCN10_DPP(dpp_base); struct dcn10_dpp *dpp = TO_DCN10_DPP(dpp_base);
uint32_t ocsc_mode = 0; uint32_t ocsc_mode = 0;
if (default_adjust != NULL) { switch (colorspace) {
switch (default_adjust->out_color_space) {
case COLOR_SPACE_SRGB: case COLOR_SPACE_SRGB:
case COLOR_SPACE_2020_RGB_FULLRANGE: case COLOR_SPACE_2020_RGB_FULLRANGE:
ocsc_mode = 0; ocsc_mode = 0;
...@@ -254,7 +253,6 @@ void dpp1_cm_set_output_csc_default( ...@@ -254,7 +253,6 @@ void dpp1_cm_set_output_csc_default(
default: default:
break; break;
} }
}
REG_SET(CM_OCSC_CONTROL, 0, CM_OCSC_MODE, ocsc_mode); REG_SET(CM_OCSC_CONTROL, 0, CM_OCSC_MODE, ocsc_mode);
......
...@@ -2097,6 +2097,8 @@ static void program_csc_matrix(struct pipe_ctx *pipe_ctx, ...@@ -2097,6 +2097,8 @@ static void program_csc_matrix(struct pipe_ctx *pipe_ctx,
tbl_entry.color_space = color_space; tbl_entry.color_space = color_space;
//tbl_entry.regval = matrix; //tbl_entry.regval = matrix;
pipe_ctx->plane_res.dpp->funcs->opp_set_csc_adjustment(pipe_ctx->plane_res.dpp, &tbl_entry); pipe_ctx->plane_res.dpp->funcs->opp_set_csc_adjustment(pipe_ctx->plane_res.dpp, &tbl_entry);
} else {
pipe_ctx->plane_res.dpp->funcs->opp_set_csc_default(pipe_ctx->plane_res.dpp, colorspace);
} }
} }
static bool is_lower_pipe_tree_visible(struct pipe_ctx *pipe_ctx) static bool is_lower_pipe_tree_visible(struct pipe_ctx *pipe_ctx)
......
...@@ -64,7 +64,7 @@ struct dpp_funcs { ...@@ -64,7 +64,7 @@ struct dpp_funcs {
void (*opp_set_csc_default)( void (*opp_set_csc_default)(
struct dpp *dpp, struct dpp *dpp,
const struct default_adjustment *default_adjust); enum dc_color_space colorspace);
void (*opp_set_csc_adjustment)( void (*opp_set_csc_adjustment)(
struct dpp *dpp, struct dpp *dpp,
......
...@@ -168,16 +168,23 @@ static void armada_drm_crtc_update(struct armada_crtc *dcrtc) ...@@ -168,16 +168,23 @@ static void armada_drm_crtc_update(struct armada_crtc *dcrtc)
void armada_drm_plane_calc_addrs(u32 *addrs, struct drm_framebuffer *fb, void armada_drm_plane_calc_addrs(u32 *addrs, struct drm_framebuffer *fb,
int x, int y) int x, int y)
{ {
const struct drm_format_info *format = fb->format;
unsigned int num_planes = format->num_planes;
u32 addr = drm_fb_obj(fb)->dev_addr; u32 addr = drm_fb_obj(fb)->dev_addr;
int num_planes = fb->format->num_planes;
int i; int i;
if (num_planes > 3) if (num_planes > 3)
num_planes = 3; num_planes = 3;
for (i = 0; i < num_planes; i++) addrs[0] = addr + fb->offsets[0] + y * fb->pitches[0] +
x * format->cpp[0];
y /= format->vsub;
x /= format->hsub;
for (i = 1; i < num_planes; i++)
addrs[i] = addr + fb->offsets[i] + y * fb->pitches[i] + addrs[i] = addr + fb->offsets[i] + y * fb->pitches[i] +
x * fb->format->cpp[i]; x * format->cpp[i];
for (; i < 3; i++) for (; i < 3; i++)
addrs[i] = 0; addrs[i] = 0;
} }
...@@ -744,15 +751,14 @@ void armada_drm_crtc_plane_disable(struct armada_crtc *dcrtc, ...@@ -744,15 +751,14 @@ void armada_drm_crtc_plane_disable(struct armada_crtc *dcrtc,
if (plane->fb) if (plane->fb)
drm_framebuffer_put(plane->fb); drm_framebuffer_put(plane->fb);
/* Power down the Y/U/V FIFOs */
sram_para1 = CFG_PDWN16x66 | CFG_PDWN32x66;
/* Power down most RAMs and FIFOs if this is the primary plane */ /* Power down most RAMs and FIFOs if this is the primary plane */
if (plane->type == DRM_PLANE_TYPE_PRIMARY) { if (plane->type == DRM_PLANE_TYPE_PRIMARY) {
sram_para1 |= CFG_PDWN256x32 | CFG_PDWN256x24 | CFG_PDWN256x8 | sram_para1 = CFG_PDWN256x32 | CFG_PDWN256x24 | CFG_PDWN256x8 |
CFG_PDWN32x32 | CFG_PDWN64x66; CFG_PDWN32x32 | CFG_PDWN64x66;
dma_ctrl0_mask = CFG_GRA_ENA; dma_ctrl0_mask = CFG_GRA_ENA;
} else { } else {
/* Power down the Y/U/V FIFOs */
sram_para1 = CFG_PDWN16x66 | CFG_PDWN32x66;
dma_ctrl0_mask = CFG_DMA_ENA; dma_ctrl0_mask = CFG_DMA_ENA;
} }
...@@ -1225,17 +1231,13 @@ static int armada_drm_crtc_create(struct drm_device *drm, struct device *dev, ...@@ -1225,17 +1231,13 @@ static int armada_drm_crtc_create(struct drm_device *drm, struct device *dev,
ret = devm_request_irq(dev, irq, armada_drm_irq, 0, "armada_drm_crtc", ret = devm_request_irq(dev, irq, armada_drm_irq, 0, "armada_drm_crtc",
dcrtc); dcrtc);
if (ret < 0) { if (ret < 0)
kfree(dcrtc); goto err_crtc;
return ret;
}
if (dcrtc->variant->init) { if (dcrtc->variant->init) {
ret = dcrtc->variant->init(dcrtc, dev); ret = dcrtc->variant->init(dcrtc, dev);
if (ret) { if (ret)
kfree(dcrtc); goto err_crtc;
return ret;
}
} }
/* Ensure AXI pipeline is enabled */ /* Ensure AXI pipeline is enabled */
...@@ -1246,13 +1248,15 @@ static int armada_drm_crtc_create(struct drm_device *drm, struct device *dev, ...@@ -1246,13 +1248,15 @@ static int armada_drm_crtc_create(struct drm_device *drm, struct device *dev,
dcrtc->crtc.port = port; dcrtc->crtc.port = port;
primary = kzalloc(sizeof(*primary), GFP_KERNEL); primary = kzalloc(sizeof(*primary), GFP_KERNEL);
if (!primary) if (!primary) {
return -ENOMEM; ret = -ENOMEM;
goto err_crtc;
}
ret = armada_drm_plane_init(primary); ret = armada_drm_plane_init(primary);
if (ret) { if (ret) {
kfree(primary); kfree(primary);
return ret; goto err_crtc;
} }
ret = drm_universal_plane_init(drm, &primary->base, 0, ret = drm_universal_plane_init(drm, &primary->base, 0,
...@@ -1263,7 +1267,7 @@ static int armada_drm_crtc_create(struct drm_device *drm, struct device *dev, ...@@ -1263,7 +1267,7 @@ static int armada_drm_crtc_create(struct drm_device *drm, struct device *dev,
DRM_PLANE_TYPE_PRIMARY, NULL); DRM_PLANE_TYPE_PRIMARY, NULL);
if (ret) { if (ret) {
kfree(primary); kfree(primary);
return ret; goto err_crtc;
} }
ret = drm_crtc_init_with_planes(drm, &dcrtc->crtc, &primary->base, NULL, ret = drm_crtc_init_with_planes(drm, &dcrtc->crtc, &primary->base, NULL,
...@@ -1282,6 +1286,9 @@ static int armada_drm_crtc_create(struct drm_device *drm, struct device *dev, ...@@ -1282,6 +1286,9 @@ static int armada_drm_crtc_create(struct drm_device *drm, struct device *dev,
err_crtc_init: err_crtc_init:
primary->base.funcs->destroy(&primary->base); primary->base.funcs->destroy(&primary->base);
err_crtc:
kfree(dcrtc);
return ret; return ret;
} }
......
...@@ -42,6 +42,8 @@ struct armada_plane_work { ...@@ -42,6 +42,8 @@ struct armada_plane_work {
}; };
struct armada_plane_state { struct armada_plane_state {
u16 src_x;
u16 src_y;
u32 src_hw; u32 src_hw;
u32 dst_hw; u32 dst_hw;
u32 dst_yx; u32 dst_yx;
......
...@@ -99,6 +99,7 @@ armada_ovl_plane_update(struct drm_plane *plane, struct drm_crtc *crtc, ...@@ -99,6 +99,7 @@ armada_ovl_plane_update(struct drm_plane *plane, struct drm_crtc *crtc,
{ {
struct armada_ovl_plane *dplane = drm_to_armada_ovl_plane(plane); struct armada_ovl_plane *dplane = drm_to_armada_ovl_plane(plane);
struct armada_crtc *dcrtc = drm_to_armada_crtc(crtc); struct armada_crtc *dcrtc = drm_to_armada_crtc(crtc);
const struct drm_format_info *format;
struct drm_rect src = { struct drm_rect src = {
.x1 = src_x, .x1 = src_x,
.y1 = src_y, .y1 = src_y,
...@@ -117,7 +118,7 @@ armada_ovl_plane_update(struct drm_plane *plane, struct drm_crtc *crtc, ...@@ -117,7 +118,7 @@ armada_ovl_plane_update(struct drm_plane *plane, struct drm_crtc *crtc,
}; };
uint32_t val, ctrl0; uint32_t val, ctrl0;
unsigned idx = 0; unsigned idx = 0;
bool visible; bool visible, fb_changed;
int ret; int ret;
trace_armada_ovl_plane_update(plane, crtc, fb, trace_armada_ovl_plane_update(plane, crtc, fb,
...@@ -138,6 +139,18 @@ armada_ovl_plane_update(struct drm_plane *plane, struct drm_crtc *crtc, ...@@ -138,6 +139,18 @@ armada_ovl_plane_update(struct drm_plane *plane, struct drm_crtc *crtc,
if (!visible) if (!visible)
ctrl0 &= ~CFG_DMA_ENA; ctrl0 &= ~CFG_DMA_ENA;
/*
* Shifting a YUV packed format image by one pixel causes the U/V
* planes to swap. Compensate for it by also toggling the UV swap.
*/
format = fb->format;
if (format->num_planes == 1 && src.x1 >> 16 & (format->hsub - 1))
ctrl0 ^= CFG_DMA_MOD(CFG_SWAPUV);
fb_changed = plane->fb != fb ||
dplane->base.state.src_x != src.x1 >> 16 ||
dplane->base.state.src_y != src.y1 >> 16;
if (!dcrtc->plane) { if (!dcrtc->plane) {
dcrtc->plane = plane; dcrtc->plane = plane;
armada_ovl_update_attr(&dplane->prop, dcrtc); armada_ovl_update_attr(&dplane->prop, dcrtc);
...@@ -145,7 +158,7 @@ armada_ovl_plane_update(struct drm_plane *plane, struct drm_crtc *crtc, ...@@ -145,7 +158,7 @@ armada_ovl_plane_update(struct drm_plane *plane, struct drm_crtc *crtc,
/* FIXME: overlay on an interlaced display */ /* FIXME: overlay on an interlaced display */
/* Just updating the position/size? */ /* Just updating the position/size? */
if (plane->fb == fb && dplane->base.state.ctrl0 == ctrl0) { if (!fb_changed && dplane->base.state.ctrl0 == ctrl0) {
val = (drm_rect_height(&src) & 0xffff0000) | val = (drm_rect_height(&src) & 0xffff0000) |
drm_rect_width(&src) >> 16; drm_rect_width(&src) >> 16;
dplane->base.state.src_hw = val; dplane->base.state.src_hw = val;
...@@ -169,9 +182,8 @@ armada_ovl_plane_update(struct drm_plane *plane, struct drm_crtc *crtc, ...@@ -169,9 +182,8 @@ armada_ovl_plane_update(struct drm_plane *plane, struct drm_crtc *crtc,
if (armada_drm_plane_work_wait(&dplane->base, HZ / 25) == 0) if (armada_drm_plane_work_wait(&dplane->base, HZ / 25) == 0)
armada_drm_plane_work_cancel(dcrtc, &dplane->base); armada_drm_plane_work_cancel(dcrtc, &dplane->base);
if (plane->fb != fb) { if (fb_changed) {
u32 addrs[3], pixel_format; u32 addrs[3];
int num_planes, hsub;
/* /*
* Take a reference on the new framebuffer - we want to * Take a reference on the new framebuffer - we want to
...@@ -182,23 +194,11 @@ armada_ovl_plane_update(struct drm_plane *plane, struct drm_crtc *crtc, ...@@ -182,23 +194,11 @@ armada_ovl_plane_update(struct drm_plane *plane, struct drm_crtc *crtc,
if (plane->fb) if (plane->fb)
armada_ovl_retire_fb(dplane, plane->fb); armada_ovl_retire_fb(dplane, plane->fb);
src_y = src.y1 >> 16; dplane->base.state.src_y = src_y = src.y1 >> 16;
src_x = src.x1 >> 16; dplane->base.state.src_x = src_x = src.x1 >> 16;
armada_drm_plane_calc_addrs(addrs, fb, src_x, src_y); armada_drm_plane_calc_addrs(addrs, fb, src_x, src_y);
pixel_format = fb->format->format;
hsub = drm_format_horz_chroma_subsampling(pixel_format);
num_planes = fb->format->num_planes;
/*
* Annoyingly, shifting a YUYV-format image by one pixel
* causes the U/V planes to toggle. Toggle the UV swap.
* (Unfortunately, this causes momentary colour flickering.)
*/
if (src_x & (hsub - 1) && num_planes == 1)
ctrl0 ^= CFG_DMA_MOD(CFG_SWAPUV);
armada_reg_queue_set(dplane->vbl.regs, idx, addrs[0], armada_reg_queue_set(dplane->vbl.regs, idx, addrs[0],
LCD_SPU_DMA_START_ADDR_Y0); LCD_SPU_DMA_START_ADDR_Y0);
armada_reg_queue_set(dplane->vbl.regs, idx, addrs[1], armada_reg_queue_set(dplane->vbl.regs, idx, addrs[1],
......
...@@ -2368,6 +2368,9 @@ struct drm_i915_private { ...@@ -2368,6 +2368,9 @@ struct drm_i915_private {
*/ */
struct workqueue_struct *wq; struct workqueue_struct *wq;
/* ordered wq for modesets */
struct workqueue_struct *modeset_wq;
/* Display functions */ /* Display functions */
struct drm_i915_display_funcs display; struct drm_i915_display_funcs display;
......
...@@ -6977,6 +6977,7 @@ enum { ...@@ -6977,6 +6977,7 @@ enum {
#define RESET_PCH_HANDSHAKE_ENABLE (1<<4) #define RESET_PCH_HANDSHAKE_ENABLE (1<<4)
#define GEN8_CHICKEN_DCPR_1 _MMIO(0x46430) #define GEN8_CHICKEN_DCPR_1 _MMIO(0x46430)
#define SKL_SELECT_ALTERNATE_DC_EXIT (1<<30)
#define MASK_WAKEMEM (1<<13) #define MASK_WAKEMEM (1<<13)
#define SKL_DFSM _MMIO(0x51000) #define SKL_DFSM _MMIO(0x51000)
...@@ -8522,6 +8523,7 @@ enum skl_power_gate { ...@@ -8522,6 +8523,7 @@ enum skl_power_gate {
#define BXT_CDCLK_CD2X_DIV_SEL_2 (2<<22) #define BXT_CDCLK_CD2X_DIV_SEL_2 (2<<22)
#define BXT_CDCLK_CD2X_DIV_SEL_4 (3<<22) #define BXT_CDCLK_CD2X_DIV_SEL_4 (3<<22)
#define BXT_CDCLK_CD2X_PIPE(pipe) ((pipe)<<20) #define BXT_CDCLK_CD2X_PIPE(pipe) ((pipe)<<20)
#define CDCLK_DIVMUX_CD_OVERRIDE (1<<19)
#define BXT_CDCLK_CD2X_PIPE_NONE BXT_CDCLK_CD2X_PIPE(3) #define BXT_CDCLK_CD2X_PIPE_NONE BXT_CDCLK_CD2X_PIPE(3)
#define BXT_CDCLK_SSA_PRECHARGE_ENABLE (1<<16) #define BXT_CDCLK_SSA_PRECHARGE_ENABLE (1<<16)
#define CDCLK_FREQ_DECIMAL_MASK (0x7ff) #define CDCLK_FREQ_DECIMAL_MASK (0x7ff)
......
...@@ -860,16 +860,10 @@ static void skl_set_preferred_cdclk_vco(struct drm_i915_private *dev_priv, ...@@ -860,16 +860,10 @@ static void skl_set_preferred_cdclk_vco(struct drm_i915_private *dev_priv,
static void skl_dpll0_enable(struct drm_i915_private *dev_priv, int vco) static void skl_dpll0_enable(struct drm_i915_private *dev_priv, int vco)
{ {
int min_cdclk = skl_calc_cdclk(0, vco);
u32 val; u32 val;
WARN_ON(vco != 8100000 && vco != 8640000); WARN_ON(vco != 8100000 && vco != 8640000);
/* select the minimum CDCLK before enabling DPLL 0 */
val = CDCLK_FREQ_337_308 | skl_cdclk_decimal(min_cdclk);
I915_WRITE(CDCLK_CTL, val);
POSTING_READ(CDCLK_CTL);
/* /*
* We always enable DPLL0 with the lowest link rate possible, but still * We always enable DPLL0 with the lowest link rate possible, but still
* taking into account the VCO required to operate the eDP panel at the * taking into account the VCO required to operate the eDP panel at the
...@@ -923,7 +917,7 @@ static void skl_set_cdclk(struct drm_i915_private *dev_priv, ...@@ -923,7 +917,7 @@ static void skl_set_cdclk(struct drm_i915_private *dev_priv,
{ {
int cdclk = cdclk_state->cdclk; int cdclk = cdclk_state->cdclk;
int vco = cdclk_state->vco; int vco = cdclk_state->vco;
u32 freq_select, pcu_ack; u32 freq_select, pcu_ack, cdclk_ctl;
int ret; int ret;
WARN_ON((cdclk == 24000) != (vco == 0)); WARN_ON((cdclk == 24000) != (vco == 0));
...@@ -940,7 +934,7 @@ static void skl_set_cdclk(struct drm_i915_private *dev_priv, ...@@ -940,7 +934,7 @@ static void skl_set_cdclk(struct drm_i915_private *dev_priv,
return; return;
} }
/* set CDCLK_CTL */ /* Choose frequency for this cdclk */
switch (cdclk) { switch (cdclk) {
case 450000: case 450000:
case 432000: case 432000:
...@@ -968,10 +962,33 @@ static void skl_set_cdclk(struct drm_i915_private *dev_priv, ...@@ -968,10 +962,33 @@ static void skl_set_cdclk(struct drm_i915_private *dev_priv,
dev_priv->cdclk.hw.vco != vco) dev_priv->cdclk.hw.vco != vco)
skl_dpll0_disable(dev_priv); skl_dpll0_disable(dev_priv);
cdclk_ctl = I915_READ(CDCLK_CTL);
if (dev_priv->cdclk.hw.vco != vco) {
/* Wa Display #1183: skl,kbl,cfl */
cdclk_ctl &= ~(CDCLK_FREQ_SEL_MASK | CDCLK_FREQ_DECIMAL_MASK);
cdclk_ctl |= freq_select | skl_cdclk_decimal(cdclk);
I915_WRITE(CDCLK_CTL, cdclk_ctl);
}
/* Wa Display #1183: skl,kbl,cfl */
cdclk_ctl |= CDCLK_DIVMUX_CD_OVERRIDE;
I915_WRITE(CDCLK_CTL, cdclk_ctl);
POSTING_READ(CDCLK_CTL);
if (dev_priv->cdclk.hw.vco != vco) if (dev_priv->cdclk.hw.vco != vco)
skl_dpll0_enable(dev_priv, vco); skl_dpll0_enable(dev_priv, vco);
I915_WRITE(CDCLK_CTL, freq_select | skl_cdclk_decimal(cdclk)); /* Wa Display #1183: skl,kbl,cfl */
cdclk_ctl &= ~(CDCLK_FREQ_SEL_MASK | CDCLK_FREQ_DECIMAL_MASK);
I915_WRITE(CDCLK_CTL, cdclk_ctl);
cdclk_ctl |= freq_select | skl_cdclk_decimal(cdclk);
I915_WRITE(CDCLK_CTL, cdclk_ctl);
/* Wa Display #1183: skl,kbl,cfl */
cdclk_ctl &= ~CDCLK_DIVMUX_CD_OVERRIDE;
I915_WRITE(CDCLK_CTL, cdclk_ctl);
POSTING_READ(CDCLK_CTL); POSTING_READ(CDCLK_CTL);
/* inform PCU of the change */ /* inform PCU of the change */
......
...@@ -12544,11 +12544,15 @@ static int intel_atomic_commit(struct drm_device *dev, ...@@ -12544,11 +12544,15 @@ static int intel_atomic_commit(struct drm_device *dev,
INIT_WORK(&state->commit_work, intel_atomic_commit_work); INIT_WORK(&state->commit_work, intel_atomic_commit_work);
i915_sw_fence_commit(&intel_state->commit_ready); i915_sw_fence_commit(&intel_state->commit_ready);
if (nonblock) if (nonblock && intel_state->modeset) {
queue_work(dev_priv->modeset_wq, &state->commit_work);
} else if (nonblock) {
queue_work(system_unbound_wq, &state->commit_work); queue_work(system_unbound_wq, &state->commit_work);
else } else {
if (intel_state->modeset)
flush_workqueue(dev_priv->modeset_wq);
intel_atomic_commit_tail(state); intel_atomic_commit_tail(state);
}
return 0; return 0;
} }
...@@ -14462,6 +14466,8 @@ int intel_modeset_init(struct drm_device *dev) ...@@ -14462,6 +14466,8 @@ int intel_modeset_init(struct drm_device *dev)
enum pipe pipe; enum pipe pipe;
struct intel_crtc *crtc; struct intel_crtc *crtc;
dev_priv->modeset_wq = alloc_ordered_workqueue("i915_modeset", 0);
drm_mode_config_init(dev); drm_mode_config_init(dev);
dev->mode_config.min_width = 0; dev->mode_config.min_width = 0;
...@@ -15270,6 +15276,8 @@ void intel_modeset_cleanup(struct drm_device *dev) ...@@ -15270,6 +15276,8 @@ void intel_modeset_cleanup(struct drm_device *dev)
intel_cleanup_gt_powersave(dev_priv); intel_cleanup_gt_powersave(dev_priv);
intel_teardown_gmbus(dev_priv); intel_teardown_gmbus(dev_priv);
destroy_workqueue(dev_priv->modeset_wq);
} }
void intel_connector_attach_encoder(struct intel_connector *connector, void intel_connector_attach_encoder(struct intel_connector *connector,
......
...@@ -590,7 +590,7 @@ static void hsw_psr_disable(struct intel_dp *intel_dp, ...@@ -590,7 +590,7 @@ static void hsw_psr_disable(struct intel_dp *intel_dp,
struct drm_i915_private *dev_priv = to_i915(dev); struct drm_i915_private *dev_priv = to_i915(dev);
if (dev_priv->psr.active) { if (dev_priv->psr.active) {
i915_reg_t psr_ctl; i915_reg_t psr_status;
u32 psr_status_mask; u32 psr_status_mask;
if (dev_priv->psr.aux_frame_sync) if (dev_priv->psr.aux_frame_sync)
...@@ -599,24 +599,24 @@ static void hsw_psr_disable(struct intel_dp *intel_dp, ...@@ -599,24 +599,24 @@ static void hsw_psr_disable(struct intel_dp *intel_dp,
0); 0);
if (dev_priv->psr.psr2_support) { if (dev_priv->psr.psr2_support) {
psr_ctl = EDP_PSR2_CTL; psr_status = EDP_PSR2_STATUS_CTL;
psr_status_mask = EDP_PSR2_STATUS_STATE_MASK; psr_status_mask = EDP_PSR2_STATUS_STATE_MASK;
I915_WRITE(psr_ctl, I915_WRITE(EDP_PSR2_CTL,
I915_READ(psr_ctl) & I915_READ(EDP_PSR2_CTL) &
~(EDP_PSR2_ENABLE | EDP_SU_TRACK_ENABLE)); ~(EDP_PSR2_ENABLE | EDP_SU_TRACK_ENABLE));
} else { } else {
psr_ctl = EDP_PSR_STATUS_CTL; psr_status = EDP_PSR_STATUS_CTL;
psr_status_mask = EDP_PSR_STATUS_STATE_MASK; psr_status_mask = EDP_PSR_STATUS_STATE_MASK;
I915_WRITE(psr_ctl, I915_WRITE(EDP_PSR_CTL,
I915_READ(psr_ctl) & ~EDP_PSR_ENABLE); I915_READ(EDP_PSR_CTL) & ~EDP_PSR_ENABLE);
} }
/* Wait till PSR is idle */ /* Wait till PSR is idle */
if (intel_wait_for_register(dev_priv, if (intel_wait_for_register(dev_priv,
psr_ctl, psr_status_mask, 0, psr_status, psr_status_mask, 0,
2000)) 2000))
DRM_ERROR("Timed out waiting for PSR Idle State\n"); DRM_ERROR("Timed out waiting for PSR Idle State\n");
......
...@@ -598,6 +598,11 @@ void gen9_enable_dc5(struct drm_i915_private *dev_priv) ...@@ -598,6 +598,11 @@ void gen9_enable_dc5(struct drm_i915_private *dev_priv)
DRM_DEBUG_KMS("Enabling DC5\n"); DRM_DEBUG_KMS("Enabling DC5\n");
/* Wa Display #1183: skl,kbl,cfl */
if (IS_GEN9_BC(dev_priv))
I915_WRITE(GEN8_CHICKEN_DCPR_1, I915_READ(GEN8_CHICKEN_DCPR_1) |
SKL_SELECT_ALTERNATE_DC_EXIT);
gen9_set_dc_state(dev_priv, DC_STATE_EN_UPTO_DC5); gen9_set_dc_state(dev_priv, DC_STATE_EN_UPTO_DC5);
} }
...@@ -625,6 +630,11 @@ void skl_disable_dc6(struct drm_i915_private *dev_priv) ...@@ -625,6 +630,11 @@ void skl_disable_dc6(struct drm_i915_private *dev_priv)
{ {
DRM_DEBUG_KMS("Disabling DC6\n"); DRM_DEBUG_KMS("Disabling DC6\n");
/* Wa Display #1183: skl,kbl,cfl */
if (IS_GEN9_BC(dev_priv))
I915_WRITE(GEN8_CHICKEN_DCPR_1, I915_READ(GEN8_CHICKEN_DCPR_1) |
SKL_SELECT_ALTERNATE_DC_EXIT);
gen9_set_dc_state(dev_priv, DC_STATE_DISABLE); gen9_set_dc_state(dev_priv, DC_STATE_DISABLE);
} }
...@@ -1786,6 +1796,7 @@ void intel_display_power_put(struct drm_i915_private *dev_priv, ...@@ -1786,6 +1796,7 @@ void intel_display_power_put(struct drm_i915_private *dev_priv,
GLK_DISPLAY_POWERWELL_2_POWER_DOMAINS | \ GLK_DISPLAY_POWERWELL_2_POWER_DOMAINS | \
BIT_ULL(POWER_DOMAIN_MODESET) | \ BIT_ULL(POWER_DOMAIN_MODESET) | \
BIT_ULL(POWER_DOMAIN_AUX_A) | \ BIT_ULL(POWER_DOMAIN_AUX_A) | \
BIT_ULL(POWER_DOMAIN_GMBUS) | \
BIT_ULL(POWER_DOMAIN_INIT)) BIT_ULL(POWER_DOMAIN_INIT))
#define CNL_DISPLAY_POWERWELL_2_POWER_DOMAINS ( \ #define CNL_DISPLAY_POWERWELL_2_POWER_DOMAINS ( \
......
...@@ -78,6 +78,8 @@ static void hdmi_cec_received_msg(struct hdmi_core_data *core) ...@@ -78,6 +78,8 @@ static void hdmi_cec_received_msg(struct hdmi_core_data *core)
/* then read the message */ /* then read the message */
msg.len = cnt & 0xf; msg.len = cnt & 0xf;
if (msg.len > CEC_MAX_MSG_SIZE - 2)
msg.len = CEC_MAX_MSG_SIZE - 2;
msg.msg[0] = hdmi_read_reg(core->base, msg.msg[0] = hdmi_read_reg(core->base,
HDMI_CEC_RX_CMD_HEADER); HDMI_CEC_RX_CMD_HEADER);
msg.msg[1] = hdmi_read_reg(core->base, msg.msg[1] = hdmi_read_reg(core->base,
...@@ -104,26 +106,6 @@ static void hdmi_cec_received_msg(struct hdmi_core_data *core) ...@@ -104,26 +106,6 @@ static void hdmi_cec_received_msg(struct hdmi_core_data *core)
} }
} }
static void hdmi_cec_transmit_fifo_empty(struct hdmi_core_data *core, u32 stat1)
{
if (stat1 & 2) {
u32 dbg3 = hdmi_read_reg(core->base, HDMI_CEC_DBG_3);
cec_transmit_done(core->adap,
CEC_TX_STATUS_NACK |
CEC_TX_STATUS_MAX_RETRIES,
0, (dbg3 >> 4) & 7, 0, 0);
} else if (stat1 & 1) {
cec_transmit_done(core->adap,
CEC_TX_STATUS_ARB_LOST |
CEC_TX_STATUS_MAX_RETRIES,
0, 0, 0, 0);
} else if (stat1 == 0) {
cec_transmit_done(core->adap, CEC_TX_STATUS_OK,
0, 0, 0, 0);
}
}
void hdmi4_cec_irq(struct hdmi_core_data *core) void hdmi4_cec_irq(struct hdmi_core_data *core)
{ {
u32 stat0 = hdmi_read_reg(core->base, HDMI_CEC_INT_STATUS_0); u32 stat0 = hdmi_read_reg(core->base, HDMI_CEC_INT_STATUS_0);
...@@ -132,27 +114,21 @@ void hdmi4_cec_irq(struct hdmi_core_data *core) ...@@ -132,27 +114,21 @@ void hdmi4_cec_irq(struct hdmi_core_data *core)
hdmi_write_reg(core->base, HDMI_CEC_INT_STATUS_0, stat0); hdmi_write_reg(core->base, HDMI_CEC_INT_STATUS_0, stat0);
hdmi_write_reg(core->base, HDMI_CEC_INT_STATUS_1, stat1); hdmi_write_reg(core->base, HDMI_CEC_INT_STATUS_1, stat1);
if (stat0 & 0x40) if (stat0 & 0x20) {
cec_transmit_done(core->adap, CEC_TX_STATUS_OK,
0, 0, 0, 0);
REG_FLD_MOD(core->base, HDMI_CEC_DBG_3, 0x1, 7, 7); REG_FLD_MOD(core->base, HDMI_CEC_DBG_3, 0x1, 7, 7);
else if (stat0 & 0x24) } else if (stat1 & 0x02) {
hdmi_cec_transmit_fifo_empty(core, stat1);
if (stat1 & 2) {
u32 dbg3 = hdmi_read_reg(core->base, HDMI_CEC_DBG_3); u32 dbg3 = hdmi_read_reg(core->base, HDMI_CEC_DBG_3);
cec_transmit_done(core->adap, cec_transmit_done(core->adap,
CEC_TX_STATUS_NACK | CEC_TX_STATUS_NACK |
CEC_TX_STATUS_MAX_RETRIES, CEC_TX_STATUS_MAX_RETRIES,
0, (dbg3 >> 4) & 7, 0, 0); 0, (dbg3 >> 4) & 7, 0, 0);
} else if (stat1 & 1) { REG_FLD_MOD(core->base, HDMI_CEC_DBG_3, 0x1, 7, 7);
cec_transmit_done(core->adap,
CEC_TX_STATUS_ARB_LOST |
CEC_TX_STATUS_MAX_RETRIES,
0, 0, 0, 0);
} }
if (stat0 & 0x02) if (stat0 & 0x02)
hdmi_cec_received_msg(core); hdmi_cec_received_msg(core);
if (stat1 & 0x3)
REG_FLD_MOD(core->base, HDMI_CEC_DBG_3, 0x1, 7, 7);
} }
static bool hdmi_cec_clear_tx_fifo(struct cec_adapter *adap) static bool hdmi_cec_clear_tx_fifo(struct cec_adapter *adap)
...@@ -231,18 +207,14 @@ static int hdmi_cec_adap_enable(struct cec_adapter *adap, bool enable) ...@@ -231,18 +207,14 @@ static int hdmi_cec_adap_enable(struct cec_adapter *adap, bool enable)
/* /*
* Enable CEC interrupts: * Enable CEC interrupts:
* Transmit Buffer Full/Empty Change event * Transmit Buffer Full/Empty Change event
* Transmitter FIFO Empty event
* Receiver FIFO Not Empty event * Receiver FIFO Not Empty event
*/ */
hdmi_write_reg(core->base, HDMI_CEC_INT_ENABLE_0, 0x26); hdmi_write_reg(core->base, HDMI_CEC_INT_ENABLE_0, 0x22);
/* /*
* Enable CEC interrupts: * Enable CEC interrupts:
* RX FIFO Overrun Error event
* Short Pulse Detected event
* Frame Retransmit Count Exceeded event * Frame Retransmit Count Exceeded event
* Start Bit Irregularity event
*/ */
hdmi_write_reg(core->base, HDMI_CEC_INT_ENABLE_1, 0x0f); hdmi_write_reg(core->base, HDMI_CEC_INT_ENABLE_1, 0x02);
/* cec calibration enable (self clearing) */ /* cec calibration enable (self clearing) */
hdmi_write_reg(core->base, HDMI_CEC_SETUP, 0x03); hdmi_write_reg(core->base, HDMI_CEC_SETUP, 0x03);
......
...@@ -1007,6 +1007,8 @@ int ttm_page_alloc_init(struct ttm_mem_global *glob, unsigned max_pages) ...@@ -1007,6 +1007,8 @@ int ttm_page_alloc_init(struct ttm_mem_global *glob, unsigned max_pages)
pr_info("Initializing pool allocator\n"); pr_info("Initializing pool allocator\n");
_manager = kzalloc(sizeof(*_manager), GFP_KERNEL); _manager = kzalloc(sizeof(*_manager), GFP_KERNEL);
if (!_manager)
return -ENOMEM;
ttm_page_pool_init_locked(&_manager->wc_pool, GFP_HIGHUSER, "wc", 0); ttm_page_pool_init_locked(&_manager->wc_pool, GFP_HIGHUSER, "wc", 0);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment