Skip to content

Commit

Permalink
Merge tag 'drm-fixes-2021-10-22' of git://anongit.freedesktop.org/drm…
Browse files Browse the repository at this point in the history
…/drm

Pull drm fixes from Dave Airlie:
 "Nothing too crazy at the end of the cycle, the kmb modesetting fixes
  are probably a bit large but it's not a major driver, and its fixing
  monitor doesn't turn on type problems.

  Otherwise it's just a few minor patches, one ast regression revert, an
  msm power stability fix.

  ast:
   - fix regression with connector detect

  msm:
   - fix power stability issue

  msxfb:
   - fix crash on unload

  panel:
   - sync fix

  kmb:
   - modesetting fixes"

* tag 'drm-fixes-2021-10-22' of git://anongit.freedesktop.org/drm/drm:
  Revert "drm/ast: Add detect function support"
  drm/kmb: Enable ADV bridge after modeset
  drm/kmb: Corrected typo in handle_lcd_irq
  drm/kmb: Disable change of plane parameters
  drm/kmb: Remove clearing DPHY regs
  drm/kmb: Limit supported mode to 1080p
  drm/kmb: Work around for higher system clock
  drm/panel: ilitek-ili9881c: Fix sync for Feixin K101-IM2BYL02 panel
  drm: mxsfb: Fix NULL pointer dereference crash on unload
  drm/msm/devfreq: Restrict idle clamping to a618 for now
  • Loading branch information
torvalds committed Oct 22, 2021
2 parents 658aafc + 595cb5e commit 6422251
Show file tree
Hide file tree
Showing 13 changed files with 137 additions and 42 deletions.
18 changes: 1 addition & 17 deletions drivers/gpu/drm/ast/ast_mode.c
Original file line number Diff line number Diff line change
Expand Up @@ -1300,18 +1300,6 @@ static enum drm_mode_status ast_mode_valid(struct drm_connector *connector,
return flags;
}

static enum drm_connector_status ast_connector_detect(struct drm_connector
*connector, bool force)
{
int r;

r = ast_get_modes(connector);
if (r <= 0)
return connector_status_disconnected;

return connector_status_connected;
}

