Skip to content

Commit 5befcdc

Browse files
Liu YingMarek Vasut
authored andcommitted
drm: lcdif: Determine bus format and flags in ->atomic_check()
Instead of determining LCDIF output bus format and bus flags in ->atomic_enable(), do that in ->atomic_check(). This is a preparation for the upcoming patch to check consistent bus format and bus flags across all first downstream bridges in ->atomic_check(). New lcdif_crtc_state structure is introduced to cache bus format and bus flags states in ->atomic_check() so that they can be read in ->atomic_enable(). Tested-by: Alexander Stein <alexander.stein@ew.tq-group.com> Reviewed-by: Alexander Stein <alexander.stein@ew.tq-group.com> Reviewed-by: Marek Vasut <marex@denx.de> Signed-off-by: Liu Ying <victor.liu@nxp.com> Signed-off-by: Marek Vasut <marex@denx.de> Link: https://patchwork.freedesktop.org/patch/msgid/20230510092450.4024730-4-victor.liu@nxp.com
1 parent 3f07432 commit 5befcdc

1 file changed

Lines changed: 102 additions & 38 deletions

File tree

drivers/gpu/drm/mxsfb/lcdif_kms.c

Lines changed: 102 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,18 @@
3030
#include "lcdif_drv.h"
3131
#include "lcdif_regs.h"
3232

33+
struct lcdif_crtc_state {
34+
struct drm_crtc_state base; /* always be the first member */
35+
u32 bus_format;
36+
u32 bus_flags;
37+
};
38+
39+
static inline struct lcdif_crtc_state *
40+
to_lcdif_crtc_state(struct drm_crtc_state *s)
41+
{
42+
return container_of(s, struct lcdif_crtc_state, base);
43+
}
44+
3345
/* -----------------------------------------------------------------------------
3446
* CRTC
3547
*/
@@ -385,48 +397,75 @@ static void lcdif_reset_block(struct lcdif_drm_private *lcdif)
385397
readl(lcdif->base + LCDC_V8_CTRL);
386398
}
387399

388-
static void lcdif_crtc_mode_set_nofb(struct lcdif_drm_private *lcdif,
389-
struct drm_plane_state *plane_state,
390-
struct drm_bridge_state *bridge_state,
391-
const u32 bus_format)
400+
static void lcdif_crtc_mode_set_nofb(struct drm_crtc_state *crtc_state,
401+
struct drm_plane_state *plane_state)
392402
{
393-
struct drm_device *drm = lcdif->crtc.dev;
394-
struct drm_display_mode *m = &lcdif->crtc.state->adjusted_mode;
395-
u32 bus_flags = 0;
396-
397-
if (lcdif->bridge->timings)
398-
bus_flags = lcdif->bridge->timings->input_bus_flags;
399-
else if (bridge_state)
400-
bus_flags = bridge_state->input_bus_cfg.flags;
403+
struct lcdif_crtc_state *lcdif_crtc_state = to_lcdif_crtc_state(crtc_state);
404+
struct drm_device *drm = crtc_state->crtc->dev;
405+
struct lcdif_drm_private *lcdif = to_lcdif_drm_private(drm);
406+
struct drm_display_mode *m = &crtc_state->adjusted_mode;
401407

402408
DRM_DEV_DEBUG_DRIVER(drm->dev, "Pixel clock: %dkHz (actual: %dkHz)\n",
403409
m->crtc_clock,
404410
(int)(clk_get_rate(lcdif->clk) / 1000));
405411
DRM_DEV_DEBUG_DRIVER(drm->dev, "Bridge bus_flags: 0x%08X\n",
406-
bus_flags);
412+
lcdif_crtc_state->bus_flags);
407413
DRM_DEV_DEBUG_DRIVER(drm->dev, "Mode flags: 0x%08X\n", m->flags);
408414

409415
/* Mandatory eLCDIF reset as per the Reference Manual */
410416
lcdif_reset_block(lcdif);
411417

412-
lcdif_set_formats(lcdif, plane_state, bus_format);
418+
lcdif_set_formats(lcdif, plane_state, lcdif_crtc_state->bus_format);
413419

