mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git
synced 2025-01-17 22:05:08 +00:00
- Add default modes for connectors in unknown state
- R-Car DU conversion to DRM-managed API - R-Car DU miscellaneous fixes - Miscellaneous bridge and bridge bindings fixes - Assorted misc driver cleanups - Constify drm_driver for PCI devices -----BEGIN PGP SIGNATURE----- iQJWBAABCgBAFiEEy51od1KYIM1TCZsbZficN7xUIQ0FAl/z+e0iHGxhdXJlbnQu cGluY2hhcnRAaWRlYXNvbmJvYXJkLmNvbQAKCRBl+Jw3vFQhDc4jEAC0jEoDN8IK dEF/3DrG7P6v5FDk/+XqEkXYXLq/lJAVVKialQOn0mWYpdHOZn3POww7RM2qmvkp M3pJHx915Gq+McrAIehVuA8DFTIblUvX8iJYFhfXnIDJPccd2nCl34P914B8y4X+ jEJxDu5eHaiEavUrWttGOJQfP80V0b2pGFD1m85WA3DOtpgKFK12l3UqVrOIIYp3 kwaDYCN29hImmSOM1+PJjna2ZTaY1sJ4SWJzl5yHHLzWw6kf2RuA6hkMvhDuCZWW C/NlN4vYYDQKteMzG5jI1eijjkR0nl0S8MmS+ZMh2vPfDkDDnweZwKHbPZ90BLJi 5yd6OeVkhFIn75JQk8XDEwYnsAAdK6CWsfKscCsemda7TPL9J7xniSuWUKTuG9TM axJl2/VLxpO/99vGA1yBByg4Ypuq3tY2iPFWVKgSPZ5F4di28Q5ZJzkv1Ul9CJoK 7gHLk2ZM4bnsaNxhGjQB1IMZwnfBpmrddXQYDBPGvUpGDX3K4dJItA+vGR5FnKAH pJSC+C1JPI6OzDH6MLg4uolMFR3iMpnqffHtpLl/ElwbNk9VP6qArfihNmdYicgT UNbsQnOLCA9NBmGTaEy78DOzgrgvtxvc8KvUyXlgiXy8DWLwkShVgWoI4FJw7cTQ xxd6CER00mi43i6NfxNBnlO0vMLY4bPeeA== =eQ9W -----END PGP SIGNATURE----- Merge tag 'du-next-20210105' of git://linuxtv.org/pinchartl/media into drm-next - Add default modes for connectors in unknown state - R-Car DU conversion to DRM-managed API - R-Car DU miscellaneous fixes - Miscellaneous bridge and bridge bindings fixes - Assorted misc driver cleanups - Constify drm_driver for PCI devices Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch> From: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Link: https://patchwork.freedesktop.org/patch/msgid/X/P8IOrVXkTpLeCm@pendragon.ideasonboard.com
This commit is contained in:
commit
73dc923eeb
@ -83,9 +83,9 @@ properties:
|
|||||||
$ref: /schemas/types.yaml#/definitions/phandle
|
$ref: /schemas/types.yaml#/definitions/phandle
|
||||||
description:
|
description:
|
||||||
phandle to the companion LVDS encoder. This property is mandatory
|
phandle to the companion LVDS encoder. This property is mandatory
|
||||||
for the first LVDS encoder on D3 and E3 SoCs, and shall point to
|
for the first LVDS encoder on R-Car D3 and E3, and RZ/G2E SoCs, and shall
|
||||||
the second encoder to be used as a companion in dual-link mode. It
|
point to the second encoder to be used as a companion in dual-link mode.
|
||||||
shall not be set for any other LVDS encoder.
|
It shall not be set for any other LVDS encoder.
|
||||||
|
|
||||||
required:
|
required:
|
||||||
- compatible
|
- compatible
|
||||||
|
@ -30,11 +30,17 @@ properties:
|
|||||||
This device has four video ports. Their connections are modeled using the
|
This device has four video ports. Their connections are modeled using the
|
||||||
OF graph bindings specified in Documentation/devicetree/bindings/graph.txt.
|
OF graph bindings specified in Documentation/devicetree/bindings/graph.txt.
|
||||||
|
|
||||||
The device can operate in single-link mode or dual-link mode. In
|
The device can operate in single or dual input and output modes.
|
||||||
single-link mode, all pixels are received on port@0, and port@1 shall not
|
|
||||||
contain any endpoint. In dual-link mode, even-numbered pixels are
|
When operating in single input mode, all pixels are received on port@0,
|
||||||
received on port@0 and odd-numbered pixels on port@1, and both port@0 and
|
and port@1 shall not contain any endpoint. In dual input mode,
|
||||||
port@1 shall contain endpoints.
|
even-numbered pixels are received on port@0 and odd-numbered pixels on
|
||||||
|
port@1, and both port@0 and port@1 shall contain endpoints.
|
||||||
|
|
||||||
|
When operating in single output mode all pixels are output from the first
|
||||||
|
CMOS/TTL port and port@3 shall not contain any endpoint. In dual output
|
||||||
|
mode pixels are output from both CMOS/TTL ports and both port@2 and
|
||||||
|
port@3 shall contain endpoints.
|
||||||
|
|
||||||
properties:
|
properties:
|
||||||
'#address-cells':
|
'#address-cells':
|
||||||
|
@ -162,15 +162,10 @@ static const struct drm_plane_helper_funcs arc_pgu_plane_helper_funcs = {
|
|||||||
.atomic_update = arc_pgu_plane_atomic_update,
|
.atomic_update = arc_pgu_plane_atomic_update,
|
||||||
};
|
};
|
||||||
|
|
||||||
static void arc_pgu_plane_destroy(struct drm_plane *plane)
|
|
||||||
{
|
|
||||||
drm_plane_cleanup(plane);
|
|
||||||
}
|
|
||||||
|
|
||||||
static const struct drm_plane_funcs arc_pgu_plane_funcs = {
|
static const struct drm_plane_funcs arc_pgu_plane_funcs = {
|
||||||
.update_plane = drm_atomic_helper_update_plane,
|
.update_plane = drm_atomic_helper_update_plane,
|
||||||
.disable_plane = drm_atomic_helper_disable_plane,
|
.disable_plane = drm_atomic_helper_disable_plane,
|
||||||
.destroy = arc_pgu_plane_destroy,
|
.destroy = drm_plane_cleanup,
|
||||||
.reset = drm_atomic_helper_plane_reset,
|
.reset = drm_atomic_helper_plane_reset,
|
||||||
.atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state,
|
.atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state,
|
||||||
.atomic_destroy_state = drm_atomic_helper_plane_destroy_state,
|
.atomic_destroy_state = drm_atomic_helper_plane_destroy_state,
|
||||||
@ -213,7 +208,7 @@ int arc_pgu_setup_crtc(struct drm_device *drm)
|
|||||||
ret = drm_crtc_init_with_planes(drm, &arcpgu->crtc, primary, NULL,
|
ret = drm_crtc_init_with_planes(drm, &arcpgu->crtc, primary, NULL,
|
||||||
&arc_pgu_crtc_funcs, NULL);
|
&arc_pgu_crtc_funcs, NULL);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
arc_pgu_plane_destroy(primary);
|
drm_plane_cleanup(primary);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -145,7 +145,7 @@ static void arcpgu_debugfs_init(struct drm_minor *minor)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static struct drm_driver arcpgu_drm_driver = {
|
static const struct drm_driver arcpgu_drm_driver = {
|
||||||
.driver_features = DRIVER_MODESET | DRIVER_GEM | DRIVER_ATOMIC,
|
.driver_features = DRIVER_MODESET | DRIVER_GEM | DRIVER_ATOMIC,
|
||||||
.name = "arcpgu",
|
.name = "arcpgu",
|
||||||
.desc = "ARC PGU Controller",
|
.desc = "ARC PGU Controller",
|
||||||
|
@ -1292,8 +1292,7 @@ static int adv7511_probe(struct i2c_client *i2c, const struct i2c_device_id *id)
|
|||||||
|
|
||||||
err_unregister_cec:
|
err_unregister_cec:
|
||||||
i2c_unregister_device(adv7511->i2c_cec);
|
i2c_unregister_device(adv7511->i2c_cec);
|
||||||
if (adv7511->cec_clk)
|
clk_disable_unprepare(adv7511->cec_clk);
|
||||||
clk_disable_unprepare(adv7511->cec_clk);
|
|
||||||
err_i2c_unregister_packet:
|
err_i2c_unregister_packet:
|
||||||
i2c_unregister_device(adv7511->i2c_packet);
|
i2c_unregister_device(adv7511->i2c_packet);
|
||||||
err_i2c_unregister_edid:
|
err_i2c_unregister_edid:
|
||||||
@ -1311,8 +1310,7 @@ static int adv7511_remove(struct i2c_client *i2c)
|
|||||||
if (adv7511->type == ADV7533 || adv7511->type == ADV7535)
|
if (adv7511->type == ADV7533 || adv7511->type == ADV7535)
|
||||||
adv7533_detach_dsi(adv7511);
|
adv7533_detach_dsi(adv7511);
|
||||||
i2c_unregister_device(adv7511->i2c_cec);
|
i2c_unregister_device(adv7511->i2c_cec);
|
||||||
if (adv7511->cec_clk)
|
clk_disable_unprepare(adv7511->cec_clk);
|
||||||
clk_disable_unprepare(adv7511->cec_clk);
|
|
||||||
|
|
||||||
adv7511_uninit_regulators(adv7511);
|
adv7511_uninit_regulators(adv7511);
|
||||||
|
|
||||||
|
@ -3440,8 +3440,7 @@ struct dw_hdmi *dw_hdmi_probe(struct platform_device *pdev,
|
|||||||
|
|
||||||
err_iahb:
|
err_iahb:
|
||||||
clk_disable_unprepare(hdmi->iahb_clk);
|
clk_disable_unprepare(hdmi->iahb_clk);
|
||||||
if (hdmi->cec_clk)
|
clk_disable_unprepare(hdmi->cec_clk);
|
||||||
clk_disable_unprepare(hdmi->cec_clk);
|
|
||||||
err_isfr:
|
err_isfr:
|
||||||
clk_disable_unprepare(hdmi->isfr_clk);
|
clk_disable_unprepare(hdmi->isfr_clk);
|
||||||
err_res:
|
err_res:
|
||||||
@ -3465,8 +3464,7 @@ void dw_hdmi_remove(struct dw_hdmi *hdmi)
|
|||||||
|
|
||||||
clk_disable_unprepare(hdmi->iahb_clk);
|
clk_disable_unprepare(hdmi->iahb_clk);
|
||||||
clk_disable_unprepare(hdmi->isfr_clk);
|
clk_disable_unprepare(hdmi->isfr_clk);
|
||||||
if (hdmi->cec_clk)
|
clk_disable_unprepare(hdmi->cec_clk);
|
||||||
clk_disable_unprepare(hdmi->cec_clk);
|
|
||||||
|
|
||||||
if (hdmi->i2c)
|
if (hdmi->i2c)
|
||||||
i2c_del_adapter(&hdmi->i2c->adap);
|
i2c_del_adapter(&hdmi->i2c->adap);
|
||||||
|
@ -202,7 +202,7 @@ static int thc63_probe(struct platform_device *pdev)
|
|||||||
thc63->dev = &pdev->dev;
|
thc63->dev = &pdev->dev;
|
||||||
platform_set_drvdata(pdev, thc63);
|
platform_set_drvdata(pdev, thc63);
|
||||||
|
|
||||||
thc63->vcc = devm_regulator_get_optional(thc63->dev, "vcc");
|
thc63->vcc = devm_regulator_get(thc63->dev, "vcc");
|
||||||
if (IS_ERR(thc63->vcc)) {
|
if (IS_ERR(thc63->vcc)) {
|
||||||
if (PTR_ERR(thc63->vcc) == -EPROBE_DEFER)
|
if (PTR_ERR(thc63->vcc) == -EPROBE_DEFER)
|
||||||
return -EPROBE_DEFER;
|
return -EPROBE_DEFER;
|
||||||
|
@ -589,11 +589,7 @@ static int drm_dev_init(struct drm_device *dev,
|
|||||||
|
|
||||||
kref_init(&dev->ref);
|
kref_init(&dev->ref);
|
||||||
dev->dev = get_device(parent);
|
dev->dev = get_device(parent);
|
||||||
#ifdef CONFIG_DRM_LEGACY
|
|
||||||
dev->driver = (struct drm_driver *)driver;
|
|
||||||
#else
|
|
||||||
dev->driver = driver;
|
dev->driver = driver;
|
||||||
#endif
|
|
||||||
|
|
||||||
INIT_LIST_HEAD(&dev->managed.resources);
|
INIT_LIST_HEAD(&dev->managed.resources);
|
||||||
spin_lock_init(&dev->managed.lock);
|
spin_lock_init(&dev->managed.lock);
|
||||||
|
@ -29,6 +29,7 @@
|
|||||||
#include <drm/drm_mode.h>
|
#include <drm/drm_mode.h>
|
||||||
|
|
||||||
#include "drm_crtc_internal.h"
|
#include "drm_crtc_internal.h"
|
||||||
|
#include "drm_internal.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* DOC: overview
|
* DOC: overview
|
||||||
@ -46,9 +47,10 @@
|
|||||||
* KMS frame buffers.
|
* KMS frame buffers.
|
||||||
*
|
*
|
||||||
* To support dumb objects drivers must implement the &drm_driver.dumb_create
|
* To support dumb objects drivers must implement the &drm_driver.dumb_create
|
||||||
* operation. &drm_driver.dumb_destroy defaults to drm_gem_dumb_destroy() if
|
* and &drm_driver.dumb_map_offset operations (the latter defaults to
|
||||||
* not set and &drm_driver.dumb_map_offset defaults to
|
* drm_gem_dumb_map_offset() if not set). Drivers that don't use GEM handles
|
||||||
* drm_gem_dumb_map_offset(). See the callbacks for further details.
|
* additionally need to implement the &drm_driver.dumb_destroy operation. See
|
||||||
|
* the callbacks for further details.
|
||||||
*
|
*
|
||||||
* Note that dumb objects may not be used for gpu acceleration, as has been
|
* Note that dumb objects may not be used for gpu acceleration, as has been
|
||||||
* attempted on some ARM embedded platforms. Such drivers really must have
|
* attempted on some ARM embedded platforms. Such drivers really must have
|
||||||
|
@ -335,22 +335,12 @@ out:
|
|||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(drm_gem_dumb_map_offset);
|
EXPORT_SYMBOL_GPL(drm_gem_dumb_map_offset);
|
||||||
|
|
||||||
/**
|
|
||||||
* drm_gem_dumb_destroy - dumb fb callback helper for gem based drivers
|
|
||||||
* @file: drm file-private structure to remove the dumb handle from
|
|
||||||
* @dev: corresponding drm_device
|
|
||||||
* @handle: the dumb handle to remove
|
|
||||||
*
|
|
||||||
* This implements the &drm_driver.dumb_destroy kms driver callback for drivers
|
|
||||||
* which use gem to manage their backing storage.
|
|
||||||
*/
|
|
||||||
int drm_gem_dumb_destroy(struct drm_file *file,
|
int drm_gem_dumb_destroy(struct drm_file *file,
|
||||||
struct drm_device *dev,
|
struct drm_device *dev,
|
||||||
uint32_t handle)
|
u32 handle)
|
||||||
{
|
{
|
||||||
return drm_gem_handle_delete(file, handle);
|
return drm_gem_handle_delete(file, handle);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(drm_gem_dumb_destroy);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* drm_gem_handle_create_tail - internal functions to create a handle
|
* drm_gem_handle_create_tail - internal functions to create a handle
|
||||||
|
@ -191,6 +191,9 @@ void drm_gem_unpin(struct drm_gem_object *obj);
|
|||||||
int drm_gem_vmap(struct drm_gem_object *obj, struct dma_buf_map *map);
|
int drm_gem_vmap(struct drm_gem_object *obj, struct dma_buf_map *map);
|
||||||
void drm_gem_vunmap(struct drm_gem_object *obj, struct dma_buf_map *map);
|
void drm_gem_vunmap(struct drm_gem_object *obj, struct dma_buf_map *map);
|
||||||
|
|
||||||
|
int drm_gem_dumb_destroy(struct drm_file *file, struct drm_device *dev,
|
||||||
|
u32 handle);
|
||||||
|
|
||||||
/* drm_debugfs.c drm_debugfs_crc.c */
|
/* drm_debugfs.c drm_debugfs_crc.c */
|
||||||
#if defined(CONFIG_DEBUG_FS)
|
#if defined(CONFIG_DEBUG_FS)
|
||||||
int drm_debugfs_init(struct drm_minor *minor, int minor_id,
|
int drm_debugfs_init(struct drm_minor *minor, int minor_id,
|
||||||
|
@ -24,6 +24,8 @@
|
|||||||
|
|
||||||
#include <linux/dma-mapping.h>
|
#include <linux/dma-mapping.h>
|
||||||
#include <linux/export.h>
|
#include <linux/export.h>
|
||||||
|
#include <linux/list.h>
|
||||||
|
#include <linux/mutex.h>
|
||||||
#include <linux/pci.h>
|
#include <linux/pci.h>
|
||||||
#include <linux/slab.h>
|
#include <linux/slab.h>
|
||||||
|
|
||||||
@ -36,6 +38,9 @@
|
|||||||
#include "drm_legacy.h"
|
#include "drm_legacy.h"
|
||||||
|
|
||||||
#ifdef CONFIG_DRM_LEGACY
|
#ifdef CONFIG_DRM_LEGACY
|
||||||
|
/* List of devices hanging off drivers with stealth attach. */
|
||||||
|
static LIST_HEAD(legacy_dev_list);
|
||||||
|
static DEFINE_MUTEX(legacy_dev_list_lock);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* drm_pci_alloc - Allocate a PCI consistent memory block, for DMA.
|
* drm_pci_alloc - Allocate a PCI consistent memory block, for DMA.
|
||||||
@ -196,7 +201,7 @@ static void drm_pci_agp_init(struct drm_device *dev)
|
|||||||
|
|
||||||
static int drm_get_pci_dev(struct pci_dev *pdev,
|
static int drm_get_pci_dev(struct pci_dev *pdev,
|
||||||
const struct pci_device_id *ent,
|
const struct pci_device_id *ent,
|
||||||
struct drm_driver *driver)
|
const struct drm_driver *driver)
|
||||||
{
|
{
|
||||||
struct drm_device *dev;
|
struct drm_device *dev;
|
||||||
int ret;
|
int ret;
|
||||||
@ -225,10 +230,11 @@ static int drm_get_pci_dev(struct pci_dev *pdev,
|
|||||||
if (ret)
|
if (ret)
|
||||||
goto err_agp;
|
goto err_agp;
|
||||||
|
|
||||||
/* No locking needed since shadow-attach is single-threaded since it may
|
if (drm_core_check_feature(dev, DRIVER_LEGACY)) {
|
||||||
* only be called from the per-driver module init hook. */
|
mutex_lock(&legacy_dev_list_lock);
|
||||||
if (drm_core_check_feature(dev, DRIVER_LEGACY))
|
list_add_tail(&dev->legacy_dev_list, &legacy_dev_list);
|
||||||
list_add_tail(&dev->legacy_dev_list, &driver->legacy_dev_list);
|
mutex_unlock(&legacy_dev_list_lock);
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
@ -249,7 +255,8 @@ err_free:
|
|||||||
*
|
*
|
||||||
* Return: 0 on success or a negative error code on failure.
|
* Return: 0 on success or a negative error code on failure.
|
||||||
*/
|
*/
|
||||||
int drm_legacy_pci_init(struct drm_driver *driver, struct pci_driver *pdriver)
|
int drm_legacy_pci_init(const struct drm_driver *driver,
|
||||||
|
struct pci_driver *pdriver)
|
||||||
{
|
{
|
||||||
struct pci_dev *pdev = NULL;
|
struct pci_dev *pdev = NULL;
|
||||||
const struct pci_device_id *pid;
|
const struct pci_device_id *pid;
|
||||||
@ -261,7 +268,6 @@ int drm_legacy_pci_init(struct drm_driver *driver, struct pci_driver *pdriver)
|
|||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
/* If not using KMS, fall back to stealth mode manual scanning. */
|
/* If not using KMS, fall back to stealth mode manual scanning. */
|
||||||
INIT_LIST_HEAD(&driver->legacy_dev_list);
|
|
||||||
for (i = 0; pdriver->id_table[i].vendor != 0; i++) {
|
for (i = 0; pdriver->id_table[i].vendor != 0; i++) {
|
||||||
pid = &pdriver->id_table[i];
|
pid = &pdriver->id_table[i];
|
||||||
|
|
||||||
@ -295,7 +301,8 @@ EXPORT_SYMBOL(drm_legacy_pci_init);
|
|||||||
* Unregister a DRM driver shadow-attached through drm_legacy_pci_init(). This
|
* Unregister a DRM driver shadow-attached through drm_legacy_pci_init(). This
|
||||||
* is deprecated and only used by dri1 drivers.
|
* is deprecated and only used by dri1 drivers.
|
||||||
*/
|
*/
|
||||||
void drm_legacy_pci_exit(struct drm_driver *driver, struct pci_driver *pdriver)
|
void drm_legacy_pci_exit(const struct drm_driver *driver,
|
||||||
|
struct pci_driver *pdriver)
|
||||||
{
|
{
|
||||||
struct drm_device *dev, *tmp;
|
struct drm_device *dev, *tmp;
|
||||||
|
|
||||||
@ -304,11 +311,15 @@ void drm_legacy_pci_exit(struct drm_driver *driver, struct pci_driver *pdriver)
|
|||||||
if (!(driver->driver_features & DRIVER_LEGACY)) {
|
if (!(driver->driver_features & DRIVER_LEGACY)) {
|
||||||
WARN_ON(1);
|
WARN_ON(1);
|
||||||
} else {
|
} else {
|
||||||
list_for_each_entry_safe(dev, tmp, &driver->legacy_dev_list,
|
mutex_lock(&legacy_dev_list_lock);
|
||||||
|
list_for_each_entry_safe(dev, tmp, &legacy_dev_list,
|
||||||
legacy_dev_list) {
|
legacy_dev_list) {
|
||||||
list_del(&dev->legacy_dev_list);
|
if (dev->driver == driver) {
|
||||||
drm_put_dev(dev);
|
list_del(&dev->legacy_dev_list);
|
||||||
|
drm_put_dev(dev);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
mutex_unlock(&legacy_dev_list_lock);
|
||||||
}
|
}
|
||||||
DRM_INFO("Module unloaded\n");
|
DRM_INFO("Module unloaded\n");
|
||||||
}
|
}
|
||||||
|
@ -515,7 +515,8 @@ retry:
|
|||||||
if (count == 0 && connector->status == connector_status_connected)
|
if (count == 0 && connector->status == connector_status_connected)
|
||||||
count = drm_add_override_edid_modes(connector);
|
count = drm_add_override_edid_modes(connector);
|
||||||
|
|
||||||
if (count == 0 && connector->status == connector_status_connected)
|
if (count == 0 && (connector->status == connector_status_connected ||
|
||||||
|
connector->status == connector_status_unknown))
|
||||||
count = drm_add_modes_noedid(connector, 1024, 768);
|
count = drm_add_modes_noedid(connector, 1024, 768);
|
||||||
count += drm_helper_probe_add_cmdline_mode(connector);
|
count += drm_helper_probe_add_cmdline_mode(connector);
|
||||||
if (count == 0)
|
if (count == 0)
|
||||||
|
@ -400,7 +400,7 @@ static void kmb_irq_reset(struct drm_device *drm)
|
|||||||
|
|
||||||
DEFINE_DRM_GEM_CMA_FOPS(fops);
|
DEFINE_DRM_GEM_CMA_FOPS(fops);
|
||||||
|
|
||||||
static struct drm_driver kmb_driver = {
|
static const struct drm_driver kmb_driver = {
|
||||||
.driver_features = DRIVER_GEM |
|
.driver_features = DRIVER_GEM |
|
||||||
DRIVER_MODESET | DRIVER_ATOMIC,
|
DRIVER_MODESET | DRIVER_ATOMIC,
|
||||||
.irq_handler = kmb_isr,
|
.irq_handler = kmb_isr,
|
||||||
|
@ -122,7 +122,7 @@ int rcar_cmm_enable(struct platform_device *pdev)
|
|||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
ret = pm_runtime_get_sync(&pdev->dev);
|
ret = pm_runtime_resume_and_get(&pdev->dev);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
|
@ -730,13 +730,10 @@ static void rcar_du_crtc_atomic_enable(struct drm_crtc *crtc,
|
|||||||
*/
|
*/
|
||||||
if (rcdu->info->lvds_clk_mask & BIT(rcrtc->index) &&
|
if (rcdu->info->lvds_clk_mask & BIT(rcrtc->index) &&
|
||||||
rstate->outputs == BIT(RCAR_DU_OUTPUT_DPAD0)) {
|
rstate->outputs == BIT(RCAR_DU_OUTPUT_DPAD0)) {
|
||||||
struct rcar_du_encoder *encoder =
|
struct drm_bridge *bridge = rcdu->lvds[rcrtc->index];
|
||||||
rcdu->encoders[RCAR_DU_OUTPUT_LVDS0 + rcrtc->index];
|
|
||||||
const struct drm_display_mode *mode =
|
const struct drm_display_mode *mode =
|
||||||
&crtc->state->adjusted_mode;
|
&crtc->state->adjusted_mode;
|
||||||
struct drm_bridge *bridge;
|
|
||||||
|
|
||||||
bridge = drm_bridge_chain_get_first_bridge(&encoder->base);
|
|
||||||
rcar_lvds_clk_enable(bridge, mode->clock * 1000);
|
rcar_lvds_clk_enable(bridge, mode->clock * 1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -764,15 +761,12 @@ static void rcar_du_crtc_atomic_disable(struct drm_crtc *crtc,
|
|||||||
|
|
||||||
if (rcdu->info->lvds_clk_mask & BIT(rcrtc->index) &&
|
if (rcdu->info->lvds_clk_mask & BIT(rcrtc->index) &&
|
||||||
rstate->outputs == BIT(RCAR_DU_OUTPUT_DPAD0)) {
|
rstate->outputs == BIT(RCAR_DU_OUTPUT_DPAD0)) {
|
||||||
struct rcar_du_encoder *encoder =
|
struct drm_bridge *bridge = rcdu->lvds[rcrtc->index];
|
||||||
rcdu->encoders[RCAR_DU_OUTPUT_LVDS0 + rcrtc->index];
|
|
||||||
struct drm_bridge *bridge;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Disable the LVDS clock output, see
|
* Disable the LVDS clock output, see
|
||||||
* rcar_du_crtc_atomic_enable().
|
* rcar_du_crtc_atomic_enable().
|
||||||
*/
|
*/
|
||||||
bridge = drm_bridge_chain_get_first_bridge(&encoder->base);
|
|
||||||
rcar_lvds_clk_disable(bridge);
|
rcar_lvds_clk_disable(bridge);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1256,7 +1250,7 @@ int rcar_du_crtc_create(struct rcar_du_group *rgrp, unsigned int swindex,
|
|||||||
else
|
else
|
||||||
primary = &rgrp->planes[swindex % 2].plane;
|
primary = &rgrp->planes[swindex % 2].plane;
|
||||||
|
|
||||||
ret = drm_crtc_init_with_planes(rcdu->ddev, crtc, primary, NULL,
|
ret = drm_crtc_init_with_planes(&rcdu->ddev, crtc, primary, NULL,
|
||||||
rcdu->info->gen <= 2 ?
|
rcdu->info->gen <= 2 ?
|
||||||
&crtc_funcs_gen2 : &crtc_funcs_gen3,
|
&crtc_funcs_gen2 : &crtc_funcs_gen3,
|
||||||
NULL);
|
NULL);
|
||||||
|
@ -18,10 +18,11 @@
|
|||||||
#include <linux/wait.h>
|
#include <linux/wait.h>
|
||||||
|
|
||||||
#include <drm/drm_atomic_helper.h>
|
#include <drm/drm_atomic_helper.h>
|
||||||
|
#include <drm/drm_drv.h>
|
||||||
#include <drm/drm_fb_cma_helper.h>
|
#include <drm/drm_fb_cma_helper.h>
|
||||||
#include <drm/drm_fb_helper.h>
|
#include <drm/drm_fb_helper.h>
|
||||||
#include <drm/drm_drv.h>
|
|
||||||
#include <drm/drm_gem_cma_helper.h>
|
#include <drm/drm_gem_cma_helper.h>
|
||||||
|
#include <drm/drm_managed.h>
|
||||||
#include <drm/drm_probe_helper.h>
|
#include <drm/drm_probe_helper.h>
|
||||||
|
|
||||||
#include "rcar_du_drv.h"
|
#include "rcar_du_drv.h"
|
||||||
@ -527,14 +528,14 @@ static int rcar_du_pm_suspend(struct device *dev)
|
|||||||
{
|
{
|
||||||
struct rcar_du_device *rcdu = dev_get_drvdata(dev);
|
struct rcar_du_device *rcdu = dev_get_drvdata(dev);
|
||||||
|
|
||||||
return drm_mode_config_helper_suspend(rcdu->ddev);
|
return drm_mode_config_helper_suspend(&rcdu->ddev);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int rcar_du_pm_resume(struct device *dev)
|
static int rcar_du_pm_resume(struct device *dev)
|
||||||
{
|
{
|
||||||
struct rcar_du_device *rcdu = dev_get_drvdata(dev);
|
struct rcar_du_device *rcdu = dev_get_drvdata(dev);
|
||||||
|
|
||||||
return drm_mode_config_helper_resume(rcdu->ddev);
|
return drm_mode_config_helper_resume(&rcdu->ddev);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -549,7 +550,7 @@ static const struct dev_pm_ops rcar_du_pm_ops = {
|
|||||||
static int rcar_du_remove(struct platform_device *pdev)
|
static int rcar_du_remove(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
struct rcar_du_device *rcdu = platform_get_drvdata(pdev);
|
struct rcar_du_device *rcdu = platform_get_drvdata(pdev);
|
||||||
struct drm_device *ddev = rcdu->ddev;
|
struct drm_device *ddev = &rcdu->ddev;
|
||||||
|
|
||||||
drm_dev_unregister(ddev);
|
drm_dev_unregister(ddev);
|
||||||
|
|
||||||
@ -563,14 +564,14 @@ static int rcar_du_remove(struct platform_device *pdev)
|
|||||||
static int rcar_du_probe(struct platform_device *pdev)
|
static int rcar_du_probe(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
struct rcar_du_device *rcdu;
|
struct rcar_du_device *rcdu;
|
||||||
struct drm_device *ddev;
|
|
||||||
struct resource *mem;
|
struct resource *mem;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
/* Allocate and initialize the R-Car device structure. */
|
/* Allocate and initialize the R-Car device structure. */
|
||||||
rcdu = devm_kzalloc(&pdev->dev, sizeof(*rcdu), GFP_KERNEL);
|
rcdu = devm_drm_dev_alloc(&pdev->dev, &rcar_du_driver,
|
||||||
if (rcdu == NULL)
|
struct rcar_du_device, ddev);
|
||||||
return -ENOMEM;
|
if (IS_ERR(rcdu))
|
||||||
|
return PTR_ERR(rcdu);
|
||||||
|
|
||||||
rcdu->dev = &pdev->dev;
|
rcdu->dev = &pdev->dev;
|
||||||
rcdu->info = of_device_get_match_data(rcdu->dev);
|
rcdu->info = of_device_get_match_data(rcdu->dev);
|
||||||
@ -584,13 +585,6 @@ static int rcar_du_probe(struct platform_device *pdev)
|
|||||||
return PTR_ERR(rcdu->mmio);
|
return PTR_ERR(rcdu->mmio);
|
||||||
|
|
||||||
/* DRM/KMS objects */
|
/* DRM/KMS objects */
|
||||||
ddev = drm_dev_alloc(&rcar_du_driver, &pdev->dev);
|
|
||||||
if (IS_ERR(ddev))
|
|
||||||
return PTR_ERR(ddev);
|
|
||||||
|
|
||||||
rcdu->ddev = ddev;
|
|
||||||
ddev->dev_private = rcdu;
|
|
||||||
|
|
||||||
ret = rcar_du_modeset_init(rcdu);
|
ret = rcar_du_modeset_init(rcdu);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
if (ret != -EPROBE_DEFER)
|
if (ret != -EPROBE_DEFER)
|
||||||
@ -599,25 +593,24 @@ static int rcar_du_probe(struct platform_device *pdev)
|
|||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
ddev->irq_enabled = 1;
|
rcdu->ddev.irq_enabled = 1;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Register the DRM device with the core and the connectors with
|
* Register the DRM device with the core and the connectors with
|
||||||
* sysfs.
|
* sysfs.
|
||||||
*/
|
*/
|
||||||
ret = drm_dev_register(ddev, 0);
|
ret = drm_dev_register(&rcdu->ddev, 0);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
DRM_INFO("Device %s probed\n", dev_name(&pdev->dev));
|
DRM_INFO("Device %s probed\n", dev_name(&pdev->dev));
|
||||||
|
|
||||||
drm_fbdev_generic_setup(ddev, 32);
|
drm_fbdev_generic_setup(&rcdu->ddev, 32);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
error:
|
error:
|
||||||
rcar_du_remove(pdev);
|
drm_kms_helper_poll_fini(&rcdu->ddev);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -13,6 +13,8 @@
|
|||||||
#include <linux/kernel.h>
|
#include <linux/kernel.h>
|
||||||
#include <linux/wait.h>
|
#include <linux/wait.h>
|
||||||
|
|
||||||
|
#include <drm/drm_device.h>
|
||||||
|
|
||||||
#include "rcar_cmm.h"
|
#include "rcar_cmm.h"
|
||||||
#include "rcar_du_crtc.h"
|
#include "rcar_du_crtc.h"
|
||||||
#include "rcar_du_group.h"
|
#include "rcar_du_group.h"
|
||||||
@ -20,10 +22,9 @@
|
|||||||
|
|
||||||
struct clk;
|
struct clk;
|
||||||
struct device;
|
struct device;
|
||||||
struct drm_device;
|
struct drm_bridge;
|
||||||
struct drm_property;
|
struct drm_property;
|
||||||
struct rcar_du_device;
|
struct rcar_du_device;
|
||||||
struct rcar_du_encoder;
|
|
||||||
|
|
||||||
#define RCAR_DU_FEATURE_CRTC_IRQ_CLOCK BIT(0) /* Per-CRTC IRQ and clock */
|
#define RCAR_DU_FEATURE_CRTC_IRQ_CLOCK BIT(0) /* Per-CRTC IRQ and clock */
|
||||||
#define RCAR_DU_FEATURE_VSP1_SOURCE BIT(1) /* Has inputs from VSP1 */
|
#define RCAR_DU_FEATURE_VSP1_SOURCE BIT(1) /* Has inputs from VSP1 */
|
||||||
@ -71,6 +72,7 @@ struct rcar_du_device_info {
|
|||||||
#define RCAR_DU_MAX_CRTCS 4
|
#define RCAR_DU_MAX_CRTCS 4
|
||||||
#define RCAR_DU_MAX_GROUPS DIV_ROUND_UP(RCAR_DU_MAX_CRTCS, 2)
|
#define RCAR_DU_MAX_GROUPS DIV_ROUND_UP(RCAR_DU_MAX_CRTCS, 2)
|
||||||
#define RCAR_DU_MAX_VSPS 4
|
#define RCAR_DU_MAX_VSPS 4
|
||||||
|
#define RCAR_DU_MAX_LVDS 2
|
||||||
|
|
||||||
struct rcar_du_device {
|
struct rcar_du_device {
|
||||||
struct device *dev;
|
struct device *dev;
|
||||||
@ -78,16 +80,15 @@ struct rcar_du_device {
|
|||||||
|
|
||||||
void __iomem *mmio;
|
void __iomem *mmio;
|
||||||
|
|
||||||
struct drm_device *ddev;
|
struct drm_device ddev;
|
||||||
|
|
||||||
struct rcar_du_crtc crtcs[RCAR_DU_MAX_CRTCS];
|
struct rcar_du_crtc crtcs[RCAR_DU_MAX_CRTCS];
|
||||||
unsigned int num_crtcs;
|
unsigned int num_crtcs;
|
||||||
|
|
||||||
struct rcar_du_encoder *encoders[RCAR_DU_OUTPUT_MAX];
|
|
||||||
|
|
||||||
struct rcar_du_group groups[RCAR_DU_MAX_GROUPS];
|
struct rcar_du_group groups[RCAR_DU_MAX_GROUPS];
|
||||||
struct platform_device *cmms[RCAR_DU_MAX_CRTCS];
|
struct platform_device *cmms[RCAR_DU_MAX_CRTCS];
|
||||||
struct rcar_du_vsp vsps[RCAR_DU_MAX_VSPS];
|
struct rcar_du_vsp vsps[RCAR_DU_MAX_VSPS];
|
||||||
|
struct drm_bridge *lvds[RCAR_DU_MAX_LVDS];
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
struct drm_property *colorkey;
|
struct drm_property *colorkey;
|
||||||
@ -98,6 +99,11 @@ struct rcar_du_device {
|
|||||||
unsigned int vspd1_sink;
|
unsigned int vspd1_sink;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static inline struct rcar_du_device *to_rcar_du_device(struct drm_device *dev)
|
||||||
|
{
|
||||||
|
return container_of(dev, struct rcar_du_device, ddev);
|
||||||
|
}
|
||||||
|
|
||||||
static inline bool rcar_du_has(struct rcar_du_device *rcdu,
|
static inline bool rcar_du_has(struct rcar_du_device *rcdu,
|
||||||
unsigned int feature)
|
unsigned int feature)
|
||||||
{
|
{
|
||||||
|
@ -8,12 +8,13 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <linux/export.h>
|
#include <linux/export.h>
|
||||||
|
#include <linux/slab.h>
|
||||||
|
|
||||||
#include <drm/drm_bridge.h>
|
#include <drm/drm_bridge.h>
|
||||||
#include <drm/drm_crtc.h>
|
#include <drm/drm_crtc.h>
|
||||||
|
#include <drm/drm_managed.h>
|
||||||
#include <drm/drm_modeset_helper_vtables.h>
|
#include <drm/drm_modeset_helper_vtables.h>
|
||||||
#include <drm/drm_panel.h>
|
#include <drm/drm_panel.h>
|
||||||
#include <drm/drm_simple_kms_helper.h>
|
|
||||||
|
|
||||||
#include "rcar_du_drv.h"
|
#include "rcar_du_drv.h"
|
||||||
#include "rcar_du_encoder.h"
|
#include "rcar_du_encoder.h"
|
||||||
@ -44,26 +45,25 @@ static unsigned int rcar_du_encoder_count_ports(struct device_node *node)
|
|||||||
return num_ports;
|
return num_ports;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const struct drm_encoder_funcs rcar_du_encoder_funcs = {
|
||||||
|
};
|
||||||
|
|
||||||
|
static void rcar_du_encoder_release(struct drm_device *dev, void *res)
|
||||||
|
{
|
||||||
|
struct rcar_du_encoder *renc = res;
|
||||||
|
|
||||||
|
drm_encoder_cleanup(&renc->base);
|
||||||
|
kfree(renc);
|
||||||
|
}
|
||||||
|
|
||||||
int rcar_du_encoder_init(struct rcar_du_device *rcdu,
|
int rcar_du_encoder_init(struct rcar_du_device *rcdu,
|
||||||
enum rcar_du_output output,
|
enum rcar_du_output output,
|
||||||
struct device_node *enc_node)
|
struct device_node *enc_node)
|
||||||
{
|
{
|
||||||
struct rcar_du_encoder *renc;
|
struct rcar_du_encoder *renc;
|
||||||
struct drm_encoder *encoder;
|
|
||||||
struct drm_bridge *bridge;
|
struct drm_bridge *bridge;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
renc = devm_kzalloc(rcdu->dev, sizeof(*renc), GFP_KERNEL);
|
|
||||||
if (renc == NULL)
|
|
||||||
return -ENOMEM;
|
|
||||||
|
|
||||||
rcdu->encoders[output] = renc;
|
|
||||||
renc->output = output;
|
|
||||||
encoder = rcar_encoder_to_drm_encoder(renc);
|
|
||||||
|
|
||||||
dev_dbg(rcdu->dev, "initializing encoder %pOF for output %u\n",
|
|
||||||
enc_node, output);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Locate the DRM bridge from the DT node. For the DPAD outputs, if the
|
* Locate the DRM bridge from the DT node. For the DPAD outputs, if the
|
||||||
* DT node has a single port, assume that it describes a panel and
|
* DT node has a single port, assume that it describes a panel and
|
||||||
@ -74,57 +74,57 @@ int rcar_du_encoder_init(struct rcar_du_device *rcdu,
|
|||||||
rcar_du_encoder_count_ports(enc_node) == 1) {
|
rcar_du_encoder_count_ports(enc_node) == 1) {
|
||||||
struct drm_panel *panel = of_drm_find_panel(enc_node);
|
struct drm_panel *panel = of_drm_find_panel(enc_node);
|
||||||
|
|
||||||
if (IS_ERR(panel)) {
|
if (IS_ERR(panel))
|
||||||
ret = PTR_ERR(panel);
|
return PTR_ERR(panel);
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
|
|
||||||
bridge = devm_drm_panel_bridge_add_typed(rcdu->dev, panel,
|
bridge = devm_drm_panel_bridge_add_typed(rcdu->dev, panel,
|
||||||
DRM_MODE_CONNECTOR_DPI);
|
DRM_MODE_CONNECTOR_DPI);
|
||||||
if (IS_ERR(bridge)) {
|
if (IS_ERR(bridge))
|
||||||
ret = PTR_ERR(bridge);
|
return PTR_ERR(bridge);
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
bridge = of_drm_find_bridge(enc_node);
|
bridge = of_drm_find_bridge(enc_node);
|
||||||
if (!bridge) {
|
if (!bridge)
|
||||||
ret = -EPROBE_DEFER;
|
return -EPROBE_DEFER;
|
||||||
goto done;
|
|
||||||
}
|
if (output == RCAR_DU_OUTPUT_LVDS0 ||
|
||||||
|
output == RCAR_DU_OUTPUT_LVDS1)
|
||||||
|
rcdu->lvds[output - RCAR_DU_OUTPUT_LVDS0] = bridge;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* On Gen3 skip the LVDS1 output if the LVDS1 encoder is used as a
|
* Create and initialize the encoder. On Gen3 skip the LVDS1 output if
|
||||||
* companion for LVDS0 in dual-link mode.
|
* the LVDS1 encoder is used as a companion for LVDS0 in dual-link
|
||||||
|
* mode.
|
||||||
*/
|
*/
|
||||||
if (rcdu->info->gen >= 3 && output == RCAR_DU_OUTPUT_LVDS1) {
|
if (rcdu->info->gen >= 3 && output == RCAR_DU_OUTPUT_LVDS1) {
|
||||||
if (rcar_lvds_dual_link(bridge)) {
|
if (rcar_lvds_dual_link(bridge))
|
||||||
ret = -ENOLINK;
|
return -ENOLINK;
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = drm_simple_encoder_init(rcdu->ddev, encoder,
|
renc = kzalloc(sizeof(*renc), GFP_KERNEL);
|
||||||
DRM_MODE_ENCODER_NONE);
|
if (renc == NULL)
|
||||||
if (ret < 0)
|
return -ENOMEM;
|
||||||
goto done;
|
|
||||||
|
renc->output = output;
|
||||||
|
|
||||||
|
dev_dbg(rcdu->dev, "initializing encoder %pOF for output %u\n",
|
||||||
|
enc_node, output);
|
||||||
|
|
||||||
|
ret = drm_encoder_init(&rcdu->ddev, &renc->base, &rcar_du_encoder_funcs,
|
||||||
|
DRM_MODE_ENCODER_NONE, NULL);
|
||||||
|
if (ret < 0) {
|
||||||
|
kfree(renc);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = drmm_add_action_or_reset(&rcdu->ddev, rcar_du_encoder_release,
|
||||||
|
renc);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Attach the bridge to the encoder. The bridge will create the
|
* Attach the bridge to the encoder. The bridge will create the
|
||||||
* connector.
|
* connector.
|
||||||
*/
|
*/
|
||||||
ret = drm_bridge_attach(encoder, bridge, NULL, 0);
|
return drm_bridge_attach(&renc->base, bridge, NULL, 0);
|
||||||
if (ret) {
|
|
||||||
drm_encoder_cleanup(encoder);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
done:
|
|
||||||
if (ret < 0) {
|
|
||||||
if (encoder->name)
|
|
||||||
encoder->funcs->destroy(encoder);
|
|
||||||
devm_kfree(rcdu->dev, renc);
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
@ -22,8 +22,6 @@ struct rcar_du_encoder {
|
|||||||
#define to_rcar_encoder(e) \
|
#define to_rcar_encoder(e) \
|
||||||
container_of(e, struct rcar_du_encoder, base)
|
container_of(e, struct rcar_du_encoder, base)
|
||||||
|
|
||||||
#define rcar_encoder_to_drm_encoder(e) (&(e)->base)
|
|
||||||
|
|
||||||
int rcar_du_encoder_init(struct rcar_du_device *rcdu,
|
int rcar_du_encoder_init(struct rcar_du_device *rcdu,
|
||||||
enum rcar_du_output output,
|
enum rcar_du_output output,
|
||||||
struct device_node *enc_node);
|
struct device_node *enc_node);
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
#include <drm/drm_fb_cma_helper.h>
|
#include <drm/drm_fb_cma_helper.h>
|
||||||
#include <drm/drm_gem_cma_helper.h>
|
#include <drm/drm_gem_cma_helper.h>
|
||||||
#include <drm/drm_gem_framebuffer_helper.h>
|
#include <drm/drm_gem_framebuffer_helper.h>
|
||||||
|
#include <drm/drm_managed.h>
|
||||||
#include <drm/drm_probe_helper.h>
|
#include <drm/drm_probe_helper.h>
|
||||||
#include <drm/drm_vblank.h>
|
#include <drm/drm_vblank.h>
|
||||||
|
|
||||||
@ -327,7 +328,7 @@ const struct rcar_du_format_info *rcar_du_format_info(u32 fourcc)
|
|||||||
int rcar_du_dumb_create(struct drm_file *file, struct drm_device *dev,
|
int rcar_du_dumb_create(struct drm_file *file, struct drm_device *dev,
|
||||||
struct drm_mode_create_dumb *args)
|
struct drm_mode_create_dumb *args)
|
||||||
{
|
{
|
||||||
struct rcar_du_device *rcdu = dev->dev_private;
|
struct rcar_du_device *rcdu = to_rcar_du_device(dev);
|
||||||
unsigned int min_pitch = DIV_ROUND_UP(args->width * args->bpp, 8);
|
unsigned int min_pitch = DIV_ROUND_UP(args->width * args->bpp, 8);
|
||||||
unsigned int align;
|
unsigned int align;
|
||||||
|
|
||||||
@ -349,7 +350,7 @@ static struct drm_framebuffer *
|
|||||||
rcar_du_fb_create(struct drm_device *dev, struct drm_file *file_priv,
|
rcar_du_fb_create(struct drm_device *dev, struct drm_file *file_priv,
|
||||||
const struct drm_mode_fb_cmd2 *mode_cmd)
|
const struct drm_mode_fb_cmd2 *mode_cmd)
|
||||||
{
|
{
|
||||||
struct rcar_du_device *rcdu = dev->dev_private;
|
struct rcar_du_device *rcdu = to_rcar_du_device(dev);
|
||||||
const struct rcar_du_format_info *format;
|
const struct rcar_du_format_info *format;
|
||||||
unsigned int chroma_pitch;
|
unsigned int chroma_pitch;
|
||||||
unsigned int max_pitch;
|
unsigned int max_pitch;
|
||||||
@ -421,7 +422,7 @@ rcar_du_fb_create(struct drm_device *dev, struct drm_file *file_priv,
|
|||||||
static int rcar_du_atomic_check(struct drm_device *dev,
|
static int rcar_du_atomic_check(struct drm_device *dev,
|
||||||
struct drm_atomic_state *state)
|
struct drm_atomic_state *state)
|
||||||
{
|
{
|
||||||
struct rcar_du_device *rcdu = dev->dev_private;
|
struct rcar_du_device *rcdu = to_rcar_du_device(dev);
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
ret = drm_atomic_helper_check(dev, state);
|
ret = drm_atomic_helper_check(dev, state);
|
||||||
@ -437,7 +438,7 @@ static int rcar_du_atomic_check(struct drm_device *dev,
|
|||||||
static void rcar_du_atomic_commit_tail(struct drm_atomic_state *old_state)
|
static void rcar_du_atomic_commit_tail(struct drm_atomic_state *old_state)
|
||||||
{
|
{
|
||||||
struct drm_device *dev = old_state->dev;
|
struct drm_device *dev = old_state->dev;
|
||||||
struct rcar_du_device *rcdu = dev->dev_private;
|
struct rcar_du_device *rcdu = to_rcar_du_device(dev);
|
||||||
struct drm_crtc_state *crtc_state;
|
struct drm_crtc_state *crtc_state;
|
||||||
struct drm_crtc *crtc;
|
struct drm_crtc *crtc;
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
@ -583,7 +584,7 @@ static int rcar_du_properties_init(struct rcar_du_device *rcdu)
|
|||||||
* or enable source color keying (1).
|
* or enable source color keying (1).
|
||||||
*/
|
*/
|
||||||
rcdu->props.colorkey =
|
rcdu->props.colorkey =
|
||||||
drm_property_create_range(rcdu->ddev, 0, "colorkey",
|
drm_property_create_range(&rcdu->ddev, 0, "colorkey",
|
||||||
0, 0x01ffffff);
|
0, 0x01ffffff);
|
||||||
if (rcdu->props.colorkey == NULL)
|
if (rcdu->props.colorkey == NULL)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
@ -700,10 +701,10 @@ static int rcar_du_cmm_init(struct rcar_du_device *rcdu)
|
|||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
cmm = of_parse_phandle(np, "renesas,cmms", i);
|
cmm = of_parse_phandle(np, "renesas,cmms", i);
|
||||||
if (IS_ERR(cmm)) {
|
if (!cmm) {
|
||||||
dev_err(rcdu->dev,
|
dev_err(rcdu->dev,
|
||||||
"Failed to parse 'renesas,cmms' property\n");
|
"Failed to parse 'renesas,cmms' property\n");
|
||||||
return PTR_ERR(cmm);
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!of_device_is_available(cmm)) {
|
if (!of_device_is_available(cmm)) {
|
||||||
@ -713,10 +714,10 @@ static int rcar_du_cmm_init(struct rcar_du_device *rcdu)
|
|||||||
}
|
}
|
||||||
|
|
||||||
pdev = of_find_device_by_node(cmm);
|
pdev = of_find_device_by_node(cmm);
|
||||||
if (IS_ERR(pdev)) {
|
if (!pdev) {
|
||||||
dev_err(rcdu->dev, "No device found for CMM%u\n", i);
|
dev_err(rcdu->dev, "No device found for CMM%u\n", i);
|
||||||
of_node_put(cmm);
|
of_node_put(cmm);
|
||||||
return PTR_ERR(pdev);
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
of_node_put(cmm);
|
of_node_put(cmm);
|
||||||
@ -726,8 +727,12 @@ static int rcar_du_cmm_init(struct rcar_du_device *rcdu)
|
|||||||
* disabled: return 0 and let the DU continue probing.
|
* disabled: return 0 and let the DU continue probing.
|
||||||
*/
|
*/
|
||||||
ret = rcar_cmm_init(pdev);
|
ret = rcar_cmm_init(pdev);
|
||||||
if (ret)
|
if (ret) {
|
||||||
|
platform_device_put(pdev);
|
||||||
return ret == -ENODEV ? 0 : ret;
|
return ret == -ENODEV ? 0 : ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
rcdu->cmms[i] = pdev;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Enforce suspend/resume ordering by making the CMM a provider
|
* Enforce suspend/resume ordering by making the CMM a provider
|
||||||
@ -739,20 +744,27 @@ static int rcar_du_cmm_init(struct rcar_du_device *rcdu)
|
|||||||
"Failed to create device link to CMM%u\n", i);
|
"Failed to create device link to CMM%u\n", i);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
rcdu->cmms[i] = pdev;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void rcar_du_modeset_cleanup(struct drm_device *dev, void *res)
|
||||||
|
{
|
||||||
|
struct rcar_du_device *rcdu = to_rcar_du_device(dev);
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
for (i = 0; i < ARRAY_SIZE(rcdu->cmms); ++i)
|
||||||
|
platform_device_put(rcdu->cmms[i]);
|
||||||
|
}
|
||||||
|
|
||||||
int rcar_du_modeset_init(struct rcar_du_device *rcdu)
|
int rcar_du_modeset_init(struct rcar_du_device *rcdu)
|
||||||
{
|
{
|
||||||
static const unsigned int mmio_offsets[] = {
|
static const unsigned int mmio_offsets[] = {
|
||||||
DU0_REG_OFFSET, DU2_REG_OFFSET
|
DU0_REG_OFFSET, DU2_REG_OFFSET
|
||||||
};
|
};
|
||||||
|
|
||||||
struct drm_device *dev = rcdu->ddev;
|
struct drm_device *dev = &rcdu->ddev;
|
||||||
struct drm_encoder *encoder;
|
struct drm_encoder *encoder;
|
||||||
unsigned int dpad0_sources;
|
unsigned int dpad0_sources;
|
||||||
unsigned int num_encoders;
|
unsigned int num_encoders;
|
||||||
@ -766,6 +778,10 @@ int rcar_du_modeset_init(struct rcar_du_device *rcdu)
|
|||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
|
ret = drmm_add_action(&rcdu->ddev, rcar_du_modeset_cleanup, NULL);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
dev->mode_config.min_width = 0;
|
dev->mode_config.min_width = 0;
|
||||||
dev->mode_config.min_height = 0;
|
dev->mode_config.min_height = 0;
|
||||||
dev->mode_config.normalize_zpos = true;
|
dev->mode_config.normalize_zpos = true;
|
||||||
|
@ -128,7 +128,7 @@ static int rcar_du_plane_hwalloc(struct rcar_du_plane *plane,
|
|||||||
int rcar_du_atomic_check_planes(struct drm_device *dev,
|
int rcar_du_atomic_check_planes(struct drm_device *dev,
|
||||||
struct drm_atomic_state *state)
|
struct drm_atomic_state *state)
|
||||||
{
|
{
|
||||||
struct rcar_du_device *rcdu = dev->dev_private;
|
struct rcar_du_device *rcdu = to_rcar_du_device(dev);
|
||||||
unsigned int group_freed_planes[RCAR_DU_MAX_GROUPS] = { 0, };
|
unsigned int group_freed_planes[RCAR_DU_MAX_GROUPS] = { 0, };
|
||||||
unsigned int group_free_planes[RCAR_DU_MAX_GROUPS] = { 0, };
|
unsigned int group_free_planes[RCAR_DU_MAX_GROUPS] = { 0, };
|
||||||
bool needs_realloc = false;
|
bool needs_realloc = false;
|
||||||
@ -773,9 +773,9 @@ int rcar_du_planes_init(struct rcar_du_group *rgrp)
|
|||||||
|
|
||||||
plane->group = rgrp;
|
plane->group = rgrp;
|
||||||
|
|
||||||
ret = drm_universal_plane_init(rcdu->ddev, &plane->plane, crtcs,
|
ret = drm_universal_plane_init(&rcdu->ddev, &plane->plane,
|
||||||
&rcar_du_plane_funcs, formats,
|
crtcs, &rcar_du_plane_funcs,
|
||||||
ARRAY_SIZE(formats),
|
formats, ARRAY_SIZE(formats),
|
||||||
NULL, type, NULL);
|
NULL, type, NULL);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -21,6 +21,7 @@
|
|||||||
#include <linux/dma-mapping.h>
|
#include <linux/dma-mapping.h>
|
||||||
#include <linux/of_platform.h>
|
#include <linux/of_platform.h>
|
||||||
#include <linux/scatterlist.h>
|
#include <linux/scatterlist.h>
|
||||||
|
#include <linux/slab.h>
|
||||||
#include <linux/videodev2.h>
|
#include <linux/videodev2.h>
|
||||||
|
|
||||||
#include <media/vsp1.h>
|
#include <media/vsp1.h>
|
||||||
@ -344,6 +345,15 @@ static const struct drm_plane_funcs rcar_du_vsp_plane_funcs = {
|
|||||||
static void rcar_du_vsp_cleanup(struct drm_device *dev, void *res)
|
static void rcar_du_vsp_cleanup(struct drm_device *dev, void *res)
|
||||||
{
|
{
|
||||||
struct rcar_du_vsp *vsp = res;
|
struct rcar_du_vsp *vsp = res;
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
for (i = 0; i < vsp->num_planes; ++i) {
|
||||||
|
struct rcar_du_vsp_plane *plane = &vsp->planes[i];
|
||||||
|
|
||||||
|
drm_plane_cleanup(&plane->plane);
|
||||||
|
}
|
||||||
|
|
||||||
|
kfree(vsp->planes);
|
||||||
|
|
||||||
put_device(vsp->vsp);
|
put_device(vsp->vsp);
|
||||||
}
|
}
|
||||||
@ -354,6 +364,7 @@ int rcar_du_vsp_init(struct rcar_du_vsp *vsp, struct device_node *np,
|
|||||||
struct rcar_du_device *rcdu = vsp->dev;
|
struct rcar_du_device *rcdu = vsp->dev;
|
||||||
struct platform_device *pdev;
|
struct platform_device *pdev;
|
||||||
unsigned int num_crtcs = hweight32(crtcs);
|
unsigned int num_crtcs = hweight32(crtcs);
|
||||||
|
unsigned int num_planes;
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
@ -364,7 +375,7 @@ int rcar_du_vsp_init(struct rcar_du_vsp *vsp, struct device_node *np,
|
|||||||
|
|
||||||
vsp->vsp = &pdev->dev;
|
vsp->vsp = &pdev->dev;
|
||||||
|
|
||||||
ret = drmm_add_action(rcdu->ddev, rcar_du_vsp_cleanup, vsp);
|
ret = drmm_add_action_or_reset(&rcdu->ddev, rcar_du_vsp_cleanup, vsp);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
@ -376,14 +387,13 @@ int rcar_du_vsp_init(struct rcar_du_vsp *vsp, struct device_node *np,
|
|||||||
* The VSP2D (Gen3) has 5 RPFs, but the VSP1D (Gen2) is limited to
|
* The VSP2D (Gen3) has 5 RPFs, but the VSP1D (Gen2) is limited to
|
||||||
* 4 RPFs.
|
* 4 RPFs.
|
||||||
*/
|
*/
|
||||||
vsp->num_planes = rcdu->info->gen >= 3 ? 5 : 4;
|
num_planes = rcdu->info->gen >= 3 ? 5 : 4;
|
||||||
|
|
||||||
vsp->planes = devm_kcalloc(rcdu->dev, vsp->num_planes,
|
vsp->planes = kcalloc(num_planes, sizeof(*vsp->planes), GFP_KERNEL);
|
||||||
sizeof(*vsp->planes), GFP_KERNEL);
|
|
||||||
if (!vsp->planes)
|
if (!vsp->planes)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
for (i = 0; i < vsp->num_planes; ++i) {
|
for (i = 0; i < num_planes; ++i) {
|
||||||
enum drm_plane_type type = i < num_crtcs
|
enum drm_plane_type type = i < num_crtcs
|
||||||
? DRM_PLANE_TYPE_PRIMARY
|
? DRM_PLANE_TYPE_PRIMARY
|
||||||
: DRM_PLANE_TYPE_OVERLAY;
|
: DRM_PLANE_TYPE_OVERLAY;
|
||||||
@ -392,8 +402,8 @@ int rcar_du_vsp_init(struct rcar_du_vsp *vsp, struct device_node *np,
|
|||||||
plane->vsp = vsp;
|
plane->vsp = vsp;
|
||||||
plane->index = i;
|
plane->index = i;
|
||||||
|
|
||||||
ret = drm_universal_plane_init(rcdu->ddev, &plane->plane, crtcs,
|
ret = drm_universal_plane_init(&rcdu->ddev, &plane->plane,
|
||||||
&rcar_du_vsp_plane_funcs,
|
crtcs, &rcar_du_vsp_plane_funcs,
|
||||||
rcar_du_vsp_formats,
|
rcar_du_vsp_formats,
|
||||||
ARRAY_SIZE(rcar_du_vsp_formats),
|
ARRAY_SIZE(rcar_du_vsp_formats),
|
||||||
NULL, type, NULL);
|
NULL, type, NULL);
|
||||||
@ -409,8 +419,10 @@ int rcar_du_vsp_init(struct rcar_du_vsp *vsp, struct device_node *np,
|
|||||||
} else {
|
} else {
|
||||||
drm_plane_create_alpha_property(&plane->plane);
|
drm_plane_create_alpha_property(&plane->plane);
|
||||||
drm_plane_create_zpos_property(&plane->plane, 1, 1,
|
drm_plane_create_zpos_property(&plane->plane, 1, 1,
|
||||||
vsp->num_planes - 1);
|
num_planes - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
vsp->num_planes++;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -204,7 +204,7 @@ int rcar_du_writeback_init(struct rcar_du_device *rcdu,
|
|||||||
drm_connector_helper_add(&wb_conn->base,
|
drm_connector_helper_add(&wb_conn->base,
|
||||||
&rcar_du_wb_conn_helper_funcs);
|
&rcar_du_wb_conn_helper_funcs);
|
||||||
|
|
||||||
return drm_writeback_connector_init(rcdu->ddev, wb_conn,
|
return drm_writeback_connector_init(&rcdu->ddev, wb_conn,
|
||||||
&rcar_du_wb_conn_funcs,
|
&rcar_du_wb_conn_funcs,
|
||||||
&rcar_du_wb_enc_helper_funcs,
|
&rcar_du_wb_enc_helper_funcs,
|
||||||
writeback_formats,
|
writeback_formats,
|
||||||
|
@ -330,13 +330,6 @@ static const struct drm_plane_helper_funcs sti_cursor_helpers_funcs = {
|
|||||||
.atomic_disable = sti_cursor_atomic_disable,
|
.atomic_disable = sti_cursor_atomic_disable,
|
||||||
};
|
};
|
||||||
|
|
||||||
static void sti_cursor_destroy(struct drm_plane *drm_plane)
|
|
||||||
{
|
|
||||||
DRM_DEBUG_DRIVER("\n");
|
|
||||||
|
|
||||||
drm_plane_cleanup(drm_plane);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int sti_cursor_late_register(struct drm_plane *drm_plane)
|
static int sti_cursor_late_register(struct drm_plane *drm_plane)
|
||||||
{
|
{
|
||||||
struct sti_plane *plane = to_sti_plane(drm_plane);
|
struct sti_plane *plane = to_sti_plane(drm_plane);
|
||||||
@ -350,7 +343,7 @@ static int sti_cursor_late_register(struct drm_plane *drm_plane)
|
|||||||
static const struct drm_plane_funcs sti_cursor_plane_helpers_funcs = {
|
static const struct drm_plane_funcs sti_cursor_plane_helpers_funcs = {
|
||||||
.update_plane = drm_atomic_helper_update_plane,
|
.update_plane = drm_atomic_helper_update_plane,
|
||||||
.disable_plane = drm_atomic_helper_disable_plane,
|
.disable_plane = drm_atomic_helper_disable_plane,
|
||||||
.destroy = sti_cursor_destroy,
|
.destroy = drm_plane_cleanup,
|
||||||
.reset = sti_plane_reset,
|
.reset = sti_plane_reset,
|
||||||
.atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state,
|
.atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state,
|
||||||
.atomic_destroy_state = drm_atomic_helper_plane_destroy_state,
|
.atomic_destroy_state = drm_atomic_helper_plane_destroy_state,
|
||||||
|
@ -884,13 +884,6 @@ static const struct drm_plane_helper_funcs sti_gdp_helpers_funcs = {
|
|||||||
.atomic_disable = sti_gdp_atomic_disable,
|
.atomic_disable = sti_gdp_atomic_disable,
|
||||||
};
|
};
|
||||||
|
|
||||||
static void sti_gdp_destroy(struct drm_plane *drm_plane)
|
|
||||||
{
|
|
||||||
DRM_DEBUG_DRIVER("\n");
|
|
||||||
|
|
||||||
drm_plane_cleanup(drm_plane);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int sti_gdp_late_register(struct drm_plane *drm_plane)
|
static int sti_gdp_late_register(struct drm_plane *drm_plane)
|
||||||
{
|
{
|
||||||
struct sti_plane *plane = to_sti_plane(drm_plane);
|
struct sti_plane *plane = to_sti_plane(drm_plane);
|
||||||
@ -902,7 +895,7 @@ static int sti_gdp_late_register(struct drm_plane *drm_plane)
|
|||||||
static const struct drm_plane_funcs sti_gdp_plane_helpers_funcs = {
|
static const struct drm_plane_funcs sti_gdp_plane_helpers_funcs = {
|
||||||
.update_plane = drm_atomic_helper_update_plane,
|
.update_plane = drm_atomic_helper_update_plane,
|
||||||
.disable_plane = drm_atomic_helper_disable_plane,
|
.disable_plane = drm_atomic_helper_disable_plane,
|
||||||
.destroy = sti_gdp_destroy,
|
.destroy = drm_plane_cleanup,
|
||||||
.reset = sti_plane_reset,
|
.reset = sti_plane_reset,
|
||||||
.atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state,
|
.atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state,
|
||||||
.atomic_destroy_state = drm_atomic_helper_plane_destroy_state,
|
.atomic_destroy_state = drm_atomic_helper_plane_destroy_state,
|
||||||
|
@ -1262,13 +1262,6 @@ static const struct drm_plane_helper_funcs sti_hqvdp_helpers_funcs = {
|
|||||||
.atomic_disable = sti_hqvdp_atomic_disable,
|
.atomic_disable = sti_hqvdp_atomic_disable,
|
||||||
};
|
};
|
||||||
|
|
||||||
static void sti_hqvdp_destroy(struct drm_plane *drm_plane)
|
|
||||||
{
|
|
||||||
DRM_DEBUG_DRIVER("\n");
|
|
||||||
|
|
||||||
drm_plane_cleanup(drm_plane);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int sti_hqvdp_late_register(struct drm_plane *drm_plane)
|
static int sti_hqvdp_late_register(struct drm_plane *drm_plane)
|
||||||
{
|
{
|
||||||
struct sti_plane *plane = to_sti_plane(drm_plane);
|
struct sti_plane *plane = to_sti_plane(drm_plane);
|
||||||
@ -1282,7 +1275,7 @@ static int sti_hqvdp_late_register(struct drm_plane *drm_plane)
|
|||||||
static const struct drm_plane_funcs sti_hqvdp_plane_helpers_funcs = {
|
static const struct drm_plane_funcs sti_hqvdp_plane_helpers_funcs = {
|
||||||
.update_plane = drm_atomic_helper_update_plane,
|
.update_plane = drm_atomic_helper_update_plane,
|
||||||
.disable_plane = drm_atomic_helper_disable_plane,
|
.disable_plane = drm_atomic_helper_disable_plane,
|
||||||
.destroy = sti_hqvdp_destroy,
|
.destroy = drm_plane_cleanup,
|
||||||
.reset = sti_plane_reset,
|
.reset = sti_plane_reset,
|
||||||
.atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state,
|
.atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state,
|
||||||
.atomic_destroy_state = drm_atomic_helper_plane_destroy_state,
|
.atomic_destroy_state = drm_atomic_helper_plane_destroy_state,
|
||||||
|
@ -56,7 +56,7 @@ static const struct file_operations tdfx_driver_fops = {
|
|||||||
.llseek = noop_llseek,
|
.llseek = noop_llseek,
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct drm_driver driver = {
|
static const struct drm_driver driver = {
|
||||||
.driver_features = DRIVER_LEGACY,
|
.driver_features = DRIVER_LEGACY,
|
||||||
.fops = &tdfx_driver_fops,
|
.fops = &tdfx_driver_fops,
|
||||||
.name = DRIVER_NAME,
|
.name = DRIVER_NAME,
|
||||||
|
@ -1268,11 +1268,6 @@ static const struct drm_plane_helper_funcs vc4_plane_helper_funcs = {
|
|||||||
.atomic_async_update = vc4_plane_atomic_async_update,
|
.atomic_async_update = vc4_plane_atomic_async_update,
|
||||||
};
|
};
|
||||||
|
|
||||||
static void vc4_plane_destroy(struct drm_plane *plane)
|
|
||||||
{
|
|
||||||
drm_plane_cleanup(plane);
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool vc4_format_mod_supported(struct drm_plane *plane,
|
static bool vc4_format_mod_supported(struct drm_plane *plane,
|
||||||
uint32_t format,
|
uint32_t format,
|
||||||
uint64_t modifier)
|
uint64_t modifier)
|
||||||
@ -1323,7 +1318,7 @@ static bool vc4_format_mod_supported(struct drm_plane *plane,
|
|||||||
static const struct drm_plane_funcs vc4_plane_funcs = {
|
static const struct drm_plane_funcs vc4_plane_funcs = {
|
||||||
.update_plane = drm_atomic_helper_update_plane,
|
.update_plane = drm_atomic_helper_update_plane,
|
||||||
.disable_plane = drm_atomic_helper_disable_plane,
|
.disable_plane = drm_atomic_helper_disable_plane,
|
||||||
.destroy = vc4_plane_destroy,
|
.destroy = drm_plane_cleanup,
|
||||||
.set_property = NULL,
|
.set_property = NULL,
|
||||||
.reset = vc4_plane_reset,
|
.reset = vc4_plane_reset,
|
||||||
.atomic_duplicate_state = vc4_plane_duplicate_state,
|
.atomic_duplicate_state = vc4_plane_duplicate_state,
|
||||||
|
@ -438,15 +438,10 @@ static const struct drm_plane_helper_funcs zx_gl_plane_helper_funcs = {
|
|||||||
.atomic_disable = zx_plane_atomic_disable,
|
.atomic_disable = zx_plane_atomic_disable,
|
||||||
};
|
};
|
||||||
|
|
||||||
static void zx_plane_destroy(struct drm_plane *plane)
|
|
||||||
{
|
|
||||||
drm_plane_cleanup(plane);
|
|
||||||
}
|
|
||||||
|
|
||||||
static const struct drm_plane_funcs zx_plane_funcs = {
|
static const struct drm_plane_funcs zx_plane_funcs = {
|
||||||
.update_plane = drm_atomic_helper_update_plane,
|
.update_plane = drm_atomic_helper_update_plane,
|
||||||
.disable_plane = drm_atomic_helper_disable_plane,
|
.disable_plane = drm_atomic_helper_disable_plane,
|
||||||
.destroy = zx_plane_destroy,
|
.destroy = drm_plane_cleanup,
|
||||||
.reset = drm_atomic_helper_plane_reset,
|
.reset = drm_atomic_helper_plane_reset,
|
||||||
.atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state,
|
.atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state,
|
||||||
.atomic_destroy_state = drm_atomic_helper_plane_destroy_state,
|
.atomic_destroy_state = drm_atomic_helper_plane_destroy_state,
|
||||||
|
@ -51,13 +51,6 @@ enum switch_power_state {
|
|||||||
* may contain multiple heads.
|
* may contain multiple heads.
|
||||||
*/
|
*/
|
||||||
struct drm_device {
|
struct drm_device {
|
||||||
/**
|
|
||||||
* @legacy_dev_list:
|
|
||||||
*
|
|
||||||
* List of devices per driver for stealth attach cleanup
|
|
||||||
*/
|
|
||||||
struct list_head legacy_dev_list;
|
|
||||||
|
|
||||||
/** @if_version: Highest interface version set */
|
/** @if_version: Highest interface version set */
|
||||||
int if_version;
|
int if_version;
|
||||||
|
|
||||||
@ -83,11 +76,7 @@ struct drm_device {
|
|||||||
} managed;
|
} managed;
|
||||||
|
|
||||||
/** @driver: DRM driver managing the device */
|
/** @driver: DRM driver managing the device */
|
||||||
#ifdef CONFIG_DRM_LEGACY
|
|
||||||
struct drm_driver *driver;
|
|
||||||
#else
|
|
||||||
const struct drm_driver *driver;
|
const struct drm_driver *driver;
|
||||||
#endif
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @dev_private:
|
* @dev_private:
|
||||||
@ -336,6 +325,9 @@ struct drm_device {
|
|||||||
/* Everything below here is for legacy driver, never use! */
|
/* Everything below here is for legacy driver, never use! */
|
||||||
/* private: */
|
/* private: */
|
||||||
#if IS_ENABLED(CONFIG_DRM_LEGACY)
|
#if IS_ENABLED(CONFIG_DRM_LEGACY)
|
||||||
|
/* List of devices per driver for stealth attach cleanup */
|
||||||
|
struct list_head legacy_dev_list;
|
||||||
|
|
||||||
/* Context handle management - linked list of context handles */
|
/* Context handle management - linked list of context handles */
|
||||||
struct list_head ctxlist;
|
struct list_head ctxlist;
|
||||||
|
|
||||||
|
@ -499,8 +499,6 @@ struct drm_driver {
|
|||||||
/* Everything below here is for legacy driver, never use! */
|
/* Everything below here is for legacy driver, never use! */
|
||||||
/* private: */
|
/* private: */
|
||||||
|
|
||||||
/* List of devices hanging off this driver with stealth attach. */
|
|
||||||
struct list_head legacy_dev_list;
|
|
||||||
int (*firstopen) (struct drm_device *);
|
int (*firstopen) (struct drm_device *);
|
||||||
void (*preclose) (struct drm_device *, struct drm_file *file_priv);
|
void (*preclose) (struct drm_device *, struct drm_file *file_priv);
|
||||||
int (*dma_ioctl) (struct drm_device *dev, void *data, struct drm_file *file_priv);
|
int (*dma_ioctl) (struct drm_device *dev, void *data, struct drm_file *file_priv);
|
||||||
|
@ -416,8 +416,5 @@ int drm_gem_fence_array_add_implicit(struct xarray *fence_array,
|
|||||||
bool write);
|
bool write);
|
||||||
int drm_gem_dumb_map_offset(struct drm_file *file, struct drm_device *dev,
|
int drm_gem_dumb_map_offset(struct drm_file *file, struct drm_device *dev,
|
||||||
u32 handle, u64 *offset);
|
u32 handle, u64 *offset);
|
||||||
int drm_gem_dumb_destroy(struct drm_file *file,
|
|
||||||
struct drm_device *dev,
|
|
||||||
uint32_t handle);
|
|
||||||
|
|
||||||
#endif /* __DRM_GEM_H__ */
|
#endif /* __DRM_GEM_H__ */
|
||||||
|
@ -198,8 +198,10 @@ struct drm_dma_handle *drm_pci_alloc(struct drm_device *dev, size_t size,
|
|||||||
size_t align);
|
size_t align);
|
||||||
void drm_pci_free(struct drm_device *dev, struct drm_dma_handle *dmah);
|
void drm_pci_free(struct drm_device *dev, struct drm_dma_handle *dmah);
|
||||||
|
|
||||||
int drm_legacy_pci_init(struct drm_driver *driver, struct pci_driver *pdriver);
|
int drm_legacy_pci_init(const struct drm_driver *driver,
|
||||||
void drm_legacy_pci_exit(struct drm_driver *driver, struct pci_driver *pdriver);
|
struct pci_driver *pdriver);
|
||||||
|
void drm_legacy_pci_exit(const struct drm_driver *driver,
|
||||||
|
struct pci_driver *pdriver);
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
@ -214,13 +216,13 @@ static inline void drm_pci_free(struct drm_device *dev,
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int drm_legacy_pci_init(struct drm_driver *driver,
|
static inline int drm_legacy_pci_init(const struct drm_driver *driver,
|
||||||
struct pci_driver *pdriver)
|
struct pci_driver *pdriver)
|
||||||
{
|
{
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void drm_legacy_pci_exit(struct drm_driver *driver,
|
static inline void drm_legacy_pci_exit(const struct drm_driver *driver,
|
||||||
struct pci_driver *pdriver)
|
struct pci_driver *pdriver)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -866,13 +866,19 @@ struct drm_connector_helper_funcs {
|
|||||||
* The usual way to implement this is to cache the EDID retrieved in the
|
* The usual way to implement this is to cache the EDID retrieved in the
|
||||||
* probe callback somewhere in the driver-private connector structure.
|
* probe callback somewhere in the driver-private connector structure.
|
||||||
* In this function drivers then parse the modes in the EDID and add
|
* In this function drivers then parse the modes in the EDID and add
|
||||||
* them by calling drm_add_edid_modes(). But connectors that driver a
|
* them by calling drm_add_edid_modes(). But connectors that drive a
|
||||||
* fixed panel can also manually add specific modes using
|
* fixed panel can also manually add specific modes using
|
||||||
* drm_mode_probed_add(). Drivers which manually add modes should also
|
* drm_mode_probed_add(). Drivers which manually add modes should also
|
||||||
* make sure that the &drm_connector.display_info,
|
* make sure that the &drm_connector.display_info,
|
||||||
* &drm_connector.width_mm and &drm_connector.height_mm fields are
|
* &drm_connector.width_mm and &drm_connector.height_mm fields are
|
||||||
* filled in.
|
* filled in.
|
||||||
*
|
*
|
||||||
|
* Note that the caller function will automatically add standard VESA
|
||||||
|
* DMT modes up to 1024x768 if the .get_modes() helper operation returns
|
||||||
|
* no mode and if the connector status is connector_status_connected or
|
||||||
|
* connector_status_unknown. There is no need to call
|
||||||
|
* drm_add_modes_noedid() manually in that case.
|
||||||
|
*
|
||||||
* Virtual drivers that just want some standard VESA mode with a given
|
* Virtual drivers that just want some standard VESA mode with a given
|
||||||
* resolution can call drm_add_modes_noedid(), and mark the preferred
|
* resolution can call drm_add_modes_noedid(), and mark the preferred
|
||||||
* one using drm_set_preferred_mode().
|
* one using drm_set_preferred_mode().
|
||||||
|
Loading…
x
Reference in New Issue
Block a user