Implement a read function for struct drm_edid and read the EDID data
with drm_edit_read_custom(). Update the connector data accordingly.

The EDID data comes from the emulator itself and the connector stores
a copy in its EDID property. The drm_edid field in struct bochs_device
is therefore not required. Remove it.

If qemu provides no EDID data, install default display modes as before.

Signed-off-by: Thomas Zimmermann <tzimmerm...@suse.de>
Acked-by: Gerd Hoffmann <kra...@redhat.com>
---
 drivers/gpu/drm/tiny/bochs.c | 48 +++++++++++++++++-------------------
 1 file changed, 22 insertions(+), 26 deletions(-)

diff --git a/drivers/gpu/drm/tiny/bochs.c b/drivers/gpu/drm/tiny/bochs.c
index 47a45a14306c..197fc00b373f 100644
--- a/drivers/gpu/drm/tiny/bochs.c
+++ b/drivers/gpu/drm/tiny/bochs.c
@@ -85,7 +85,6 @@ struct bochs_device {
        u16 yres_virtual;
        u32 stride;
        u32 bpp;
-       const struct drm_edid *drm_edid;
 
        /* drm */
        struct drm_device *dev;
@@ -172,12 +171,14 @@ static void bochs_hw_set_little_endian(struct 
bochs_device *bochs)
 #define bochs_hw_set_native_endian(_b) bochs_hw_set_little_endian(_b)
 #endif
 
-static int bochs_get_edid_block(void *data, u8 *buf,
-                               unsigned int block, size_t len)
+static int bochs_get_edid_block(void *data, u8 *buf, unsigned int block, 
size_t len)
 {
        struct bochs_device *bochs = data;
        size_t i, start = block * EDID_LENGTH;
 
+       if (!bochs->mmio)
+               return -1;
+
        if (start + len > 0x400 /* vga register offset */)
                return -1;
 
@@ -187,25 +188,20 @@ static int bochs_get_edid_block(void *data, u8 *buf,
        return 0;
 }
 
-static int bochs_hw_load_edid(struct bochs_device *bochs)
+static const struct drm_edid *bochs_hw_read_edid(struct drm_connector 
*connector)
 {
+       struct drm_device *dev = connector->dev;
+       struct bochs_device *bochs = dev->dev_private;
        u8 header[8];
 
-       if (!bochs->mmio)
-               return -1;
-
        /* check header to detect whenever edid support is enabled in qemu */
        bochs_get_edid_block(bochs, header, 0, ARRAY_SIZE(header));
        if (drm_edid_header_is_valid(header) != 8)
-               return -1;
+               return NULL;
 
-       drm_edid_free(bochs->drm_edid);
-       bochs->drm_edid = drm_edid_read_custom(&bochs->connector,
-                                              bochs_get_edid_block, bochs);
-       if (!bochs->drm_edid)
-               return -1;
+       drm_dbg(dev, "Found EDID data blob.\n");
 
-       return 0;
+       return drm_edid_read_custom(connector, bochs_get_edid_block, bochs);
 }
 
 static int bochs_hw_init(struct drm_device *dev)
@@ -303,7 +299,6 @@ static void bochs_hw_fini(struct drm_device *dev)
        if (bochs->fb_map)
                iounmap(bochs->fb_map);
        pci_release_regions(to_pci_dev(dev->dev));
-       drm_edid_free(bochs->drm_edid);
 }
 
 static void bochs_hw_blank(struct bochs_device *bochs, bool blank)
@@ -469,21 +464,28 @@ static const struct drm_simple_display_pipe_funcs 
bochs_pipe_funcs = {
        .cleanup_fb = drm_gem_vram_simple_display_pipe_cleanup_fb,
 };
 
-static int bochs_connector_get_modes(struct drm_connector *connector)
+static int bochs_connector_helper_get_modes(struct drm_connector *connector)
 {
+       const struct drm_edid *edid;
        int count;
 
-       count = drm_edid_connector_add_modes(connector);
+       edid = bochs_hw_read_edid(connector);
 
-       if (!count) {
+       if (edid) {
+               drm_edid_connector_update(connector, edid);
+               count = drm_edid_connector_add_modes(connector);
+               drm_edid_free(edid);
+       } else {
+               drm_edid_connector_update(connector, NULL);
                count = drm_add_modes_noedid(connector, 8192, 8192);
                drm_set_preferred_mode(connector, defx, defy);
        }
+
        return count;
 }
 
 static const struct drm_connector_helper_funcs 
bochs_connector_connector_helper_funcs = {
-       .get_modes = bochs_connector_get_modes,
+       .get_modes = bochs_connector_helper_get_modes,
 };
 
 static const struct drm_connector_funcs bochs_connector_connector_funcs = {
@@ -501,14 +503,8 @@ static void bochs_connector_init(struct drm_device *dev)
 
        drm_connector_init(dev, connector, &bochs_connector_connector_funcs,
                           DRM_MODE_CONNECTOR_VIRTUAL);
+       drm_connector_attach_edid_property(connector);
        drm_connector_helper_add(connector, 
&bochs_connector_connector_helper_funcs);
-
-       bochs_hw_load_edid(bochs);
-       if (bochs->drm_edid) {
-               DRM_INFO("Found EDID data blob.\n");
-               drm_connector_attach_edid_property(connector);
-               drm_edid_connector_update(&bochs->connector, bochs->drm_edid);
-       }
 }
 
 static const struct drm_mode_config_funcs bochs_mode_funcs = {
-- 
2.46.0

Reply via email to