From 1b9eb8d557c692e5f1dd831b5e7134e6d07a4dd4 Mon Sep 17 00:00:00 2001 From: Dave Stevenson Date: Tue, 9 Apr 2019 14:00:07 +0100 Subject: [PATCH] drm/vc4: Set the display number when querying the display resolution Without this the two displays got set to the same resolution. (Requires a firmware bug fix to work). Signed-off-by: Dave Stevenson --- drivers/gpu/drm/vc4/vc4_firmware_kms.c | 37 +++++++++++++++++++------- 1 file changed, 27 insertions(+), 10 deletions(-) --- a/drivers/gpu/drm/vc4/vc4_firmware_kms.c +++ b/drivers/gpu/drm/vc4/vc4_firmware_kms.c @@ -75,6 +75,13 @@ struct mailbox_blank_display { u32 blank; }; +struct mailbox_get_width_height { + struct rpi_firmware_property_tag_header tag1; + u32 display; + struct rpi_firmware_property_tag_header tag2; + u32 wh[2]; +}; + static const struct vc_image_format { u32 drm; /* DRM_FORMAT_* */ u32 vc_image; /* VC_IMAGE_* */ @@ -192,6 +199,7 @@ struct vc4_fkms_connector { * hook. */ struct drm_encoder *encoder; + u32 display_idx; }; static inline struct vc4_fkms_connector * @@ -723,21 +731,27 @@ vc4_fkms_connector_detect(struct drm_con static int vc4_fkms_connector_get_modes(struct drm_connector *connector) { struct drm_device *dev = connector->dev; + struct vc4_fkms_connector *fkms_connector = + to_vc4_fkms_connector(connector); struct vc4_dev *vc4 = to_vc4_dev(dev); - u32 wh[2] = {0, 0}; - int ret; struct drm_display_mode *mode; + struct mailbox_get_width_height wh = { + .tag1 = {RPI_FIRMWARE_FRAMEBUFFER_SET_DISPLAY_NUM, 4, 0, }, + .display = fkms_connector->display_idx, + .tag2 = { RPI_FIRMWARE_FRAMEBUFFER_GET_PHYSICAL_WIDTH_HEIGHT, + 8, 0, }, + }; + int ret; + + ret = rpi_firmware_property_list(vc4->firmware, &wh, sizeof(wh)); - ret = rpi_firmware_property(vc4->firmware, - RPI_FIRMWARE_FRAMEBUFFER_GET_PHYSICAL_WIDTH_HEIGHT, - &wh, sizeof(wh)); if (ret) { DRM_ERROR("Failed to get screen size: %d (0x%08x 0x%08x)\n", - ret, wh[0], wh[1]); + ret, wh.wh[0], wh.wh[1]); return 0; } - mode = drm_cvt_mode(dev, wh[0], wh[1], 60 /* vrefresh */, + mode = drm_cvt_mode(dev, wh.wh[0], wh.wh[1], 60 /* vrefresh */, 0, 0, false); drm_mode_probed_add(connector, mode); @@ -772,8 +786,9 @@ static const struct drm_connector_helper .best_encoder = vc4_fkms_connector_best_encoder, }; -static struct drm_connector *vc4_fkms_connector_init(struct drm_device *dev, - struct drm_encoder *encoder) +static struct drm_connector * +vc4_fkms_connector_init(struct drm_device *dev, struct drm_encoder *encoder, + u32 display_idx) { struct drm_connector *connector = NULL; struct vc4_fkms_connector *fkms_connector; @@ -788,6 +803,7 @@ static struct drm_connector *vc4_fkms_co connector = &fkms_connector->base; fkms_connector->encoder = encoder; + fkms_connector->display_idx = display_idx; drm_connector_init(dev, connector, &vc4_fkms_connector_funcs, DRM_MODE_CONNECTOR_HDMIA); @@ -904,7 +920,8 @@ static int vc4_fkms_create_screen(struct drm_encoder_helper_add(&vc4_encoder->base, &vc4_fkms_encoder_helper_funcs); - vc4_crtc->connector = vc4_fkms_connector_init(drm, &vc4_encoder->base); + vc4_crtc->connector = vc4_fkms_connector_init(drm, &vc4_encoder->base, + display_idx); if (IS_ERR(vc4_crtc->connector)) { ret = PTR_ERR(vc4_crtc->connector); goto err_destroy_encoder;