Skip to content

Commit 083320e

Browse files
committed
Merge tag 'drm-misc-next-fixes-2020-10-02' of git://anongit.freedesktop.org/drm/drm-misc into drm-next
Three fixes for vc4 that addresses dual-display breakages Signed-off-by: Dave Airlie <[email protected]> From: Maxime Ripard <[email protected]> Link: https://patchwork.freedesktop.org/patch/msgid/[email protected]
2 parents edb8998 + 8ba0b6d commit 083320e

File tree

3 files changed

+29
-9
lines changed

3 files changed

+29
-9
lines changed

drivers/gpu/drm/vc4/vc4_crtc.c

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -852,11 +852,19 @@ void vc4_crtc_destroy_state(struct drm_crtc *crtc,
852852

853853
void vc4_crtc_reset(struct drm_crtc *crtc)
854854
{
855+
struct vc4_crtc_state *vc4_crtc_state;
856+
855857
if (crtc->state)
856858
vc4_crtc_destroy_state(crtc, crtc->state);
857-
crtc->state = kzalloc(sizeof(struct vc4_crtc_state), GFP_KERNEL);
858-
if (crtc->state)
859-
__drm_atomic_helper_crtc_reset(crtc, crtc->state);
859+
860+
vc4_crtc_state = kzalloc(sizeof(*vc4_crtc_state), GFP_KERNEL);
861+
if (!vc4_crtc_state) {
862+
crtc->state = NULL;
863+
return;
864+
}
865+
866+
vc4_crtc_state->assigned_channel = VC4_HVS_CHANNEL_DISABLED;
867+
__drm_atomic_helper_crtc_reset(crtc, &vc4_crtc_state->base);
860868
}
861869

862870
static const struct drm_crtc_funcs vc4_crtc_funcs = {

drivers/gpu/drm/vc4/vc4_drv.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -532,6 +532,8 @@ struct vc4_crtc_state {
532532
} margins;
533533
};
534534

535+
#define VC4_HVS_CHANNEL_DISABLED ((unsigned int)-1)
536+
535537
static inline struct vc4_crtc_state *
536538
to_vc4_crtc_state(struct drm_crtc_state *crtc_state)
537539
{

drivers/gpu/drm/vc4/vc4_kms.c

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -616,7 +616,7 @@ static int
616616
vc4_atomic_check(struct drm_device *dev, struct drm_atomic_state *state)
617617
{
618618
unsigned long unassigned_channels = GENMASK(NUM_CHANNELS - 1, 0);
619-
struct drm_crtc_state *crtc_state;
619+
struct drm_crtc_state *old_crtc_state, *new_crtc_state;
620620
struct drm_crtc *crtc;
621621
int i, ret;
622622

@@ -629,6 +629,8 @@ vc4_atomic_check(struct drm_device *dev, struct drm_atomic_state *state)
629629
* modified.
630630
*/
631631
list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
632+
struct drm_crtc_state *crtc_state;
633+
632634
if (!crtc->state->enable)
633635
continue;
634636

@@ -637,15 +639,23 @@ vc4_atomic_check(struct drm_device *dev, struct drm_atomic_state *state)
637639
return PTR_ERR(crtc_state);
638640
}
639641

640-
for_each_new_crtc_in_state(state, crtc, crtc_state, i) {
641-
struct vc4_crtc_state *vc4_crtc_state =
642-
to_vc4_crtc_state(crtc_state);
642+
for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) {
643+
struct vc4_crtc_state *new_vc4_crtc_state =
644+
to_vc4_crtc_state(new_crtc_state);
643645
struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc);
644646
unsigned int matching_channels;
645647

646-
if (!crtc_state->active)
648+
if (old_crtc_state->enable && !new_crtc_state->enable)
649+
new_vc4_crtc_state->assigned_channel = VC4_HVS_CHANNEL_DISABLED;
650+
651+
if (!new_crtc_state->enable)
647652
continue;
648653

654+
if (new_vc4_crtc_state->assigned_channel != VC4_HVS_CHANNEL_DISABLED) {
655+
unassigned_channels &= ~BIT(new_vc4_crtc_state->assigned_channel);
656+
continue;
657+
}
658+
649659
/*
650660
* The problem we have to solve here is that we have
651661
* up to 7 encoders, connected to up to 6 CRTCs.
@@ -674,7 +684,7 @@ vc4_atomic_check(struct drm_device *dev, struct drm_atomic_state *state)
674684
if (matching_channels) {
675685
unsigned int channel = ffs(matching_channels) - 1;
676686

677-
vc4_crtc_state->assigned_channel = channel;
687+
new_vc4_crtc_state->assigned_channel = channel;
678688
unassigned_channels &= ~BIT(channel);
679689
} else {
680690
return -EINVAL;

0 commit comments

Comments
 (0)