static void ast_connector_destroy(struct drm_connector *connector)
{
struct ast_connector *ast_connector = to_ast_connector(connector);
Expand All @@ -1327,7 +1315,6 @@ static const struct drm_connector_helper_funcs ast_connector_helper_funcs = {

static const struct drm_connector_funcs ast_connector_funcs = {
.reset = drm_atomic_helper_connector_reset,
.detect = ast_connector_detect,
.fill_modes = drm_helper_probe_single_connector_modes,
.destroy = ast_connector_destroy,
.atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
Expand Down Expand Up @@ -1355,8 +1342,7 @@ static int ast_connector_init(struct drm_device *dev)
connector->interlace_allowed = 0;
connector->doublescan_allowed = 0;

connector->polled = DRM_CONNECTOR_POLL_CONNECT |
DRM_CONNECTOR_POLL_DISCONNECT;
connector->polled = DRM_CONNECTOR_POLL_CONNECT;

drm_connector_attach_encoder(connector, encoder);

Expand Down Expand Up @@ -1425,8 +1411,6 @@ int ast_mode_config_init(struct ast_private *ast)

drm_mode_config_reset(dev);

drm_kms_helper_poll_init(dev);

return 0;
}

Expand Down
41 changes: 38 additions & 3 deletions drivers/gpu/drm/kmb/kmb_crtc.c
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,8 @@ static const struct drm_crtc_funcs kmb_crtc_funcs = {
.disable_vblank = kmb_crtc_disable_vblank,
};

static void kmb_crtc_set_mode(struct drm_crtc *crtc)
static void kmb_crtc_set_mode(struct drm_crtc *crtc,
struct drm_atomic_state *old_state)
{
struct drm_device *dev = crtc->dev;
struct drm_display_mode *m = &crtc->state->adjusted_mode;
Expand All @@ -75,7 +76,7 @@ static void kmb_crtc_set_mode(struct drm_crtc *crtc)
unsigned int val = 0;

/* Initialize mipi */
kmb_dsi_mode_set(kmb->kmb_dsi, m, kmb->sys_clk_mhz);
kmb_dsi_mode_set(kmb->kmb_dsi, m, kmb->sys_clk_mhz, old_state);
drm_info(dev,
"vfp= %d vbp= %d vsync_len=%d hfp=%d hbp=%d hsync_len=%d\n",
m->crtc_vsync_start - m->crtc_vdisplay,
Expand Down Expand Up @@ -138,7 +139,7 @@ static void kmb_crtc_atomic_enable(struct drm_crtc *crtc,
struct kmb_drm_private *kmb = crtc_to_kmb_priv(crtc);

clk_prepare_enable(kmb->kmb_clk.clk_lcd);
kmb_crtc_set_mode(crtc);
kmb_crtc_set_mode(crtc, state);
drm_crtc_vblank_on(crtc);
}

Expand Down Expand Up @@ -185,11 +186,45 @@ static void kmb_crtc_atomic_flush(struct drm_crtc *crtc,
spin_unlock_irq(&crtc->dev->event_lock);
}

static enum drm_mode_status
kmb_crtc_mode_valid(struct drm_crtc *crtc,
const struct drm_display_mode *mode)
{
int refresh;
struct drm_device *dev = crtc->dev;
int vfp = mode->vsync_start - mode->vdisplay;

if (mode->vdisplay < KMB_CRTC_MAX_HEIGHT) {
drm_dbg(dev, "height = %d less than %d",
mode->vdisplay, KMB_CRTC_MAX_HEIGHT);
return MODE_BAD_VVALUE;
}
if (mode->hdisplay < KMB_CRTC_MAX_WIDTH) {
drm_dbg(dev, "width = %d less than %d",
mode->hdisplay, KMB_CRTC_MAX_WIDTH);
return MODE_BAD_HVALUE;
}
refresh = drm_mode_vrefresh(mode);
if (refresh < KMB_MIN_VREFRESH || refresh > KMB_MAX_VREFRESH) {
drm_dbg(dev, "refresh = %d less than %d or greater than %d",
refresh, KMB_MIN_VREFRESH, KMB_MAX_VREFRESH);
return MODE_BAD;
}

if (vfp < KMB_CRTC_MIN_VFP) {
drm_dbg(dev, "vfp = %d less than %d", vfp, KMB_CRTC_MIN_VFP);
return MODE_BAD;
}

return MODE_OK;
}

static const struct drm_crtc_helper_funcs kmb_crtc_helper_funcs = {
.atomic_begin = kmb_crtc_atomic_begin,
.atomic_enable = kmb_crtc_atomic_enable,
.atomic_disable = kmb_crtc_atomic_disable,
.atomic_flush = kmb_crtc_atomic_flush,
.mode_valid = kmb_crtc_mode_valid,
};

int kmb_setup_crtc(struct drm_device *drm)
Expand Down
2 changes: 1 addition & 1 deletion drivers/gpu/drm/kmb/kmb_drv.c
Original file line number Diff line number Diff line change
Expand Up @@ -380,7 +380,7 @@ static irqreturn_t handle_lcd_irq(struct drm_device *dev)
if (val & LAYER3_DMA_FIFO_UNDERFLOW)
drm_dbg(&kmb->drm,
"LAYER3:GL1 DMA UNDERFLOW val = 0x%lx", val);
if (val & LAYER3_DMA_FIFO_UNDERFLOW)
if (val & LAYER3_DMA_FIFO_OVERFLOW)
drm_dbg(&kmb->drm,
"LAYER3:GL1 DMA OVERFLOW val = 0x%lx", val);
}
Expand Down
10 changes: 9 additions & 1 deletion drivers/gpu/drm/kmb/kmb_drv.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,18 @@
#define DRIVER_MAJOR 1
#define DRIVER_MINOR 1

/* Platform definitions */
#define KMB_CRTC_MIN_VFP 4
#define KMB_CRTC_MAX_WIDTH 1920 /* max width in pixels */
#define KMB_CRTC_MAX_HEIGHT 1080 /* max height in pixels */
#define KMB_CRTC_MIN_WIDTH 1920
#define KMB_CRTC_MIN_HEIGHT 1080
#define KMB_FB_MAX_WIDTH 1920
#define KMB_FB_MAX_HEIGHT 1080
#define KMB_FB_MIN_WIDTH 1
#define KMB_FB_MIN_HEIGHT 1

#define KMB_MIN_VREFRESH 59 /*vertical refresh in Hz */
#define KMB_MAX_VREFRESH 60 /*vertical refresh in Hz */
#define KMB_LCD_DEFAULT_CLK 200000000
#define KMB_SYS_CLK_MHZ 500

Expand All @@ -50,6 +57,7 @@ struct kmb_drm_private {
spinlock_t irq_lock;
int irq_lcd;
int sys_clk_mhz;
struct disp_cfg init_disp_cfg[KMB_MAX_PLANES];
struct layer_status plane_status[KMB_MAX_PLANES];
int kmb_under_flow;
int kmb_flush_done;
Expand Down
25 changes: 15 additions & 10 deletions drivers/gpu/drm/kmb/kmb_dsi.c
Original file line number Diff line number Diff line change
Expand Up @@ -482,6 +482,10 @@ static u32 mipi_tx_fg_section_cfg(struct kmb_dsi *kmb_dsi,
return 0;
}

#define CLK_DIFF_LOW 50
#define CLK_DIFF_HI 60
#define SYSCLK_500 500

static void mipi_tx_fg_cfg_regs(struct kmb_dsi *kmb_dsi, u8 frame_gen,
struct mipi_tx_frame_timing_cfg *fg_cfg)
{
Expand All @@ -492,7 +496,12 @@ static void mipi_tx_fg_cfg_regs(struct kmb_dsi *kmb_dsi, u8 frame_gen,
/* 500 Mhz system clock minus 50 to account for the difference in
* MIPI clock speed in RTL tests
*/
sysclk = kmb_dsi->sys_clk_mhz - 50;
if (kmb_dsi->sys_clk_mhz == SYSCLK_500) {
sysclk = kmb_dsi->sys_clk_mhz - CLK_DIFF_LOW;
} else {
/* 700 Mhz clk*/
sysclk = kmb_dsi->sys_clk_mhz - CLK_DIFF_HI;
}

/* PPL-Pixel Packing Layer, LLP-Low Level Protocol
* Frame genartor timing parameters are clocked on the system clock,
Expand Down Expand Up @@ -1322,7 +1331,8 @@ static u32 mipi_tx_init_dphy(struct kmb_dsi *kmb_dsi,
return 0;
}

static void connect_lcd_to_mipi(struct kmb_dsi *kmb_dsi)
static void connect_lcd_to_mipi(struct kmb_dsi *kmb_dsi,
struct drm_atomic_state *old_state)
{
struct regmap *msscam;

Expand All @@ -1331,7 +1341,7 @@ static void connect_lcd_to_mipi(struct kmb_dsi *kmb_dsi)
dev_dbg(kmb_dsi->dev, "failed to get msscam syscon");
return;
}

drm_atomic_bridge_chain_enable(adv_bridge, old_state);
/* DISABLE MIPI->CIF CONNECTION */
regmap_write(msscam, MSS_MIPI_CIF_CFG, 0);

Expand All @@ -1342,7 +1352,7 @@ static void connect_lcd_to_mipi(struct kmb_dsi *kmb_dsi)
}

int kmb_dsi_mode_set(struct kmb_dsi *kmb_dsi, struct drm_display_mode *mode,
int sys_clk_mhz)
int sys_clk_mhz, struct drm_atomic_state *old_state)
{
u64 data_rate;

Expand Down Expand Up @@ -1384,18 +1394,13 @@ int kmb_dsi_mode_set(struct kmb_dsi *kmb_dsi, struct drm_display_mode *mode,
mipi_tx_init_cfg.lane_rate_mbps = data_rate;
}

kmb_write_mipi(kmb_dsi, DPHY_ENABLE, 0);
kmb_write_mipi(kmb_dsi, DPHY_INIT_CTRL0, 0);
kmb_write_mipi(kmb_dsi, DPHY_INIT_CTRL1, 0);
kmb_write_mipi(kmb_dsi, DPHY_INIT_CTRL2, 0);

/* Initialize mipi controller */
mipi_tx_init_cntrl(kmb_dsi, &mipi_tx_init_cfg);

/* Dphy initialization */
mipi_tx_init_dphy(kmb_dsi, &mipi_tx_init_cfg);

connect_lcd_to_mipi(kmb_dsi);
connect_lcd_to_mipi(kmb_dsi, old_state);
dev_info(kmb_dsi->dev, "mipi hw initialized");

return 0;
Expand Down
2 changes: 1 addition & 1 deletion drivers/gpu/drm/kmb/kmb_dsi.h
Original file line number Diff line number Diff line change
Expand Up @@ -380,7 +380,7 @@ int kmb_dsi_host_bridge_init(struct device *dev);
struct kmb_dsi *kmb_dsi_init(struct platform_device *pdev);
void kmb_dsi_host_unregister(struct kmb_dsi *kmb_dsi);
int kmb_dsi_mode_set(struct kmb_dsi *kmb_dsi, struct drm_display_mode *mode,
int sys_clk_mhz);
int sys_clk_mhz, struct drm_atomic_state *old_state);
int kmb_dsi_map_mmio(struct kmb_dsi *kmb_dsi);
int kmb_dsi_clk_init(struct kmb_dsi *kmb_dsi);
int kmb_dsi_encoder_init(struct drm_device *dev, struct kmb_dsi *kmb_dsi);
Expand Down
43 changes: 42 additions & 1 deletion drivers/gpu/drm/kmb/kmb_plane.c
Original file line number Diff line number Diff line change
Expand Up @@ -67,8 +67,21 @@ static const u32 kmb_formats_v[] = {

static unsigned int check_pixel_format(struct drm_plane *plane, u32 format)
{
struct kmb_drm_private *kmb;
struct kmb_plane *kmb_plane = to_kmb_plane(plane);
int i;
int plane_id = kmb_plane->id;
struct disp_cfg init_disp_cfg;

kmb = to_kmb(plane->dev);
init_disp_cfg = kmb->init_disp_cfg[plane_id];
/* Due to HW limitations, changing pixel format after initial
* plane configuration is not supported.
*/
if (init_disp_cfg.format && init_disp_cfg.format != format) {
drm_dbg(&kmb->drm, "Cannot change format after initial plane configuration");
return -EINVAL;
}
for (i = 0; i < plane->format_count; i++) {
if (plane->format_types[i] == format)
return 0;
Expand All @@ -81,11 +94,17 @@ static int kmb_plane_atomic_check(struct drm_plane *plane,
{
struct drm_plane_state *new_plane_state = drm_atomic_get_new_plane_state(state,
plane);
struct kmb_drm_private *kmb;
struct kmb_plane *kmb_plane = to_kmb_plane(plane);
int plane_id = kmb_plane->id;
struct disp_cfg init_disp_cfg;
struct drm_framebuffer *fb;
int ret;
struct drm_crtc_state *crtc_state;
bool can_position;

kmb = to_kmb(plane->dev);
init_disp_cfg = kmb->init_disp_cfg[plane_id];
fb = new_plane_state->fb;
if (!fb || !new_plane_state->crtc)
return 0;
Expand All @@ -99,6 +118,16 @@ static int kmb_plane_atomic_check(struct drm_plane *plane,
new_plane_state->crtc_w < KMB_FB_MIN_WIDTH ||
new_plane_state->crtc_h < KMB_FB_MIN_HEIGHT)
return -EINVAL;

/* Due to HW limitations, changing plane height or width after
* initial plane configuration is not supported.
*/
if ((init_disp_cfg.width && init_disp_cfg.height) &&
(init_disp_cfg.width != fb->width ||
init_disp_cfg.height != fb->height)) {
drm_dbg(&kmb->drm, "Cannot change plane height or width after initial configuration");
return -EINVAL;
}
can_position = (plane->type == DRM_PLANE_TYPE_OVERLAY);
crtc_state =
drm_atomic_get_existing_crtc_state(state,
Expand Down Expand Up @@ -335,6 +364,7 @@ static void kmb_plane_atomic_update(struct drm_plane *plane,
unsigned char plane_id;
int num_planes;
static dma_addr_t addr[MAX_SUB_PLANES];
struct disp_cfg *init_disp_cfg;

if (!plane || !new_plane_state || !old_plane_state)
return;
Expand All @@ -357,7 +387,8 @@ static void kmb_plane_atomic_update(struct drm_plane *plane,
}
spin_unlock_irq(&kmb->irq_lock);

src_w = (new_plane_state->src_w >> 16);
init_disp_cfg = &kmb->init_disp_cfg[plane_id];
src_w = new_plane_state->src_w >> 16;
src_h = new_plane_state->src_h >> 16;
crtc_x = new_plane_state->crtc_x;
crtc_y = new_plane_state->crtc_y;
Expand Down Expand Up @@ -500,6 +531,16 @@ static void kmb_plane_atomic_update(struct drm_plane *plane,

/* Enable DMA */
kmb_write_lcd(kmb, LCD_LAYERn_DMA_CFG(plane_id), dma_cfg);

/* Save initial display config */
if (!init_disp_cfg->width ||
!init_disp_cfg->height ||
!init_disp_cfg->format) {
init_disp_cfg->width = width;
init_disp_cfg->height = height;
init_disp_cfg->format = fb->format->format;
}

drm_dbg(&kmb->drm, "dma_cfg=0x%x LCD_DMA_CFG=0x%x\n", dma_cfg,
kmb_read_lcd(kmb, LCD_LAYERn_DMA_CFG(plane_id)));

Expand Down
6 changes: 6 additions & 0 deletions drivers/gpu/drm/kmb/kmb_plane.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,12 @@ struct layer_status {
u32 ctrl;
};

struct disp_cfg {
unsigned int width;
unsigned int height;
unsigned int format;
};

struct kmb_plane *kmb_plane_init(struct drm_device *drm);
void kmb_plane_destroy(struct drm_plane *plane);
#endif /* __KMB_PLANE_H__ */
7 changes: 7 additions & 0 deletions drivers/gpu/drm/msm/adreno/a6xx_gpu.c
Original file line number Diff line number Diff line change
Expand Up @@ -1838,6 +1838,13 @@ struct msm_gpu *a6xx_gpu_init(struct drm_device *dev)
adreno_cmp_rev(ADRENO_REV(6, 3, 5, ANY_ID), info->rev)))
adreno_gpu->base.hw_apriv = true;

/*
* For now only clamp to idle freq for devices where this is known not
* to cause power supply issues:
*/
if (info && (info->revn == 618))
gpu->clamp_to_idle = true;

a6xx_llc_slices_init(pdev, a6xx_gpu);

ret = a6xx_set_supported_hw(&pdev->dev, config->rev);
Expand Down
4 changes: 4 additions & 0 deletions drivers/gpu/drm/msm/msm_gpu.h
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,10 @@ struct msm_gpu {
uint32_t suspend_count;

struct msm_gpu_state *crashstate;

/* Enable clamping to idle freq when inactive: */
bool clamp_to_idle;

/* True if the hardware supports expanded apriv (a650 and newer) */
bool hw_apriv;

Expand Down
3 changes: 2 additions & 1 deletion drivers/gpu/drm/msm/msm_gpu_devfreq.c
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,8 @@ void msm_devfreq_idle(struct msm_gpu *gpu)

idle_freq = get_freq(gpu);

msm_devfreq_target(&gpu->pdev->dev, &target_freq, 0);
if (gpu->clamp_to_idle)
msm_devfreq_target(&gpu->pdev->dev, &target_freq, 0);

df->idle_time = ktime_get();
df->idle_freq = idle_freq;
Expand Down
6 changes: 5 additions & 1 deletion drivers/gpu/drm/mxsfb/mxsfb_drv.c
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,11 @@ static void mxsfb_irq_disable(struct drm_device *drm)
struct mxsfb_drm_private *mxsfb = drm->dev_private;

mxsfb_enable_axi_clk(mxsfb);
mxsfb->crtc.funcs->disable_vblank(&mxsfb->crtc);

/* Disable and clear VBLANK IRQ */
writel(CTRL1_CUR_FRAME_DONE_IRQ_EN, mxsfb->base + LCDC_CTRL1 + REG_CLR);
writel(CTRL1_CUR_FRAME_DONE_IRQ, mxsfb->base + LCDC_CTRL1 + REG_CLR);

mxsfb_disable_axi_clk(mxsfb);
}

Expand Down
Loading

0 comments on commit 6422251

Please sign in to comment.