drm-misc-next for 6.2:

UAPI Changes:
 
 Cross-subsystem Changes:
 - fbdev: Add support for the nomodeset kernel parameter
 
 Core Changes:
 - client: Add kunit tests for drm_connector_pick_cmdline_mode()
 - dma-buf: Move dma_buf_mmap_internal() to new locking specification
 - edid: Dump EDID on drm_edid_get_panel_id() failure, Stop using a
   temporary device to load the EDID through the firmware mechanism
 - fb-helper: Remove damage worker
 - gem-vram: Fix deadlock in drm_gem_vram_vmap()
 - modes: Named mode parsing improvements
 - tests: Add Kunit helpers to create a DRM device
 
 Driver Changes:
 - hisilicon: convert to drm_mode_init()
 - malidp: Use drm-managed resources
 - msm: convert to drm_mode_init() and drm_mode_copy()
 - mtk: convert to drm_mode_init()
 - nouveau: Support backlight control for nva3
 - rockchip: convert to drm_mode_copy()
 - sti: convert to drm_mode_copy()
 - v3d: Switch to drm-managed resources
 - vc4: Fix potential NULL pointer dereference
 
 - panels:
   - New panel: NewVision NV3051D
 -----BEGIN PGP SIGNATURE-----
 
 iHUEABYKAB0WIQRcEzekXsqa64kGDp7j7w1vZxhRxQUCY3XyTAAKCRDj7w1vZxhR
 xfh8APkBLspfEk0WneXqIanPLOLCIU4Fcd7IvjNsy5nRODM5ewD8D4pCzRYz6zGf
 0rAHzuvISUBHBWES/EWpO61GJ7d/1gA=
 =ZM1O
 -----END PGP SIGNATURE-----

Merge tag 'drm-misc-next-2022-11-17' of git://anongit.freedesktop.org/drm/drm-misc into drm-next

drm-misc-next for 6.2:

UAPI Changes:

Cross-subsystem Changes:
- fbdev: Add support for the nomodeset kernel parameter

Core Changes:
- client: Add kunit tests for drm_connector_pick_cmdline_mode()
- dma-buf: Move dma_buf_mmap_internal() to new locking specification
- edid: Dump EDID on drm_edid_get_panel_id() failure, Stop using a
  temporary device to load the EDID through the firmware mechanism
- fb-helper: Remove damage worker
- gem-vram: Fix deadlock in drm_gem_vram_vmap()
- modes: Named mode parsing improvements
- tests: Add Kunit helpers to create a DRM device

Driver Changes:
- hisilicon: convert to drm_mode_init()
- malidp: Use drm-managed resources
- msm: convert to drm_mode_init() and drm_mode_copy()
- mtk: convert to drm_mode_init()
- nouveau: Support backlight control for nva3
- rockchip: convert to drm_mode_copy()
- sti: convert to drm_mode_copy()
- v3d: Switch to drm-managed resources
- vc4: Fix potential NULL pointer dereference

- panels:
  - New panel: NewVision NV3051D

Signed-off-by: Dave Airlie <airlied@redhat.com>

From: Maxime Ripard <maxime@cerno.tech>
Link: https://patchwork.freedesktop.org/patch/msgid/20221117083628.mzij5nrbdzokek7c@houat
This commit is contained in:
Dave Airlie 2022-11-22 09:21:10 +10:00
commit 4302423c88
108 changed files with 1330 additions and 190 deletions

View File

@ -3777,12 +3777,15 @@
shutdown the other cpus. Instead use the REBOOT_VECTOR
irq.
nomodeset Disable kernel modesetting. DRM drivers will not perform
display-mode changes or accelerated rendering. Only the
system framebuffer will be available for use if this was
set-up by the firmware or boot loader.
nomodeset Disable kernel modesetting. Most systems' firmware
sets up a display mode and provides framebuffer memory
for output. With nomodeset, DRM and fbdev drivers will
not load if they could possibly displace the pre-
initialized output. Only the system framebuffer will
be available for use. The respective drivers will not
perform display-mode changes or accelerated rendering.
Useful as fallback, or for testing and debugging.
Useful as error fallback, or for testing and debugging.
nomodule Disable module load

View File

@ -0,0 +1,63 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/display/panel/newvision,nv3051d.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: NewVision NV3051D based LCD panel
description: |
The NewVision NV3051D is a driver chip used to drive DSI panels. For now,
this driver only supports the 640x480 panels found in the Anbernic RG353
based devices.
maintainers:
- Chris Morgan <macromorgan@hotmail.com>
allOf:
- $ref: panel-common.yaml#
properties:
compatible:
items:
- enum:
- anbernic,rg353p-panel
- anbernic,rg353v-panel
- const: newvision,nv3051d
reg: true
backlight: true
port: true
reset-gpios:
description: Active low reset GPIO
vdd-supply: true
required:
- compatible
- reg
- backlight
additionalProperties: false
examples:
- |
#include <dt-bindings/gpio/gpio.h>
dsi {
#address-cells = <1>;
#size-cells = <0>;
panel@0 {
compatible = "anbernic,rg353p-panel", "newvision,nv3051d";
reg = <0>;
backlight = <&backlight>;
reset-gpios = <&gpio4 0 GPIO_ACTIVE_LOW>;
vdd-supply = <&vcc3v3_lcd>;
port {
mipi_in_panel: endpoint {
remote-endpoint = <&mipi_out_panel>;
};
};
};
};
...

View File

@ -887,6 +887,8 @@ patternProperties:
description: Shenzhen Netxeon Technology CO., LTD
"^neweast,.*":
description: Guangdong Neweast Optoelectronics CO., LTD
"^newvision,.*":
description: New Vision Display (Shenzhen) Co., Ltd.
"^nexbox,.*":
description: Nexbox
"^nextthing,.*":

View File

@ -26,6 +26,11 @@ Valid mode specifiers (mode_option argument)::
with <xres>, <yres>, <bpp> and <refresh> decimal numbers and <name> a string.
Things between square brackets are optional.
Valid names are::
- NSTC: 480i output, with the CCIR System-M TV mode and NTSC color encoding
- PAL: 576i output, with the CCIR System-B TV mode and PAL color encoding
If 'M' is specified in the mode_option argument (after <yres> and before
<bpp> and <refresh>, if specified) the timings will be calculated using
VESA(TM) Coordinated Video Timings instead of looking up the mode from a table.

View File

@ -6701,8 +6701,10 @@ F: drivers/gpu/drm/drm_aperture.c
F: drivers/gpu/drm/tiny/ofdrm.c
F: drivers/gpu/drm/tiny/simpledrm.c
F: drivers/video/aperture.c
F: drivers/video/nomodeset.c
F: include/drm/drm_aperture.h
F: include/linux/aperture.h
F: include/video/nomodeset.h
DRM DRIVER FOR SIS VIDEO CARDS
S: Orphan / Obsolete

View File

@ -129,6 +129,7 @@ static struct file_system_type dma_buf_fs_type = {
static int dma_buf_mmap_internal(struct file *file, struct vm_area_struct *vma)
{
struct dma_buf *dmabuf;
int ret;
if (!is_dma_buf_file(file))
return -EINVAL;
@ -144,7 +145,11 @@ static int dma_buf_mmap_internal(struct file *file, struct vm_area_struct *vma)
dmabuf->size >> PAGE_SHIFT)
return -EINVAL;
return dmabuf->ops->mmap(dmabuf, vma);
dma_resv_lock(dmabuf->resv, NULL);
ret = dmabuf->ops->mmap(dmabuf, vma);
dma_resv_unlock(dmabuf->resv);
return ret;
}
static loff_t dma_buf_llseek(struct file *file, loff_t offset, int whence)

View File

