drm-misc-fixes for v5.15-rc7:
- Rebased, to remove vc4 patches. - Fix mxsfb crash on unload. - Use correct sync parameters for Feixin K101-IM2BYL02. - Assorted kmb modeset/atomic fixes. -----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEEuXvWqAysSYEJGuVH/lWMcqZwE8MFAmFxM6YACgkQ/lWMcqZw E8MDpRAAki0KQpdlg00AglHfomXg40A6fzCMha5eFWxG1inPav11+Rquxu/E1q1q z3dt6MsHMxoj+rV9vedpRJKcj1HP0GYIgzXJGLKbA0he5Ie4XCAKMj8KixpcKnIJ GG3giX+ownnHcKOKcV6AvF/wiXoIGaIYCSwllEBZ01bW92rVBIPVkvadbcpCCtR+ rqm4tz6vcRV23M5XqBhzDjaB9IZ+5Xjvyw8CNF2yuoFbPprSML0WVF6NZuF/me8W L3d8P6CVXUzvIJzRN8LogpyYUtcWjx1jgLAt6urU9xCh/kVl08NB0w8Aw2ZIJS3l xI+G2P549TTAg6JK5WGIEUiaNNMjtsO17BEk+PjXwQrtaIemkiPKwLZn0zaZuEsR 5HCV0vRkzMeoYKOD5epZKLRw15nUDMu1I8a/O9Lkxe6u0FNRu8sQ3bO4TwfYSDLv 742YL7UcYVFQq805NBPIeV2WI5W5ROSk8MVQAAyOHQRKTUpJd+cbXJsUFCvAeZ0o EFk3R4CoV6ZoJMDLuq08S4nvDut1TyIF6QJpUWKt5X/kcguz4y0ymoJT2FhDeODf fgIulBc5e8Qa12afbKY2u1OCoFFnQZIwL3tv3PfVXLzGNIO1MeY2la0Is3saMPuy +kAlLDtk0YpVMsLTcmv+5nlehdB554ob72/4y9s0ppOMso1CbYg= =dKM5 -----END PGP SIGNATURE----- Merge tag 'drm-misc-fixes-2021-10-21-1' of git://anongit.freedesktop.org/drm/drm-misc into drm-fixes drm-misc-fixes for v5.15-rc7: - Rebased, to remove vc4 patches. - Fix mxsfb crash on unload. - Use correct sync parameters for Feixin K101-IM2BYL02. - Assorted kmb modeset/atomic fixes. Signed-off-by: Dave Airlie <airlied@redhat.com> From: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/e66eaf89-b9b9-41f5-d0d2-dad7e59fabb5@linux.intel.com
This commit is contained in:
commit
7e1c5440f4
|
@ -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;
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
||||
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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)));
|
||||
|
||||
|
|
|
@ -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__ */
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -590,14 +590,14 @@ static const struct drm_display_mode k101_im2byl02_default_mode = {
|
|||
.clock = 69700,
|
||||
|
||||
.hdisplay = 800,
|
||||
.hsync_start = 800 + 6,
|
||||
.hsync_end = 800 + 6 + 15,
|
||||
.htotal = 800 + 6 + 15 + 16,
|
||||
.hsync_start = 800 + 52,
|
||||
.hsync_end = 800 + 52 + 8,
|
||||
.htotal = 800 + 52 + 8 + 48,
|
||||
|
||||
.vdisplay = 1280,
|
||||
.vsync_start = 1280 + 8,
|
||||
.vsync_end = 1280 + 8 + 48,
|
||||
.vtotal = 1280 + 8 + 48 + 52,
|
||||
.vsync_start = 1280 + 16,
|
||||
.vsync_end = 1280 + 16 + 6,
|
||||
.vtotal = 1280 + 16 + 6 + 15,
|
||||
|
||||
.width_mm = 135,
|
||||
.height_mm = 217,
|
||||
|
|
Loading…
Reference in New Issue