drm/vc4: crtc: Assign output to channel automatically
The HVS found in the BCM2711 has 6 outputs and 3 FIFOs, with each output being connected to a pixelvalve, and some muxing between the FIFOs and outputs. Any output cannot feed from any FIFO though, and they all have a bunch of constraints. In order to support this, let's store the possible FIFOs each output can be assigned to in the vc4_crtc_data, and use that information at atomic_check time to iterate over all the CRTCs enabled and assign them FIFOs. The channel assigned is then set in the vc4_crtc_state so that the rest of the driver can use it. Signed-off-by: Maxime Ripard <maxime@cerno.tech> Tested-by: Chanwoo Choi <cw00.choi@samsung.com> Tested-by: Hoegeun Kwon <hoegeun.kwon@samsung.com> Tested-by: Stefan Wahren <stefan.wahren@i2se.com> Reviewed-by: Dave Stevenson <dave.stevenson@raspberrypi.com> Link: https://patchwork.freedesktop.org/patch/msgid/f9aba3814ef37156ff36f310118cdd3954dd3dc5.1599120059.git-series.maxime@cerno.tech
This commit is contained in:
@@ -88,6 +88,7 @@ static bool vc4_crtc_get_scanout_position(struct drm_crtc *crtc,
|
||||
struct drm_device *dev = crtc->dev;
|
||||
struct vc4_dev *vc4 = to_vc4_dev(dev);
|
||||
struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc);
|
||||
struct vc4_crtc_state *vc4_crtc_state = to_vc4_crtc_state(crtc->state);
|
||||
unsigned int cob_size;
|
||||
u32 val;
|
||||
int fifo_lines;
|
||||
@@ -104,7 +105,7 @@ static bool vc4_crtc_get_scanout_position(struct drm_crtc *crtc,
|
||||
* Read vertical scanline which is currently composed for our
|
||||
* pixelvalve by the HVS, and also the scaler status.
|
||||
*/
|
||||
val = HVS_READ(SCALER_DISPSTATX(vc4_crtc->channel));
|
||||
val = HVS_READ(SCALER_DISPSTATX(vc4_crtc_state->assigned_channel));
|
||||
|
||||
/* Get optional system timestamp after query. */
|
||||
if (etime)
|
||||
@@ -124,7 +125,7 @@ static bool vc4_crtc_get_scanout_position(struct drm_crtc *crtc,
|
||||
*hpos += mode->crtc_htotal / 2;
|
||||
}
|
||||
|
||||
cob_size = vc4_crtc_get_cob_allocation(vc4, vc4_crtc->channel);
|
||||
cob_size = vc4_crtc_get_cob_allocation(vc4, vc4_crtc_state->assigned_channel);
|
||||
/* This is the offset we need for translating hvs -> pv scanout pos. */
|
||||
fifo_lines = cob_size / mode->crtc_hdisplay;
|
||||
|
||||
@@ -520,7 +521,7 @@ static void vc4_crtc_handle_page_flip(struct vc4_crtc *vc4_crtc)
|
||||
struct drm_device *dev = crtc->dev;
|
||||
struct vc4_dev *vc4 = to_vc4_dev(dev);
|
||||
struct vc4_crtc_state *vc4_state = to_vc4_crtc_state(crtc->state);
|
||||
u32 chan = vc4_crtc->channel;
|
||||
u32 chan = vc4_state->assigned_channel;
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&dev->event_lock, flags);
|
||||
@@ -719,6 +720,7 @@ struct drm_crtc_state *vc4_crtc_duplicate_state(struct drm_crtc *crtc)
|
||||
old_vc4_state = to_vc4_crtc_state(crtc->state);
|
||||
vc4_state->feed_txp = old_vc4_state->feed_txp;
|
||||
vc4_state->margins = old_vc4_state->margins;
|
||||
vc4_state->assigned_channel = old_vc4_state->assigned_channel;
|
||||
|
||||
__drm_atomic_helper_crtc_duplicate_state(crtc, &vc4_state->base);
|
||||
return &vc4_state->base;
|
||||
@@ -779,6 +781,7 @@ static const struct drm_crtc_helper_funcs vc4_crtc_helper_funcs = {
|
||||
|
||||
static const struct vc4_pv_data bcm2835_pv0_data = {
|
||||
.base = {
|
||||
.hvs_available_channels = BIT(0),
|
||||
.hvs_output = 0,
|
||||
},
|
||||
.debugfs_name = "crtc0_regs",
|
||||
@@ -791,6 +794,7 @@ static const struct vc4_pv_data bcm2835_pv0_data = {
|
||||
|
||||
static const struct vc4_pv_data bcm2835_pv1_data = {
|
||||
.base = {
|
||||
.hvs_available_channels = BIT(2),
|
||||
.hvs_output = 2,
|
||||
},
|
||||
.debugfs_name = "crtc1_regs",
|
||||
@@ -803,6 +807,7 @@ static const struct vc4_pv_data bcm2835_pv1_data = {
|
||||
|
||||
static const struct vc4_pv_data bcm2835_pv2_data = {
|
||||
.base = {
|
||||
.hvs_available_channels = BIT(1),
|
||||
.hvs_output = 1,
|
||||
},
|
||||
.debugfs_name = "crtc2_regs",
|
||||
@@ -866,7 +871,6 @@ int vc4_crtc_init(struct drm_device *drm, struct vc4_crtc *vc4_crtc,
|
||||
drm_crtc_init_with_planes(drm, crtc, primary_plane, NULL,
|
||||
crtc_funcs, NULL);
|
||||
drm_crtc_helper_add(crtc, crtc_helper_funcs);
|
||||
vc4_crtc->channel = vc4_crtc->data->hvs_output;
|
||||
drm_mode_crtc_set_gamma_size(crtc, ARRAY_SIZE(vc4_crtc->lut_r));
|
||||
drm_crtc_enable_color_mgmt(crtc, 0, false, crtc->gamma_size);
|
||||
|
||||
|
Reference in New Issue
Block a user