Skip to content

Commit

Permalink
Merge tag 'drm-fixes-2021-02-12' of git://anongit.freedesktop.org/drm…
Browse files Browse the repository at this point in the history
…/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
  • Loading branch information
torvalds committed Feb 12, 2021
2 parents e77a681 + 551c818 commit a81bfdf
Show file tree
Hide file tree
Showing 12 changed files with 122 additions and 78 deletions.
4 changes: 2 additions & 2 deletions drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
1 change: 1 addition & 0 deletions drivers/gpu/drm/drm_dp_mst_topology.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
17 changes: 8 additions & 9 deletions drivers/gpu/drm/i915/display/intel_overlay.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand Down Expand Up @@ -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));
Expand Down
67 changes: 37 additions & 30 deletions drivers/gpu/drm/i915/display/intel_tc.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand Down Expand Up @@ -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);
Expand Down
25 changes: 25 additions & 0 deletions drivers/gpu/drm/sun4i/sun4i_tcon.c
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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,
};

Expand Down
6 changes: 6 additions & 0 deletions drivers/gpu/drm/sun4i/sun4i_tcon.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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 */
Expand Down
10 changes: 3 additions & 7 deletions drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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;
Expand Down Expand Up @@ -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 = {
Expand Down
1 change: 0 additions & 1 deletion drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
};

Expand Down
26 changes: 9 additions & 17 deletions drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c
Original file line number Diff line number Diff line change
Expand Up @@ -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}
};

Expand Down
10 changes: 10 additions & 0 deletions drivers/gpu/drm/ttm/ttm_pool.c
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand Down Expand Up @@ -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);
Expand Down
18 changes: 14 additions & 4 deletions drivers/gpu/drm/vc4/vc4_plane.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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
Expand Down Expand Up @@ -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
Expand Down
15 changes: 7 additions & 8 deletions drivers/gpu/drm/xlnx/zynqmp_disp.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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);
}
Expand Down

0 comments on commit a81bfdf

Please sign in to comment.