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:
commit
4302423c88
@ -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
|
||||
|
||||
|
@ -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>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
...
|
@ -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,.*":
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
#
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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 {
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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",
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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},
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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])) {
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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 |
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
504
drivers/gpu/drm/panel/panel-newvision-nv3051d.c
Normal file
504
drivers/gpu/drm/panel/panel-newvision-nv3051d.c
Normal 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");
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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. */
|
||||
|
@ -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");
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
98
drivers/gpu/drm/tests/drm_client_modeset_test.c
Normal file
98
drivers/gpu/drm/tests/drm_client_modeset_test.c
Normal 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);
|
71
drivers/gpu/drm/tests/drm_kunit_helpers.c
Normal file
71
drivers/gpu/drm/tests/drm_kunit_helpers.c
Normal 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");
|
11
drivers/gpu/drm/tests/drm_kunit_helpers.h
Normal file
11
drivers/gpu/drm/tests/drm_kunit_helpers.h
Normal 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_
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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/
|
||||
|
@ -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.
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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 "
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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");
|
||||
|
@ -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);
|
||||
|
@ -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.
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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... */
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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
Loading…
Reference in New Issue
Block a user