1 // SPDX-License-Identifier: GPL-2.0-only
3 * Copyright (C) 2017 The Linux Foundation. All rights reserved.
9 * As of now, there are only 2 combinations possible for source split:
17 static int lm_right_pair
[] = { 1, -1, 5, -1, -1, -1 };
19 static int get_right_pair_idx(struct mdp5_kms
*mdp5_kms
, int lm
)
24 pair_lm
= lm_right_pair
[lm
];
28 for (i
= 0; i
< mdp5_kms
->num_hwmixers
; i
++) {
29 struct mdp5_hw_mixer
*mixer
= mdp5_kms
->hwmixers
[i
];
31 if (mixer
->lm
== pair_lm
)
38 int mdp5_mixer_assign(struct drm_atomic_state
*s
, struct drm_crtc
*crtc
,
39 uint32_t caps
, struct mdp5_hw_mixer
**mixer
,
40 struct mdp5_hw_mixer
**r_mixer
)
42 struct msm_drm_private
*priv
= s
->dev
->dev_private
;
43 struct mdp5_kms
*mdp5_kms
= to_mdp5_kms(to_mdp_kms(priv
->kms
));
44 struct mdp5_global_state
*global_state
= mdp5_get_global_state(s
);
45 struct mdp5_hw_mixer_state
*new_state
;
48 if (IS_ERR(global_state
))
49 return PTR_ERR(global_state
);
51 new_state
= &global_state
->hwmixer
;
53 for (i
= 0; i
< mdp5_kms
->num_hwmixers
; i
++) {
54 struct mdp5_hw_mixer
*cur
= mdp5_kms
->hwmixers
[i
];
57 * skip if already in-use by a different CRTC. If there is a
58 * mixer already assigned to this CRTC, it means this call is
59 * a request to get an additional right mixer. Assume that the
60 * existing mixer is the 'left' one, and try to see if we can
61 * get its corresponding 'right' pair.
63 if (new_state
->hwmixer_to_crtc
[cur
->idx
] &&
64 new_state
->hwmixer_to_crtc
[cur
->idx
] != crtc
)
67 /* skip if doesn't support some required caps: */
68 if (caps
& ~cur
->caps
)
74 pair_idx
= get_right_pair_idx(mdp5_kms
, cur
->lm
);
78 if (new_state
->hwmixer_to_crtc
[pair_idx
])
81 *r_mixer
= mdp5_kms
->hwmixers
[pair_idx
];
85 * prefer a pair-able LM over an unpairable one. We can
86 * switch the CRTC from Normal mode to Source Split mode
87 * without requiring a full modeset if we had already
88 * assigned this CRTC a pair-able LM.
90 * TODO: There will be assignment sequences which would
91 * result in the CRTC requiring a full modeset, even
92 * if we have the LM resources to prevent it. For a platform
93 * with a few displays, we don't run out of pair-able LMs
94 * so easily. For now, ignore the possibility of requiring
97 if (!(*mixer
) || cur
->caps
& MDP_LM_CAP_PAIR
)
104 if (r_mixer
&& !(*r_mixer
))
107 DBG("assigning Layer Mixer %d to crtc %s", (*mixer
)->lm
, crtc
->name
);
109 new_state
->hwmixer_to_crtc
[(*mixer
)->idx
] = crtc
;
111 DBG("assigning Right Layer Mixer %d to crtc %s", (*r_mixer
)->lm
,
113 new_state
->hwmixer_to_crtc
[(*r_mixer
)->idx
] = crtc
;
119 void mdp5_mixer_release(struct drm_atomic_state
*s
, struct mdp5_hw_mixer
*mixer
)
121 struct mdp5_global_state
*global_state
= mdp5_get_global_state(s
);
122 struct mdp5_hw_mixer_state
*new_state
= &global_state
->hwmixer
;
127 if (WARN_ON(!new_state
->hwmixer_to_crtc
[mixer
->idx
]))
130 DBG("%s: release from crtc %s", mixer
->name
,
131 new_state
->hwmixer_to_crtc
[mixer
->idx
]->name
);
133 new_state
->hwmixer_to_crtc
[mixer
->idx
] = NULL
;
136 void mdp5_mixer_destroy(struct mdp5_hw_mixer
*mixer
)
141 static const char * const mixer_names
[] = {
142 "LM0", "LM1", "LM2", "LM3", "LM4", "LM5",
145 struct mdp5_hw_mixer
*mdp5_mixer_init(const struct mdp5_lm_instance
*lm
)
147 struct mdp5_hw_mixer
*mixer
;
149 mixer
= kzalloc(sizeof(*mixer
), GFP_KERNEL
);
151 return ERR_PTR(-ENOMEM
);
153 mixer
->name
= mixer_names
[lm
->id
];
155 mixer
->caps
= lm
->caps
;
157 mixer
->dspp
= lm
->dspp
;
158 mixer
->flush_mask
= mdp_ctl_flush_mask_lm(lm
->id
);