Commit a942b3c2 authored by Dave Airlie's avatar Dave Airlie

Merge tag 'drm-misc-next-2017-12-14' of git://anongit.freedesktop.org/drm/drm-misc into drm-next

drm-misc-next for 4.16:

Cross-subsystem Changes:

 - Documentation for amlogic dt dt-bindings

Core Changes:

 - Update edid-derived drm_display_info fields at edid property set

Driver Changes:

 - A bunch of clean up from Noralf, including the last patches to reduce
 fbdev emulation footprint.

* tag 'drm-misc-next-2017-12-14' of git://anongit.freedesktop.org/drm/drm-misc: (30 commits)
  drm/atomic-helper: Make zpos property kerneldoc less misleading
  drm: Update edid-derived drm_display_info fields at edid property set [v2]
  MAINTAINERS: Remove Jani as drm-misc co-maintainer
  drm/tinydrm: Use drm_fb_cma_fbdev_init_with_funcs/fini()
  drm/arm/mali: Use drm_fb_cma_fbdev_init/fini()
  drm/zte: Use drm_fb_cma_fbdev_init/fini()
  drm/vc4: Use drm_fb_cma_fbdev_init/fini()
  drm/tve200: Use drm_fb_cma_fbdev_init/fini()
  drm/tilcdc: Use drm_fb_cma_fbdev_init/fini()
  drm/sun4i: Use drm_fb_cma_fbdev_init/fini()
  drm/stm: Use drm_fb_cma_fbdev_init/fini()
  drm/sti: Use drm_fb_cma_fbdev_init/fini()
  drm/pl111: Use drm_fb_cma_fbdev_init/fini()
  drm/imx: Use drm_fb_cma_fbdev_init/fini()
  drm/atmel-hlcdc: Use drm_fb_cma_fbdev_init/fini()
  drm/cma-helper: Add drm_fb_cma_fbdev_init/fini()
  drm/gem-fb-helper: drm_gem_fbdev_fb_create() make funcs optional
  drm/tegra: Use drm_fb_helper_lastclose() and _poll_changed()
  drm/rockchip: Use drm_fb_helper_lastclose() and _poll_changed()
  drm/omap: Use drm_fb_helper_lastclose() and _poll_changed()
  ...