@ -13,6 +13,7 @@
#include <linux/dma-buf.h>
#include <linux/dma-heap.h>
#include <linux/dma-map-ops.h>
#include <linux/dma-resv.h>
#include <linux/err.h>
#include <linux/highmem.h>
#include <linux/io.h>
@ -182,6 +183,8 @@ static int cma_heap_mmap(struct dma_buf *dmabuf, struct vm_area_struct *vma)
{
struct cma_heap_buffer *buffer = dmabuf->priv;
dma_resv_assert_held(dmabuf->resv);
if ((vma->vm_flags & (VM_SHARED | VM_MAYSHARE)) == 0)
return -EINVAL;

View File

@ -13,6 +13,7 @@
#include <linux/dma-buf.h>
#include <linux/dma-mapping.h>
#include <linux/dma-heap.h>
#include <linux/dma-resv.h>
#include <linux/err.h>
#include <linux/highmem.h>
#include <linux/mm.h>
@ -201,6 +202,8 @@ static int system_heap_mmap(struct dma_buf *dmabuf, struct vm_area_struct *vma)
struct sg_page_iter piter;
int ret;
dma_resv_assert_held(dmabuf->resv);
for_each_sgtable_page(table, &piter, vma->vm_pgoff) {
struct page *page = sg_page_iter_page(&piter);

View File

@ -2,6 +2,7 @@
#include <linux/cred.h>
#include <linux/device.h>
#include <linux/dma-buf.h>
#include <linux/dma-resv.h>
#include <linux/highmem.h>
#include <linux/init.h>
#include <linux/kernel.h>
@ -49,6 +50,8 @@ static int mmap_udmabuf(struct dma_buf *buf, struct vm_area_struct *vma)
{
struct udmabuf *ubuf = buf->priv;
dma_resv_assert_held(buf->resv);
if ((vma->vm_flags & (VM_SHARED | VM_MAYSHARE)) == 0)
return -EINVAL;

View File

@ -8,7 +8,6 @@
menuconfig DRM
tristate "Direct Rendering Manager (XFree86 4.1.0 and higher DRI support)"
depends on (AGP || AGP=n) && !EMULATED_CMPXCHG && HAS_DMA
select DRM_NOMODESET
select DRM_PANEL_ORIENTATION_QUIRKS
select HDMI
select FB_CMDLINE
@ -19,6 +18,7 @@ menuconfig DRM
# gallium uses SYS_kcmp for os_same_file_description() to de-duplicate
# device and dmabuf fd. Let's make sure that is available for our userspace.
select KCMP
select VIDEO_NOMODESET
help
Kernel-level support for the Direct Rendering Infrastructure (DRI)
introduced in XFree86 4.0. If you say Y here, you need to select
@ -514,11 +514,6 @@ config DRM_EXPORT_FOR_TESTS
config DRM_PANEL_ORIENTATION_QUIRKS
tristate
# Separate option because nomodeset parameter is global and expected built-in
config DRM_NOMODESET
bool
default n
config DRM_LIB_RANDOM
bool
default n

View File

@ -72,7 +72,6 @@ drm-$(CONFIG_DRM_PRIVACY_SCREEN) += \
drm_privacy_screen_x86.o
obj-$(CONFIG_DRM) += drm.o
obj-$(CONFIG_DRM_NOMODESET) += drm_nomodeset.o
obj-$(CONFIG_DRM_PANEL_ORIENTATION_QUIRKS) += drm_panel_orientation_quirks.o
#

View File

@ -514,7 +514,6 @@ static void malidp_crtc_disable_vblank(struct drm_crtc *crtc)
}
static const struct drm_crtc_funcs malidp_crtc_funcs = {
.destroy = drm_crtc_cleanup,
.set_config = drm_atomic_helper_set_config,
.page_flip = drm_atomic_helper_page_flip,
.reset = malidp_crtc_reset,
@ -526,7 +525,7 @@ static const struct drm_crtc_funcs malidp_crtc_funcs = {
int malidp_crtc_init(struct drm_device *drm)
{
struct malidp_drm *malidp = drm->dev_private;
struct malidp_drm *malidp = drm_to_malidp(drm);
struct drm_plane *primary = NULL, *plane;
int ret;
@ -548,8 +547,8 @@ int malidp_crtc_init(struct drm_device *drm)
return -EINVAL;
}
ret = drm_crtc_init_with_planes(drm, &malidp->crtc, primary, NULL,
&malidp_crtc_funcs, NULL);
ret = drmm_crtc_init_with_planes(drm, &malidp->crtc, primary, NULL,
&malidp_crtc_funcs, NULL);
if (ret)
return ret;

View File

@ -23,6 +23,7 @@
#include <drm/drm_fourcc.h>
#include <drm/drm_gem_dma_helper.h>
#include <drm/drm_gem_framebuffer_helper.h>
#include <drm/drm_managed.h>
#include <drm/drm_modeset_helper.h>
#include <drm/drm_module.h>
#include <drm/drm_of.h>
@ -168,7 +169,7 @@ static void malidp_atomic_commit_se_config(struct drm_crtc *crtc,
*/
static int malidp_set_and_wait_config_valid(struct drm_device *drm)
{
struct malidp_drm *malidp = drm->dev_private;
struct malidp_drm *malidp = drm_to_malidp(drm);
struct malidp_hw_device *hwdev = malidp->dev;
int ret;
@ -189,7 +190,7 @@ static int malidp_set_and_wait_config_valid(struct drm_device *drm)
static void malidp_atomic_commit_hw_done(struct drm_atomic_state *state)
{
struct drm_device *drm = state->dev;
struct malidp_drm *malidp = drm->dev_private;
struct malidp_drm *malidp = drm_to_malidp(drm);
int loop = 5;
malidp->event = malidp->crtc.state->event;
@ -230,7 +231,7 @@ static void malidp_atomic_commit_hw_done(struct drm_atomic_state *state)
static void malidp_atomic_commit_tail(struct drm_atomic_state *state)
{
struct drm_device *drm = state->dev;
struct malidp_drm *malidp = drm->dev_private;
struct malidp_drm *malidp = drm_to_malidp(drm);
struct drm_crtc *crtc;
struct drm_crtc_state *old_crtc_state;
int i;
@ -392,10 +393,12 @@ static const struct drm_mode_config_funcs malidp_mode_config_funcs = {
static int malidp_init(struct drm_device *drm)
{
int ret;
struct malidp_drm *malidp = drm->dev_private;
struct malidp_drm *malidp = drm_to_malidp(drm);
struct malidp_hw_device *hwdev = malidp->dev;
drm_mode_config_init(drm);
ret = drmm_mode_config_init(drm);
if (ret)
goto out;
drm->mode_config.min_width = hwdev->min_line_size;
drm->mode_config.min_height = hwdev->min_line_size;
@ -406,29 +409,21 @@ static int malidp_init(struct drm_device *drm)
ret = malidp_crtc_init(drm);
if (ret)
goto crtc_fail;
goto out;
ret = malidp_mw_connector_init(drm);
if (ret)
goto crtc_fail;
goto out;
return 0;
crtc_fail:
drm_mode_config_cleanup(drm);
out:
return ret;
}
static void malidp_fini(struct drm_device *drm)
{
drm_mode_config_cleanup(drm);
}
static int malidp_irq_init(struct platform_device *pdev)
{
int irq_de, irq_se, ret = 0;
struct drm_device *drm = dev_get_drvdata(&pdev->dev);
struct malidp_drm *malidp = drm->dev_private;
struct malidp_drm *malidp = drm_to_malidp(drm);
struct malidp_hw_device *hwdev = malidp->dev;
/* fetch the interrupts from DT */
@ -462,7 +457,7 @@ static int malidp_dumb_create(struct drm_file *file_priv,
struct drm_device *drm,
struct drm_mode_create_dumb *args)
{
struct malidp_drm *malidp = drm->dev_private;
struct malidp_drm *malidp = drm_to_malidp(drm);
/* allocate for the worst case scenario, i.e. rotated buffers */
u8 alignment = malidp_hw_get_pitch_align(malidp->dev, 1);
@ -508,7 +503,7 @@ static void malidp_error_stats_dump(const char *prefix,
static int malidp_show_stats(struct seq_file *m, void *arg)
{
struct drm_device *drm = m->private;
struct malidp_drm *malidp = drm->dev_private;
struct malidp_drm *malidp = drm_to_malidp(drm);
unsigned long irqflags;
struct malidp_error_stats de_errors, se_errors;
@ -531,7 +526,7 @@ static ssize_t malidp_debugfs_write(struct file *file, const char __user *ubuf,
{
struct seq_file *m = file->private_data;
struct drm_device *drm = m->private;
struct malidp_drm *malidp = drm->dev_private;
struct malidp_drm *malidp = drm_to_malidp(drm);
unsigned long irqflags;
spin_lock_irqsave(&malidp->errors_lock, irqflags);
@ -552,7 +547,7 @@ static const struct file_operations malidp_debugfs_fops = {
static void malidp_debugfs_init(struct drm_minor *minor)
{
struct malidp_drm *malidp = minor->dev->dev_private;
struct malidp_drm *malidp = drm_to_malidp(minor->dev);
malidp_error_stats_init(&malidp->de_errors);
malidp_error_stats_init(&malidp->se_errors);
@ -652,7 +647,7 @@ static ssize_t core_id_show(struct device *dev, struct device_attribute *attr,
char *buf)
{
struct drm_device *drm = dev_get_drvdata(dev);
struct malidp_drm *malidp = drm->dev_private;
struct malidp_drm *malidp = drm_to_malidp(drm);
return snprintf(buf, PAGE_SIZE, "%08x\n", malidp->core_id);
}
@ -670,7 +665,7 @@ ATTRIBUTE_GROUPS(mali_dp);
static int malidp_runtime_pm_suspend(struct device *dev)
{
struct drm_device *drm = dev_get_drvdata(dev);
struct malidp_drm *malidp = drm->dev_private;
struct malidp_drm *malidp = drm_to_malidp(drm);
struct malidp_hw_device *hwdev = malidp->dev;
/* we can only suspend if the hardware is in config mode */
@ -689,7 +684,7 @@ static int malidp_runtime_pm_suspend(struct device *dev)
static int malidp_runtime_pm_resume(struct device *dev)
{
struct drm_device *drm = dev_get_drvdata(dev);
struct malidp_drm *malidp = drm->dev_private;
struct malidp_drm *malidp = drm_to_malidp(drm);
struct malidp_hw_device *hwdev = malidp->dev;
clk_prepare_enable(hwdev->pclk);
@ -716,11 +711,13 @@ static int malidp_bind(struct device *dev)
int ret = 0, i;
u32 version, out_depth = 0;
malidp = devm_kzalloc(dev, sizeof(*malidp), GFP_KERNEL);
if (!malidp)
return -ENOMEM;
malidp = devm_drm_dev_alloc(dev, &malidp_driver, typeof(*malidp), base);
if (IS_ERR(malidp))
return PTR_ERR(malidp);
hwdev = devm_kzalloc(dev, sizeof(*hwdev), GFP_KERNEL);
drm = &malidp->base;
hwdev = drmm_kzalloc(drm, sizeof(*hwdev), GFP_KERNEL);
if (!hwdev)
return -ENOMEM;
@ -753,13 +750,6 @@ static int malidp_bind(struct device *dev)
if (ret && ret != -ENODEV)
return ret;
drm = drm_dev_alloc(&malidp_driver, dev);
if (IS_ERR(drm)) {
ret = PTR_ERR(drm);
goto alloc_fail;
}
drm->dev_private = malidp;
dev_set_drvdata(dev, drm);
/* Enable power management */
@ -878,17 +868,13 @@ irq_init_fail:
bind_fail:
of_node_put(malidp->crtc.port);
malidp->crtc.port = NULL;
malidp_fini(drm);
query_hw_fail:
pm_runtime_put(dev);
if (pm_runtime_enabled(dev))
pm_runtime_disable(dev);
else
malidp_runtime_pm_suspend(dev);
drm->dev_private = NULL;
dev_set_drvdata(dev, NULL);
drm_dev_put(drm);
alloc_fail:
of_reserved_mem_device_release(dev);
return ret;
@ -897,7 +883,7 @@ alloc_fail:
static void malidp_unbind(struct device *dev)
{
struct drm_device *drm = dev_get_drvdata(dev);
struct malidp_drm *malidp = drm->dev_private;
struct malidp_drm *malidp = drm_to_malidp(drm);
struct malidp_hw_device *hwdev = malidp->dev;
drm_dev_unregister(drm);
@ -909,15 +895,12 @@ static void malidp_unbind(struct device *dev)
component_unbind_all(dev, drm);
of_node_put(malidp->crtc.port);
malidp->crtc.port = NULL;
malidp_fini(drm);
pm_runtime_put(dev);
if (pm_runtime_enabled(dev))
pm_runtime_disable(dev);
else
malidp_runtime_pm_suspend(dev);
drm->dev_private = NULL;
dev_set_drvdata(dev, NULL);
drm_dev_put(drm);
of_reserved_mem_device_release(dev);
}

View File

@ -29,6 +29,7 @@ struct malidp_error_stats {
};
struct malidp_drm {
struct drm_device base;
struct malidp_hw_device *dev;
struct drm_crtc crtc;
struct drm_writeback_connector mw_connector;
@ -44,6 +45,7 @@ struct malidp_drm {
#endif
};
#define drm_to_malidp(x) container_of(x, struct malidp_drm, base)
#define crtc_to_malidp_device(x) container_of(x, struct malidp_drm, crtc)
struct malidp_plane {

View File

@ -1168,7 +1168,7 @@ static void malidp_hw_clear_irq(struct malidp_hw_device *hwdev, u8 block, u32 ir
static irqreturn_t malidp_de_irq(int irq, void *arg)
{
struct drm_device *drm = arg;
struct malidp_drm *malidp = drm->dev_private;
struct malidp_drm *malidp = drm_to_malidp(drm);
struct malidp_hw_device *hwdev;
struct malidp_hw *hw;
const struct malidp_irq_map *de;
@ -1226,7 +1226,7 @@ static irqreturn_t malidp_de_irq(int irq, void *arg)
static irqreturn_t malidp_de_irq_thread_handler(int irq, void *arg)
{
struct drm_device *drm = arg;
struct malidp_drm *malidp = drm->dev_private;
struct malidp_drm *malidp = drm_to_malidp(drm);
wake_up(&malidp->wq);
@ -1252,7 +1252,7 @@ void malidp_de_irq_hw_init(struct malidp_hw_device *hwdev)
int malidp_de_irq_init(struct drm_device *drm, int irq)
{
struct malidp_drm *malidp = drm->dev_private;
struct malidp_drm *malidp = drm_to_malidp(drm);
struct malidp_hw_device *hwdev = malidp->dev;
int ret;
@ -1286,7 +1286,7 @@ void malidp_de_irq_fini(struct malidp_hw_device *hwdev)
static irqreturn_t malidp_se_irq(int irq, void *arg)
{
struct drm_device *drm = arg;
struct malidp_drm *malidp = drm->dev_private;
struct malidp_drm *malidp = drm_to_malidp(drm);
struct malidp_hw_device *hwdev = malidp->dev;
struct malidp_hw *hw = hwdev->hw;
const struct malidp_irq_map *se = &hw->map.se_irq_map;
@ -1363,7 +1363,7 @@ static irqreturn_t malidp_se_irq_thread_handler(int irq, void *arg)
int malidp_se_irq_init(struct drm_device *drm, int irq)
{
struct malidp_drm *malidp = drm->dev_private;
struct malidp_drm *malidp = drm_to_malidp(drm);
struct malidp_hw_device *hwdev = malidp->dev;
int ret;

View File

@ -129,7 +129,7 @@ malidp_mw_encoder_atomic_check(struct drm_encoder *encoder,
struct drm_connector_state *conn_state)
{
struct malidp_mw_connector_state *mw_state = to_mw_state(conn_state);
struct malidp_drm *malidp = encoder->dev->dev_private;
struct malidp_drm *malidp = drm_to_malidp(encoder->dev);
struct drm_framebuffer *fb;
int i, n_planes;
@ -207,7 +207,7 @@ static u32 *get_writeback_formats(struct malidp_drm *malidp, int *n_formats)
int malidp_mw_connector_init(struct drm_device *drm)
{
struct malidp_drm *malidp = drm->dev_private;
struct malidp_drm *malidp = drm_to_malidp(drm);
u32 *formats;
int ret, n_formats;
@ -236,7 +236,7 @@ int malidp_mw_connector_init(struct drm_device *drm)
void malidp_mw_atomic_commit(struct drm_device *drm,
struct drm_atomic_state *old_state)
{
struct malidp_drm *malidp = drm->dev_private;
struct malidp_drm *malidp = drm_to_malidp(drm);
struct drm_writeback_connector *mw_conn = &malidp->mw_connector;
struct drm_connector_state *conn_state = mw_conn->base.state;
struct malidp_hw_device *hwdev = malidp->dev;

View File

@ -68,14 +68,6 @@
/* readahead for partial-frame prefetch */
#define MALIDP_MMU_PREFETCH_READAHEAD 8
static void malidp_de_plane_destroy(struct drm_plane *plane)
{
struct malidp_plane *mp = to_malidp_plane(plane);
drm_plane_cleanup(plane);
kfree(mp);
}
/*
* Replicate what the default ->reset hook does: free the state pointer and
* allocate a new empty object. We just need enough space to store
@ -151,7 +143,7 @@ bool malidp_format_mod_supported(struct drm_device *drm,
{
const struct drm_format_info *info;
const u64 *modifiers;
struct malidp_drm *malidp = drm->dev_private;
struct malidp_drm *malidp = drm_to_malidp(drm);
const struct malidp_hw_regmap *map = &malidp->dev->hw->map;
if (WARN_ON(modifier == DRM_FORMAT_MOD_INVALID))
@ -260,7 +252,6 @@ static bool malidp_format_mod_supported_per_plane(struct drm_plane *plane,
static const struct drm_plane_funcs malidp_de_plane_funcs = {
.update_plane = drm_atomic_helper_update_plane,
.disable_plane = drm_atomic_helper_disable_plane,
.destroy = malidp_de_plane_destroy,
.reset = malidp_plane_reset,
.atomic_duplicate_state = malidp_duplicate_plane_state,
.atomic_destroy_state = malidp_destroy_plane_state,
@ -931,7 +922,7 @@ static const uint64_t linear_only_modifiers[] = {
int malidp_de_planes_init(struct drm_device *drm)
{
struct malidp_drm *malidp = drm->dev_private;
struct malidp_drm *malidp = drm_to_malidp(drm);
const struct malidp_hw_regmap *map = &malidp->dev->hw->map;
struct malidp_plane *plane = NULL;
enum drm_plane_type plane_type;
@ -972,12 +963,6 @@ int malidp_de_planes_init(struct drm_device *drm)
for (i = 0; i < map->n_layers; i++) {
u8 id = map->layers[i].id;
plane = kzalloc(sizeof(*plane), GFP_KERNEL);
if (!plane) {
ret = -ENOMEM;
goto cleanup;
}
/* build the list of DRM supported formats based on the map */
for (n = 0, j = 0; j < map->n_pixel_formats; j++) {
if ((map->pixel_formats[j].layer & id) == id)
@ -990,13 +975,14 @@ int malidp_de_planes_init(struct drm_device *drm)
/*
* All the layers except smart layer supports AFBC modifiers.
*/
ret = drm_universal_plane_init(drm, &plane->base, crtcs,
&malidp_de_plane_funcs, formats, n,
(id == DE_SMART) ? linear_only_modifiers : modifiers,
plane_type, NULL);
if (ret < 0)
plane = drmm_universal_plane_alloc(drm, struct malidp_plane, base,
crtcs, &malidp_de_plane_funcs, formats, n,
(id == DE_SMART) ? linear_only_modifiers :
modifiers, plane_type, NULL);
if (IS_ERR(plane)) {
ret = PTR_ERR(plane);
goto cleanup;
}
drm_plane_helper_add(&plane->base,
&malidp_de_plane_helper_funcs);

View File

@ -1237,3 +1237,7 @@ int drm_client_modeset_dpms(struct drm_client_dev *client, int mode)
return ret;
}
EXPORT_SYMBOL(drm_client_modeset_dpms);
#ifdef CONFIG_DRM_KUNIT_TEST
#include "tests/drm_client_modeset_test.c"
#endif

View File

@ -2807,6 +2807,8 @@ u32 drm_edid_get_panel_id(struct i2c_adapter *adapter)
if (edid_block_status_valid(status, edid_block_tag(base_block)))
panel_id = edid_extract_panel_id(base_block);
else
edid_block_dump(KERN_NOTICE, base_block, 0);
kfree(base_block);

View File

@ -172,20 +172,9 @@ static const struct drm_edid *edid_load(struct drm_connector *connector, const c
fwdata = generic_edid[builtin];
fwsize = sizeof(generic_edid[builtin]);
} else {
struct platform_device *pdev;
int err;
pdev = platform_device_register_simple(connector->name, -1, NULL, 0);
if (IS_ERR(pdev)) {
drm_err(connector->dev,
"[CONNECTOR:%d:%s] Failed to register EDID firmware platform device for connector \"%s\"\n",
connector->base.id, connector->name,
connector->name);
return ERR_CAST(pdev);
}
err = request_firmware(&fw, name, &pdev->dev);
platform_device_unregister(pdev);
err = request_firmware(&fw, name, connector->dev->dev);
if (err) {
drm_err(connector->dev,
"[CONNECTOR:%d:%s] Requesting EDID firmware \"%s\" failed (err=%d)\n",

View File

@ -367,9 +367,8 @@ static void drm_fb_helper_resume_worker(struct work_struct *work)
console_unlock();
}
static void drm_fb_helper_damage_work(struct work_struct *work)
static void drm_fb_helper_fb_dirty(struct drm_fb_helper *helper)
{
struct drm_fb_helper *helper = container_of(work, struct drm_fb_helper, damage_work);
struct drm_device *dev = helper->dev;
struct drm_clip_rect *clip = &helper->damage_clip;
struct drm_clip_rect clip_copy;
@ -419,7 +418,6 @@ void drm_fb_helper_prepare(struct drm_device *dev, struct drm_fb_helper *helper,
INIT_LIST_HEAD(&helper->kernel_fb_list);
spin_lock_init(&helper->damage_lock);
INIT_WORK(&helper->resume_work, drm_fb_helper_resume_worker);
INIT_WORK(&helper->damage_work, drm_fb_helper_damage_work);
helper->damage_clip.x1 = helper->damage_clip.y1 = ~0;
mutex_init(&helper->lock);
helper->funcs = funcs;
@ -551,7 +549,6 @@ void drm_fb_helper_fini(struct drm_fb_helper *fb_helper)
return;
cancel_work_sync(&fb_helper->resume_work);
cancel_work_sync(&fb_helper->damage_work);
info = fb_helper->info;
if (info) {
@ -576,8 +573,8 @@ void drm_fb_helper_fini(struct drm_fb_helper *fb_helper)
}
EXPORT_SYMBOL(drm_fb_helper_fini);
static void drm_fb_helper_damage(struct drm_fb_helper *helper, u32 x, u32 y,
u32 width, u32 height)
static void drm_fb_helper_add_damage_clip(struct drm_fb_helper *helper, u32 x, u32 y,
u32 width, u32 height)
{
struct drm_clip_rect *clip = &helper->damage_clip;
unsigned long flags;
@ -588,8 +585,21 @@ static void drm_fb_helper_damage(struct drm_fb_helper *helper, u32 x, u32 y,
clip->x2 = max_t(u32, clip->x2, x + width);
clip->y2 = max_t(u32, clip->y2, y + height);
spin_unlock_irqrestore(&helper->damage_lock, flags);
}
schedule_work(&helper->damage_work);
static void drm_fb_helper_damage(struct drm_fb_helper *helper, u32 x, u32 y,
u32 width, u32 height)
{
struct fb_info *info = helper->info;
drm_fb_helper_add_damage_clip(helper, x, y, width, height);
/*
* The current fbdev emulation only flushes buffers if a damage
* update is necessary. And we can assume that deferred I/O has
* been enabled as damage updates require deferred I/O for mmap.
*/
fb_deferred_io_schedule_flush(info);
}
/*
@ -644,22 +654,26 @@ void drm_fb_helper_deferred_io(struct fb_info *info, struct list_head *pagerefli
min_off = min(min_off, start);
max_off = max(max_off, end);
}
if (min_off >= max_off)
return;
if (helper->funcs->fb_dirty) {
/*
* As we can only track pages, we might reach beyond the end
* of the screen and account for non-existing scanlines. Hence,
* keep the covered memory area within the screen buffer.
*/
max_off = min(max_off, info->screen_size);
/*
* As we can only track pages, we might reach beyond the end
* of the screen and account for non-existing scanlines. Hence,
* keep the covered memory area within the screen buffer.
*/
max_off = min(max_off, info->screen_size);
if (min_off < max_off) {
drm_fb_helper_memory_range_to_clip(info, min_off, max_off - min_off, &damage_area);
drm_fb_helper_damage(helper, damage_area.x1, damage_area.y1,
drm_rect_width(&damage_area),
drm_rect_height(&damage_area));
drm_fb_helper_add_damage_clip(helper, damage_area.x1, damage_area.y1,
drm_rect_width(&damage_area),
drm_rect_height(&damage_area));
}
/*
* Flushes all dirty pages from mmap's pageref list and the
* areas that have been written by struct fb_ops callbacks.
*/
drm_fb_helper_fb_dirty(helper);
}
EXPORT_SYMBOL(drm_fb_helper_deferred_io);

View File

@ -297,12 +297,12 @@ const struct drm_format_info *__drm_format_info(u32 format)
.vsub = 2, .is_yuv = true },
{ .format = DRM_FORMAT_Q410, .depth = 0,
.num_planes = 3, .char_per_block = { 2, 2, 2 },
.block_w = { 1, 1, 1 }, .block_h = { 1, 1, 1 }, .hsub = 0,
.vsub = 0, .is_yuv = true },
.block_w = { 1, 1, 1 }, .block_h = { 1, 1, 1 }, .hsub = 1,
.vsub = 1, .is_yuv = true },
{ .format = DRM_FORMAT_Q401, .depth = 0,
.num_planes = 3, .char_per_block = { 2, 2, 2 },
.block_w = { 1, 1, 1 }, .block_h = { 1, 1, 1 }, .hsub = 0,
.vsub = 0, .is_yuv = true },
.block_w = { 1, 1, 1 }, .block_h = { 1, 1, 1 }, .hsub = 1,
.vsub = 1, .is_yuv = true },
{ .format = DRM_FORMAT_P030, .depth = 0, .num_planes = 2,
.char_per_block = { 4, 8, 0 }, .block_w = { 3, 3, 0 }, .block_h = { 1, 1, 0 },
.hsub = 2, .vsub = 2, .is_yuv = true},

View File

@ -433,25 +433,19 @@ int drm_gem_vram_vmap(struct drm_gem_vram_object *gbo, struct iosys_map *map)
{
int ret;
ret = ttm_bo_reserve(&gbo->bo, true, false, NULL);
if (ret)
return ret;
dma_resv_assert_held(gbo->bo.base.resv);
ret = drm_gem_vram_pin_locked(gbo, 0);
if (ret)
goto err_ttm_bo_unreserve;
return ret;
ret = drm_gem_vram_kmap_locked(gbo, map);
if (ret)
goto err_drm_gem_vram_unpin_locked;
ttm_bo_unreserve(&gbo->bo);
return 0;
err_drm_gem_vram_unpin_locked:
drm_gem_vram_unpin_locked(gbo);
err_ttm_bo_unreserve:
ttm_bo_unreserve(&gbo->bo);
return ret;
}
EXPORT_SYMBOL(drm_gem_vram_vmap);
@ -467,16 +461,10 @@ EXPORT_SYMBOL(drm_gem_vram_vmap);
void drm_gem_vram_vunmap(struct drm_gem_vram_object *gbo,
struct iosys_map *map)
{
int ret;
ret = ttm_bo_reserve(&gbo->bo, false, false, NULL);
if (WARN_ONCE(ret, "ttm_bo_reserve_failed(): ret=%d\n", ret))
return;
dma_resv_assert_held(gbo->bo.base.resv);
drm_gem_vram_kunmap_locked(gbo, map);
drm_gem_vram_unpin_locked(gbo);
ttm_bo_unreserve(&gbo->bo);
}
EXPORT_SYMBOL(drm_gem_vram_vunmap);

View File

@ -1750,11 +1750,78 @@ static int drm_mode_parse_cmdline_options(const char *str,
return 0;
}
static const char * const drm_named_modes_whitelist[] = {
"NTSC",
"PAL",
struct drm_named_mode {
const char *name;
unsigned int pixel_clock_khz;
unsigned int xres;
unsigned int yres;
unsigned int flags;
};
#define NAMED_MODE(_name, _pclk, _x, _y, _flags) \
{ \
.name = _name, \
.pixel_clock_khz = _pclk, \
.xres = _x, \
.yres = _y, \
.flags = _flags, \
}
static const struct drm_named_mode drm_named_modes[] = {
NAMED_MODE("NTSC", 13500, 720, 480, DRM_MODE_FLAG_INTERLACE),
NAMED_MODE("PAL", 13500, 720, 576, DRM_MODE_FLAG_INTERLACE),
};
static int drm_mode_parse_cmdline_named_mode(const char *name,
unsigned int name_end,
struct drm_cmdline_mode *cmdline_mode)
{
unsigned int i;
if (!name_end)
return 0;
/* If the name starts with a digit, it's not a named mode */
if (isdigit(name[0]))
return 0;
/*
* If there's an equal sign in the name, the command-line
* contains only an option and no mode.
*/
if (strnchr(name, name_end, '='))
return 0;
/* The connection status extras can be set without a mode. */
if (name_end == 1 &&
(name[0] == 'd' || name[0] == 'D' || name[0] == 'e'))
return 0;
/*
* We're sure we're a named mode at this point, iterate over the
* list of modes we're aware of.
*/
for (i = 0; i < ARRAY_SIZE(drm_named_modes); i++) {
const struct drm_named_mode *mode = &drm_named_modes[i];
int ret;
ret = str_has_prefix(name, mode->name);
if (ret != name_end)
continue;
strcpy(cmdline_mode->name, mode->name);
cmdline_mode->pixel_clock = mode->pixel_clock_khz;
cmdline_mode->xres = mode->xres;
cmdline_mode->yres = mode->yres;
cmdline_mode->interlace = !!(mode->flags & DRM_MODE_FLAG_INTERLACE);
cmdline_mode->specified = true;
return 1;
}
return -EINVAL;
}
/**
* drm_mode_parse_command_line_for_connector - parse command line modeline for connector
* @mode_option: optional per connector mode option
@ -1791,7 +1858,7 @@ bool drm_mode_parse_command_line_for_connector(const char *mode_option,
const char *bpp_ptr = NULL, *refresh_ptr = NULL, *extra_ptr = NULL;
const char *options_ptr = NULL;
char *bpp_end_ptr = NULL, *refresh_end_ptr = NULL;
int i, len, ret;
int len, ret;
memset(mode, 0, sizeof(*mode));
mode->panel_orientation = DRM_MODE_PANEL_ORIENTATION_UNKNOWN;
@ -1832,18 +1899,19 @@ bool drm_mode_parse_command_line_for_connector(const char *mode_option,
parse_extras = true;
}
/* First check for a named mode */
for (i = 0; i < ARRAY_SIZE(drm_named_modes_whitelist); i++) {
ret = str_has_prefix(name, drm_named_modes_whitelist[i]);
if (ret == mode_end) {
if (refresh_ptr)
return false; /* named + refresh is invalid */
if (!mode_end)
return false;
strcpy(mode->name, drm_named_modes_whitelist[i]);
mode->specified = true;
break;
}
}
ret = drm_mode_parse_cmdline_named_mode(name, mode_end, mode);
if (ret < 0)
return false;
/*
* Having a mode that starts by a letter (and thus is named) and
* an at-sign (used to specify a refresh rate) is disallowed.
*/
if (ret && refresh_ptr)
return false;
/* No named mode? Check for a normal mode argument, e.g. 1024x768 */
if (!mode->specified && isdigit(name[0])) {

View File

@ -781,6 +781,8 @@ int drm_gem_dmabuf_mmap(struct dma_buf *dma_buf, struct vm_area_struct *vma)
struct drm_gem_object *obj = dma_buf->priv;
struct drm_device *dev = obj->dev;
dma_resv_assert_held(dma_buf->resv);
if (!dev->driver->gem_prime_mmap)
return -ENOSYS;

View File

@ -658,7 +658,7 @@ static enum drm_mode_status dsi_encoder_mode_valid(struct drm_encoder *encoder,
* reset adj_mode to the mode value each time,
* so we don't adjust the mode twice
*/
drm_mode_copy(&adj_mode, mode);
drm_mode_init(&adj_mode, mode);
crtc_funcs = crtc->helper_private;
if (crtc_funcs && crtc_funcs->mode_fixup)

View File

@ -97,6 +97,8 @@ static int i915_gem_dmabuf_mmap(struct dma_buf *dma_buf, struct vm_area_struct *
struct drm_i915_private *i915 = to_i915(obj->base.dev);
int ret;
dma_resv_assert_held(dma_buf->resv);
if (obj->base.size < vma->vm_end - vma->vm_start)
return -EINVAL;

View File

@ -1217,7 +1217,7 @@ static int mtk_hdmi_bridge_mode_valid(struct drm_bridge *bridge,
if (next_bridge) {
struct drm_display_mode adjusted_mode;
drm_mode_copy(&adjusted_mode, mode);
drm_mode_init(&adjusted_mode, mode);
if (!drm_bridge_chain_mode_fixup(next_bridge, mode,
&adjusted_mode))
return MODE_BAD;

View File

@ -237,12 +237,13 @@ static void dpu_encoder_phys_vid_setup_timing_engine(
unsigned long lock_flags;
struct dpu_hw_intf_cfg intf_cfg = { 0 };
drm_mode_init(&mode, &phys_enc->cached_mode);
if (!phys_enc->hw_ctl->ops.setup_intf_cfg) {
DPU_ERROR("invalid encoder %d\n", phys_enc != NULL);
return;
}
mode = phys_enc->cached_mode;
if (!phys_enc->hw_intf->ops.setup_timing_gen) {
DPU_ERROR("timing engine setup is not supported\n");
return;
@ -634,7 +635,9 @@ static int dpu_encoder_phys_vid_get_frame_count(
{
struct intf_status s = {0};
u32 fetch_start = 0;
struct drm_display_mode mode = phys_enc->cached_mode;
struct drm_display_mode mode;
drm_mode_init(&mode, &phys_enc->cached_mode);
if (!dpu_encoder_phys_vid_is_master(phys_enc))
return -EINVAL;

View File

@ -857,7 +857,7 @@ static int dp_display_set_mode(struct msm_dp *dp_display,
dp = container_of(dp_display, struct dp_display_private, dp_display);
dp->panel->dp_mode.drm_mode = mode->drm_mode;
drm_mode_copy(&dp->panel->dp_mode.drm_mode, &mode->drm_mode);
dp->panel->dp_mode.bpp = mode->bpp;
dp->panel->dp_mode.capabilities = mode->capabilities;
dp_panel_init_panel_info(dp->panel);

View File

@ -264,7 +264,11 @@ nva3_set_intensity(struct backlight_device *bd)
u32 div, val;
div = nvif_rd32(device, NV50_PDISP_SOR_PWM_DIV(or));
val = (bd->props.brightness * div) / 100;
val = backlight_get_brightness(bd);
if (val)
val = (val * div) / 100;
if (div) {
nvif_wr32(device, NV50_PDISP_SOR_PWM_CTL(or),
val |

View File

@ -66,6 +66,8 @@ static int omap_gem_dmabuf_mmap(struct dma_buf *buffer,
struct drm_gem_object *obj = buffer->priv;
int ret = 0;
dma_resv_assert_held(buffer->resv);
ret = drm_gem_mmap_obj(obj, omap_gem_mmap_size(obj), vma);
if (ret < 0)
return ret;

View File

@ -306,6 +306,15 @@ config DRM_PANEL_NEC_NL8048HL11
panel (found on the Zoom2/3/3630 SDP boards). To compile this driver
as a module, choose M here.
config DRM_PANEL_NEWVISION_NV3051D
tristate "NewVision NV3051D DSI panel"
depends on OF
depends on DRM_MIPI_DSI
depends on BACKLIGHT_CLASS_DEVICE
help
This driver supports the NV3051D based panel found on the Anbernic
RG353P and RG353V.
config DRM_PANEL_NEWVISION_NV3052C
tristate "NewVision NV3052C RGB/SPI panel"
depends on OF && SPI

View File

@ -28,6 +28,7 @@ obj-$(CONFIG_DRM_PANEL_LEADTEK_LTK500HD1829) += panel-leadtek-ltk500hd1829.o
obj-$(CONFIG_DRM_PANEL_LG_LB035Q02) += panel-lg-lb035q02.o
obj-$(CONFIG_DRM_PANEL_LG_LG4573) += panel-lg-lg4573.o
obj-$(CONFIG_DRM_PANEL_NEC_NL8048HL11) += panel-nec-nl8048hl11.o
obj-$(CONFIG_DRM_PANEL_NEWVISION_NV3051D) += panel-newvision-nv3051d.o
obj-$(CONFIG_DRM_PANEL_NEWVISION_NV3052C) += panel-newvision-nv3052c.o
obj-$(CONFIG_DRM_PANEL_NOVATEK_NT35510) += panel-novatek-nt35510.o
obj-$(CONFIG_DRM_PANEL_NOVATEK_NT35560) += panel-novatek-nt35560.o

View File

@ -0,0 +1,504 @@
// SPDX-License-Identifier: GPL-2.0
/*
* NV3051D MIPI-DSI panel driver for Anbernic RG353x
* Copyright (C) 2022 Chris Morgan
*
* based on
*
* Elida kd35t133 3.5" MIPI-DSI panel driver
* Copyright (C) Theobroma Systems 2020
*/
#include <linux/delay.h>
#include <linux/gpio/consumer.h>
#include <linux/media-bus-format.h>
#include <linux/module.h>
#include <linux/of_device.h>
#include <linux/regulator/consumer.h>
#include <video/display_timing.h>
#include <video/mipi_display.h>
#include <drm/drm_mipi_dsi.h>
#include <drm/drm_modes.h>
#include <drm/drm_panel.h>
struct nv3051d_panel_info {
const struct drm_display_mode *display_modes;
unsigned int num_modes;
u16 width_mm, height_mm;
u32 bus_flags;
};
struct panel_nv3051d {
struct device *dev;
struct drm_panel panel;
struct gpio_desc *reset_gpio;
const struct nv3051d_panel_info *panel_info;
struct regulator *vdd;
};
static inline struct panel_nv3051d *panel_to_panelnv3051d(struct drm_panel *panel)
{
return container_of(panel, struct panel_nv3051d, panel);
}
static int panel_nv3051d_init_sequence(struct panel_nv3051d *ctx)
{
struct mipi_dsi_device *dsi = to_mipi_dsi_device(ctx->dev);
/*
* Init sequence was supplied by device vendor with no
* documentation.
*/
mipi_dsi_dcs_write_seq(dsi, 0xFF, 0x30);
mipi_dsi_dcs_write_seq(dsi, 0xFF, 0x52);
mipi_dsi_dcs_write_seq(dsi, 0xFF, 0x01);
mipi_dsi_dcs_write_seq(dsi, 0xE3, 0x00);
mipi_dsi_dcs_write_seq(dsi, 0x03, 0x40);
mipi_dsi_dcs_write_seq(dsi, 0x04, 0x00);
mipi_dsi_dcs_write_seq(dsi, 0x05, 0x03);
mipi_dsi_dcs_write_seq(dsi, 0x24, 0x12);
mipi_dsi_dcs_write_seq(dsi, 0x25, 0x1E);
mipi_dsi_dcs_write_seq(dsi, 0x26, 0x28);
mipi_dsi_dcs_write_seq(dsi, 0x27, 0x52);
mipi_dsi_dcs_write_seq(dsi, 0x28, 0x57);
mipi_dsi_dcs_write_seq(dsi, 0x29, 0x01);
mipi_dsi_dcs_write_seq(dsi, 0x2A, 0xDF);
mipi_dsi_dcs_write_seq(dsi, 0x38, 0x9C);
mipi_dsi_dcs_write_seq(dsi, 0x39, 0xA7);
mipi_dsi_dcs_write_seq(dsi, 0x3A, 0x53);
mipi_dsi_dcs_write_seq(dsi, 0x44, 0x00);
mipi_dsi_dcs_write_seq(dsi, 0x49, 0x3C);
mipi_dsi_dcs_write_seq(dsi, 0x59, 0xFE);
mipi_dsi_dcs_write_seq(dsi, 0x5C, 0x00);
mipi_dsi_dcs_write_seq(dsi, 0x91, 0x77);
mipi_dsi_dcs_write_seq(dsi, 0x92, 0x77);
mipi_dsi_dcs_write_seq(dsi, 0xA0, 0x55);
mipi_dsi_dcs_write_seq(dsi, 0xA1, 0x50);
mipi_dsi_dcs_write_seq(dsi, 0xA4, 0x9C);
mipi_dsi_dcs_write_seq(dsi, 0xA7, 0x02);
mipi_dsi_dcs_write_seq(dsi, 0xA8, 0x01);
mipi_dsi_dcs_write_seq(dsi, 0xA9, 0x01);
mipi_dsi_dcs_write_seq(dsi, 0xAA, 0xFC);
mipi_dsi_dcs_write_seq(dsi, 0xAB, 0x28);
mipi_dsi_dcs_write_seq(dsi, 0xAC, 0x06);
mipi_dsi_dcs_write_seq(dsi, 0xAD, 0x06);
mipi_dsi_dcs_write_seq(dsi, 0xAE, 0x06);
mipi_dsi_dcs_write_seq(dsi, 0xAF, 0x03);
mipi_dsi_dcs_write_seq(dsi, 0xB0, 0x08);
mipi_dsi_dcs_write_seq(dsi, 0xB1, 0x26);
mipi_dsi_dcs_write_seq(dsi, 0xB2, 0x28);
mipi_dsi_dcs_write_seq(dsi, 0xB3, 0x28);
mipi_dsi_dcs_write_seq(dsi, 0xB4, 0x33);
mipi_dsi_dcs_write_seq(dsi, 0xB5, 0x08);
mipi_dsi_dcs_write_seq(dsi, 0xB6, 0x26);
mipi_dsi_dcs_write_seq(dsi, 0xB7, 0x08);
mipi_dsi_dcs_write_seq(dsi, 0xB8, 0x26);
mipi_dsi_dcs_write_seq(dsi, 0xFF, 0x30);
mipi_dsi_dcs_write_seq(dsi, 0xFF, 0x52);
mipi_dsi_dcs_write_seq(dsi, 0xFF, 0x02);
mipi_dsi_dcs_write_seq(dsi, 0xB1, 0x0E);
mipi_dsi_dcs_write_seq(dsi, 0xD1, 0x0E);
mipi_dsi_dcs_write_seq(dsi, 0xB4, 0x29);
mipi_dsi_dcs_write_seq(dsi, 0xD4, 0x2B);
mipi_dsi_dcs_write_seq(dsi, 0xB2, 0x0C);
mipi_dsi_dcs_write_seq(dsi, 0xD2, 0x0A);
mipi_dsi_dcs_write_seq(dsi, 0xB3, 0x28);
mipi_dsi_dcs_write_seq(dsi, 0xD3, 0x28);
mipi_dsi_dcs_write_seq(dsi, 0xB6, 0x11);
mipi_dsi_dcs_write_seq(dsi, 0xD6, 0x0D);
mipi_dsi_dcs_write_seq(dsi, 0xB7, 0x32);
mipi_dsi_dcs_write_seq(dsi, 0xD7, 0x30);
mipi_dsi_dcs_write_seq(dsi, 0xC1, 0x04);
mipi_dsi_dcs_write_seq(dsi, 0xE1, 0x06);
mipi_dsi_dcs_write_seq(dsi, 0xB8, 0x0A);
mipi_dsi_dcs_write_seq(dsi, 0xD8, 0x0A);
mipi_dsi_dcs_write_seq(dsi, 0xB9, 0x01);
mipi_dsi_dcs_write_seq(dsi, 0xD9, 0x01);
mipi_dsi_dcs_write_seq(dsi, 0xBD, 0x13);
mipi_dsi_dcs_write_seq(dsi, 0xDD, 0x13);
mipi_dsi_dcs_write_seq(dsi, 0xBC, 0x11);
mipi_dsi_dcs_write_seq(dsi, 0xDC, 0x11);
mipi_dsi_dcs_write_seq(dsi, 0xBB, 0x0F);
mipi_dsi_dcs_write_seq(dsi, 0xDB, 0x0F);
mipi_dsi_dcs_write_seq(dsi, 0xBA, 0x0F);
mipi_dsi_dcs_write_seq(dsi, 0xDA, 0x0F);
mipi_dsi_dcs_write_seq(dsi, 0xBE, 0x18);
mipi_dsi_dcs_write_seq(dsi, 0xDE, 0x18);
mipi_dsi_dcs_write_seq(dsi, 0xBF, 0x0F);
mipi_dsi_dcs_write_seq(dsi, 0xDF, 0x0F);
mipi_dsi_dcs_write_seq(dsi, 0xC0, 0x17);
mipi_dsi_dcs_write_seq(dsi, 0xE0, 0x17);
mipi_dsi_dcs_write_seq(dsi, 0xB5, 0x3B);
mipi_dsi_dcs_write_seq(dsi, 0xD5, 0x3C);
mipi_dsi_dcs_write_seq(dsi, 0xB0, 0x0B);
mipi_dsi_dcs_write_seq(dsi, 0xD0, 0x0C);
mipi_dsi_dcs_write_seq(dsi, 0xFF, 0x30);
mipi_dsi_dcs_write_seq(dsi, 0xFF, 0x52);
mipi_dsi_dcs_write_seq(dsi, 0xFF, 0x03);
mipi_dsi_dcs_write_seq(dsi, 0x00, 0x2A);
mipi_dsi_dcs_write_seq(dsi, 0x01, 0x2A);
mipi_dsi_dcs_write_seq(dsi, 0x02, 0x2A);
mipi_dsi_dcs_write_seq(dsi, 0x03, 0x2A);
mipi_dsi_dcs_write_seq(dsi, 0x04, 0x61);
mipi_dsi_dcs_write_seq(dsi, 0x05, 0x80);
mipi_dsi_dcs_write_seq(dsi, 0x06, 0xC7);
mipi_dsi_dcs_write_seq(dsi, 0x07, 0x01);
mipi_dsi_dcs_write_seq(dsi, 0x08, 0x82);
mipi_dsi_dcs_write_seq(dsi, 0x09, 0x83);
mipi_dsi_dcs_write_seq(dsi, 0x30, 0x2A);
mipi_dsi_dcs_write_seq(dsi, 0x31, 0x2A);
mipi_dsi_dcs_write_seq(dsi, 0x32, 0x2A);
mipi_dsi_dcs_write_seq(dsi, 0x33, 0x2A);
mipi_dsi_dcs_write_seq(dsi, 0x34, 0x61);
mipi_dsi_dcs_write_seq(dsi, 0x35, 0xC5);
mipi_dsi_dcs_write_seq(dsi, 0x36, 0x80);
mipi_dsi_dcs_write_seq(dsi, 0x37, 0x23);
mipi_dsi_dcs_write_seq(dsi, 0x40, 0x82);
mipi_dsi_dcs_write_seq(dsi, 0x41, 0x83);
mipi_dsi_dcs_write_seq(dsi, 0x42, 0x80);
mipi_dsi_dcs_write_seq(dsi, 0x43, 0x81);
mipi_dsi_dcs_write_seq(dsi, 0x44, 0x11);
mipi_dsi_dcs_write_seq(dsi, 0x45, 0xF2);
mipi_dsi_dcs_write_seq(dsi, 0x46, 0xF1);
mipi_dsi_dcs_write_seq(dsi, 0x47, 0x11);
mipi_dsi_dcs_write_seq(dsi, 0x48, 0xF4);
mipi_dsi_dcs_write_seq(dsi, 0x49, 0xF3);
mipi_dsi_dcs_write_seq(dsi, 0x50, 0x02);
mipi_dsi_dcs_write_seq(dsi, 0x51, 0x01);
mipi_dsi_dcs_write_seq(dsi, 0x52, 0x04);
mipi_dsi_dcs_write_seq(dsi, 0x53, 0x03);
mipi_dsi_dcs_write_seq(dsi, 0x54, 0x11);
mipi_dsi_dcs_write_seq(dsi, 0x55, 0xF6);
mipi_dsi_dcs_write_seq(dsi, 0x56, 0xF5);
mipi_dsi_dcs_write_seq(dsi, 0x57, 0x11);
mipi_dsi_dcs_write_seq(dsi, 0x58, 0xF8);
mipi_dsi_dcs_write_seq(dsi, 0x59, 0xF7);
mipi_dsi_dcs_write_seq(dsi, 0x7E, 0x02);
mipi_dsi_dcs_write_seq(dsi, 0x7F, 0x80);
mipi_dsi_dcs_write_seq(dsi, 0xE0, 0x5A);
mipi_dsi_dcs_write_seq(dsi, 0xB1, 0x00);
mipi_dsi_dcs_write_seq(dsi, 0xB4, 0x0E);
mipi_dsi_dcs_write_seq(dsi, 0xB5, 0x0F);
mipi_dsi_dcs_write_seq(dsi, 0xB6, 0x04);
mipi_dsi_dcs_write_seq(dsi, 0xB7, 0x07);
mipi_dsi_dcs_write_seq(dsi, 0xB8, 0x06);
mipi_dsi_dcs_write_seq(dsi, 0xB9, 0x05);
mipi_dsi_dcs_write_seq(dsi, 0xBA, 0x0F);
mipi_dsi_dcs_write_seq(dsi, 0xC7, 0x00);
mipi_dsi_dcs_write_seq(dsi, 0xCA, 0x0E);
mipi_dsi_dcs_write_seq(dsi, 0xCB, 0x0F);
mipi_dsi_dcs_write_seq(dsi, 0xCC, 0x04);
mipi_dsi_dcs_write_seq(dsi, 0xCD, 0x07);
mipi_dsi_dcs_write_seq(dsi, 0xCE, 0x06);
mipi_dsi_dcs_write_seq(dsi, 0xCF, 0x05);
mipi_dsi_dcs_write_seq(dsi, 0xD0, 0x0F);
mipi_dsi_dcs_write_seq(dsi, 0x81, 0x0F);
mipi_dsi_dcs_write_seq(dsi, 0x84, 0x0E);
mipi_dsi_dcs_write_seq(dsi, 0x85, 0x0F);
mipi_dsi_dcs_write_seq(dsi, 0x86, 0x07);
mipi_dsi_dcs_write_seq(dsi, 0x87, 0x04);
mipi_dsi_dcs_write_seq(dsi, 0x88, 0x05);
mipi_dsi_dcs_write_seq(dsi, 0x89, 0x06);
mipi_dsi_dcs_write_seq(dsi, 0x8A, 0x00);
mipi_dsi_dcs_write_seq(dsi, 0x97, 0x0F);
mipi_dsi_dcs_write_seq(dsi, 0x9A, 0x0E);
mipi_dsi_dcs_write_seq(dsi, 0x9B, 0x0F);
mipi_dsi_dcs_write_seq(dsi, 0x9C, 0x07);
mipi_dsi_dcs_write_seq(dsi, 0x9D, 0x04);
mipi_dsi_dcs_write_seq(dsi, 0x9E, 0x05);
mipi_dsi_dcs_write_seq(dsi, 0x9F, 0x06);
mipi_dsi_dcs_write_seq(dsi, 0xA0, 0x00);
mipi_dsi_dcs_write_seq(dsi, 0xFF, 0x30);
mipi_dsi_dcs_write_seq(dsi, 0xFF, 0x52);
mipi_dsi_dcs_write_seq(dsi, 0xFF, 0x02);
mipi_dsi_dcs_write_seq(dsi, 0x01, 0x01);
mipi_dsi_dcs_write_seq(dsi, 0x02, 0xDA);
mipi_dsi_dcs_write_seq(dsi, 0x03, 0xBA);
mipi_dsi_dcs_write_seq(dsi, 0x04, 0xA8);
mipi_dsi_dcs_write_seq(dsi, 0x05, 0x9A);
mipi_dsi_dcs_write_seq(dsi, 0x06, 0x70);
mipi_dsi_dcs_write_seq(dsi, 0x07, 0xFF);
mipi_dsi_dcs_write_seq(dsi, 0x08, 0x91);
mipi_dsi_dcs_write_seq(dsi, 0x09, 0x90);
mipi_dsi_dcs_write_seq(dsi, 0x0A, 0xFF);
mipi_dsi_dcs_write_seq(dsi, 0x0B, 0x8F);
mipi_dsi_dcs_write_seq(dsi, 0x0C, 0x60);
mipi_dsi_dcs_write_seq(dsi, 0x0D, 0x58);
mipi_dsi_dcs_write_seq(dsi, 0x0E, 0x48);
mipi_dsi_dcs_write_seq(dsi, 0x0F, 0x38);
mipi_dsi_dcs_write_seq(dsi, 0x10, 0x2B);
mipi_dsi_dcs_write_seq(dsi, 0xFF, 0x30);
mipi_dsi_dcs_write_seq(dsi, 0xFF, 0x52);
mipi_dsi_dcs_write_seq(dsi, 0xFF, 0x00);
mipi_dsi_dcs_write_seq(dsi, 0x36, 0x02);
mipi_dsi_dcs_write_seq(dsi, 0x3A, 0x70);
dev_dbg(ctx->dev, "Panel init sequence done\n");
return 0;
}
static int panel_nv3051d_unprepare(struct drm_panel *panel)
{
struct panel_nv3051d *ctx = panel_to_panelnv3051d(panel);
struct mipi_dsi_device *dsi = to_mipi_dsi_device(ctx->dev);
int ret;
ret = mipi_dsi_dcs_set_display_off(dsi);
if (ret < 0)
dev_err(ctx->dev, "failed to set display off: %d\n", ret);
msleep(20);
ret = mipi_dsi_dcs_enter_sleep_mode(dsi);
if (ret < 0) {
dev_err(ctx->dev, "failed to enter sleep mode: %d\n", ret);
return ret;
}
usleep_range(10000, 15000);
regulator_disable(ctx->vdd);
return 0;
}
static int panel_nv3051d_prepare(struct drm_panel *panel)
{
struct panel_nv3051d *ctx = panel_to_panelnv3051d(panel);
struct mipi_dsi_device *dsi = to_mipi_dsi_device(ctx->dev);
int ret;
dev_dbg(ctx->dev, "Resetting the panel\n");
ret = regulator_enable(ctx->vdd);
if (ret < 0) {
dev_err(ctx->dev, "Failed to enable vdd supply: %d\n", ret);
return ret;
}
usleep_range(2000, 3000);
gpiod_set_value_cansleep(ctx->reset_gpio, 1);
msleep(150);
gpiod_set_value_cansleep(ctx->reset_gpio, 0);
msleep(20);
ret = panel_nv3051d_init_sequence(ctx);
if (ret < 0) {
dev_err(ctx->dev, "Panel init sequence failed: %d\n", ret);
goto disable_vdd;
}
ret = mipi_dsi_dcs_exit_sleep_mode(dsi);
if (ret < 0) {
dev_err(ctx->dev, "Failed to exit sleep mode: %d\n", ret);
goto disable_vdd;
}
msleep(200);
ret = mipi_dsi_dcs_set_display_on(dsi);
if (ret < 0) {
dev_err(ctx->dev, "Failed to set display on: %d\n", ret);
goto disable_vdd;
}
usleep_range(10000, 15000);
return 0;
disable_vdd:
regulator_disable(ctx->vdd);
return ret;
}
static int panel_nv3051d_get_modes(struct drm_panel *panel,
struct drm_connector *connector)
{
struct panel_nv3051d *ctx = panel_to_panelnv3051d(panel);
const struct nv3051d_panel_info *panel_info = ctx->panel_info;
struct drm_display_mode *mode;
unsigned int i;
for (i = 0; i < panel_info->num_modes; i++) {
mode = drm_mode_duplicate(connector->dev,
&panel_info->display_modes[i]);
if (!mode)
return -ENOMEM;
drm_mode_set_name(mode);
mode->type = DRM_MODE_TYPE_DRIVER;
if (panel_info->num_modes == 1)
mode->type |= DRM_MODE_TYPE_PREFERRED;
drm_mode_probed_add(connector, mode);
}
connector->display_info.bpc = 8;
connector->display_info.width_mm = panel_info->width_mm;
connector->display_info.height_mm = panel_info->height_mm;
connector->display_info.bus_flags = panel_info->bus_flags;
return panel_info->num_modes;
}
static const struct drm_panel_funcs panel_nv3051d_funcs = {
.unprepare = panel_nv3051d_unprepare,
.prepare = panel_nv3051d_prepare,
.get_modes = panel_nv3051d_get_modes,
};
static int panel_nv3051d_probe(struct mipi_dsi_device *dsi)
{
struct device *dev = &dsi->dev;
struct panel_nv3051d *ctx;
int ret;
ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL);
if (!ctx)
return -ENOMEM;
ctx->dev = dev;
ctx->panel_info = of_device_get_match_data(dev);
if (!ctx->panel_info)
return -EINVAL;
ctx->reset_gpio = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_HIGH);
if (IS_ERR(ctx->reset_gpio)) {
dev_err(dev, "cannot get reset gpio\n");
return PTR_ERR(ctx->reset_gpio);
}
ctx->vdd = devm_regulator_get(dev, "vdd");
if (IS_ERR(ctx->vdd)) {
ret = PTR_ERR(ctx->vdd);
if (ret != -EPROBE_DEFER)
dev_err(dev, "Failed to request vdd regulator: %d\n", ret);
return ret;
}
mipi_dsi_set_drvdata(dsi, ctx);
dsi->lanes = 4;
dsi->format = MIPI_DSI_FMT_RGB888;
dsi->mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_BURST |
MIPI_DSI_MODE_LPM | MIPI_DSI_MODE_NO_EOT_PACKET;
drm_panel_init(&ctx->panel, &dsi->dev, &panel_nv3051d_funcs,
DRM_MODE_CONNECTOR_DSI);
ret = drm_panel_of_backlight(&ctx->panel);
if (ret)
return ret;
drm_panel_add(&ctx->panel);
ret = mipi_dsi_attach(dsi);
if (ret < 0) {
dev_err(dev, "mipi_dsi_attach failed: %d\n", ret);
drm_panel_remove(&ctx->panel);
return ret;
}
return 0;
}
static void panel_nv3051d_shutdown(struct mipi_dsi_device *dsi)
{
struct panel_nv3051d *ctx = mipi_dsi_get_drvdata(dsi);
int ret;
ret = drm_panel_unprepare(&ctx->panel);
if (ret < 0)
dev_err(&dsi->dev, "Failed to unprepare panel: %d\n", ret);
ret = drm_panel_disable(&ctx->panel);
if (ret < 0)
dev_err(&dsi->dev, "Failed to disable panel: %d\n", ret);
}
static void panel_nv3051d_remove(struct mipi_dsi_device *dsi)
{
struct panel_nv3051d *ctx = mipi_dsi_get_drvdata(dsi);
int ret;
panel_nv3051d_shutdown(dsi);
ret = mipi_dsi_detach(dsi);
if (ret < 0)
dev_err(&dsi->dev, "Failed to detach from DSI host: %d\n", ret);
drm_panel_remove(&ctx->panel);
}
static const struct drm_display_mode nv3051d_rgxx3_modes[] = {
{ /* 120hz */
.hdisplay = 640,
.hsync_start = 640 + 40,
.hsync_end = 640 + 40 + 2,
.htotal = 640 + 40 + 2 + 80,
.vdisplay = 480,
.vsync_start = 480 + 18,
.vsync_end = 480 + 18 + 2,
.vtotal = 480 + 18 + 2 + 28,
.clock = 48300,
.flags = DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC,
},
{ /* 100hz */
.hdisplay = 640,
.hsync_start = 640 + 40,
.hsync_end = 640 + 40 + 2,
.htotal = 640 + 40 + 2 + 80,
.vdisplay = 480,
.vsync_start = 480 + 18,
.vsync_end = 480 + 18 + 2,
.vtotal = 480 + 18 + 2 + 28,
.clock = 40250,
.flags = DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC,
},
{ /* 60hz */
.hdisplay = 640,
.hsync_start = 640 + 40,
.hsync_end = 640 + 40 + 2,
.htotal = 640 + 40 + 2 + 80,
.vdisplay = 480,
.vsync_start = 480 + 18,
.vsync_end = 480 + 18 + 2,
.vtotal = 480 + 18 + 2 + 28,
.clock = 24150,
.flags = DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC,
},
};
static const struct nv3051d_panel_info nv3051d_rgxx3_info = {
.display_modes = nv3051d_rgxx3_modes,
.num_modes = ARRAY_SIZE(nv3051d_rgxx3_modes),
.width_mm = 70,
.height_mm = 57,
.bus_flags = DRM_BUS_FLAG_DE_LOW | DRM_BUS_FLAG_PIXDATA_DRIVE_NEGEDGE,
};
static const struct of_device_id newvision_nv3051d_of_match[] = {
{ .compatible = "newvision,nv3051d", .data = &nv3051d_rgxx3_info },
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, newvision_nv3051d_of_match);
static struct mipi_dsi_driver newvision_nv3051d_driver = {
.driver = {
.name = "panel-newvision-nv3051d",
.of_match_table = newvision_nv3051d_of_match,
},
.probe = panel_nv3051d_probe,
.remove = panel_nv3051d_remove,
.shutdown = panel_nv3051d_shutdown,
};
module_mipi_dsi_driver(newvision_nv3051d_driver);
MODULE_AUTHOR("Chris Morgan <macromorgan@hotmail.com>");
MODULE_DESCRIPTION("DRM driver for Newvision NV3051D based MIPI DSI panels");
MODULE_LICENSE("GPL");

View File

@ -571,7 +571,7 @@ static void cdn_dp_encoder_mode_set(struct drm_encoder *encoder,
video->v_sync_polarity = !!(mode->flags & DRM_MODE_FLAG_NVSYNC);
video->h_sync_polarity = !!(mode->flags & DRM_MODE_FLAG_NHSYNC);
memcpy(&dp->mode, adjusted, sizeof(*mode));
drm_mode_copy(&dp->mode, adjusted);
}
static bool cdn_dp_check_link_status(struct cdn_dp_device *dp)

View File

@ -499,7 +499,7 @@ static void inno_hdmi_encoder_mode_set(struct drm_encoder *encoder,
inno_hdmi_setup(hdmi, adj_mode);
/* Store the display mode for plugin/DPMS poweron events */
memcpy(&hdmi->previous_mode, adj_mode, sizeof(hdmi->previous_mode));
drm_mode_copy(&hdmi->previous_mode, adj_mode);
}
static void inno_hdmi_encoder_enable(struct drm_encoder *encoder)

View File

@ -395,7 +395,7 @@ rk3066_hdmi_encoder_mode_set(struct drm_encoder *encoder,
struct rk3066_hdmi *hdmi = encoder_to_rk3066_hdmi(encoder);
/* Store the display mode for plugin/DPMS poweron events. */
memcpy(&hdmi->previous_mode, adj_mode, sizeof(hdmi->previous_mode));
drm_mode_copy(&hdmi->previous_mode, adj_mode);
}
static void rk3066_hdmi_encoder_enable(struct drm_encoder *encoder)

View File

@ -288,7 +288,7 @@ static void sti_dvo_set_mode(struct drm_bridge *bridge,
DRM_DEBUG_DRIVER("\n");
memcpy(&dvo->mode, mode, sizeof(struct drm_display_mode));
drm_mode_copy(&dvo->mode, mode);
/* According to the path used (main or aux), the dvo clocks should
* have a different parent clock. */

View File

@ -524,7 +524,7 @@ static void sti_hda_set_mode(struct drm_bridge *bridge,
DRM_DEBUG_DRIVER("\n");
memcpy(&hda->mode, mode, sizeof(struct drm_display_mode));
drm_mode_copy(&hda->mode, mode);
if (!hda_get_mode_idx(hda->mode, &mode_idx)) {
DRM_ERROR("Undefined mode\n");

View File

@ -941,7 +941,7 @@ static void sti_hdmi_set_mode(struct drm_bridge *bridge,
DRM_DEBUG_DRIVER("\n");
/* Copy the drm display mode in the connector local structure */
memcpy(&hdmi->mode, mode, sizeof(struct drm_display_mode));
drm_mode_copy(&hdmi->mode, mode);
/* Update clock framerate according to the selected mode */
ret = clk_set_rate(hdmi->clk_pix, mode->clock * 1000);

View File

@ -694,6 +694,8 @@ static int tegra_gem_prime_mmap(struct dma_buf *buf, struct vm_area_struct *vma)
struct drm_gem_object *gem = buf->priv;
int err;
dma_resv_assert_held(buf->resv);
err = drm_gem_mmap_obj(gem, gem->size, vma);
if (err < 0)
return err;

View File

@ -8,6 +8,7 @@ obj-$(CONFIG_DRM_KUNIT_TEST) += \
drm_format_helper_test.o \
drm_format_test.o \
drm_framebuffer_test.o \
drm_kunit_helpers.o \
drm_mm_test.o \
drm_plane_helper_test.o \
drm_rect_test.o

View File

@ -0,0 +1,98 @@
// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (c) 2022 Maxime Ripard <mripard@kernel.org>
*/
#include <kunit/test.h>
#include <drm/drm_connector.h>
#include <drm/drm_edid.h>
#include <drm/drm_drv.h>
#include <drm/drm_modes.h>
#include <drm/drm_modeset_helper_vtables.h>
#include <drm/drm_probe_helper.h>
#include "drm_kunit_helpers.h"
struct drm_client_modeset_test_priv {
struct drm_device *drm;
struct drm_connector connector;
};
static int drm_client_modeset_connector_get_modes(struct drm_connector *connector)
{
return drm_add_modes_noedid(connector, 1920, 1200);
}
static const struct drm_connector_helper_funcs drm_client_modeset_connector_helper_funcs = {
.get_modes = drm_client_modeset_connector_get_modes,
};
static const struct drm_connector_funcs drm_client_modeset_connector_funcs = {
};
static int drm_client_modeset_test_init(struct kunit *test)
{
struct drm_client_modeset_test_priv *priv;
int ret;
priv = kunit_kzalloc(test, sizeof(*priv), GFP_KERNEL);
KUNIT_ASSERT_NOT_NULL(test, priv);
test->priv = priv;
priv->drm = drm_kunit_device_init(test, DRIVER_MODESET, "drm-client-modeset-test");
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, priv->drm);
ret = drmm_connector_init(priv->drm, &priv->connector,
&drm_client_modeset_connector_funcs,
DRM_MODE_CONNECTOR_Unknown,
NULL);
KUNIT_ASSERT_EQ(test, ret, 0);
drm_connector_helper_add(&priv->connector, &drm_client_modeset_connector_helper_funcs);
return 0;
}
static void drm_test_pick_cmdline_res_1920_1080_60(struct kunit *test)
{
struct drm_client_modeset_test_priv *priv = test->priv;
struct drm_device *drm = priv->drm;
struct drm_connector *connector = &priv->connector;
struct drm_cmdline_mode *cmdline_mode = &connector->cmdline_mode;
struct drm_display_mode *expected_mode, *mode;
const char *cmdline = "1920x1080@60";
int ret;
expected_mode = drm_mode_find_dmt(priv->drm, 1920, 1080, 60, false);
KUNIT_ASSERT_NOT_NULL(test, expected_mode);
KUNIT_ASSERT_TRUE(test,
drm_mode_parse_command_line_for_connector(cmdline,
connector,
cmdline_mode));
mutex_lock(&drm->mode_config.mutex);
ret = drm_helper_probe_single_connector_modes(connector, 1920, 1080);
mutex_unlock(&drm->mode_config.mutex);
KUNIT_ASSERT_GT(test, ret, 0);
mode = drm_connector_pick_cmdline_mode(connector);
KUNIT_ASSERT_NOT_NULL(test, mode);
KUNIT_EXPECT_TRUE(test, drm_mode_equal(expected_mode, mode));
}
static struct kunit_case drm_test_pick_cmdline_tests[] = {
KUNIT_CASE(drm_test_pick_cmdline_res_1920_1080_60),
{}
};
static struct kunit_suite drm_test_pick_cmdline_test_suite = {
.name = "drm_test_pick_cmdline",
.init = drm_client_modeset_test_init,
.test_cases = drm_test_pick_cmdline_tests
};
kunit_test_suite(drm_test_pick_cmdline_test_suite);

View File

@ -0,0 +1,71 @@
// SPDX-License-Identifier: GPL-2.0
#include <drm/drm_drv.h>
#include <drm/drm_managed.h>
#include <kunit/resource.h>
#include <linux/device.h>
#include "drm_kunit_helpers.h"
struct kunit_dev {
struct drm_device base;
};
static const struct drm_mode_config_funcs drm_mode_config_funcs = {
};
static int dev_init(struct kunit_resource *res, void *ptr)
{
char *name = ptr;
struct device *dev;
dev = root_device_register(name);
if (IS_ERR(dev))
return PTR_ERR(dev);
res->data = dev;
return 0;
}
static void dev_free(struct kunit_resource *res)
{
struct device *dev = res->data;
root_device_unregister(dev);
}
struct drm_device *drm_kunit_device_init(struct kunit *test, u32 features, char *name)
{
struct kunit_dev *kdev;
struct drm_device *drm;
struct drm_driver *driver;
struct device *dev;
int ret;
dev = kunit_alloc_resource(test, dev_init, dev_free, GFP_KERNEL, name);
if (!dev)
return ERR_PTR(-ENOMEM);
driver = kunit_kzalloc(test, sizeof(*driver), GFP_KERNEL);
if (!driver)
return ERR_PTR(-ENOMEM);
driver->driver_features = features;
kdev = devm_drm_dev_alloc(dev, driver, struct kunit_dev, base);
if (IS_ERR(kdev))
return ERR_CAST(kdev);
drm = &kdev->base;
drm->mode_config.funcs = &drm_mode_config_funcs;
ret = drmm_mode_config_init(drm);
if (ret)
return ERR_PTR(ret);
return drm;
}
MODULE_AUTHOR("Maxime Ripard <maxime@cerno.tech>");
MODULE_LICENSE("GPL");

View File

@ -0,0 +1,11 @@
// SPDX-License-Identifier: GPL-2.0
#ifndef DRM_KUNIT_HELPERS_H_
#define DRM_KUNIT_HELPERS_H_
struct drm_device;
struct kunit;
struct drm_device *drm_kunit_device_init(struct kunit *test, u32 features, char *name);
#endif // DRM_KUNIT_HELPERS_H_

View File

@ -10,6 +10,7 @@
#include <linux/sched/signal.h>
#include <linux/uaccess.h>
#include <drm/drm_managed.h>
#include <drm/drm_syncobj.h>
#include <uapi/drm/v3d_drm.h>
@ -1075,10 +1076,18 @@ v3d_gem_init(struct drm_device *dev)
spin_lock_init(&v3d->mm_lock);
spin_lock_init(&v3d->job_lock);
mutex_init(&v3d->bo_lock);
mutex_init(&v3d->reset_lock);
mutex_init(&v3d->sched_lock);
mutex_init(&v3d->cache_clean_lock);
ret = drmm_mutex_init(dev, &v3d->bo_lock);
if (ret)
return ret;
ret = drmm_mutex_init(dev, &v3d->reset_lock);
if (ret)
return ret;
ret = drmm_mutex_init(dev, &v3d->sched_lock);
if (ret)
return ret;
ret = drmm_mutex_init(dev, &v3d->cache_clean_lock);
if (ret)
return ret;
/* Note: We don't allocate address 0. Various bits of HW
* treat 0 as special, such as the occlusion query counters

View File

@ -17,8 +17,10 @@ void v3d_perfmon_get(struct v3d_perfmon *perfmon)
void v3d_perfmon_put(struct v3d_perfmon *perfmon)
{
if (perfmon && refcount_dec_and_test(&perfmon->refcnt))
if (perfmon && refcount_dec_and_test(&perfmon->refcnt)) {
mutex_destroy(&perfmon->lock);
kfree(perfmon);
}
}
void v3d_perfmon_start(struct v3d_dev *v3d, struct v3d_perfmon *perfmon)
@ -113,6 +115,7 @@ void v3d_perfmon_close_file(struct v3d_file_priv *v3d_priv)
idr_for_each(&v3d_priv->perfmon.idr, v3d_perfmon_idr_del, NULL);
idr_destroy(&v3d_priv->perfmon.idr);
mutex_unlock(&v3d_priv->perfmon.lock);
mutex_destroy(&v3d_priv->perfmon.lock);
}
int v3d_perfmon_create_ioctl(struct drm_device *dev, void *data,
@ -154,6 +157,7 @@ int v3d_perfmon_create_ioctl(struct drm_device *dev, void *data,
mutex_unlock(&v3d_priv->perfmon.lock);
if (ret < 0) {
mutex_destroy(&perfmon->lock);
kfree(perfmon);
return ret;
}

View File

@ -124,9 +124,8 @@ static unsigned long long
vc4_hdmi_encoder_compute_mode_clock(const struct drm_display_mode *mode,
unsigned int bpc, enum vc4_hdmi_output_format fmt);
static bool vc4_hdmi_supports_scrambling(struct drm_encoder *encoder)
static bool vc4_hdmi_supports_scrambling(struct vc4_hdmi *vc4_hdmi)
{
struct vc4_hdmi *vc4_hdmi = encoder_to_vc4_hdmi(encoder);
struct drm_display_info *display = &vc4_hdmi->connector.display_info;
lockdep_assert_held(&vc4_hdmi->mutex);
@ -319,9 +318,8 @@ out:
static int vc4_hdmi_reset_link(struct drm_connector *connector,
struct drm_modeset_acquire_ctx *ctx)
{
struct drm_device *drm = connector->dev;
struct vc4_hdmi *vc4_hdmi = connector_to_vc4_hdmi(connector);
struct drm_encoder *encoder = &vc4_hdmi->encoder.base;
struct drm_device *drm;
struct vc4_hdmi *vc4_hdmi;
struct drm_connector_state *conn_state;
struct drm_crtc_state *crtc_state;
struct drm_crtc *crtc;
@ -332,6 +330,7 @@ static int vc4_hdmi_reset_link(struct drm_connector *connector,
if (!connector)
return 0;
drm = connector->dev;
ret = drm_modeset_lock(&drm->mode_config.connection_mutex, ctx);
if (ret)
return ret;
@ -349,7 +348,8 @@ static int vc4_hdmi_reset_link(struct drm_connector *connector,
if (!crtc_state->active)
return 0;
if (!vc4_hdmi_supports_scrambling(encoder))
vc4_hdmi = connector_to_vc4_hdmi(connector);
if (!vc4_hdmi_supports_scrambling(vc4_hdmi))
return 0;
scrambling_needed = vc4_hdmi_mode_needs_scrambling(&vc4_hdmi->saved_adjusted_mode,
@ -867,7 +867,7 @@ static void vc4_hdmi_enable_scrambling(struct drm_encoder *encoder)
lockdep_assert_held(&vc4_hdmi->mutex);
if (!vc4_hdmi_supports_scrambling(encoder))
if (!vc4_hdmi_supports_scrambling(vc4_hdmi))
return;
if (!vc4_hdmi_mode_needs_scrambling(mode,

View File

@ -11,6 +11,7 @@
*/
#include <linux/dma-buf.h>
#include <linux/dma-resv.h>
#include <linux/module.h>
#include <linux/refcount.h>
#include <linux/scatterlist.h>
@ -455,6 +456,8 @@ static int vb2_dc_dmabuf_ops_vmap(struct dma_buf *dbuf, struct iosys_map *map)
static int vb2_dc_dmabuf_ops_mmap(struct dma_buf *dbuf,
struct vm_area_struct *vma)
{
dma_resv_assert_held(dbuf->resv);
return vb2_dc_mmap(dbuf->priv, vma);
}

View File

@ -10,6 +10,7 @@
* the Free Software Foundation.
*/
#include <linux/dma-resv.h>
#include <linux/module.h>
#include <linux/mm.h>
#include <linux/refcount.h>
@ -495,6 +496,8 @@ static int vb2_dma_sg_dmabuf_ops_vmap(struct dma_buf *dbuf,
static int vb2_dma_sg_dmabuf_ops_mmap(struct dma_buf *dbuf,
struct vm_area_struct *vma)
{
dma_resv_assert_held(dbuf->resv);
return vb2_dma_sg_mmap(dbuf->priv, vma);
}

View File

@ -10,6 +10,7 @@
* the Free Software Foundation.
*/
#include <linux/dma-resv.h>
#include <linux/io.h>
#include <linux/module.h>
#include <linux/mm.h>
@ -316,6 +317,8 @@ static int vb2_vmalloc_dmabuf_ops_vmap(struct dma_buf *dbuf,
static int vb2_vmalloc_dmabuf_ops_mmap(struct dma_buf *dbuf,
struct vm_area_struct *vma)
{
dma_resv_assert_held(dbuf->resv);
return vb2_vmalloc_mmap(dbuf->priv, vma);
}

View File

@ -6,6 +6,7 @@
#include <linux/device.h>
#include <linux/dma-buf.h>
#include <linux/dma-mapping.h>
#include <linux/dma-resv.h>
#include <linux/idr.h>
#include <linux/list.h>
#include <linux/miscdevice.h>
@ -682,6 +683,8 @@ static int fastrpc_mmap(struct dma_buf *dmabuf,
struct fastrpc_buf *buf = dmabuf->priv;
size_t size = vma->vm_end - vma->vm_start;
dma_resv_assert_held(dmabuf->resv);
return dma_mmap_coherent(buf->dev, vma, buf->virt,
FASTRPC_PHYS(buf->phys), size);
}

View File

@ -6,6 +6,7 @@ config FB_SM750
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
select VIDEO_NOMODESET
help
Frame buffer driver for the Silicon Motion SM750 chip
with 2D accelearion and dual head support.

View File

@ -1168,6 +1168,9 @@ static int __init lynxfb_init(void)
{
char *option;
if (fb_modesetting_disabled("sm750fb"))
return -ENODEV;
#ifdef MODULE
option = g_option;
#else

View File

@ -11,6 +11,10 @@ config APERTURE_HELPERS
Support tracking and hand-over of aperture ownership. Required
by graphics drivers for firmware-provided framebuffers.
config VIDEO_NOMODESET
bool
default n
if HAS_IOMEM
config HAVE_FB_ATMEL

View File

@ -2,6 +2,7 @@
obj-$(CONFIG_APERTURE_HELPERS) += aperture.o
obj-$(CONFIG_VGASTATE) += vgastate.o
obj-$(CONFIG_VIDEO_NOMODESET) += nomodeset.o
obj-$(CONFIG_HDMI) += hdmi.o
obj-$(CONFIG_VT) += console/

View File

@ -227,6 +227,7 @@ config FB_CIRRUS
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
select VIDEO_NOMODESET
help
This enables support for Cirrus Logic GD542x/543x based boards on
Amiga: SD64, Piccolo, Picasso II/II+, Picasso IV, or EGS Spectrum.
@ -245,6 +246,7 @@ config FB_PM2
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
select VIDEO_NOMODESET
help
This is the frame buffer device driver for cards based on
the 3D Labs Permedia, Permedia 2 and Permedia 2V chips.
@ -340,6 +342,7 @@ config FB_CYBER2000
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
select VIDEO_NOMODESET
help
This enables support for the Integraphics CyberPro 20x0 and 5000
VGA chips used in the Rebel.com Netwinder and other machines.
@ -504,6 +507,7 @@ config FB_CT65550
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
select VIDEO_NOMODESET
help
This is the frame buffer device driver for the Chips & Technologies
65550 graphics chip in PowerBooks.
@ -514,6 +518,7 @@ config FB_ASILIANT
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
select VIDEO_NOMODESET
help
This is the frame buffer device driver for the Asiliant 69030 chipset
@ -522,6 +527,7 @@ config FB_IMSTT
depends on (FB = y) && PCI
select FB_CFB_IMAGEBLIT
select FB_MACMODES if PPC_PMAC
select VIDEO_NOMODESET
help
The IMS Twin Turbo is a PCI-based frame buffer card bundled with
many Macintosh and compatible computers.
@ -585,6 +591,7 @@ config FB_TGA
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
select BITREVERSE
select VIDEO_NOMODESET
help
This is the frame buffer device driver for generic TGA and SFB+
graphic cards. These include DEC ZLXp-E1, -E2 and -E3 PCI cards,
@ -777,6 +784,7 @@ config FB_XVR500
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
select VIDEO_NOMODESET
help
This is the framebuffer device for the Sun XVR-500 and similar
graphics cards based upon the 3DLABS Wildcat chipset. The driver
@ -790,6 +798,7 @@ config FB_XVR2500
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
select VIDEO_NOMODESET
help
This is the framebuffer device for the Sun XVR-2500 and similar
graphics cards based upon the 3DLABS Wildcat chipset. The driver
@ -816,6 +825,7 @@ config FB_PVR2
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
select VIDEO_NOMODESET
help
Say Y here if you have a PowerVR 2 card in your box. If you plan to
run linux on your Dreamcast, you will have to say Y here.
@ -881,6 +891,7 @@ config FB_NVIDIA
select FB_CFB_IMAGEBLIT
select BITREVERSE
select VGASTATE
select VIDEO_NOMODESET
help
This driver supports graphics boards with the nVidia chips, TNT
and newer. For very old chipsets, such as the RIVA128, then use
@ -928,6 +939,7 @@ config FB_RIVA
select FB_CFB_IMAGEBLIT
select BITREVERSE
select VGASTATE
select VIDEO_NOMODESET
help
This driver supports graphics boards with the nVidia Riva/Geforce
chips.
@ -972,6 +984,7 @@ config FB_I740
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
select VGASTATE
select VIDEO_NOMODESET
select FB_DDC
help
This driver supports graphics cards based on Intel740 chip.
@ -984,6 +997,7 @@ config FB_I810
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
select VGASTATE
select VIDEO_NOMODESET
help
This driver supports the on-board graphics built in to the Intel 810
and 815 chipsets. Say Y if you have and plan to use such a board.
@ -1034,6 +1048,7 @@ config FB_LE80578
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
select VIDEO_NOMODESET
help
This driver supports the LE80578 (Vermilion Range) chipset
@ -1051,6 +1066,7 @@ config FB_INTEL
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
select BOOT_VESA_SUPPORT if FB_INTEL = y
select VIDEO_NOMODESET
depends on !DRM_I915
help
This driver supports the on-board graphics built in to the Intel
@ -1088,6 +1104,7 @@ config FB_MATROX
select FB_CFB_IMAGEBLIT
select FB_TILEBLITTING
select FB_MACMODES if PPC_PMAC
select VIDEO_NOMODESET
help
Say Y here if you have a Matrox Millennium, Matrox Millennium II,
Matrox Mystique, Matrox Mystique 220, Matrox Productiva G100, Matrox
@ -1208,6 +1225,7 @@ config FB_RADEON
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
select FB_MACMODES if PPC
select VIDEO_NOMODESET
help
Choose this option if you want to use an ATI Radeon graphics card as
a framebuffer device. There are both PCI and AGP versions. You
@ -1247,6 +1265,7 @@ config FB_ATY128
select FB_CFB_IMAGEBLIT
select FB_BACKLIGHT if FB_ATY128_BACKLIGHT
select FB_MACMODES if PPC_PMAC
select VIDEO_NOMODESET
help
This driver supports graphics boards with the ATI Rage128 chips.
Say Y if you have such a graphics board and read
@ -1271,6 +1290,7 @@ config FB_ATY
select FB_BACKLIGHT if FB_ATY_BACKLIGHT
select FB_MACMODES if PPC
select FB_ATY_CT if SPARC64 && PCI
select VIDEO_NOMODESET
help
This driver supports graphics boards with the ATI Mach64 chips.
Say Y if you have such a graphics board.
@ -1321,6 +1341,7 @@ config FB_S3
select FB_TILEBLITTING
select FB_SVGALIB
select VGASTATE
select VIDEO_NOMODESET
select FONT_8x16 if FRAMEBUFFER_CONSOLE
help
Driver for graphics boards with S3 Trio / S3 Virge chip.
@ -1341,6 +1362,7 @@ config FB_SAVAGE
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
select VGASTATE
select VIDEO_NOMODESET
help
This driver supports notebooks and computers with S3 Savage PCI/AGP
chips.
@ -1379,6 +1401,7 @@ config FB_SIS
select FB_CFB_IMAGEBLIT
select BOOT_VESA_SUPPORT if FB_SIS = y
select FB_SIS_300 if !FB_SIS_315
select VIDEO_NOMODESET
help
This is the frame buffer device driver for the SiS 300, 315, 330
and 340 series as well as XGI V3XT, V5, V8, Z7 graphics chipsets.
@ -1408,6 +1431,7 @@ config FB_VIA
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
select I2C_ALGOBIT
select VIDEO_NOMODESET
help
This is the frame buffer device driver for Graphics chips of VIA
UniChrome (Pro) Family (CLE266,PM800/CN400,P4M800CE/P4M800Pro/
@ -1447,6 +1471,7 @@ config FB_NEOMAGIC
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
select VGASTATE
select VIDEO_NOMODESET
help
This driver supports notebooks with NeoMagic PCI chips.
Say Y if you have such a graphics card.
@ -1460,6 +1485,7 @@ config FB_KYRO
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
select VIDEO_NOMODESET
help
Say Y here if you have a STG4000 / Kyro / PowerVR 3 based
graphics board.
@ -1474,6 +1500,7 @@ config FB_3DFX
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_MODE_HELPERS
select VIDEO_NOMODESET
help
This driver supports graphics boards with the 3Dfx Banshee,
Voodoo3 or VSA-100 (aka Voodoo4/5) chips. Say Y if you have
@ -1503,6 +1530,7 @@ config FB_VOODOO1
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
select VIDEO_NOMODESET
help
Say Y here if you have a 3Dfx Voodoo Graphics (Voodoo1/sst1) or
Voodoo2 (cvg) based graphics card.
@ -1524,6 +1552,7 @@ config FB_VT8623
select FB_TILEBLITTING
select FB_SVGALIB
select VGASTATE
select VIDEO_NOMODESET
select FONT_8x16 if FRAMEBUFFER_CONSOLE
help
Driver for CastleRock integrated graphics core in the
@ -1537,6 +1566,7 @@ config FB_TRIDENT
select FB_CFB_IMAGEBLIT
select FB_DDC
select FB_MODE_HELPERS
select VIDEO_NOMODESET
help
This is the frame buffer device driver for Trident PCI/AGP chipsets.
Supported chipset families are TGUI 9440/96XX, 3DImage, Blade3D
@ -1560,6 +1590,7 @@ config FB_ARK
select FB_TILEBLITTING
select FB_SVGALIB
select VGASTATE
select VIDEO_NOMODESET
select FONT_8x16 if FRAMEBUFFER_CONSOLE
help
Driver for PCI graphics boards with ARK 2000PV chip
@ -1571,6 +1602,7 @@ config FB_PM3
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
select VIDEO_NOMODESET
help
This is the frame buffer device driver for the 3DLabs Permedia3
chipset, used in Formac ProFormance III, 3DLabs Oxygen VX1 &
@ -1583,6 +1615,7 @@ config FB_CARMINE
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
select VIDEO_NOMODESET
help
This is the frame buffer device driver for the Fujitsu Carmine chip.
The driver provides two independent frame buffer devices.
@ -1961,6 +1994,7 @@ config FB_IBM_GXT4500
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
select VIDEO_NOMODESET
help
Say Y here to enable support for the IBM GXT4000P/6000P and
GXT4500P/6500P display adaptor based on Raster Engine RC1000,
@ -2101,6 +2135,7 @@ config FB_MB862XX
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
select VIDEO_NOMODESET
help
Frame buffer driver for Fujitsu Carmine/Coral-P(A)/Lime controllers.
@ -2188,6 +2223,7 @@ config FB_HYPERV
select FB_CFB_IMAGEBLIT
select FB_DEFERRED_IO
select DMA_CMA if HAVE_DMA_CONTIGUOUS && CMA
select VIDEO_NOMODESET
help
This framebuffer driver supports Microsoft Hyper-V Synthetic Video.
@ -2230,6 +2266,7 @@ config FB_SM712
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
select VIDEO_NOMODESET
help
Frame buffer driver for the Silicon Motion SM710, SM712, SM721
and SM722 chips.

View File

@ -1187,7 +1187,12 @@ static int __init arkfb_init(void)
#ifndef MODULE
char *option = NULL;
#endif
if (fb_modesetting_disabled("arkfb"))
return -ENODEV;
#ifndef MODULE
if (fb_get_options("arkfb", &option))
return -ENODEV;

View File

@ -616,6 +616,9 @@ static struct pci_driver asiliantfb_driver = {
static int __init asiliantfb_init(void)
{
if (fb_modesetting_disabled("asiliantfb"))
return -ENODEV;
if (fb_get_options("asiliantfb", NULL))
return -ENODEV;

View File

@ -2503,7 +2503,12 @@ static int aty128fb_init(void)
{
#ifndef MODULE
char *option = NULL;
#endif
if (fb_modesetting_disabled("aty128fb"))
return -ENODEV;
#ifndef MODULE
if (fb_get_options("aty128fb", &option))
return -ENODEV;
aty128fb_setup(option);

View File

@ -3965,7 +3965,12 @@ static int __init atyfb_init(void)
int err1 = 1, err2 = 1;
#ifndef MODULE
char *option = NULL;
#endif
if (fb_modesetting_disabled("atyfb"))
return -ENODEV;
#ifndef MODULE
if (fb_get_options("atyfb", &option))
return -ENODEV;
atyfb_setup(option);

View File

@ -2607,7 +2607,12 @@ static int __init radeonfb_init (void)
{
#ifndef MODULE
char *option = NULL;
#endif
if (fb_modesetting_disabled("radeonfb"))
return -ENODEV;
#ifndef MODULE
if (fb_get_options("radeonfb", &option))
return -ENODEV;
radeonfb_setup(option);

View File

@ -773,6 +773,9 @@ static struct pci_driver carmine_pci_driver = {
static int __init carminefb_init(void)
{
if (fb_modesetting_disabled("carminefb"))
return -ENODEV;
if (!(fb_displays &
(CARMINE_USE_DISPLAY0 | CARMINE_USE_DISPLAY1))) {
printk(KERN_ERR "If you disable both displays than you don't "

View File

@ -506,6 +506,9 @@ static struct pci_driver chipsfb_driver = {
int __init chips_init(void)
{
if (fb_modesetting_disabled("chipsfb"))
return -ENODEV;
if (fb_get_options("chipsfb", NULL))
return -ENODEV;

View File

@ -2359,7 +2359,12 @@ static int __init cirrusfb_init(void)
#ifndef MODULE
char *option = NULL;
#endif
if (fb_modesetting_disabled("cirrusfb"))
return -ENODEV;
#ifndef MODULE
if (fb_get_options("cirrusfb", &option))
return -ENODEV;
cirrusfb_setup(option);

View File

@ -332,3 +332,19 @@ void fb_deferred_io_cleanup(struct fb_info *info)
mutex_destroy(&fbdefio->lock);
}
EXPORT_SYMBOL_GPL(fb_deferred_io_cleanup);
void fb_deferred_io_schedule_flush(struct fb_info *info)
{
struct fb_deferred_io *fbdefio = info->fbdefio;
if (WARN_ON_ONCE(!fbdefio))
return; /* bug in driver logic */
/*
* There's no requirement from callers to schedule the
* flush immediately. Rather schedule the worker with a
* delay and let a few more writes pile up.
*/
schedule_delayed_work(&info->deferred_work, fbdefio->delay);
}
EXPORT_SYMBOL_GPL(fb_deferred_io_schedule_flush);

View File

@ -40,6 +40,7 @@
#include <asm/fb.h>
#include <video/nomodeset.h>
#include <video/vga.h>
/*
@ -1844,4 +1845,18 @@ int fb_new_modelist(struct fb_info *info)
return 0;
}
#if defined(CONFIG_VIDEO_NOMODESET)
bool fb_modesetting_disabled(const char *drvname)
{
bool fwonly = video_firmware_drivers_only();
if (fwonly)
pr_warn("Driver %s not loading because of nomodeset parameter\n",
drvname);
return fwonly;
}
EXPORT_SYMBOL(fb_modesetting_disabled);
#endif
MODULE_LICENSE("GPL");

View File

@ -48,7 +48,6 @@
#include <linux/i2c.h>
#include <linux/i2c-algo-bit.h>
#ifdef __arm__
#include <asm/mach-types.h>
#endif
@ -1876,7 +1875,12 @@ static int __init cyber2000fb_init(void)
#ifndef MODULE
char *option = NULL;
#endif
if (fb_modesetting_disabled("CyberPro"))
return -ENODEV;
#ifndef MODULE
if (fb_get_options("cyber2000fb", &option))
return -ENODEV;
cyber2000fb_setup(option);

View File

@ -15,6 +15,7 @@ config FB_GEODE_LX
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
select VIDEO_NOMODESET
help
Framebuffer driver for the display controller integrated into the
AMD Geode LX processors.
@ -30,6 +31,7 @@ config FB_GEODE_GX
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
select VIDEO_NOMODESET
help
Framebuffer driver for the display controller integrated into the
AMD Geode GX processors.
@ -45,6 +47,7 @@ config FB_GEODE_GX1
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
select VIDEO_NOMODESET
help
Framebuffer driver for the display controller integrated into the
AMD Geode GX1 processor.

View File

@ -446,7 +446,12 @@ static int __init gx1fb_init(void)
{
#ifndef MODULE
char *option = NULL;
#endif
if (fb_modesetting_disabled("gx1fb"))
return -ENODEV;
#ifndef MODULE
if (fb_get_options("gx1fb", &option))
return -ENODEV;
gx1fb_setup(option);

View File

@ -511,7 +511,12 @@ static int __init gxfb_init(void)
{
#ifndef MODULE
char *option = NULL;
#endif
if (fb_modesetting_disabled("gxfb"))
return -ENODEV;
#ifndef MODULE
if (fb_get_options("gxfb", &option))
return -ENODEV;

View File

@ -647,7 +647,12 @@ static int __init lxfb_init(void)
{
#ifndef MODULE
char *option = NULL;
#endif
if (fb_modesetting_disabled("lxfb"))
return -ENODEV;
#ifndef MODULE
if (fb_get_options("lxfb", &option))
return -ENODEV;

View File

@ -779,6 +779,9 @@ static struct pci_driver gxt4500_driver = {
static int gxt4500_init(void)
{
if (fb_modesetting_disabled("gxt4500"))
return -ENODEV;
#ifndef MODULE
if (fb_get_options("gxt4500", &mode_option))
return -ENODEV;

View File

@ -59,7 +59,6 @@
#include <linux/hyperv.h>
/* Hyper-V Synthetic Video Protocol definitions and structures */
#define MAX_VMBUS_PKT_SIZE 0x4000
@ -1363,6 +1362,9 @@ static int __init hvfb_drv_init(void)
{
int ret;
if (fb_modesetting_disabled("hyper_fb"))
return -ENODEV;
ret = vmbus_driver_register(&hvfb_drv);
if (ret != 0)
return ret;

View File

@ -1285,7 +1285,12 @@ static int __init i740fb_init(void)
{
#ifndef MODULE
char *option = NULL;
#endif
if (fb_modesetting_disabled("i740fb"))
return -ENODEV;
#ifndef MODULE
if (fb_get_options("i740fb", &option))
return -ENODEV;
i740fb_setup(option);

View File

@ -2143,6 +2143,9 @@ static int i810fb_init(void)
{
char *option = NULL;
if (fb_modesetting_disabled("i810fb"))
return -ENODEV;
if (fb_get_options("i810fb", &option))
return -ENODEV;
i810fb_setup(option);
@ -2159,6 +2162,9 @@ static int i810fb_init(void)
static int i810fb_init(void)
{
if (fb_modesetting_disabled("i810fb"))
return -ENODEV;
hsync1 *= 1000;
hsync2 *= 1000;

View File

@ -1617,7 +1617,12 @@ static int __init imsttfb_init(void)
{
#ifndef MODULE
char *option = NULL;
#endif
if (fb_modesetting_disabled("imsttfb"))
return -ENODEV;
#ifndef MODULE
if (fb_get_options("imsttfb", &option))
return -ENODEV;

View File

@ -389,6 +389,9 @@ static int __init intelfb_init(void)
if (idonly)
return -ENODEV;
if (fb_modesetting_disabled("intelfb"))
return -ENODEV;
#ifndef MODULE
if (fb_get_options("intelfb", &option))
return -ENODEV;

View File

@ -789,7 +789,12 @@ static int __init kyrofb_init(void)
{
#ifndef MODULE
char *option = NULL;
#endif
if (fb_modesetting_disabled("kyrofb"))
return -ENODEV;
#ifndef MODULE
if (fb_get_options("kyrofb", &option))
return -ENODEV;
kyrofb_setup(option);

View File

@ -2314,6 +2314,9 @@ static void __init matroxfb_init_params(void) {
static int __init matrox_init(void) {
int err;
if (fb_modesetting_disabled("matroxfb"))
return -ENODEV;
matroxfb_init_params();
err = pci_register_driver(&matroxfb_driver);
dev = -1; /* accept all new devices... */

View File

@ -1181,6 +1181,9 @@ static int mb862xxfb_init(void)
{
int ret = -ENODEV;
if (fb_modesetting_disabled(DRV_NAME))
return -ENODEV;
#if defined(CONFIG_FB_MB862XX_LIME)
ret = platform_driver_register(&of_platform_mb862xxfb_driver);
#endif

View File

@ -2209,7 +2209,12 @@ static int __init neofb_init(void)
{
#ifndef MODULE
char *option = NULL;
#endif
if (fb_modesetting_disabled("neofb"))
return -ENODEV;
#ifndef MODULE
if (fb_get_options("neofb", &option))
return -ENODEV;
neofb_setup(option);

View File

@ -1521,7 +1521,12 @@ static int nvidiafb_init(void)
{
#ifndef MODULE
char *option = NULL;
#endif
if (fb_modesetting_disabled("nvidiafb"))
return -ENODEV;
#ifndef MODULE
if (fb_get_options("nvidiafb", &option))
return -ENODEV;
nvidiafb_setup(option);

View File

@ -1799,7 +1799,12 @@ static int __init pm2fb_init(void)
{
#ifndef MODULE
char *option = NULL;
#endif
if (fb_modesetting_disabled("pm2fb"))
return -ENODEV;
#ifndef MODULE
if (fb_get_options("pm2fb", &option))
return -ENODEV;
pm2fb_setup(option);

View File

@ -1540,7 +1540,12 @@ static int __init pm3fb_init(void)
*/
#ifndef MODULE
char *option = NULL;
#endif
if (fb_modesetting_disabled("pm3fb"))
return -ENODEV;
#ifndef MODULE
if (fb_get_options("pm3fb", &option))
return -ENODEV;
pm3fb_setup(option);

View File

@ -1082,7 +1082,12 @@ static int __init pvr2fb_init(void)
#ifndef MODULE
char *option = NULL;
#endif
if (fb_modesetting_disabled("pvr2fb"))
return -ENODEV;
#ifndef MODULE
if (fb_get_options("pvr2fb", &option))
return -ENODEV;
pvr2fb_setup(option);

View File

@ -2165,7 +2165,12 @@ static int rivafb_init(void)
{
#ifndef MODULE
char *option = NULL;
#endif
if (fb_modesetting_disabled("rivafb"))
return -ENODEV;
#ifndef MODULE
if (fb_get_options("rivafb", &option))
return -ENODEV;
rivafb_setup(option);

View File

@ -1558,7 +1558,12 @@ static int __init s3fb_init(void)
#ifndef MODULE
char *option = NULL;
#endif
if (fb_modesetting_disabled("s3fb"))
return -ENODEV;
#ifndef MODULE
if (fb_get_options("s3fb", &option))
return -ENODEV;
s3fb_setup(option);

View File

@ -2556,6 +2556,9 @@ static int __init savagefb_init(void)
DBG("savagefb_init");
if (fb_modesetting_disabled("savagefb"))
return -ENODEV;
if (fb_get_options("savagefb", &option))
return -ENODEV;

View File

@ -6588,7 +6588,12 @@ static int __init sisfb_init(void)
{
#ifndef MODULE
char *options = NULL;
#endif
if (fb_modesetting_disabled("sisfb"))
return -ENODEV;
#ifndef MODULE
if(fb_get_options("sisfb", &options))
return -ENODEV;

View File

@ -987,7 +987,12 @@ static int __init xxxfb_init(void)
*/
#ifndef MODULE
char *option = NULL;
#endif
if (fb_modesetting_disabled("xxxfb"))
return -ENODEV;
#ifndef MODULE
if (fb_get_options("xxxfb", &option))
return -ENODEV;
xxxfb_setup(option);

View File

@ -1756,6 +1756,9 @@ static int __init sm712fb_init(void)
{
char *option = NULL;
if (fb_modesetting_disabled("sm712fb"))
return -ENODEV;
if (fb_get_options("sm712fb", &option))
return -ENODEV;
if (option && *option)

View File

@ -1503,6 +1503,9 @@ static int sstfb_init(void)
{
char *option = NULL;
if (fb_modesetting_disabled("sstfb"))
return -ENODEV;
if (fb_get_options("sstfb", &option))
return -ENODEV;
sstfb_setup(option);

View File

@ -247,6 +247,9 @@ static struct pci_driver s3d_driver = {
static int __init s3d_init(void)
{
if (fb_modesetting_disabled("s3d"))
return -ENODEV;
if (fb_get_options("s3d", NULL))
return -ENODEV;

View File

@ -430,6 +430,9 @@ static struct pci_driver e3d_driver = {
static int __init e3d_init(void)
{
if (fb_modesetting_disabled("e3d"))
return -ENODEV;
if (fb_get_options("e3d", NULL))
return -ENODEV;

View File

@ -1632,7 +1632,12 @@ static int __init tdfxfb_init(void)
{
#ifndef MODULE
char *option = NULL;
#endif
if (fb_modesetting_disabled("tdfxfb"))
return -ENODEV;
#ifndef MODULE
if (fb_get_options("tdfxfb", &option))
return -ENODEV;

View File

@ -1597,7 +1597,12 @@ static int tgafb_init(void)
int status;
#ifndef MODULE
char *option = NULL;
#endif
if (fb_modesetting_disabled("tgafb"))
return -ENODEV;
#ifndef MODULE
if (fb_get_options("tgafb", &option))
return -ENODEV;
tgafb_setup(option);

View File

@ -1811,7 +1811,12 @@ static int __init tridentfb_init(void)
{
#ifndef MODULE
char *option = NULL;
#endif
if (fb_modesetting_disabled("tridentfb"))
return -ENODEV;
#ifndef MODULE
if (fb_get_options("tridentfb", &option))
return -ENODEV;
tridentfb_setup(option);

View File

@ -1057,7 +1057,12 @@ static int __init vmlfb_init(void)
#ifndef MODULE
char *option = NULL;
#endif
if (fb_modesetting_disabled("vmlfb"))
return -ENODEV;
#ifndef MODULE
if (fb_get_options(MODULE_NAME, &option))
return -ENODEV;
#endif

Some files were not shown because too many files have changed in this diff Show More