hc
2024-01-05 071106ecf68c401173c58808b1cf5f68cc50d390
kernel/include/drm/drm_fb_helper.h
....@@ -36,21 +36,11 @@
3636 #include <drm/drm_crtc.h>
3737 #include <drm/drm_device.h>
3838 #include <linux/kgdb.h>
39
+#include <linux/vgaarb.h>
3940
4041 enum mode_set_atomic {
4142 LEAVE_ATOMIC_MODE_SET,
4243 ENTER_ATOMIC_MODE_SET,
43
-};
44
-
45
-struct drm_fb_offset {
46
- int x, y;
47
-};
48
-
49
-struct drm_fb_helper_crtc {
50
- struct drm_mode_set mode_set;
51
- struct drm_display_mode *desired_mode;
52
- int x, y;
53
- int rotation;
5444 };
5545
5646 /**
....@@ -67,10 +57,8 @@
6757 * according to the largest width/height (so it is large enough for all CRTCs
6858 * to scanout). But the fbdev width/height is sized to the minimum width/
6959 * height of all the displays. This ensures that fbcon fits on the smallest
70
- * of the attached displays.
71
- *
72
- * So what is passed to drm_fb_helper_fill_var() should be fb_width/fb_height,
73
- * rather than the surface size.
60
+ * of the attached displays. fb_width/fb_height is used by
61
+ * drm_fb_helper_fill_info() to fill out the &fb_info.var structure.
7462 */
7563 struct drm_fb_helper_surface_size {
7664 u32 fb_width;
....@@ -103,43 +91,12 @@
10391 */
10492 int (*fb_probe)(struct drm_fb_helper *helper,
10593 struct drm_fb_helper_surface_size *sizes);
106
-
107
- /**
108
- * @initial_config:
109
- *
110
- * Driver callback to setup an initial fbdev display configuration.
111
- * Drivers can use this callback to tell the fbdev emulation what the
112
- * preferred initial configuration is. This is useful to implement
113
- * smooth booting where the fbdev (and subsequently all userspace) never
114
- * changes the mode, but always inherits the existing configuration.
115
- *
116
- * This callback is optional.
117
- *
118
- * RETURNS:
119
- *
120
- * The driver should return true if a suitable initial configuration has
121
- * been filled out and false when the fbdev helper should fall back to
122
- * the default probing logic.
123
- */
124
- bool (*initial_config)(struct drm_fb_helper *fb_helper,
125
- struct drm_fb_helper_crtc **crtcs,
126
- struct drm_display_mode **modes,
127
- struct drm_fb_offset *offsets,
128
- bool *enabled, int width, int height);
129
-};
130
-
131
-struct drm_fb_helper_connector {
132
- struct drm_connector *connector;
13394 };
13495
13596 /**
13697 * struct drm_fb_helper - main structure to emulate fbdev on top of KMS
13798 * @fb: Scanout framebuffer object
13899 * @dev: DRM device
139
- * @crtc_count: number of possible CRTCs
140
- * @crtc_info: per-CRTC helper state (mode, x/y offset, etc)
141
- * @connector_count: number of connected connectors
142
- * @connector_info_alloc_count: size of connector_info
143100 * @funcs: driver callbacks for fb helper
144101 * @fbdev: emulated fbdev device info struct
145102 * @pseudo_palette: fake palette of 16 colors
....@@ -171,24 +128,6 @@
171128
172129 struct drm_framebuffer *fb;
173130 struct drm_device *dev;
174
- int crtc_count;
175
- struct drm_fb_helper_crtc *crtc_info;
176
- int connector_count;
177
- int connector_info_alloc_count;
178
- /**
179
- * @sw_rotations:
180
- * Bitmask of all rotations requested for panel-orientation which
181
- * could not be handled in hardware. If only one bit is set
182
- * fbdev->fbcon_rotate_hint gets set to the requested rotation.
183
- */
184
- int sw_rotations;
185
- /**
186
- * @connector_info:
187
- *
188
- * Array of per-connector information. Do not iterate directly, but use
189
- * drm_fb_helper_for_each_connector.
190
- */
191
- struct drm_fb_helper_connector **connector_info;
192131 const struct drm_fb_helper_funcs *funcs;
193132 struct fb_info *fbdev;
194133 u32 pseudo_palette[17];
....@@ -274,8 +213,7 @@
274213 #ifdef CONFIG_DRM_FBDEV_EMULATION
275214 void drm_fb_helper_prepare(struct drm_device *dev, struct drm_fb_helper *helper,
276215 const struct drm_fb_helper_funcs *funcs);
277
-int drm_fb_helper_init(struct drm_device *dev,
278
- struct drm_fb_helper *helper, int max_conn);
216
+int drm_fb_helper_init(struct drm_device *dev, struct drm_fb_helper *helper);
279217 void drm_fb_helper_fini(struct drm_fb_helper *helper);
280218 int drm_fb_helper_blank(int blank, struct fb_info *info);
281219 int drm_fb_helper_pan_display(struct fb_var_screeninfo *var,
....@@ -288,16 +226,12 @@
288226
289227 struct fb_info *drm_fb_helper_alloc_fbi(struct drm_fb_helper *fb_helper);
290228 void drm_fb_helper_unregister_fbi(struct drm_fb_helper *fb_helper);
291
-void drm_fb_helper_fill_var(struct fb_info *info, struct drm_fb_helper *fb_helper,
292
- uint32_t fb_width, uint32_t fb_height);
293
-void drm_fb_helper_fill_fix(struct fb_info *info, uint32_t pitch,
294
- uint32_t depth);
295
-
296
-void drm_fb_helper_unlink_fbi(struct drm_fb_helper *fb_helper);
229
+void drm_fb_helper_fill_info(struct fb_info *info,
230
+ struct drm_fb_helper *fb_helper,
231
+ struct drm_fb_helper_surface_size *sizes);
297232
298233 void drm_fb_helper_deferred_io(struct fb_info *info,
299234 struct list_head *pagelist);
300
-int drm_fb_helper_defio_init(struct drm_fb_helper *fb_helper);
301235
302236 ssize_t drm_fb_helper_sys_read(struct fb_info *info, char __user *buf,
303237 size_t count, loff_t *ppos);
....@@ -329,32 +263,14 @@
329263
330264 int drm_fb_helper_hotplug_event(struct drm_fb_helper *fb_helper);
331265 int drm_fb_helper_initial_config(struct drm_fb_helper *fb_helper, int bpp_sel);
332
-int drm_fb_helper_single_add_all_connectors(struct drm_fb_helper *fb_helper);
333266 int drm_fb_helper_debug_enter(struct fb_info *info);
334267 int drm_fb_helper_debug_leave(struct fb_info *info);
335
-struct drm_display_mode *
336
-drm_has_preferred_mode(struct drm_fb_helper_connector *fb_connector,
337
- int width, int height);
338
-struct drm_display_mode *
339
-drm_pick_cmdline_mode(struct drm_fb_helper_connector *fb_helper_conn);
340
-
341
-int drm_fb_helper_add_one_connector(struct drm_fb_helper *fb_helper, struct drm_connector *connector);
342
-int drm_fb_helper_remove_one_connector(struct drm_fb_helper *fb_helper,
343
- struct drm_connector *connector);
344
-
345
-int drm_fb_helper_fbdev_setup(struct drm_device *dev,
346
- struct drm_fb_helper *fb_helper,
347
- const struct drm_fb_helper_funcs *funcs,
348
- unsigned int preferred_bpp,
349
- unsigned int max_conn_count);
350
-void drm_fb_helper_fbdev_teardown(struct drm_device *dev);
351268
352269 void drm_fb_helper_lastclose(struct drm_device *dev);
353270 void drm_fb_helper_output_poll_changed(struct drm_device *dev);
354271
355
-int drm_fb_helper_generic_probe(struct drm_fb_helper *fb_helper,
356
- struct drm_fb_helper_surface_size *sizes);
357
-int drm_fbdev_generic_setup(struct drm_device *dev, unsigned int preferred_bpp);
272
+void drm_fbdev_generic_setup(struct drm_device *dev,
273
+ unsigned int preferred_bpp);
358274 #else
359275 static inline void drm_fb_helper_prepare(struct drm_device *dev,
360276 struct drm_fb_helper *helper,
....@@ -363,8 +279,7 @@
363279 }
364280
365281 static inline int drm_fb_helper_init(struct drm_device *dev,
366
- struct drm_fb_helper *helper,
367
- int max_conn)
282
+ struct drm_fb_helper *helper)
368283 {
369284 /* So drivers can use it to free the struct */
370285 helper->dev = dev;
....@@ -417,14 +332,10 @@
417332 {
418333 }
419334
420
-static inline void drm_fb_helper_fill_var(struct fb_info *info,
421
- struct drm_fb_helper *fb_helper,
422
- uint32_t fb_width, uint32_t fb_height)
423
-{
424
-}
425
-
426
-static inline void drm_fb_helper_fill_fix(struct fb_info *info, uint32_t pitch,
427
- uint32_t depth)
335
+static inline void
336
+drm_fb_helper_fill_info(struct fb_info *info,
337
+ struct drm_fb_helper *fb_helper,
338
+ struct drm_fb_helper_surface_size *sizes)
428339 {
429340 }
430341
....@@ -438,10 +349,6 @@
438349 unsigned long arg)
439350 {
440351 return 0;
441
-}
442
-
443
-static inline void drm_fb_helper_unlink_fbi(struct drm_fb_helper *fb_helper)
444
-{
445352 }
446353
447354 static inline void drm_fb_helper_deferred_io(struct fb_info *info,
....@@ -519,12 +426,6 @@
519426 return 0;
520427 }
521428
522
-static inline int
523
-drm_fb_helper_single_add_all_connectors(struct drm_fb_helper *fb_helper)
524
-{
525
- return 0;
526
-}
527
-
528429 static inline int drm_fb_helper_debug_enter(struct fb_info *info)
529430 {
530431 return 0;
....@@ -535,52 +436,6 @@
535436 return 0;
536437 }
537438
538
-static inline struct drm_display_mode *
539
-drm_has_preferred_mode(struct drm_fb_helper_connector *fb_connector,
540
- int width, int height)
541
-{
542
- return NULL;
543
-}
544
-
545
-static inline struct drm_display_mode *
546
-drm_pick_cmdline_mode(struct drm_fb_helper_connector *fb_helper_conn,
547
- int width, int height)
548
-{
549
- return NULL;
550
-}
551
-
552
-static inline int
553
-drm_fb_helper_add_one_connector(struct drm_fb_helper *fb_helper,
554
- struct drm_connector *connector)
555
-{
556
- return 0;
557
-}
558
-
559
-static inline int
560
-drm_fb_helper_remove_one_connector(struct drm_fb_helper *fb_helper,
561
- struct drm_connector *connector)
562
-{
563
- return 0;
564
-}
565
-
566
-static inline int
567
-drm_fb_helper_fbdev_setup(struct drm_device *dev,
568
- struct drm_fb_helper *fb_helper,
569
- const struct drm_fb_helper_funcs *funcs,
570
- unsigned int preferred_bpp,
571
- unsigned int max_conn_count)
572
-{
573
- /* So drivers can use it to free the struct */
574
- dev->fb_helper = fb_helper;
575
-
576
- return 0;
577
-}
578
-
579
-static inline void drm_fb_helper_fbdev_teardown(struct drm_device *dev)
580
-{
581
- dev->fb_helper = NULL;
582
-}
583
-
584439 static inline void drm_fb_helper_lastclose(struct drm_device *dev)
585440 {
586441 }
....@@ -589,21 +444,23 @@
589444 {
590445 }
591446
592
-static inline int
593
-drm_fb_helper_generic_probe(struct drm_fb_helper *fb_helper,
594
- struct drm_fb_helper_surface_size *sizes)
595
-{
596
- return 0;
597
-}
598
-
599
-static inline int
447
+static inline void
600448 drm_fbdev_generic_setup(struct drm_device *dev, unsigned int preferred_bpp)
601449 {
602
- return 0;
603450 }
604451
605452 #endif
606453
454
+/**
455
+ * drm_fb_helper_remove_conflicting_framebuffers - remove firmware-configured framebuffers
456
+ * @a: memory range, users of which are to be removed
457
+ * @name: requesting driver name
458
+ * @primary: also kick vga16fb if present
459
+ *
460
+ * This function removes framebuffer devices (initialized by firmware/bootloader)
461
+ * which use memory range described by @a. If @a is NULL all such devices are
462
+ * removed.
463
+ */
607464 static inline int
608465 drm_fb_helper_remove_conflicting_framebuffers(struct apertures_struct *a,
609466 const char *name, bool primary)
....@@ -615,4 +472,33 @@
615472 #endif
616473 }
617474
475
+/**
476
+ * drm_fb_helper_remove_conflicting_pci_framebuffers - remove firmware-configured framebuffers for PCI devices
477
+ * @pdev: PCI device
478
+ * @name: requesting driver name
479
+ *
480
+ * This function removes framebuffer devices (eg. initialized by firmware)
481
+ * using memory range configured for any of @pdev's memory bars.
482
+ *
483
+ * The function assumes that PCI device with shadowed ROM drives a primary
484
+ * display and so kicks out vga16fb.
485
+ */
486
+static inline int
487
+drm_fb_helper_remove_conflicting_pci_framebuffers(struct pci_dev *pdev,
488
+ const char *name)
489
+{
490
+ int ret = 0;
491
+
492
+ /*
493
+ * WARNING: Apparently we must kick fbdev drivers before vgacon,
494
+ * otherwise the vga fbdev driver falls over.
495
+ */
496
+#if IS_REACHABLE(CONFIG_FB)
497
+ ret = remove_conflicting_pci_framebuffers(pdev, name);
498
+#endif
499
+ if (ret == 0)
500
+ ret = vga_remove_vgacon(pdev);
501
+ return ret;
502
+}
503
+
618504 #endif