414-
lcdif_set_mode(lcdif, bus_flags);
420+
lcdif_set_mode(lcdif, lcdif_crtc_state->bus_flags);
415421
}
416422

417423
static int lcdif_crtc_atomic_check(struct drm_crtc *crtc,
418424
struct drm_atomic_state *state)
419425
{
426+
struct drm_device *drm = crtc->dev;
427+
struct lcdif_drm_private *lcdif = to_lcdif_drm_private(drm);
420428
struct drm_crtc_state *crtc_state = drm_atomic_get_new_crtc_state(state,
421429
crtc);
430+
struct lcdif_crtc_state *lcdif_crtc_state = to_lcdif_crtc_state(crtc_state);
422431
bool has_primary = crtc_state->plane_mask &
423432
drm_plane_mask(crtc->primary);
433+
struct drm_bridge_state *bridge_state;
434+
struct drm_bridge *bridge = lcdif->bridge;
435+
int ret;
424436

425437
/* The primary plane has to be enabled when the CRTC is active. */
426438
if (crtc_state->active && !has_primary)
427439
return -EINVAL;
428440

429-
return drm_atomic_add_affected_planes(state, crtc);
441+
ret = drm_atomic_add_affected_planes(state, crtc);
442+
if (ret)
443+
return ret;
444+
445+
bridge_state = drm_atomic_get_new_bridge_state(state, bridge);
446+
if (!bridge_state)
447+
lcdif_crtc_state->bus_format = MEDIA_BUS_FMT_FIXED;
448+
else
449+
lcdif_crtc_state->bus_format = bridge_state->input_bus_cfg.format;
450+
451+
if (lcdif_crtc_state->bus_format == MEDIA_BUS_FMT_FIXED) {
452+
dev_warn_once(drm->dev,
453+
"Bridge does not provide bus format, assuming MEDIA_BUS_FMT_RGB888_1X24.\n"
454+
"Please fix bridge driver by handling atomic_get_input_bus_fmts.\n");
455+
lcdif_crtc_state->bus_format = MEDIA_BUS_FMT_RGB888_1X24;
456+
} else if (!lcdif_crtc_state->bus_format) {
457+
/* If all else fails, default to RGB888_1X24 */
458+
lcdif_crtc_state->bus_format = MEDIA_BUS_FMT_RGB888_1X24;
459+
}
460+
461+
if (bridge->timings)
462+
lcdif_crtc_state->bus_flags = bridge->timings->input_bus_flags;
463+
else if (bridge_state)
464+
lcdif_crtc_state->bus_flags = bridge_state->input_bus_cfg.flags;
465+
else
466+
lcdif_crtc_state->bus_flags = 0;
467+
468+
return 0;
430469
}
431470

