@@ -2118,9 +2118,11 @@ static int amdgpu_pci_probe(struct pci_dev *pdev,
!list_empty(&adev_to_drm(adev)->mode_config.connector_list)) {
/* select 8 bpp console on low vram cards */
if (adev->gmc.real_vram_size <= (32*1024*1024))
- drm_fbdev_generic_setup(adev_to_drm(adev), 8);
+ drm_fbdev_generic_setup(adev_to_drm(adev),
+ DRM_FB_OPTION(DRM_FB_BPP, 8));
else
- drm_fbdev_generic_setup(adev_to_drm(adev), 32);
+ drm_fbdev_generic_setup(adev_to_drm(adev),
+ DRM_FB_OPTION(DRM_FB_BPP, 32));
}
ret = amdgpu_debugfs_init(adev);
@@ -321,7 +321,7 @@ static int hdlcd_drm_bind(struct device *dev)
if (ret)
goto err_register;
- drm_fbdev_generic_setup(drm, 32);
+ drm_fbdev_generic_setup(drm, DRM_FB_OPTION(DRM_FB_BPP, 32));
return 0;
@@ -863,7 +863,7 @@ static int malidp_bind(struct device *dev)
if (ret)
goto register_fail;
- drm_fbdev_generic_setup(drm, 32);
+ drm_fbdev_generic_setup(drm, DRM_FB_OPTION(DRM_FB_BPP, 32));
return 0;
@@ -343,7 +343,7 @@ static int aspeed_gfx_probe(struct platform_device *pdev)
if (ret)
goto err_unload;
- drm_fbdev_generic_setup(&priv->drm, 32);
+ drm_fbdev_generic_setup(&priv->drm, DRM_FB_OPTION(DRM_FB_BPP, 32));
return 0;
err_unload:
@@ -126,7 +126,7 @@ static int ast_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
if (ret)
return ret;
- drm_fbdev_generic_setup(dev, 32);
+ drm_fbdev_generic_setup(dev, DRM_FB_OPTION(DRM_FB_BPP, 32));
return 0;
}
@@ -760,7 +760,7 @@ static int atmel_hlcdc_dc_drm_probe(struct platform_device *pdev)
if (ret)
goto err_unload;
- drm_fbdev_generic_setup(ddev, 24);
+ drm_fbdev_generic_setup(ddev, DRM_FB_OPTION(DRM_FB_BPP, 24));
return 0;
@@ -324,7 +324,7 @@ void drm_minor_release(struct drm_minor *minor)
* if (ret)
* return ret;
*
- * drm_fbdev_generic_setup(drm, 32);
+ * drm_fbdev_generic_setup(drm, DRM_FB_OPTION(DRM_FB_BPP, 32));
*
* return 0;
* }
@@ -2501,8 +2501,17 @@ static const struct drm_client_funcs drm_fbdev_client_funcs = {
/**
* drm_fbdev_generic_setup() - Setup generic fbdev emulation
* @dev: DRM device
- * @preferred_bpp: Preferred bits per pixel for the device.
- * @dev->mode_config.preferred_depth is used if this is zero.
+ * @options: options for the registered framebuffer.
+ *
+ * The @options parameter is a multi-field parameter that can contain
+ * different options for the emulated framebuffer device registered.
+ *
+ * The options field values can be set using DRM_FB_OPTION() to compute
+ * the value according to the option bitfield and can be obtained using
+ * DRM_FB_GET_OPTION(). The options fields are the following:
+ *
+ * * DRM_FB_BPP: bits per pixel for the device. If the field is not set,
+ * @dev->mode_config.preferred_depth is used instead.
*
* This function sets up generic fbdev emulation for drivers that supports
* dumb buffers with a virtual address and that can be mmap'ed.
@@ -2525,8 +2534,7 @@ static const struct drm_client_funcs drm_fbdev_client_funcs = {
*
* The fbdev is destroyed by drm_dev_unregister().
*/
-void drm_fbdev_generic_setup(struct drm_device *dev,
- unsigned int preferred_bpp)
+void drm_fbdev_generic_setup(struct drm_device *dev, const unsigned int options)
{
struct drm_fb_helper *fb_helper;
int ret;
@@ -2555,11 +2563,11 @@ void drm_fbdev_generic_setup(struct drm_device *dev,
* mess, resulting in some drivers picking wrong fbdev defaults and
* others wrong preferred_depth defaults.
*/
- if (!preferred_bpp)
- preferred_bpp = dev->mode_config.preferred_depth;
- if (!preferred_bpp)
- preferred_bpp = 32;
- fb_helper->preferred_bpp = preferred_bpp;
+ fb_helper->preferred_bpp = DRM_FB_GET_OPTION(DRM_FB_BPP, options);
+ if (!fb_helper->preferred_bpp)
+ fb_helper->preferred_bpp = dev->mode_config.preferred_depth;
+ if (!fb_helper->preferred_bpp)
+ fb_helper->preferred_bpp = 32;
ret = drm_fbdev_client_hotplug(&fb_helper->client);
if (ret)
@@ -334,7 +334,7 @@ static int fsl_dcu_drm_probe(struct platform_device *pdev)
if (ret < 0)
goto put;
- drm_fbdev_generic_setup(drm, legacyfb_depth);
+ drm_fbdev_generic_setup(drm, DRM_FB_OPTION(DRM_FB_BPP, legacyfb_depth));
return 0;
@@ -237,7 +237,7 @@ static int kirin_drm_bind(struct device *dev)
if (ret)
goto err_kms_cleanup;
- drm_fbdev_generic_setup(drm_dev, 32);
+ drm_fbdev_generic_setup(drm_dev, DRM_FB_OPTION(DRM_FB_BPP, 32));
return 0;
@@ -148,7 +148,7 @@ struct dcss_kms_dev *dcss_kms_attach(struct dcss_dev *dcss)
if (ret)
goto cleanup_crtc;
- drm_fbdev_generic_setup(drm, 32);
+ drm_fbdev_generic_setup(drm, DRM_FB_OPTION(DRM_FB_BPP, 32));
return kms;
@@ -251,7 +251,7 @@ static int imx_drm_bind(struct device *dev)
if (ret)
goto err_poll_fini;
- drm_fbdev_generic_setup(drm, legacyfb_depth);
+ drm_fbdev_generic_setup(drm, DRM_FB_OPTION(DRM_FB_BPP, legacyfb_depth));
return 0;
@@ -1388,7 +1388,7 @@ static int ingenic_drm_bind(struct device *dev, bool has_components)
goto err_clk_notifier_unregister;
}
- drm_fbdev_generic_setup(drm, 32);
+ drm_fbdev_generic_setup(drm, DRM_FB_OPTION(DRM_FB_BPP, 32));
return 0;
@@ -238,7 +238,7 @@ static int mcde_drm_bind(struct device *dev)
if (ret < 0)
goto unbind;
- drm_fbdev_generic_setup(drm, 32);
+ drm_fbdev_generic_setup(drm, DRM_FB_OPTION(DRM_FB_BPP, 32));
return 0;
@@ -393,7 +393,7 @@ static int mtk_drm_bind(struct device *dev)
if (ret < 0)
goto err_deinit;
- drm_fbdev_generic_setup(drm, 32);
+ drm_fbdev_generic_setup(drm, DRM_FB_OPTION(DRM_FB_BPP, 32));
return 0;
@@ -350,7 +350,7 @@ static int meson_drv_bind_master(struct device *dev, bool has_components)
if (ret)
goto uninstall_irq;
- drm_fbdev_generic_setup(drm, 32);
+ drm_fbdev_generic_setup(drm, DRM_FB_OPTION(DRM_FB_BPP, 32));
return 0;
@@ -357,7 +357,7 @@ static int mxsfb_probe(struct platform_device *pdev)
if (ret)
goto err_unload;
- drm_fbdev_generic_setup(drm, 32);
+ drm_fbdev_generic_setup(drm, DRM_FB_OPTION(DRM_FB_BPP, 32));
return 0;
@@ -308,7 +308,7 @@ static int pl111_amba_probe(struct amba_device *amba_dev,
if (ret < 0)
goto dev_put;
- drm_fbdev_generic_setup(drm, priv->variant->fb_bpp);
+ drm_fbdev_generic_setup(drm, DRM_FB_OPTION(DRM_FB_BPP, priv->variant->fb_bpp));
return 0;
@@ -122,7 +122,7 @@ qxl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
if (ret)
goto modeset_cleanup;
- drm_fbdev_generic_setup(&qdev->ddev, 32);
+ drm_fbdev_generic_setup(&qdev->ddev, DRM_FB_OPTION(DRM_FB_BPP, 32));
return 0;
modeset_cleanup:
@@ -681,7 +681,7 @@ static int rcar_du_probe(struct platform_device *pdev)
DRM_INFO("Device %s probed\n", dev_name(&pdev->dev));
- drm_fbdev_generic_setup(&rcdu->ddev, 32);
+ drm_fbdev_generic_setup(&rcdu->ddev, DRM_FB_OPTION(DRM_FB_BPP, 32));
return 0;
@@ -200,7 +200,7 @@ static int sti_bind(struct device *dev)
drm_mode_config_reset(ddev);
- drm_fbdev_generic_setup(ddev, 32);
+ drm_fbdev_generic_setup(ddev, DRM_FB_OPTION(DRM_FB_BPP, 32));
return 0;
@@ -203,7 +203,7 @@ static int stm_drm_platform_probe(struct platform_device *pdev)
if (ret)
goto err_put;
- drm_fbdev_generic_setup(ddev, 16);
+ drm_fbdev_generic_setup(ddev, DRM_FB_OPTION(DRM_FB_BPP, 16));
return 0;
@@ -112,7 +112,7 @@ static int sun4i_drv_bind(struct device *dev)
if (ret)
goto finish_poll;
- drm_fbdev_generic_setup(drm, 32);
+ drm_fbdev_generic_setup(drm, DRM_FB_OPTION(DRM_FB_BPP, 32));
return 0;
@@ -180,7 +180,7 @@ static int tidss_probe(struct platform_device *pdev)
goto err_irq_uninstall;
}
- drm_fbdev_generic_setup(ddev, 32);
+ drm_fbdev_generic_setup(ddev, DRM_FB_OPTION(DRM_FB_BPP, 32));
dev_dbg(dev, "%s done\n", __func__);
@@ -384,7 +384,7 @@ static int tilcdc_init(const struct drm_driver *ddrv, struct device *dev)
goto init_failed;
priv->is_registered = true;
- drm_fbdev_generic_setup(ddev, bpp);
+ drm_fbdev_generic_setup(ddev, DRM_FB_OPTION(DRM_FB_BPP, bpp));
return 0;
init_failed:
@@ -392,7 +392,7 @@ static int arcpgu_probe(struct platform_device *pdev)
if (ret)
goto err_unload;
- drm_fbdev_generic_setup(&arcpgu->drm, 16);
+ drm_fbdev_generic_setup(&arcpgu->drm, DRM_FB_OPTION(DRM_FB_BPP, 16));
return 0;
@@ -663,7 +663,7 @@ static int bochs_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent
if (ret)
goto err_free_dev;
- drm_fbdev_generic_setup(dev, 32);
+ drm_fbdev_generic_setup(dev, DRM_FB_OPTION(DRM_FB_BPP, 32));
return ret;
err_free_dev:
@@ -226,7 +226,7 @@ static int tve200_probe(struct platform_device *pdev)
* Passing in 16 here will make the RGB565 mode the default
* Passing in 32 will use XRGB8888 mode
*/
- drm_fbdev_generic_setup(drm, 16);
+ drm_fbdev_generic_setup(drm, DRM_FB_OPTION(DRM_FB_BPP, 16));
return 0;
@@ -79,7 +79,7 @@ static int vbox_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
if (ret)
goto err_irq_fini;
- drm_fbdev_generic_setup(&vbox->ddev, 32);
+ drm_fbdev_generic_setup(&vbox->ddev, DRM_FB_OPTION(DRM_FB_BPP, 32));
return 0;
@@ -291,7 +291,7 @@ static int vc4_drm_bind(struct device *dev)
if (ret < 0)
goto unbind_all;
- drm_fbdev_generic_setup(drm, 16);
+ drm_fbdev_generic_setup(drm, DRM_FB_OPTION(DRM_FB_BPP, 16));
return 0;
@@ -128,7 +128,7 @@ static int virtio_gpu_probe(struct virtio_device *vdev)
if (ret)
goto err_deinit;
- drm_fbdev_generic_setup(vdev->priv, 32);
+ drm_fbdev_generic_setup(vdev->priv, DRM_FB_OPTION(DRM_FB_BPP, 32));
return 0;
err_deinit:
@@ -135,7 +135,7 @@ static int zynqmp_dpsub_drm_init(struct zynqmp_dpsub *dpsub)
goto err_poll_fini;
/* Initialize fbdev generic emulation. */
- drm_fbdev_generic_setup(drm, 24);
+ drm_fbdev_generic_setup(drm, DRM_FB_OPTION(DRM_FB_BPP, 24));
return 0;
@@ -35,6 +35,7 @@ struct drm_fb_helper;
#include <drm/drm_client.h>
#include <drm/drm_crtc.h>
#include <drm/drm_device.h>
+#include <linux/bitfield.h>
#include <linux/kgdb.h>
enum mode_set_atomic {
@@ -42,6 +43,17 @@ enum mode_set_atomic {
ENTER_ATOMIC_MODE_SET,
};
+#define DRM_FB_BPP_MASK GENMASK(7, 0)
+
+/* Using the GNU statement expression extension */
+#define DRM_FB_OPTION(option, value) \
+ ({ \
+ WARN_ON(!FIELD_FIT(option##_MASK, value)); \
+ FIELD_PREP(option##_MASK, value); \
+ })
+
+#define DRM_FB_GET_OPTION(option, word) FIELD_GET(option##_MASK, word)
+
/**
* struct drm_fb_helper_surface_size - describes fbdev size and scanout surface size
* @fb_width: fbdev width
@@ -269,7 +281,7 @@ void drm_fb_helper_lastclose(struct drm_device *dev);
void drm_fb_helper_output_poll_changed(struct drm_device *dev);
void drm_fbdev_generic_setup(struct drm_device *dev,
- unsigned int preferred_bpp);
+ const unsigned int options);
#else
static inline void drm_fb_helper_prepare(struct drm_device *dev,
struct drm_fb_helper *helper,