drm tiled monitor support (not hiding in kernel)
Subsystems (3)
Dave Airlie
maintainerSo I believe attempts to hide the DP MST tiled monitors in the kernel, are a path to failure, so I've resurrected my previous code to just create a tile property on the connectors for userspace to key off.
The contents of the tile blob are ABI, and I expect it to be parsed by a fair few userspace projects.
So far I've ported a few pieces of GNOME to using it and posted patches for that to their lists,
The X server should use this for make better XINERAMA info, but otherwise drivers should pass the TILE property through to the clients, as it contains nothing kernel specific.
Dave.
Dave Airlie
maintainerPATCH 1/6 drm/displayid: add displayid defines and edid extension
From: Dave Airlie <[email protected]>
These are just taken from the DisplayID v1.3 spec, and the DDC spec.
--- include/drm/drm_displayid.h | 76 +++++++++++++++++++++++++++++++++++++++++++++ include/drm/drm_edid.h | 2 ++ 2 files changed, 78 insertions(+) create mode 100644 include/drm/drm_displayid.h
include/drm/drm_displayid.h new file +76 -0
@@ -0,0 +1,76 @@ +/* +* Copyright © 2014 Red Hat Inc. +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR +* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +* OTHER DEALINGS IN THE SOFTWARE. +*/ +#ifndef DRM_DISPLAYID_H +#define DRM_DISPLAYID_H + +#define DATA_BLOCK_PRODUCT_ID 0x00 +#define DATA_BLOCK_DISPLAY_PARAMETERS 0x01 +#define DATA_BLOCK_COLOR_CHARACTERISTICS 0x02 +#define DATA_BLOCK_TYPE_1_DETAILED_TIMING 0x03 +#define DATA_BLOCK_TYPE_2_DETAILED_TIMING 0x04 +#define DATA_BLOCK_TYPE_3_SHORT_TIMING 0x05 +#define DATA_BLOCK_TYPE_4_DMT_TIMING 0x06 +#define DATA_BLOCK_VESA_TIMING 0x07 +#define DATA_BLOCK_CEA_TIMING 0x08 +#define DATA_BLOCK_VIDEO_TIMING_RANGE 0x09 +#define DATA_BLOCK_PRODUCT_SERIAL_NUMBER 0x0a +#define DATA_BLOCK_GP_ASCII_STRING 0x0b +#define DATA_BLOCK_DISPLAY_DEVICE_DATA 0x0c +#define DATA_BLOCK_INTERFACE_POWER_SEQUENCING 0x0d +#define DATA_BLOCK_TRANSFER_CHARACTERISTICS 0x0e +#define DATA_BLOCK_DISPLAY_INTERFACE 0x0f +#define DATA_BLOCK_STEREO_DISPLAY_INTERFACE 0x10 +#define DATA_BLOCK_TILED_DISPLAY 0x12 + +#define DATA_BLOCK_VENDOR_SPECIFIC 0x7f + +#define PRODUCT_TYPE_EXTENSION 0 +#define PRODUCT_TYPE_TEST 1 +#define PRODUCT_TYPE_PANEL 2 +#define PRODUCT_TYPE_MONITOR 3 +#define PRODUCT_TYPE_TV 4 +#define PRODUCT_TYPE_REPEATER 5 +#define PRODUCT_TYPE_DIRECT_DRIVE 6 + +struct displayid_hdr { +u8 rev; +u8 bytes; +u8 prod_id; +u8 ext_count; +} __attribute__((packed)); + +struct displayid_block { +u8 tag; +u8 rev; +u8 num_bytes; +}; + +struct displayid_tiled_block { +struct displayid_block base; +u8 tile_cap; +u8 topo[3 ]; +u8 tile_size[4 ]; +u8 tile_pixel_bezel[5 ]; +u8 topology_id[8 ]; +} __attribute__((packed)); + +#endif
include/drm/drm_edid.h +2 -0
@@ -27,12 +27,14 @@#define EDID_LENGTH 128#define DDC_ADDR 0x50 +#define DDC_ADDR2 0x52/* E-DDC 1.2 - where DisplayID can hide */ #define CEA_EXT 0x02#define VTB_EXT 0x10#define DI_EXT 0x40#define LS_EXT 0x50#define MI_EXT 0x60 +#define DISPLAYID_EXT 0x70struct est_timings {u8 t1;
Signature · 6 lines
2.1.0 _______________________________________________ Intel-gfx mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Jani Nikula
maintainerRe: [PATCH 1/6] drm/displayid: add displayid defines and edid extension
Quoted 67 lines · Dave Airlie
From: Dave Airlie <[email protected]>
These are just taken from the DisplayID v1.3 spec, and the DDC spec.
Signed-off-by Dave Airlie <[email protected]>--- include/drm/drm_displayid.h | 76 +++++++++++++++++++++++++++++++++++++++++++++ include/drm/drm_edid.h | 2 ++ 2 files changed, 78 insertions(+) create mode 100644 include/drm/drm_displayid.hinclude/drm/drm_displayid.h new file +49
-0@@ -0,0 +1,76 @@ +/* +* Copyright © 2014 Red Hat Inc. +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR +* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +* OTHER DEALINGS IN THE SOFTWARE. +*/ +#ifndef DRM_DISPLAYID_H +#define DRM_DISPLAYID_H + +#define DATA_BLOCK_PRODUCT_ID 0x00 +#define DATA_BLOCK_DISPLAY_PARAMETERS 0x01 +#define DATA_BLOCK_COLOR_CHARACTERISTICS 0x02 +#define DATA_BLOCK_TYPE_1_DETAILED_TIMING 0x03 +#define DATA_BLOCK_TYPE_2_DETAILED_TIMING 0x04 +#define DATA_BLOCK_TYPE_3_SHORT_TIMING 0x05 +#define DATA_BLOCK_TYPE_4_DMT_TIMING 0x06 +#define DATA_BLOCK_VESA_TIMING 0x07 +#define DATA_BLOCK_CEA_TIMING 0x08 +#define DATA_BLOCK_VIDEO_TIMING_RANGE 0x09 +#define DATA_BLOCK_PRODUCT_SERIAL_NUMBER 0x0a +#define DATA_BLOCK_GP_ASCII_STRING 0x0b +#define DATA_BLOCK_DISPLAY_DEVICE_DATA 0x0c +#define DATA_BLOCK_INTERFACE_POWER_SEQUENCING 0x0d +#define DATA_BLOCK_TRANSFER_CHARACTERISTICS 0x0e +#define DATA_BLOCK_DISPLAY_INTERFACE 0x0f +#define DATA_BLOCK_STEREO_DISPLAY_INTERFACE 0x10 +#define DATA_BLOCK_TILED_DISPLAY 0x12 + +#define DATA_BLOCK_VENDOR_SPECIFIC 0x7f + +#define PRODUCT_TYPE_EXTENSION 0 +#define PRODUCT_TYPE_TEST 1 +#define PRODUCT_TYPE_PANEL 2 +#define PRODUCT_TYPE_MONITOR 3
include/drm/drm_displayid.h line 59
Quoted 10 lines
include/drm/drm_displayid.h new file +10
-0+#define PRODUCT_TYPE_TV 4 +#define PRODUCT_TYPE_REPEATER 5 +#define PRODUCT_TYPE_DIRECT_DRIVE 6 + +struct displayid_hdr { +u8 rev; +u8 bytes; +u8 prod_id; +u8 ext_count; +} __attribute__((packed));
__packed is preferred now I think.
BR,
Jani.
Quoted 43 lines
include/drm/drm_displayid.h new file +17
-0+ +struct displayid_block { +u8 tag; +u8 rev; +u8 num_bytes; +}; + +struct displayid_tiled_block { +struct displayid_block base; +u8 tile_cap; +u8 topo[3 ]; +u8 tile_size[4 ]; +u8 tile_pixel_bezel[5 ]; +u8 topology_id[8 ]; +} __attribute__((packed)); + +#endif include/drm/drm_edid.h +2
-0@@ -27,12 +27,14 @@#define EDID_LENGTH 128#define DDC_ADDR 0x50 +#define DDC_ADDR2 0x52/* E-DDC 1.2 - where DisplayID can hide */ #define CEA_EXT 0x02#define VTB_EXT 0x10#define DI_EXT 0x40#define LS_EXT 0x50#define MI_EXT 0x60 +#define DISPLAYID_EXT 0x70struct est_timings {u8 t1;Signature · 6 lines
2.1.0 _______________________________________________ Intel-gfx mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Signature · 5 lines
Jani Nikula, Intel Open Source Technology Center _______________________________________________ Intel-gfx mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Dave Airlie
maintainerPATCH 2/6 drm: add tile_group support.
In reply to Dave AirlieFrom: Dave Airlie <[email protected]>
A tile group is an identifier shared by a single monitor, DisplayID topology has 8 bytes we can use for this, just use those for now until something else comes up in the future. We assign these to an idr and use the idr to tell userspace what connectors are in the same tile group.
DisplayID v1.3 says the serial number must be unique for displays from the same manufacturer.
--- drivers/gpu/drm/drm_crtc.c | 61 ++++++++++++++++++++++++++++++++++++++++++++++ include/drm/drm_crtc.h | 16 ++++++++++++ 2 files changed, 77 insertions(+)
drivers/gpu/drm/drm_crtc.c +61 -0
@@ -5037,6 +5037,7 @@ void drm_mode_config_init(struct drm_device *dev)INIT_LIST_HEAD (&dev->mode_config.property_blob_list);INIT_LIST_HEAD (&dev->mode_config.plane_list);idr_init (&dev->mode_config.crtc_idr); +idr_init (&dev->mode_config.tile_idr);drm_modeset_lock_all (dev);drm_mode_create_standard_connector_properties (dev);
@@ -5146,3 +5147,63 @@ struct drm_property *drm_mode_create_rotation_property(struct drm_device *dev, supported_rotations); }EXPORT_SYMBOL (drm_mode_create_rotation_property); + +static void drm_tile_group_free (struct kref *kref) +{ + struct drm_tile_group *tg = container_of(kref, struct drm_tile_group, refcount); +struct drm_device *dev = tg->dev; +mutex_lock (&dev->mode_config.idr_mutex); +idr_remove (&dev->mode_config.tile_idr, tg->id); +mutex_lock (&dev->mode_config.idr_mutex); +kfree (tg); +} + +void drm_mode_put_tile_group (struct drm_device *dev, +struct drm_tile_group *tg) +{ +kref_put (&tg->refcount, drm_tile_group_free); +} + +struct drm_tile_group *drm_mode_get_tile_group (struct drm_device *dev, +char topology[8 ]) +{ +struct drm_tile_group *tg; +int id; +mutex_lock (&dev->mode_config.idr_mutex); +idr_for_each_entry (&dev->mode_config.tile_idr, tg, id) { +if (!memcmp (tg->group_data, topology,8 )) { +kref_get (&tg->refcount); +mutex_unlock (&dev->mode_config.idr_mutex); +return tg; + } + } +mutex_unlock (&dev->mode_config.idr_mutex); +return NULL ; +} + +struct drm_tile_group *drm_mode_create_tile_group (struct drm_device *dev, +char topology[8 ]) +{ +struct drm_tile_group *tg; +int ret; + + tg =kzalloc (sizeof (*tg),GFP_KERNEL ); +if (!tg) +return ERR_PTR (-ENOMEM ); + +kref_init (&tg->refcount); +memcpy (tg->group_data, topology,8 ); + tg->dev = dev; + +mutex_lock (&dev->mode_config.idr_mutex); + ret =idr_alloc (&dev->mode_config.tile_idr, tg,1 ,0 ,GFP_KERNEL ); +if (ret >=0 ) { + tg->id = ret; + }else { +kfree (tg); + tg =NULL ; + } + +mutex_unlock (&dev->mode_config.idr_mutex); +return tg; +}
include/drm/drm_crtc.h +16 -0
@@ -136,6 +136,14 @@ struct drm_display_info {u8 cea_rev; }; +/* data corresponds to displayid vend/prod/serial */ +struct drm_tile_group { +struct kref refcount; +struct drm_device *dev; +int id; +u8 group_data[8 ]; +}; +struct drm_framebuffer_funcs {/* note: use drm_framebuffer_remove() */ void (*destroy)(struct drm_framebuffer *framebuffer);
@@ -770,6 +778,7 @@ struct drm_mode_config {struct drm_modeset_acquire_ctx *acquire_ctx;/* for legacy _lock_all() / _unlock_all() */ struct mutex idr_mutex;/* for IDR management */ struct idr crtc_idr;/* use this idr for all IDs, fb, crtc, connector, modes - just makes life easier */ +struct idr tile_idr;/* use this idr for all IDs, fb, crtc, connector, modes - just makes life easier */ /* this is limited to one for now */
@@ -1106,6 +1115,13 @@ extern void drm_set_preferred_mode(struct drm_connector *connector,extern int drm_edid_header_is_valid (const u8 *raw_edid);extern bool drm_edid_block_valid (u8 *raw_edid,int block,bool print_bad_edid);extern bool drm_edid_is_valid (struct edid *edid); + +extern struct drm_tile_group *drm_mode_create_tile_group (struct drm_device *dev, +char topology[8 ]); +extern struct drm_tile_group *drm_mode_get_tile_group (struct drm_device *dev, +char topology[8 ]); +extern void drm_mode_put_tile_group (struct drm_device *dev, +struct drm_tile_group *tg);struct drm_display_mode *drm_mode_find_dmt (struct drm_device *dev,int hsize,int vsize,int fresh,bool rb);
Signature · 1 line
2.1.0
Re: [PATCH 2/6] drm: add tile_group support.
Hi
Quoted 22 lines · Dave Airlie
From: Dave Airlie <[email protected]>
A tile group is an identifier shared by a single monitor, DisplayID topology has 8 bytes we can use for this, just use those for now until something else comes up in the future. We assign these to an idr and use the idr to tell userspace what connectors are in the same tile group.
DisplayID v1.3 says the serial number must be unique for displays from the same manufacturer.
Signed-off-by Dave Airlie <[email protected]>--- drivers/gpu/drm/drm_crtc.c | 61 ++++++++++++++++++++++++++++++++++++++++++++++ include/drm/drm_crtc.h | 16 ++++++++++++ 2 files changed, 77 insertions(+)drivers/gpu/drm/drm_crtc.c +0
-0
drivers/gpu/drm/drm_crtc.c void drm_mode_config_init(struct drm_device *dev) · line 5040
Quoted 4 lines
drivers/gpu/drm/drm_crtc.c +1
-0@@ -5037,6 +5037,7 @@ void drm_mode_config_init(struct drm_device *dev)INIT_LIST_HEAD (&dev->mode_config.property_blob_list);INIT_LIST_HEAD (&dev->mode_config.plane_list);idr_init (&dev->mode_config.crtc_idr); +idr_init (&dev->mode_config.tile_idr);
You are missing a call to idr_destroy() in drm_mode_config_cleanup(). The IDR caches are not cleaned up automatically when it drops to size 0...
Thanks
David
Quoted 115 lines
drivers/gpu/drm/drm_crtc.c +60
-0drm_modeset_lock_all (dev);drm_mode_create_standard_connector_properties (dev);@@ -5146,3 +5147,63 @@ struct drm_property *drm_mode_create_rotation_property(struct drm_device *dev, supported_rotations); }EXPORT_SYMBOL (drm_mode_create_rotation_property); + +static void drm_tile_group_free (struct kref *kref) +{ + struct drm_tile_group *tg = container_of(kref, struct drm_tile_group, refcount); +struct drm_device *dev = tg->dev; +mutex_lock (&dev->mode_config.idr_mutex); +idr_remove (&dev->mode_config.tile_idr, tg->id); +mutex_lock (&dev->mode_config.idr_mutex); +kfree (tg); +} + +void drm_mode_put_tile_group (struct drm_device *dev, +struct drm_tile_group *tg) +{ +kref_put (&tg->refcount, drm_tile_group_free); +} + +struct drm_tile_group *drm_mode_get_tile_group (struct drm_device *dev, +char topology[8 ]) +{ +struct drm_tile_group *tg; +int id; +mutex_lock (&dev->mode_config.idr_mutex); +idr_for_each_entry (&dev->mode_config.tile_idr, tg, id) { +if (!memcmp (tg->group_data, topology,8 )) { +kref_get (&tg->refcount); +mutex_unlock (&dev->mode_config.idr_mutex); +return tg; + } + } +mutex_unlock (&dev->mode_config.idr_mutex); +return NULL ; +} + +struct drm_tile_group *drm_mode_create_tile_group (struct drm_device *dev, +char topology[8 ]) +{ +struct drm_tile_group *tg; +int ret; + + tg =kzalloc (sizeof (*tg),GFP_KERNEL ); +if (!tg) +return ERR_PTR (-ENOMEM ); + +kref_init (&tg->refcount); +memcpy (tg->group_data, topology,8 ); + tg->dev = dev; + +mutex_lock (&dev->mode_config.idr_mutex); + ret =idr_alloc (&dev->mode_config.tile_idr, tg,1 ,0 ,GFP_KERNEL ); +if (ret >=0 ) { + tg->id = ret; + }else { +kfree (tg); + tg =NULL ; + } + +mutex_unlock (&dev->mode_config.idr_mutex); +return tg; +}include/drm/drm_crtc.h +16
-1@@ -136,6 +136,14 @@ struct drm_display_info {u8 cea_rev; }; +/* data corresponds to displayid vend/prod/serial */ +struct drm_tile_group { +struct kref refcount; +struct drm_device *dev; +int id; +u8 group_data[8 ]; +}; +struct drm_framebuffer_funcs {/* note: use drm_framebuffer_remove() */ void (*destroy)(struct drm_framebuffer *framebuffer);@@ -770,6 +778,7 @@ struct drm_mode_config {struct drm_modeset_acquire_ctx *acquire_ctx;/* for legacy _lock_all() / _unlock_all() */ struct mutex idr_mutex;/* for IDR management */ struct idr crtc_idr;/* use this idr for all IDs, fb, crtc, connector, modes - just makes life easier */ +struct idr tile_idr;/* use this idr for all IDs, fb, crtc, connector, modes - just makes life easier */ /* this is limited to one for now */ @@ -1106,6 +1115,13 @@ extern void drm_set_preferred_mode(struct drm_connector *connector,extern int drm_edid_header_is_valid (const u8 *raw_edid);extern bool drm_edid_block_valid (u8 *raw_edid,int block,bool print_bad_edid);extern bool drm_edid_is_valid (struct edid *edid); + +extern struct drm_tile_group *drm_mode_create_tile_group (struct drm_device *dev, +char topology[8 ]); +extern struct drm_tile_group *drm_mode_get_tile_group (struct drm_device *dev, +char topology[8 ]); +extern void drm_mode_put_tile_group (struct drm_device *dev, +struct drm_tile_group *tg);struct drm_display_mode *drm_mode_find_dmt (struct drm_device *dev,int hsize,int vsize,int fresh,bool rb); --2.1.0
_______________________________________________
dri-devel mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH 2/6] drm: add tile_group support.
In reply to Dave AirlieQuoted 49 lines · Dave Airlie
From: Dave Airlie <[email protected]>
A tile group is an identifier shared by a single monitor, DisplayID topology has 8 bytes we can use for this, just use those for now until something else comes up in the future. We assign these to an idr and use the idr to tell userspace what connectors are in the same tile group.
DisplayID v1.3 says the serial number must be unique for displays from the same manufacturer.
Signed-off-by Dave Airlie <[email protected]>--- drivers/gpu/drm/drm_crtc.c | 61 ++++++++++++++++++++++++++++++++++++++++++++++ include/drm/drm_crtc.h | 16 ++++++++++++ 2 files changed, 77 insertions(+)drivers/gpu/drm/drm_crtc.c +17
-0@@ -5037,6 +5037,7 @@ void drm_mode_config_init(struct drm_device *dev)INIT_LIST_HEAD (&dev->mode_config.property_blob_list);INIT_LIST_HEAD (&dev->mode_config.plane_list);idr_init (&dev->mode_config.crtc_idr); +idr_init (&dev->mode_config.tile_idr);drm_modeset_lock_all (dev);drm_mode_create_standard_connector_properties (dev);@@ -5146,3 +5147,63 @@ struct drm_property *drm_mode_create_rotation_property(struct drm_device *dev, supported_rotations); }EXPORT_SYMBOL (drm_mode_create_rotation_property); + +static void drm_tile_group_free (struct kref *kref) +{ + struct drm_tile_group *tg = container_of(kref, struct drm_tile_group, refcount); +struct drm_device *dev = tg->dev; +mutex_lock (&dev->mode_config.idr_mutex); +idr_remove (&dev->mode_config.tile_idr, tg->id); +mutex_lock (&dev->mode_config.idr_mutex); +kfree (tg); +} + +void drm_mode_put_tile_group (struct drm_device *dev, +struct drm_tile_group *tg) +{ +kref_put (&tg->refcount, drm_tile_group_free); +}
drivers/gpu/drm/drm_crtc.c struct drm_property *drm_mode_create_rotation_property(struct drm_device *dev, · line 5175
Quoted 10 lines
drivers/gpu/drm/drm_crtc.c +10
-0+ +struct drm_tile_group *drm_mode_get_tile_group (struct drm_device *dev, +char topology[8 ]) +{ +struct drm_tile_group *tg; +int id; +mutex_lock (&dev->mode_config.idr_mutex); +idr_for_each_entry (&dev->mode_config.tile_idr, tg, id) { +if (!memcmp (tg->group_data, topology,8 )) { +kref_get (&tg->refcount);
Don't you need a kref_get_unless_zero here since we only destroy the idr entry after the refcount dropped to zero? Or is there some magic thing that prevents this like another mutex (in which case some mutex assert in get/put would be good)?
And kerneldoc for the non-exported functions please, preferrably with some overview DOC: section to pull it all together.
-Daniel
Quoted 82 lines
drivers/gpu/drm/drm_crtc.c +34
-0+mutex_unlock (&dev->mode_config.idr_mutex); +return tg; + } + } +mutex_unlock (&dev->mode_config.idr_mutex); +return NULL ; +} + +struct drm_tile_group *drm_mode_create_tile_group (struct drm_device *dev, +char topology[8 ]) +{ +struct drm_tile_group *tg; +int ret; + + tg =kzalloc (sizeof (*tg),GFP_KERNEL ); +if (!tg) +return ERR_PTR (-ENOMEM ); + +kref_init (&tg->refcount); +memcpy (tg->group_data, topology,8 ); + tg->dev = dev; + +mutex_lock (&dev->mode_config.idr_mutex); + ret =idr_alloc (&dev->mode_config.tile_idr, tg,1 ,0 ,GFP_KERNEL ); +if (ret >=0 ) { + tg->id = ret; + }else { +kfree (tg); + tg =NULL ; + } + +mutex_unlock (&dev->mode_config.idr_mutex); +return tg; +}include/drm/drm_crtc.h +16
-0@@ -136,6 +136,14 @@ struct drm_display_info {u8 cea_rev; }; +/* data corresponds to displayid vend/prod/serial */ +struct drm_tile_group { +struct kref refcount; +struct drm_device *dev; +int id; +u8 group_data[8 ]; +}; +struct drm_framebuffer_funcs {/* note: use drm_framebuffer_remove() */ void (*destroy)(struct drm_framebuffer *framebuffer);@@ -770,6 +778,7 @@ struct drm_mode_config {struct drm_modeset_acquire_ctx *acquire_ctx;/* for legacy _lock_all() / _unlock_all() */ struct mutex idr_mutex;/* for IDR management */ struct idr crtc_idr;/* use this idr for all IDs, fb, crtc, connector, modes - just makes life easier */ +struct idr tile_idr;/* use this idr for all IDs, fb, crtc, connector, modes - just makes life easier */ /* this is limited to one for now */ @@ -1106,6 +1115,13 @@ extern void drm_set_preferred_mode(struct drm_connector *connector,extern int drm_edid_header_is_valid (const u8 *raw_edid);extern bool drm_edid_block_valid (u8 *raw_edid,int block,bool print_bad_edid);extern bool drm_edid_is_valid (struct edid *edid); + +extern struct drm_tile_group *drm_mode_create_tile_group (struct drm_device *dev, +char topology[8 ]); +extern struct drm_tile_group *drm_mode_get_tile_group (struct drm_device *dev, +char topology[8 ]); +extern void drm_mode_put_tile_group (struct drm_device *dev, +struct drm_tile_group *tg);struct drm_display_mode *drm_mode_find_dmt (struct drm_device *dev,int hsize,int vsize,int fresh,bool rb);Signature · 6 lines
2.1.0 _______________________________________________ dri-devel mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/dri-devel
Signature · 3 lines
Daniel Vetter Software Engineer, Intel Corporation +41 (0) 79 365 57 48 - http://blog.ffwll.ch
Dave Airlie
maintainerRe: [PATCH 2/6] drm: add tile_group support.
Quoted 4 lines
Don't you need a
kref_get_unless_zerohere since we only destroy the idr entry after the refcount dropped to zero? Or is there some magic thing that prevents this like another mutex (in which case some mutex assert in get/put would be good)?
This does all happen under mode_config.mutex but I think I'd rather use get_unless_zero.
Quoted 3 lines
And kerneldoc for the non-exported functions please, preferrably with some overview DOC: section to pull it all together.
I'm posting v2, advice on kerneldoc required, so the functions end up in the right place, I don't really wnat to add a new C file for this.
Dave.
Re: [PATCH 2/6] drm: add tile_group support.
Quoted 5 lines · Dave Airlie
Quoted 2 lines
And kerneldoc for the non-exported functions please, preferrably with some overview DOC: section to pull it all together.
I'm posting v2, advice on kerneldoc required, so the functions end up in the right place, I don't really wnat to add a new C file for this.
Argh sorry that was a boilerplate reply that escated ;-) I've sent the same one to pretty much all the recent i915 patch series where this is the new rule. I don't think drm internal docs make a lot of sense as long as all the driver stuff is nicely documented. Some barrier to entry for core drm might actually be useful ...
Cheers, Daniel
Signature · 3 lines
Daniel Vetter Software Engineer, Intel Corporation +41 (0) 79 365 57 48 - http://blog.ffwll.ch
Dave Airlie
maintainerPATCH 3/6 drm/mst: cached EDID for logical ports
In reply to Dave AirlieFrom: Dave Airlie <[email protected]>
Logical ports are never going to have EDID changes, they are used for the internal ports on MST monitors.
We cache the EDIDs from these to save time at MST probe.
--- drivers/gpu/drm/drm_dp_mst_topology.c | 20 ++++++++++++++++++-- drivers/gpu/drm/i915/intel_dp_mst.c | 2 +- include/drm/drm_dp_mst_helper.h | 4 +++- 3 files changed, 22 insertions(+), 4 deletions(-)
drivers/gpu/drm/drm_dp_mst_topology.c +18 -2
@@ -858,6 +858,8 @@ static void drm_dp_destroy_port(struct kref *kref)struct drm_dp_mst_topology_mgr *mgr = port->mgr;if (!port->input) { port->vcpi.num_slots =0 ; + +kfree (port->cached_edid);if (port->connector) (*port->mgr->cbs->destroy_connector)(mgr, port->connector);drm_dp_port_teardown_pdt (port, port->pdt);
@@ -1096,6 +1098,10 @@ static void drm_dp_add_port(struct drm_dp_mst_branch *mstb,char proppath[255 ];build_mst_prop_path (port, mstb, proppath); port->connector = (*mstb->mgr->cbs->add_connector)(mstb->mgr, port, proppath); + +if (port->port_num >=8 ) { + port->cached_edid =drm_get_edid (port->connector, &port->aux.ddc); + } }/* put reference to this port */
@@ -2149,7 +2155,8 @@ EXPORT_SYMBOL(drm_dp_mst_hpd_irq);* This returns the current connection state for a port. It validates the * port pointer still exists so the caller doesn't require a reference */ -enum drm_connector_status drm_dp_mst_detect_port (struct drm_dp_mst_topology_mgr *mgr,struct drm_dp_mst_port *port) +enum drm_connector_status drm_dp_mst_detect_port (struct drm_connector *connector, +struct drm_dp_mst_topology_mgr *mgr,struct drm_dp_mst_port *port) {enum drm_connector_status status = connector_status_disconnected;
@@ -2168,6 +2175,10 @@ enum drm_connector_status drm_dp_mst_detect_port(struct drm_dp_mst_topology_mgrcase DP_PEER_DEVICE_SST_SINK : status = connector_status_connected; +/* for logical ports - cache the EDID */ +if (port->port_num >=8 && !port->cached_edid) { + port->cached_edid =drm_get_edid (connector, &port->aux.ddc); + }break ;case DP_PEER_DEVICE_DP_LEGACY_CONV :if (port->ldps)
@@ -2199,7 +2210,12 @@ struct edid *drm_dp_mst_get_edid(struct drm_connector *connector, struct drm_dp_if (!port)return NULL ; - edid =drm_get_edid (connector, &port->aux.ddc); +if (port->cached_edid) + edid =drm_edid_duplicate (port->cached_edid); +else + edid =drm_get_edid (connector, &port->aux.ddc); + +drm_mode_connector_set_tile_property (connector);drm_dp_put_port (port);return edid; }
drivers/gpu/drm/i915/intel_dp_mst.c +1 -1
@@ -283,7 +283,7 @@ intel_mst_port_dp_detect(struct drm_connector *connector)struct intel_connector *intel_connector =to_intel_connector (connector);struct intel_dp *intel_dp = intel_connector->mst_port; -return drm_dp_mst_detect_port (&intel_dp->mst_mgr, intel_connector->port); +return drm_dp_mst_detect_port (connector, &intel_dp->mst_mgr, intel_connector->port); } static enum drm_connector_status
include/drm/drm_dp_mst_helper.h +3 -1
@@ -92,6 +92,8 @@ struct drm_dp_mst_port {struct drm_dp_vcpi vcpi;struct drm_connector *connector;struct drm_dp_mst_topology_mgr *mgr; + +struct edid *cached_edid;/* for DP logical ports - make tiling work */ };/**
@@ -474,7 +476,7 @@ int drm_dp_mst_topology_mgr_set_mst(struct drm_dp_mst_topology_mgr *mgr, bool msint drm_dp_mst_hpd_irq (struct drm_dp_mst_topology_mgr *mgr,u8 *esi,bool *handled); -enum drm_connector_status drm_dp_mst_detect_port (struct drm_dp_mst_topology_mgr *mgr,struct drm_dp_mst_port *port); +enum drm_connector_status drm_dp_mst_detect_port (struct drm_connector *connector,struct drm_dp_mst_topology_mgr *mgr,struct drm_dp_mst_port *port);struct edid *drm_dp_mst_get_edid (struct drm_connector *connector,struct drm_dp_mst_topology_mgr *mgr,struct drm_dp_mst_port *port);
Signature · 1 line
2.1.0
Dave Airlie
maintainerPATCH 4/6 drm/connector: store tile information from displayid
In reply to Dave AirlieFrom: Dave Airlie <[email protected]>
This creates a tile group from DisplayID block, and stores the pieces of parsed info from the DisplayID block into the connector.
--- drivers/gpu/drm/drm_crtc.c | 5 ++ drivers/gpu/drm/drm_edid.c | 139 ++++++++++++++++++++++++++++++++++++++++++++- include/drm/drm_crtc.h | 9 +++ 3 files changed, 151 insertions(+), 2 deletions(-)
drivers/gpu/drm/drm_crtc.c +5 -0
@@ -939,6 +939,11 @@ void drm_connector_cleanup(struct drm_connector *connector)struct drm_device *dev = connector->dev;struct drm_display_mode *mode, *t; +if (connector->tile_group) { +drm_mode_put_tile_group (dev, connector->tile_group); + connector->tile_group =NULL ; + } +list_for_each_entry_safe (mode, t, &connector->probed_modes, head)drm_mode_remove (connector, mode);
drivers/gpu/drm/drm_edid.c +137 -2
178 lines not on this page · raw message
include/drm/drm_crtc.h +9 -0
@@ -572,6 +572,15 @@ struct drm_connector {unsigned bad_edid_counter;struct dentry *debugfs_entry; + +/* DisplayID bits */ +bool has_tile; +struct drm_tile_group *tile_group; +bool tile_is_single_monitor; + +uint8_t num_h_tile, num_v_tile; +uint8_t tile_h_loc, tile_v_loc; +uint16_t tile_h_size, tile_v_size; };/**
Signature · 1 line
2.1.0
Dave Airlie
maintainerPATCH 5/6 drm/tile: expose the tile property to userspace
In reply to Dave AirlieFrom: Dave Airlie <[email protected]>
This takes the tiling info from the connector and
exposes it to userspace, as a blob object in a
connector property.
The contents of the blob is ABI.
--- drivers/gpu/drm/drm_crtc.c | 36 ++++++++++++++++++++++++++++++++++++ drivers/gpu/drm/i915/intel_dp_mst.c | 2 ++ include/drm/drm_crtc.h | 4 ++++ 3 files changed, 42 insertions(+)
drivers/gpu/drm/drm_crtc.c +36 -0
@@ -1319,6 +1319,11 @@ static int drm_mode_create_standard_connector_properties(struct drm_device *dev) "PATH", 0); dev->mode_config.path_property = dev_path; + dev->mode_config.tile_property =drm_property_create (dev, +DRM_MODE_PROP_BLOB | +DRM_MODE_PROP_IMMUTABLE , +"TILE" ,0 ); +return 0 ; }
@@ -4004,6 +4009,37 @@ int drm_mode_connector_set_path_property(struct drm_connector *connector, }EXPORT_SYMBOL (drm_mode_connector_set_path_property); +int drm_mode_connector_set_tile_property (struct drm_connector *connector) +{ +struct drm_device *dev = connector->dev; +int ret, size; +char tile[256 ]; + +if (connector->tile_blob_ptr) +drm_property_destroy_blob (dev, connector->tile_blob_ptr); + +if (!connector->has_tile) { + connector->tile_blob_ptr =NULL ; + ret =drm_object_property_set_value (&connector->base, + dev->mode_config.tile_property,0 ); +return ret; + } + +snprintf (tile,256 ,"%d:%d:%d:%d:%d:%d:%d:%d" , connector->tile_group->id, connector->tile_is_single_monitor, connector->num_h_tile, connector->num_v_tile, connector->tile_h_loc, connector->tile_v_loc, connector->tile_h_size, connector->tile_v_size); + size =strlen (tile) +1 ; + + connector->tile_blob_ptr =drm_property_create_blob (connector->dev, + size, tile); +if (!connector->tile_blob_ptr) +return -EINVAL ; + + ret =drm_object_property_set_value (&connector->base, + dev->mode_config.tile_property, + connector->tile_blob_ptr->base.id); +return ret; +} +EXPORT_SYMBOL (drm_mode_connector_set_tile_property); +/** * drm_mode_connector_update_edid_property - update the edid property of a connector * @connector: drm connector
drivers/gpu/drm/i915/intel_dp_mst.c +2 -0
@@ -422,6 +422,8 @@ static struct drm_connector *intel_dp_add_mst_connector(struct drm_dp_mst_topolointel_dp_add_properties (intel_dp, connector);drm_object_attach_property (&connector->base, dev->mode_config.path_property,0 ); +drm_object_attach_property (&connector->base, dev->mode_config.tile_property,0 ); +drm_mode_connector_set_path_property (connector, pathprop);drm_reinit_primary_mode_group (dev);mutex_lock (&dev->mode_config.mutex);
include/drm/drm_crtc.h +4 -0
@@ -548,6 +548,8 @@ struct drm_connector {struct drm_property_blob *path_blob_ptr; +struct drm_property_blob *tile_blob_ptr; +uint8_t polled;/* DRM_CONNECTOR_POLL_* */ /* requested DPMS state */
@@ -838,6 +840,7 @@ struct drm_mode_config {struct drm_property *edid_property;struct drm_property *dpms_property;struct drm_property *path_property; +struct drm_property *tile_property;struct drm_property *plane_type_property;/* DVI-I properties */
@@ -990,6 +993,7 @@ extern void drm_mode_config_cleanup(struct drm_device *dev);extern int drm_mode_connector_set_path_property (struct drm_connector *connector,char *path); +int drm_mode_connector_set_tile_property (struct drm_connector *connector);extern int drm_mode_connector_update_edid_property (struct drm_connector *connector,struct edid *edid);
Signature · 1 line
2.1.0
Re: [PATCH 5/6] drm/tile: expose the tile property to userspace
Hi
Quoted 52 lines · Dave Airlie
From: Dave Airlie <[email protected]>
This takes the tiling info from the connector and
exposes it to userspace, as a blob object in a
connector property.The contents of the blob is ABI.
Signed-off-by Dave Airlie <[email protected]>--- drivers/gpu/drm/drm_crtc.c | 36 ++++++++++++++++++++++++++++++++++++ drivers/gpu/drm/i915/intel_dp_mst.c | 2 ++ include/drm/drm_crtc.h | 4 ++++ 3 files changed, 42 insertions(+)drivers/gpu/drm/drm_crtc.c +22
-0@@ -1319,6 +1319,11 @@ static int drm_mode_create_standard_connector_properties(struct drm_device *dev) "PATH", 0); dev->mode_config.path_property = dev_path; + dev->mode_config.tile_property =drm_property_create (dev, +DRM_MODE_PROP_BLOB | +DRM_MODE_PROP_IMMUTABLE , +"TILE" ,0 ); +return 0 ; }@@ -4004,6 +4009,37 @@ int drm_mode_connector_set_path_property(struct drm_connector *connector, }EXPORT_SYMBOL (drm_mode_connector_set_path_property); +int drm_mode_connector_set_tile_property (struct drm_connector *connector) +{ +struct drm_device *dev = connector->dev; +int ret, size; +char tile[256 ]; + +if (connector->tile_blob_ptr) +drm_property_destroy_blob (dev, connector->tile_blob_ptr); + +if (!connector->has_tile) { + connector->tile_blob_ptr =NULL ; + ret =drm_object_property_set_value (&connector->base, + dev->mode_config.tile_property,0 ); +return ret; + } + +snprintf (tile,256 ,"%d:%d:%d:%d:%d:%d:%d:%d" , connector->tile_group->id, connector->tile_is_single_monitor, connector->num_h_tile, connector->num_v_tile, connector->tile_h_loc, connector->tile_v_loc, connector->tile_h_size, connector->tile_v_size);
drivers/gpu/drm/drm_crtc.c int drm_mode_connector_set_path_property(struct drm_connector *connector, · line 4038
Quoted 10 lines
drivers/gpu/drm/drm_crtc.c +10
-0+ size =strlen (tile) +1 ; + + connector->tile_blob_ptr =drm_property_create_blob (connector->dev, + size, tile); +if (!connector->tile_blob_ptr) +return -EINVAL ; + + ret =drm_object_property_set_value (&connector->base, + dev->mode_config.tile_property, + connector->tile_blob_ptr->base.id);
I recently looked at property hotplugging and I think it needs the same fix you pushed for connectors (drm_mode_object_get_reg() and friends). I wanted to look at the same thing for brightness properties, but didn't have time for that so far.
The race is mostly theoretical, but I think we should still try to fix it.
Thanks
David
Quoted 56 lines
drivers/gpu/drm/drm_crtc.c +4
-0+return ret; +} +EXPORT_SYMBOL (drm_mode_connector_set_tile_property); +/** * drm_mode_connector_update_edid_property - update the edid property of a connector * @connector: drm connector drivers/gpu/drm/i915/intel_dp_mst.c +2
-0@@ -422,6 +422,8 @@ static struct drm_connector *intel_dp_add_mst_connector(struct drm_dp_mst_topolointel_dp_add_properties (intel_dp, connector);drm_object_attach_property (&connector->base, dev->mode_config.path_property,0 ); +drm_object_attach_property (&connector->base, dev->mode_config.tile_property,0 ); +drm_mode_connector_set_path_property (connector, pathprop);drm_reinit_primary_mode_group (dev);mutex_lock (&dev->mode_config.mutex);include/drm/drm_crtc.h +4
-1@@ -548,6 +548,8 @@ struct drm_connector {struct drm_property_blob *path_blob_ptr; +struct drm_property_blob *tile_blob_ptr; +uint8_t polled;/* DRM_CONNECTOR_POLL_* */ /* requested DPMS state */ @@ -838,6 +840,7 @@ struct drm_mode_config {struct drm_property *edid_property;struct drm_property *dpms_property;struct drm_property *path_property; +struct drm_property *tile_property;struct drm_property *plane_type_property;/* DVI-I properties */ @@ -990,6 +993,7 @@ extern void drm_mode_config_cleanup(struct drm_device *dev);extern int drm_mode_connector_set_path_property (struct drm_connector *connector,char *path); +int drm_mode_connector_set_tile_property (struct drm_connector *connector);extern int drm_mode_connector_update_edid_property (struct drm_connector *connector,struct edid *edid); --2.1.0
_______________________________________________
dri-devel mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH 5/6] drm/tile: expose the tile property to userspace
In reply to Dave AirlieQuoted 32 lines · Dave Airlie
From: Dave Airlie <[email protected]>
This takes the tiling info from the connector and
exposes it to userspace, as a blob object in a
connector property.The contents of the blob is ABI.
Signed-off-by Dave Airlie <[email protected]>--- drivers/gpu/drm/drm_crtc.c | 36 ++++++++++++++++++++++++++++++++++++ drivers/gpu/drm/i915/intel_dp_mst.c | 2 ++ include/drm/drm_crtc.h | 4 ++++ 3 files changed, 42 insertions(+)drivers/gpu/drm/drm_crtc.c +5
-0@@ -1319,6 +1319,11 @@ static int drm_mode_create_standard_connector_properties(struct drm_device *dev) "PATH", 0); dev->mode_config.path_property = dev_path; + dev->mode_config.tile_property =drm_property_create (dev, +DRM_MODE_PROP_BLOB | +DRM_MODE_PROP_IMMUTABLE , +"TILE" ,0 ); +return 0 ; }
drivers/gpu/drm/drm_crtc.c int drm_mode_connector_set_path_property(struct drm_connector *connector, · line 4012
Quoted 4 lines
drivers/gpu/drm/drm_crtc.c +1
-0@@ -4004,6 +4009,37 @@ int drm_mode_connector_set_path_property(struct drm_connector *connector, }EXPORT_SYMBOL (drm_mode_connector_set_path_property); +int drm_mode_connector_set_tile_property (struct drm_connector *connector)
Same again, please add some kerneldoc for this function here. -Daniel
Quoted 82 lines
drivers/gpu/drm/drm_crtc.c +30
-0+{ +struct drm_device *dev = connector->dev; +int ret, size; +char tile[256 ]; + +if (connector->tile_blob_ptr) +drm_property_destroy_blob (dev, connector->tile_blob_ptr); + +if (!connector->has_tile) { + connector->tile_blob_ptr =NULL ; + ret =drm_object_property_set_value (&connector->base, + dev->mode_config.tile_property,0 ); +return ret; + } + +snprintf (tile,256 ,"%d:%d:%d:%d:%d:%d:%d:%d" , connector->tile_group->id, connector->tile_is_single_monitor, connector->num_h_tile, connector->num_v_tile, connector->tile_h_loc, connector->tile_v_loc, connector->tile_h_size, connector->tile_v_size); + size =strlen (tile) +1 ; + + connector->tile_blob_ptr =drm_property_create_blob (connector->dev, + size, tile); +if (!connector->tile_blob_ptr) +return -EINVAL ; + + ret =drm_object_property_set_value (&connector->base, + dev->mode_config.tile_property, + connector->tile_blob_ptr->base.id); +return ret; +} +EXPORT_SYMBOL (drm_mode_connector_set_tile_property); +/** * drm_mode_connector_update_edid_property - update the edid property of a connector * @connector: drm connector drivers/gpu/drm/i915/intel_dp_mst.c +2
-0@@ -422,6 +422,8 @@ static struct drm_connector *intel_dp_add_mst_connector(struct drm_dp_mst_topolointel_dp_add_properties (intel_dp, connector);drm_object_attach_property (&connector->base, dev->mode_config.path_property,0 ); +drm_object_attach_property (&connector->base, dev->mode_config.tile_property,0 ); +drm_mode_connector_set_path_property (connector, pathprop);drm_reinit_primary_mode_group (dev);mutex_lock (&dev->mode_config.mutex);include/drm/drm_crtc.h +4
-0@@ -548,6 +548,8 @@ struct drm_connector {struct drm_property_blob *path_blob_ptr; +struct drm_property_blob *tile_blob_ptr; +uint8_t polled;/* DRM_CONNECTOR_POLL_* */ /* requested DPMS state */ @@ -838,6 +840,7 @@ struct drm_mode_config {struct drm_property *edid_property;struct drm_property *dpms_property;struct drm_property *path_property; +struct drm_property *tile_property;struct drm_property *plane_type_property;/* DVI-I properties */ @@ -990,6 +993,7 @@ extern void drm_mode_config_cleanup(struct drm_device *dev);extern int drm_mode_connector_set_path_property (struct drm_connector *connector,char *path); +int drm_mode_connector_set_tile_property (struct drm_connector *connector);extern int drm_mode_connector_update_edid_property (struct drm_connector *connector,struct edid *edid);Signature · 6 lines
2.1.0 _______________________________________________ Intel-gfx mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Signature · 3 lines
Daniel Vetter Software Engineer, Intel Corporation +41 (0) 79 365 57 48 - http://blog.ffwll.ch
Re: [Intel-gfx] [PATCH 5/6] drm/tile: expose the tile property to userspace
Quoted 32 lines · Daniel Vetter
Quoted 31 lines · Dave Airlie
From: Dave Airlie <[email protected]>
This takes the tiling info from the connector and
exposes it to userspace, as a blob object in a
connector property.The contents of the blob is ABI.
Signed-off-by Dave Airlie <[email protected]>--- drivers/gpu/drm/drm_crtc.c | 36 ++++++++++++++++++++++++++++++++++++ drivers/gpu/drm/i915/intel_dp_mst.c | 2 ++ include/drm/drm_crtc.h | 4 ++++ 3 files changed, 42 insertions(+)drivers/gpu/drm/drm_crtc.c +5
-0@@ -1319,6 +1319,11 @@ static int drm_mode_create_standard_connector_properties(struct drm_device *dev) "PATH", 0); dev->mode_config.path_property = dev_path; + dev->mode_config.tile_property =drm_property_create (dev, +DRM_MODE_PROP_BLOB | +DRM_MODE_PROP_IMMUTABLE , +"TILE" ,0 ); +return 0 ; }
Quoted 7 lines
drivers/gpu/drm/drm_crtc.c int drm_mode_connector_set_path_property(struct drm_connector *connector, · line 4012
Quoted 5 lines
drivers/gpu/drm/drm_crtc.c +1
-0@@ -4004,6 +4009,37 @@ int drm_mode_connector_set_path_property(struct drm_connector *connector, }EXPORT_SYMBOL (drm_mode_connector_set_path_property); +int drm_mode_connector_set_tile_property (struct drm_connector *connector)Same again, please add some kerneldoc for this function here.
While at it, please also add the missing kerneldoc for the functions you've already added for dp mst support.
Thanks, Daniel
Signature · 3 lines
Daniel Vetter Software Engineer, Intel Corporation +41 (0) 79 365 57 48 - http://blog.ffwll.ch
Re: [PATCH 5/6] drm/tile: expose the tile property to userspace
Quoted 37 lines · Daniel Vetter
Quoted 36 lines · Daniel Vetter
Quoted 35 lines · Dave Airlie
From: Dave Airlie <[email protected]>
This takes the tiling info from the connector and
exposes it to userspace, as a blob object in a
connector property.The contents of the blob is ABI.
Signed-off-by Dave Airlie <[email protected]>--- drivers/gpu/drm/drm_crtc.c | 36 ++++++++++++++++++++++++++++++++++++ drivers/gpu/drm/i915/intel_dp_mst.c | 2 ++ include/drm/drm_crtc.h | 4 ++++ 3 files changed, 42 insertions(+)drivers/gpu/drm/drm_crtc.c +5
-0@@ -1319,6 +1319,11 @@ static int drm_mode_create_standard_connector_properties(struct drm_device *dev) "PATH", 0); dev->mode_config.path_property = dev_path; + dev->mode_config.tile_property =drm_property_create (dev, +DRM_MODE_PROP_BLOB | +DRM_MODE_PROP_IMMUTABLE , +"TILE" ,0 ); +return 0 ; }@@ -4004,6 +4009,37 @@ int drm_mode_connector_set_path_property(struct drm_connector *connector, }EXPORT_SYMBOL (drm_mode_connector_set_path_property);
Quoted 6 lines
Quoted 3 lines
drivers/gpu/drm/drm_crtc.c int drm_mode_connector_set_path_property(struct drm_connector *connector, · line 4012
Quoted 1 line
drivers/gpu/drm/drm_crtc.c +1
-0+int drm_mode_connector_set_tile_property (struct drm_connector *connector)Same again, please add some kerneldoc for this function here.
While at it, please also add the missing kerneldoc for the functions you've already added for dp mst support.
And the docbook xml table with all the properties we have should also be updated for both of them.
-Daniel
Signature · 3 lines
Daniel Vetter Software Engineer, Intel Corporation +41 (0) 79 365 57 48 - http://blog.ffwll.ch
Dave Airlie
maintainerPATCH 6/6 drm/fb: add support for tiled monitor configurations.
In reply to Dave AirlieFrom: Dave Airlie <[email protected]>
This adds fbdev/con support for tiled monitors, so that we only set a mode on the correct half of the monitor, or span the two halves if needed.
--- drivers/gpu/drm/drm_fb_helper.c | 122 +++++++++++++++++++++++++++++++------ drivers/gpu/drm/i915/intel_fbdev.c | 25 +++++++- include/drm/drm_fb_helper.h | 6 ++ 3 files changed, 130 insertions(+), 23 deletions(-)
drivers/gpu/drm/drm_fb_helper.c +102 -20
@@ -1042,19 +1042,21 @@ static int drm_fb_helper_single_fb_probe(struct drm_fb_helper *fb_helper, crtc_count =0 ;for (i =0 ; i < fb_helper->crtc_count; i++) {struct drm_display_mode *desired_mode; +int x, y; desired_mode = fb_helper->crtc_info[i].desired_mode; - + x = fb_helper->crtc_info[i].x; + y = fb_helper->crtc_info[i].y;if (desired_mode) {if (gamma_size ==0 ) gamma_size = fb_helper->crtc_info[i].mode_set.crtc->gamma_size; -if (desired_mode->hdisplay < sizes.fb_width) - sizes.fb_width = desired_mode->hdisplay; -if (desired_mode->vdisplay < sizes.fb_height) - sizes.fb_height = desired_mode->vdisplay; -if (desired_mode->hdisplay > sizes.surface_width) - sizes.surface_width = desired_mode->hdisplay; -if (desired_mode->vdisplay > sizes.surface_height) - sizes.surface_height = desired_mode->vdisplay; +if (desired_mode->hdisplay + x < sizes.fb_width) + sizes.fb_width = desired_mode->hdisplay + x; +if (desired_mode->vdisplay + y < sizes.fb_height) + sizes.fb_height = desired_mode->vdisplay + y; +if (desired_mode->hdisplay + x > sizes.surface_width) + sizes.surface_width = desired_mode->hdisplay + x; +if (desired_mode->vdisplay + y > sizes.surface_height) + sizes.surface_height = desired_mode->vdisplay + y; crtc_count++; } }
@@ -1356,6 +1358,7 @@ static void drm_enable_connectors(struct drm_fb_helper *fb_helper,static bool drm_target_cloned (struct drm_fb_helper *fb_helper,struct drm_display_mode **modes, +struct drm_fb_offset *offsets,bool *enabled,int width,int height) {int count, i, j;
@@ -1427,27 +1430,88 @@ static bool drm_target_cloned(struct drm_fb_helper *fb_helper,return false; } +static int drm_get_tile_offsets (struct drm_fb_helper *fb_helper, +struct drm_display_mode **modes, +struct drm_fb_offset *offsets, +int idx, +int h_idx,int v_idx) +{ +struct drm_fb_helper_connector *fb_helper_conn; +int i; +int hoffset =0 , voffset =0 ; + +for (i =0 ; i < fb_helper->connector_count; i++) { + fb_helper_conn = fb_helper->connector_info[i]; +if (!fb_helper_conn->connector->has_tile) +continue ; + +if (!modes[i] && (h_idx || v_idx)) { +DRM_DEBUG_KMS ("no modes for connector tiled %d %d\n" , i, + fb_helper_conn->connector->base.id); +continue ; + } +if (fb_helper_conn->connector->tile_h_loc < h_idx) + hoffset += modes[i]->hdisplay; + +if (fb_helper_conn->connector->tile_v_loc < v_idx) + voffset += modes[i]->vdisplay; + } + offsets[idx].x = hoffset; + offsets[idx].y = voffset; +DRM_DEBUG_KMS ("returned %d %d for %d %d\n" , hoffset, voffset, h_idx, v_idx); +return 0 ; +} +static bool drm_target_preferred (struct drm_fb_helper *fb_helper,struct drm_display_mode **modes, +struct drm_fb_offset *offsets,bool *enabled,int width,int height) {struct drm_fb_helper_connector *fb_helper_conn;int i; - +uint64_t conn_configured =0 , mask; +int tile_pass =0 ; + mask = (1 << fb_helper->connector_count) -1 ; +retry:for (i =0 ; i < fb_helper->connector_count; i++) { fb_helper_conn = fb_helper->connector_info[i]; -if (enabled[i] == false) +if (conn_configured & (1 << i)) +continue ; + +if (enabled[i] == false) { + conn_configured |= (1 << i); +continue ; + } + +/* first pass over all the untiled connectors */ +if (tile_pass ==0 && fb_helper_conn->connector->has_tile)continue ; +if (tile_pass ==1 ) { +if (fb_helper_conn->connector->tile_h_loc !=0 || + fb_helper_conn->connector->tile_v_loc !=0 ) +continue ; + + }else { +if (fb_helper_conn->connector->tile_h_loc != tile_pass -1 && + fb_helper_conn->connector->tile_v_loc != tile_pass -1 ) +/* if this tile_pass doesn't cover any of the tiles - keep going */ +continue ; + +/* find the tile offsets for this pass - need +to find all tiles left and above */ +drm_get_tile_offsets (fb_helper, modes, offsets, + i, fb_helper_conn->connector->tile_h_loc, fb_helper_conn->connector->tile_v_loc); + }DRM_DEBUG_KMS ("looking for cmdline mode on connector %d\n" , fb_helper_conn->connector->base.id);/* got for command line mode first */ modes[i] =drm_pick_cmdline_mode (fb_helper_conn, width, height);if (!modes[i]) { -DRM_DEBUG_KMS ("looking for preferred mode on connector %d\n" , - fb_helper_conn->connector->base.id); +DRM_DEBUG_KMS ("looking for preferred mode on connector %d %d\n" , + fb_helper_conn->connector->base.id, fb_helper_conn->connector->tile_group ? fb_helper_conn->connector->tile_group->id :0 ); modes[i] =drm_has_preferred_mode (fb_helper_conn, width, height); }/* No preferred modes, pick one off the list */
@@ -1457,6 +1521,13 @@ static bool drm_target_preferred(struct drm_fb_helper *fb_helper, }DRM_DEBUG_KMS ("found mode %s\n" , modes[i] ? modes[i]->name :"none" ); + conn_configured |= (1 << i); + } + +if ((conn_configured & mask) != mask) { +DRM_ERROR ("not all connectors configured %d %llx %llx\n" , tile_pass, conn_configured, mask); + tile_pass++; + goto retry; }return true; }
@@ -1546,6 +1617,7 @@ static void drm_setup_crtcs(struct drm_fb_helper *fb_helper)struct drm_device *dev = fb_helper->dev;struct drm_fb_helper_crtc **crtcs;struct drm_display_mode **modes; +struct drm_fb_offset *offsets;struct drm_mode_set *modeset;bool *enabled;int width, height;
@@ -1560,9 +1632,11 @@ static void drm_setup_crtcs(struct drm_fb_helper *fb_helper) sizeof(struct drm_fb_helper_crtc *), GFP_KERNEL); modes =kcalloc (dev->mode_config.num_connector,sizeof (struct drm_display_mode *),GFP_KERNEL ); + offsets =kcalloc (dev->mode_config.num_connector, +sizeof (struct drm_fb_offset ),GFP_KERNEL ); enabled =kcalloc (dev->mode_config.num_connector,sizeof (bool ),GFP_KERNEL ); -if (!crtcs || !modes || !enabled) { +if (!crtcs || !modes || !enabled | !offsets) {DRM_ERROR ("Memory allocation failed\n" ); goto out; }
@@ -1572,14 +1646,16 @@ static void drm_setup_crtcs(struct drm_fb_helper *fb_helper)if (!(fb_helper->funcs->initial_config && fb_helper->funcs->initial_config (fb_helper, crtcs, modes, + offsets, enabled, width, height))) {memset (modes,0 , dev->mode_config.num_connector*sizeof (modes[0 ]));memset (crtcs,0 , dev->mode_config.num_connector*sizeof (crtcs[0 ])); +memset (offsets,0 , dev->mode_config.num_connector*sizeof (offsets[0 ])); -if (!drm_target_cloned (fb_helper, - modes, enabled, width, height) && - !drm_target_preferred (fb_helper, - modes, enabled, width, height)) +if (!drm_target_cloned (fb_helper, modes, offsets, + enabled, width, height) && + !drm_target_preferred (fb_helper, modes, offsets, + enabled, width, height))DRM_ERROR ("Unable to find initial modes\n" ); DRM_DEBUG_KMS("picking CRTCs for %dx%d config\n",
@@ -1599,18 +1675,23 @@ static void drm_setup_crtcs(struct drm_fb_helper *fb_helper)for (i =0 ; i < fb_helper->connector_count; i++) {struct drm_display_mode *mode = modes[i];struct drm_fb_helper_crtc *fb_crtc = crtcs[i]; +struct drm_fb_offset *offset = &offsets[i]; modeset = &fb_crtc->mode_set;if (mode && fb_crtc) { -DRM_DEBUG_KMS ("desired mode %s set on crtc %d\n" , - mode->name, fb_crtc->mode_set.crtc->base.id); +DRM_DEBUG_KMS ("desired mode %s set on crtc %d (%d,%d)\n" , + mode->name, fb_crtc->mode_set.crtc->base.id, offset->x, offset->y); fb_crtc->desired_mode = mode; + fb_crtc->x = offset->x; + fb_crtc->y = offset->y;if (modeset->mode)drm_mode_destroy (dev, modeset->mode); modeset->mode =drm_mode_duplicate (dev, fb_crtc->desired_mode); modeset->connectors[modeset->num_connectors++] = fb_helper->connector_info[i]->connector; modeset->fb = fb_helper->fb; + modeset->x = offset->x; + modeset->y = offset->y; } }
@@ -1628,6 +1709,7 @@ static void drm_setup_crtcs(struct drm_fb_helper *fb_helper) out:kfree (crtcs);kfree (modes); +kfree (offsets);kfree (enabled); }
drivers/gpu/drm/i915/intel_fbdev.c +22 -3
@@ -322,6 +322,7 @@ intel_fb_helper_crtc(struct drm_fb_helper *fb_helper, struct drm_crtc *crtc)static bool intel_fb_initial_config (struct drm_fb_helper *fb_helper,struct drm_fb_helper_crtc **crtcs,struct drm_display_mode **modes, +struct drm_fb_offset *offsets,bool *enabled,int width,int height) {struct drm_device *dev = fb_helper->dev;
@@ -330,6 +331,8 @@ static bool intel_fb_initial_config(struct drm_fb_helper *fb_helper,bool fallback = true;int num_connectors_enabled =0 ;int num_connectors_detected =0 ; +uint64_t conn_configured =0 , mask; +int pass =0 ;/* * If the user specified any force options, just bail here
@@ -355,7 +358,8 @@ static bool intel_fb_initial_config(struct drm_fb_helper *fb_helper,return false;memcpy (save_enabled, enabled, dev->mode_config.num_connector); - + mask = (1 << fb_helper->connector_count) -1 ; +retry:for (i =0 ; i < fb_helper->connector_count; i++) {struct drm_fb_helper_connector *fb_conn;struct drm_connector *connector;
@@ -365,12 +369,19 @@ static bool intel_fb_initial_config(struct drm_fb_helper *fb_helper, fb_conn = fb_helper->connector_info[i]; connector = fb_conn->connector; +if (conn_configured & (1 << i)) +continue ; + +if (pass ==0 && !connector->has_tile) +continue ; +if (connector->status == connector_status_connected) num_connectors_detected++;if (!enabled[i]) {DRM_DEBUG_KMS ("connector %s not enabled, skipping\n" , connector->name); + conn_configured |= (1 << i);continue ; }
@@ -379,6 +390,7 @@ static bool intel_fb_initial_config(struct drm_fb_helper *fb_helper,DRM_DEBUG_KMS ("connector %s has no encoder or crtc, skipping\n" , connector->name); enabled[i] = false; + conn_configured |= (1 << i);continue ; }
@@ -407,8 +419,8 @@ static bool intel_fb_initial_config(struct drm_fb_helper *fb_helper,/* try for preferred next */ if (!modes[i]) { -DRM_DEBUG_KMS ("looking for preferred mode on connector %s\n" , - connector->name); +DRM_DEBUG_KMS ("looking for preferred mode on connector %s %d\n" , + connector->name, connector->has_tile); modes[i] =drm_has_preferred_mode (fb_conn, width, height); }
@@ -451,6 +463,13 @@ static bool intel_fb_initial_config(struct drm_fb_helper *fb_helper, modes[i]->flags & DRM_MODE_FLAG_INTERLACE ? "i" :""); fallback = false; + conn_configured |= (1 << i); + } + +if ((conn_configured & mask) != mask) { +DRM_ERROR ("not all connectors configured %d %llx %llx\n" , pass, conn_configured, mask); + pass++; + goto retry; }/*
include/drm/drm_fb_helper.h +6 -0
@@ -34,9 +34,14 @@ struct drm_fb_helper;#include <linux/kgdb.h> +struct drm_fb_offset { +int x, y; +}; +struct drm_fb_helper_crtc {struct drm_mode_set mode_set;struct drm_display_mode *desired_mode; +int x, y; };struct drm_fb_helper_surface_size {
@@ -72,6 +77,7 @@ struct drm_fb_helper_funcs {bool (*initial_config)(struct drm_fb_helper *fb_helper,struct drm_fb_helper_crtc **crtcs,struct drm_display_mode **modes, +struct drm_fb_offset *offsets,bool *enabled,int width,int height); };
Signature · 1 line
2.1.0