mirror of
https://github.com/torvalds/linux.git
synced 2024-11-29 23:51:37 +00:00
drm fixes for 5.11-rc8
ttm: - page pool regression fix. dp_mst: - Don't report un-attached ports as connected amdgpu: - Blank screen fix i915: - Ensure Type-C FIA is powered when initializing - Fix overlay frontbuffer tracking sun4i: - tcon1 sync polarity fix - Always set HDMI clock rate - Fix H6 HDMI PHY config - Fix H6 max frequency vc4: - Fix buffer overflow xlnx: - Fix memory leak -----BEGIN PGP SIGNATURE----- iQIcBAABAgAGBQJgJf1KAAoJEAx081l5xIa+CwYQAKj4UzfoZnjLH7174FiLsbmJ DzOXcLIjQkMWSmMUnTmUmUclBSTexXaIm7sUzbHNsjpIet+cjxVQo8UhatOokM48 YrNnYRnkReiy2rLJYMB5tSPDXAh8BNuZDGXiN4AEPdxErFK0DsisDzSSYZJfg01M Qpt/diCJRu4T3Hr+YletfxWV+Dqq5m79zXmMfr1NlCW4D1V1WLEVW1zyb5rTFiTn goBis52fL2FWTe9DVFa+VVDqCeQxMxs4/gFsZoY5IMTy/w+4YI9gy4BElnyDcOoW kWz7rjUNl5Hy1BG3YrH9egzKktlGzqHuD6x8bp/PbQdgL8w9m/hvKghYssByHDs0 WBhEg8gd9XviWRfIdNuFeJ4/jq6kMlmLEzZKbcBUpP7Du5/c3rUMqhHFTilz4y7y 8kNDAG5rtL/9b8um0H2MR179qYspRiL0XhG0HL4YZuopfruhmky8gkRhYcsOHkPR WYFR321FItpXFTw8/gUdudeEr2KssWZ9Ob2lBO960Or2JEtWPYSk1F3G7SCt6N+L IalFXYRMG2OfAiNjjiVEiZNFe1dgpfy89tka5bVnVuuBEYx+DjU7ZTl3i4xAxtYG X8WA1de0FzuYiiEUBrrYe8s6YFBEo4Z20dlA1ghYU/rMEXNfte0RVW8DAdsKiTwd Bqt8tCb6CblCNPxbkeQ3 =HSyG -----END PGP SIGNATURE----- Merge tag 'drm-fixes-2021-02-12' of git://anongit.freedesktop.org/drm/drm Pull drm fixes from Dave Airlie: "Regular fixes for final, there is a ttm regression fix, dp-mst fix, one amdgpu revert, two i915 fixes, and some misc fixes for sun4i, xlnx, and vc4. All pretty quiet and don't think we have any known outstanding regressions. ttm: - page pool regression fix. dp_mst: - don't report un-attached ports as connected amdgpu: - blank screen fix i915: - ensure Type-C FIA is powered when initializing - fix overlay frontbuffer tracking sun4i: - tcon1 sync polarity fix - always set HDMI clock rate - fix H6 HDMI PHY config - fix H6 max frequency vc4: - fix buffer overflow xlnx: - fix memory leak" * tag 'drm-fixes-2021-02-12' of git://anongit.freedesktop.org/drm/drm: drm/ttm: make sure pool pages are cleared drm/sun4i: dw-hdmi: Fix max. frequency for H6 drm/sun4i: Fix H6 HDMI PHY configuration drm/sun4i: dw-hdmi: always set clock rate drm/sun4i: tcon: set sync polarity for tcon1 channel drm/i915: Fix overlay frontbuffer tracking Revert "drm/amd/display: Update NV1x SR latency values" drm/i915/tgl+: Make sure TypeC FIA is powered up when initializing it drm/dp_mst: Don't report ports connected if nothing is attached to them drm/xlnx: fix kmemleak by sending vblank_event in atomic_disable drm/vc4: hvs: Fix buffer overflow with the dlist handling
This commit is contained in:
commit
a81bfdf8bf
@ -297,8 +297,8 @@ static struct _vcs_dpi_soc_bounding_box_st dcn2_0_soc = {
|
||||
},
|
||||
},
|
||||
.num_states = 5,
|
||||
.sr_exit_time_us = 11.6,
|
||||
.sr_enter_plus_exit_time_us = 13.9,
|
||||
.sr_exit_time_us = 8.6,
|
||||
.sr_enter_plus_exit_time_us = 10.9,
|
||||
.urgent_latency_us = 4.0,
|
||||
.urgent_latency_pixel_data_only_us = 4.0,
|
||||
.urgent_latency_pixel_mixed_with_vm_data_us = 4.0,
|
||||
|
@ -4224,6 +4224,7 @@ drm_dp_mst_detect_port(struct drm_connector *connector,
|
||||
|
||||
switch (port->pdt) {
|
||||
case DP_PEER_DEVICE_NONE:
|
||||
break;
|
||||
case DP_PEER_DEVICE_MST_BRANCHING:
|
||||
if (!port->mcs)
|
||||
ret = connector_status_connected;
|
||||
|
@ -182,6 +182,7 @@ struct intel_overlay {
|
||||
struct intel_crtc *crtc;
|
||||
struct i915_vma *vma;
|
||||
struct i915_vma *old_vma;
|
||||
struct intel_frontbuffer *frontbuffer;
|
||||
bool active;
|
||||
bool pfit_active;
|
||||
u32 pfit_vscale_ratio; /* shifted-point number, (1<<12) == 1.0 */
|
||||
@ -282,21 +283,19 @@ static void intel_overlay_flip_prepare(struct intel_overlay *overlay,
|
||||
struct i915_vma *vma)
|
||||
{
|
||||
enum pipe pipe = overlay->crtc->pipe;
|
||||
struct intel_frontbuffer *from = NULL, *to = NULL;
|
||||
struct intel_frontbuffer *frontbuffer = NULL;
|
||||
|
||||
drm_WARN_ON(&overlay->i915->drm, overlay->old_vma);
|
||||
|
||||
if (overlay->vma)
|
||||
from = intel_frontbuffer_get(overlay->vma->obj);
|
||||
if (vma)
|
||||
to = intel_frontbuffer_get(vma->obj);
|
||||
frontbuffer = intel_frontbuffer_get(vma->obj);
|
||||
|
||||
intel_frontbuffer_track(from, to, INTEL_FRONTBUFFER_OVERLAY(pipe));
|
||||
intel_frontbuffer_track(overlay->frontbuffer, frontbuffer,
|
||||
INTEL_FRONTBUFFER_OVERLAY(pipe));
|
||||
|
||||
if (to)
|
||||
intel_frontbuffer_put(to);
|
||||
if (from)
|
||||
intel_frontbuffer_put(from);
|
||||
if (overlay->frontbuffer)
|
||||
intel_frontbuffer_put(overlay->frontbuffer);
|
||||
overlay->frontbuffer = frontbuffer;
|
||||
|
||||
intel_frontbuffer_flip_prepare(overlay->i915,
|
||||
INTEL_FRONTBUFFER_OVERLAY(pipe));
|
||||
|
@ -23,36 +23,6 @@ static const char *tc_port_mode_name(enum tc_port_mode mode)
|
||||
return names[mode];
|
||||
}
|
||||
|
||||
static void
|
||||
tc_port_load_fia_params(struct drm_i915_private *i915,
|
||||
struct intel_digital_port *dig_port)
|
||||
{
|
||||
enum port port = dig_port->base.port;
|
||||
enum tc_port tc_port = intel_port_to_tc(i915, port);
|
||||
u32 modular_fia;
|
||||
|
||||
if (INTEL_INFO(i915)->display.has_modular_fia) {
|
||||
modular_fia = intel_uncore_read(&i915->uncore,
|
||||
PORT_TX_DFLEXDPSP(FIA1));
|
||||
drm_WARN_ON(&i915->drm, modular_fia == 0xffffffff);
|
||||
modular_fia &= MODULAR_FIA_MASK;
|
||||
} else {
|
||||
modular_fia = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Each Modular FIA instance houses 2 TC ports. In SOC that has more
|
||||
* than two TC ports, there are multiple instances of Modular FIA.
|
||||
*/
|
||||
if (modular_fia) {
|
||||
dig_port->tc_phy_fia = tc_port / 2;
|
||||
dig_port->tc_phy_fia_idx = tc_port % 2;
|
||||
} else {
|
||||
dig_port->tc_phy_fia = FIA1;
|
||||
dig_port->tc_phy_fia_idx = tc_port;
|
||||
}
|
||||
}
|
||||
|
||||
static enum intel_display_power_domain
|
||||
tc_cold_get_power_domain(struct intel_digital_port *dig_port)
|
||||
{
|
||||
@ -646,6 +616,43 @@ void intel_tc_port_put_link(struct intel_digital_port *dig_port)
|
||||
mutex_unlock(&dig_port->tc_lock);
|
||||
}
|
||||
|
||||
static bool
|
||||
tc_has_modular_fia(struct drm_i915_private *i915, struct intel_digital_port *dig_port)
|
||||
{
|
||||
intel_wakeref_t wakeref;
|
||||
u32 val;
|
||||
|
||||
if (!INTEL_INFO(i915)->display.has_modular_fia)
|
||||
return false;
|
||||
|
||||
wakeref = tc_cold_block(dig_port);
|
||||
val = intel_uncore_read(&i915->uncore, PORT_TX_DFLEXDPSP(FIA1));
|
||||
tc_cold_unblock(dig_port, wakeref);
|
||||
|
||||
drm_WARN_ON(&i915->drm, val == 0xffffffff);
|
||||
|
||||
return val & MODULAR_FIA_MASK;
|
||||
}
|
||||
|
||||
static void
|
||||
tc_port_load_fia_params(struct drm_i915_private *i915, struct intel_digital_port *dig_port)
|
||||
{
|
||||
enum port port = dig_port->base.port;
|
||||
enum tc_port tc_port = intel_port_to_tc(i915, port);
|
||||
|
||||
/*
|
||||
* Each Modular FIA instance houses 2 TC ports. In SOC that has more
|
||||
* than two TC ports, there are multiple instances of Modular FIA.
|
||||
*/
|
||||
if (tc_has_modular_fia(i915, dig_port)) {
|
||||
dig_port->tc_phy_fia = tc_port / 2;
|
||||
dig_port->tc_phy_fia_idx = tc_port % 2;
|
||||
} else {
|
||||
dig_port->tc_phy_fia = FIA1;
|
||||
dig_port->tc_phy_fia_idx = tc_port;
|
||||
}
|
||||
}
|
||||
|
||||
void intel_tc_port_init(struct intel_digital_port *dig_port, bool is_legacy)
|
||||
{
|
||||
struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev);
|
||||
|
@ -689,6 +689,30 @@ static void sun4i_tcon1_mode_set(struct sun4i_tcon *tcon,
|
||||
SUN4I_TCON1_BASIC5_V_SYNC(vsync) |
|
||||
SUN4I_TCON1_BASIC5_H_SYNC(hsync));
|
||||
|
||||
/* Setup the polarity of multiple signals */
|
||||
if (tcon->quirks->polarity_in_ch0) {
|
||||
val = 0;
|
||||
|
||||
if (mode->flags & DRM_MODE_FLAG_PHSYNC)
|
||||
val |= SUN4I_TCON0_IO_POL_HSYNC_POSITIVE;
|
||||
|
||||
if (mode->flags & DRM_MODE_FLAG_PVSYNC)
|
||||
val |= SUN4I_TCON0_IO_POL_VSYNC_POSITIVE;
|
||||
|
||||
regmap_write(tcon->regs, SUN4I_TCON0_IO_POL_REG, val);
|
||||
} else {
|
||||
/* according to vendor driver, this bit must be always set */
|
||||
val = SUN4I_TCON1_IO_POL_UNKNOWN;
|
||||
|
||||
if (mode->flags & DRM_MODE_FLAG_PHSYNC)
|
||||
val |= SUN4I_TCON1_IO_POL_HSYNC_POSITIVE;
|
||||
|
||||
if (mode->flags & DRM_MODE_FLAG_PVSYNC)
|
||||
val |= SUN4I_TCON1_IO_POL_VSYNC_POSITIVE;
|
||||
|
||||
regmap_write(tcon->regs, SUN4I_TCON1_IO_POL_REG, val);
|
||||
}
|
||||
|
||||
/* Map output pins to channel 1 */
|
||||
regmap_update_bits(tcon->regs, SUN4I_TCON_GCTL_REG,
|
||||
SUN4I_TCON_GCTL_IOMAP_MASK,
|
||||
@ -1517,6 +1541,7 @@ static const struct sun4i_tcon_quirks sun8i_a83t_tv_quirks = {
|
||||
|
||||
static const struct sun4i_tcon_quirks sun8i_r40_tv_quirks = {
|
||||
.has_channel_1 = true,
|
||||
.polarity_in_ch0 = true,
|
||||
.set_mux = sun8i_r40_tcon_tv_set_mux,
|
||||
};
|
||||
|
||||
|
@ -153,6 +153,11 @@
|
||||
#define SUN4I_TCON1_BASIC5_V_SYNC(height) (((height) - 1) & 0x3ff)
|
||||
|
||||
#define SUN4I_TCON1_IO_POL_REG 0xf0
|
||||
/* there is no documentation about this bit */
|
||||
#define SUN4I_TCON1_IO_POL_UNKNOWN BIT(26)
|
||||
#define SUN4I_TCON1_IO_POL_HSYNC_POSITIVE BIT(25)
|
||||
#define SUN4I_TCON1_IO_POL_VSYNC_POSITIVE BIT(24)
|
||||
|
||||
#define SUN4I_TCON1_IO_TRI_REG 0xf4
|
||||
|
||||
#define SUN4I_TCON_ECC_FIFO_REG 0xf8
|
||||
@ -235,6 +240,7 @@ struct sun4i_tcon_quirks {
|
||||
bool needs_de_be_mux; /* sun6i needs mux to select backend */
|
||||
bool needs_edp_reset; /* a80 edp reset needed for tcon0 access */
|
||||
bool supports_lvds; /* Does the TCON support an LVDS output? */
|
||||
bool polarity_in_ch0; /* some tcon1 channels have polarity bits in tcon0 pol register */
|
||||
u8 dclk_min_div; /* minimum divider for TCON0 DCLK */
|
||||
|
||||
/* callback to handle tcon muxing options */
|
||||
|
@ -21,8 +21,7 @@ static void sun8i_dw_hdmi_encoder_mode_set(struct drm_encoder *encoder,
|
||||
{
|
||||
struct sun8i_dw_hdmi *hdmi = encoder_to_sun8i_dw_hdmi(encoder);
|
||||
|
||||
if (hdmi->quirks->set_rate)
|
||||
clk_set_rate(hdmi->clk_tmds, mode->crtc_clock * 1000);
|
||||
clk_set_rate(hdmi->clk_tmds, mode->crtc_clock * 1000);
|
||||
}
|
||||
|
||||
static const struct drm_encoder_helper_funcs
|
||||
@ -48,11 +47,9 @@ sun8i_dw_hdmi_mode_valid_h6(struct dw_hdmi *hdmi, void *data,
|
||||
{
|
||||
/*
|
||||
* Controller support maximum of 594 MHz, which correlates to
|
||||
* 4K@60Hz 4:4:4 or RGB. However, for frequencies greater than
|
||||
* 340 MHz scrambling has to be enabled. Because scrambling is
|
||||
* not yet implemented, just limit to 340 MHz for now.
|
||||
* 4K@60Hz 4:4:4 or RGB.
|
||||
*/
|
||||
if (mode->clock > 340000)
|
||||
if (mode->clock > 594000)
|
||||
return MODE_CLOCK_HIGH;
|
||||
|
||||
return MODE_OK;
|
||||
@ -295,7 +292,6 @@ static int sun8i_dw_hdmi_remove(struct platform_device *pdev)
|
||||
|
||||
static const struct sun8i_dw_hdmi_quirks sun8i_a83t_quirks = {
|
||||
.mode_valid = sun8i_dw_hdmi_mode_valid_a83t,
|
||||
.set_rate = true,
|
||||
};
|
||||
|
||||
static const struct sun8i_dw_hdmi_quirks sun50i_h6_quirks = {
|
||||
|
@ -179,7 +179,6 @@ struct sun8i_dw_hdmi_quirks {
|
||||
enum drm_mode_status (*mode_valid)(struct dw_hdmi *hdmi, void *data,
|
||||
const struct drm_display_info *info,
|
||||
const struct drm_display_mode *mode);
|
||||
unsigned int set_rate : 1;
|
||||
unsigned int use_drm_infoframe : 1;
|
||||
};
|
||||
|
||||
|
@ -104,29 +104,21 @@ static const struct dw_hdmi_mpll_config sun50i_h6_mpll_cfg[] = {
|
||||
|
||||
static const struct dw_hdmi_curr_ctrl sun50i_h6_cur_ctr[] = {
|
||||
/* pixelclk bpp8 bpp10 bpp12 */
|
||||
{ 25175000, { 0x0000, 0x0000, 0x0000 }, },
|
||||
{ 27000000, { 0x0012, 0x0000, 0x0000 }, },
|
||||
{ 59400000, { 0x0008, 0x0008, 0x0008 }, },
|
||||
{ 72000000, { 0x0008, 0x0008, 0x001b }, },
|
||||
{ 74250000, { 0x0013, 0x0013, 0x0013 }, },
|
||||
{ 90000000, { 0x0008, 0x001a, 0x001b }, },
|
||||
{ 118800000, { 0x001b, 0x001a, 0x001b }, },
|
||||
{ 144000000, { 0x001b, 0x001a, 0x0034 }, },
|
||||
{ 180000000, { 0x001b, 0x0033, 0x0034 }, },
|
||||
{ 216000000, { 0x0036, 0x0033, 0x0034 }, },
|
||||
{ 237600000, { 0x0036, 0x0033, 0x001b }, },
|
||||
{ 288000000, { 0x0036, 0x001b, 0x001b }, },
|
||||
{ 297000000, { 0x0019, 0x001b, 0x0019 }, },
|
||||
{ 330000000, { 0x0036, 0x001b, 0x001b }, },
|
||||
{ 594000000, { 0x003f, 0x001b, 0x001b }, },
|
||||
{ 74250000, { 0x0013, 0x001a, 0x001b }, },
|
||||
{ 148500000, { 0x0019, 0x0033, 0x0034 }, },
|
||||
{ 297000000, { 0x0019, 0x001b, 0x001b }, },
|
||||
{ 594000000, { 0x0010, 0x001b, 0x001b }, },
|
||||
{ ~0UL, { 0x0000, 0x0000, 0x0000 }, }
|
||||
};
|
||||
|
||||
static const struct dw_hdmi_phy_config sun50i_h6_phy_config[] = {
|
||||
/*pixelclk symbol term vlev*/
|
||||
{ 74250000, 0x8009, 0x0004, 0x0232},
|
||||
{ 148500000, 0x8029, 0x0004, 0x0273},
|
||||
{ 594000000, 0x8039, 0x0004, 0x014a},
|
||||
{ 27000000, 0x8009, 0x0007, 0x02b0 },
|
||||
{ 74250000, 0x8009, 0x0006, 0x022d },
|
||||
{ 148500000, 0x8029, 0x0006, 0x0270 },
|
||||
{ 297000000, 0x8039, 0x0005, 0x01ab },
|
||||
{ 594000000, 0x8029, 0x0000, 0x008a },
|
||||
{ ~0UL, 0x0000, 0x0000, 0x0000}
|
||||
};
|
||||
|
||||
|
@ -33,6 +33,7 @@
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/dma-mapping.h>
|
||||
#include <linux/highmem.h>
|
||||
|
||||
#ifdef CONFIG_X86
|
||||
#include <asm/set_memory.h>
|
||||
@ -218,6 +219,15 @@ static void ttm_pool_unmap(struct ttm_pool *pool, dma_addr_t dma_addr,
|
||||
/* Give pages into a specific pool_type */
|
||||
static void ttm_pool_type_give(struct ttm_pool_type *pt, struct page *p)
|
||||
{
|
||||
unsigned int i, num_pages = 1 << pt->order;
|
||||
|
||||
for (i = 0; i < num_pages; ++i) {
|
||||
if (PageHighMem(p))
|
||||
clear_highpage(p + i);
|
||||
else
|
||||
clear_page(page_address(p + i));
|
||||
}
|
||||
|
||||
spin_lock(&pt->lock);
|
||||
list_add(&p->lru, &pt->pages);
|
||||
spin_unlock(&pt->lock);
|
||||
|
@ -220,7 +220,7 @@ static void vc4_plane_reset(struct drm_plane *plane)
|
||||
__drm_atomic_helper_plane_reset(plane, &vc4_state->base);
|
||||
}
|
||||
|
||||
static void vc4_dlist_write(struct vc4_plane_state *vc4_state, u32 val)
|
||||
static void vc4_dlist_counter_increment(struct vc4_plane_state *vc4_state)
|
||||
{
|
||||
if (vc4_state->dlist_count == vc4_state->dlist_size) {
|
||||
u32 new_size = max(4u, vc4_state->dlist_count * 2);
|
||||
@ -235,7 +235,15 @@ static void vc4_dlist_write(struct vc4_plane_state *vc4_state, u32 val)
|
||||
vc4_state->dlist_size = new_size;
|
||||
}
|
||||
|
||||
vc4_state->dlist[vc4_state->dlist_count++] = val;
|
||||
vc4_state->dlist_count++;
|
||||
}
|
||||
|
||||
static void vc4_dlist_write(struct vc4_plane_state *vc4_state, u32 val)
|
||||
{
|
||||
unsigned int idx = vc4_state->dlist_count;
|
||||
|
||||
vc4_dlist_counter_increment(vc4_state);
|
||||
vc4_state->dlist[idx] = val;
|
||||
}
|
||||
|
||||
/* Returns the scl0/scl1 field based on whether the dimensions need to
|
||||
@ -978,8 +986,10 @@ static int vc4_plane_mode_set(struct drm_plane *plane,
|
||||
* be set when calling vc4_plane_allocate_lbm().
|
||||
*/
|
||||
if (vc4_state->y_scaling[0] != VC4_SCALING_NONE ||
|
||||
vc4_state->y_scaling[1] != VC4_SCALING_NONE)
|
||||
vc4_state->lbm_offset = vc4_state->dlist_count++;
|
||||
vc4_state->y_scaling[1] != VC4_SCALING_NONE) {
|
||||
vc4_state->lbm_offset = vc4_state->dlist_count;
|
||||
vc4_dlist_counter_increment(vc4_state);
|
||||
}
|
||||
|
||||
if (num_planes > 1) {
|
||||
/* Emit Cb/Cr as channel 0 and Y as channel
|
||||
|
@ -1396,19 +1396,11 @@ static void zynqmp_disp_enable(struct zynqmp_disp *disp)
|
||||
*/
|
||||
static void zynqmp_disp_disable(struct zynqmp_disp *disp)
|
||||
{
|
||||
struct drm_crtc *crtc = &disp->crtc;
|
||||
|
||||
zynqmp_disp_audio_disable(&disp->audio);
|
||||
|
||||
zynqmp_disp_avbuf_disable_audio(&disp->avbuf);
|
||||
zynqmp_disp_avbuf_disable_channels(&disp->avbuf);
|
||||
zynqmp_disp_avbuf_disable(&disp->avbuf);
|
||||
|
||||
/* Mark the flip is done as crtc is disabled anyway */
|
||||
if (crtc->state->event) {
|
||||
complete_all(crtc->state->event->base.completion);
|
||||
crtc->state->event = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static inline struct zynqmp_disp *crtc_to_disp(struct drm_crtc *crtc)
|
||||
@ -1499,6 +1491,13 @@ zynqmp_disp_crtc_atomic_disable(struct drm_crtc *crtc,
|
||||
|
||||
drm_crtc_vblank_off(&disp->crtc);
|
||||
|
||||
spin_lock_irq(&crtc->dev->event_lock);
|
||||
if (crtc->state->event) {
|
||||
drm_crtc_send_vblank_event(crtc, crtc->state->event);
|
||||
crtc->state->event = NULL;
|
||||
}
|
||||
spin_unlock_irq(&crtc->dev->event_lock);
|
||||
|
||||
clk_disable_unprepare(disp->pclk);
|
||||
pm_runtime_put_sync(disp->dev);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user