parents 9428088c ca40cfc8
......@@ -48,6 +48,10 @@ Required properties:
Documentation/devicetree/bindings/reset/reset.txt,
the reset-names should be "hdmitx_apb", "hdmitx", "hdmitx_phy"
Optional properties:
- hdmi-supply: Optional phandle to an external 5V regulator to power the HDMI
logic, as described in the file ../regulator/regulator.txt
Required nodes:
The connections to the HDMI ports are modeled using the OF graph
......
......@@ -64,6 +64,10 @@ Required properties:
- reg-names: should contain the names of the previous memory regions
- interrupts: should contain the VENC Vsync interrupt number
Optional properties:
- power-domains: Optional phandle to associated power domain as described in
the file ../power/power_domain.txt
Required nodes:
The connections to the VPU output video ports are modeled using the OF graph
......
......@@ -395,11 +395,6 @@ those drivers as simple as possible, so lots of room for refactoring:
one of the ideas for having a shared dsi/dbi helper, abstracting away the
transport details more.
- tinydrm_lastclose could be drm_fb_helper_lastclose. Only thing we need
for that is to store the drm_fb_helper pointer somewhere in
drm_device->mode_config. And then we could roll that out to all the
drivers.
- tinydrm_gem_cma_prime_import_sg_table should probably go into the cma
helpers, as a _vmapped variant (since not every driver needs the vmap).
And tinydrm_gem_cma_free_object could the be merged into
......
......@@ -4592,7 +4592,6 @@ F: include/linux/vga*
DRM DRIVERS AND MISC GPU PATCHES
M: Daniel Vetter <daniel.vetter@intel.com>
M: Jani Nikula <jani.nikula@linux.intel.com>
M: Gustavo Padovan <gustavo@padovan.org>
M: Sean Paul <seanpaul@chromium.org>
W: https://01.org/linuxgraphics/gfx-docs/maintainer-tools/drm-misc.html
......
......@@ -13,7 +13,6 @@
#include <linux/module.h>
#include <linux/clk.h>
#include <linux/component.h>
#include <linux/console.h>
#include <linux/of_device.h>
#include <linux/of_graph.h>
#include <linux/of_reserved_mem.h>
......@@ -24,6 +23,7 @@
#include <drm/drm_atomic_helper.h>
#include <drm/drm_crtc.h>
#include <drm/drm_crtc_helper.h>
#include <drm/drm_fb_helper.h>
#include <drm/drm_fb_cma_helper.h>
#include <drm/drm_gem_cma_helper.h>
#include <drm/drm_gem_framebuffer_helper.h>
......@@ -183,13 +183,6 @@ static int malidp_set_and_wait_config_valid(struct drm_device *drm)
return (ret > 0) ? 0 : -ETIMEDOUT;
}
static void malidp_output_poll_changed(struct drm_device *drm)
{
struct malidp_drm *malidp = drm->dev_private;
drm_fbdev_cma_hotplug_event(malidp->fbdev);
}
static void malidp_atomic_commit_hw_done(struct drm_atomic_state *state)
{
struct drm_pending_vblank_event *event;
......@@ -252,7 +245,7 @@ static const struct drm_mode_config_helper_funcs malidp_mode_config_helpers = {
static const struct drm_mode_config_funcs malidp_mode_config_funcs = {
.fb_create = drm_gem_fb_create,
.output_poll_changed = malidp_output_poll_changed,
.output_poll_changed = drm_fb_helper_output_poll_changed,
.atomic_check = drm_atomic_helper_check,
.atomic_commit = drm_atomic_helper_commit,
};
......@@ -317,19 +310,12 @@ static int malidp_irq_init(struct platform_device *pdev)
return 0;
}
static void malidp_lastclose(struct drm_device *drm)
{
struct malidp_drm *malidp = drm->dev_private;
drm_fbdev_cma_restore_mode(malidp->fbdev);
}
DEFINE_DRM_GEM_CMA_FOPS(fops);
static struct drm_driver malidp_driver = {
.driver_features = DRIVER_GEM | DRIVER_MODESET | DRIVER_ATOMIC |
DRIVER_PRIME,
.lastclose = malidp_lastclose,
.lastclose = drm_fb_helper_lastclose,
.gem_free_object_unlocked = drm_gem_cma_free_object,
.gem_vm_ops = &drm_gem_cma_vm_ops,
.dumb_create = drm_gem_cma_dumb_create,
......@@ -623,14 +609,9 @@ static int malidp_bind(struct device *dev)
drm_mode_config_reset(drm);
malidp->fbdev = drm_fbdev_cma_init(drm, 32,
drm->mode_config.num_connector);
if (IS_ERR(malidp->fbdev)) {
ret = PTR_ERR(malidp->fbdev);
malidp->fbdev = NULL;
ret = drm_fb_cma_fbdev_init(drm, 32, 0);
if (ret)
goto fbdev_fail;
}
drm_kms_helper_poll_init(drm);
......@@ -641,10 +622,7 @@ static int malidp_bind(struct device *dev)
return 0;
register_fail:
if (malidp->fbdev) {
drm_fbdev_cma_fini(malidp->fbdev);
malidp->fbdev = NULL;
}
drm_fb_cma_fbdev_fini(drm);
drm_kms_helper_poll_fini(drm);
fbdev_fail:
pm_runtime_get_sync(dev);
......@@ -681,10 +659,7 @@ static void malidp_unbind(struct device *dev)
struct malidp_drm *malidp = drm->dev_private;
drm_dev_unregister(drm);
if (malidp->fbdev) {
drm_fbdev_cma_fini(malidp->fbdev);
malidp->fbdev = NULL;
}
drm_fb_cma_fbdev_fini(drm);
drm_kms_helper_poll_fini(drm);
pm_runtime_get_sync(dev);
malidp_se_irq_fini(drm);
......
......@@ -20,7 +20,6 @@
struct malidp_drm {
struct malidp_hw_device *dev;
struct drm_fbdev_cma *fbdev;
struct drm_crtc crtc;
wait_queue_head_t wq;
atomic_t config_valid;
......
......@@ -84,7 +84,6 @@ void armada_drm_queue_unref_work(struct drm_device *,
extern const struct drm_mode_config_funcs armada_drm_mode_config_funcs;
int armada_fbdev_init(struct drm_device *);
void armada_fbdev_lastclose(struct drm_device *);
void armada_fbdev_fini(struct drm_device *);
int armada_overlay_plane_create(struct drm_device *, unsigned long);
......
......@@ -10,6 +10,7 @@
#include <linux/module.h>
#include <linux/of_graph.h>
#include <drm/drm_crtc_helper.h>
#include <drm/drm_fb_helper.h>
#include <drm/drm_of.h>
#include "armada_crtc.h"
#include "armada_drm.h"
......@@ -54,15 +55,10 @@ static struct drm_ioctl_desc armada_ioctls[] = {
DRM_IOCTL_DEF_DRV(ARMADA_GEM_PWRITE, armada_gem_pwrite_ioctl, 0),
};
static void armada_drm_lastclose(struct drm_device *dev)
{
armada_fbdev_lastclose(dev);
}
DEFINE_DRM_GEM_FOPS(armada_drm_fops);
static struct drm_driver armada_drm_driver = {
.lastclose = armada_drm_lastclose,
.lastclose = drm_fb_helper_lastclose,
.gem_free_object_unlocked = armada_gem_free_object,
.prime_handle_to_fd = drm_gem_prime_handle_to_fd,
.prime_fd_to_handle = drm_gem_prime_fd_to_handle,
......
......@@ -154,16 +154,7 @@ static struct drm_framebuffer *armada_fb_create(struct drm_device *dev,
return ERR_PTR(ret);
}
static void armada_output_poll_changed(struct drm_device *dev)
{
struct armada_private *priv = dev->dev_private;
struct drm_fb_helper *fbh = priv->fbdev;
if (fbh)
drm_fb_helper_hotplug_event(fbh);
}
const struct drm_mode_config_funcs armada_drm_mode_config_funcs = {
.fb_create = armada_fb_create,
.output_poll_changed = armada_output_poll_changed,
.output_poll_changed = drm_fb_helper_output_poll_changed,
};
......@@ -159,14 +159,6 @@ int armada_fbdev_init(struct drm_device *dev)
return ret;
}
void armada_fbdev_lastclose(struct drm_device *dev)
{
struct armada_private *priv = dev->dev_private;
if (priv->fbdev)
drm_fb_helper_restore_fbdev_mode_unlocked(priv->fbdev);
}
void armada_fbdev_fini(struct drm_device *dev)
{
struct armada_private *priv = dev->dev_private;
......
......@@ -461,13 +461,6 @@ static struct drm_framebuffer *atmel_hlcdc_fb_create(struct drm_device *dev,
return drm_gem_fb_create(dev, file_priv, mode_cmd);
}
static void atmel_hlcdc_fb_output_poll_changed(struct drm_device *dev)
{
struct atmel_hlcdc_dc *dc = dev->dev_private;
drm_fbdev_cma_hotplug_event(dc->fbdev);
}
struct atmel_hlcdc_dc_commit {
struct work_struct work;
struct drm_device *dev;
......@@ -563,7 +556,7 @@ static int atmel_hlcdc_dc_atomic_commit(struct drm_device *dev,
static const struct drm_mode_config_funcs mode_config_funcs = {
.fb_create = atmel_hlcdc_fb_create,
.output_poll_changed = atmel_hlcdc_fb_output_poll_changed,
.output_poll_changed = drm_fb_helper_output_poll_changed,
.atomic_check = drm_atomic_helper_check,
.atomic_commit = atmel_hlcdc_dc_atomic_commit,
};
......@@ -665,10 +658,7 @@ static int atmel_hlcdc_dc_load(struct drm_device *dev)
platform_set_drvdata(pdev, dev);
dc->fbdev = drm_fbdev_cma_init(dev, 24,
dev->mode_config.num_connector);
if (IS_ERR(dc->fbdev))
dc->fbdev = NULL;
drm_fb_cma_fbdev_init(dev, 24, 0);
drm_kms_helper_poll_init(dev);
......@@ -688,8 +678,7 @@ static void atmel_hlcdc_dc_unload(struct drm_device *dev)
{
struct atmel_hlcdc_dc *dc = dev->dev_private;
if (dc->fbdev)
drm_fbdev_cma_fini(dc->fbdev);
drm_fb_cma_fbdev_fini(dev);
flush_workqueue(dc->wq);
drm_kms_helper_poll_fini(dev);
drm_mode_config_cleanup(dev);
......@@ -705,13 +694,6 @@ static void atmel_hlcdc_dc_unload(struct drm_device *dev)
destroy_workqueue(dc->wq);
}
static void atmel_hlcdc_dc_lastclose(struct drm_device *dev)
{
struct atmel_hlcdc_dc *dc = dev->dev_private;
drm_fbdev_cma_restore_mode(dc->fbdev);
}
static int atmel_hlcdc_dc_irq_postinstall(struct drm_device *dev)
{
struct atmel_hlcdc_dc *dc = dev->dev_private;
......@@ -744,7 +726,7 @@ static struct drm_driver atmel_hlcdc_dc_driver = {
.driver_features = DRIVER_HAVE_IRQ | DRIVER_GEM |
DRIVER_MODESET | DRIVER_PRIME |
DRIVER_ATOMIC,
.lastclose = atmel_hlcdc_dc_lastclose,
.lastclose = drm_fb_helper_lastclose,
.irq_handler = atmel_hlcdc_dc_irq_handler,
.irq_preinstall = atmel_hlcdc_dc_irq_uninstall,
.irq_postinstall = atmel_hlcdc_dc_irq_postinstall,
......
......@@ -32,6 +32,7 @@
#include <drm/drm_atomic_helper.h>
#include <drm/drm_crtc.h>
#include <drm/drm_crtc_helper.h>
#include <drm/drm_fb_helper.h>
#include <drm/drm_fb_cma_helper.h>
#include <drm/drm_gem_cma_helper.h>
#include <drm/drm_gem_framebuffer_helper.h>
......@@ -374,7 +375,6 @@ struct atmel_hlcdc_dc {
const struct atmel_hlcdc_dc_desc *desc;
struct dma_pool *dscrpool;
struct atmel_hlcdc *hlcdc;
struct drm_fbdev_cma *fbdev;
struct drm_crtc *crtc;
struct atmel_hlcdc_layer *layers[ATMEL_HLCDC_MAX_LAYERS];
struct workqueue_struct *wq;
......
......@@ -214,9 +214,11 @@ EXPORT_SYMBOL(drm_rotation_simplify);
* This function initializes generic mutable zpos property and enables support
* for it in drm core. Drivers can then attach this property to planes to enable
* support for configurable planes arrangement during blending operation.
* Once mutable zpos property has been enabled, the DRM core will automatically
* calculate &drm_plane_state.normalized_zpos values. Usually min should be set
* to 0 and max to maximal number of planes for given crtc - 1.
* Drivers that attach a mutable zpos property to any plane should call the
* drm_atomic_normalize_zpos() helper during their implementation of
* &drm_mode_config_funcs.atomic_check(), which will update the normalized zpos
* values and store them in &drm_plane_state.normalized_zpos. Usually min
* should be set to 0 and max to maximal number of planes for given crtc - 1.
*
* If zpos of some planes cannot be changed (like fixed background or
* cursor/topmost planes), driver should adjust min/max values and assign those
......
......@@ -1229,6 +1229,19 @@ int drm_mode_connector_update_edid_property(struct drm_connector *connector,
if (edid)
size = EDID_LENGTH * (1 + edid->extensions);
/* Set the display info, using edid if available, otherwise
* reseting the values to defaults. This duplicates the work
* done in drm_add_edid_modes, but that function is not
* consistently called before this one in all drivers and the
* computation is cheap enough that it seems better to
* duplicate it rather than attempt to ensure some arbitrary
* ordering of calls.
*/
if (edid)
drm_add_display_info(connector, edid);
else
drm_reset_display_info(connector);
drm_object_property_set_value(&connector->base,
dev->mode_config.non_desktop_property,
connector->display_info.non_desktop);
......
......@@ -1731,7 +1731,7 @@ EXPORT_SYMBOL(drm_edid_duplicate);
*
* Returns true if @vendor is in @edid, false otherwise
*/
static bool edid_vendor(struct edid *edid, const char *vendor)
static bool edid_vendor(const struct edid *edid, const char *vendor)
{
char edid_vendor[3];
......@@ -1749,7 +1749,7 @@ static bool edid_vendor(struct edid *edid, const char *vendor)
*
* This tells subsequent routines what fixes they need to apply.
*/
static u32 edid_get_quirks(struct edid *edid)
static u32 edid_get_quirks(const struct edid *edid)
{
const struct edid_quirk *quirk;
int i;
......@@ -2813,7 +2813,7 @@ add_detailed_modes(struct drm_connector *connector, struct edid *edid,
/*
* Search EDID for CEA extension block.
*/
static u8 *drm_find_edid_extension(struct edid *edid, int ext_id)
static u8 *drm_find_edid_extension(const struct edid *edid, int ext_id)
{
u8 *edid_ext = NULL;
int i;
......@@ -2835,12 +2835,12 @@ static u8 *drm_find_edid_extension(struct edid *edid, int ext_id)
return edid_ext;
}
static u8 *drm_find_cea_extension(struct edid *edid)
static u8 *drm_find_cea_extension(const struct edid *edid)
{
return drm_find_edid_extension(edid, CEA_EXT);
}
static u8 *drm_find_displayid_extension(struct edid *edid)
static u8 *drm_find_displayid_extension(const struct edid *edid)
{
return drm_find_edid_extension(edid, DISPLAYID_EXT);
}
......@@ -4378,7 +4378,7 @@ drm_parse_hdmi_vsdb_video(struct drm_connector *connector, const u8 *db)
}
static void drm_parse_cea_ext(struct drm_connector *connector,
struct edid *edid)
const struct edid *edid)
{
struct drm_display_info *info = &connector->display_info;
const u8 *edid_ext;
......@@ -4412,11 +4412,34 @@ static void drm_parse_cea_ext(struct drm_connector *connector,
}
}
static void drm_add_display_info(struct drm_connector *connector,
struct edid *edid, u32 quirks)
/* A connector has no EDID information, so we've got no EDID to compute quirks from. Reset
* all of the values which would have been set from EDID
*/
void
drm_reset_display_info(struct drm_connector *connector)
{
struct drm_display_info *info = &connector->display_info;
info->width_mm = 0;
info->height_mm = 0;
info->bpc = 0;
info->color_formats = 0;
info->cea_rev = 0;
info->max_tmds_clock = 0;
info->dvi_dual = false;
info->has_hdmi_infoframe = false;
info->non_desktop = 0;
}
EXPORT_SYMBOL_GPL(drm_reset_display_info);
u32 drm_add_display_info(struct drm_connector *connector, const struct edid *edid)
{
struct drm_display_info *info = &connector->display_info;
u32 quirks = edid_get_quirks(edid);
info->width_mm = edid->width_cm * 10;
info->height_mm = edid->height_cm * 10;
......@@ -4430,11 +4453,13 @@ static void drm_add_display_info(struct drm_connector *connector,
info->non_desktop = !!(quirks & EDID_QUIRK_NON_DESKTOP);
DRM_DEBUG_KMS("non_desktop set to %d\n", info->non_desktop);
if (edid->revision < 3)
return;
return quirks;
if (!(edid->input & DRM_EDID_INPUT_DIGITAL))
return;
return quirks;
drm_parse_cea_ext(connector, edid);
......@@ -4454,7 +4479,7 @@ static void drm_add_display_info(struct drm_connector *connector,
/* Only defined for 1.4 with digital displays */
if (edid->revision < 4)
return;
return quirks;
switch (edid->input & DRM_EDID_DIGITAL_DEPTH_MASK) {
case DRM_EDID_DIGITAL_DEPTH_6:
......@@ -4489,7 +4514,9 @@ static void drm_add_display_info(struct drm_connector *connector,
info->color_formats |= DRM_COLOR_FORMAT_YCRCB444;
if (edid->features & DRM_EDID_FEATURE_RGB_YCRCB422)
info->color_formats |= DRM_COLOR_FORMAT_YCRCB422;
return quirks;
}
EXPORT_SYMBOL_GPL(drm_add_display_info);
static int validate_displayid(u8 *displayid, int length, int idx)
{
......@@ -4645,8 +4672,6 @@ int drm_add_edid_modes(struct drm_connector *connector, struct edid *edid)
return 0;
}
quirks = edid_get_quirks(edid);
drm_edid_to_eld(connector, edid);
/*
......@@ -4654,7 +4679,7 @@ int drm_add_edid_modes(struct drm_connector *connector, struct edid *edid)
* To avoid multiple parsing of same block, lets parse that map
* from sink info, before parsing CEA modes.
*/
drm_add_display_info(connector, edid, quirks);
quirks = drm_add_display_info(connector, edid);
/*
* EDID spec says modes should be preferred in this order:
......
......@@ -23,6 +23,7 @@
#include <drm/drm_gem_cma_helper.h>
#include <drm/drm_gem_framebuffer_helper.h>
#include <drm/drm_fb_cma_helper.h>
#include <drm/drm_print.h>
#include <linux/module.h>
#define DEFAULT_FBDEFIO_DELAY_MS 50
......@@ -42,7 +43,7 @@ struct drm_fbdev_cma {
* callback function to create a cma backed framebuffer.
*
* An fbdev framebuffer backed by cma is also available by calling
* drm_fbdev_cma_init(). drm_fbdev_cma_fini() tears it down.
* drm_fb_cma_fbdev_init(). drm_fb_cma_fbdev_fini() tears it down.
* If the &drm_framebuffer_funcs.dirty callback is set, fb_deferred_io will be
* set up automatically. &drm_framebuffer_funcs.dirty is called by
* drm_fb_helper_deferred_io() in process context (&struct delayed_work).
......@@ -68,7 +69,7 @@ struct drm_fbdev_cma {
*
* Initialize::
*
* fbdev = drm_fbdev_cma_init_with_funcs(dev, 16,
* fbdev = drm_fb_cma_fbdev_init_with_funcs(dev, 16,
* dev->mode_config.num_crtc,
* dev->mode_config.num_connector,
* &driver_fb_funcs);
......@@ -256,7 +257,7 @@ drm_fbdev_cma_create(struct drm_fb_helper *helper,
fbi->screen_size = size;
fbi->fix.smem_len = size;
if (fbdev_cma->fb_funcs->dirty) {
if (fb->funcs->dirty) {
ret = drm_fbdev_cma_defio_init(fbi, obj);
if (ret)
goto err_cma_destroy;
......@@ -277,6 +278,118 @@ static const struct drm_fb_helper_funcs drm_fb_cma_helper_funcs = {
.fb_probe = drm_fbdev_cma_create,
};
/**
* drm_fb_cma_fbdev_init_with_funcs() - Allocate and initialize 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.
* @max_conn_count: Maximum number of connectors.
* @dev->mode_config.num_connector is used if this is zero.
* @funcs: Framebuffer functions, in particular a custom dirty() callback.
* Can be NULL.
*
* Returns:
* Zero on success or negative error code on failure.
*/
int drm_fb_cma_fbdev_init_with_funcs(struct drm_device *dev,
unsigned int preferred_bpp, unsigned int max_conn_count,
const struct drm_framebuffer_funcs *funcs)
{
struct drm_fbdev_cma *fbdev_cma;
struct drm_fb_helper *fb_helper;
int ret;
if (!preferred_bpp)
preferred_bpp = dev->mode_config.preferred_depth;
if (!preferred_bpp)
preferred_bpp = 32;
if (!max_conn_count)
max_conn_count = dev->mode_config.num_connector;
fbdev_cma = kzalloc(sizeof(*fbdev_cma), GFP_KERNEL);
if (!fbdev_cma)
return -ENOMEM;
fbdev_cma->fb_funcs = funcs;
fb_helper = &fbdev_cma->fb_helper;
drm_fb_helper_prepare(dev, fb_helper, &drm_fb_cma_helper_funcs);
ret = drm_fb_helper_init(dev, fb_helper, max_conn_count);
if (ret < 0) {
DRM_DEV_ERROR(dev->dev, "Failed to initialize fbdev helper.\n");
goto err_free;
}
ret = drm_fb_helper_single_add_all_connectors(fb_helper);
if (ret < 0) {
DRM_DEV_ERROR(dev->dev, "Failed to add connectors.\n");
goto err_drm_fb_helper_fini;
}
ret = drm_fb_helper_initial_config(fb_helper, preferred_bpp);
if (ret < 0) {
DRM_DEV_ERROR(dev->dev, "Failed to set fbdev configuration.\n");
goto err_drm_fb_helper_fini;
}
return 0;
err_drm_fb_helper_fini:
drm_fb_helper_fini(fb_helper);
err_free:
kfree(fbdev_cma);
return ret;
}
EXPORT_SYMBOL_GPL(drm_fb_cma_fbdev_init_with_funcs);
/**
* drm_fb_cma_fbdev_init() - Allocate and initialize 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.
* @max_conn_count: Maximum number of connectors.
* @dev->mode_config.num_connector is used if this is zero.
*
* Returns:
* Zero on success or negative error code on failure.
*/
int drm_fb_cma_fbdev_init(struct drm_device *dev, unsigned int preferred_bpp,
unsigned int max_conn_count)
{
return drm_fb_cma_fbdev_init_with_funcs(dev, preferred_bpp,
max_conn_count, NULL);
}
EXPORT_SYMBOL_GPL(drm_fb_cma_fbdev_init);
/**
* drm_fb_cma_fbdev_fini() - Teardown fbdev emulation
* @dev: DRM device
*/
void drm_fb_cma_fbdev_fini(struct drm_device *dev)
{
struct drm_fb_helper *fb_helper = dev->fb_helper;
if (!fb_helper)
return;
/* Unregister if it hasn't been done already */
if (fb_helper->fbdev && fb_helper->fbdev->dev)
drm_fb_helper_unregister_fbi(fb_helper);
if (fb_helper->fbdev)
drm_fbdev_cma_defio_fini(fb_helper->fbdev);
if (fb_helper->fb)
drm_framebuffer_remove(fb_helper->fb);
drm_fb_helper_fini(fb_helper);
kfree(to_fbdev_cma(fb_helper));
}
EXPORT_SYMBOL_GPL(drm_fb_cma_fbdev_fini);
/**
* drm_fbdev_cma_init_with_funcs() - Allocate and initializes a drm_fbdev_cma struct
* @dev: DRM device
......
......@@ -272,7 +272,8 @@ EXPORT_SYMBOL_GPL(drm_gem_fb_prepare_fb);
* @sizes: fbdev size description
* @pitch_align: Optional pitch alignment
* @obj: GEM object backing the framebuffer
* @funcs: vtable to be used for the new framebuffer object
* @funcs: Optional vtable to be used for the new framebuffer object when the
* dirty callback is needed.
*
* This function creates a framebuffer from a &drm_fb_helper_surface_size
* description for use in the &drm_fb_helper_funcs.fb_probe callback.
......@@ -300,6 +301,9 @@ drm_gem_fbdev_fb_create(struct drm_device *dev,
if (obj->size < mode_cmd.pitches[0] * mode_cmd.height)
return ERR_PTR(-EINVAL);
if (!funcs)
funcs = &drm_gem_fb_funcs;
return drm_gem_fb_alloc(dev, &mode_cmd, &obj, 1, funcs);
}
EXPORT_SYMBOL(drm_gem_fbdev_fb_create);
......@@ -467,6 +467,9 @@ void drm_mode_config_cleanup(struct drm_device *dev)
*/
WARN_ON(!list_empty(&dev->mode_config.fb_list));
list_for_each_entry_safe(fb, fbt, &dev->mode_config.fb_list, head) {
struct drm_printer p = drm_debug_printer("[leaked fb]");
drm_printf(&p, "framebuffer[%u]:\n", fb->base.id);
drm_framebuffer_print_info(&p, 1, fb);
drm_framebuffer_free(&fb->base.refcount);
}
......
......@@ -16,6 +16,7 @@
#include <drm/drm_atomic.h>
#include <drm/drm_atomic_helper.h>
#include <drm/drm_crtc_helper.h>
#include <drm/drm_fb_helper.h>
#include <linux/component.h>
......@@ -89,11 +90,6 @@ static void exynos_drm_postclose(struct drm_device *dev, struct drm_file *file)
file->driver_priv = NULL;
}
static void exynos_drm_lastclose(struct drm_device *dev)
{
exynos_drm_fbdev_restore_mode(dev);
}
static const struct vm_operations_struct exynos_drm_gem_vm_ops = {
.fault = exynos_drm_gem_fault,
.open = drm_gem_vm_open,
......@@ -140,7 +136,7 @@ static struct drm_driver exynos_drm_driver = {
.driver_features = DRIVER_MODESET | DRIVER_GEM | DRIVER_PRIME
| DRIVER_ATOMIC | DRIVER_RENDER,
.open = exynos_drm_open,
.lastclose = exynos_drm_lastclose,
.lastclose = drm_fb_helper_lastclose,
.postclose = exynos_drm_postclose,
.gem_free_object_unlocked = exynos_drm_gem_free_object,
.gem_vm_ops = &exynos_drm_gem_vm_ops,
......
......@@ -205,7 +205,7 @@ static struct drm_mode_config_helper_funcs exynos_drm_mode_config_helpers = {
static const struct drm_mode_config_funcs exynos_drm_mode_config_funcs = {
.fb_create = exynos_user_fb_create,
.output_poll_changed = exynos_drm_output_poll_changed,
.output_poll_changed = drm_fb_helper_output_poll_changed,
.atomic_check = exynos_atomic_check,
.atomic_commit = drm_atomic_helper_commit,
};
......
......@@ -270,24 +270,6 @@ void exynos_drm_fbdev_fini(struct drm_device *dev)
private->fb_helper = NULL;
}
void exynos_drm_fbdev_restore_mode(struct drm_device *dev)
{
struct exynos_drm_private *private = dev->dev_private;
if (!private || !private->fb_helper)
return;
drm_fb_helper_restore_fbdev_mode_unlocked(private->fb_helper);
}
void exynos_drm_output_poll_changed(struct drm_device *dev)
{
struct exynos_drm_private *private = dev->dev_private;
struct drm_fb_helper *fb_helper = private->fb_helper;
drm_fb_helper_hotplug_event(fb_helper);
}
void exynos_drm_fbdev_suspend(struct drm_device *dev)
{
struct exynos_drm_private *private = dev->dev_private;
......
......@@ -19,8 +19,6 @@
int exynos_drm_fbdev_init(struct drm_device *dev);
void exynos_drm_fbdev_fini(struct drm_device *dev);
void exynos_drm_fbdev_restore_mode(struct drm_device *dev);
void exynos_drm_output_poll_changed(struct drm_device *dev);
void exynos_drm_fbdev_suspend(struct drm_device *drm);
void exynos_drm_fbdev_resume(struct drm_device *drm);
......
......@@ -576,13 +576,6 @@ static void psb_fbdev_fini(struct drm_device *dev)
dev_priv->fbdev = NULL;
}
static void psbfb_output_poll_changed(struct drm_device *dev)
{
struct drm_psb_private *dev_priv = dev->dev_private;
struct psb_fbdev *fbdev = (struct psb_fbdev *)dev_priv->fbdev;
drm_fb_helper_hotplug_event(&fbdev->psb_fb_helper);
}
/**
* psb_user_framebuffer_create_handle - add hamdle to a framebuffer
* @fb: framebuffer
......@@ -623,7 +616,7 @@ static void psb_user_framebuffer_destroy(struct drm_framebuffer *fb)
static const struct drm_mode_config_funcs psb_mode_funcs = {
.fb_create = psb_user_framebuffer_create,
.output_poll_changed = psbfb_output_poll_changed,
.output_poll_changed = drm_fb_helper_output_poll_changed,
};
static void psb_setup_outputs(struct drm_device *dev)
......
......@@ -107,19 +107,6 @@ MODULE_DEVICE_TABLE(pci, pciidlist);
static const struct drm_ioctl_desc psb_ioctls[] = {
};
static void psb_driver_lastclose(struct drm_device *dev)
{
int ret;
struct drm_psb_private *dev_priv = dev->dev_private;
struct psb_fbdev *fbdev = dev_priv->fbdev;
ret = drm_fb_helper_restore_fbdev_mode_unlocked(&fbdev->psb_fb_helper);
if (ret)
DRM_DEBUG("failed to restore crtc mode\n");
return;
}
static int psb_do_init(struct drm_device *dev)
{
struct drm_psb_private *dev_priv = dev->dev_private;
......@@ -479,7 +466,7 @@ static struct drm_driver driver = {
DRIVER_MODESET | DRIVER_GEM,
.load = psb_driver_load,
.unload = psb_driver_unload,
.lastclose = psb_driver_lastclose,
.lastclose = drm_fb_helper_lastclose,
.num_ioctls = ARRAY_SIZE(psb_ioctls),
.irq_preinstall = psb_irq_preinstall,
......
......@@ -38,7 +38,6 @@
struct imx_drm_device {
struct drm_device *drm;
unsigned int pipes;
struct drm_fbdev_cma *fbhelper;
struct drm_atomic_state *state;
};
......@@ -47,13 +46,6 @@ static int legacyfb_depth = 16;
module_param(legacyfb_depth, int, 0444);
#endif
static void imx_drm_driver_lastclose(struct drm_device *drm)
{
struct imx_drm_device *imxdrm = drm->dev_private;
drm_fbdev_cma_restore_mode(imxdrm->fbhelper);
}
DEFINE_DRM_GEM_CMA_FOPS(imx_drm_driver_fops);
void imx_drm_connector_destroy(struct drm_connector *connector)
......@@ -69,13 +61,6 @@ void imx_drm_encoder_destroy(struct drm_encoder *encoder)
}
EXPORT_SYMBOL_GPL(imx_drm_encoder_destroy);
static void imx_drm_output_poll_changed(struct drm_device *drm)
{
struct imx_drm_device *imxdrm = drm->dev_private;
drm_fbdev_cma_hotplug_event(imxdrm->fbhelper);
}
static int imx_drm_atomic_check(struct drm_device *dev,
struct drm_atomic_state *state)
{
......@@ -107,7 +92,7 @@ static int imx_drm_atomic_check(struct drm_device *dev,
static const struct drm_mode_config_funcs imx_drm_mode_config_funcs = {
.fb_create = drm_gem_fb_create,
.output_poll_changed = imx_drm_output_poll_changed,
.output_poll_changed = drm_fb_helper_output_poll_changed,
.atomic_check = imx_drm_atomic_check,
.atomic_commit = drm_atomic_helper_commit,
};
......@@ -186,7 +171,7 @@ static const struct drm_ioctl_desc imx_drm_ioctls[] = {
static struct drm_driver imx_drm_driver = {
.driver_features = DRIVER_MODESET | DRIVER_GEM | DRIVER_PRIME |
DRIVER_ATOMIC,
.lastclose = imx_drm_driver_lastclose,
.lastclose = drm_fb_helper_lastclose,
.gem_free_object_unlocked = drm_gem_cma_free_object,
.gem_vm_ops = &drm_gem_cma_vm_ops,
.dumb_create = drm_gem_cma_dumb_create,
......@@ -298,12 +283,9 @@ static int imx_drm_bind(struct device *dev)
dev_warn(dev, "Invalid legacyfb_depth. Defaulting to 16bpp\n");
legacyfb_depth = 16;
}
imxdrm->fbhelper = drm_fbdev_cma_init(drm, legacyfb_depth, MAX_CRTC);
if (IS_ERR(imxdrm->fbhelper)) {
ret = PTR_ERR(imxdrm->fbhelper);
imxdrm->fbhelper = NULL;
ret = drm_fb_cma_fbdev_init(drm, legacyfb_depth, MAX_CRTC);
if (ret)
goto err_unbind;
}
#endif
drm_kms_helper_poll_init(drm);
......@@ -317,8 +299,7 @@ static int imx_drm_bind(struct device *dev)
err_fbhelper:
drm_kms_helper_poll_fini(drm);
#if IS_ENABLED(CONFIG_DRM_FBDEV_EMULATION)
if (imxdrm->fbhelper)
drm_fbdev_cma_fini(imxdrm->fbhelper);
drm_fb_cma_fbdev_fini(drm);
err_unbind:
#endif
component_unbind_all(drm->dev, drm);
......@@ -333,14 +314,12 @@ static int imx_drm_bind(struct device *dev)
static void imx_drm_unbind(struct device *dev)
{
struct drm_device *drm = dev_get_drvdata(dev);
struct imx_drm_device *imxdrm = drm->dev_private;
drm_dev_unregister(drm);
drm_kms_helper_poll_fini(drm);
if (imxdrm->fbhelper)
drm_fbdev_cma_fini(imxdrm->fbhelper);
drm_fb_cma_fbdev_fini(drm);
drm_mode_config_cleanup(drm);
......
......@@ -8,7 +8,6 @@ struct drm_connector;
struct drm_device;
struct drm_display_mode;
struct drm_encoder;
struct drm_fbdev_cma;
struct drm_framebuffer;
struct drm_plane;
struct imx_drm_crtc;
......
......@@ -151,6 +151,14 @@ static struct regmap_config meson_regmap_config = {
.max_register = 0x1000,
};
static void meson_vpu_init(struct meson_drm *priv)
{
writel_relaxed(0x210000, priv->io_base + _REG(VPU_RDARB_MODE_L1C1));
writel_relaxed(0x10000, priv->io_base + _REG(VPU_RDARB_MODE_L1C2));
writel_relaxed(0x900000, priv->io_base + _REG(VPU_RDARB_MODE_L2C1));
writel_relaxed(0x20000, priv->io_base + _REG(VPU_WRARB_MODE_L2C1));
}
static int meson_drv_bind_master(struct device *dev, bool has_components)
{
struct platform_device *pdev = to_platform_device(dev);
......@@ -222,6 +230,7 @@ static int meson_drv_bind_master(struct device *dev, bool has_components)
/* Hardware Initialization */
meson_vpu_init(priv);
meson_venc_init(priv);
meson_vpp_init(priv);
meson_viu_init(priv);
......
......@@ -23,6 +23,7 @@
#include <linux/of_graph.h>
#include <linux/reset.h>
#include <linux/clk.h>
#include <linux/regulator/consumer.h>
#include <drm/drmP.h>
#include <drm/drm_edid.h>
......@@ -137,6 +138,7 @@ struct meson_dw_hdmi {
struct reset_control *hdmitx_phy;
struct clk *hdmi_pclk;
struct clk *venci_clk;
struct regulator *hdmi_supply;
u32 irq_stat;
};
#define encoder_to_meson_dw_hdmi(x) \
......@@ -751,6 +753,17 @@ static int meson_dw_hdmi_bind(struct device *dev, struct device *master,
dw_plat_data = &meson_dw_hdmi->dw_plat_data;
encoder = &meson_dw_hdmi->encoder;
meson_dw_hdmi->hdmi_supply = devm_regulator_get_optional(dev, "hdmi");
if (IS_ERR(meson_dw_hdmi->hdmi_supply)) {
if (PTR_ERR(meson_dw_hdmi->hdmi_supply) == -EPROBE_DEFER)
return -EPROBE_DEFER;
meson_dw_hdmi->hdmi_supply = NULL;
} else {
ret = regulator_enable(meson_dw_hdmi->hdmi_supply);
if (ret)
return ret;
}
meson_dw_hdmi->hdmitx_apb = devm_reset_control_get_exclusive(dev,
"hdmitx_apb");
if (IS_ERR(meson_dw_hdmi->hdmitx_apb)) {
......
......@@ -1363,6 +1363,10 @@
#define VPU_PROT3_STAT_1 0x277a
#define VPU_PROT3_STAT_2 0x277b
#define VPU_PROT3_REQ_ONOFF 0x277c
#define VPU_RDARB_MODE_L1C1 0x2790
#define VPU_RDARB_MODE_L1C2 0x2799
#define VPU_RDARB_MODE_L2C1 0x279d
#define VPU_WRARB_MODE_L2C1 0x27a2
/* osd super scale */
#define OSDSR_HV_SIZEIN 0x3130
......
......@@ -37,16 +37,9 @@
#define MSM_VERSION_MINOR 3
#define MSM_VERSION_PATCHLEVEL 0
static void msm_fb_output_poll_changed(struct drm_device *dev)
{
struct msm_drm_private *priv = dev->dev_private;
if (priv->fbdev)
drm_fb_helper_hotplug_event(priv->fbdev);
}
static const struct drm_mode_config_funcs mode_config_funcs = {
.fb_create = msm_framebuffer_create,
.output_poll_changed = msm_fb_output_poll_changed,
.output_poll_changed = drm_fb_helper_output_poll_changed,
.atomic_check = drm_atomic_helper_check,
.atomic_commit = msm_atomic_commit,
.atomic_state_alloc = msm_atomic_state_alloc,
......@@ -551,13 +544,6 @@ static void msm_postclose(struct drm_device *dev, struct drm_file *file)
context_close(ctx);
}
static void msm_lastclose(struct drm_device *dev)
{
struct msm_drm_private *priv = dev->dev_private;
if (priv->fbdev)
drm_fb_helper_restore_fbdev_mode_unlocked(priv->fbdev);
}
static irqreturn_t msm_irq(int irq, void *arg)
{
struct drm_device *dev = arg;
......@@ -866,7 +852,7 @@ static struct drm_driver msm_driver = {
DRIVER_MODESET,
.open = msm_open,
.postclose = msm_postclose,
.lastclose = msm_lastclose,
.lastclose = drm_fb_helper_lastclose,
.irq_handler = msm_irq,
.irq_preinstall = msm_irq_preinstall,
.irq_postinstall = msm_irq_postinstall,
......
......@@ -29,6 +29,7 @@
#include <drm/drm_atomic.h>
#include <drm/drm_atomic_helper.h>
#include <drm/drm_crtc_helper.h>
#include <drm/drm_fb_helper.h>
#include <nvif/class.h>
......@@ -292,7 +293,7 @@ nouveau_user_framebuffer_create(struct drm_device *dev,
static const struct drm_mode_config_funcs nouveau_mode_config_funcs = {
.fb_create = nouveau_user_framebuffer_create,
.output_poll_changed = nouveau_fbcon_output_poll_changed,
.output_poll_changed = drm_fb_helper_output_poll_changed,
};
......
......@@ -413,14 +413,6 @@ nouveau_fbcon_create(struct drm_fb_helper *helper,
return ret;
}
void
nouveau_fbcon_output_poll_changed(struct drm_device *dev)
{
struct nouveau_drm *drm = nouveau_drm(dev);
if (drm->fbcon)
drm_fb_helper_hotplug_event(&drm->fbcon->helper);
}
static int
nouveau_fbcon_destroy(struct drm_device *dev, struct nouveau_fbdev *fbcon)
{
......
......@@ -68,8 +68,6 @@ void nouveau_fbcon_set_suspend(struct drm_device *dev, int state);
void nouveau_fbcon_accel_save_disable(struct drm_device *dev);
void nouveau_fbcon_accel_restore(struct drm_device *dev);
void nouveau_fbcon_output_poll_changed(struct drm_device *dev);
extern int nouveau_nofbaccel;
#endif /* __NV50_FBCON_H__ */
......
......@@ -4,6 +4,7 @@
#include <drm/drmP.h>
#include <drm/drm_crtc_helper.h>
#include <drm/drm_fb_helper.h>
#include "nouveau_drv.h"
#include "nouveau_acpi.h"
......@@ -61,7 +62,7 @@ static void
nouveau_switcheroo_reprobe(struct pci_dev *pdev)
{
struct drm_device *dev = pci_get_drvdata(pdev);
nouveau_fbcon_output_poll_changed(dev);
drm_fb_helper_output_poll_changed(dev);
}
static bool
......
......@@ -4311,7 +4311,7 @@ nv50_disp_atomic_state_alloc(struct drm_device *dev)
static const struct drm_mode_config_funcs
nv50_disp_func = {
.fb_create = nouveau_user_framebuffer_create,
.output_poll_changed = nouveau_fbcon_output_poll_changed,
.output_poll_changed = drm_fb_helper_output_poll_changed,
.atomic_check = nv50_disp_atomic_check,
.atomic_commit = nv50_disp_atomic_commit,
.atomic_state_alloc = nv50_disp_atomic_state_alloc,
......
......@@ -46,14 +46,6 @@
* devices
*/
static void omap_fb_output_poll_changed(struct drm_device *dev)
{
struct omap_drm_private *priv = dev->dev_private;
DBG("dev=%p", dev);
if (priv->fbdev)
drm_fb_helper_hotplug_event(priv->fbdev);
}
static void omap_atomic_wait_for_completion(struct drm_device *dev,
struct drm_atomic_state *old_state)
{
......@@ -132,7 +124,7 @@ static const struct drm_mode_config_helper_funcs omap_mode_config_helper_funcs =
static const struct drm_mode_config_funcs omap_mode_config_funcs = {
.fb_create = omap_framebuffer_create,
.output_poll_changed = omap_fb_output_poll_changed,
.output_poll_changed = drm_fb_helper_output_poll_changed,
.atomic_check = drm_atomic_helper_check,
.atomic_commit = drm_atomic_helper_commit,
};
......@@ -467,28 +459,6 @@ static int dev_open(struct drm_device *dev, struct drm_file *file)
return 0;
}
/**
* lastclose - clean up after all DRM clients have exited
* @dev: DRM device
*
* Take care of cleaning up after all DRM clients have exited. In the
* mode setting case, we want to restore the kernel's initial mode (just
* in case the last client left us in a bad state).
*/
static void dev_lastclose(struct drm_device *dev)
{
struct omap_drm_private *priv = dev->dev_private;
int ret;
DBG("lastclose: dev=%p", dev);
if (priv->fbdev) {
ret = drm_fb_helper_restore_fbdev_mode_unlocked(priv->fbdev);
if (ret)
DBG("failed to restore crtc mode");
}
}
static const struct vm_operations_struct omap_gem_vm_ops = {
.fault = omap_gem_fault,
.open = drm_gem_vm_open,
......@@ -511,7 +481,7 @@ static struct drm_driver omap_drm_driver = {
.driver_features = DRIVER_MODESET | DRIVER_GEM | DRIVER_PRIME |
DRIVER_ATOMIC | DRIVER_RENDER,
.open = dev_open,
.lastclose = dev_lastclose,
.lastclose = drm_fb_helper_lastclose,
#ifdef CONFIG_DEBUG_FS
.debugfs_init = omap_debugfs_init,
#endif
......
......@@ -53,7 +53,6 @@ struct pl111_drm_dev_private {
struct drm_panel *panel;
struct drm_bridge *bridge;
struct drm_simple_display_pipe pipe;
struct drm_fbdev_cma *fbdev;
void *regs;
u32 ienb;
......
......@@ -64,6 +64,7 @@
#include <drm/drm_crtc_helper.h>
#include <drm/drm_gem_cma_helper.h>
#include <drm/drm_gem_framebuffer_helper.h>
#include <drm/drm_fb_helper.h>
#include <drm/drm_fb_cma_helper.h>
#include <drm/drm_of.h>
#include <drm/drm_bridge.h>
......@@ -137,8 +138,7 @@ static int pl111_modeset_init(struct drm_device *dev)
drm_mode_config_reset(dev);
priv->fbdev = drm_fbdev_cma_init(dev, 32,
dev->mode_config.num_connector);
drm_fb_cma_fbdev_init(dev, 32, 0);
drm_kms_helper_poll_init(dev);
......@@ -155,17 +155,10 @@ static int pl111_modeset_init(struct drm_device *dev)
DEFINE_DRM_GEM_CMA_FOPS(drm_fops);
static void pl111_lastclose(struct drm_device *dev)
{
struct pl111_drm_dev_private *priv = dev->dev_private;
drm_fbdev_cma_restore_mode(priv->fbdev);
}
static struct drm_driver pl111_drm_driver = {
.driver_features =
DRIVER_MODESET | DRIVER_GEM | DRIVER_PRIME | DRIVER_ATOMIC,
.lastclose = pl111_lastclose,
.lastclose = drm_fb_helper_lastclose,
.ioctls = NULL,
.fops = &drm_fops,
.name = "pl111",
......@@ -281,8 +274,7 @@ static int pl111_amba_remove(struct amba_device *amba_dev)
struct pl111_drm_dev_private *priv = drm->dev_private;
drm_dev_unregister(drm);
if (priv->fbdev)
drm_fbdev_cma_fini(priv->fbdev);
drm_fb_cma_fbdev_fini(drm);
if (priv->panel)
drm_panel_bridge_remove(priv->bridge);
drm_mode_config_cleanup(drm);
......
......@@ -207,13 +207,6 @@ static void rockchip_drm_unbind(struct device *dev)
drm_dev_unref(drm_dev);
}
static void rockchip_drm_lastclose(struct drm_device *dev)
{
struct rockchip_drm_private *priv = dev->dev_private;
drm_fb_helper_restore_fbdev_mode_unlocked(&priv->fbdev_helper);
}
static const struct file_operations rockchip_drm_driver_fops = {
.owner = THIS_MODULE,
.open = drm_open,
......@@ -228,7 +221,7 @@ static const struct file_operations rockchip_drm_driver_fops = {
static struct drm_driver rockchip_drm_driver = {
.driver_features = DRIVER_MODESET | DRIVER_GEM |
DRIVER_PRIME | DRIVER_ATOMIC,
.lastclose = rockchip_drm_lastclose,
.lastclose = drm_fb_helper_lastclose,
.gem_vm_ops = &drm_gem_cma_vm_ops,
.gem_free_object_unlocked = rockchip_gem_free_object,
.dumb_create = rockchip_gem_dumb_create,
......
......@@ -167,20 +167,13 @@ rockchip_user_fb_create(struct drm_device *dev, struct drm_file *file_priv,
return ERR_PTR(ret);
}
static void rockchip_drm_output_poll_changed(struct drm_device *dev)
{
struct rockchip_drm_private *private = dev->dev_private;
drm_fb_helper_hotplug_event(&private->fbdev_helper);
}
static const struct drm_mode_config_helper_funcs rockchip_mode_config_helpers = {
.atomic_commit_tail = drm_atomic_helper_commit_tail_rpm,
};
static const struct drm_mode_config_funcs rockchip_drm_mode_config_funcs = {
.fb_create = rockchip_user_fb_create,
.output_poll_changed = rockchip_drm_output_poll_changed,
.output_poll_changed = drm_fb_helper_output_poll_changed,
.atomic_check = drm_atomic_helper_check,
.atomic_commit = drm_atomic_helper_commit,
};
......
......@@ -17,6 +17,7 @@
#include <drm/drm_crtc_helper.h>
#include <drm/drm_gem_cma_helper.h>
#include <drm/drm_gem_framebuffer_helper.h>
#include <drm/drm_fb_helper.h>
#include <drm/drm_fb_cma_helper.h>
#include <drm/drm_of.h>
......@@ -138,16 +139,9 @@ static int sti_atomic_check(struct drm_device *dev,
return ret;
}
static void sti_output_poll_changed(struct drm_device *ddev)
{
struct sti_private *private = ddev->dev_private;
drm_fbdev_cma_hotplug_event(private->fbdev);
}
static const struct drm_mode_config_funcs sti_mode_config_funcs = {
.fb_create = drm_gem_fb_create,
.output_poll_changed = sti_output_poll_changed,
.output_poll_changed = drm_fb_helper_output_poll_changed,
.atomic_check = sti_atomic_check,
.atomic_commit = drm_atomic_helper_commit,
};
......@@ -230,11 +224,7 @@ static void sti_cleanup(struct drm_device *ddev)
{
struct sti_private *private = ddev->dev_private;
if (private->fbdev) {
drm_fbdev_cma_fini(private->fbdev);
private->fbdev = NULL;
}
drm_fb_cma_fbdev_fini(ddev);
drm_kms_helper_poll_fini(ddev);
component_unbind_all(ddev->dev, ddev);
kfree(private);
......@@ -244,8 +234,6 @@ static void sti_cleanup(struct drm_device *ddev)
static int sti_bind(struct device *dev)
{
struct drm_device *ddev;
struct sti_private *private;
struct drm_fbdev_cma *fbdev;
int ret;
ddev = drm_dev_alloc(&sti_driver, dev);
......@@ -266,15 +254,10 @@ static int sti_bind(struct device *dev)
drm_mode_config_reset(ddev);
private = ddev->dev_private;
if (ddev->mode_config.num_connector) {
fbdev = drm_fbdev_cma_init(ddev, 32,
ddev->mode_config.num_connector);
if (IS_ERR(fbdev)) {
ret = drm_fb_cma_fbdev_init(ddev, 32, 0);
if (ret)
DRM_DEBUG_DRIVER("Warning: fails to create fbdev\n");
fbdev = NULL;
}
private->fbdev = fbdev;
}
return 0;
......
......@@ -24,7 +24,6 @@ struct sti_private {
struct sti_compositor *compo;
struct drm_property *plane_zorder_property;
struct drm_device *drm_dev;
struct drm_fbdev_cma *fbdev;
};
extern struct platform_driver sti_tvout_driver;
......
......@@ -14,6 +14,7 @@
#include <drm/drm_atomic.h>
#include <drm/drm_atomic_helper.h>
#include <drm/drm_crtc_helper.h>
#include <drm/drm_fb_helper.h>
#include <drm/drm_fb_cma_helper.h>
#include <drm/drm_gem_cma_helper.h>
#include <drm/drm_gem_framebuffer_helper.h>
......@@ -23,35 +24,19 @@
#define STM_MAX_FB_WIDTH 2048
#define STM_MAX_FB_HEIGHT 2048 /* same as width to handle orientation */
static void drv_output_poll_changed(struct drm_device *ddev)
{
struct ltdc_device *ldev = ddev->dev_private;
drm_fbdev_cma_hotplug_event(ldev->fbdev);
}
static const struct drm_mode_config_funcs drv_mode_config_funcs = {
.fb_create = drm_gem_fb_create,
.output_poll_changed = drv_output_poll_changed,
.output_poll_changed = drm_fb_helper_output_poll_changed,
.atomic_check = drm_atomic_helper_check,
.atomic_commit = drm_atomic_helper_commit,
};
static void drv_lastclose(struct drm_device *ddev)
{
struct ltdc_device *ldev = ddev->dev_private;
DRM_DEBUG("%s\n", __func__);
drm_fbdev_cma_restore_mode(ldev->fbdev);
}
DEFINE_DRM_GEM_CMA_FOPS(drv_driver_fops);
static struct drm_driver drv_driver = {
.driver_features = DRIVER_MODESET | DRIVER_GEM | DRIVER_PRIME |
DRIVER_ATOMIC,
.lastclose = drv_lastclose,
.lastclose = drm_fb_helper_lastclose,
.name = "stm",
.desc = "STMicroelectronics SoC DRM",
.date = "20170330",
......@@ -78,7 +63,6 @@ static struct drm_driver drv_driver = {
static int drv_load(struct drm_device *ddev)
{
struct platform_device *pdev = to_platform_device(ddev->dev);
struct drm_fbdev_cma *fbdev;
struct ltdc_device *ldev;
int ret;
......@@ -111,14 +95,9 @@ static int drv_load(struct drm_device *ddev)
drm_kms_helper_poll_init(ddev);
if (ddev->mode_config.num_connector) {
ldev = ddev->dev_private;
fbdev = drm_fbdev_cma_init(ddev, 16,
ddev->mode_config.num_connector);
if (IS_ERR(fbdev)) {
ret = drm_fb_cma_fbdev_init(ddev, 16, 0);
if (ret)
DRM_DEBUG("Warning: fails to create fbdev\n");
fbdev = NULL;
}
ldev->fbdev = fbdev;
}
platform_set_drvdata(pdev, ddev);
......@@ -131,14 +110,9 @@ static int drv_load(struct drm_device *ddev)
static void drv_unload(struct drm_device *ddev)
{
struct ltdc_device *ldev = ddev->dev_private;
DRM_DEBUG("%s\n", __func__);
if (ldev->fbdev) {
drm_fbdev_cma_fini(ldev->fbdev);
ldev->fbdev = NULL;
}
drm_fb_cma_fbdev_fini(ddev);
drm_kms_helper_poll_fini(ddev);
ltdc_unload(ddev);
drm_mode_config_cleanup(ddev);
......
......@@ -20,7 +20,6 @@ struct ltdc_caps {
};
struct ltdc_device {
struct drm_fbdev_cma *fbdev;
void __iomem *regs;
struct clk *pixel_clk; /* lcd pixel clock */
struct mutex err_lock; /* protecting error_status */
......
......@@ -26,20 +26,13 @@
#include "sun4i_framebuffer.h"
#include "sun4i_tcon.h"
static void sun4i_drv_lastclose(struct drm_device *dev)
{
struct sun4i_drv *drv = dev->dev_private;
drm_fbdev_cma_restore_mode(drv->fbdev);
}
DEFINE_DRM_GEM_CMA_FOPS(sun4i_drv_fops);
static struct drm_driver sun4i_drv_driver = {
.driver_features = DRIVER_GEM | DRIVER_MODESET | DRIVER_PRIME | DRIVER_ATOMIC,
/* Generic Operations */
.lastclose = sun4i_drv_lastclose,
.lastclose = drm_fb_helper_lastclose,
.fops = &sun4i_drv_fops,
.name = "sun4i-drm",
.desc = "Allwinner sun4i Display Engine",
......@@ -126,10 +119,9 @@ static int sun4i_drv_bind(struct device *dev)
sun4i_remove_framebuffers();
/* Create our framebuffer */
drv->fbdev = sun4i_framebuffer_init(drm);
if (IS_ERR(drv->fbdev)) {
ret = sun4i_framebuffer_init(drm);
if (ret) {
dev_err(drm->dev, "Couldn't create our framebuffer\n");
ret = PTR_ERR(drv->fbdev);
goto cleanup_mode_config;
}
......
......@@ -20,8 +20,6 @@
struct sun4i_drv {
struct list_head engine_list;
struct list_head tcon_list;
struct drm_fbdev_cma *fbdev;
};
#endif /* _SUN4I_DRV_H_ */
......@@ -11,6 +11,7 @@
*/
#include <drm/drm_atomic_helper.h>
#include <drm/drm_fb_helper.h>
#include <drm/drm_fb_cma_helper.h>
#include <drm/drm_gem_framebuffer_helper.h>
#include <drm/drmP.h>
......@@ -18,21 +19,14 @@
#include "sun4i_drv.h"
#include "sun4i_framebuffer.h"
static void sun4i_de_output_poll_changed(struct drm_device *drm)
{
struct sun4i_drv *drv = drm->dev_private;
drm_fbdev_cma_hotplug_event(drv->fbdev);
}
static const struct drm_mode_config_funcs sun4i_de_mode_config_funcs = {
.output_poll_changed = sun4i_de_output_poll_changed,
.output_poll_changed = drm_fb_helper_output_poll_changed,
.atomic_check = drm_atomic_helper_check,
.atomic_commit = drm_atomic_helper_commit,
.fb_create = drm_gem_fb_create,
};
struct drm_fbdev_cma *sun4i_framebuffer_init(struct drm_device *drm)
int sun4i_framebuffer_init(struct drm_device *drm)
{
drm_mode_config_reset(drm);
......@@ -41,12 +35,10 @@ struct drm_fbdev_cma *sun4i_framebuffer_init(struct drm_device *drm)
drm->mode_config.funcs = &sun4i_de_mode_config_funcs;
return drm_fbdev_cma_init(drm, 32, drm->mode_config.num_connector);
return drm_fb_cma_fbdev_init(drm, 32, 0);
}
void sun4i_framebuffer_free(struct drm_device *drm)
{
struct sun4i_drv *drv = drm->dev_private;
drm_fbdev_cma_fini(drv->fbdev);
drm_fb_cma_fbdev_fini(drm);
}
......@@ -13,7 +13,7 @@
#ifndef _SUN4I_FRAMEBUFFER_H_
#define _SUN4I_FRAMEBUFFER_H_
struct drm_fbdev_cma *sun4i_framebuffer_init(struct drm_device *drm);
int sun4i_framebuffer_init(struct drm_device *drm);
void sun4i_framebuffer_free(struct drm_device *drm);
#endif /* _SUN4I_FRAMEBUFFER_H_ */
......@@ -120,7 +120,7 @@ static int tegra_atomic_commit(struct drm_device *drm,
static const struct drm_mode_config_funcs tegra_drm_mode_funcs = {
.fb_create = tegra_fb_create,
#ifdef CONFIG_DRM_FBDEV_EMULATION
.output_poll_changed = tegra_fb_output_poll_changed,
.output_poll_changed = drm_fb_helper_output_poll_changed,
#endif
.atomic_check = drm_atomic_helper_check,
.atomic_commit = tegra_atomic_commit,
......@@ -286,15 +286,6 @@ static void tegra_drm_context_free(struct tegra_drm_context *context)
kfree(context);
}
static void tegra_drm_lastclose(struct drm_device *drm)
{
#ifdef CONFIG_DRM_FBDEV_EMULATION
struct tegra_drm *tegra = drm->dev_private;
tegra_fbdev_restore_mode(tegra->fbdev);
#endif
}
static struct host1x_bo *
host1x_bo_lookup(struct drm_file *file, u32 handle)
{
......@@ -1100,7 +1091,7 @@ static struct drm_driver tegra_drm_driver = {
.unload = tegra_drm_unload,
.open = tegra_drm_open,
.postclose = tegra_drm_postclose,
.lastclose = tegra_drm_lastclose,
.lastclose = drm_fb_helper_lastclose,
#if defined(CONFIG_DEBUG_FS)
.debugfs_init = tegra_debugfs_init,
......
......@@ -188,10 +188,6 @@ int tegra_drm_fb_init(struct drm_device *drm);
void tegra_drm_fb_exit(struct drm_device *drm);
void tegra_drm_fb_suspend(struct drm_device *drm);
void tegra_drm_fb_resume(struct drm_device *drm);
#ifdef CONFIG_DRM_FBDEV_EMULATION
void tegra_fbdev_restore_mode(struct tegra_fbdev *fbdev);
void tegra_fb_output_poll_changed(struct drm_device *drm);
#endif
extern struct platform_driver tegra_dc_driver;
extern struct platform_driver tegra_hdmi_driver;
......
......@@ -361,20 +361,6 @@ static void tegra_fbdev_exit(struct tegra_fbdev *fbdev)
drm_fb_helper_fini(&fbdev->base);
tegra_fbdev_free(fbdev);
}
void tegra_fbdev_restore_mode(struct tegra_fbdev *fbdev)
{
if (fbdev)
drm_fb_helper_restore_fbdev_mode_unlocked(&fbdev->base);
}
void tegra_fb_output_poll_changed(struct drm_device *drm)
{
struct tegra_drm *tegra = drm->dev_private;
if (tegra->fbdev)
drm_fb_helper_hotplug_event(&tegra->fbdev->base);
}
#endif
int tegra_drm_fb_prepare(struct drm_device *drm)
......
......@@ -69,12 +69,6 @@ static struct drm_framebuffer *tilcdc_fb_create(struct drm_device *dev,
return drm_gem_fb_create(dev, file_priv, mode_cmd);
}
static void tilcdc_fb_output_poll_changed(struct drm_device *dev)
{
struct tilcdc_drm_private *priv = dev->dev_private;
drm_fbdev_cma_hotplug_event(priv->fbdev);
}
static int tilcdc_atomic_check(struct drm_device *dev,
struct drm_atomic_state *state)
{
......@@ -146,7 +140,7 @@ static int tilcdc_commit(struct drm_device *dev,
static const struct drm_mode_config_funcs mode_config_funcs = {
.fb_create = tilcdc_fb_create,
.output_poll_changed = tilcdc_fb_output_poll_changed,
.output_poll_changed = drm_fb_helper_output_poll_changed,
.atomic_check = tilcdc_atomic_check,
.atomic_commit = tilcdc_commit,
};
......@@ -198,8 +192,7 @@ static void tilcdc_fini(struct drm_device *dev)
drm_kms_helper_poll_fini(dev);
if (priv->fbdev)
drm_fbdev_cma_fini(priv->fbdev);
drm_fb_cma_fbdev_fini(dev);
drm_irq_uninstall(dev);
drm_mode_config_cleanup(dev);
......@@ -405,12 +398,9 @@ static int tilcdc_init(struct drm_driver *ddrv, struct device *dev)
drm_mode_config_reset(ddev);
priv->fbdev = drm_fbdev_cma_init(ddev, bpp,
ddev->mode_config.num_connector);
if (IS_ERR(priv->fbdev)) {
ret = PTR_ERR(priv->fbdev);
ret = drm_fb_cma_fbdev_init(ddev, bpp, 0);
if (ret)
goto init_failed;
}
drm_kms_helper_poll_init(ddev);
......@@ -427,12 +417,6 @@ static int tilcdc_init(struct drm_driver *ddrv, struct device *dev)
return ret;
}
static void tilcdc_lastclose(struct drm_device *dev)
{
struct tilcdc_drm_private *priv = dev->dev_private;
drm_fbdev_cma_restore_mode(priv->fbdev);
}
static irqreturn_t tilcdc_irq(int irq, void *arg)
{
struct drm_device *dev = arg;
......@@ -537,7 +521,7 @@ DEFINE_DRM_GEM_CMA_FOPS(fops);
static struct drm_driver tilcdc_driver = {
.driver_features = (DRIVER_HAVE_IRQ | DRIVER_GEM | DRIVER_MODESET |
DRIVER_PRIME | DRIVER_ATOMIC),
.lastclose = tilcdc_lastclose,
.lastclose = drm_fb_helper_lastclose,
.irq_handler = tilcdc_irq,
.gem_free_object_unlocked = drm_gem_cma_free_object,
.gem_print_info = drm_gem_cma_print_info,
......
......@@ -79,8 +79,6 @@ struct tilcdc_drm_private {
struct workqueue_struct *wq;
struct drm_fbdev_cma *fbdev;
struct drm_crtc *crtc;
unsigned int num_encoders;
......
......@@ -10,6 +10,7 @@
#include <drm/drm_atomic.h>
#include <drm/drm_atomic_helper.h>
#include <drm/drm_crtc_helper.h>
#include <drm/drm_fb_helper.h>
#include <drm/drm_gem_framebuffer_helper.h>
#include <drm/tinydrm/tinydrm.h>
#include <linux/device.h>
......@@ -35,23 +36,6 @@
* and registers the DRM device using devm_tinydrm_register().
*/
/**
* tinydrm_lastclose - DRM lastclose helper
* @drm: DRM device
*
* This function ensures that fbdev is restored when drm_lastclose() is called
* on the last drm_release(). Drivers can use this as their
* &drm_driver->lastclose callback.
*/
void tinydrm_lastclose(struct drm_device *drm)
{
struct tinydrm_device *tdev = drm->dev_private;
DRM_DEBUG_KMS("\n");
drm_fbdev_cma_restore_mode(tdev->fbdev_cma);
}
EXPORT_SYMBOL(tinydrm_lastclose);
/**
* tinydrm_gem_cma_prime_import_sg_table - Produce a CMA GEM object from
* another driver's scatter/gather table of pinned pages
......@@ -214,35 +198,24 @@ EXPORT_SYMBOL(devm_tinydrm_init);
static int tinydrm_register(struct tinydrm_device *tdev)
{
struct drm_device *drm = tdev->drm;
int bpp = drm->mode_config.preferred_depth;
struct drm_fbdev_cma *fbdev;
int ret;
ret = drm_dev_register(tdev->drm, 0);
if (ret)
return ret;
fbdev = drm_fbdev_cma_init_with_funcs(drm, bpp ? bpp : 32,
drm->mode_config.num_connector,
tdev->fb_funcs);
if (IS_ERR(fbdev))
DRM_ERROR("Failed to initialize fbdev: %ld\n", PTR_ERR(fbdev));
else
tdev->fbdev_cma = fbdev;
ret = drm_fb_cma_fbdev_init_with_funcs(drm, 0, 0, tdev->fb_funcs);
if (ret)
DRM_ERROR("Failed to initialize fbdev: %d\n", ret);
return 0;
}
static void tinydrm_unregister(struct tinydrm_device *tdev)
{
struct drm_fbdev_cma *fbdev_cma = tdev->fbdev_cma;
drm_atomic_helper_shutdown(tdev->drm);
/* don't restore fbdev in lastclose, keep pipeline disabled */
tdev->fbdev_cma = NULL;
drm_fb_cma_fbdev_fini(tdev->drm);
drm_dev_unregister(tdev->drm);
if (fbdev_cma)
drm_fbdev_cma_fini(fbdev_cma);
}
static void devm_tinydrm_register_release(void *data)
......
......@@ -20,6 +20,7 @@
#include <linux/spi/spi.h>
#include <video/mipi_display.h>
#include <drm/drm_fb_helper.h>
#include <drm/drm_gem_framebuffer_helper.h>
#include <drm/tinydrm/mipi-dbi.h>
#include <drm/tinydrm/tinydrm-helpers.h>
......@@ -381,7 +382,7 @@ static struct drm_driver ili9225_driver = {
DRIVER_ATOMIC,
.fops = &ili9225_fops,
TINYDRM_GEM_DRIVER_OPS,
.lastclose = tinydrm_lastclose,
.lastclose = drm_fb_helper_lastclose,
.name = "ili9225",
.desc = "Ilitek ILI9225",
.date = "20171106",
......
......@@ -9,6 +9,7 @@
* (at your option) any later version.
*/
#include <drm/drm_fb_helper.h>
#include <drm/drm_modeset_helper.h>
#include <drm/tinydrm/ili9341.h>
#include <drm/tinydrm/mipi-dbi.h>
......@@ -140,7 +141,7 @@ static struct drm_driver mi0283qt_driver = {
DRIVER_ATOMIC,
.fops = &mi0283qt_fops,
TINYDRM_GEM_DRIVER_OPS,
.lastclose = tinydrm_lastclose,
.lastclose = drm_fb_helper_lastclose,
.debugfs_init = mipi_dbi_debugfs_init,
.name = "mi0283qt",
.desc = "Multi-Inno MI0283QT",
......
......@@ -17,6 +17,7 @@
#include <linux/spi/spi.h>
#include <video/mipi_display.h>
#include <drm/drm_fb_helper.h>
#include <drm/drm_gem_framebuffer_helper.h>
#include <drm/tinydrm/mipi-dbi.h>
#include <drm/tinydrm/tinydrm-helpers.h>
......@@ -320,7 +321,7 @@ static struct drm_driver st7586_driver = {
DRIVER_ATOMIC,
.fops = &st7586_fops,
TINYDRM_GEM_DRIVER_OPS,
.lastclose = tinydrm_lastclose,
.lastclose = drm_fb_helper_lastclose,
.debugfs_init = mipi_dbi_debugfs_init,
.name = "st7586",
.desc = "Sitronix ST7586",
......
......@@ -103,7 +103,6 @@ struct tve200_drm_dev_private {
struct drm_panel *panel;
struct drm_bridge *bridge;
struct drm_simple_display_pipe pipe;
struct drm_fbdev_cma *fbdev;
void *regs;
struct clk *pclk;
......
......@@ -46,6 +46,7 @@
#include <drm/drm_crtc_helper.h>
#include <drm/drm_gem_cma_helper.h>
#include <drm/drm_gem_framebuffer_helper.h>
#include <drm/drm_fb_helper.h>
#include <drm/drm_fb_cma_helper.h>
#include <drm/drm_panel.h>
#include <drm/drm_of.h>
......@@ -130,8 +131,7 @@ static int tve200_modeset_init(struct drm_device *dev)
* Passing in 16 here will make the RGB656 mode the default
* Passing in 32 will use XRGB8888 mode
*/
priv->fbdev = drm_fbdev_cma_init(dev, 16,
dev->mode_config.num_connector);
drm_fb_cma_fbdev_init(dev, 16, 0);
drm_kms_helper_poll_init(dev);
goto finish;
......@@ -146,17 +146,10 @@ static int tve200_modeset_init(struct drm_device *dev)
DEFINE_DRM_GEM_CMA_FOPS(drm_fops);
static void tve200_lastclose(struct drm_device *dev)
{
struct tve200_drm_dev_private *priv = dev->dev_private;
drm_fbdev_cma_restore_mode(priv->fbdev);
}
static struct drm_driver tve200_drm_driver = {
.driver_features =
DRIVER_MODESET | DRIVER_GEM | DRIVER_PRIME | DRIVER_ATOMIC,
.lastclose = tve200_lastclose,
.lastclose = drm_fb_helper_lastclose,
.ioctls = NULL,
.fops = &drm_fops,
.name = "tve200",
......@@ -270,8 +263,7 @@ static int tve200_remove(struct platform_device *pdev)
struct tve200_drm_dev_private *priv = drm->dev_private;
drm_dev_unregister(drm);
if (priv->fbdev)
drm_fbdev_cma_fini(priv->fbdev);
drm_fb_cma_fbdev_fini(drm);
if (priv->panel)
drm_panel_bridge_remove(priv->bridge);
drm_mode_config_cleanup(drm);
......
......@@ -111,13 +111,6 @@ static int vc4_get_param_ioctl(struct drm_device *dev, void *data,
return 0;
}
static void vc4_lastclose(struct drm_device *dev)
{
struct vc4_dev *vc4 = to_vc4_dev(dev);
drm_fbdev_cma_restore_mode(vc4->fbdev);
}
static const struct vm_operations_struct vc4_vm_ops = {
.fault = vc4_fault,
.open = drm_gem_vm_open,
......@@ -159,7 +152,7 @@ static struct drm_driver vc4_drm_driver = {
DRIVER_HAVE_IRQ |
DRIVER_RENDER |
DRIVER_PRIME),
.lastclose = vc4_lastclose,
.lastclose = drm_fb_helper_lastclose,
.irq_handler = vc4_irq,
.irq_preinstall = vc4_irq_preinstall,
.irq_postinstall = vc4_irq_postinstall,
......@@ -301,12 +294,10 @@ static void vc4_drm_unbind(struct device *dev)
{
struct platform_device *pdev = to_platform_device(dev);
struct drm_device *drm = platform_get_drvdata(pdev);
struct vc4_dev *vc4 = to_vc4_dev(drm);
drm_dev_unregister(drm);
if (vc4->fbdev)
drm_fbdev_cma_fini(vc4->fbdev);
drm_fb_cma_fbdev_fini(drm);
drm_mode_config_cleanup(drm);
......
......@@ -39,8 +39,6 @@ struct vc4_dev {
struct vc4_dsi *dsi1;
struct vc4_vec *vec;
struct drm_fbdev_cma *fbdev;
struct vc4_hang_state *hang_state;
/* The kernel-space BO cache. Tracks buffers that have been
......
......@@ -19,17 +19,11 @@
#include <drm/drm_atomic_helper.h>
#include <drm/drm_crtc_helper.h>
#include <drm/drm_plane_helper.h>
#include <drm/drm_fb_helper.h>
#include <drm/drm_fb_cma_helper.h>
#include <drm/drm_gem_framebuffer_helper.h>
#include "vc4_drv.h"
static void vc4_output_poll_changed(struct drm_device *dev)
{
struct vc4_dev *vc4 = to_vc4_dev(dev);
drm_fbdev_cma_hotplug_event(vc4->fbdev);
}
static void
vc4_atomic_complete_commit(struct drm_atomic_state *state)
{
......@@ -194,7 +188,7 @@ static struct drm_framebuffer *vc4_fb_create(struct drm_device *dev,
}
static const struct drm_mode_config_funcs vc4_mode_funcs = {
.output_poll_changed = vc4_output_poll_changed,
.output_poll_changed = drm_fb_helper_output_poll_changed,
.atomic_check = drm_atomic_helper_check,
.atomic_commit = vc4_atomic_commit,
.fb_create = vc4_fb_create,
......@@ -224,12 +218,8 @@ int vc4_kms_load(struct drm_device *dev)
drm_mode_config_reset(dev);
if (dev->mode_config.num_connector) {
vc4->fbdev = drm_fbdev_cma_init(dev, 32,
dev->mode_config.num_connector);
if (IS_ERR(vc4->fbdev))
vc4->fbdev = NULL;
}
if (dev->mode_config.num_connector)
drm_fb_cma_fbdev_init(dev, 32, 0);
drm_kms_helper_poll_init(dev);
......
......@@ -29,37 +29,19 @@
#include "zx_drm_drv.h"
#include "zx_vou.h"
struct zx_drm_private {
struct drm_fbdev_cma *fbdev;
};
static void zx_drm_fb_output_poll_changed(struct drm_device *drm)
{
struct zx_drm_private *priv = drm->dev_private;
drm_fbdev_cma_hotplug_event(priv->fbdev);
}
static const struct drm_mode_config_funcs zx_drm_mode_config_funcs = {
.fb_create = drm_gem_fb_create,
.output_poll_changed = zx_drm_fb_output_poll_changed,
.output_poll_changed = drm_fb_helper_output_poll_changed,
.atomic_check = drm_atomic_helper_check,
.atomic_commit = drm_atomic_helper_commit,
};
static void zx_drm_lastclose(struct drm_device *drm)
{
struct zx_drm_private *priv = drm->dev_private;
drm_fbdev_cma_restore_mode(priv->fbdev);
}
DEFINE_DRM_GEM_CMA_FOPS(zx_drm_fops);
static struct drm_driver zx_drm_driver = {
.driver_features = DRIVER_GEM | DRIVER_MODESET | DRIVER_PRIME |
DRIVER_ATOMIC,
.lastclose = zx_drm_lastclose,
.lastclose = drm_fb_helper_lastclose,
.gem_free_object_unlocked = drm_gem_cma_free_object,
.gem_vm_ops = &drm_gem_cma_vm_ops,
.dumb_create = drm_gem_cma_dumb_create,
......@@ -83,18 +65,12 @@ static struct drm_driver zx_drm_driver = {
static int zx_drm_bind(struct device *dev)
{
struct drm_device *drm;
struct zx_drm_private *priv;
int ret;
priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
if (!priv)
return -ENOMEM;
drm = drm_dev_alloc(&zx_drm_driver, dev);
if (IS_ERR(drm))
return PTR_ERR(drm);
drm->dev_private = priv;
dev_set_drvdata(dev, drm);
drm_mode_config_init(drm);
......@@ -125,12 +101,9 @@ static int zx_drm_bind(struct device *dev)
drm_mode_config_reset(drm);
drm_kms_helper_poll_init(drm);
priv->fbdev = drm_fbdev_cma_init(drm, 32,
drm->mode_config.num_connector);
if (IS_ERR(priv->fbdev)) {
ret = PTR_ERR(priv->fbdev);
ret = drm_fb_cma_fbdev_init(drm, 32, 0);
if (ret) {
DRM_DEV_ERROR(dev, "failed to init cma fbdev: %d\n", ret);
priv->fbdev = NULL;
goto out_poll_fini;
}
......@@ -141,10 +114,7 @@ static int zx_drm_bind(struct device *dev)
return 0;
out_fbdev_fini:
if (priv->fbdev) {
drm_fbdev_cma_fini(priv->fbdev);
priv->fbdev = NULL;
}
drm_fb_cma_fbdev_fini(drm);
out_poll_fini:
drm_kms_helper_poll_fini(drm);
drm_mode_config_cleanup(drm);
......@@ -152,7 +122,6 @@ static int zx_drm_bind(struct device *dev)
component_unbind_all(dev, drm);
out_unregister:
dev_set_drvdata(dev, NULL);
drm->dev_private = NULL;
drm_dev_unref(drm);
return ret;
}
......@@ -160,18 +129,13 @@ static int zx_drm_bind(struct device *dev)
static void zx_drm_unbind(struct device *dev)
{
struct drm_device *drm = dev_get_drvdata(dev);
struct zx_drm_private *priv = drm->dev_private;
drm_dev_unregister(drm);
if (priv->fbdev) {
drm_fbdev_cma_fini(priv->fbdev);
priv->fbdev = NULL;
}
drm_fb_cma_fbdev_fini(drm);
drm_kms_helper_poll_fini(drm);
drm_mode_config_cleanup(drm);
component_unbind_all(dev, drm);
dev_set_drvdata(dev, NULL);
drm->dev_private = NULL;
drm_dev_unref(drm);
}
......
......@@ -465,6 +465,8 @@ struct edid *drm_get_edid(struct drm_connector *connector,
struct edid *drm_get_edid_switcheroo(struct drm_connector *connector,
struct i2c_adapter *adapter);
struct edid *drm_edid_duplicate(const struct edid *edid);
void drm_reset_display_info(struct drm_connector *connector);
u32 drm_add_display_info(struct drm_connector *connector, const struct edid *edid);
int drm_add_edid_modes(struct drm_connector *connector, struct edid *edid);
u8 drm_match_cea_mode(const struct drm_display_mode *to_match);
......
......@@ -16,6 +16,13 @@ struct drm_mode_fb_cmd2;
struct drm_plane;
struct drm_plane_state;
int drm_fb_cma_fbdev_init_with_funcs(struct drm_device *dev,
unsigned int preferred_bpp, unsigned int max_conn_count,
const struct drm_framebuffer_funcs *funcs);
int drm_fb_cma_fbdev_init(struct drm_device *dev, unsigned int preferred_bpp,
unsigned int max_conn_count);
void drm_fb_cma_fbdev_fini(struct drm_device *dev);
struct drm_fbdev_cma *drm_fbdev_cma_init_with_funcs(struct drm_device *dev,
unsigned int preferred_bpp, unsigned int max_conn_count,
const struct drm_framebuffer_funcs *funcs);
......
......@@ -19,14 +19,12 @@
* @drm: DRM device
* @pipe: Display pipe structure
* @dirty_lock: Serializes framebuffer flushing
* @fbdev_cma: CMA fbdev structure
* @fb_funcs: Framebuffer functions used when creating framebuffers
*/
struct tinydrm_device {
struct drm_device *drm;
struct drm_simple_display_pipe pipe;
struct mutex dirty_lock;
struct drm_fbdev_cma *fbdev_cma;
const struct drm_framebuffer_funcs *fb_funcs;
};
......@@ -80,7 +78,6 @@ pipe_to_tinydrm(struct drm_simple_display_pipe *pipe)
.type = DRM_MODE_TYPE_DRIVER, \
.clock = 1 /* pass validation */
void tinydrm_lastclose(struct drm_device *drm);
void tinydrm_gem_cma_free_object(struct drm_gem_object *gem_obj);
struct drm_gem_object *
tinydrm_gem_cma_prime_import_sg_table(struct drm_device *drm,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment