From 61e57a8d72f2336faf39b5d940215cf085e01e6e Mon Sep 17 00:00:00 2001 From: Adam Jackson Date: Mon, 29 Mar 2010 21:43:18 +0000 Subject: drm/edid: Fix secondary block fetch. This makes fetching the second EDID block on HDMI monitors actually work. DDC can't transfer more than 128 bytes at a time. Also, rearrange the code so the pure DDC bits are separate from block parse. Signed-off-by: Adam Jackson Signed-off-by: Dave Airlie --- include/drm/drm_crtc.h | 2 -- 1 file changed, 2 deletions(-) (limited to 'include') diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h index 1347524a8e3..f74523a299c 100644 --- a/include/drm/drm_crtc.h +++ b/include/drm/drm_crtc.h @@ -666,8 +666,6 @@ extern void drm_fb_release(struct drm_file *file_priv); extern int drm_mode_group_init_legacy_group(struct drm_device *dev, struct drm_mode_group *group); extern struct edid *drm_get_edid(struct drm_connector *connector, struct i2c_adapter *adapter); -extern int drm_do_probe_ddc_edid(struct i2c_adapter *adapter, - unsigned char *buf, int len); extern int drm_add_edid_modes(struct drm_connector *connector, struct edid *edid); extern void drm_mode_probed_add(struct drm_connector *connector, struct drm_display_mode *mode); extern void drm_mode_remove(struct drm_connector *connector, struct drm_display_mode *mode); -- cgit v1.2.3-18-g5258 From 7466f4cc508878a8328dff1c328a2b4108888d2e Mon Sep 17 00:00:00 2001 From: Adam Jackson Date: Mon, 29 Mar 2010 21:43:23 +0000 Subject: drm/edid: Remove arbitrary EDID extension limit Signed-off-by: Adam Jackson Signed-off-by: Dave Airlie --- include/drm/drm_edid.h | 3 --- 1 file changed, 3 deletions(-) (limited to 'include') diff --git a/include/drm/drm_edid.h b/include/drm/drm_edid.h index b4209898f11..d33c3e03860 100644 --- a/include/drm/drm_edid.h +++ b/include/drm/drm_edid.h @@ -201,7 +201,4 @@ struct edid { #define EDID_PRODUCT_ID(e) ((e)->prod_code[0] | ((e)->prod_code[1] << 8)) -/* define the number of Extension EDID block */ -#define DRM_MAX_EDID_EXT_NUM 4 - #endif /* __DRM_EDID_H__ */ -- cgit v1.2.3-18-g5258 From 7a37435008b0ffea2442eb1134ddd4adeea81e19 Mon Sep 17 00:00:00 2001 From: Adam Jackson Date: Mon, 29 Mar 2010 21:43:30 +0000 Subject: drm/edid: Add secondary GTF curve support Before CVT-R, some monitors would advertise support for an alternative GTF formula with lower blanking intervals. Correctly identify such monitors, and use the alternative formula when generating modes for them. Note that we only do this for "standard" timing descriptors (tuples of hsize in characters / aspect ratio / vertical refresh). Range-based mode lists still only refer to the primary GTF curve. It would be possible to do better for the latter case, but monitors are required to support the primary curve over the entire advertised range, so all it would win you is a lower pixel clock and therefore possibly better image quality on analog links. Signed-off-by: Adam Jackson Signed-off-by: Dave Airlie --- include/drm/drm_crtc.h | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'include') diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h index f74523a299c..8eb3630ee67 100644 --- a/include/drm/drm_crtc.h +++ b/include/drm/drm_crtc.h @@ -797,6 +797,10 @@ extern struct drm_display_mode *drm_cvt_mode(struct drm_device *dev, extern struct drm_display_mode *drm_gtf_mode(struct drm_device *dev, int hdisplay, int vdisplay, int vrefresh, bool interlaced, int margins); +extern struct drm_display_mode *drm_gtf_mode_complex(struct drm_device *dev, + int hdisplay, int vdisplay, int vrefresh, + bool interlaced, int margins, int GTF_M, + int GTF_2C, int GTF_K, int GTF_2J); extern int drm_add_modes_noedid(struct drm_connector *connector, int hdisplay, int vdisplay); -- cgit v1.2.3-18-g5258 From 1403b1a38e8b19a4cc17e2c158e278628943a436 Mon Sep 17 00:00:00 2001 From: Pauli Nieminen Date: Thu, 1 Apr 2010 12:44:57 +0000 Subject: drm/ttm: add pool wc/uc page allocator V3 On AGP system we might allocate/free routinely uncached or wc memory, changing page from cached (wb) to uc or wc is very expensive and involves a lot of flushing. To improve performance this allocator use a pool of uc,wc pages. Pools are protected with spinlocks to allow multiple threads to allocate pages simultanously. Expensive operations are done outside of spinlock to maximize concurrency. Pools are linked lists of pages that were recently freed. mm shrink callback allows kernel to claim back pages when they are required for something else. Fixes: * set_pages_array_wb handles highmem pages so we don't have to remove them from pool. * Add count parameter to ttm_put_pages to avoid looping in free code. * Change looping from _safe to normal in pool fill error path. * Initialize sum variable and make the loop prettier in get_num_unused_pages. * Moved pages_freed reseting inside the loop in ttm_page_pool_free. * Add warning comment about spinlock context in ttm_page_pool_free. Based on Jerome Glisse's and Dave Airlie's pool allocator. Signed-off-by: Jerome Glisse Signed-off-by: Dave Airlie Signed-off-by: Pauli Nieminen Reviewed-by: Jerome Glisse Signed-off-by: Dave Airlie --- include/drm/ttm/ttm_page_alloc.h | 70 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) create mode 100644 include/drm/ttm/ttm_page_alloc.h (limited to 'include') diff --git a/include/drm/ttm/ttm_page_alloc.h b/include/drm/ttm/ttm_page_alloc.h new file mode 100644 index 00000000000..043d817b816 --- /dev/null +++ b/include/drm/ttm/ttm_page_alloc.h @@ -0,0 +1,70 @@ +/* + * Copyright (c) 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, sub license, + * 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 (including the + * next paragraph) 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 NON-INFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS 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. + * + * Authors: Dave Airlie + * Jerome Glisse + */ +#ifndef TTM_PAGE_ALLOC +#define TTM_PAGE_ALLOC + +#include "ttm_bo_driver.h" +#include "ttm_memory.h" + +/** + * Get count number of pages from pool to pages list. + * + * @pages: heado of empty linked list where pages are filled. + * @flags: ttm flags for page allocation. + * @cstate: ttm caching state for the page. + * @count: number of pages to allocate. + */ +int ttm_get_pages(struct list_head *pages, + int flags, + enum ttm_caching_state cstate, + unsigned count); +/** + * Put linked list of pages to pool. + * + * @pages: list of pages to free. + * @page_count: number of pages in the list. Zero can be passed for unknown + * count. + * @flags: ttm flags for page allocation. + * @cstate: ttm caching state. + */ +void ttm_put_pages(struct list_head *pages, + unsigned page_count, + int flags, + enum ttm_caching_state cstate); +/** + * Initialize pool allocator. + * + * Pool allocator is internaly reference counted so it can be initialized + * multiple times but ttm_page_alloc_fini has to be called same number of + * times. + */ +int ttm_page_alloc_init(unsigned max_pages); +/** + * Free pool allocator. + */ +void ttm_page_alloc_fini(void); + +#endif -- cgit v1.2.3-18-g5258 From 0745866165598b067442c472911280527b08be3e Mon Sep 17 00:00:00 2001 From: Pauli Nieminen Date: Thu, 1 Apr 2010 12:44:58 +0000 Subject: drm/ttm: Add debugfs output entry to pool allocator. ttm_page_alloc_debugfs can be registered to output the state of pools. Debugfs file will output number of pages freed from the pool, number of pages in pool now and the lowes number of pages in pool since previous shrink. Signed-off-by: Pauli Nieminen Signed-off-by: Dave Airlie --- include/drm/ttm/ttm_page_alloc.h | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'include') diff --git a/include/drm/ttm/ttm_page_alloc.h b/include/drm/ttm/ttm_page_alloc.h index 043d817b816..8b091c309df 100644 --- a/include/drm/ttm/ttm_page_alloc.h +++ b/include/drm/ttm/ttm_page_alloc.h @@ -67,4 +67,8 @@ int ttm_page_alloc_init(unsigned max_pages); */ void ttm_page_alloc_fini(void); +/** + * Output the state of pools to debugfs file + */ +extern int ttm_page_alloc_debugfs(struct seq_file *m, void *data); #endif -- cgit v1.2.3-18-g5258 From c96af79e3463d5d3f865625baa8bb8aa4c0944a0 Mon Sep 17 00:00:00 2001 From: Pauli Nieminen Date: Thu, 1 Apr 2010 12:45:03 +0000 Subject: drm/ttm: Add sysfs interface to control pool allocator. Sysfs interface allows user to configure pool allocator functionality and change limits for the size of pool. Signed-off-by: Pauli Nieminen Signed-off-by: Dave Airlie --- include/drm/ttm/ttm_page_alloc.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include') diff --git a/include/drm/ttm/ttm_page_alloc.h b/include/drm/ttm/ttm_page_alloc.h index 8b091c309df..8bb4de567b2 100644 --- a/include/drm/ttm/ttm_page_alloc.h +++ b/include/drm/ttm/ttm_page_alloc.h @@ -61,7 +61,7 @@ void ttm_put_pages(struct list_head *pages, * multiple times but ttm_page_alloc_fini has to be called same number of * times. */ -int ttm_page_alloc_init(unsigned max_pages); +int ttm_page_alloc_init(struct ttm_mem_global *glob, unsigned max_pages); /** * Free pool allocator. */ -- cgit v1.2.3-18-g5258 From 386516744ba45d50f42c6999151cc210cb4f96e4 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Tue, 30 Mar 2010 05:34:13 +0000 Subject: drm/fb: fix fbdev object model + cleanup properly. The fbdev layer in the kms code should act like a consumer of the kms services and avoid having relying on information being store in the kms core structures in order for it to work. This patch a) removes the info pointer/psuedo palette from the core drm_framebuffer structure and moves it to the fbdev helper layer, it also removes the core drm keeping a list of kernel kms fbdevs. b) migrated all the fb helper functions out of the crtc helper file into the fb helper file. c) pushed the fb probing/hotplug control into the driver d) makes the surface sizes into a structure for ease of passing This changes the intel/radeon/nouveau drivers to use the new helper. Signed-off-by: Dave Airlie --- include/drm/drm_crtc.h | 12 ------------ include/drm/drm_crtc_helper.h | 1 - include/drm/drm_fb_helper.h | 24 ++++++++++++++++-------- 3 files changed, 16 insertions(+), 21 deletions(-) (limited to 'include') diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h index 1347524a8e3..c70814b184e 100644 --- a/include/drm/drm_crtc.h +++ b/include/drm/drm_crtc.h @@ -271,8 +271,6 @@ struct drm_framebuffer { unsigned int depth; int bits_per_pixel; int flags; - struct fb_info *fbdev; - u32 pseudo_palette[17]; struct list_head filp_head; /* if you are using the helper */ void *helper_private; @@ -548,16 +546,9 @@ struct drm_mode_set { /** * struct drm_mode_config_funcs - configure CRTCs for a given screen layout - * @resize: adjust CRTCs as necessary for the proposed layout - * - * Currently only a resize hook is available. DRM will call back into the - * driver with a new screen width and height. If the driver can't support - * the proposed size, it can return false. Otherwise it should adjust - * the CRTC<->connector mappings as needed and update its view of the screen. */ struct drm_mode_config_funcs { struct drm_framebuffer *(*fb_create)(struct drm_device *dev, struct drm_file *file_priv, struct drm_mode_fb_cmd *mode_cmd); - int (*fb_changed)(struct drm_device *dev); }; struct drm_mode_group { @@ -590,9 +581,6 @@ struct drm_mode_config { struct list_head property_list; - /* in-kernel framebuffers - hung of filp_head in drm_framebuffer */ - struct list_head fb_kernel_list; - int min_width, min_height; int max_width, max_height; struct drm_mode_config_funcs *funcs; diff --git a/include/drm/drm_crtc_helper.h b/include/drm/drm_crtc_helper.h index b29e20168b5..ce7aab77f7d 100644 --- a/include/drm/drm_crtc_helper.h +++ b/include/drm/drm_crtc_helper.h @@ -97,7 +97,6 @@ struct drm_connector_helper_funcs { extern int drm_helper_probe_single_connector_modes(struct drm_connector *connector, uint32_t maxX, uint32_t maxY); extern void drm_helper_disable_unused_functions(struct drm_device *dev); extern int drm_helper_hotplug_stage_two(struct drm_device *dev); -extern bool drm_helper_initial_config(struct drm_device *dev); extern int drm_crtc_helper_set_config(struct drm_mode_set *set); extern bool drm_crtc_helper_set_mode(struct drm_crtc *crtc, struct drm_display_mode *mode, diff --git a/include/drm/drm_fb_helper.h b/include/drm/drm_fb_helper.h index 58c892a2cbf..38ab0daffd1 100644 --- a/include/drm/drm_fb_helper.h +++ b/include/drm/drm_fb_helper.h @@ -57,6 +57,15 @@ struct drm_fb_helper_cmdline_mode { bool margins; }; +struct drm_fb_helper_surface_size { + u32 fb_width; + u32 fb_height; + u32 surface_width; + u32 surface_height; + u32 surface_bpp; + u32 surface_depth; +}; + struct drm_fb_helper_connector { struct drm_fb_helper_cmdline_mode cmdline_mode; }; @@ -69,19 +78,16 @@ struct drm_fb_helper { struct drm_fb_helper_crtc *crtc_info; struct drm_fb_helper_funcs *funcs; int conn_limit; + struct fb_info *fbdev; + u32 pseudo_palette[17]; struct list_head kernel_fb_list; }; int drm_fb_helper_single_fb_probe(struct drm_device *dev, int preferred_bpp, int (*fb_create)(struct drm_device *dev, - uint32_t fb_width, - uint32_t fb_height, - uint32_t surface_width, - uint32_t surface_height, - uint32_t surface_depth, - uint32_t surface_bpp, - struct drm_framebuffer **fb_ptr)); + struct drm_fb_helper_surface_size *sizes, + struct drm_fb_helper **fb_ptr)); int drm_fb_helper_init_crtc_count(struct drm_fb_helper *helper, int crtc_count, int max_conn); void drm_fb_helper_free(struct drm_fb_helper *helper); @@ -99,7 +105,7 @@ int drm_fb_helper_setcolreg(unsigned regno, struct fb_info *info); void drm_fb_helper_restore(void); -void drm_fb_helper_fill_var(struct fb_info *info, struct drm_framebuffer *fb, +void drm_fb_helper_fill_var(struct fb_info *info, struct drm_fb_helper *fb_helper, uint32_t fb_width, uint32_t fb_height); void drm_fb_helper_fill_fix(struct fb_info *info, uint32_t pitch, uint32_t depth); @@ -108,4 +114,6 @@ int drm_fb_helper_add_connector(struct drm_connector *connector); int drm_fb_helper_parse_command_line(struct drm_device *dev); int drm_fb_helper_setcmap(struct fb_cmap *cmap, struct fb_info *info); +bool drm_helper_fb_hotplug_event(struct drm_device *dev); +bool drm_helper_initial_config(struct drm_device *dev); #endif -- cgit v1.2.3-18-g5258 From 8be48d924c307e72e3797ab5bde81b07a1ccc52d Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Tue, 30 Mar 2010 05:34:14 +0000 Subject: drm/kms/fb: move to using fb helper crtc grouping instead of core crtc list This move to using the list of crtcs in the fb helper and cleans up the whole picking code, now we store the crtc/connectors we want directly into the modeset and we use the modeset directly to set the mode. Fixes from James Simmons and Ben Skeggs. Signed-off-by: Dave Airlie --- include/drm/drm_crtc.h | 5 ----- include/drm/drm_fb_helper.h | 21 +++++++++++++-------- 2 files changed, 13 insertions(+), 13 deletions(-) (limited to 'include') diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h index c70814b184e..e4e34bae22c 100644 --- a/include/drm/drm_crtc.h +++ b/include/drm/drm_crtc.h @@ -367,9 +367,6 @@ struct drm_crtc_funcs { * @enabled: is this CRTC enabled? * @x: x position on screen * @y: y position on screen - * @desired_mode: new desired mode - * @desired_x: desired x for desired_mode - * @desired_y: desired y for desired_mode * @funcs: CRTC control functions * * Each CRTC may have one or more connectors associated with it. This structure @@ -389,8 +386,6 @@ struct drm_crtc { struct drm_display_mode mode; int x, y; - struct drm_display_mode *desired_mode; - int desired_x, desired_y; const struct drm_crtc_funcs *funcs; /* CRTC gamma size for reporting to userspace */ diff --git a/include/drm/drm_fb_helper.h b/include/drm/drm_fb_helper.h index 38ab0daffd1..b1ea66f11de 100644 --- a/include/drm/drm_fb_helper.h +++ b/include/drm/drm_fb_helper.h @@ -33,6 +33,7 @@ struct drm_fb_helper_crtc { uint32_t crtc_id; struct drm_mode_set mode_set; + struct drm_display_mode *desired_mode; }; @@ -81,14 +82,16 @@ struct drm_fb_helper { struct fb_info *fbdev; u32 pseudo_palette[17]; struct list_head kernel_fb_list; + + int (*fb_probe)(struct drm_fb_helper *helper, + struct drm_fb_helper_surface_size *sizes); }; -int drm_fb_helper_single_fb_probe(struct drm_device *dev, - int preferred_bpp, - int (*fb_create)(struct drm_device *dev, - struct drm_fb_helper_surface_size *sizes, - struct drm_fb_helper **fb_ptr)); -int drm_fb_helper_init_crtc_count(struct drm_fb_helper *helper, int crtc_count, +int drm_fb_helper_single_fb_probe(struct drm_fb_helper *helper, + int preferred_bpp); + +int drm_fb_helper_init_crtc_count(struct drm_device *dev, + struct drm_fb_helper *helper, int crtc_count, int max_conn); void drm_fb_helper_free(struct drm_fb_helper *helper); int drm_fb_helper_blank(int blank, struct fb_info *info); @@ -114,6 +117,8 @@ int drm_fb_helper_add_connector(struct drm_connector *connector); int drm_fb_helper_parse_command_line(struct drm_device *dev); int drm_fb_helper_setcmap(struct fb_cmap *cmap, struct fb_info *info); -bool drm_helper_fb_hotplug_event(struct drm_device *dev); -bool drm_helper_initial_config(struct drm_device *dev); +bool drm_helper_fb_hotplug_event(struct drm_fb_helper *fb_helper, u32 max_width, + u32 max_height); +bool drm_fb_helper_initial_config(struct drm_fb_helper *fb_helper); + #endif -- cgit v1.2.3-18-g5258 From 0b4c0f3f0eceacb691e2b5570d9b16d751ce1b48 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Tue, 30 Mar 2010 05:34:15 +0000 Subject: drm/kms/fb: separate fbdev connector list from core drm connectors This breaks the connection between the core drm connector list and the fbdev connector usage, and allows them to become disjoint in the future. It also removes the untype void* that was in the connector struct to support this. All connectors are added to the fbdev now but this could be changed in the future. Signed-off-by: Dave Airlie --- include/drm/drm_crtc.h | 1 - include/drm/drm_crtc_helper.h | 5 +---- include/drm/drm_fb_helper.h | 6 ++++-- 3 files changed, 5 insertions(+), 7 deletions(-) (limited to 'include') diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h index e4e34bae22c..fce2042ad0a 100644 --- a/include/drm/drm_crtc.h +++ b/include/drm/drm_crtc.h @@ -514,7 +514,6 @@ struct drm_connector { uint32_t encoder_ids[DRM_CONNECTOR_MAX_ENCODER]; uint32_t force_encoder_id; struct drm_encoder *encoder; /* currently active encoder */ - void *fb_helper_private; }; /** diff --git a/include/drm/drm_crtc_helper.h b/include/drm/drm_crtc_helper.h index ce7aab77f7d..b1fa0f8cfa6 100644 --- a/include/drm/drm_crtc_helper.h +++ b/include/drm/drm_crtc_helper.h @@ -39,7 +39,6 @@ #include -#include "drm_fb_helper.h" struct drm_crtc_helper_funcs { /* * Control power levels on the CRTC. If the mode passed in is @@ -96,7 +95,6 @@ struct drm_connector_helper_funcs { extern int drm_helper_probe_single_connector_modes(struct drm_connector *connector, uint32_t maxX, uint32_t maxY); extern void drm_helper_disable_unused_functions(struct drm_device *dev); -extern int drm_helper_hotplug_stage_two(struct drm_device *dev); extern int drm_crtc_helper_set_config(struct drm_mode_set *set); extern bool drm_crtc_helper_set_mode(struct drm_crtc *crtc, struct drm_display_mode *mode, @@ -122,11 +120,10 @@ static inline void drm_encoder_helper_add(struct drm_encoder *encoder, encoder->helper_private = (void *)funcs; } -static inline int drm_connector_helper_add(struct drm_connector *connector, +static inline void drm_connector_helper_add(struct drm_connector *connector, const struct drm_connector_helper_funcs *funcs) { connector->helper_private = (void *)funcs; - return drm_fb_helper_add_connector(connector); } extern int drm_helper_resume_force_mode(struct drm_device *dev); diff --git a/include/drm/drm_fb_helper.h b/include/drm/drm_fb_helper.h index b1ea66f11de..50094f94d4c 100644 --- a/include/drm/drm_fb_helper.h +++ b/include/drm/drm_fb_helper.h @@ -69,6 +69,7 @@ struct drm_fb_helper_surface_size { struct drm_fb_helper_connector { struct drm_fb_helper_cmdline_mode cmdline_mode; + struct drm_connector *connector; }; struct drm_fb_helper { @@ -77,6 +78,8 @@ struct drm_fb_helper { struct drm_display_mode *mode; int crtc_count; struct drm_fb_helper_crtc *crtc_info; + int connector_count; + struct drm_fb_helper_connector **connector_info; struct drm_fb_helper_funcs *funcs; int conn_limit; struct fb_info *fbdev; @@ -113,12 +116,11 @@ void drm_fb_helper_fill_var(struct fb_info *info, struct drm_fb_helper *fb_helpe void drm_fb_helper_fill_fix(struct fb_info *info, uint32_t pitch, uint32_t depth); -int drm_fb_helper_add_connector(struct drm_connector *connector); -int drm_fb_helper_parse_command_line(struct drm_device *dev); int drm_fb_helper_setcmap(struct fb_cmap *cmap, struct fb_info *info); bool drm_helper_fb_hotplug_event(struct drm_fb_helper *fb_helper, u32 max_width, u32 max_height); bool drm_fb_helper_initial_config(struct drm_fb_helper *fb_helper); +int drm_fb_helper_single_add_all_connectors(struct drm_fb_helper *fb_helper); #endif -- cgit v1.2.3-18-g5258 From 5c4426a782bc9509573fc7958a786ebd14fafdf3 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Tue, 30 Mar 2010 05:34:17 +0000 Subject: drm/kms/fb: add polling support for when nothing is connected. When we are running in a headless environment we have no idea what output the user might plug in later, we only have hotplug detect from the digital outputs. So if we detect no connected outputs at initialisation, start a slow work operation to poll every 5 seconds for an output. this is only hooked up for radeon so far, on hw where we have full hotplug detection there is no need for this. Signed-off-by: Dave Airlie --- include/drm/drm_fb_helper.h | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) (limited to 'include') diff --git a/include/drm/drm_fb_helper.h b/include/drm/drm_fb_helper.h index 50094f94d4c..a073d73c195 100644 --- a/include/drm/drm_fb_helper.h +++ b/include/drm/drm_fb_helper.h @@ -30,6 +30,8 @@ #ifndef DRM_FB_HELPER_H #define DRM_FB_HELPER_H +#include + struct drm_fb_helper_crtc { uint32_t crtc_id; struct drm_mode_set mode_set; @@ -86,8 +88,12 @@ struct drm_fb_helper { u32 pseudo_palette[17]; struct list_head kernel_fb_list; + struct delayed_slow_work output_poll_slow_work; + bool poll_enabled; int (*fb_probe)(struct drm_fb_helper *helper, struct drm_fb_helper_surface_size *sizes); + + void (*fb_poll_changed)(struct drm_fb_helper *helper); }; int drm_fb_helper_single_fb_probe(struct drm_fb_helper *helper, @@ -118,9 +124,11 @@ void drm_fb_helper_fill_fix(struct fb_info *info, uint32_t pitch, int drm_fb_helper_setcmap(struct fb_cmap *cmap, struct fb_info *info); -bool drm_helper_fb_hotplug_event(struct drm_fb_helper *fb_helper, u32 max_width, - u32 max_height); +bool drm_helper_fb_hotplug_event(struct drm_fb_helper *fb_helper, + u32 max_width, u32 max_height, bool polled); bool drm_fb_helper_initial_config(struct drm_fb_helper *fb_helper); int drm_fb_helper_single_add_all_connectors(struct drm_fb_helper *fb_helper); +void drm_fb_helper_poll_init(struct drm_fb_helper *fb_helper); +void drm_fb_helper_poll_fini(struct drm_fb_helper *fb_helper); #endif -- cgit v1.2.3-18-g5258 From 4abe35204af82a018ca3ce6db4102aa09719698e Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Tue, 30 Mar 2010 05:34:18 +0000 Subject: drm/kms/fb: use slow work mechanism for normal hotplug also. a) slow work is always used now for any fbcon hotplug, as its not a fast task and is more suited to being ran under slow work. b) attempt to not do any fbdev changes when X is running as we'll just mess it up. This hooks set_par to hopefully do the changes once X hands control to fbdev. This also adds the nouveau/intel hotplug support. Signed-off-by: Dave Airlie --- include/drm/drm_fb_helper.h | 47 +++++++++++++++++++++++++-------------------- 1 file changed, 26 insertions(+), 21 deletions(-) (limited to 'include') diff --git a/include/drm/drm_fb_helper.h b/include/drm/drm_fb_helper.h index a073d73c195..9b55a94fead 100644 --- a/include/drm/drm_fb_helper.h +++ b/include/drm/drm_fb_helper.h @@ -32,20 +32,14 @@ #include +struct drm_fb_helper; + struct drm_fb_helper_crtc { uint32_t crtc_id; struct drm_mode_set mode_set; struct drm_display_mode *desired_mode; }; - -struct drm_fb_helper_funcs { - void (*gamma_set)(struct drm_crtc *crtc, u16 red, u16 green, - u16 blue, int regno); - void (*gamma_get)(struct drm_crtc *crtc, u16 *red, u16 *green, - u16 *blue, int regno); -}; - /* mode specified on the command line */ struct drm_fb_helper_cmdline_mode { bool specified; @@ -69,6 +63,19 @@ struct drm_fb_helper_surface_size { u32 surface_depth; }; +struct drm_fb_helper_funcs { + void (*gamma_set)(struct drm_crtc *crtc, u16 red, u16 green, + u16 blue, int regno); + void (*gamma_get)(struct drm_crtc *crtc, u16 *red, u16 *green, + u16 *blue, int regno); + + int (*fb_probe)(struct drm_fb_helper *helper, + struct drm_fb_helper_surface_size *sizes); + + void (*fb_output_status_changed)(struct drm_fb_helper *helper); + +}; + struct drm_fb_helper_connector { struct drm_fb_helper_cmdline_mode cmdline_mode; struct drm_connector *connector; @@ -88,21 +95,20 @@ struct drm_fb_helper { u32 pseudo_palette[17]; struct list_head kernel_fb_list; - struct delayed_slow_work output_poll_slow_work; + struct delayed_slow_work output_status_change_slow_work; bool poll_enabled; - int (*fb_probe)(struct drm_fb_helper *helper, - struct drm_fb_helper_surface_size *sizes); - - void (*fb_poll_changed)(struct drm_fb_helper *helper); + /* we got a hotplug but fbdev wasn't running the console + delay until next set_par */ + bool delayed_hotplug; }; int drm_fb_helper_single_fb_probe(struct drm_fb_helper *helper, int preferred_bpp); -int drm_fb_helper_init_crtc_count(struct drm_device *dev, - struct drm_fb_helper *helper, int crtc_count, - int max_conn); -void drm_fb_helper_free(struct drm_fb_helper *helper); +int drm_fb_helper_init(struct drm_device *dev, + struct drm_fb_helper *helper, int crtc_count, + int max_conn, bool polled); +void drm_fb_helper_fini(struct drm_fb_helper *helper); int drm_fb_helper_blank(int blank, struct fb_info *info); int drm_fb_helper_pan_display(struct fb_var_screeninfo *var, struct fb_info *info); @@ -125,10 +131,9 @@ void drm_fb_helper_fill_fix(struct fb_info *info, uint32_t pitch, int drm_fb_helper_setcmap(struct fb_cmap *cmap, struct fb_info *info); bool drm_helper_fb_hotplug_event(struct drm_fb_helper *fb_helper, - u32 max_width, u32 max_height, bool polled); -bool drm_fb_helper_initial_config(struct drm_fb_helper *fb_helper); + bool polled); +bool drm_fb_helper_initial_config(struct drm_fb_helper *fb_helper, int bpp_sel); int drm_fb_helper_single_add_all_connectors(struct drm_fb_helper *fb_helper); -void drm_fb_helper_poll_init(struct drm_fb_helper *fb_helper); -void drm_fb_helper_poll_fini(struct drm_fb_helper *fb_helper); +void drm_helper_fb_hpd_irq_event(struct drm_fb_helper *fb_helper); #endif -- cgit v1.2.3-18-g5258 From 9d87fa2138d06ff400551800d67d522625033e35 Mon Sep 17 00:00:00 2001 From: Jerome Glisse Date: Wed, 7 Apr 2010 10:21:19 +0000 Subject: drm/ttm: split no_wait argument in 2 GPU or reserve wait There is case where we want to be able to wait only for the GPU while not waiting for other buffer to be unreserved. This patch split the no_wait argument all the way down in the whole ttm path so that upper level can decide on what to wait on or not. [airlied: squashed these 4 for bisectability reasons.] drm/radeon/kms: update to TTM no_wait splitted argument drm/nouveau: update to TTM no_wait splitted argument drm/vmwgfx: update to TTM no_wait splitted argument [vmwgfx patch: Reviewed-by: Thomas Hellstrom ] Signed-off-by: Jerome Glisse Acked-by: Thomas Hellstrom Signed-off-by: Dave Airlie --- include/drm/ttm/ttm_bo_api.h | 6 ++++-- include/drm/ttm/ttm_bo_driver.h | 29 ++++++++++++++++++----------- 2 files changed, 22 insertions(+), 13 deletions(-) (limited to 'include') diff --git a/include/drm/ttm/ttm_bo_api.h b/include/drm/ttm/ttm_bo_api.h index 81eb9f45883..8c8005ec4ea 100644 --- a/include/drm/ttm/ttm_bo_api.h +++ b/include/drm/ttm/ttm_bo_api.h @@ -313,7 +313,8 @@ extern int ttm_bo_wait(struct ttm_buffer_object *bo, bool lazy, * @bo: The buffer object. * @placement: Proposed placement for the buffer object. * @interruptible: Sleep interruptible if sleeping. - * @no_wait: Return immediately if the buffer is busy. + * @no_wait_reserve: Return immediately if other buffers are busy. + * @no_wait_gpu: Return immediately if the GPU is busy. * * Changes placement and caching policy of the buffer object * according proposed placement. @@ -325,7 +326,8 @@ extern int ttm_bo_wait(struct ttm_buffer_object *bo, bool lazy, */ extern int ttm_bo_validate(struct ttm_buffer_object *bo, struct ttm_placement *placement, - bool interruptible, bool no_wait); + bool interruptible, bool no_wait_reserve, + bool no_wait_gpu); /** * ttm_bo_unref diff --git a/include/drm/ttm/ttm_bo_driver.h b/include/drm/ttm/ttm_bo_driver.h index e929c27ede2..69f70e418c2 100644 --- a/include/drm/ttm/ttm_bo_driver.h +++ b/include/drm/ttm/ttm_bo_driver.h @@ -311,7 +311,8 @@ struct ttm_bo_driver { */ int (*move) (struct ttm_buffer_object *bo, bool evict, bool interruptible, - bool no_wait, struct ttm_mem_reg *new_mem); + bool no_wait_reserve, bool no_wait_gpu, + struct ttm_mem_reg *new_mem); /** * struct ttm_bo_driver_member verify_access @@ -633,7 +634,8 @@ extern bool ttm_mem_reg_is_pci(struct ttm_bo_device *bdev, * @proposed_placement: Proposed new placement for the buffer object. * @mem: A struct ttm_mem_reg. * @interruptible: Sleep interruptible when sliping. - * @no_wait: Don't sleep waiting for space to become available. + * @no_wait_reserve: Return immediately if other buffers are busy. + * @no_wait_gpu: Return immediately if the GPU is busy. * * Allocate memory space for the buffer object pointed to by @bo, using * the placement flags in @mem, potentially evicting other idle buffer objects. @@ -647,7 +649,8 @@ extern bool ttm_mem_reg_is_pci(struct ttm_bo_device *bdev, extern int ttm_bo_mem_space(struct ttm_buffer_object *bo, struct ttm_placement *placement, struct ttm_mem_reg *mem, - bool interruptible, bool no_wait); + bool interruptible, + bool no_wait_reserve, bool no_wait_gpu); /** * ttm_bo_wait_for_cpu * @@ -826,7 +829,8 @@ extern void ttm_bo_unblock_reservation(struct ttm_buffer_object *bo); * * @bo: A pointer to a struct ttm_buffer_object. * @evict: 1: This is an eviction. Don't try to pipeline. - * @no_wait: Never sleep, but rather return with -EBUSY. + * @no_wait_reserve: Return immediately if other buffers are busy. + * @no_wait_gpu: Return immediately if the GPU is busy. * @new_mem: struct ttm_mem_reg indicating where to move. * * Optimized move function for a buffer object with both old and @@ -840,15 +844,16 @@ extern void ttm_bo_unblock_reservation(struct ttm_buffer_object *bo); */ extern int ttm_bo_move_ttm(struct ttm_buffer_object *bo, - bool evict, bool no_wait, - struct ttm_mem_reg *new_mem); + bool evict, bool no_wait_reserve, + bool no_wait_gpu, struct ttm_mem_reg *new_mem); /** * ttm_bo_move_memcpy * * @bo: A pointer to a struct ttm_buffer_object. * @evict: 1: This is an eviction. Don't try to pipeline. - * @no_wait: Never sleep, but rather return with -EBUSY. + * @no_wait_reserve: Return immediately if other buffers are busy. + * @no_wait_gpu: Return immediately if the GPU is busy. * @new_mem: struct ttm_mem_reg indicating where to move. * * Fallback move function for a mappable buffer object in mappable memory. @@ -862,8 +867,8 @@ extern int ttm_bo_move_ttm(struct ttm_buffer_object *bo, */ extern int ttm_bo_move_memcpy(struct ttm_buffer_object *bo, - bool evict, - bool no_wait, struct ttm_mem_reg *new_mem); + bool evict, bool no_wait_reserve, + bool no_wait_gpu, struct ttm_mem_reg *new_mem); /** * ttm_bo_free_old_node @@ -882,7 +887,8 @@ extern void ttm_bo_free_old_node(struct ttm_buffer_object *bo); * @sync_obj_arg: An argument to pass to the sync object idle / wait * functions. * @evict: This is an evict move. Don't return until the buffer is idle. - * @no_wait: Never sleep, but rather return with -EBUSY. + * @no_wait_reserve: Return immediately if other buffers are busy. + * @no_wait_gpu: Return immediately if the GPU is busy. * @new_mem: struct ttm_mem_reg indicating where to move. * * Accelerated move function to be called when an accelerated move @@ -896,7 +902,8 @@ extern void ttm_bo_free_old_node(struct ttm_buffer_object *bo); extern int ttm_bo_move_accel_cleanup(struct ttm_buffer_object *bo, void *sync_obj, void *sync_obj_arg, - bool evict, bool no_wait, + bool evict, bool no_wait_reserve, + bool no_wait_gpu, struct ttm_mem_reg *new_mem); /** * ttm_io_prot -- cgit v1.2.3-18-g5258 From 1d397043bcc2c8cdccb584a8ef73131f28f18e4c Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Fri, 9 Apr 2010 19:05:04 +0000 Subject: drm: extract drm_gem_object_init This function can be used by drivers who allocate the drm gem object on their own. No functional change in here, just preparation. Signed-off-by: Daniel Vetter Acked-by: Eric Anholt Signed-off-by: Dave Airlie --- include/drm/drmP.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include') diff --git a/include/drm/drmP.h b/include/drm/drmP.h index 2f3b3a00b7a..b3b57b561b9 100644 --- a/include/drm/drmP.h +++ b/include/drm/drmP.h @@ -1432,6 +1432,8 @@ void drm_gem_object_free(struct kref *kref); void drm_gem_object_free_unlocked(struct kref *kref); struct drm_gem_object *drm_gem_object_alloc(struct drm_device *dev, size_t size); +int drm_gem_object_init(struct drm_device *dev, + struct drm_gem_object *obj, size_t size); void drm_gem_object_handle_free(struct kref *kref); void drm_gem_vm_open(struct vm_area_struct *vma); void drm_gem_vm_close(struct vm_area_struct *vma); -- cgit v1.2.3-18-g5258 From fd632aa34c8592fb1d37fc83cbffa827bc7dd42c Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Fri, 9 Apr 2010 19:05:05 +0000 Subject: drm: free core gem object from driver callbacks When drivers embed the core gem object into their own structures, they'll have to do this. Temporarily this results in an ugly kfree(gem_obj); in every gem driver. Signed-off-by: Daniel Vetter Acked-by: Eric Anholt Signed-off-by: Dave Airlie --- include/drm/drmP.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include') diff --git a/include/drm/drmP.h b/include/drm/drmP.h index b3b57b561b9..c1b987158df 100644 --- a/include/drm/drmP.h +++ b/include/drm/drmP.h @@ -1428,6 +1428,7 @@ extern void drm_sysfs_connector_remove(struct drm_connector *connector); /* Graphics Execution Manager library functions (drm_gem.c) */ int drm_gem_init(struct drm_device *dev); void drm_gem_destroy(struct drm_device *dev); +void drm_gem_object_release(struct drm_gem_object *obj); void drm_gem_object_free(struct kref *kref); void drm_gem_object_free_unlocked(struct kref *kref); struct drm_gem_object *drm_gem_object_alloc(struct drm_device *dev, -- cgit v1.2.3-18-g5258 From 82c5da6bf8b55a931b042fb531083863d26c8020 Mon Sep 17 00:00:00 2001 From: Jerome Glisse Date: Fri, 9 Apr 2010 14:39:23 +0200 Subject: drm/ttm: ttm_fault callback to allow driver to handle bo placement V6 On fault the driver is given the opportunity to perform any operation it sees fit in order to place the buffer into a CPU visible area of memory. This patch doesn't break TTM users, nouveau, vmwgfx and radeon should keep working properly. Future patch will take advantage of this infrastructure and remove the old path from TTM once driver are converted. V2 return VM_FAULT_NOPAGE if callback return -EBUSY or -ERESTARTSYS V3 balance io_mem_reserve and io_mem_free call, fault_reserve_notify is responsible to perform any necessary task for mapping to succeed V4 minor cleanup, atomic_t -> bool as member is protected by reserve mecanism from concurent access V5 the callback is now responsible for iomapping the bo and providing a virtual address this simplify TTM and will allow to get rid of TTM_MEMTYPE_FLAG_NEEDS_IOREMAP V6 use the bus addr data to decide to ioremap or this isn't needed but we don't necesarily need to ioremap in the callback but still allow driver to use static mapping Signed-off-by: Jerome Glisse Reviewed-by: Thomas Hellstrom Signed-off-by: Dave Airlie --- include/drm/ttm/ttm_bo_api.h | 23 +++++++++++++++++++++++ include/drm/ttm/ttm_bo_driver.h | 16 +++++++++++++++- 2 files changed, 38 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/include/drm/ttm/ttm_bo_api.h b/include/drm/ttm/ttm_bo_api.h index 8c8005ec4ea..3e273e0b941 100644 --- a/include/drm/ttm/ttm_bo_api.h +++ b/include/drm/ttm/ttm_bo_api.h @@ -66,6 +66,26 @@ struct ttm_placement { const uint32_t *busy_placement; }; +/** + * struct ttm_bus_placement + * + * @addr: mapped virtual address + * @base: bus base address + * @is_iomem: is this io memory ? + * @size: size in byte + * @offset: offset from the base address + * + * Structure indicating the bus placement of an object. + */ +struct ttm_bus_placement { + void *addr; + unsigned long base; + unsigned long size; + unsigned long offset; + bool is_iomem; + bool io_reserved; +}; + /** * struct ttm_mem_reg @@ -75,6 +95,7 @@ struct ttm_placement { * @num_pages: Actual size of memory region in pages. * @page_alignment: Page alignment. * @placement: Placement flags. + * @bus: Placement on io bus accessible to the CPU * * Structure indicating the placement and space resources used by a * buffer object. @@ -87,6 +108,7 @@ struct ttm_mem_reg { uint32_t page_alignment; uint32_t mem_type; uint32_t placement; + struct ttm_bus_placement bus; }; /** @@ -274,6 +296,7 @@ struct ttm_bo_kmap_obj { ttm_bo_map_kmap = 3, ttm_bo_map_premapped = 4 | TTM_BO_MAP_IOMEM_MASK, } bo_kmap_type; + struct ttm_buffer_object *bo; }; /** diff --git a/include/drm/ttm/ttm_bo_driver.h b/include/drm/ttm/ttm_bo_driver.h index 69f70e418c2..da39865d67d 100644 --- a/include/drm/ttm/ttm_bo_driver.h +++ b/include/drm/ttm/ttm_bo_driver.h @@ -352,12 +352,21 @@ struct ttm_bo_driver { struct ttm_mem_reg *new_mem); /* notify the driver we are taking a fault on this BO * and have reserved it */ - void (*fault_reserve_notify)(struct ttm_buffer_object *bo); + int (*fault_reserve_notify)(struct ttm_buffer_object *bo); /** * notify the driver that we're about to swap out this bo */ void (*swap_notify) (struct ttm_buffer_object *bo); + + /** + * Driver callback on when mapping io memory (for bo_move_memcpy + * for instance). TTM will take care to call io_mem_free whenever + * the mapping is not use anymore. io_mem_reserve & io_mem_free + * are balanced. + */ + int (*io_mem_reserve)(struct ttm_bo_device *bdev, struct ttm_mem_reg *mem); + void (*io_mem_free)(struct ttm_bo_device *bdev, struct ttm_mem_reg *mem); }; /** @@ -685,6 +694,11 @@ extern int ttm_bo_pci_offset(struct ttm_bo_device *bdev, unsigned long *bus_offset, unsigned long *bus_size); +extern int ttm_mem_io_reserve(struct ttm_bo_device *bdev, + struct ttm_mem_reg *mem); +extern void ttm_mem_io_free(struct ttm_bo_device *bdev, + struct ttm_mem_reg *mem); + extern void ttm_bo_global_release(struct ttm_global_reference *ref); extern int ttm_bo_global_init(struct ttm_global_reference *ref); -- cgit v1.2.3-18-g5258 From 0c321c79627189204d7d0bf65ab19f5ac419abed Mon Sep 17 00:00:00 2001 From: Jerome Glisse Date: Wed, 7 Apr 2010 10:21:27 +0000 Subject: drm/ttm: remove io_ field from TTM V6 All TTM driver have been converted to new io_mem_reserve/free interface which allow driver to choose and return proper io base, offset to core TTM for ioremapping if necessary. This patch remove what is now deadcode. V2 adapt to match with change in first patch of the patchset V3 update after io_mem_reserve/io_mem_free callback balancing V4 adjust to minor cleanup V5 remove the needs ioremap flag V6 keep the ioremapping facility in TTM [airlied- squashed driver removals in here also] Signed-off-by: Jerome Glisse Reviewed-by: Thomas Hellstrom Signed-off-by: Dave Airlie --- include/drm/ttm/ttm_bo_driver.h | 12 ------------ 1 file changed, 12 deletions(-) (limited to 'include') diff --git a/include/drm/ttm/ttm_bo_driver.h b/include/drm/ttm/ttm_bo_driver.h index da39865d67d..7720b1787e2 100644 --- a/include/drm/ttm/ttm_bo_driver.h +++ b/include/drm/ttm/ttm_bo_driver.h @@ -176,8 +176,6 @@ struct ttm_tt { #define TTM_MEMTYPE_FLAG_FIXED (1 << 0) /* Fixed (on-card) PCI memory */ #define TTM_MEMTYPE_FLAG_MAPPABLE (1 << 1) /* Memory mappable */ -#define TTM_MEMTYPE_FLAG_NEEDS_IOREMAP (1 << 2) /* Fixed memory needs ioremap - before kernel access. */ #define TTM_MEMTYPE_FLAG_CMA (1 << 3) /* Can't map aperture */ /** @@ -189,13 +187,6 @@ struct ttm_tt { * managed by this memory type. * @gpu_offset: If used, the GPU offset of the first managed page of * fixed memory or the first managed location in an aperture. - * @io_offset: The io_offset of the first managed page of IO memory or - * the first managed location in an aperture. For TTM_MEMTYPE_FLAG_CMA - * memory, this should be set to NULL. - * @io_size: The size of a managed IO region (fixed memory or aperture). - * @io_addr: Virtual kernel address if the io region is pre-mapped. For - * TTM_MEMTYPE_FLAG_NEEDS_IOREMAP there is no pre-mapped io map and - * @io_addr should be set to NULL. * @size: Size of the managed region. * @available_caching: A mask of available caching types, TTM_PL_FLAG_XX, * as defined in ttm_placement_common.h @@ -221,9 +212,6 @@ struct ttm_mem_type_manager { bool use_type; uint32_t flags; unsigned long gpu_offset; - unsigned long io_offset; - unsigned long io_size; - void *io_addr; uint64_t size; uint32_t available_caching; uint32_t default_caching; -- cgit v1.2.3-18-g5258 From 96525a2f7448c427bb8d99240907a6bd2d9e818c Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Fri, 14 May 2010 13:06:19 +0200 Subject: drm_edid: There should be 6 Standard Timings Smatch complained that we initialize 6 elements in add_detailed_modes() but the timings[] array is declared with 5 elements. Adam Jackson verified that 6 is the correct number of timings. On Mon, May 10, 2010 at 12:08:24PM -0400, Adam Jackson wrote: > > > struct std_timing timings[5]; > > > ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ > > This decl is wrong, should be 6. From the 1.4 spec: > > "Six additional Standard Timings may be listed as a display descriptor > (tag #FAh)." > > The 1.3 spec is a little less explicit about it, but does show 6 > standard timing codes in the 0xFA detailed subblock, terminated by 0x0A > in the 18th byte. I don't have the docs for 1.2 or earlier, but we're > paranoid enough about not adding broken timings that we should be fine. This patch is basically a clean up, because timings[] is declared inside a union and increasing the number of elements here doesn't change the overall size of the union. Signed-off-by: Dan Carpenter Signed-off-by: Dave Airlie --- include/drm/drm_edid.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include') diff --git a/include/drm/drm_edid.h b/include/drm/drm_edid.h index d33c3e03860..39e2cc5c7e6 100644 --- a/include/drm/drm_edid.h +++ b/include/drm/drm_edid.h @@ -120,7 +120,7 @@ struct detailed_non_pixel { struct detailed_data_string str; struct detailed_data_monitor_range range; struct detailed_data_wpindex color; - struct std_timing timings[5]; + struct std_timing timings[6]; struct cvt_timing cvt[4]; } data; } __attribute__((packed)); -- cgit v1.2.3-18-g5258 From bc35afdb182d4c48c889fe27ba7a5d7ea0c8194d Mon Sep 17 00:00:00 2001 From: Jerome Glisse Date: Wed, 12 May 2010 18:01:13 +0200 Subject: drm/radeon/kms: add query for crtc hw id from crtc id to get info V2 Userspace need to know the hw crtc id (0, 1, 2, ...) from the drm crtc id. Bump the minor version so userspace can enable conditionaly features depend on this. V2 use num_crtc and avoid DRM_ERROR Signed-off-by: Jerome Glisse Signed-off-by: Dave Airlie --- include/drm/radeon_drm.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include') diff --git a/include/drm/radeon_drm.h b/include/drm/radeon_drm.h index 81e614bf2dc..3ff9fc071df 100644 --- a/include/drm/radeon_drm.h +++ b/include/drm/radeon_drm.h @@ -902,6 +902,7 @@ struct drm_radeon_cs { #define RADEON_INFO_NUM_GB_PIPES 0x01 #define RADEON_INFO_NUM_Z_PIPES 0x02 #define RADEON_INFO_ACCEL_WORKING 0x03 +#define RADEON_INFO_CRTC_FROM_ID 0x04 struct drm_radeon_info { uint32_t request; -- cgit v1.2.3-18-g5258 From 1471ca9aa71cd37b6a7476bb6f06a3a8622ea1bd Mon Sep 17 00:00:00 2001 From: Marcin Slusarz Date: Sun, 16 May 2010 17:27:03 +0200 Subject: fbdev: allow passing more than one aperture for handoff It removes a hack from nouveau code which had to detect which region to pass to kick vesafb/efifb. Signed-off-by: Marcin Slusarz Cc: Eric Anholt Cc: Ben Skeggs Cc: Thomas Hellstrom Cc: Dave Airlie Cc: Peter Jones Cc: Benjamin Herrenschmidt Signed-off-by: Dave Airlie --- include/linux/fb.h | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) (limited to 'include') diff --git a/include/linux/fb.h b/include/linux/fb.h index c10163b4c40..de5ff5fa838 100644 --- a/include/linux/fb.h +++ b/include/linux/fb.h @@ -403,6 +403,7 @@ struct fb_cursor { #include #include #include +#include #include struct vm_area_struct; @@ -862,10 +863,22 @@ struct fb_info { /* we need the PCI or similiar aperture base/size not smem_start/size as smem_start may just be an object allocated inside the aperture so may not actually overlap */ - resource_size_t aperture_base; - resource_size_t aperture_size; + struct apertures_struct { + unsigned int count; + struct aperture { + resource_size_t base; + resource_size_t size; + } ranges[0]; + } *apertures; }; +static inline struct apertures_struct *alloc_apertures(unsigned int max_num) { + struct apertures_struct *a = kzalloc(sizeof(struct apertures_struct) + + max_num * sizeof(struct aperture), GFP_KERNEL); + a->count = max_num; + return a; +} + #ifdef MODULE #define FBINFO_DEFAULT FBINFO_MODULE #else -- cgit v1.2.3-18-g5258 From 06415c564fb98562a4d6b6215615deb2d1cc0dae Mon Sep 17 00:00:00 2001 From: Marcin Slusarz Date: Sun, 16 May 2010 17:29:56 +0200 Subject: fbmem, drm/nouveau: kick firmware framebuffers as soon as possible Currently vesafb/efifb/... is kicked when hardware driver is registering framebuffer. To do it hardware must be fully functional, so there's a short window between start of initialisation and framebuffer registration when two drivers touch the hardware. Unfortunately sometimes it breaks nouveau initialisation. Fix it by kicking firmware driver(s) before we start touching the hardware. Reported-by: Didier Spaier Tested-by: Didier Spaier Signed-off-by: Marcin Slusarz Cc: Ben Skeggs Cc: Peter Jones Cc: Andrew Morton Signed-off-by: Dave Airlie --- include/linux/fb.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include') diff --git a/include/linux/fb.h b/include/linux/fb.h index de5ff5fa838..f88e2549123 100644 --- a/include/linux/fb.h +++ b/include/linux/fb.h @@ -971,6 +971,7 @@ extern ssize_t fb_sys_write(struct fb_info *info, const char __user *buf, /* drivers/video/fbmem.c */ extern int register_framebuffer(struct fb_info *fb_info); extern int unregister_framebuffer(struct fb_info *fb_info); +extern void remove_conflicting_framebuffers(struct apertures_struct *a, const char *name); extern int fb_prepare_logo(struct fb_info *fb_info, int rotate); extern int fb_show_logo(struct fb_info *fb_info, int rotate); extern char* fb_get_buffer_offset(struct fb_info *info, struct fb_pixmap *buf, u32 size); -- cgit v1.2.3-18-g5258 From 3b9676e7ac6eff4f50f1b48b6c36664f55b79507 Mon Sep 17 00:00:00 2001 From: Marcin Slusarz Date: Sun, 16 May 2010 17:33:09 +0200 Subject: vga16fb, drm: vga16fb->drm handoff let vga16fb claim 0xA0000+0x10000 region as its aperture; drm drivers don't use it, so we have to detect it and kick vga16fb manually - but only if drm is driving the primary card Signed-off-by: Marcin Slusarz Cc: James Simmons Cc: Dave Airlie Cc: Ben Skeggs Signed-off-by: Dave Airlie --- include/linux/fb.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/include/linux/fb.h b/include/linux/fb.h index f88e2549123..1296af45169 100644 --- a/include/linux/fb.h +++ b/include/linux/fb.h @@ -971,7 +971,8 @@ extern ssize_t fb_sys_write(struct fb_info *info, const char __user *buf, /* drivers/video/fbmem.c */ extern int register_framebuffer(struct fb_info *fb_info); extern int unregister_framebuffer(struct fb_info *fb_info); -extern void remove_conflicting_framebuffers(struct apertures_struct *a, const char *name); +extern void remove_conflicting_framebuffers(struct apertures_struct *a, + const char *name, bool primary); extern int fb_prepare_logo(struct fb_info *fb_info, int rotate); extern int fb_show_logo(struct fb_info *fb_info, int rotate); extern char* fb_get_buffer_offset(struct fb_info *info, struct fb_pixmap *buf, u32 size); -- cgit v1.2.3-18-g5258 From eb1f8e4f3be898df808e2dfc131099f5831d491d Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Fri, 7 May 2010 06:42:51 +0000 Subject: drm/fbdev: rework output polling to be back in the core. (v4) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit After thinking it over a lot it made more sense for the core to deal with the output polling especially so it can notify X. v2: drop plans for fake connector - per Michel's comments - fix X patch sent to xorg-devel, add intel polled/hpd setting, add initial nouveau polled/hpd settings. v3: add config lock take inside polling, add intel/nouveau poll init/fini calls v4: config lock was a bit agressive, only needed around connector list reading. otherwise it could re-enter. glisse: discard drm_helper_hpd_irq_event v3: Reviewed-by: Michel Dänzer Signed-off-by: Dave Airlie --- include/drm/drm_crtc.h | 17 +++++++++++++++++ include/drm/drm_crtc_helper.h | 3 +++ include/drm/drm_fb_helper.h | 13 ++----------- 3 files changed, 22 insertions(+), 11 deletions(-) (limited to 'include') diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h index c560364663a..2e4bf92faa8 100644 --- a/include/drm/drm_crtc.h +++ b/include/drm/drm_crtc.h @@ -31,6 +31,7 @@ #include #include +#include struct drm_device; struct drm_mode_set; @@ -460,6 +461,15 @@ enum drm_connector_force { DRM_FORCE_ON_DIGITAL, /* for DVI-I use digital connector */ }; +/* should we poll this connector for connects and disconnects */ +/* hot plug detectable */ +#define DRM_CONNECTOR_POLL_HPD (1 << 0) +/* poll for connections */ +#define DRM_CONNECTOR_POLL_CONNECT (1 << 1) +/* can cleanly poll for disconnections without flickering the screen */ +/* DACs should rarely do this without a lot of testing */ +#define DRM_CONNECTOR_POLL_DISCONNECT (1 << 2) + /** * drm_connector - central DRM connector control structure * @crtc: CRTC this connector is currently connected to, NULL if none @@ -504,6 +514,8 @@ struct drm_connector { u32 property_ids[DRM_CONNECTOR_MAX_PROPERTY]; uint64_t property_values[DRM_CONNECTOR_MAX_PROPERTY]; + uint8_t polled; /* DRM_CONNECTOR_POLL_* */ + /* requested DPMS state */ int dpms; @@ -543,6 +555,7 @@ struct drm_mode_set { */ struct drm_mode_config_funcs { struct drm_framebuffer *(*fb_create)(struct drm_device *dev, struct drm_file *file_priv, struct drm_mode_fb_cmd *mode_cmd); + void (*output_poll_changed)(struct drm_device *dev); }; struct drm_mode_group { @@ -580,6 +593,10 @@ struct drm_mode_config { struct drm_mode_config_funcs *funcs; resource_size_t fb_base; + /* output poll support */ + bool poll_enabled; + struct delayed_slow_work output_poll_slow_work; + /* pointers to standard properties */ struct list_head property_blob_list; struct drm_property *edid_property; diff --git a/include/drm/drm_crtc_helper.h b/include/drm/drm_crtc_helper.h index b1fa0f8cfa6..dc5873c21e4 100644 --- a/include/drm/drm_crtc_helper.h +++ b/include/drm/drm_crtc_helper.h @@ -127,4 +127,7 @@ static inline void drm_connector_helper_add(struct drm_connector *connector, } extern int drm_helper_resume_force_mode(struct drm_device *dev); +extern void drm_kms_helper_poll_init(struct drm_device *dev); +extern void drm_kms_helper_poll_fini(struct drm_device *dev); +extern void drm_helper_hpd_irq_event(struct drm_device *dev); #endif diff --git a/include/drm/drm_fb_helper.h b/include/drm/drm_fb_helper.h index 9b55a94fead..f0a6afc47e7 100644 --- a/include/drm/drm_fb_helper.h +++ b/include/drm/drm_fb_helper.h @@ -30,8 +30,6 @@ #ifndef DRM_FB_HELPER_H #define DRM_FB_HELPER_H -#include - struct drm_fb_helper; struct drm_fb_helper_crtc { @@ -71,9 +69,6 @@ struct drm_fb_helper_funcs { int (*fb_probe)(struct drm_fb_helper *helper, struct drm_fb_helper_surface_size *sizes); - - void (*fb_output_status_changed)(struct drm_fb_helper *helper); - }; struct drm_fb_helper_connector { @@ -95,8 +90,6 @@ struct drm_fb_helper { u32 pseudo_palette[17]; struct list_head kernel_fb_list; - struct delayed_slow_work output_status_change_slow_work; - bool poll_enabled; /* we got a hotplug but fbdev wasn't running the console delay until next set_par */ bool delayed_hotplug; @@ -107,7 +100,7 @@ int drm_fb_helper_single_fb_probe(struct drm_fb_helper *helper, int drm_fb_helper_init(struct drm_device *dev, struct drm_fb_helper *helper, int crtc_count, - int max_conn, bool polled); + int max_conn); void drm_fb_helper_fini(struct drm_fb_helper *helper); int drm_fb_helper_blank(int blank, struct fb_info *info); int drm_fb_helper_pan_display(struct fb_var_screeninfo *var, @@ -130,10 +123,8 @@ void drm_fb_helper_fill_fix(struct fb_info *info, uint32_t pitch, int drm_fb_helper_setcmap(struct fb_cmap *cmap, struct fb_info *info); -bool drm_helper_fb_hotplug_event(struct drm_fb_helper *fb_helper, - bool polled); +bool drm_fb_helper_hotplug_event(struct drm_fb_helper *fb_helper); bool drm_fb_helper_initial_config(struct drm_fb_helper *fb_helper, int bpp_sel); int drm_fb_helper_single_add_all_connectors(struct drm_fb_helper *fb_helper); -void drm_helper_fb_hpd_irq_event(struct drm_fb_helper *fb_helper); #endif -- cgit v1.2.3-18-g5258 From 1d42bbc8f7f9ce4d852692ef7aa336b133b0830a Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Fri, 7 May 2010 05:02:30 +0000 Subject: drm/fbdev: fix cloning on fbcon Simple cloning rules compared to server: (a) single crtc (b) > 1 connector active (c) check command line mode (d) try and find 1024x768 DMT mode if no command line. (e) fail to clone Signed-off-by: Dave Airlie --- include/drm/drm_crtc.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include') diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h index 2e4bf92faa8..93a1a31b9c2 100644 --- a/include/drm/drm_crtc.h +++ b/include/drm/drm_crtc.h @@ -804,4 +804,6 @@ extern int drm_add_modes_noedid(struct drm_connector *connector, int hdisplay, int vdisplay); extern bool drm_edid_is_valid(struct edid *edid); +struct drm_display_mode *drm_mode_find_dmt(struct drm_device *dev, + int hsize, int vsize, int fresh); #endif /* __DRM_CRTC_H__ */ -- cgit v1.2.3-18-g5258 From 7c5ee5366f79f53de2a11e73953daee6d58df124 Mon Sep 17 00:00:00 2001 From: Matthew Garrett Date: Mon, 26 Apr 2010 16:00:09 -0400 Subject: ttm: Provide an API for starting and stopping the delayed workqueue We want to be able to prevent the delayed workqueue from changing state while we're reclocking, so add an API to block and unblock it. Signed-off-by: Matthew Garrett Signed-off-by: Dave Airlie --- include/drm/ttm/ttm_bo_api.h | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) (limited to 'include') diff --git a/include/drm/ttm/ttm_bo_api.h b/include/drm/ttm/ttm_bo_api.h index 3e273e0b941..267a86c74e2 100644 --- a/include/drm/ttm/ttm_bo_api.h +++ b/include/drm/ttm/ttm_bo_api.h @@ -361,6 +361,23 @@ extern int ttm_bo_validate(struct ttm_buffer_object *bo, */ extern void ttm_bo_unref(struct ttm_buffer_object **bo); +/** + * ttm_bo_lock_delayed_workqueue + * + * Prevent the delayed workqueue from running. + * Returns + * True if the workqueue was queued at the time + */ +extern int ttm_bo_lock_delayed_workqueue(struct ttm_bo_device *bdev); + +/** + * ttm_bo_unlock_delayed_workqueue + * + * Allows the delayed workqueue to run. + */ +extern void ttm_bo_unlock_delayed_workqueue(struct ttm_bo_device *bdev, + int resched); + /** * ttm_bo_synccpu_write_grab * -- cgit v1.2.3-18-g5258 From 68adac5e49436992e9c999fbae879d9ac5b72d4e Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 28 Apr 2010 11:46:42 +1000 Subject: drm: move radeon_fixed.h to shared drm_fixed.h header Will be used by nouveau driver also in the near future. Signed-off-by: Ben Skeggs Signed-off-by: Dave Airlie --- include/drm/drm_fixed.h | 67 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) create mode 100644 include/drm/drm_fixed.h (limited to 'include') diff --git a/include/drm/drm_fixed.h b/include/drm/drm_fixed.h new file mode 100644 index 00000000000..4a08a664ff1 --- /dev/null +++ b/include/drm/drm_fixed.h @@ -0,0 +1,67 @@ +/* + * Copyright 2009 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. + * + * Authors: Dave Airlie + */ +#ifndef DRM_FIXED_H +#define DRM_FIXED_H + +typedef union dfixed { + u32 full; +} fixed20_12; + + +#define dfixed_const(A) (u32)(((A) << 12))/* + ((B + 0.000122)*4096)) */ +#define dfixed_const_half(A) (u32)(((A) << 12) + 2048) +#define dfixed_const_666(A) (u32)(((A) << 12) + 2731) +#define dfixed_const_8(A) (u32)(((A) << 12) + 3277) +#define dfixed_mul(A, B) ((u64)((u64)(A).full * (B).full + 2048) >> 12) +#define dfixed_init(A) { .full = dfixed_const((A)) } +#define dfixed_init_half(A) { .full = dfixed_const_half((A)) } +#define dfixed_trunc(A) ((A).full >> 12) + +static inline u32 dfixed_floor(fixed20_12 A) +{ + u32 non_frac = dfixed_trunc(A); + + return dfixed_const(non_frac); +} + +static inline u32 dfixed_ceil(fixed20_12 A) +{ + u32 non_frac = dfixed_trunc(A); + + if (A.full > dfixed_const(non_frac)) + return dfixed_const(non_frac + 1); + else + return dfixed_const(non_frac); +} + +static inline u32 dfixed_div(fixed20_12 A, fixed20_12 B) +{ + u64 tmp = ((u64)A.full << 13); + + do_div(tmp, B.full); + tmp += 1; + tmp /= 2; + return lower_32_bits(tmp); +} +#endif -- cgit v1.2.3-18-g5258