432471
static void lcdif_crtc_atomic_flush(struct drm_crtc *crtc,
@@ -458,35 +497,18 @@ static void lcdif_crtc_atomic_enable(struct drm_crtc *crtc,
458497
struct drm_atomic_state *state)
459498
{
460499
struct lcdif_drm_private *lcdif = to_lcdif_drm_private(crtc->dev);
500+
struct drm_crtc_state *new_cstate = drm_atomic_get_new_crtc_state(state, crtc);
461501
struct drm_plane_state *new_pstate = drm_atomic_get_new_plane_state(state,
462502
crtc->primary);
463503
struct drm_display_mode *m = &lcdif->crtc.state->adjusted_mode;
464-
struct drm_bridge_state *bridge_state = NULL;
465504
struct drm_device *drm = lcdif->drm;
466-
u32 bus_format;
467505
dma_addr_t paddr;
468506

469-
bridge_state = drm_atomic_get_new_bridge_state(state, lcdif->bridge);
470-
if (!bridge_state)
471-
bus_format = MEDIA_BUS_FMT_FIXED;
472-
else
473-
bus_format = bridge_state->input_bus_cfg.format;
474-
475-
if (bus_format == MEDIA_BUS_FMT_FIXED) {
476-
dev_warn_once(drm->dev,
477-
"Bridge does not provide bus format, assuming MEDIA_BUS_FMT_RGB888_1X24.\n"
478-
"Please fix bridge driver by handling atomic_get_input_bus_fmts.\n");
479-
bus_format = MEDIA_BUS_FMT_RGB888_1X24;
480-
} else if (!bus_format) {
481-
/* If all else fails, default to RGB888_1X24 */
482-
bus_format = MEDIA_BUS_FMT_RGB888_1X24;
483-
}
484-
485507
clk_set_rate(lcdif->clk, m->crtc_clock * 1000);
486508

487509
pm_runtime_get_sync(drm->dev);
488510

489-
lcdif_crtc_mode_set_nofb(lcdif, new_pstate, bridge_state, bus_format);
511+
lcdif_crtc_mode_set_nofb(new_cstate, new_pstate);
490512

491513
/* Write cur_buf as well to avoid an initial corrupt frame */
492514
paddr = drm_fb_dma_get_gem_addr(new_pstate->fb, new_pstate, 0);
@@ -523,6 +545,48 @@ static void lcdif_crtc_atomic_disable(struct drm_crtc *crtc,
523545
pm_runtime_put_sync(drm->dev);
524546
}
525547

548+
static void lcdif_crtc_atomic_destroy_state(struct drm_crtc *crtc,
549+
struct drm_crtc_state *state)
550+
{
551+
__drm_atomic_helper_crtc_destroy_state(state);
552+
kfree(to_lcdif_crtc_state(state));
553+
}
554+
555+
static void lcdif_crtc_reset(struct drm_crtc *crtc)
556+
{
557+
struct lcdif_crtc_state *state;
558+
559+
if (crtc->state)
560+
lcdif_crtc_atomic_destroy_state(crtc, crtc->state);
561+
562+
crtc->state = NULL;
563+
564+
state = kzalloc(sizeof(*state), GFP_KERNEL);
565+
if (state)
566+
__drm_atomic_helper_crtc_reset(crtc, &state->base);
567+
}
568+
569+
static struct drm_crtc_state *
570+
lcdif_crtc_atomic_duplicate_state(struct drm_crtc *crtc)
571+
{
572+
struct lcdif_crtc_state *old = to_lcdif_crtc_state(crtc->state);
573+
struct lcdif_crtc_state *new;
574+
575+
if (WARN_ON(!crtc->state))
576+
return NULL;
577+
578+
new = kzalloc(sizeof(*new), GFP_KERNEL);
579+
if (!new)
580+
return NULL;
581+
582+
__drm_atomic_helper_crtc_duplicate_state(crtc, &new->base);
583+
584+
new->bus_format = old->bus_format;
585+
new->bus_flags = old->bus_flags;
586+
587+
return &new->base;
588+
}
589+
526590
static int lcdif_crtc_enable_vblank(struct drm_crtc *crtc)
527591
{
528592
struct lcdif_drm_private *lcdif = to_lcdif_drm_private(crtc->dev);
@@ -551,12 +615,12 @@ static const struct drm_crtc_helper_funcs lcdif_crtc_helper_funcs = {
551615
};
552616

553617
static const struct drm_crtc_funcs lcdif_crtc_funcs = {
554-
.reset = drm_atomic_helper_crtc_reset,
618+
.reset = lcdif_crtc_reset,
555619
.destroy = drm_crtc_cleanup,
556620
.set_config = drm_atomic_helper_set_config,
557621
.page_flip = drm_atomic_helper_page_flip,
558-
.atomic_duplicate_state = drm_atomic_helper_crtc_duplicate_state,
559-
.atomic_destroy_state = drm_atomic_helper_crtc_destroy_state,
622+
.atomic_duplicate_state = lcdif_crtc_atomic_duplicate_state,
623+
.atomic_destroy_state = lcdif_crtc_atomic_destroy_state,
560624
.enable_vblank = lcdif_crtc_enable_vblank,
561625
.disable_vblank = lcdif_crtc_disable_vblank,
562626
};

0 commit comments

Comments
 (0)