drm-misc-next for 6.1:
UAPI Changes: Cross-subsystem Changes: - dma-buf: Improve signaling when debugging Core Changes: - Backlight handling improvements - format-helper: Add drm_fb_build_fourcc_list() - fourcc: Kunit tests improvements - modes: Add DRM_MODE_INIT() macro - plane: Remove drm_plane_init(), Allocate planes with drm_universal_plane_alloc() - plane-helper: Add drm_plane_helper_atomic_check() - probe-helper: Add drm_connector_helper_get_modes_fixed() and drm_crtc_helper_mode_valid_fixed() - tests: Conversion to parametrized tests, test name consistency Driver Changes: - amdgpu: Fix for a VRAM eviction issue - ast: Resolution handling improvements - mediatek: small code improvements for DP - omap: Refcounting fix, small improvements - rockchip: RK3568 support, Gamma support for RK3399 - sun4i: Build failure fix when !OF - udl: Multiple fixes here and there - vc4: HDMI hotplug handling improvements - vkms: Warning fix -----BEGIN PGP SIGNATURE----- iHUEABYKAB0WIQRcEzekXsqa64kGDp7j7w1vZxhRxQUCYy1ikAAKCRDj7w1vZxhR xWepAQC6CjJl40F3t8Xp/hH3MJtrr0jCA3zFLS5boIk3v7/Q8QEA9FW8zr4Svujz 9RJe8oN3ZVX133Zp+61WhziYI0XJuwg= =Veif -----END PGP SIGNATURE----- Merge tag 'drm-misc-next-2022-09-23' of git://anongit.freedesktop.org/drm/drm-misc into drm-next drm-misc-next for 6.1: UAPI Changes: Cross-subsystem Changes: - dma-buf: Improve signaling when debugging Core Changes: - Backlight handling improvements - format-helper: Add drm_fb_build_fourcc_list() - fourcc: Kunit tests improvements - modes: Add DRM_MODE_INIT() macro - plane: Remove drm_plane_init(), Allocate planes with drm_universal_plane_alloc() - plane-helper: Add drm_plane_helper_atomic_check() - probe-helper: Add drm_connector_helper_get_modes_fixed() and drm_crtc_helper_mode_valid_fixed() - tests: Conversion to parametrized tests, test name consistency Driver Changes: - amdgpu: Fix for a VRAM eviction issue - ast: Resolution handling improvements - mediatek: small code improvements for DP - omap: Refcounting fix, small improvements - rockchip: RK3568 support, Gamma support for RK3399 - sun4i: Build failure fix when !OF - udl: Multiple fixes here and there - vc4: HDMI hotplug handling improvements - vkms: Warning fix Signed-off-by: Dave Airlie <airlied@redhat.com> From: Maxime Ripard <maxime@cerno.tech> Link: https://patchwork.freedesktop.org/patch/msgid/20220923073943.d43tne5hni3iknlv@houat
This commit is contained in:
commit
907cc346ff
|
@ -14,19 +14,6 @@ properties:
|
|||
compatible:
|
||||
const: chrontel,ch7033
|
||||
|
||||
chrontel,byteswap:
|
||||
$ref: /schemas/types.yaml#/definitions/uint8
|
||||
enum:
|
||||
- 0 # BYTE_SWAP_RGB
|
||||
- 1 # BYTE_SWAP_RBG
|
||||
- 2 # BYTE_SWAP_GRB
|
||||
- 3 # BYTE_SWAP_GBR
|
||||
- 4 # BYTE_SWAP_BRG
|
||||
- 5 # BYTE_SWAP_BGR
|
||||
description: |
|
||||
Set the byteswap value of the bridge. This is optional and if not
|
||||
set value of BYTE_SWAP_BGR is used.
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
description: I2C address of the device
|
||||
|
|
|
@ -8,6 +8,7 @@ Required properties:
|
|||
"rockchip,px30-mipi-dsi", "snps,dw-mipi-dsi"
|
||||
"rockchip,rk3288-mipi-dsi", "snps,dw-mipi-dsi"
|
||||
"rockchip,rk3399-mipi-dsi", "snps,dw-mipi-dsi"
|
||||
"rockchip,rk3568-mipi-dsi", "snps,dw-mipi-dsi"
|
||||
- reg: Represent the physical address range of the controller.
|
||||
- interrupts: Represent the controller's interrupt to the CPU(s).
|
||||
- clocks, clock-names: Phandles to the controller's pll reference
|
||||
|
|
|
@ -679,6 +679,74 @@ Contact: Sam Ravnborg
|
|||
|
||||
Level: Advanced
|
||||
|
||||
Brightness handling on devices with multiple internal panels
|
||||
============================================================
|
||||
|
||||
On x86/ACPI devices there can be multiple backlight firmware interfaces:
|
||||
(ACPI) video, vendor specific and others. As well as direct/native (PWM)
|
||||
register programming by the KMS driver.
|
||||
|
||||
To deal with this backlight drivers used on x86/ACPI call
|
||||
acpi_video_get_backlight_type() which has heuristics (+quirks) to select
|
||||
which backlight interface to use; and backlight drivers which do not match
|
||||
the returned type will not register themselves, so that only one backlight
|
||||
device gets registered (in a single GPU setup, see below).
|
||||
|
||||
At the moment this more or less assumes that there will only
|
||||
be 1 (internal) panel on a system.
|
||||
|
||||
On systems with 2 panels this may be a problem, depending on
|
||||
what interface acpi_video_get_backlight_type() selects:
|
||||
|
||||
1. native: in this case the KMS driver is expected to know which backlight
|
||||
device belongs to which output so everything should just work.
|
||||
2. video: this does support controlling multiple backlights, but some work
|
||||
will need to be done to get the output <-> backlight device mapping
|
||||
|
||||
The above assumes both panels will require the same backlight interface type.
|
||||
Things will break on systems with multiple panels where the 2 panels need
|
||||
a different type of control. E.g. one panel needs ACPI video backlight control,
|
||||
where as the other is using native backlight control. Currently in this case
|
||||
only one of the 2 required backlight devices will get registered, based on
|
||||
the acpi_video_get_backlight_type() return value.
|
||||
|
||||
If this (theoretical) case ever shows up, then supporting this will need some
|
||||
work. A possible solution here would be to pass a device and connector-name
|
||||
to acpi_video_get_backlight_type() so that it can deal with this.
|
||||
|
||||
Note in a way we already have a case where userspace sees 2 panels,
|
||||
in dual GPU laptop setups with a mux. On those systems we may see
|
||||
either 2 native backlight devices; or 2 native backlight devices.
|
||||
|
||||
Userspace already has code to deal with this by detecting if the related
|
||||
panel is active (iow which way the mux between the GPU and the panels
|
||||
points) and then uses that backlight device. Userspace here very much
|
||||
assumes a single panel though. It picks only 1 of the 2 backlight devices
|
||||
and then only uses that one.
|
||||
|
||||
Note that all userspace code (that I know off) is currently hardcoded
|
||||
to assume a single panel.
|
||||
|
||||
Before the recent changes to not register multiple (e.g. video + native)
|
||||
/sys/class/backlight devices for a single panel (on a single GPU laptop),
|
||||
userspace would see multiple backlight devices all controlling the same
|
||||
backlight.
|
||||
|
||||
To deal with this userspace had to always picks one preferred device under
|
||||
/sys/class/backlight and will ignore the others. So to support brightness
|
||||
control on multiple panels userspace will need to be updated too.
|
||||
|
||||
There are plans to allow brightness control through the KMS API by adding
|
||||
a "display brightness" property to drm_connector objects for panels. This
|
||||
solves a number of issues with the /sys/class/backlight API, including not
|
||||
being able to map a sysfs backlight device to a specific connector. Any
|
||||
userspace changes to add support for brightness control on devices with
|
||||
multiple panels really should build on top of this new KMS property.
|
||||
|
||||
Contact: Hans de Goede
|
||||
|
||||
Level: Advanced
|
||||
|
||||
Outside DRM
|
||||
===========
|
||||
|
||||
|
|
|
@ -14532,6 +14532,7 @@ M: Daniel Dadap <ddadap@nvidia.com>
|
|||
L: platform-driver-x86@vger.kernel.org
|
||||
S: Supported
|
||||
F: drivers/platform/x86/nvidia-wmi-ec-backlight.c
|
||||
F: include/linux/platform_data/x86/nvidia-wmi-ec-backlight.h
|
||||
|
||||
NVM EXPRESS DRIVER
|
||||
M: Keith Busch <kbusch@kernel.org>
|
||||
|
|
|
@ -212,6 +212,7 @@ config ACPI_VIDEO
|
|||
tristate "Video"
|
||||
depends on BACKLIGHT_CLASS_DEVICE
|
||||
depends on INPUT
|
||||
depends on ACPI_WMI || !X86
|
||||
select THERMAL
|
||||
help
|
||||
This driver implements the ACPI Extensions For Display Adapters
|
||||
|
|
|
@ -73,6 +73,16 @@ module_param(device_id_scheme, bool, 0444);
|
|||
static int only_lcd = -1;
|
||||
module_param(only_lcd, int, 0444);
|
||||
|
||||
/*
|
||||
* Display probing is known to take up to 5 seconds, so delay the fallback
|
||||
* backlight registration by 5 seconds + 3 seconds for some extra margin.
|
||||
*/
|
||||
static int register_backlight_delay = 8;
|
||||
module_param(register_backlight_delay, int, 0444);
|
||||
MODULE_PARM_DESC(register_backlight_delay,
|
||||
"Delay in seconds before doing fallback (non GPU driver triggered) "
|
||||
"backlight registration, set to 0 to disable.");
|
||||
|
||||
static bool may_report_brightness_keys;
|
||||
static int register_count;
|
||||
static DEFINE_MUTEX(register_count_mutex);
|
||||
|
@ -81,7 +91,9 @@ static LIST_HEAD(video_bus_head);
|
|||
static int acpi_video_bus_add(struct acpi_device *device);
|
||||
static int acpi_video_bus_remove(struct acpi_device *device);
|
||||
static void acpi_video_bus_notify(struct acpi_device *device, u32 event);
|
||||
void acpi_video_detect_exit(void);
|
||||
static void acpi_video_bus_register_backlight_work(struct work_struct *ignored);
|
||||
static DECLARE_DELAYED_WORK(video_bus_register_backlight_work,
|
||||
acpi_video_bus_register_backlight_work);
|
||||
|
||||
/*
|
||||
* Indices in the _BCL method response: the first two items are special,
|
||||
|
@ -1859,8 +1871,6 @@ static int acpi_video_bus_register_backlight(struct acpi_video_bus *video)
|
|||
if (video->backlight_registered)
|
||||
return 0;
|
||||
|
||||
acpi_video_run_bcl_for_osi(video);
|
||||
|
||||
if (acpi_video_get_backlight_type() != acpi_backlight_video)
|
||||
return 0;
|
||||
|
||||
|
@ -2086,7 +2096,11 @@ static int acpi_video_bus_add(struct acpi_device *device)
|
|||
list_add_tail(&video->entry, &video_bus_head);
|
||||
mutex_unlock(&video_list_lock);
|
||||
|
||||
acpi_video_bus_register_backlight(video);
|
||||
/*
|
||||
* The userspace visible backlight_device gets registered separately
|
||||
* from acpi_video_register_backlight().
|
||||
*/
|
||||
acpi_video_run_bcl_for_osi(video);
|
||||
acpi_video_bus_add_notify_handler(video);
|
||||
|
||||
return 0;
|
||||
|
@ -2111,20 +2125,25 @@ static int acpi_video_bus_remove(struct acpi_device *device)
|
|||
|
||||
video = acpi_driver_data(device);
|
||||
|
||||
acpi_video_bus_remove_notify_handler(video);
|
||||
acpi_video_bus_unregister_backlight(video);
|
||||
acpi_video_bus_put_devices(video);
|
||||
|
||||
mutex_lock(&video_list_lock);
|
||||
list_del(&video->entry);
|
||||
mutex_unlock(&video_list_lock);
|
||||
|
||||
acpi_video_bus_remove_notify_handler(video);
|
||||
acpi_video_bus_unregister_backlight(video);
|
||||
acpi_video_bus_put_devices(video);
|
||||
|
||||
kfree(video->attached_array);
|
||||
kfree(video);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void acpi_video_bus_register_backlight_work(struct work_struct *ignored)
|
||||
{
|
||||
acpi_video_register_backlight();
|
||||
}
|
||||
|
||||
static int __init is_i740(struct pci_dev *dev)
|
||||
{
|
||||
if (dev->device == 0x00D1)
|
||||
|
@ -2235,6 +2254,18 @@ int acpi_video_register(void)
|
|||
*/
|
||||
register_count = 1;
|
||||
|
||||
/*
|
||||
* acpi_video_bus_add() skips registering the userspace visible
|
||||
* backlight_device. The intend is for this to be registered by the
|
||||
* drm/kms driver calling acpi_video_register_backlight() *after* it is
|
||||
* done setting up its own native backlight device. The delayed work
|
||||
* ensures that acpi_video_register_backlight() always gets called
|
||||
* eventually, in case there is no drm/kms driver or it is disabled.
|
||||
*/
|
||||
if (register_backlight_delay)
|
||||
schedule_delayed_work(&video_bus_register_backlight_work,
|
||||
register_backlight_delay * HZ);
|
||||
|
||||
leave:
|
||||
mutex_unlock(®ister_count_mutex);
|
||||
return ret;
|
||||
|
@ -2245,6 +2276,7 @@ void acpi_video_unregister(void)
|
|||
{
|
||||
mutex_lock(®ister_count_mutex);
|
||||
if (register_count) {
|
||||
cancel_delayed_work_sync(&video_bus_register_backlight_work);
|
||||
acpi_bus_unregister_driver(&acpi_video_bus);
|
||||
register_count = 0;
|
||||
may_report_brightness_keys = false;
|
||||
|
@ -2253,19 +2285,16 @@ void acpi_video_unregister(void)
|
|||
}
|
||||
EXPORT_SYMBOL(acpi_video_unregister);
|
||||
|
||||
void acpi_video_unregister_backlight(void)
|
||||
void acpi_video_register_backlight(void)
|
||||
{
|
||||
struct acpi_video_bus *video;
|
||||
|
||||
mutex_lock(®ister_count_mutex);
|
||||
if (register_count) {
|
||||
mutex_lock(&video_list_lock);
|
||||
list_for_each_entry(video, &video_bus_head, entry)
|
||||
acpi_video_bus_unregister_backlight(video);
|
||||
mutex_unlock(&video_list_lock);
|
||||
}
|
||||
mutex_unlock(®ister_count_mutex);
|
||||
mutex_lock(&video_list_lock);
|
||||
list_for_each_entry(video, &video_bus_head, entry)
|
||||
acpi_video_bus_register_backlight(video);
|
||||
mutex_unlock(&video_list_lock);
|
||||
}
|
||||
EXPORT_SYMBOL(acpi_video_register_backlight);
|
||||
|
||||
bool acpi_video_handles_brightness_key_presses(void)
|
||||
{
|
||||
|
@ -2302,7 +2331,6 @@ static int __init acpi_video_init(void)
|
|||
|
||||
static void __exit acpi_video_exit(void)
|
||||
{
|
||||
acpi_video_detect_exit();
|
||||
acpi_video_unregister();
|
||||
}
|
||||
|
||||
|
|
|
@ -17,8 +17,9 @@
|
|||
* Otherwise vendor specific drivers like thinkpad_acpi, asus-laptop,
|
||||
* sony_acpi,... can take care about backlight brightness.
|
||||
*
|
||||
* Backlight drivers can use acpi_video_get_backlight_type() to determine
|
||||
* which driver should handle the backlight.
|
||||
* Backlight drivers can use acpi_video_get_backlight_type() to determine which
|
||||
* driver should handle the backlight. RAW/GPU-driver backlight drivers must
|
||||
* use the acpi_video_backlight_use_native() helper for this.
|
||||
*
|
||||
* If CONFIG_ACPI_VIDEO is neither set as "compiled in" (y) nor as a module (m)
|
||||
* this file will not be compiled and acpi_video_get_backlight_type() will
|
||||
|
@ -27,20 +28,16 @@
|
|||
|
||||
#include <linux/export.h>
|
||||
#include <linux/acpi.h>
|
||||
#include <linux/apple-gmux.h>
|
||||
#include <linux/backlight.h>
|
||||
#include <linux/dmi.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/platform_data/x86/nvidia-wmi-ec-backlight.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/workqueue.h>
|
||||
#include <acpi/video.h>
|
||||
|
||||
void acpi_video_unregister_backlight(void);
|
||||
|
||||
static bool backlight_notifier_registered;
|
||||
static struct notifier_block backlight_nb;
|
||||
static struct work_struct backlight_notify_work;
|
||||
|
||||
static enum acpi_backlight_type acpi_backlight_cmdline = acpi_backlight_undef;
|
||||
static enum acpi_backlight_type acpi_backlight_dmi = acpi_backlight_undef;
|
||||
|
||||
|
@ -78,6 +75,36 @@ find_video(acpi_handle handle, u32 lvl, void *context, void **rv)
|
|||
return AE_OK;
|
||||
}
|
||||
|
||||
/* This depends on ACPI_WMI which is X86 only */
|
||||
#ifdef CONFIG_X86
|
||||
static bool nvidia_wmi_ec_supported(void)
|
||||
{
|
||||
struct wmi_brightness_args args = {
|
||||
.mode = WMI_BRIGHTNESS_MODE_GET,
|
||||
.val = 0,
|
||||
.ret = 0,
|
||||
};
|
||||
struct acpi_buffer buf = { (acpi_size)sizeof(args), &args };
|
||||
acpi_status status;
|
||||
|
||||
status = wmi_evaluate_method(WMI_BRIGHTNESS_GUID, 0,
|
||||
WMI_BRIGHTNESS_METHOD_SOURCE, &buf, &buf);
|
||||
if (ACPI_FAILURE(status))
|
||||
return false;
|
||||
|
||||
/*
|
||||
* If brightness is handled by the EC then nvidia-wmi-ec-backlight
|
||||
* should be used, else the GPU driver(s) should be used.
|
||||
*/
|
||||
return args.ret == WMI_BRIGHTNESS_SOURCE_EC;
|
||||
}
|
||||
#else
|
||||
static bool nvidia_wmi_ec_supported(void)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Force to use vendor driver when the ACPI device is known to be
|
||||
* buggy */
|
||||
static int video_detect_force_vendor(const struct dmi_system_id *d)
|
||||
|
@ -105,62 +132,142 @@ static int video_detect_force_none(const struct dmi_system_id *d)
|
|||
}
|
||||
|
||||
static const struct dmi_system_id video_detect_dmi_table[] = {
|
||||
/* On Samsung X360, the BIOS will set a flag (VDRV) if generic
|
||||
* ACPI backlight device is used. This flag will definitively break
|
||||
* the backlight interface (even the vendor interface) until next
|
||||
* reboot. It's why we should prevent video.ko from being used here
|
||||
* and we can't rely on a later call to acpi_video_unregister().
|
||||
*/
|
||||
{
|
||||
/* https://bugzilla.redhat.com/show_bug.cgi?id=1128309 */
|
||||
.callback = video_detect_force_vendor,
|
||||
/* X360 */
|
||||
/* Acer KAV80 */
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "X360"),
|
||||
DMI_MATCH(DMI_BOARD_NAME, "X360"),
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "KAV80"),
|
||||
},
|
||||
},
|
||||
{
|
||||
.callback = video_detect_force_vendor,
|
||||
/* Asus UL30VT */
|
||||
.matches = {
|
||||
.callback = video_detect_force_vendor,
|
||||
/* Asus UL30VT */
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "UL30VT"),
|
||||
},
|
||||
},
|
||||
{
|
||||
.callback = video_detect_force_vendor,
|
||||
/* Asus UL30A */
|
||||
.matches = {
|
||||
.callback = video_detect_force_vendor,
|
||||
/* Asus UL30A */
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "UL30A"),
|
||||
},
|
||||
},
|
||||
{
|
||||
.callback = video_detect_force_vendor,
|
||||
/* GIGABYTE GB-BXBT-2807 */
|
||||
.matches = {
|
||||
.callback = video_detect_force_vendor,
|
||||
/* Asus X55U */
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "X55U"),
|
||||
},
|
||||
},
|
||||
{
|
||||
.callback = video_detect_force_vendor,
|
||||
/* Asus X101CH */
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "X101CH"),
|
||||
},
|
||||
},
|
||||
{
|
||||
.callback = video_detect_force_vendor,
|
||||
/* Asus X401U */
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "X401U"),
|
||||
},
|
||||
},
|
||||
{
|
||||
.callback = video_detect_force_vendor,
|
||||
/* Asus X501U */
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "X501U"),
|
||||
},
|
||||
},
|
||||
{
|
||||
.callback = video_detect_force_vendor,
|
||||
/* Asus 1015CX */
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "1015CX"),
|
||||
},
|
||||
},
|
||||
{
|
||||
.callback = video_detect_force_vendor,
|
||||
/* GIGABYTE GB-BXBT-2807 */
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "GIGABYTE"),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "GB-BXBT-2807"),
|
||||
},
|
||||
},
|
||||
{
|
||||
.callback = video_detect_force_vendor,
|
||||
/* Sony VPCEH3U1E */
|
||||
.matches = {
|
||||
.callback = video_detect_force_vendor,
|
||||
/* Samsung N150/N210/N220 */
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "N150/N210/N220"),
|
||||
DMI_MATCH(DMI_BOARD_NAME, "N150/N210/N220"),
|
||||
},
|
||||
},
|
||||
{
|
||||
.callback = video_detect_force_vendor,
|
||||
/* Samsung NF110/NF210/NF310 */
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "NF110/NF210/NF310"),
|
||||
DMI_MATCH(DMI_BOARD_NAME, "NF110/NF210/NF310"),
|
||||
},
|
||||
},
|
||||
{
|
||||
.callback = video_detect_force_vendor,
|
||||
/* Samsung NC210 */
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "NC210/NC110"),
|
||||
DMI_MATCH(DMI_BOARD_NAME, "NC210/NC110"),
|
||||
},
|
||||
},
|
||||
{
|
||||
.callback = video_detect_force_vendor,
|
||||
/* Sony VPCEH3U1E */
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "VPCEH3U1E"),
|
||||
},
|
||||
},
|
||||
{
|
||||
.callback = video_detect_force_vendor,
|
||||
/* Xiaomi Mi Pad 2 */
|
||||
.matches = {
|
||||
.callback = video_detect_force_vendor,
|
||||
/* Xiaomi Mi Pad 2 */
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "Xiaomi Inc"),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "Mipad2"),
|
||||
},
|
||||
},
|
||||
|
||||
/*
|
||||
* Toshiba models with Transflective display, these need to use
|
||||
* the toshiba_acpi vendor driver for proper Transflective handling.
|
||||
*/
|
||||
{
|
||||
.callback = video_detect_force_vendor,
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "PORTEGE R500"),
|
||||
},
|
||||
},
|
||||
{
|
||||
.callback = video_detect_force_vendor,
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "PORTEGE R600"),
|
||||
},
|
||||
},
|
||||
|
||||
/*
|
||||
* These models have a working acpi_video backlight control, and using
|
||||
* native backlight causes a regression where backlight does not work
|
||||
|
@ -389,6 +496,41 @@ static const struct dmi_system_id video_detect_dmi_table[] = {
|
|||
DMI_MATCH(DMI_BOARD_NAME, "JV50"),
|
||||
},
|
||||
},
|
||||
{
|
||||
/* https://bugzilla.redhat.com/show_bug.cgi?id=1012674 */
|
||||
.callback = video_detect_force_native,
|
||||
/* Acer Aspire 5741 */
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_BOARD_VENDOR, "Acer"),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5741"),
|
||||
},
|
||||
},
|
||||
{
|
||||
/* https://bugzilla.kernel.org/show_bug.cgi?id=42993 */
|
||||
.callback = video_detect_force_native,
|
||||
/* Acer Aspire 5750 */
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_BOARD_VENDOR, "Acer"),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5750"),
|
||||
},
|
||||
},
|
||||
{
|
||||
/* https://bugzilla.kernel.org/show_bug.cgi?id=42833 */
|
||||
.callback = video_detect_force_native,
|
||||
/* Acer Extensa 5235 */
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_BOARD_VENDOR, "Acer"),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "Extensa 5235"),
|
||||
},
|
||||
},
|
||||
{
|
||||
.callback = video_detect_force_native,
|
||||
/* Acer TravelMate 4750 */
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_BOARD_VENDOR, "Acer"),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 4750"),
|
||||
},
|
||||
},
|
||||
{
|
||||
/* https://bugzilla.kernel.org/show_bug.cgi?id=207835 */
|
||||
.callback = video_detect_force_native,
|
||||
|
@ -400,120 +542,74 @@ static const struct dmi_system_id video_detect_dmi_table[] = {
|
|||
},
|
||||
},
|
||||
{
|
||||
.callback = video_detect_force_native,
|
||||
/* ASUSTeK COMPUTER INC. GA401 */
|
||||
.matches = {
|
||||
/* https://bugzilla.kernel.org/show_bug.cgi?id=36322 */
|
||||
.callback = video_detect_force_native,
|
||||
/* Acer TravelMate 5760 */
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_BOARD_VENDOR, "Acer"),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 5760"),
|
||||
},
|
||||
},
|
||||
{
|
||||
.callback = video_detect_force_native,
|
||||
/* ASUSTeK COMPUTER INC. GA401 */
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "GA401"),
|
||||
},
|
||||
},
|
||||
{
|
||||
.callback = video_detect_force_native,
|
||||
/* ASUSTeK COMPUTER INC. GA502 */
|
||||
.matches = {
|
||||
.callback = video_detect_force_native,
|
||||
/* ASUSTeK COMPUTER INC. GA502 */
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "GA502"),
|
||||
},
|
||||
},
|
||||
{
|
||||
.callback = video_detect_force_native,
|
||||
/* ASUSTeK COMPUTER INC. GA503 */
|
||||
.matches = {
|
||||
.callback = video_detect_force_native,
|
||||
/* ASUSTeK COMPUTER INC. GA503 */
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "GA503"),
|
||||
},
|
||||
},
|
||||
/*
|
||||
* Clevo NL5xRU and NL5xNU/TUXEDO Aura 15 Gen1 and Gen2 have both a
|
||||
* working native and video interface. However the default detection
|
||||
* mechanism first registers the video interface before unregistering
|
||||
* it again and switching to the native interface during boot. This
|
||||
* results in a dangling SBIOS request for backlight change for some
|
||||
* reason, causing the backlight to switch to ~2% once per boot on the
|
||||
* first power cord connect or disconnect event. Setting the native
|
||||
* interface explicitly circumvents this buggy behaviour, by avoiding
|
||||
* the unregistering process.
|
||||
*/
|
||||
{
|
||||
.callback = video_detect_force_native,
|
||||
.ident = "Clevo NL5xRU",
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_BOARD_NAME, "NL5xRU"),
|
||||
.callback = video_detect_force_native,
|
||||
/* Asus UX303UB */
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "UX303UB"),
|
||||
},
|
||||
},
|
||||
{
|
||||
.callback = video_detect_force_native,
|
||||
.ident = "Clevo NL5xRU",
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"),
|
||||
DMI_MATCH(DMI_BOARD_NAME, "AURA1501"),
|
||||
.callback = video_detect_force_native,
|
||||
/* Samsung N150P */
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "N150P"),
|
||||
DMI_MATCH(DMI_BOARD_NAME, "N150P"),
|
||||
},
|
||||
},
|
||||
{
|
||||
.callback = video_detect_force_native,
|
||||
.ident = "Clevo NL5xRU",
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"),
|
||||
DMI_MATCH(DMI_BOARD_NAME, "EDUBOOK1502"),
|
||||
.callback = video_detect_force_native,
|
||||
/* Samsung N145P/N250P/N260P */
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "N145P/N250P/N260P"),
|
||||
DMI_MATCH(DMI_BOARD_NAME, "N145P/N250P/N260P"),
|
||||
},
|
||||
},
|
||||
{
|
||||
.callback = video_detect_force_native,
|
||||
.ident = "Clevo NL5xNU",
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_BOARD_NAME, "NL5xNU"),
|
||||
},
|
||||
},
|
||||
/*
|
||||
* The TongFang PF5PU1G, PF4NU1F, PF5NU1G, and PF5LUXG/TUXEDO BA15 Gen10,
|
||||
* Pulse 14/15 Gen1, and Pulse 15 Gen2 have the same problem as the Clevo
|
||||
* NL5xRU and NL5xNU/TUXEDO Aura 15 Gen1 and Gen2. See the description
|
||||
* above.
|
||||
*/
|
||||
{
|
||||
.callback = video_detect_force_native,
|
||||
.ident = "TongFang PF5PU1G",
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_BOARD_NAME, "PF5PU1G"),
|
||||
},
|
||||
},
|
||||
{
|
||||
.callback = video_detect_force_native,
|
||||
.ident = "TongFang PF4NU1F",
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_BOARD_NAME, "PF4NU1F"),
|
||||
},
|
||||
},
|
||||
{
|
||||
.callback = video_detect_force_native,
|
||||
.ident = "TongFang PF4NU1F",
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"),
|
||||
DMI_MATCH(DMI_BOARD_NAME, "PULSE1401"),
|
||||
},
|
||||
},
|
||||
{
|
||||
.callback = video_detect_force_native,
|
||||
.ident = "TongFang PF5NU1G",
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_BOARD_NAME, "PF5NU1G"),
|
||||
},
|
||||
},
|
||||
{
|
||||
.callback = video_detect_force_native,
|
||||
.ident = "TongFang PF5NU1G",
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"),
|
||||
DMI_MATCH(DMI_BOARD_NAME, "PULSE1501"),
|
||||
},
|
||||
},
|
||||
{
|
||||
.callback = video_detect_force_native,
|
||||
.ident = "TongFang PF5LUXG",
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_BOARD_NAME, "PF5LUXG"),
|
||||
.callback = video_detect_force_native,
|
||||
/* Samsung N250P */
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "N250P"),
|
||||
DMI_MATCH(DMI_BOARD_NAME, "N250P"),
|
||||
},
|
||||
},
|
||||
|
||||
/*
|
||||
* Desktops which falsely report a backlight and which our heuristics
|
||||
* for this do not catch.
|
||||
|
@ -537,43 +633,15 @@ static const struct dmi_system_id video_detect_dmi_table[] = {
|
|||
{ },
|
||||
};
|
||||
|
||||
/* This uses a workqueue to avoid various locking ordering issues */
|
||||
static void acpi_video_backlight_notify_work(struct work_struct *work)
|
||||
{
|
||||
if (acpi_video_get_backlight_type() != acpi_backlight_video)
|
||||
acpi_video_unregister_backlight();
|
||||
}
|
||||
|
||||
static int acpi_video_backlight_notify(struct notifier_block *nb,
|
||||
unsigned long val, void *bd)
|
||||
{
|
||||
struct backlight_device *backlight = bd;
|
||||
|
||||
/* A raw bl registering may change video -> native */
|
||||
if (backlight->props.type == BACKLIGHT_RAW &&
|
||||
val == BACKLIGHT_REGISTERED)
|
||||
schedule_work(&backlight_notify_work);
|
||||
|
||||
return NOTIFY_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* Determine which type of backlight interface to use on this system,
|
||||
* First check cmdline, then dmi quirks, then do autodetect.
|
||||
*
|
||||
* The autodetect order is:
|
||||
* 1) Is the acpi-video backlight interface supported ->
|
||||
* no, use a vendor interface
|
||||
* 2) Is this a win8 "ready" BIOS and do we have a native interface ->
|
||||
* yes, use a native interface
|
||||
* 3) Else use the acpi-video interface
|
||||
*
|
||||
* Arguably the native on win8 check should be done first, but that would
|
||||
* be a behavior change, which may causes issues.
|
||||
*/
|
||||
enum acpi_backlight_type acpi_video_get_backlight_type(void)
|
||||
static enum acpi_backlight_type __acpi_video_get_backlight_type(bool native)
|
||||
{
|
||||
static DEFINE_MUTEX(init_mutex);
|
||||
static bool nvidia_wmi_ec_present;
|
||||
static bool native_available;
|
||||
static bool init_done;
|
||||
static long video_caps;
|
||||
|
||||
|
@ -585,48 +653,60 @@ enum acpi_backlight_type acpi_video_get_backlight_type(void)
|
|||
acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
|
||||
ACPI_UINT32_MAX, find_video, NULL,
|
||||
&video_caps, NULL);
|
||||
INIT_WORK(&backlight_notify_work,
|
||||
acpi_video_backlight_notify_work);
|
||||
backlight_nb.notifier_call = acpi_video_backlight_notify;
|
||||
backlight_nb.priority = 0;
|
||||
if (backlight_register_notifier(&backlight_nb) == 0)
|
||||
backlight_notifier_registered = true;
|
||||
nvidia_wmi_ec_present = nvidia_wmi_ec_supported();
|
||||
init_done = true;
|
||||
}
|
||||
if (native)
|
||||
native_available = true;
|
||||
mutex_unlock(&init_mutex);
|
||||
|
||||
/*
|
||||
* The below heuristics / detection steps are in order of descending
|
||||
* presedence. The commandline takes presedence over anything else.
|
||||
*/
|
||||
if (acpi_backlight_cmdline != acpi_backlight_undef)
|
||||
return acpi_backlight_cmdline;
|
||||
|
||||
/* DMI quirks override any autodetection. */
|
||||
if (acpi_backlight_dmi != acpi_backlight_undef)
|
||||
return acpi_backlight_dmi;
|
||||
|
||||
if (!(video_caps & ACPI_VIDEO_BACKLIGHT))
|
||||
return acpi_backlight_vendor;
|
||||
/* Special cases such as nvidia_wmi_ec and apple gmux. */
|
||||
if (nvidia_wmi_ec_present)
|
||||
return acpi_backlight_nvidia_wmi_ec;
|
||||
|
||||
if (acpi_osi_is_win8() && backlight_device_get_by_type(BACKLIGHT_RAW))
|
||||
return acpi_backlight_native;
|
||||
if (apple_gmux_present())
|
||||
return acpi_backlight_apple_gmux;
|
||||
|
||||
return acpi_backlight_video;
|
||||
/* On systems with ACPI video use either native or ACPI video. */
|
||||
if (video_caps & ACPI_VIDEO_BACKLIGHT) {
|
||||
/*
|
||||
* Windows 8 and newer no longer use the ACPI video interface,
|
||||
* so it often does not work. If the ACPI tables are written
|
||||
* for win8 and native brightness ctl is available, use that.
|
||||
*
|
||||
* The native check deliberately is inside the if acpi-video
|
||||
* block on older devices without acpi-video support native
|
||||
* is usually not the best choice.
|
||||
*/
|
||||
if (acpi_osi_is_win8() && native_available)
|
||||
return acpi_backlight_native;
|
||||
else
|
||||
return acpi_backlight_video;
|
||||
}
|
||||
|
||||
/* No ACPI video (old hw), use vendor specific fw methods. */
|
||||
return acpi_backlight_vendor;
|
||||
}
|
||||
|
||||
enum acpi_backlight_type acpi_video_get_backlight_type(void)
|
||||
{
|
||||
return __acpi_video_get_backlight_type(false);
|
||||
}
|
||||
EXPORT_SYMBOL(acpi_video_get_backlight_type);
|
||||
|
||||
/*
|
||||
* Set the preferred backlight interface type based on DMI info.
|
||||
* This function allows DMI blacklists to be implemented by external
|
||||
* platform drivers instead of putting a big blacklist in video_detect.c
|
||||
*/
|
||||
void acpi_video_set_dmi_backlight_type(enum acpi_backlight_type type)
|
||||
bool acpi_video_backlight_use_native(void)
|
||||
{
|
||||
acpi_backlight_dmi = type;
|
||||
/* Remove acpi-video backlight interface if it is no longer desired */
|
||||
if (acpi_video_get_backlight_type() != acpi_backlight_video)
|
||||
acpi_video_unregister_backlight();
|
||||
}
|
||||
EXPORT_SYMBOL(acpi_video_set_dmi_backlight_type);
|
||||
|
||||
void __exit acpi_video_detect_exit(void)
|
||||
{
|
||||
if (backlight_notifier_registered)
|
||||
backlight_unregister_notifier(&backlight_nb);
|
||||
return __acpi_video_get_backlight_type(true) == acpi_backlight_native;
|
||||
}
|
||||
EXPORT_SYMBOL(acpi_video_backlight_use_native);
|
||||
|
|
|
@ -136,6 +136,10 @@ struct dma_fence *dma_fence_get_stub(void)
|
|||
&dma_fence_stub_ops,
|
||||
&dma_fence_stub_lock,
|
||||
0, 0);
|
||||
|
||||
set_bit(DMA_FENCE_FLAG_ENABLE_SIGNAL_BIT,
|
||||
&dma_fence_stub.flags);
|
||||
|
||||
dma_fence_signal_locked(&dma_fence_stub);
|
||||
}
|
||||
spin_unlock(&dma_fence_stub_lock);
|
||||
|
@ -161,6 +165,10 @@ struct dma_fence *dma_fence_allocate_private_stub(void)
|
|||
&dma_fence_stub_ops,
|
||||
&dma_fence_stub_lock,
|
||||
0, 0);
|
||||
|
||||
set_bit(DMA_FENCE_FLAG_ENABLE_SIGNAL_BIT,
|
||||
&dma_fence_stub.flags);
|
||||
|
||||
dma_fence_signal(fence);
|
||||
|
||||
return fence;
|
||||
|
@ -500,6 +508,8 @@ dma_fence_wait_timeout(struct dma_fence *fence, bool intr, signed long timeout)
|
|||
|
||||
__dma_fence_might_wait();
|
||||
|
||||
dma_fence_enable_sw_signaling(fence);
|
||||
|
||||
trace_dma_fence_wait_start(fence);
|
||||
if (fence->ops->wait)
|
||||
ret = fence->ops->wait(fence, intr, timeout);
|
||||
|
@ -601,9 +611,6 @@ void dma_fence_enable_sw_signaling(struct dma_fence *fence)
|
|||
{
|
||||
unsigned long flags;
|
||||
|
||||
if (test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &fence->flags))
|
||||
return;
|
||||
|
||||
spin_lock_irqsave(fence->lock, flags);
|
||||
__dma_fence_enable_signaling(fence);
|
||||
spin_unlock_irqrestore(fence->lock, flags);
|
||||
|
@ -756,19 +763,16 @@ dma_fence_default_wait(struct dma_fence *fence, bool intr, signed long timeout)
|
|||
unsigned long flags;
|
||||
signed long ret = timeout ? timeout : 1;
|
||||
|
||||
if (test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &fence->flags))
|
||||
return ret;
|
||||
|
||||
spin_lock_irqsave(fence->lock, flags);
|
||||
|
||||
if (test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &fence->flags))
|
||||
goto out;
|
||||
|
||||
if (intr && signal_pending(current)) {
|
||||
ret = -ERESTARTSYS;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!__dma_fence_enable_signaling(fence))
|
||||
goto out;
|
||||
|
||||
if (!timeout) {
|
||||
ret = 0;
|
||||
goto out;
|
||||
|
|
|
@ -87,6 +87,8 @@ static int sanitycheck(void *arg)
|
|||
if (!chain)
|
||||
err = -ENOMEM;
|
||||
|
||||
dma_fence_enable_sw_signaling(chain);
|
||||
|
||||
dma_fence_signal(f);
|
||||
dma_fence_put(f);
|
||||
|
||||
|
@ -143,6 +145,8 @@ static int fence_chains_init(struct fence_chains *fc, unsigned int count,
|
|||
}
|
||||
|
||||
fc->tail = fc->chains[i];
|
||||
|
||||
dma_fence_enable_sw_signaling(fc->chains[i]);
|
||||
}
|
||||
|
||||
fc->chain_length = i;
|
||||
|
|
|
@ -102,6 +102,8 @@ static int sanitycheck(void *arg)
|
|||
if (!f)
|
||||
return -ENOMEM;
|
||||
|
||||
dma_fence_enable_sw_signaling(f);
|
||||
|
||||
array = mock_array(1, f);
|
||||
if (!array)
|
||||
return -ENOMEM;
|
||||
|
@ -124,12 +126,16 @@ static int unwrap_array(void *arg)
|
|||
if (!f1)
|
||||
return -ENOMEM;
|
||||
|
||||
dma_fence_enable_sw_signaling(f1);
|
||||
|
||||
f2 = mock_fence();
|
||||
if (!f2) {
|
||||
dma_fence_put(f1);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
dma_fence_enable_sw_signaling(f2);
|
||||
|
||||
array = mock_array(2, f1, f2);
|
||||
if (!array)
|
||||
return -ENOMEM;
|
||||
|
@ -164,12 +170,16 @@ static int unwrap_chain(void *arg)
|
|||
if (!f1)
|
||||
return -ENOMEM;
|
||||
|
||||
dma_fence_enable_sw_signaling(f1);
|
||||
|
||||
f2 = mock_fence();
|
||||
if (!f2) {
|
||||
dma_fence_put(f1);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
dma_fence_enable_sw_signaling(f2);
|
||||
|
||||
chain = mock_chain(f1, f2);
|
||||
if (!chain)
|
||||
return -ENOMEM;
|
||||
|
@ -204,12 +214,16 @@ static int unwrap_chain_array(void *arg)
|
|||
if (!f1)
|
||||
return -ENOMEM;
|
||||
|
||||
dma_fence_enable_sw_signaling(f1);
|
||||
|
||||
f2 = mock_fence();
|
||||
if (!f2) {
|
||||
dma_fence_put(f1);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
dma_fence_enable_sw_signaling(f2);
|
||||
|
||||
array = mock_array(2, f1, f2);
|
||||
if (!array)
|
||||
return -ENOMEM;
|
||||
|
@ -248,12 +262,16 @@ static int unwrap_merge(void *arg)
|
|||
if (!f1)
|
||||
return -ENOMEM;
|
||||
|
||||
dma_fence_enable_sw_signaling(f1);
|
||||
|
||||
f2 = mock_fence();
|
||||
if (!f2) {
|
||||
err = -ENOMEM;
|
||||
goto error_put_f1;
|
||||
}
|
||||
|
||||
dma_fence_enable_sw_signaling(f2);
|
||||
|
||||
f3 = dma_fence_unwrap_merge(f1, f2);
|
||||
if (!f3) {
|
||||
err = -ENOMEM;
|
||||
|
@ -296,10 +314,14 @@ static int unwrap_merge_complex(void *arg)
|
|||
if (!f1)
|
||||
return -ENOMEM;
|
||||
|
||||
dma_fence_enable_sw_signaling(f1);
|
||||
|
||||
f2 = mock_fence();
|
||||
if (!f2)
|
||||
goto error_put_f1;
|
||||
|
||||
dma_fence_enable_sw_signaling(f2);
|
||||
|
||||
f3 = dma_fence_unwrap_merge(f1, f2);
|
||||
if (!f3)
|
||||
goto error_put_f2;
|
||||
|
|
|
@ -102,6 +102,8 @@ static int sanitycheck(void *arg)
|
|||
if (!f)
|
||||
return -ENOMEM;
|
||||
|
||||
dma_fence_enable_sw_signaling(f);
|
||||
|
||||
dma_fence_signal(f);
|
||||
dma_fence_put(f);
|
||||
|
||||
|
@ -117,6 +119,8 @@ static int test_signaling(void *arg)
|
|||
if (!f)
|
||||
return -ENOMEM;
|
||||
|
||||
dma_fence_enable_sw_signaling(f);
|
||||
|
||||
if (dma_fence_is_signaled(f)) {
|
||||
pr_err("Fence unexpectedly signaled on creation\n");
|
||||
goto err_free;
|
||||
|
@ -190,6 +194,8 @@ static int test_late_add_callback(void *arg)
|
|||
if (!f)
|
||||
return -ENOMEM;
|
||||
|
||||
dma_fence_enable_sw_signaling(f);
|
||||
|
||||
dma_fence_signal(f);
|
||||
|
||||
if (!dma_fence_add_callback(f, &cb.cb, simple_callback)) {
|
||||
|
@ -282,6 +288,8 @@ static int test_status(void *arg)
|
|||
if (!f)
|
||||
return -ENOMEM;
|
||||
|
||||
dma_fence_enable_sw_signaling(f);
|
||||
|
||||
if (dma_fence_get_status(f)) {
|
||||
pr_err("Fence unexpectedly has signaled status on creation\n");
|
||||
goto err_free;
|
||||
|
@ -308,6 +316,8 @@ static int test_error(void *arg)
|
|||
if (!f)
|
||||
return -ENOMEM;
|
||||
|
||||
dma_fence_enable_sw_signaling(f);
|
||||
|
||||
dma_fence_set_error(f, -EIO);
|
||||
|
||||
if (dma_fence_get_status(f)) {
|
||||
|
@ -337,6 +347,8 @@ static int test_wait(void *arg)
|
|||
if (!f)
|
||||
return -ENOMEM;
|
||||
|
||||
dma_fence_enable_sw_signaling(f);
|
||||
|
||||
if (dma_fence_wait_timeout(f, false, 0) != -ETIME) {
|
||||
pr_err("Wait reported complete before being signaled\n");
|
||||
goto err_free;
|
||||
|
@ -379,6 +391,8 @@ static int test_wait_timeout(void *arg)
|
|||
if (!wt.f)
|
||||
return -ENOMEM;
|
||||
|
||||
dma_fence_enable_sw_signaling(wt.f);
|
||||
|
||||
if (dma_fence_wait_timeout(wt.f, false, 1) != -ETIME) {
|
||||
pr_err("Wait reported complete before being signaled\n");
|
||||
goto err_free;
|
||||
|
@ -458,6 +472,8 @@ static int thread_signal_callback(void *arg)
|
|||
break;
|
||||
}
|
||||
|
||||
dma_fence_enable_sw_signaling(f1);
|
||||
|
||||
rcu_assign_pointer(t->fences[t->id], f1);
|
||||
smp_wmb();
|
||||
|
||||
|
|
|
@ -45,6 +45,8 @@ static int sanitycheck(void *arg)
|
|||
if (!f)
|
||||
return -ENOMEM;
|
||||
|
||||
dma_fence_enable_sw_signaling(f);
|
||||
|
||||
dma_fence_signal(f);
|
||||
dma_fence_put(f);
|
||||
|
||||
|
@ -69,6 +71,8 @@ static int test_signaling(void *arg)
|
|||
if (!f)
|
||||
return -ENOMEM;
|
||||
|
||||
dma_fence_enable_sw_signaling(f);
|
||||
|
||||
dma_resv_init(&resv);
|
||||
r = dma_resv_lock(&resv, NULL);
|
||||
if (r) {
|
||||
|
@ -114,6 +118,8 @@ static int test_for_each(void *arg)
|
|||
if (!f)
|
||||
return -ENOMEM;
|
||||
|
||||
dma_fence_enable_sw_signaling(f);
|
||||
|
||||
dma_resv_init(&resv);
|
||||
r = dma_resv_lock(&resv, NULL);
|
||||
if (r) {
|
||||
|
@ -173,6 +179,8 @@ static int test_for_each_unlocked(void *arg)
|
|||
if (!f)
|
||||
return -ENOMEM;
|
||||
|
||||
dma_fence_enable_sw_signaling(f);
|
||||
|
||||
dma_resv_init(&resv);
|
||||
r = dma_resv_lock(&resv, NULL);
|
||||
if (r) {
|
||||
|
@ -244,6 +252,8 @@ static int test_get_fences(void *arg)
|
|||
if (!f)
|
||||
return -ENOMEM;
|
||||
|
||||
dma_fence_enable_sw_signaling(f);
|
||||
|
||||
dma_resv_init(&resv);
|
||||
r = dma_resv_lock(&resv, NULL);
|
||||
if (r) {
|
||||
|
|
|
@ -235,6 +235,13 @@ config DRM_RADEON
|
|||
select HWMON
|
||||
select BACKLIGHT_CLASS_DEVICE
|
||||
select INTERVAL_TREE
|
||||
# radeon depends on ACPI_VIDEO when ACPI is enabled, for select to work
|
||||
# ACPI_VIDEO's dependencies must also be selected.
|
||||
select INPUT if ACPI
|
||||
select ACPI_VIDEO if ACPI
|
||||
# On x86 ACPI_VIDEO also needs ACPI_WMI
|
||||
select X86_PLATFORM_DEVICES if ACPI && X86
|
||||
select ACPI_WMI if ACPI && X86
|
||||
help
|
||||
Choose this option if you have an ATI Radeon graphics card. There
|
||||
are both PCI and AGP versions. You don't need to choose this to
|
||||
|
@ -260,6 +267,13 @@ config DRM_AMDGPU
|
|||
select BACKLIGHT_CLASS_DEVICE
|
||||
select INTERVAL_TREE
|
||||
select DRM_BUDDY
|
||||
# amdgpu depends on ACPI_VIDEO when ACPI is enabled, for select to work
|
||||
# ACPI_VIDEO's dependencies must also be selected.
|
||||
select INPUT if ACPI
|
||||
select ACPI_VIDEO if ACPI
|
||||
# On x86 ACPI_VIDEO also needs ACPI_WMI
|
||||
select X86_PLATFORM_DEVICES if ACPI && X86
|
||||
select ACPI_WMI if ACPI && X86
|
||||
help
|
||||
Choose this option if you have a recent AMD Radeon graphics card.
|
||||
|
||||
|
|
|
@ -746,7 +746,7 @@ static bool amdgpu_vram_mgr_intersects(struct ttm_resource_manager *man,
|
|||
(amdgpu_vram_mgr_block_size(block) >> PAGE_SHIFT);
|
||||
|
||||
if (place->fpfn < lpfn &&
|
||||
(place->lpfn && place->lpfn > fpfn))
|
||||
(!place->lpfn || place->lpfn > fpfn))
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -26,6 +26,8 @@
|
|||
|
||||
#include <linux/pci.h>
|
||||
|
||||
#include <acpi/video.h>
|
||||
|
||||
#include <drm/drm_crtc_helper.h>
|
||||
#include <drm/amdgpu_drm.h>
|
||||
#include "amdgpu.h"
|
||||
|
@ -182,7 +184,12 @@ void amdgpu_atombios_encoder_init_backlight(struct amdgpu_encoder *amdgpu_encode
|
|||
return;
|
||||
|
||||
if (!(adev->mode_info.firmware_flags & ATOM_BIOS_INFO_BL_CONTROLLED_BY_GPU))
|
||||
return;
|
||||
goto register_acpi_backlight;
|
||||
|
||||
if (!acpi_video_backlight_use_native()) {
|
||||
drm_info(dev, "Skipping amdgpu atom DIG backlight registration\n");
|
||||
goto register_acpi_backlight;
|
||||
}
|
||||
|
||||
pdata = kmalloc(sizeof(struct amdgpu_backlight_privdata), GFP_KERNEL);
|
||||
if (!pdata) {
|
||||
|
@ -218,6 +225,11 @@ void amdgpu_atombios_encoder_init_backlight(struct amdgpu_encoder *amdgpu_encode
|
|||
error:
|
||||
kfree(pdata);
|
||||
return;
|
||||
|
||||
register_acpi_backlight:
|
||||
/* Try registering an ACPI video backlight device instead. */
|
||||
acpi_video_register_backlight();
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -90,6 +90,8 @@
|
|||
#include <drm/drm_gem_atomic_helper.h>
|
||||
#include <drm/drm_plane_helper.h>
|
||||
|
||||
#include <acpi/video.h>
|
||||
|
||||
#include "ivsrcid/dcn/irqsrcs_dcn_1_0.h"
|
||||
|
||||
#include "dcn/dcn_1_0_offset.h"
|
||||
|
@ -4038,6 +4040,13 @@ amdgpu_dm_register_backlight_device(struct amdgpu_display_manager *dm)
|
|||
amdgpu_dm_update_backlight_caps(dm, dm->num_of_edps);
|
||||
dm->brightness[dm->num_of_edps] = AMDGPU_MAX_BL_LEVEL;
|
||||
|
||||
if (!acpi_video_backlight_use_native()) {
|
||||
drm_info(adev_to_drm(dm->adev), "Skipping amdgpu DM backlight registration\n");
|
||||
/* Try registering an ACPI video backlight device instead. */
|
||||
acpi_video_register_backlight();
|
||||
return;
|
||||
}
|
||||
|
||||
props.max_brightness = AMDGPU_MAX_BL_LEVEL;
|
||||
props.brightness = AMDGPU_MAX_BL_LEVEL;
|
||||
props.type = BACKLIGHT_RAW;
|
||||
|
|
|
@ -401,8 +401,6 @@ extern int phm_powerdown_uvd(struct pp_hwmgr *hwmgr);
|
|||
extern int phm_setup_asic(struct pp_hwmgr *hwmgr);
|
||||
extern int phm_enable_dynamic_state_management(struct pp_hwmgr *hwmgr);
|
||||
extern int phm_disable_dynamic_state_management(struct pp_hwmgr *hwmgr);
|
||||
extern bool phm_is_hw_access_blocked(struct pp_hwmgr *hwmgr);
|
||||
extern int phm_block_hw_access(struct pp_hwmgr *hwmgr, bool block);
|
||||
extern int phm_set_power_state(struct pp_hwmgr *hwmgr,
|
||||
const struct pp_hw_power_state *pcurrent_state,
|
||||
const struct pp_hw_power_state *pnew_power_state);
|
||||
|
|
|
@ -113,6 +113,9 @@ static bool ast_get_vbios_mode_info(const struct drm_format_info *format,
|
|||
case 1024:
|
||||
vbios_mode->enh_table = &res_1024x768[refresh_rate_index];
|
||||
break;
|
||||
case 1152:
|
||||
vbios_mode->enh_table = &res_1152x864[refresh_rate_index];
|
||||
break;
|
||||
case 1280:
|
||||
if (mode->crtc_vdisplay == 800)
|
||||
vbios_mode->enh_table = &res_1280x800[refresh_rate_index];
|
||||
|
@ -310,7 +313,7 @@ static void ast_set_crtc_reg(struct ast_private *ast,
|
|||
u8 jreg05 = 0, jreg07 = 0, jreg09 = 0, jregAC = 0, jregAD = 0, jregAE = 0;
|
||||
u16 temp, precache = 0;
|
||||
|
||||
if ((ast->chip == AST2500) &&
|
||||
if ((ast->chip == AST2500 || ast->chip == AST2600) &&
|
||||
(vbios_mode->enh_table->flags & AST2500PreCatchCRT))
|
||||
precache = 40;
|
||||
|
||||
|
@ -351,6 +354,12 @@ static void ast_set_crtc_reg(struct ast_private *ast,
|
|||
ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xAC, 0x00, jregAC);
|
||||
ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xAD, 0x00, jregAD);
|
||||
|
||||
// Workaround for HSync Time non octave pixels (1920x1080@60Hz HSync 44 pixels);
|
||||
if ((ast->chip == AST2600) && (mode->crtc_vdisplay == 1080))
|
||||
ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xFC, 0xFD, 0x02);
|
||||
else
|
||||
ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xFC, 0xFD, 0x00);
|
||||
|
||||
/* vert timings */
|
||||
temp = (mode->crtc_vtotal) - 2;
|
||||
if (temp & 0x100)
|
||||
|
@ -428,7 +437,7 @@ static void ast_set_dclk_reg(struct ast_private *ast,
|
|||
{
|
||||
const struct ast_vbios_dclk_info *clk_info;
|
||||
|
||||
if (ast->chip == AST2500)
|
||||
if ((ast->chip == AST2500) || (ast->chip == AST2600))
|
||||
clk_info = &dclk_table_ast2500[vbios_mode->enh_table->dclk_index];
|
||||
else
|
||||
clk_info = &dclk_table[vbios_mode->enh_table->dclk_index];
|
||||
|
@ -1057,6 +1066,8 @@ ast_crtc_helper_mode_valid(struct drm_crtc *crtc, const struct drm_display_mode
|
|||
return MODE_OK;
|
||||
if ((mode->hdisplay == 1600) && (mode->vdisplay == 900))
|
||||
return MODE_OK;
|
||||
if ((mode->hdisplay == 1152) && (mode->vdisplay == 864))
|
||||
return MODE_OK;
|
||||
|
||||
if ((ast->chip == AST2100) || (ast->chip == AST2200) ||
|
||||
(ast->chip == AST2300) || (ast->chip == AST2400) ||
|
||||
|
@ -1089,6 +1100,10 @@ ast_crtc_helper_mode_valid(struct drm_crtc *crtc, const struct drm_display_mode
|
|||
if (mode->vdisplay == 768)
|
||||
status = MODE_OK;
|
||||
break;
|
||||
case 1152:
|
||||
if (mode->vdisplay == 864)
|
||||
status = MODE_OK;
|
||||
break;
|
||||
case 1280:
|
||||
if (mode->vdisplay == 1024)
|
||||
status = MODE_OK;
|
||||
|
|
|
@ -272,6 +272,13 @@ static const struct ast_vbios_enhtable res_1600x1200[] = {
|
|||
(SyncPP | Charx8Dot), 0xFF, 1, 0x33 },
|
||||
};
|
||||
|
||||
static const struct ast_vbios_enhtable res_1152x864[] = {
|
||||
{1600, 1152, 64, 128, 900, 864, 1, 3, VCLK108, /* 75Hz */
|
||||
(SyncPP | Charx8Dot | NewModeInfo), 75, 1, 0x3B },
|
||||
{1600, 1152, 64, 128, 900, 864, 1, 3, VCLK108, /* end */
|
||||
(SyncPP | Charx8Dot | NewModeInfo), 0xFF, 1, 0x3B },
|
||||
};
|
||||
|
||||
/* 16:9 */
|
||||
static const struct ast_vbios_enhtable res_1360x768[] = {
|
||||
{1792, 1360, 64, 112, 795, 768, 3, 6, VCLK85_5, /* 60Hz */
|
||||
|
|
|
@ -68,7 +68,6 @@ enum {
|
|||
BYTE_SWAP_GBR = 3,
|
||||
BYTE_SWAP_BRG = 4,
|
||||
BYTE_SWAP_BGR = 5,
|
||||
BYTE_SWAP_MAX = 6,
|
||||
};
|
||||
|
||||
/* Page 0, Register 0x19 */
|
||||
|
@ -356,8 +355,6 @@ static void ch7033_bridge_mode_set(struct drm_bridge *bridge,
|
|||
int hsynclen = mode->hsync_end - mode->hsync_start;
|
||||
int vbporch = mode->vsync_start - mode->vdisplay;
|
||||
int vsynclen = mode->vsync_end - mode->vsync_start;
|
||||
u8 byte_swap;
|
||||
int ret;
|
||||
|
||||
/*
|
||||
* Page 4
|
||||
|
@ -401,16 +398,8 @@ static void ch7033_bridge_mode_set(struct drm_bridge *bridge,
|
|||
regmap_write(priv->regmap, 0x15, vbporch);
|
||||
regmap_write(priv->regmap, 0x16, vsynclen);
|
||||
|
||||
/* Input color swap. Byte order is optional and will default to
|
||||
* BYTE_SWAP_BGR to preserve backwards compatibility with existing
|
||||
* driver.
|
||||
*/
|
||||
ret = of_property_read_u8(priv->bridge.of_node, "chrontel,byteswap",
|
||||
&byte_swap);
|
||||
if (!ret && byte_swap < BYTE_SWAP_MAX)
|
||||
regmap_update_bits(priv->regmap, 0x18, SWAP, byte_swap);
|
||||
else
|
||||
regmap_update_bits(priv->regmap, 0x18, SWAP, BYTE_SWAP_BGR);
|
||||
/* Input color swap. */
|
||||
regmap_update_bits(priv->regmap, 0x18, SWAP, BYTE_SWAP_BGR);
|
||||
|
||||
/* Input clock and sync polarity. */
|
||||
regmap_update_bits(priv->regmap, 0x19, 0x1, mode->clock >> 16);
|
||||
|
|
|
@ -563,7 +563,7 @@ static void it6505_debug_print(struct it6505 *it6505, unsigned int reg,
|
|||
struct device *dev = &it6505->client->dev;
|
||||
int val;
|
||||
|
||||
if (likely(!(__drm_debug & DRM_UT_DRIVER)))
|
||||
if (!drm_debug_enabled(DRM_UT_DRIVER))
|
||||
return;
|
||||
|
||||
val = it6505_read(it6505, reg);
|
||||
|
|
|
@ -542,8 +542,8 @@ static int snd_dw_hdmi_probe(struct platform_device *pdev)
|
|||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
strlcpy(card->driver, DRIVER_NAME, sizeof(card->driver));
|
||||
strlcpy(card->shortname, "DW-HDMI", sizeof(card->shortname));
|
||||
strscpy(card->driver, DRIVER_NAME, sizeof(card->driver));
|
||||
strscpy(card->shortname, "DW-HDMI", sizeof(card->shortname));
|
||||
snprintf(card->longname, sizeof(card->longname),
|
||||
"%s rev 0x%02x, irq %d", card->shortname, revision,
|
||||
data->irq);
|
||||
|
@ -561,7 +561,7 @@ static int snd_dw_hdmi_probe(struct platform_device *pdev)
|
|||
|
||||
dw->pcm = pcm;
|
||||
pcm->private_data = dw;
|
||||
strlcpy(pcm->name, DRIVER_NAME, sizeof(pcm->name));
|
||||
strscpy(pcm->name, DRIVER_NAME, sizeof(pcm->name));
|
||||
snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_dw_hdmi_ops);
|
||||
|
||||
/*
|
||||
|
|
|
@ -35,6 +35,19 @@
|
|||
* HDMI 2.0 specification. It is a point-to-point protocol that allows the
|
||||
* HDMI source and HDMI sink to exchange data. The same I2C interface that
|
||||
* is used to access EDID serves as the transport mechanism for SCDC.
|
||||
*
|
||||
* Note: The SCDC status is going to be lost when the display is
|
||||
* disconnected. This can happen physically when the user disconnects
|
||||
* the cable, but also when a display is switched on (such as waking up
|
||||
* a TV).
|
||||
*
|
||||
* This is further complicated by the fact that, upon a disconnection /
|
||||
* reconnection, KMS won't change the mode on its own. This means that
|
||||
* one can't just rely on setting the SCDC status on enable, but also
|
||||
* has to track the connector status changes using interrupts and
|
||||
* restore the SCDC status. The typical solution for this is to trigger an
|
||||
* empty modeset in drm_connector_helper_funcs.detect_ctx(), like what vc4 does
|
||||
* in vc4_hdmi_reset_link().
|
||||
*/
|
||||
|
||||
#define SCDC_I2C_SLAVE_ADDRESS 0x54
|
||||
|
|
|
@ -74,7 +74,7 @@
|
|||
* given framebuffer memory. Ownership of the framebuffer memory is achieved
|
||||
* by calling devm_aperture_acquire_from_firmware(). On success, the driver
|
||||
* is the owner of the framebuffer range. The function fails if the
|
||||
* framebuffer is already by another driver. See below for an example.
|
||||
* framebuffer is already owned by another driver. See below for an example.
|
||||
*
|
||||
* .. code-block:: c
|
||||
*
|
||||
|
@ -112,7 +112,7 @@
|
|||
*
|
||||
* The generic driver is now subject to forced removal by other drivers. This
|
||||
* only works for platform drivers that support hot unplug.
|
||||
* When a driver calls drm_aperture_remove_conflicting_framebuffers() et al
|
||||
* When a driver calls drm_aperture_remove_conflicting_framebuffers() et al.
|
||||
* for the registered framebuffer range, the aperture helpers call
|
||||
* platform_device_unregister() and the generic driver unloads itself. It
|
||||
* may not access the device's registers, framebuffer memory, ROM, etc
|
||||
|
@ -164,7 +164,7 @@ EXPORT_SYMBOL(devm_aperture_acquire_from_firmware);
|
|||
* @primary: also kick vga16fb if present
|
||||
* @req_driver: requesting DRM driver
|
||||
*
|
||||
* This function removes graphics device drivers which use memory range described by
|
||||
* This function removes graphics device drivers which use the memory range described by
|
||||
* @base and @size.
|
||||
*
|
||||
* Returns:
|
||||
|
@ -182,8 +182,8 @@ EXPORT_SYMBOL(drm_aperture_remove_conflicting_framebuffers);
|
|||
* @pdev: PCI device
|
||||
* @req_driver: requesting DRM driver
|
||||
*
|
||||
* This function removes graphics device drivers using memory range configured
|
||||
* for any of @pdev's memory bars. The function assumes that PCI device with
|
||||
* This function removes graphics device drivers using the memory range configured
|
||||
* for any of @pdev's memory bars. The function assumes that a PCI device with
|
||||
* shadowed ROM drives a primary display and so kicks out vga16fb.
|
||||
*
|
||||
* Returns:
|
||||
|
|
|
@ -786,7 +786,7 @@ drm_atomic_helper_check_modeset(struct drm_device *dev,
|
|||
EXPORT_SYMBOL(drm_atomic_helper_check_modeset);
|
||||
|
||||
/**
|
||||
* drm_atomic_helper_check_wb_connector_state() - Check writeback encoder state
|
||||
* drm_atomic_helper_check_wb_encoder_state() - Check writeback encoder state
|
||||
* @encoder: encoder state to check
|
||||
* @conn_state: connector state to check
|
||||
*
|
||||
|
|
|
@ -224,6 +224,7 @@ drm_atomic_helper_damage_iter_init(struct drm_atomic_helper_damage_iter *iter,
|
|||
const struct drm_plane_state *old_state,
|
||||
const struct drm_plane_state *state)
|
||||
{
|
||||
struct drm_rect src;
|
||||
memset(iter, 0, sizeof(*iter));
|
||||
|
||||
if (!state || !state->crtc || !state->fb || !state->visible)
|
||||
|
@ -233,10 +234,12 @@ drm_atomic_helper_damage_iter_init(struct drm_atomic_helper_damage_iter *iter,
|
|||
iter->num_clips = drm_plane_get_damage_clips_count(state);
|
||||
|
||||
/* Round down for x1/y1 and round up for x2/y2 to catch all pixels */
|
||||
iter->plane_src.x1 = state->src.x1 >> 16;
|
||||
iter->plane_src.y1 = state->src.y1 >> 16;
|
||||
iter->plane_src.x2 = (state->src.x2 >> 16) + !!(state->src.x2 & 0xFFFF);
|
||||
iter->plane_src.y2 = (state->src.y2 >> 16) + !!(state->src.y2 & 0xFFFF);
|
||||
src = drm_plane_state_src(state);
|
||||
|
||||
iter->plane_src.x1 = src.x1 >> 16;
|
||||
iter->plane_src.y1 = src.y1 >> 16;
|
||||
iter->plane_src.x2 = (src.x2 >> 16) + !!(src.x2 & 0xFFFF);
|
||||
iter->plane_src.y2 = (src.y2 >> 16) + !!(src.y2 & 0xFFFF);
|
||||
|
||||
if (!iter->clips || !drm_rect_equals(&state->src, &old_state->src)) {
|
||||
iter->clips = NULL;
|
||||
|
|
|
@ -793,3 +793,111 @@ void drm_fb_xrgb8888_to_mono(struct iosys_map *dst, const unsigned int *dst_pitc
|
|||
kfree(src32);
|
||||
}
|
||||
EXPORT_SYMBOL(drm_fb_xrgb8888_to_mono);
|
||||
|
||||
static bool is_listed_fourcc(const uint32_t *fourccs, size_t nfourccs, uint32_t fourcc)
|
||||
{
|
||||
const uint32_t *fourccs_end = fourccs + nfourccs;
|
||||
|
||||
while (fourccs < fourccs_end) {
|
||||
if (*fourccs == fourcc)
|
||||
return true;
|
||||
++fourccs;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* drm_fb_build_fourcc_list - Filters a list of supported color formats against
|
||||
* the device's native formats
|
||||
* @dev: DRM device
|
||||
* @native_fourccs: 4CC codes of natively supported color formats
|
||||
* @native_nfourccs: The number of entries in @native_fourccs
|
||||
* @driver_fourccs: 4CC codes of all driver-supported color formats
|
||||
* @driver_nfourccs: The number of entries in @driver_fourccs
|
||||
* @fourccs_out: Returns 4CC codes of supported color formats
|
||||
* @nfourccs_out: The number of available entries in @fourccs_out
|
||||
*
|
||||
* This function create a list of supported color format from natively
|
||||
* supported formats and the emulated formats.
|
||||
* At a minimum, most userspace programs expect at least support for
|
||||
* XRGB8888 on the primary plane. Devices that have to emulate the
|
||||
* format, and possibly others, can use drm_fb_build_fourcc_list() to
|
||||
* create a list of supported color formats. The returned list can
|
||||
* be handed over to drm_universal_plane_init() et al. Native formats
|
||||
* will go before emulated formats. Other heuristics might be applied
|
||||
* to optimize the order. Formats near the beginning of the list are
|
||||
* usually preferred over formats near the end of the list.
|
||||
*
|
||||
* Returns:
|
||||
* The number of color-formats 4CC codes returned in @fourccs_out.
|
||||
*/
|
||||
size_t drm_fb_build_fourcc_list(struct drm_device *dev,
|
||||
const u32 *native_fourccs, size_t native_nfourccs,
|
||||
const u32 *driver_fourccs, size_t driver_nfourccs,
|
||||
u32 *fourccs_out, size_t nfourccs_out)
|
||||
{
|
||||
u32 *fourccs = fourccs_out;
|
||||
const u32 *fourccs_end = fourccs_out + nfourccs_out;
|
||||
bool found_native = false;
|
||||
size_t i;
|
||||
|
||||
/*
|
||||
* The device's native formats go first.
|
||||
*/
|
||||
|
||||
for (i = 0; i < native_nfourccs; ++i) {
|
||||
u32 fourcc = native_fourccs[i];
|
||||
|
||||
if (is_listed_fourcc(fourccs_out, fourccs - fourccs_out, fourcc)) {
|
||||
continue; /* skip duplicate entries */
|
||||
} else if (fourccs == fourccs_end) {
|
||||
drm_warn(dev, "Ignoring native format %p4cc\n", &fourcc);
|
||||
continue; /* end of available output buffer */
|
||||
}
|
||||
|
||||
drm_dbg_kms(dev, "adding native format %p4cc\n", &fourcc);
|
||||
|
||||
if (!found_native)
|
||||
found_native = is_listed_fourcc(driver_fourccs, driver_nfourccs, fourcc);
|
||||
*fourccs = fourcc;
|
||||
++fourccs;
|
||||
}
|
||||
|
||||
/*
|
||||
* The plane's atomic_update helper converts the framebuffer's color format
|
||||
* to a native format when copying to device memory.
|
||||
*
|
||||
* If there is not a single format supported by both, device and
|
||||
* driver, the native formats are likely not supported by the conversion
|
||||
* helpers. Therefore *only* support the native formats and add a
|
||||
* conversion helper ASAP.
|
||||
*/
|
||||
if (!found_native) {
|
||||
drm_warn(dev, "Format conversion helpers required to add extra formats.\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
/*
|
||||
* The extra formats, emulated by the driver, go second.
|
||||
*/
|
||||
|
||||
for (i = 0; (i < driver_nfourccs) && (fourccs < fourccs_end); ++i) {
|
||||
u32 fourcc = driver_fourccs[i];
|
||||
|
||||
if (is_listed_fourcc(fourccs_out, fourccs - fourccs_out, fourcc)) {
|
||||
continue; /* skip duplicate and native entries */
|
||||
} else if (fourccs == fourccs_end) {
|
||||
drm_warn(dev, "Ignoring emulated format %p4cc\n", &fourcc);
|
||||
continue; /* end of available output buffer */
|
||||
}
|
||||
|
||||
drm_dbg_kms(dev, "adding emulated format %p4cc\n", &fourcc);
|
||||
|
||||
*fourccs = fourcc;
|
||||
++fourccs;
|
||||
}
|
||||
|
||||
out:
|
||||
return fourccs - fourccs_out;
|
||||
}
|
||||
EXPORT_SYMBOL(drm_fb_build_fourcc_list);
|
||||
|
|
|
@ -309,6 +309,24 @@ err_drm_dev_exit:
|
|||
drm_dev_exit(idx);
|
||||
}
|
||||
|
||||
/**
|
||||
* mipi_dbi_pipe_mode_valid - MIPI DBI mode-valid helper
|
||||
* @pipe: Simple display pipe
|
||||
* @mode: The mode to test
|
||||
*
|
||||
* This function validates a given display mode against the MIPI DBI's hardware
|
||||
* display. Drivers can use this as their &drm_simple_display_pipe_funcs->mode_valid
|
||||
* callback.
|
||||
*/
|
||||
enum drm_mode_status mipi_dbi_pipe_mode_valid(struct drm_simple_display_pipe *pipe,
|
||||
const struct drm_display_mode *mode)
|
||||
{
|
||||
struct mipi_dbi_dev *dbidev = drm_to_mipi_dbi_dev(pipe->crtc.dev);
|
||||
|
||||
return drm_crtc_helper_mode_valid_fixed(&pipe->crtc, mode, &dbidev->mode);
|
||||
}
|
||||
EXPORT_SYMBOL(mipi_dbi_pipe_mode_valid);
|
||||
|
||||
/**
|
||||
* mipi_dbi_pipe_update - Display pipe update helper
|
||||
* @pipe: Simple display pipe
|
||||
|
@ -415,26 +433,8 @@ EXPORT_SYMBOL(mipi_dbi_pipe_disable);
|
|||
static int mipi_dbi_connector_get_modes(struct drm_connector *connector)
|
||||
{
|
||||
struct mipi_dbi_dev *dbidev = drm_to_mipi_dbi_dev(connector->dev);
|
||||
struct drm_display_mode *mode;
|
||||
|
||||
mode = drm_mode_duplicate(connector->dev, &dbidev->mode);
|
||||
if (!mode) {
|
||||
DRM_ERROR("Failed to duplicate mode\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (mode->name[0] == '\0')
|
||||
drm_mode_set_name(mode);
|
||||
|
||||
mode->type |= DRM_MODE_TYPE_PREFERRED;
|
||||
drm_mode_probed_add(connector, mode);
|
||||
|
||||
if (mode->width_mm) {
|
||||
connector->display_info.width_mm = mode->width_mm;
|
||||
connector->display_info.height_mm = mode->height_mm;
|
||||
}
|
||||
|
||||
return 1;
|
||||
return drm_connector_helper_get_modes_fixed(connector, &dbidev->mode);
|
||||
}
|
||||
|
||||
static const struct drm_connector_helper_funcs mipi_dbi_connector_hfuncs = {
|
||||
|
|
|
@ -100,8 +100,7 @@ EXPORT_SYMBOL(drm_helper_mode_fill_fb_struct);
|
|||
* This is the minimal list of formats that seem to be safe for modeset use
|
||||
* with all current DRM drivers. Most hardware can actually support more
|
||||
* formats than this and drivers may specify a more accurate list when
|
||||
* creating the primary plane. However drivers that still call
|
||||
* drm_plane_init() will use this minimal format list as the default.
|
||||
* creating the primary plane.
|
||||
*/
|
||||
static const uint32_t safe_modeset_formats[] = {
|
||||
DRM_FORMAT_XRGB8888,
|
||||
|
@ -109,43 +108,9 @@ static const uint32_t safe_modeset_formats[] = {
|
|||
};
|
||||
|
||||
static const struct drm_plane_funcs primary_plane_funcs = {
|
||||
.update_plane = drm_plane_helper_update_primary,
|
||||
.disable_plane = drm_plane_helper_disable_primary,
|
||||
.destroy = drm_plane_helper_destroy,
|
||||
DRM_PLANE_NON_ATOMIC_FUNCS,
|
||||
};
|
||||
|
||||
static struct drm_plane *create_primary_plane(struct drm_device *dev)
|
||||
{
|
||||
struct drm_plane *primary;
|
||||
int ret;
|
||||
|
||||
primary = kzalloc(sizeof(*primary), GFP_KERNEL);
|
||||
if (primary == NULL) {
|
||||
DRM_DEBUG_KMS("Failed to allocate primary plane\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Remove the format_default field from drm_plane when dropping
|
||||
* this helper.
|
||||
*/
|
||||
primary->format_default = true;
|
||||
|
||||
/* possible_crtc's will be filled in later by crtc_init */
|
||||
ret = drm_universal_plane_init(dev, primary, 0,
|
||||
&primary_plane_funcs,
|
||||
safe_modeset_formats,
|
||||
ARRAY_SIZE(safe_modeset_formats),
|
||||
NULL,
|
||||
DRM_PLANE_TYPE_PRIMARY, NULL);
|
||||
if (ret) {
|
||||
kfree(primary);
|
||||
primary = NULL;
|
||||
}
|
||||
|
||||
return primary;
|
||||
}
|
||||
|
||||
/**
|
||||
* drm_crtc_init - Legacy CRTC initialization function
|
||||
* @dev: DRM device
|
||||
|
@ -177,10 +142,33 @@ int drm_crtc_init(struct drm_device *dev, struct drm_crtc *crtc,
|
|||
const struct drm_crtc_funcs *funcs)
|
||||
{
|
||||
struct drm_plane *primary;
|
||||
int ret;
|
||||
|
||||
primary = create_primary_plane(dev);
|
||||
return drm_crtc_init_with_planes(dev, crtc, primary, NULL, funcs,
|
||||
NULL);
|
||||
/* possible_crtc's will be filled in later by crtc_init */
|
||||
primary = __drm_universal_plane_alloc(dev, sizeof(*primary), 0, 0,
|
||||
&primary_plane_funcs,
|
||||
safe_modeset_formats,
|
||||
ARRAY_SIZE(safe_modeset_formats),
|
||||
NULL, DRM_PLANE_TYPE_PRIMARY, NULL);
|
||||
if (IS_ERR(primary))
|
||||
return PTR_ERR(primary);
|
||||
|
||||
/*
|
||||
* Remove the format_default field from drm_plane when dropping
|
||||
* this helper.
|
||||
*/
|
||||
primary->format_default = true;
|
||||
|
||||
ret = drm_crtc_init_with_planes(dev, crtc, primary, NULL, funcs, NULL);
|
||||
if (ret)
|
||||
goto err_drm_plane_cleanup;
|
||||
|
||||
return 0;
|
||||
|
||||
err_drm_plane_cleanup:
|
||||
drm_plane_cleanup(primary);
|
||||
kfree(primary);
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL(drm_crtc_init);
|
||||
|
||||
|
|
|
@ -103,6 +103,12 @@ static const struct drm_dmi_panel_orientation_data lcd800x1280_rightside_up = {
|
|||
.orientation = DRM_MODE_PANEL_ORIENTATION_RIGHT_UP,
|
||||
};
|
||||
|
||||
static const struct drm_dmi_panel_orientation_data lcd1080x1920_leftside_up = {
|
||||
.width = 1080,
|
||||
.height = 1920,
|
||||
.orientation = DRM_MODE_PANEL_ORIENTATION_LEFT_UP,
|
||||
};
|
||||
|
||||
static const struct drm_dmi_panel_orientation_data lcd1200x1920_rightside_up = {
|
||||
.width = 1200,
|
||||
.height = 1920,
|
||||
|
@ -128,6 +134,12 @@ static const struct dmi_system_id orientation_data[] = {
|
|||
DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "One S1003"),
|
||||
},
|
||||
.driver_data = (void *)&lcd800x1280_rightside_up,
|
||||
}, { /* Anbernic Win600 */
|
||||
.matches = {
|
||||
DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "Anbernic"),
|
||||
DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Win600"),
|
||||
},
|
||||
.driver_data = (void *)&lcd720x1280_rightside_up,
|
||||
}, { /* Asus T100HA */
|
||||
.matches = {
|
||||
DMI_EXACT_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
|
||||
|
@ -152,6 +164,12 @@ static const struct dmi_system_id orientation_data[] = {
|
|||
DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "AYA NEO 2021"),
|
||||
},
|
||||
.driver_data = (void *)&lcd800x1280_rightside_up,
|
||||
}, { /* AYA NEO AIR */
|
||||
.matches = {
|
||||
DMI_EXACT_MATCH(DMI_SYS_VENDOR, "AYANEO"),
|
||||
DMI_MATCH(DMI_BOARD_NAME, "AIR"),
|
||||
},
|
||||
.driver_data = (void *)&lcd1080x1920_leftside_up,
|
||||
}, { /* AYA NEO NEXT */
|
||||
.matches = {
|
||||
DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "AYANEO"),
|
||||
|
|
|
@ -448,6 +448,44 @@ void *__drmm_universal_plane_alloc(struct drm_device *dev, size_t size,
|
|||
}
|
||||
EXPORT_SYMBOL(__drmm_universal_plane_alloc);
|
||||
|
||||
void *__drm_universal_plane_alloc(struct drm_device *dev, size_t size,
|
||||
size_t offset, uint32_t possible_crtcs,
|
||||
const struct drm_plane_funcs *funcs,
|
||||
const uint32_t *formats, unsigned int format_count,
|
||||
const uint64_t *format_modifiers,
|
||||
enum drm_plane_type type,
|
||||
const char *name, ...)
|
||||
{
|
||||
void *container;
|
||||
struct drm_plane *plane;
|
||||
va_list ap;
|
||||
int ret;
|
||||
|
||||
if (drm_WARN_ON(dev, !funcs))
|
||||
return ERR_PTR(-EINVAL);
|
||||
|
||||
container = kzalloc(size, GFP_KERNEL);
|
||||
if (!container)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
plane = container + offset;
|
||||
|
||||
va_start(ap, name);
|
||||
ret = __drm_universal_plane_init(dev, plane, possible_crtcs, funcs,
|
||||
formats, format_count, format_modifiers,
|
||||
type, name, ap);
|
||||
va_end(ap);
|
||||
if (ret)
|
||||
goto err_kfree;
|
||||
|
||||
return container;
|
||||
|
||||
err_kfree:
|
||||
kfree(container);
|
||||
return ERR_PTR(ret);
|
||||
}
|
||||
EXPORT_SYMBOL(__drm_universal_plane_alloc);
|
||||
|
||||
int drm_plane_register_all(struct drm_device *dev)
|
||||
{
|
||||
unsigned int num_planes = 0;
|
||||
|
@ -482,38 +520,6 @@ void drm_plane_unregister_all(struct drm_device *dev)
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* drm_plane_init - Initialize a legacy plane
|
||||
* @dev: DRM device
|
||||
* @plane: plane object to init
|
||||
* @possible_crtcs: bitmask of possible CRTCs
|
||||
* @funcs: callbacks for the new plane
|
||||
* @formats: array of supported formats (DRM_FORMAT\_\*)
|
||||
* @format_count: number of elements in @formats
|
||||
* @is_primary: plane type (primary vs overlay)
|
||||
*
|
||||
* Legacy API to initialize a DRM plane.
|
||||
*
|
||||
* New drivers should call drm_universal_plane_init() instead.
|
||||
*
|
||||
* Returns:
|
||||
* Zero on success, error code on failure.
|
||||
*/
|
||||
int drm_plane_init(struct drm_device *dev, struct drm_plane *plane,
|
||||
uint32_t possible_crtcs,
|
||||
const struct drm_plane_funcs *funcs,
|
||||
const uint32_t *formats, unsigned int format_count,
|
||||
bool is_primary)
|
||||
{
|
||||
enum drm_plane_type type;
|
||||
|
||||
type = is_primary ? DRM_PLANE_TYPE_PRIMARY : DRM_PLANE_TYPE_OVERLAY;
|
||||
return drm_universal_plane_init(dev, plane, possible_crtcs, funcs,
|
||||
formats, format_count,
|
||||
NULL, type, NULL);
|
||||
}
|
||||
EXPORT_SYMBOL(drm_plane_init);
|
||||
|
||||
/**
|
||||
* drm_plane_cleanup - Clean up the core plane usage
|
||||
* @plane: plane to cleanup
|
||||
|
|
|
@ -30,8 +30,10 @@
|
|||
#include <drm/drm_atomic_uapi.h>
|
||||
#include <drm/drm_crtc_helper.h>
|
||||
#include <drm/drm_device.h>
|
||||
#include <drm/drm_drv.h>
|
||||
#include <drm/drm_encoder.h>
|
||||
#include <drm/drm_plane_helper.h>
|
||||
#include <drm/drm_print.h>
|
||||
#include <drm/drm_rect.h>
|
||||
|
||||
#define SUBPIXEL_MASK 0xffff
|
||||
|
@ -195,10 +197,14 @@ int drm_plane_helper_update_primary(struct drm_plane *plane, struct drm_crtc *cr
|
|||
.x2 = crtc_x + crtc_w,
|
||||
.y2 = crtc_y + crtc_h,
|
||||
};
|
||||
struct drm_device *dev = plane->dev;
|
||||
struct drm_connector **connector_list;
|
||||
int num_connectors, ret;
|
||||
bool visible;
|
||||
|
||||
if (drm_WARN_ON_ONCE(dev, drm_drv_uses_atomic_modeset(dev)))
|
||||
return -EINVAL;
|
||||
|
||||
ret = drm_plane_helper_check_update(plane, crtc, fb,
|
||||
&src, &dest,
|
||||
DRM_MODE_ROTATE_0,
|
||||
|
@ -260,6 +266,10 @@ EXPORT_SYMBOL(drm_plane_helper_update_primary);
|
|||
int drm_plane_helper_disable_primary(struct drm_plane *plane,
|
||||
struct drm_modeset_acquire_ctx *ctx)
|
||||
{
|
||||
struct drm_device *dev = plane->dev;
|
||||
|
||||
drm_WARN_ON_ONCE(dev, drm_drv_uses_atomic_modeset(dev));
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
EXPORT_SYMBOL(drm_plane_helper_disable_primary);
|
||||
|
@ -278,3 +288,33 @@ void drm_plane_helper_destroy(struct drm_plane *plane)
|
|||
kfree(plane);
|
||||
}
|
||||
EXPORT_SYMBOL(drm_plane_helper_destroy);
|
||||
|
||||
/**
|
||||
* drm_plane_helper_atomic_check() - Helper to check plane atomic-state
|
||||
* @plane: plane to check
|
||||
* @state: atomic state object
|
||||
*
|
||||
* Provides a default plane-state check handler for planes whose atomic-state
|
||||
* scale and positioning are not expected to change since the plane is always
|
||||
* a fullscreen scanout buffer.
|
||||
*
|
||||
* This is often the case for the primary plane of simple framebuffers.
|
||||
*
|
||||
* RETURNS:
|
||||
* Zero on success, or an errno code otherwise.
|
||||
*/
|
||||
int drm_plane_helper_atomic_check(struct drm_plane *plane, struct drm_atomic_state *state)
|
||||
{
|
||||
struct drm_plane_state *new_plane_state = drm_atomic_get_new_plane_state(state, plane);
|
||||
struct drm_crtc *new_crtc = new_plane_state->crtc;
|
||||
struct drm_crtc_state *new_crtc_state = NULL;
|
||||
|
||||
if (new_crtc)
|
||||
new_crtc_state = drm_atomic_get_new_crtc_state(state, new_crtc);
|
||||
|
||||
return drm_atomic_helper_check_plane_state(new_plane_state, new_crtc_state,
|
||||
DRM_PLANE_NO_SCALING,
|
||||
DRM_PLANE_NO_SCALING,
|
||||
false, false);
|
||||
}
|
||||
EXPORT_SYMBOL(drm_plane_helper_atomic_check);
|
||||
|
|
|
@ -1014,6 +1014,30 @@ bool drm_helper_hpd_irq_event(struct drm_device *dev)
|
|||
}
|
||||
EXPORT_SYMBOL(drm_helper_hpd_irq_event);
|
||||
|
||||
/**
|
||||
* drm_crtc_helper_mode_valid_fixed - Validates a display mode
|
||||
* @crtc: the crtc
|
||||
* @mode: the mode to validate
|
||||
* @fixed_mode: the display hardware's mode
|
||||
*
|
||||
* Returns:
|
||||
* MODE_OK on success, or another mode-status code otherwise.
|
||||
*/
|
||||
enum drm_mode_status drm_crtc_helper_mode_valid_fixed(struct drm_crtc *crtc,
|
||||
const struct drm_display_mode *mode,
|
||||
const struct drm_display_mode *fixed_mode)
|
||||
{
|
||||
if (mode->hdisplay != fixed_mode->hdisplay && mode->vdisplay != fixed_mode->vdisplay)
|
||||
return MODE_ONE_SIZE;
|
||||
else if (mode->hdisplay != fixed_mode->hdisplay)
|
||||
return MODE_ONE_WIDTH;
|
||||
else if (mode->vdisplay != fixed_mode->vdisplay)
|
||||
return MODE_ONE_HEIGHT;
|
||||
|
||||
return MODE_OK;
|
||||
}
|
||||
EXPORT_SYMBOL(drm_crtc_helper_mode_valid_fixed);
|
||||
|
||||
/**
|
||||
* drm_connector_helper_get_modes_from_ddc - Updates the connector's EDID
|
||||
* property from the connector's
|
||||
|
@ -1050,6 +1074,46 @@ int drm_connector_helper_get_modes_from_ddc(struct drm_connector *connector)
|
|||
}
|
||||
EXPORT_SYMBOL(drm_connector_helper_get_modes_from_ddc);
|
||||
|
||||
/**
|
||||
* drm_connector_helper_get_modes_fixed - Duplicates a display mode for a connector
|
||||
* @connector: the connector
|
||||
* @fixed_mode: the display hardware's mode
|
||||
*
|
||||
* This function duplicates a display modes for a connector. Drivers for hardware
|
||||
* that only supports a single fixed mode can use this function in their connector's
|
||||
* get_modes helper.
|
||||
*
|
||||
* Returns:
|
||||
* The number of created modes.
|
||||
*/
|
||||
int drm_connector_helper_get_modes_fixed(struct drm_connector *connector,
|
||||
const struct drm_display_mode *fixed_mode)
|
||||
{
|
||||
struct drm_device *dev = connector->dev;
|
||||
struct drm_display_mode *mode;
|
||||
|
||||
mode = drm_mode_duplicate(dev, fixed_mode);
|
||||
if (!mode) {
|
||||
drm_err(dev, "Failed to duplicate mode " DRM_MODE_FMT "\n",
|
||||
DRM_MODE_ARG(fixed_mode));
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (mode->name[0] == '\0')
|
||||
drm_mode_set_name(mode);
|
||||
|
||||
mode->type |= DRM_MODE_TYPE_PREFERRED;
|
||||
drm_mode_probed_add(connector, mode);
|
||||
|
||||
if (mode->width_mm)
|
||||
connector->display_info.width_mm = mode->width_mm;
|
||||
if (mode->height_mm)
|
||||
connector->display_info.height_mm = mode->height_mm;
|
||||
|
||||
return 1;
|
||||
}
|
||||
EXPORT_SYMBOL(drm_connector_helper_get_modes_fixed);
|
||||
|
||||
/**
|
||||
* drm_connector_helper_get_modes - Read EDID and update connector.
|
||||
* @connector: The connector
|
||||
|
|
|
@ -7,6 +7,8 @@ config DRM_GMA500
|
|||
select ACPI_VIDEO if ACPI
|
||||
select BACKLIGHT_CLASS_DEVICE if ACPI
|
||||
select INPUT if ACPI
|
||||
select X86_PLATFORM_DEVICES if ACPI
|
||||
select ACPI_WMI if ACPI
|
||||
help
|
||||
Say yes for an experimental 2D KMS framebuffer driver for the
|
||||
Intel GMA500 (Poulsbo), Intel GMA600 (Moorestown/Oak Trail) and
|
||||
|
|
|
@ -7,75 +7,109 @@
|
|||
* Authors: Eric Knopp
|
||||
*/
|
||||
|
||||
#include <acpi/video.h>
|
||||
|
||||
#include "psb_drv.h"
|
||||
#include "psb_intel_reg.h"
|
||||
#include "psb_intel_drv.h"
|
||||
#include "intel_bios.h"
|
||||
#include "power.h"
|
||||
|
||||
#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE
|
||||
static void do_gma_backlight_set(struct drm_device *dev)
|
||||
{
|
||||
struct drm_psb_private *dev_priv = to_drm_psb_private(dev);
|
||||
backlight_update_status(dev_priv->backlight_device);
|
||||
}
|
||||
#endif
|
||||
|
||||
void gma_backlight_enable(struct drm_device *dev)
|
||||
{
|
||||
#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE
|
||||
struct drm_psb_private *dev_priv = to_drm_psb_private(dev);
|
||||
|
||||
dev_priv->backlight_enabled = true;
|
||||
if (dev_priv->backlight_device) {
|
||||
dev_priv->backlight_device->props.brightness = dev_priv->backlight_level;
|
||||
do_gma_backlight_set(dev);
|
||||
}
|
||||
#endif
|
||||
dev_priv->ops->backlight_set(dev, dev_priv->backlight_level);
|
||||
}
|
||||
|
||||
void gma_backlight_disable(struct drm_device *dev)
|
||||
{
|
||||
#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE
|
||||
struct drm_psb_private *dev_priv = to_drm_psb_private(dev);
|
||||
|
||||
dev_priv->backlight_enabled = false;
|
||||
if (dev_priv->backlight_device) {
|
||||
dev_priv->backlight_device->props.brightness = 0;
|
||||
do_gma_backlight_set(dev);
|
||||
}
|
||||
#endif
|
||||
dev_priv->ops->backlight_set(dev, 0);
|
||||
}
|
||||
|
||||
void gma_backlight_set(struct drm_device *dev, int v)
|
||||
{
|
||||
#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE
|
||||
struct drm_psb_private *dev_priv = to_drm_psb_private(dev);
|
||||
|
||||
dev_priv->backlight_level = v;
|
||||
if (dev_priv->backlight_device && dev_priv->backlight_enabled) {
|
||||
dev_priv->backlight_device->props.brightness = v;
|
||||
do_gma_backlight_set(dev);
|
||||
}
|
||||
#endif
|
||||
if (dev_priv->backlight_enabled)
|
||||
dev_priv->ops->backlight_set(dev, v);
|
||||
}
|
||||
|
||||
static int gma_backlight_get_brightness(struct backlight_device *bd)
|
||||
{
|
||||
struct drm_device *dev = bl_get_data(bd);
|
||||
struct drm_psb_private *dev_priv = to_drm_psb_private(dev);
|
||||
|
||||
if (dev_priv->ops->backlight_get)
|
||||
return dev_priv->ops->backlight_get(dev);
|
||||
|
||||
return dev_priv->backlight_level;
|
||||
}
|
||||
|
||||
static int gma_backlight_update_status(struct backlight_device *bd)
|
||||
{
|
||||
struct drm_device *dev = bl_get_data(bd);
|
||||
int level = backlight_get_brightness(bd);
|
||||
|
||||
/* Percentage 1-100% being valid */
|
||||
if (level < 1)
|
||||
level = 1;
|
||||
|
||||
gma_backlight_set(dev, level);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct backlight_ops gma_backlight_ops __maybe_unused = {
|
||||
.get_brightness = gma_backlight_get_brightness,
|
||||
.update_status = gma_backlight_update_status,
|
||||
};
|
||||
|
||||
int gma_backlight_init(struct drm_device *dev)
|
||||
{
|
||||
#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE
|
||||
struct drm_psb_private *dev_priv = to_drm_psb_private(dev);
|
||||
struct backlight_properties props __maybe_unused = {};
|
||||
int ret;
|
||||
|
||||
dev_priv->backlight_enabled = true;
|
||||
return dev_priv->ops->backlight_init(dev);
|
||||
#else
|
||||
return 0;
|
||||
dev_priv->backlight_level = 100;
|
||||
|
||||
ret = dev_priv->ops->backlight_init(dev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (!acpi_video_backlight_use_native()) {
|
||||
drm_info(dev, "Skipping %s backlight registration\n",
|
||||
dev_priv->ops->backlight_name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE
|
||||
props.brightness = dev_priv->backlight_level;
|
||||
props.max_brightness = PSB_MAX_BRIGHTNESS;
|
||||
props.type = BACKLIGHT_RAW;
|
||||
|
||||
dev_priv->backlight_device =
|
||||
backlight_device_register(dev_priv->ops->backlight_name,
|
||||
dev->dev, dev,
|
||||
&gma_backlight_ops, &props);
|
||||
if (IS_ERR(dev_priv->backlight_device))
|
||||
return PTR_ERR(dev_priv->backlight_device);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void gma_backlight_exit(struct drm_device *dev)
|
||||
{
|
||||
#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE
|
||||
struct drm_psb_private *dev_priv = to_drm_psb_private(dev);
|
||||
if (dev_priv->backlight_device) {
|
||||
dev_priv->backlight_device->props.brightness = 0;
|
||||
backlight_update_status(dev_priv->backlight_device);
|
||||
|
||||
if (dev_priv->backlight_device)
|
||||
backlight_device_unregister(dev_priv->backlight_device);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -5,7 +5,6 @@
|
|||
*
|
||||
**************************************************************************/
|
||||
|
||||
#include <linux/backlight.h>
|
||||
#include <linux/delay.h>
|
||||
|
||||
#include <drm/drm.h>
|
||||
|
@ -62,14 +61,10 @@ static int cdv_output_init(struct drm_device *dev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE
|
||||
|
||||
/*
|
||||
* Cedartrail Backlght Interfaces
|
||||
*/
|
||||
|
||||
static struct backlight_device *cdv_backlight_device;
|
||||
|
||||
static int cdv_backlight_combination_mode(struct drm_device *dev)
|
||||
{
|
||||
return REG_READ(BLC_PWM_CTL2) & PWM_LEGACY_MODE;
|
||||
|
@ -92,9 +87,8 @@ static u32 cdv_get_max_backlight(struct drm_device *dev)
|
|||
return max;
|
||||
}
|
||||
|
||||
static int cdv_get_brightness(struct backlight_device *bd)
|
||||
static int cdv_get_brightness(struct drm_device *dev)
|
||||
{
|
||||
struct drm_device *dev = bl_get_data(bd);
|
||||
struct pci_dev *pdev = to_pci_dev(dev->dev);
|
||||
u32 val = REG_READ(BLC_PWM_CTL) & BACKLIGHT_DUTY_CYCLE_MASK;
|
||||
|
||||
|
@ -106,20 +100,13 @@ static int cdv_get_brightness(struct backlight_device *bd)
|
|||
val *= lbpc;
|
||||
}
|
||||
return (val * 100)/cdv_get_max_backlight(dev);
|
||||
|
||||
}
|
||||
|
||||
static int cdv_set_brightness(struct backlight_device *bd)
|
||||
static void cdv_set_brightness(struct drm_device *dev, int level)
|
||||
{
|
||||
struct drm_device *dev = bl_get_data(bd);
|
||||
struct pci_dev *pdev = to_pci_dev(dev->dev);
|
||||
int level = bd->props.brightness;
|
||||
u32 blc_pwm_ctl;
|
||||
|
||||
/* Percentage 1-100% being valid */
|
||||
if (level < 1)
|
||||
level = 1;
|
||||
|
||||
level *= cdv_get_max_backlight(dev);
|
||||
level /= 100;
|
||||
|
||||
|
@ -136,38 +123,18 @@ static int cdv_set_brightness(struct backlight_device *bd)
|
|||
blc_pwm_ctl = REG_READ(BLC_PWM_CTL) & ~BACKLIGHT_DUTY_CYCLE_MASK;
|
||||
REG_WRITE(BLC_PWM_CTL, (blc_pwm_ctl |
|
||||
(level << BACKLIGHT_DUTY_CYCLE_SHIFT)));
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct backlight_ops cdv_ops = {
|
||||
.get_brightness = cdv_get_brightness,
|
||||
.update_status = cdv_set_brightness,
|
||||
};
|
||||
|
||||
static int cdv_backlight_init(struct drm_device *dev)
|
||||
{
|
||||
struct drm_psb_private *dev_priv = to_drm_psb_private(dev);
|
||||
struct backlight_properties props;
|
||||
|
||||
memset(&props, 0, sizeof(struct backlight_properties));
|
||||
props.max_brightness = 100;
|
||||
props.type = BACKLIGHT_PLATFORM;
|
||||
dev_priv->backlight_level = cdv_get_brightness(dev);
|
||||
cdv_set_brightness(dev, dev_priv->backlight_level);
|
||||
|
||||
cdv_backlight_device = backlight_device_register("psb-bl",
|
||||
NULL, (void *)dev, &cdv_ops, &props);
|
||||
if (IS_ERR(cdv_backlight_device))
|
||||
return PTR_ERR(cdv_backlight_device);
|
||||
|
||||
cdv_backlight_device->props.brightness =
|
||||
cdv_get_brightness(cdv_backlight_device);
|
||||
backlight_update_status(cdv_backlight_device);
|
||||
dev_priv->backlight_device = cdv_backlight_device;
|
||||
dev_priv->backlight_enabled = true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Provide the Cedarview specific chip logic and low level methods
|
||||
* for power management
|
||||
|
@ -581,11 +548,9 @@ static const struct psb_offset cdv_regmap[2] = {
|
|||
static int cdv_chip_setup(struct drm_device *dev)
|
||||
{
|
||||
struct drm_psb_private *dev_priv = to_drm_psb_private(dev);
|
||||
struct pci_dev *pdev = to_pci_dev(dev->dev);
|
||||
INIT_WORK(&dev_priv->hotplug_work, cdv_hotplug_work_func);
|
||||
|
||||
if (pci_enable_msi(pdev))
|
||||
dev_warn(dev->dev, "Enabling MSI failed!\n");
|
||||
dev_priv->use_msi = true;
|
||||
dev_priv->regmap = cdv_regmap;
|
||||
gma_get_core_freq(dev);
|
||||
psb_intel_opregion_init(dev);
|
||||
|
@ -615,9 +580,10 @@ const struct psb_ops cdv_chip_ops = {
|
|||
.hotplug = cdv_hotplug_event,
|
||||
.hotplug_enable = cdv_hotplug_enable,
|
||||
|
||||
#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE
|
||||
.backlight_init = cdv_backlight_init,
|
||||
#endif
|
||||
.backlight_get = cdv_get_brightness,
|
||||
.backlight_set = cdv_set_brightness,
|
||||
.backlight_name = "psb-bl",
|
||||
|
||||
.init_pm = cdv_init_pm,
|
||||
.save_regs = cdv_save_display_registers,
|
||||
|
|
|
@ -552,28 +552,11 @@ int gma_crtc_page_flip(struct drm_crtc *crtc,
|
|||
return ret;
|
||||
}
|
||||
|
||||
int gma_crtc_set_config(struct drm_mode_set *set,
|
||||
struct drm_modeset_acquire_ctx *ctx)
|
||||
{
|
||||
struct drm_device *dev = set->crtc->dev;
|
||||
struct drm_psb_private *dev_priv = to_drm_psb_private(dev);
|
||||
int ret;
|
||||
|
||||
if (!dev_priv->rpm_enabled)
|
||||
return drm_crtc_helper_set_config(set, ctx);
|
||||
|
||||
pm_runtime_forbid(dev->dev);
|
||||
ret = drm_crtc_helper_set_config(set, ctx);
|
||||
pm_runtime_allow(dev->dev);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
const struct drm_crtc_funcs gma_crtc_funcs = {
|
||||
.cursor_set = gma_crtc_cursor_set,
|
||||
.cursor_move = gma_crtc_cursor_move,
|
||||
.gamma_set = gma_crtc_gamma_set,
|
||||
.set_config = gma_crtc_set_config,
|
||||
.set_config = drm_crtc_helper_set_config,
|
||||
.destroy = gma_crtc_destroy,
|
||||
.page_flip = gma_crtc_page_flip,
|
||||
.enable_vblank = gma_crtc_enable_vblank,
|
||||
|
|
|
@ -69,8 +69,6 @@ extern int gma_crtc_page_flip(struct drm_crtc *crtc,
|
|||
struct drm_pending_vblank_event *event,
|
||||
uint32_t page_flip_flags,
|
||||
struct drm_modeset_acquire_ctx *ctx);
|
||||
extern int gma_crtc_set_config(struct drm_mode_set *set,
|
||||
struct drm_modeset_acquire_ctx *ctx);
|
||||
|
||||
extern void gma_crtc_save(struct drm_crtc *crtc);
|
||||
extern void gma_crtc_restore(struct drm_crtc *crtc);
|
||||
|
|
|
@ -5,7 +5,6 @@
|
|||
*
|
||||
**************************************************************************/
|
||||
|
||||
#include <linux/backlight.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/dmi.h>
|
||||
#include <linux/module.h>
|
||||
|
@ -37,29 +36,18 @@ static int oaktrail_output_init(struct drm_device *dev)
|
|||
* Provide the low level interfaces for the Moorestown backlight
|
||||
*/
|
||||
|
||||
#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE
|
||||
|
||||
#define MRST_BLC_MAX_PWM_REG_FREQ 0xFFFF
|
||||
#define BLC_PWM_PRECISION_FACTOR 100 /* 10000000 */
|
||||
#define BLC_PWM_FREQ_CALC_CONSTANT 32
|
||||
#define MHz 1000000
|
||||
#define BLC_ADJUSTMENT_MAX 100
|
||||
|
||||
static struct backlight_device *oaktrail_backlight_device;
|
||||
static int oaktrail_brightness;
|
||||
|
||||
static int oaktrail_set_brightness(struct backlight_device *bd)
|
||||
static void oaktrail_set_brightness(struct drm_device *dev, int level)
|
||||
{
|
||||
struct drm_device *dev = bl_get_data(oaktrail_backlight_device);
|
||||
struct drm_psb_private *dev_priv = to_drm_psb_private(dev);
|
||||
int level = bd->props.brightness;
|
||||
u32 blc_pwm_ctl;
|
||||
u32 max_pwm_blc;
|
||||
|
||||
/* Percentage 1-100% being valid */
|
||||
if (level < 1)
|
||||
level = 1;
|
||||
|
||||
if (gma_power_begin(dev, 0)) {
|
||||
/* Calculate and set the brightness value */
|
||||
max_pwm_blc = REG_READ(BLC_PWM_CTL) >> 16;
|
||||
|
@ -82,19 +70,9 @@ static int oaktrail_set_brightness(struct backlight_device *bd)
|
|||
REG_WRITE(BLC_PWM_CTL, (max_pwm_blc << 16) | blc_pwm_ctl);
|
||||
gma_power_end(dev);
|
||||
}
|
||||
oaktrail_brightness = level;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int oaktrail_get_brightness(struct backlight_device *bd)
|
||||
{
|
||||
/* return locally cached var instead of HW read (due to DPST etc.) */
|
||||
/* FIXME: ideally return actual value in case firmware fiddled with
|
||||
it */
|
||||
return oaktrail_brightness;
|
||||
}
|
||||
|
||||
static int device_backlight_init(struct drm_device *dev)
|
||||
static int oaktrail_backlight_init(struct drm_device *dev)
|
||||
{
|
||||
struct drm_psb_private *dev_priv = to_drm_psb_private(dev);
|
||||
unsigned long core_clock;
|
||||
|
@ -123,44 +101,11 @@ static int device_backlight_init(struct drm_device *dev)
|
|||
REG_WRITE(BLC_PWM_CTL, value | (value << 16));
|
||||
gma_power_end(dev);
|
||||
}
|
||||
|
||||
oaktrail_set_brightness(dev, PSB_MAX_BRIGHTNESS);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct backlight_ops oaktrail_ops = {
|
||||
.get_brightness = oaktrail_get_brightness,
|
||||
.update_status = oaktrail_set_brightness,
|
||||
};
|
||||
|
||||
static int oaktrail_backlight_init(struct drm_device *dev)
|
||||
{
|
||||
struct drm_psb_private *dev_priv = to_drm_psb_private(dev);
|
||||
int ret;
|
||||
struct backlight_properties props;
|
||||
|
||||
memset(&props, 0, sizeof(struct backlight_properties));
|
||||
props.max_brightness = 100;
|
||||
props.type = BACKLIGHT_PLATFORM;
|
||||
|
||||
oaktrail_backlight_device = backlight_device_register("oaktrail-bl",
|
||||
NULL, (void *)dev, &oaktrail_ops, &props);
|
||||
|
||||
if (IS_ERR(oaktrail_backlight_device))
|
||||
return PTR_ERR(oaktrail_backlight_device);
|
||||
|
||||
ret = device_backlight_init(dev);
|
||||
if (ret < 0) {
|
||||
backlight_device_unregister(oaktrail_backlight_device);
|
||||
return ret;
|
||||
}
|
||||
oaktrail_backlight_device->props.brightness = 100;
|
||||
oaktrail_backlight_device->props.max_brightness = 100;
|
||||
backlight_update_status(oaktrail_backlight_device);
|
||||
dev_priv->backlight_device = oaktrail_backlight_device;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Provide the Moorestown specific chip logic and low level methods
|
||||
* for power management
|
||||
|
@ -501,12 +446,9 @@ static const struct psb_offset oaktrail_regmap[2] = {
|
|||
static int oaktrail_chip_setup(struct drm_device *dev)
|
||||
{
|
||||
struct drm_psb_private *dev_priv = to_drm_psb_private(dev);
|
||||
struct pci_dev *pdev = to_pci_dev(dev->dev);
|
||||
int ret;
|
||||
|
||||
if (pci_enable_msi(pdev))
|
||||
dev_warn(dev->dev, "Enabling MSI failed!\n");
|
||||
|
||||
dev_priv->use_msi = true;
|
||||
dev_priv->regmap = oaktrail_regmap;
|
||||
|
||||
ret = mid_chip_setup(dev);
|
||||
|
@ -548,9 +490,9 @@ const struct psb_ops oaktrail_chip_ops = {
|
|||
|
||||
.output_init = oaktrail_output_init,
|
||||
|
||||
#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE
|
||||
.backlight_init = oaktrail_backlight_init,
|
||||
#endif
|
||||
.backlight_set = oaktrail_set_brightness,
|
||||
.backlight_name = "oaktrail-bl",
|
||||
|
||||
.save_regs = oaktrail_save_display_registers,
|
||||
.restore_regs = oaktrail_restore_display_registers,
|
||||
|
|
|
@ -61,7 +61,6 @@ static void oaktrail_lvds_set_power(struct drm_device *dev,
|
|||
pp_status = REG_READ(PP_STATUS);
|
||||
} while (pp_status & PP_ON);
|
||||
dev_priv->is_lvds_on = false;
|
||||
pm_request_idle(dev->dev);
|
||||
}
|
||||
gma_power_end(dev);
|
||||
}
|
||||
|
|
|
@ -150,21 +150,17 @@ static u32 asle_set_backlight(struct drm_device *dev, u32 bclp)
|
|||
{
|
||||
struct drm_psb_private *dev_priv = to_drm_psb_private(dev);
|
||||
struct opregion_asle *asle = dev_priv->opregion.asle;
|
||||
struct backlight_device *bd = dev_priv->backlight_device;
|
||||
|
||||
DRM_DEBUG_DRIVER("asle set backlight %x\n", bclp);
|
||||
|
||||
if (!(bclp & ASLE_BCLP_VALID))
|
||||
return ASLE_BACKLIGHT_FAILED;
|
||||
|
||||
if (bd == NULL)
|
||||
return ASLE_BACKLIGHT_FAILED;
|
||||
|
||||
bclp &= ASLE_BCLP_MSK;
|
||||
if (bclp > 255)
|
||||
return ASLE_BACKLIGHT_FAILED;
|
||||
|
||||
gma_backlight_set(dev, bclp * bd->props.max_brightness / 255);
|
||||
gma_backlight_set(dev, bclp * PSB_MAX_BRIGHTNESS / 255);
|
||||
|
||||
asle->cblv = (bclp * 0x64) / 0xff | ASLE_CBLV_VALID;
|
||||
|
||||
|
|
|
@ -37,9 +37,6 @@
|
|||
#include <linux/mutex.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
|
||||
static struct mutex power_mutex; /* Serialize power ops */
|
||||
static DEFINE_SPINLOCK(power_ctrl_lock); /* Serialize power claim */
|
||||
|
||||
/**
|
||||
* gma_power_init - initialise power manager
|
||||
* @dev: our device
|
||||
|
@ -54,13 +51,23 @@ void gma_power_init(struct drm_device *dev)
|
|||
dev_priv->apm_base = dev_priv->apm_reg & 0xffff;
|
||||
dev_priv->ospm_base &= 0xffff;
|
||||
|
||||
dev_priv->display_power = true; /* We start active */
|
||||
dev_priv->display_count = 0; /* Currently no users */
|
||||
dev_priv->suspended = false; /* And not suspended */
|
||||
mutex_init(&power_mutex);
|
||||
|
||||
if (dev_priv->ops->init_pm)
|
||||
dev_priv->ops->init_pm(dev);
|
||||
|
||||
/*
|
||||
* Runtime pm support is broken atm. So for now unconditionally
|
||||
* call pm_runtime_get() here and put it again in psb_driver_unload()
|
||||
*
|
||||
* To fix this we need to call pm_runtime_get() once for each active
|
||||
* pipe at boot and then put() / get() for each pipe disable / enable
|
||||
* so that the device gets runtime suspended when no pipes are active.
|
||||
* Once this is in place the pm_runtime_get() below should be replaced
|
||||
* by a pm_runtime_allow() call to undo the pm_runtime_forbid() from
|
||||
* pci_pm_init().
|
||||
*/
|
||||
pm_runtime_get(dev->dev);
|
||||
|
||||
dev_priv->pm_initialized = true;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -71,8 +78,12 @@ void gma_power_init(struct drm_device *dev)
|
|||
*/
|
||||
void gma_power_uninit(struct drm_device *dev)
|
||||
{
|
||||
pm_runtime_disable(dev->dev);
|
||||
pm_runtime_set_suspended(dev->dev);
|
||||
struct drm_psb_private *dev_priv = to_drm_psb_private(dev);
|
||||
|
||||
if (!dev_priv->pm_initialized)
|
||||
return;
|
||||
|
||||
pm_runtime_put_noidle(dev->dev);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -85,11 +96,8 @@ static void gma_suspend_display(struct drm_device *dev)
|
|||
{
|
||||
struct drm_psb_private *dev_priv = to_drm_psb_private(dev);
|
||||
|
||||
if (dev_priv->suspended)
|
||||
return;
|
||||
dev_priv->ops->save_regs(dev);
|
||||
dev_priv->ops->power_down(dev);
|
||||
dev_priv->display_power = false;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -106,8 +114,6 @@ static void gma_resume_display(struct pci_dev *pdev)
|
|||
|
||||
/* turn on the display power island */
|
||||
dev_priv->ops->power_up(dev);
|
||||
dev_priv->suspended = false;
|
||||
dev_priv->display_power = true;
|
||||
|
||||
PSB_WVDC32(dev_priv->pge_ctl | _PSB_PGETBL_ENABLED, PSB_PGETBL_CTL);
|
||||
pci_write_config_word(pdev, PSB_GMCH_CTRL,
|
||||
|
@ -131,21 +137,14 @@ static void gma_suspend_pci(struct pci_dev *pdev)
|
|||
struct drm_psb_private *dev_priv = to_drm_psb_private(dev);
|
||||
int bsm, vbt;
|
||||
|
||||
if (dev_priv->suspended)
|
||||
return;
|
||||
|
||||
pci_save_state(pdev);
|
||||
pci_read_config_dword(pdev, 0x5C, &bsm);
|
||||
dev_priv->regs.saveBSM = bsm;
|
||||
pci_read_config_dword(pdev, 0xFC, &vbt);
|
||||
dev_priv->regs.saveVBT = vbt;
|
||||
pci_read_config_dword(pdev, PSB_PCIx_MSI_ADDR_LOC, &dev_priv->msi_addr);
|
||||
pci_read_config_dword(pdev, PSB_PCIx_MSI_DATA_LOC, &dev_priv->msi_data);
|
||||
|
||||
pci_disable_device(pdev);
|
||||
pci_set_power_state(pdev, PCI_D3hot);
|
||||
|
||||
dev_priv->suspended = true;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -155,29 +154,17 @@ static void gma_suspend_pci(struct pci_dev *pdev)
|
|||
* Perform the resume processing on our PCI device state - rewrite
|
||||
* register state and re-enable the PCI device
|
||||
*/
|
||||
static bool gma_resume_pci(struct pci_dev *pdev)
|
||||
static int gma_resume_pci(struct pci_dev *pdev)
|
||||
{
|
||||
struct drm_device *dev = pci_get_drvdata(pdev);
|
||||
struct drm_psb_private *dev_priv = to_drm_psb_private(dev);
|
||||
int ret;
|
||||
|
||||
if (!dev_priv->suspended)
|
||||
return true;
|
||||
|
||||
pci_set_power_state(pdev, PCI_D0);
|
||||
pci_restore_state(pdev);
|
||||
pci_write_config_dword(pdev, 0x5c, dev_priv->regs.saveBSM);
|
||||
pci_write_config_dword(pdev, 0xFC, dev_priv->regs.saveVBT);
|
||||
/* restoring MSI address and data in PCIx space */
|
||||
pci_write_config_dword(pdev, PSB_PCIx_MSI_ADDR_LOC, dev_priv->msi_addr);
|
||||
pci_write_config_dword(pdev, PSB_PCIx_MSI_DATA_LOC, dev_priv->msi_data);
|
||||
ret = pci_enable_device(pdev);
|
||||
|
||||
if (ret != 0)
|
||||
dev_err(&pdev->dev, "pci_enable failed: %d\n", ret);
|
||||
else
|
||||
dev_priv->suspended = false;
|
||||
return !dev_priv->suspended;
|
||||
return pci_enable_device(pdev);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -192,20 +179,10 @@ int gma_power_suspend(struct device *_dev)
|
|||
{
|
||||
struct pci_dev *pdev = to_pci_dev(_dev);
|
||||
struct drm_device *dev = pci_get_drvdata(pdev);
|
||||
struct drm_psb_private *dev_priv = to_drm_psb_private(dev);
|
||||
|
||||
mutex_lock(&power_mutex);
|
||||
if (!dev_priv->suspended) {
|
||||
if (dev_priv->display_count) {
|
||||
mutex_unlock(&power_mutex);
|
||||
dev_err(dev->dev, "GPU hardware busy, cannot suspend\n");
|
||||
return -EBUSY;
|
||||
}
|
||||
gma_irq_uninstall(dev);
|
||||
gma_suspend_display(dev);
|
||||
gma_suspend_pci(pdev);
|
||||
}
|
||||
mutex_unlock(&power_mutex);
|
||||
gma_irq_uninstall(dev);
|
||||
gma_suspend_display(dev);
|
||||
gma_suspend_pci(pdev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -220,27 +197,12 @@ int gma_power_resume(struct device *_dev)
|
|||
struct pci_dev *pdev = to_pci_dev(_dev);
|
||||
struct drm_device *dev = pci_get_drvdata(pdev);
|
||||
|
||||
mutex_lock(&power_mutex);
|
||||
gma_resume_pci(pdev);
|
||||
gma_resume_display(pdev);
|
||||
gma_irq_preinstall(dev);
|
||||
gma_irq_postinstall(dev);
|
||||
mutex_unlock(&power_mutex);
|
||||
gma_irq_install(dev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* gma_power_is_on - returne true if power is on
|
||||
* @dev: our DRM device
|
||||
*
|
||||
* Returns true if the display island power is on at this moment
|
||||
*/
|
||||
bool gma_power_is_on(struct drm_device *dev)
|
||||
{
|
||||
struct drm_psb_private *dev_priv = to_drm_psb_private(dev);
|
||||
return dev_priv->display_power;
|
||||
}
|
||||
|
||||
/**
|
||||
* gma_power_begin - begin requiring power
|
||||
* @dev: our DRM device
|
||||
|
@ -251,35 +213,10 @@ bool gma_power_is_on(struct drm_device *dev)
|
|||
*/
|
||||
bool gma_power_begin(struct drm_device *dev, bool force_on)
|
||||
{
|
||||
struct drm_psb_private *dev_priv = to_drm_psb_private(dev);
|
||||
struct pci_dev *pdev = to_pci_dev(dev->dev);
|
||||
int ret;
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&power_ctrl_lock, flags);
|
||||
/* Power already on ? */
|
||||
if (dev_priv->display_power) {
|
||||
dev_priv->display_count++;
|
||||
pm_runtime_get(dev->dev);
|
||||
spin_unlock_irqrestore(&power_ctrl_lock, flags);
|
||||
return true;
|
||||
}
|
||||
if (force_on == false)
|
||||
goto out_false;
|
||||
|
||||
/* Ok power up needed */
|
||||
ret = gma_resume_pci(pdev);
|
||||
if (ret == 0) {
|
||||
gma_irq_preinstall(dev);
|
||||
gma_irq_postinstall(dev);
|
||||
pm_runtime_get(dev->dev);
|
||||
dev_priv->display_count++;
|
||||
spin_unlock_irqrestore(&power_ctrl_lock, flags);
|
||||
return true;
|
||||
}
|
||||
out_false:
|
||||
spin_unlock_irqrestore(&power_ctrl_lock, flags);
|
||||
return false;
|
||||
if (force_on)
|
||||
return pm_runtime_resume_and_get(dev->dev) == 0;
|
||||
else
|
||||
return pm_runtime_get_if_in_use(dev->dev) == 1;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -291,46 +228,5 @@ out_false:
|
|||
*/
|
||||
void gma_power_end(struct drm_device *dev)
|
||||
{
|
||||
struct drm_psb_private *dev_priv = to_drm_psb_private(dev);
|
||||
unsigned long flags;
|
||||
spin_lock_irqsave(&power_ctrl_lock, flags);
|
||||
dev_priv->display_count--;
|
||||
WARN_ON(dev_priv->display_count < 0);
|
||||
spin_unlock_irqrestore(&power_ctrl_lock, flags);
|
||||
pm_runtime_put(dev->dev);
|
||||
}
|
||||
|
||||
int psb_runtime_suspend(struct device *dev)
|
||||
{
|
||||
return gma_power_suspend(dev);
|
||||
}
|
||||
|
||||
int psb_runtime_resume(struct device *dev)
|
||||
{
|
||||
return gma_power_resume(dev);
|
||||
}
|
||||
|
||||
int psb_runtime_idle(struct device *dev)
|
||||
{
|
||||
struct drm_device *drmdev = pci_get_drvdata(to_pci_dev(dev));
|
||||
struct drm_psb_private *dev_priv = to_drm_psb_private(drmdev);
|
||||
if (dev_priv->display_count)
|
||||
return 0;
|
||||
else
|
||||
return 1;
|
||||
}
|
||||
|
||||
int gma_power_thaw(struct device *_dev)
|
||||
{
|
||||
return gma_power_resume(_dev);
|
||||
}
|
||||
|
||||
int gma_power_freeze(struct device *_dev)
|
||||
{
|
||||
return gma_power_suspend(_dev);
|
||||
}
|
||||
|
||||
int gma_power_restore(struct device *_dev)
|
||||
{
|
||||
return gma_power_resume(_dev);
|
||||
}
|
||||
|
|
|
@ -43,9 +43,6 @@ void gma_power_uninit(struct drm_device *dev);
|
|||
*/
|
||||
int gma_power_suspend(struct device *dev);
|
||||
int gma_power_resume(struct device *dev);
|
||||
int gma_power_thaw(struct device *dev);
|
||||
int gma_power_freeze(struct device *dev);
|
||||
int gma_power_restore(struct device *_dev);
|
||||
|
||||
/*
|
||||
* These are the functions the driver should use to wrap all hw access
|
||||
|
@ -54,19 +51,4 @@ int gma_power_restore(struct device *_dev);
|
|||
bool gma_power_begin(struct drm_device *dev, bool force);
|
||||
void gma_power_end(struct drm_device *dev);
|
||||
|
||||
/*
|
||||
* Use this function to do an instantaneous check for if the hw is on.
|
||||
* Only use this in cases where you know the mutex is already held such
|
||||
* as in irq install/uninstall and you need to
|
||||
* prevent a deadlock situation. Otherwise use gma_power_begin().
|
||||
*/
|
||||
bool gma_power_is_on(struct drm_device *dev);
|
||||
|
||||
/*
|
||||
* GFX-Runtime PM callbacks
|
||||
*/
|
||||
int psb_runtime_suspend(struct device *dev);
|
||||
int psb_runtime_resume(struct device *dev);
|
||||
int psb_runtime_idle(struct device *dev);
|
||||
|
||||
#endif /*_PSB_POWERMGMT_H_*/
|
||||
|
|
|
@ -5,8 +5,6 @@
|
|||
*
|
||||
**************************************************************************/
|
||||
|
||||
#include <linux/backlight.h>
|
||||
|
||||
#include <drm/drm.h>
|
||||
|
||||
#include "gma_device.h"
|
||||
|
@ -24,8 +22,6 @@ static int psb_output_init(struct drm_device *dev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE
|
||||
|
||||
/*
|
||||
* Poulsbo Backlight Interfaces
|
||||
*/
|
||||
|
@ -41,18 +37,6 @@ static int psb_output_init(struct drm_device *dev)
|
|||
#define PSB_BACKLIGHT_PWM_POLARITY_BIT_CLEAR (0xFFFE)
|
||||
#define PSB_BACKLIGHT_PWM_CTL_SHIFT (16)
|
||||
|
||||
static int psb_brightness;
|
||||
static struct backlight_device *psb_backlight_device;
|
||||
|
||||
static int psb_get_brightness(struct backlight_device *bd)
|
||||
{
|
||||
/* return locally cached var instead of HW read (due to DPST etc.) */
|
||||
/* FIXME: ideally return actual value in case firmware fiddled with
|
||||
it */
|
||||
return psb_brightness;
|
||||
}
|
||||
|
||||
|
||||
static int psb_backlight_setup(struct drm_device *dev)
|
||||
{
|
||||
struct drm_psb_private *dev_priv = to_drm_psb_private(dev);
|
||||
|
@ -86,62 +70,13 @@ static int psb_backlight_setup(struct drm_device *dev)
|
|||
REG_WRITE(BLC_PWM_CTL,
|
||||
(value << PSB_BACKLIGHT_PWM_CTL_SHIFT) | (value));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int psb_set_brightness(struct backlight_device *bd)
|
||||
{
|
||||
struct drm_device *dev = bl_get_data(psb_backlight_device);
|
||||
int level = bd->props.brightness;
|
||||
|
||||
/* Percentage 1-100% being valid */
|
||||
if (level < 1)
|
||||
level = 1;
|
||||
|
||||
psb_intel_lvds_set_brightness(dev, level);
|
||||
psb_brightness = level;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct backlight_ops psb_ops = {
|
||||
.get_brightness = psb_get_brightness,
|
||||
.update_status = psb_set_brightness,
|
||||
};
|
||||
|
||||
static int psb_backlight_init(struct drm_device *dev)
|
||||
{
|
||||
struct drm_psb_private *dev_priv = to_drm_psb_private(dev);
|
||||
int ret;
|
||||
struct backlight_properties props;
|
||||
|
||||
memset(&props, 0, sizeof(struct backlight_properties));
|
||||
props.max_brightness = 100;
|
||||
props.type = BACKLIGHT_PLATFORM;
|
||||
|
||||
psb_backlight_device = backlight_device_register("psb-bl",
|
||||
NULL, (void *)dev, &psb_ops, &props);
|
||||
if (IS_ERR(psb_backlight_device))
|
||||
return PTR_ERR(psb_backlight_device);
|
||||
|
||||
ret = psb_backlight_setup(dev);
|
||||
if (ret < 0) {
|
||||
backlight_device_unregister(psb_backlight_device);
|
||||
psb_backlight_device = NULL;
|
||||
return ret;
|
||||
}
|
||||
psb_backlight_device->props.brightness = 100;
|
||||
psb_backlight_device->props.max_brightness = 100;
|
||||
backlight_update_status(psb_backlight_device);
|
||||
dev_priv->backlight_device = psb_backlight_device;
|
||||
|
||||
psb_intel_lvds_set_brightness(dev, PSB_MAX_BRIGHTNESS);
|
||||
/* This must occur after the backlight is properly initialised */
|
||||
psb_lid_timer_init(dev_priv);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Provide the Poulsbo specific chip logic and low level methods
|
||||
* for power management
|
||||
|
@ -345,9 +280,9 @@ const struct psb_ops psb_chip_ops = {
|
|||
|
||||
.output_init = psb_output_init,
|
||||
|
||||
#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE
|
||||
.backlight_init = psb_backlight_init,
|
||||
#endif
|
||||
.backlight_init = psb_backlight_setup,
|
||||
.backlight_set = psb_intel_lvds_set_brightness,
|
||||
.backlight_name = "psb-bl",
|
||||
|
||||
.init_pm = psb_init_pm,
|
||||
.save_regs = psb_save_display_registers,
|
||||
|
|
|
@ -169,8 +169,7 @@ static void psb_driver_unload(struct drm_device *dev)
|
|||
|
||||
/* TODO: Kill vblank etc here */
|
||||
|
||||
if (dev_priv->backlight_device)
|
||||
gma_backlight_exit(dev);
|
||||
gma_backlight_exit(dev);
|
||||
psb_modeset_cleanup(dev);
|
||||
|
||||
gma_irq_uninstall(dev);
|
||||
|
@ -383,7 +382,7 @@ static int psb_driver_load(struct drm_device *dev, unsigned long flags)
|
|||
PSB_WVDC32(0xFFFFFFFF, PSB_INT_MASK_R);
|
||||
spin_unlock_irqrestore(&dev_priv->irqmask_lock, irqflags);
|
||||
|
||||
gma_irq_install(dev, pdev->irq);
|
||||
gma_irq_install(dev);
|
||||
|
||||
dev->max_vblank_count = 0xffffff; /* only 24 bits of frame count */
|
||||
|
||||
|
@ -399,6 +398,8 @@ static int psb_driver_load(struct drm_device *dev, unsigned long flags)
|
|||
if (gma_encoder->type == INTEL_OUTPUT_LVDS ||
|
||||
gma_encoder->type == INTEL_OUTPUT_MIPI) {
|
||||
ret = gma_backlight_init(dev);
|
||||
if (ret == 0)
|
||||
acpi_video_register_backlight();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -407,11 +408,6 @@ static int psb_driver_load(struct drm_device *dev, unsigned long flags)
|
|||
if (ret)
|
||||
return ret;
|
||||
psb_intel_opregion_enable_asle(dev);
|
||||
#if 0
|
||||
/* Enable runtime pm at last */
|
||||
pm_runtime_enable(dev->dev);
|
||||
pm_runtime_set_active(dev->dev);
|
||||
#endif
|
||||
|
||||
return devm_add_action_or_reset(dev->dev, psb_device_release, dev);
|
||||
|
||||
|
@ -420,33 +416,6 @@ out_err:
|
|||
return ret;
|
||||
}
|
||||
|
||||
static inline void get_brightness(struct backlight_device *bd)
|
||||
{
|
||||
#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE
|
||||
if (bd) {
|
||||
bd->props.brightness = bd->ops->get_brightness(bd);
|
||||
backlight_update_status(bd);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static long psb_unlocked_ioctl(struct file *filp, unsigned int cmd,
|
||||
unsigned long arg)
|
||||
{
|
||||
struct drm_file *file_priv = filp->private_data;
|
||||
struct drm_device *dev = file_priv->minor->dev;
|
||||
struct drm_psb_private *dev_priv = to_drm_psb_private(dev);
|
||||
static unsigned int runtime_allowed;
|
||||
|
||||
if (runtime_allowed == 1 && dev_priv->is_lvds_on) {
|
||||
runtime_allowed++;
|
||||
pm_runtime_allow(dev->dev);
|
||||
dev_priv->rpm_enabled = 1;
|
||||
}
|
||||
return drm_ioctl(filp, cmd, arg);
|
||||
/* FIXME: do we need to wrap the other side of this */
|
||||
}
|
||||
|
||||
static int psb_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
|
||||
{
|
||||
struct drm_psb_private *dev_priv;
|
||||
|
@ -493,22 +462,13 @@ static void psb_pci_remove(struct pci_dev *pdev)
|
|||
drm_dev_unregister(dev);
|
||||
}
|
||||
|
||||
static const struct dev_pm_ops psb_pm_ops = {
|
||||
.resume = gma_power_resume,
|
||||
.suspend = gma_power_suspend,
|
||||
.thaw = gma_power_thaw,
|
||||
.freeze = gma_power_freeze,
|
||||
.restore = gma_power_restore,
|
||||
.runtime_suspend = psb_runtime_suspend,
|
||||
.runtime_resume = psb_runtime_resume,
|
||||
.runtime_idle = psb_runtime_idle,
|
||||
};
|
||||
static DEFINE_RUNTIME_DEV_PM_OPS(psb_pm_ops, gma_power_suspend, gma_power_resume, NULL);
|
||||
|
||||
static const struct file_operations psb_gem_fops = {
|
||||
.owner = THIS_MODULE,
|
||||
.open = drm_open,
|
||||
.release = drm_release,
|
||||
.unlocked_ioctl = psb_unlocked_ioctl,
|
||||
.unlocked_ioctl = drm_ioctl,
|
||||
.compat_ioctl = drm_compat_ioctl,
|
||||
.mmap = drm_gem_mmap,
|
||||
.poll = drm_poll,
|
||||
|
|
|
@ -172,6 +172,8 @@
|
|||
#define PSB_WATCHDOG_DELAY (HZ * 2)
|
||||
#define PSB_LID_DELAY (HZ / 10)
|
||||
|
||||
#define PSB_MAX_BRIGHTNESS 100
|
||||
|
||||
#define PSB_PWR_STATE_ON 1
|
||||
#define PSB_PWR_STATE_OFF 2
|
||||
|
||||
|
@ -426,9 +428,7 @@ struct drm_psb_private {
|
|||
spinlock_t irqmask_lock;
|
||||
|
||||
/* Power */
|
||||
bool suspended;
|
||||
bool display_power;
|
||||
int display_count;
|
||||
bool pm_initialized;
|
||||
|
||||
/* Modesetting */
|
||||
struct psb_intel_mode_device mode_dev;
|
||||
|
@ -486,10 +486,8 @@ struct drm_psb_private {
|
|||
unsigned int core_freq;
|
||||
uint32_t iLVDS_enable;
|
||||
|
||||
/* Runtime PM state */
|
||||
int rpm_enabled;
|
||||
|
||||
/* MID specific */
|
||||
bool use_msi;
|
||||
bool has_gct;
|
||||
struct oaktrail_gct_data gct_data;
|
||||
|
||||
|
@ -499,10 +497,6 @@ struct drm_psb_private {
|
|||
/* Register state */
|
||||
struct psb_save_area regs;
|
||||
|
||||
/* MSI reg save */
|
||||
uint32_t msi_addr;
|
||||
uint32_t msi_data;
|
||||
|
||||
/* Hotplug handling */
|
||||
struct work_struct hotplug_work;
|
||||
|
||||
|
@ -530,10 +524,6 @@ struct drm_psb_private {
|
|||
|
||||
struct drm_fb_helper *fb_helper;
|
||||
|
||||
/* Panel brightness */
|
||||
int brightness;
|
||||
int brightness_adjusted;
|
||||
|
||||
bool dsr_enable;
|
||||
u32 dsr_fb_update;
|
||||
bool dpi_panel_on[3];
|
||||
|
@ -602,10 +592,13 @@ struct psb_ops {
|
|||
void (*disable_sr)(struct drm_device *dev);
|
||||
|
||||
void (*lvds_bl_power)(struct drm_device *dev, bool on);
|
||||
#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE
|
||||
|
||||
/* Backlight */
|
||||
int (*backlight_init)(struct drm_device *dev);
|
||||
#endif
|
||||
void (*backlight_set)(struct drm_device *dev, int level);
|
||||
int (*backlight_get)(struct drm_device *dev);
|
||||
const char *backlight_name;
|
||||
|
||||
int i2c_bus; /* I2C bus identifier for Moorestown */
|
||||
};
|
||||
|
||||
|
|
|
@ -197,8 +197,6 @@ extern void psb_intel_lvds_set_brightness(struct drm_device *dev, int level);
|
|||
extern void oaktrail_lvds_init(struct drm_device *dev,
|
||||
struct psb_intel_mode_device *mode_dev);
|
||||
extern void oaktrail_wait_for_INTR_PKT_SENT(struct drm_device *dev);
|
||||
extern void oaktrail_dsi_init(struct drm_device *dev,
|
||||
struct psb_intel_mode_device *mode_dev);
|
||||
struct gma_i2c_chan *oaktrail_lvds_i2c_init(struct drm_device *dev);
|
||||
extern void mid_dsi_init(struct drm_device *dev,
|
||||
struct psb_intel_mode_device *mode_dev, int dsi_num);
|
||||
|
@ -219,9 +217,6 @@ extern struct drm_crtc *psb_intel_get_crtc_from_pipe(struct drm_device *dev,
|
|||
int pipe);
|
||||
extern struct drm_connector *psb_intel_sdvo_find(struct drm_device *dev,
|
||||
int sdvoB);
|
||||
extern int psb_intel_sdvo_supports_hotplug(struct drm_connector *connector);
|
||||
extern void psb_intel_sdvo_set_hotplug(struct drm_connector *connector,
|
||||
int enable);
|
||||
extern int intelfb_probe(struct drm_device *dev);
|
||||
extern int intelfb_remove(struct drm_device *dev,
|
||||
struct drm_framebuffer *fb);
|
||||
|
|
|
@ -228,7 +228,7 @@ static irqreturn_t gma_irq_handler(int irq, void *arg)
|
|||
vdc_stat &= dev_priv->vdc_irq_mask;
|
||||
spin_unlock(&dev_priv->irqmask_lock);
|
||||
|
||||
if (dsp_int && gma_power_is_on(dev)) {
|
||||
if (dsp_int) {
|
||||
gma_vdc_interrupt(dev, vdc_stat);
|
||||
handled = 1;
|
||||
}
|
||||
|
@ -264,13 +264,12 @@ void gma_irq_preinstall(struct drm_device *dev)
|
|||
|
||||
spin_lock_irqsave(&dev_priv->irqmask_lock, irqflags);
|
||||
|
||||
if (gma_power_is_on(dev)) {
|
||||
PSB_WVDC32(0xFFFFFFFF, PSB_HWSTAM);
|
||||
PSB_WVDC32(0x00000000, PSB_INT_MASK_R);
|
||||
PSB_WVDC32(0x00000000, PSB_INT_ENABLE_R);
|
||||
PSB_WSGX32(0x00000000, PSB_CR_EVENT_HOST_ENABLE);
|
||||
PSB_RSGX32(PSB_CR_EVENT_HOST_ENABLE);
|
||||
}
|
||||
PSB_WVDC32(0xFFFFFFFF, PSB_HWSTAM);
|
||||
PSB_WVDC32(0x00000000, PSB_INT_MASK_R);
|
||||
PSB_WVDC32(0x00000000, PSB_INT_ENABLE_R);
|
||||
PSB_WSGX32(0x00000000, PSB_CR_EVENT_HOST_ENABLE);
|
||||
PSB_RSGX32(PSB_CR_EVENT_HOST_ENABLE);
|
||||
|
||||
if (dev->vblank[0].enabled)
|
||||
dev_priv->vdc_irq_mask |= _PSB_VSYNC_PIPEA_FLAG;
|
||||
if (dev->vblank[1].enabled)
|
||||
|
@ -316,17 +315,24 @@ void gma_irq_postinstall(struct drm_device *dev)
|
|||
spin_unlock_irqrestore(&dev_priv->irqmask_lock, irqflags);
|
||||
}
|
||||
|
||||
int gma_irq_install(struct drm_device *dev, unsigned int irq)
|
||||
int gma_irq_install(struct drm_device *dev)
|
||||
{
|
||||
struct drm_psb_private *dev_priv = to_drm_psb_private(dev);
|
||||
struct pci_dev *pdev = to_pci_dev(dev->dev);
|
||||
int ret;
|
||||
|
||||
if (irq == IRQ_NOTCONNECTED)
|
||||
if (dev_priv->use_msi && pci_enable_msi(pdev)) {
|
||||
dev_warn(dev->dev, "Enabling MSI failed!\n");
|
||||
dev_priv->use_msi = false;
|
||||
}
|
||||
|
||||
if (pdev->irq == IRQ_NOTCONNECTED)
|
||||
return -ENOTCONN;
|
||||
|
||||
gma_irq_preinstall(dev);
|
||||
|
||||
/* PCI devices require shared interrupts. */
|
||||
ret = request_irq(irq, gma_irq_handler, IRQF_SHARED, dev->driver->name, dev);
|
||||
ret = request_irq(pdev->irq, gma_irq_handler, IRQF_SHARED, dev->driver->name, dev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
@ -369,6 +375,8 @@ void gma_irq_uninstall(struct drm_device *dev)
|
|||
spin_unlock_irqrestore(&dev_priv->irqmask_lock, irqflags);
|
||||
|
||||
free_irq(pdev->irq, dev);
|
||||
if (dev_priv->use_msi)
|
||||
pci_disable_msi(pdev);
|
||||
}
|
||||
|
||||
int gma_crtc_enable_vblank(struct drm_crtc *crtc)
|
||||
|
|
|
@ -17,7 +17,7 @@ struct drm_device;
|
|||
|
||||
void gma_irq_preinstall(struct drm_device *dev);
|
||||
void gma_irq_postinstall(struct drm_device *dev);
|
||||
int gma_irq_install(struct drm_device *dev, unsigned int irq);
|
||||
int gma_irq_install(struct drm_device *dev);
|
||||
void gma_irq_uninstall(struct drm_device *dev);
|
||||
|
||||
int gma_crtc_enable_vblank(struct drm_crtc *crtc);
|
||||
|
|
|
@ -23,6 +23,8 @@ config DRM_I915
|
|||
# but for select to work, need to select ACPI_VIDEO's dependencies, ick
|
||||
select BACKLIGHT_CLASS_DEVICE if ACPI
|
||||
select INPUT if ACPI
|
||||
select X86_PLATFORM_DEVICES if ACPI
|
||||
select ACPI_WMI if ACPI
|
||||
select ACPI_VIDEO if ACPI
|
||||
select ACPI_BUTTON if ACPI
|
||||
select SYNC_FILE
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
|
||||
#include <linux/pci.h>
|
||||
#include <linux/acpi.h>
|
||||
#include <acpi/video.h>
|
||||
|
||||
#include "i915_drv.h"
|
||||
#include "intel_acpi.h"
|
||||
|
@ -331,3 +332,29 @@ void intel_acpi_assign_connector_fwnodes(struct drm_i915_private *i915)
|
|||
*/
|
||||
fwnode_handle_put(fwnode);
|
||||
}
|
||||
|
||||
void intel_acpi_video_register(struct drm_i915_private *i915)
|
||||
{
|
||||
struct drm_connector_list_iter conn_iter;
|
||||
struct drm_connector *connector;
|
||||
|
||||
acpi_video_register();
|
||||
|
||||
/*
|
||||
* If i915 is driving an internal panel without registering its native
|
||||
* backlight handler try to register the acpi_video backlight.
|
||||
* For panels not driven by i915 another GPU driver may still register
|
||||
* a native backlight later and acpi_video_register_backlight() should
|
||||
* only be called after any native backlights have been registered.
|
||||
*/
|
||||
drm_connector_list_iter_begin(&i915->drm, &conn_iter);
|
||||
drm_for_each_connector_iter(connector, &conn_iter) {
|
||||
struct intel_panel *panel = &to_intel_connector(connector)->panel;
|
||||
|
||||
if (panel->backlight.funcs && !panel->backlight.device) {
|
||||
acpi_video_register_backlight();
|
||||
break;
|
||||
}
|
||||
}
|
||||
drm_connector_list_iter_end(&conn_iter);
|
||||
}
|
||||
|
|
|
@ -14,6 +14,7 @@ void intel_unregister_dsm_handler(void);
|
|||
void intel_dsm_get_bios_data_funcs_supported(struct drm_i915_private *i915);
|
||||
void intel_acpi_device_id_update(struct drm_i915_private *i915);
|
||||
void intel_acpi_assign_connector_fwnodes(struct drm_i915_private *i915);
|
||||
void intel_acpi_video_register(struct drm_i915_private *i915);
|
||||
#else
|
||||
static inline void intel_register_dsm_handler(void) { return; }
|
||||
static inline void intel_unregister_dsm_handler(void) { return; }
|
||||
|
@ -23,6 +24,8 @@ static inline
|
|||
void intel_acpi_device_id_update(struct drm_i915_private *i915) { return; }
|
||||
static inline
|
||||
void intel_acpi_assign_connector_fwnodes(struct drm_i915_private *i915) { return; }
|
||||
static inline
|
||||
void intel_acpi_video_register(struct drm_i915_private *i915) { return; }
|
||||
#endif /* CONFIG_ACPI */
|
||||
|
||||
#endif /* __INTEL_ACPI_H__ */
|
||||
|
|
|
@ -8,6 +8,8 @@
|
|||
#include <linux/pwm.h>
|
||||
#include <linux/string_helpers.h>
|
||||
|
||||
#include <acpi/video.h>
|
||||
|
||||
#include "intel_backlight.h"
|
||||
#include "intel_backlight_regs.h"
|
||||
#include "intel_connector.h"
|
||||
|
@ -953,6 +955,11 @@ int intel_backlight_device_register(struct intel_connector *connector)
|
|||
|
||||
WARN_ON(panel->backlight.max == 0);
|
||||
|
||||
if (!acpi_video_backlight_use_native()) {
|
||||
drm_info(&i915->drm, "Skipping intel_backlight registration\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
memset(&props, 0, sizeof(props));
|
||||
props.type = BACKLIGHT_RAW;
|
||||
|
||||
|
|
|
@ -9045,7 +9045,7 @@ void intel_display_driver_register(struct drm_i915_private *i915)
|
|||
|
||||
/* Must be done after probing outputs */
|
||||
intel_opregion_register(i915);
|
||||
acpi_video_register();
|
||||
intel_acpi_video_register(i915);
|
||||
|
||||
intel_audio_init(i915);
|
||||
|
||||
|
|
|
@ -1222,8 +1222,8 @@ static void mtk_dp_video_mute(struct mtk_dp *mtk_dp, bool enable)
|
|||
mtk_dp->data->smc_cmd, enable,
|
||||
0, 0, 0, 0, 0, &res);
|
||||
|
||||
dev_dbg(mtk_dp->dev, "smc cmd: 0x%x, p1: 0x%x, ret: 0x%lx-0x%lx\n",
|
||||
mtk_dp->data->smc_cmd, enable, res.a0, res.a1);
|
||||
dev_dbg(mtk_dp->dev, "smc cmd: 0x%x, p1: %s, ret: 0x%lx-0x%lx\n",
|
||||
mtk_dp->data->smc_cmd, enable ? "enable" : "disable", res.a0, res.a1);
|
||||
}
|
||||
|
||||
static void mtk_dp_audio_mute(struct mtk_dp *mtk_dp, bool mute)
|
||||
|
@ -1933,39 +1933,41 @@ static enum drm_connector_status mtk_dp_bdg_detect(struct drm_bridge *bridge)
|
|||
bool enabled = mtk_dp->enabled;
|
||||
u8 sink_count = 0;
|
||||
|
||||
if (mtk_dp->train_info.cable_plugged_in) {
|
||||
if (!enabled) {
|
||||
/* power on aux */
|
||||
mtk_dp_update_bits(mtk_dp, MTK_DP_TOP_PWR_STATE,
|
||||
DP_PWR_STATE_BANDGAP_TPLL_LANE,
|
||||
DP_PWR_STATE_MASK);
|
||||
if (!mtk_dp->train_info.cable_plugged_in)
|
||||
return ret;
|
||||
|
||||
/* power on panel */
|
||||
drm_dp_dpcd_writeb(&mtk_dp->aux, DP_SET_POWER, DP_SET_POWER_D0);
|
||||
usleep_range(2000, 5000);
|
||||
}
|
||||
/*
|
||||
* Some dongles still source HPD when they do not connect to any
|
||||
* sink device. To avoid this, we need to read the sink count
|
||||
* to make sure we do connect to sink devices. After this detect
|
||||
* function, we just need to check the HPD connection to check
|
||||
* whether we connect to a sink device.
|
||||
*/
|
||||
drm_dp_dpcd_readb(&mtk_dp->aux, DP_SINK_COUNT, &sink_count);
|
||||
if (DP_GET_SINK_COUNT(sink_count))
|
||||
ret = connector_status_connected;
|
||||
if (!enabled) {
|
||||
/* power on aux */
|
||||
mtk_dp_update_bits(mtk_dp, MTK_DP_TOP_PWR_STATE,
|
||||
DP_PWR_STATE_BANDGAP_TPLL_LANE,
|
||||
DP_PWR_STATE_MASK);
|
||||
|
||||
if (!enabled) {
|
||||
/* power off panel */
|
||||
drm_dp_dpcd_writeb(&mtk_dp->aux, DP_SET_POWER, DP_SET_POWER_D3);
|
||||
usleep_range(2000, 3000);
|
||||
|
||||
/* power off aux */
|
||||
mtk_dp_update_bits(mtk_dp, MTK_DP_TOP_PWR_STATE,
|
||||
DP_PWR_STATE_BANDGAP_TPLL,
|
||||
DP_PWR_STATE_MASK);
|
||||
}
|
||||
/* power on panel */
|
||||
drm_dp_dpcd_writeb(&mtk_dp->aux, DP_SET_POWER, DP_SET_POWER_D0);
|
||||
usleep_range(2000, 5000);
|
||||
}
|
||||
/*
|
||||
* Some dongles still source HPD when they do not connect to any
|
||||
* sink device. To avoid this, we need to read the sink count
|
||||
* to make sure we do connect to sink devices. After this detect
|
||||
* function, we just need to check the HPD connection to check
|
||||
* whether we connect to a sink device.
|
||||
*/
|
||||
drm_dp_dpcd_readb(&mtk_dp->aux, DP_SINK_COUNT, &sink_count);
|
||||
if (DP_GET_SINK_COUNT(sink_count))
|
||||
ret = connector_status_connected;
|
||||
|
||||
if (!enabled) {
|
||||
/* power off panel */
|
||||
drm_dp_dpcd_writeb(&mtk_dp->aux, DP_SET_POWER, DP_SET_POWER_D3);
|
||||
usleep_range(2000, 3000);
|
||||
|
||||
/* power off aux */
|
||||
mtk_dp_update_bits(mtk_dp, MTK_DP_TOP_PWR_STATE,
|
||||
DP_PWR_STATE_BANDGAP_TPLL,
|
||||
DP_PWR_STATE_MASK);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -2642,7 +2644,7 @@ static const struct of_device_id mtk_dp_of_match[] = {
|
|||
};
|
||||
MODULE_DEVICE_TABLE(of, mtk_dp_of_match);
|
||||
|
||||
struct platform_driver mtk_dp_driver = {
|
||||
static struct platform_driver mtk_dp_driver = {
|
||||
.probe = mtk_dp_probe,
|
||||
.remove = mtk_dp_remove,
|
||||
.driver = {
|
||||
|
|
|
@ -153,8 +153,6 @@
|
|||
#define CH_STATUS_1_DP_ENC0_P0_MASK GENMASK(15, 0)
|
||||
#define MTK_DP_ENC0_P0_3094 0x3094
|
||||
#define CH_STATUS_2_DP_ENC0_P0_MASK GENMASK(7, 0)
|
||||
#define MTK_DP_ENC0_P0_30A0 0x30a0
|
||||
#define DP_ENC0_30A0_MASK (BIT(7) | BIT(8) | BIT(12))
|
||||
#define MTK_DP_ENC0_P0_30A4 0x30a4
|
||||
#define AU_TS_CFG_DP_ENC0_P0_MASK GENMASK(7, 0)
|
||||
#define MTK_DP_ENC0_P0_30A8 0x30a8
|
||||
|
@ -171,8 +169,6 @@
|
|||
#define MTK_DP_ENC0_P0_312C 0x312c
|
||||
#define ASP_HB2_DP_ENC0_P0_MASK GENMASK(7, 0)
|
||||
#define ASP_HB3_DP_ENC0_P0_MASK GENMASK(15, 8)
|
||||
#define MTK_DP_ENC0_P0_3130 0x3130
|
||||
#define MTK_DP_ENC0_P0_3138 0x3138
|
||||
#define MTK_DP_ENC0_P0_3154 0x3154
|
||||
#define PGEN_HTOTAL_DP_ENC0_P0_MASK GENMASK(13, 0)
|
||||
#define MTK_DP_ENC0_P0_3158 0x3158
|
||||
|
@ -206,8 +202,6 @@
|
|||
#define SDP_PACKET_TYPE_DP_ENC1_P0_MASK GENMASK(4, 0)
|
||||
#define SDP_PACKET_W_DP_ENC1_P0 BIT(5)
|
||||
#define SDP_PACKET_W_DP_ENC1_P0_MASK BIT(5)
|
||||
#define MTK_DP_ENC1_P0_328C 0x328c
|
||||
#define VSC_DATA_RDY_VESA_DP_ENC1_P0_MASK BIT(7)
|
||||
#define MTK_DP_ENC1_P0_3300 0x3300
|
||||
#define VIDEO_AFIFO_RDY_SEL_DP_ENC1_P0_VAL 2
|
||||
#define VIDEO_AFIFO_RDY_SEL_DP_ENC1_P0_MASK GENMASK(9, 8)
|
||||
|
|
|
@ -1276,37 +1276,9 @@ static const uint32_t modeset_formats[] = {
|
|||
};
|
||||
|
||||
static const struct drm_plane_funcs nv04_primary_plane_funcs = {
|
||||
.update_plane = drm_plane_helper_update_primary,
|
||||
.disable_plane = drm_plane_helper_disable_primary,
|
||||
.destroy = drm_plane_helper_destroy,
|
||||
DRM_PLANE_NON_ATOMIC_FUNCS,
|
||||
};
|
||||
|
||||
static struct drm_plane *
|
||||
create_primary_plane(struct drm_device *dev)
|
||||
{
|
||||
struct drm_plane *primary;
|
||||
int ret;
|
||||
|
||||
primary = kzalloc(sizeof(*primary), GFP_KERNEL);
|
||||
if (primary == NULL) {
|
||||
DRM_DEBUG_KMS("Failed to allocate primary plane\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* possible_crtc's will be filled in later by crtc_init */
|
||||
ret = drm_universal_plane_init(dev, primary, 0,
|
||||
&nv04_primary_plane_funcs,
|
||||
modeset_formats,
|
||||
ARRAY_SIZE(modeset_formats), NULL,
|
||||
DRM_PLANE_TYPE_PRIMARY, NULL);
|
||||
if (ret) {
|
||||
kfree(primary);
|
||||
primary = NULL;
|
||||
}
|
||||
|
||||
return primary;
|
||||
}
|
||||
|
||||
static int nv04_crtc_vblank_handler(struct nvif_notify *notify)
|
||||
{
|
||||
struct nouveau_crtc *nv_crtc =
|
||||
|
@ -1321,6 +1293,7 @@ nv04_crtc_create(struct drm_device *dev, int crtc_num)
|
|||
{
|
||||
struct nouveau_display *disp = nouveau_display(dev);
|
||||
struct nouveau_crtc *nv_crtc;
|
||||
struct drm_plane *primary;
|
||||
int ret;
|
||||
|
||||
nv_crtc = kzalloc(sizeof(*nv_crtc), GFP_KERNEL);
|
||||
|
@ -1335,8 +1308,18 @@ nv04_crtc_create(struct drm_device *dev, int crtc_num)
|
|||
nv_crtc->save = nv_crtc_save;
|
||||
nv_crtc->restore = nv_crtc_restore;
|
||||
|
||||
drm_crtc_init_with_planes(dev, &nv_crtc->base,
|
||||
create_primary_plane(dev), NULL,
|
||||
primary = __drm_universal_plane_alloc(dev, sizeof(*primary), 0, 0,
|
||||
&nv04_primary_plane_funcs,
|
||||
modeset_formats,
|
||||
ARRAY_SIZE(modeset_formats), NULL,
|
||||
DRM_PLANE_TYPE_PRIMARY, NULL);
|
||||
if (IS_ERR(primary)) {
|
||||
ret = PTR_ERR(primary);
|
||||
kfree(nv_crtc);
|
||||
return ret;
|
||||
}
|
||||
|
||||
drm_crtc_init_with_planes(dev, &nv_crtc->base, primary, NULL,
|
||||
&nv04_crtc_funcs, NULL);
|
||||
drm_crtc_helper_add(&nv_crtc->base, &nv04_crtc_helper_funcs);
|
||||
drm_mode_crtc_set_gamma_size(&nv_crtc->base, 256);
|
||||
|
|
|
@ -296,9 +296,10 @@ nv10_overlay_init(struct drm_device *device)
|
|||
break;
|
||||
}
|
||||
|
||||
ret = drm_plane_init(device, &plane->base, 3 /* both crtc's */,
|
||||
&nv10_plane_funcs,
|
||||
formats, num_formats, false);
|
||||
ret = drm_universal_plane_init(device, &plane->base, 3 /* both crtc's */,
|
||||
&nv10_plane_funcs,
|
||||
formats, num_formats, NULL,
|
||||
DRM_PLANE_TYPE_OVERLAY, NULL);
|
||||
if (ret)
|
||||
goto err;
|
||||
|
||||
|
@ -475,9 +476,9 @@ nv04_overlay_init(struct drm_device *device)
|
|||
if (!plane)
|
||||
return;
|
||||
|
||||
ret = drm_plane_init(device, &plane->base, 1 /* single crtc */,
|
||||
&nv04_plane_funcs,
|
||||
formats, 2, false);
|
||||
ret = drm_universal_plane_init(device, &plane->base, 1 /* single crtc */,
|
||||
&nv04_plane_funcs, formats, 2, NULL,
|
||||
DRM_PLANE_TYPE_OVERLAY, NULL);
|
||||
if (ret)
|
||||
goto err;
|
||||
|
||||
|
|
|
@ -386,3 +386,13 @@ nouveau_acpi_edid(struct drm_device *dev, struct drm_connector *connector)
|
|||
|
||||
return kmemdup(edid, EDID_LENGTH, GFP_KERNEL);
|
||||
}
|
||||
|
||||
bool nouveau_acpi_video_backlight_use_native(void)
|
||||
{
|
||||
return acpi_video_backlight_use_native();
|
||||
}
|
||||
|
||||
void nouveau_acpi_video_register_backlight(void)
|
||||
{
|
||||
acpi_video_register_backlight();
|
||||
}
|
||||
|
|
|
@ -11,6 +11,8 @@ void nouveau_register_dsm_handler(void);
|
|||
void nouveau_unregister_dsm_handler(void);
|
||||
void nouveau_switcheroo_optimus_dsm(void);
|
||||
void *nouveau_acpi_edid(struct drm_device *, struct drm_connector *);
|
||||
bool nouveau_acpi_video_backlight_use_native(void);
|
||||
void nouveau_acpi_video_register_backlight(void);
|
||||
#else
|
||||
static inline bool nouveau_is_optimus(void) { return false; };
|
||||
static inline bool nouveau_is_v1_dsm(void) { return false; };
|
||||
|
@ -18,6 +20,8 @@ static inline void nouveau_register_dsm_handler(void) {}
|
|||
static inline void nouveau_unregister_dsm_handler(void) {}
|
||||
static inline void nouveau_switcheroo_optimus_dsm(void) {}
|
||||
static inline void *nouveau_acpi_edid(struct drm_device *dev, struct drm_connector *connector) { return NULL; }
|
||||
static inline bool nouveau_acpi_video_backlight_use_native(void) { return true; }
|
||||
static inline void nouveau_acpi_video_register_backlight(void) {}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
@ -38,6 +38,7 @@
|
|||
#include "nouveau_reg.h"
|
||||
#include "nouveau_encoder.h"
|
||||
#include "nouveau_connector.h"
|
||||
#include "nouveau_acpi.h"
|
||||
|
||||
static struct ida bl_ida;
|
||||
#define BL_NAME_SIZE 15 // 12 for name + 2 for digits + 1 for '\0'
|
||||
|
@ -405,6 +406,11 @@ nouveau_backlight_init(struct drm_connector *connector)
|
|||
goto fail_alloc;
|
||||
}
|
||||
|
||||
if (!nouveau_acpi_video_backlight_use_native()) {
|
||||
NV_INFO(drm, "Skipping nv_backlight registration\n");
|
||||
goto fail_alloc;
|
||||
}
|
||||
|
||||
if (!nouveau_get_backlight_name(backlight_name, bl)) {
|
||||
NV_ERROR(drm, "Failed to retrieve a unique name for the backlight interface\n");
|
||||
goto fail_alloc;
|
||||
|
@ -430,6 +436,13 @@ nouveau_backlight_init(struct drm_connector *connector)
|
|||
|
||||
fail_alloc:
|
||||
kfree(bl);
|
||||
/*
|
||||
* If we get here we have an internal panel, but no nv_backlight,
|
||||
* try registering an ACPI video backlight device instead.
|
||||
*/
|
||||
if (ret == 0)
|
||||
nouveau_acpi_video_register_backlight();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
@ -2451,7 +2451,7 @@ static int dispc_ovl_calc_scaling_44xx(struct dispc_device *dispc,
|
|||
|
||||
*decim_x = DIV_ROUND_UP(width, in_width_max);
|
||||
|
||||
*decim_x = *decim_x > decim_x_min ? *decim_x : decim_x_min;
|
||||
*decim_x = max(*decim_x, decim_x_min);
|
||||
if (*decim_x > *x_predecim)
|
||||
return -EINVAL;
|
||||
|
||||
|
|
|
@ -1176,6 +1176,7 @@ static void __dss_uninit_ports(struct dss_device *dss, unsigned int num_ports)
|
|||
default:
|
||||
break;
|
||||
}
|
||||
of_node_put(port);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1208,11 +1209,13 @@ static int dss_init_ports(struct dss_device *dss)
|
|||
default:
|
||||
break;
|
||||
}
|
||||
of_node_put(port);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
error:
|
||||
of_node_put(port);
|
||||
__dss_uninit_ports(dss, i);
|
||||
return r;
|
||||
}
|
||||
|
|
|
@ -813,10 +813,8 @@ static int omap_dmm_probe(struct platform_device *dev)
|
|||
}
|
||||
|
||||
omap_dmm->irq = platform_get_irq(dev, 0);
|
||||
if (omap_dmm->irq < 0) {
|
||||
dev_err(&dev->dev, "failed to get IRQ resource\n");
|
||||
if (omap_dmm->irq < 0)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
omap_dmm->dev = &dev->dev;
|
||||
|
||||
|
|
|
@ -576,6 +576,7 @@ out_exit:
|
|||
}
|
||||
|
||||
static const struct drm_simple_display_pipe_funcs ili9341_dbi_funcs = {
|
||||
.mode_valid = mipi_dbi_pipe_mode_valid,
|
||||
.enable = ili9341_dbi_enable,
|
||||
.disable = mipi_dbi_pipe_disable,
|
||||
.update = mipi_dbi_pipe_update,
|
||||
|
|
|
@ -32,6 +32,8 @@
|
|||
#include <drm/drm_file.h>
|
||||
#include <drm/radeon_drm.h>
|
||||
|
||||
#include <acpi/video.h>
|
||||
|
||||
#include "atom.h"
|
||||
#include "radeon_atombios.h"
|
||||
#include "radeon.h"
|
||||
|
@ -209,6 +211,11 @@ void radeon_atom_backlight_init(struct radeon_encoder *radeon_encoder,
|
|||
if (!(rdev->mode_info.firmware_flags & ATOM_BIOS_INFO_BL_CONTROLLED_BY_GPU))
|
||||
return;
|
||||
|
||||
if (!acpi_video_backlight_use_native()) {
|
||||
drm_info(dev, "Skipping radeon atom DIG backlight registration\n");
|
||||
return;
|
||||
}
|
||||
|
||||
pdata = kmalloc(sizeof(struct radeon_backlight_privdata), GFP_KERNEL);
|
||||
if (!pdata) {
|
||||
DRM_ERROR("Memory allocation failed\n");
|
||||
|
|
|
@ -34,8 +34,6 @@
|
|||
#include "r600_reg_safe.h"
|
||||
|
||||
static int r600_nomm;
|
||||
extern void r600_cs_legacy_get_tiling_conf(struct drm_device *dev, u32 *npipes, u32 *nbanks, u32 *group_size);
|
||||
|
||||
|
||||
struct r600_cs_track {
|
||||
/* configuration we mirror so that we use same code btw kms/ums */
|
||||
|
|
|
@ -116,7 +116,6 @@ extern int radeon_use_pflipirq;
|
|||
extern int radeon_bapm;
|
||||
extern int radeon_backlight;
|
||||
extern int radeon_auxch;
|
||||
extern int radeon_mst;
|
||||
extern int radeon_uvd;
|
||||
extern int radeon_vce;
|
||||
extern int radeon_si_support;
|
||||
|
@ -2950,8 +2949,6 @@ struct radeon_hdmi_acr {
|
|||
|
||||
};
|
||||
|
||||
extern struct radeon_hdmi_acr r600_hdmi_acr(uint32_t clock);
|
||||
|
||||
extern u32 r6xx_remap_render_backend(struct radeon_device *rdev,
|
||||
u32 tiling_pipe_num,
|
||||
u32 max_rb_num,
|
||||
|
|
|
@ -30,6 +30,8 @@
|
|||
#include <drm/drm_device.h>
|
||||
#include <drm/radeon_drm.h>
|
||||
|
||||
#include <acpi/video.h>
|
||||
|
||||
#include "radeon.h"
|
||||
#include "radeon_atombios.h"
|
||||
#include "radeon_legacy_encoders.h"
|
||||
|
@ -167,7 +169,7 @@ static void radeon_encoder_add_backlight(struct radeon_encoder *radeon_encoder,
|
|||
return;
|
||||
|
||||
if (radeon_backlight == 0) {
|
||||
return;
|
||||
use_bl = false;
|
||||
} else if (radeon_backlight == 1) {
|
||||
use_bl = true;
|
||||
} else if (radeon_backlight == -1) {
|
||||
|
@ -193,6 +195,13 @@ static void radeon_encoder_add_backlight(struct radeon_encoder *radeon_encoder,
|
|||
else
|
||||
radeon_legacy_backlight_init(radeon_encoder, connector);
|
||||
}
|
||||
|
||||
/*
|
||||
* If there is no native backlight device (which may happen even when
|
||||
* use_bl==true) try registering an ACPI video backlight device instead.
|
||||
*/
|
||||
if (!rdev->mode_info.bl_encoder)
|
||||
acpi_video_register_backlight();
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -33,6 +33,8 @@
|
|||
#include <drm/drm_util.h>
|
||||
#include <drm/radeon_drm.h>
|
||||
|
||||
#include <acpi/video.h>
|
||||
|
||||
#include "radeon.h"
|
||||
#include "radeon_asic.h"
|
||||
#include "radeon_legacy_encoders.h"
|
||||
|
@ -387,6 +389,11 @@ void radeon_legacy_backlight_init(struct radeon_encoder *radeon_encoder,
|
|||
return;
|
||||
#endif
|
||||
|
||||
if (!acpi_video_backlight_use_native()) {
|
||||
drm_info(dev, "Skipping radeon legacy LVDS backlight registration\n");
|
||||
return;
|
||||
}
|
||||
|
||||
pdata = kmalloc(sizeof(struct radeon_backlight_privdata), GFP_KERNEL);
|
||||
if (!pdata) {
|
||||
DRM_ERROR("Memory allocation failed\n");
|
||||
|
|
|
@ -874,7 +874,6 @@ extern struct radeon_encoder_tv_dac *
|
|||
radeon_atombios_get_tv_dac_info(struct radeon_encoder *encoder);
|
||||
extern struct radeon_encoder_lvds *
|
||||
radeon_combios_get_lvds_info(struct radeon_encoder *encoder);
|
||||
extern void radeon_combios_get_ext_tmds_info(struct radeon_encoder *encoder);
|
||||
extern struct radeon_encoder_tv_dac *
|
||||
radeon_combios_get_tv_dac_info(struct radeon_encoder *encoder);
|
||||
extern struct radeon_encoder_primary_dac *
|
||||
|
|
|
@ -179,6 +179,23 @@
|
|||
#define RK3399_TXRX_SRC_SEL_ISP0 BIT(4)
|
||||
#define RK3399_TXRX_TURNREQUEST GENMASK(3, 0)
|
||||
|
||||
#define RK3568_GRF_VO_CON2 0x0368
|
||||
#define RK3568_DSI0_SKEWCALHS (0x1f << 11)
|
||||
#define RK3568_DSI0_FORCETXSTOPMODE (0xf << 4)
|
||||
#define RK3568_DSI0_TURNDISABLE BIT(2)
|
||||
#define RK3568_DSI0_FORCERXMODE BIT(0)
|
||||
|
||||
/*
|
||||
* Note these registers do not appear in the datasheet, they are
|
||||
* however present in the BSP driver which is where these values
|
||||
* come from. Name GRF_VO_CON3 is assumed.
|
||||
*/
|
||||
#define RK3568_GRF_VO_CON3 0x36c
|
||||
#define RK3568_DSI1_SKEWCALHS (0x1f << 11)
|
||||
#define RK3568_DSI1_FORCETXSTOPMODE (0xf << 4)
|
||||
#define RK3568_DSI1_TURNDISABLE BIT(2)
|
||||
#define RK3568_DSI1_FORCERXMODE BIT(0)
|
||||
|
||||
#define HIWORD_UPDATE(val, mask) (val | (mask) << 16)
|
||||
|
||||
enum {
|
||||
|
@ -735,8 +752,9 @@ static void dw_mipi_dsi_rockchip_config(struct dw_mipi_dsi_rockchip *dsi)
|
|||
static void dw_mipi_dsi_rockchip_set_lcdsel(struct dw_mipi_dsi_rockchip *dsi,
|
||||
int mux)
|
||||
{
|
||||
regmap_write(dsi->grf_regmap, dsi->cdata->lcdsel_grf_reg,
|
||||
mux ? dsi->cdata->lcdsel_lit : dsi->cdata->lcdsel_big);
|
||||
if (dsi->cdata->lcdsel_grf_reg < 0)
|
||||
regmap_write(dsi->grf_regmap, dsi->cdata->lcdsel_grf_reg,
|
||||
mux ? dsi->cdata->lcdsel_lit : dsi->cdata->lcdsel_big);
|
||||
}
|
||||
|
||||
static int
|
||||
|
@ -963,6 +981,8 @@ static int dw_mipi_dsi_rockchip_bind(struct device *dev,
|
|||
DRM_DEV_ERROR(dev, "Failed to create drm encoder\n");
|
||||
goto out_pll_clk;
|
||||
}
|
||||
rockchip_drm_encoder_set_crtc_endpoint_id(&dsi->encoder,
|
||||
dev->of_node, 0, 0);
|
||||
|
||||
ret = dw_mipi_dsi_bind(dsi->dmd, &dsi->encoder.encoder);
|
||||
if (ret) {
|
||||
|
@ -1612,6 +1632,30 @@ static const struct rockchip_dw_dsi_chip_data rk3399_chip_data[] = {
|
|||
{ /* sentinel */ }
|
||||
};
|
||||
|
||||
static const struct rockchip_dw_dsi_chip_data rk3568_chip_data[] = {
|
||||
{
|
||||
.reg = 0xfe060000,
|
||||
.lcdsel_grf_reg = -1,
|
||||
.lanecfg1_grf_reg = RK3568_GRF_VO_CON2,
|
||||
.lanecfg1 = HIWORD_UPDATE(0, RK3568_DSI0_SKEWCALHS |
|
||||
RK3568_DSI0_FORCETXSTOPMODE |
|
||||
RK3568_DSI0_TURNDISABLE |
|
||||
RK3568_DSI0_FORCERXMODE),
|
||||
.max_data_lanes = 4,
|
||||
},
|
||||
{
|
||||
.reg = 0xfe070000,
|
||||
.lcdsel_grf_reg = -1,
|
||||
.lanecfg1_grf_reg = RK3568_GRF_VO_CON3,
|
||||
.lanecfg1 = HIWORD_UPDATE(0, RK3568_DSI1_SKEWCALHS |
|
||||
RK3568_DSI1_FORCETXSTOPMODE |
|
||||
RK3568_DSI1_TURNDISABLE |
|
||||
RK3568_DSI1_FORCERXMODE),
|
||||
.max_data_lanes = 4,
|
||||
},
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
|
||||
static const struct of_device_id dw_mipi_dsi_rockchip_dt_ids[] = {
|
||||
{
|
||||
.compatible = "rockchip,px30-mipi-dsi",
|
||||
|
@ -1622,6 +1666,9 @@ static const struct of_device_id dw_mipi_dsi_rockchip_dt_ids[] = {
|
|||
}, {
|
||||
.compatible = "rockchip,rk3399-mipi-dsi",
|
||||
.data = &rk3399_chip_data,
|
||||
}, {
|
||||
.compatible = "rockchip,rk3568-mipi-dsi",
|
||||
.data = &rk3568_chip_data,
|
||||
},
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
#include <linux/delay.h>
|
||||
#include <linux/iopoll.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/log2.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_device.h>
|
||||
|
@ -67,6 +68,9 @@
|
|||
#define VOP_REG_SET(vop, group, name, v) \
|
||||
vop_reg_set(vop, &vop->data->group->name, 0, ~0, v, #name)
|
||||
|
||||
#define VOP_HAS_REG(vop, group, name) \
|
||||
(!!(vop->data->group->name.mask))
|
||||
|
||||
#define VOP_INTR_SET_TYPE(vop, name, type, v) \
|
||||
do { \
|
||||
int i, reg = 0, mask = 0; \
|
||||
|
@ -184,12 +188,6 @@ struct vop {
|
|||
struct vop_win win[];
|
||||
};
|
||||
|
||||
static inline void vop_writel(struct vop *vop, uint32_t offset, uint32_t v)
|
||||
{
|
||||
writel(v, vop->regs + offset);
|
||||
vop->regsbak[offset >> 2] = v;
|
||||
}
|
||||
|
||||
static inline uint32_t vop_readl(struct vop *vop, uint32_t offset)
|
||||
{
|
||||
return readl(vop->regs + offset);
|
||||
|
@ -1188,7 +1186,7 @@ static bool vop_crtc_mode_fixup(struct drm_crtc *crtc,
|
|||
*
|
||||
* Key points:
|
||||
*
|
||||
* - DRM works in in kHz.
|
||||
* - DRM works in kHz.
|
||||
* - Clock framework works in Hz.
|
||||
* - Rockchip's clock driver picks the clock rate that is the
|
||||
* same _OR LOWER_ than the one requested.
|
||||
|
@ -1223,17 +1221,22 @@ static bool vop_dsp_lut_is_enabled(struct vop *vop)
|
|||
return vop_read_reg(vop, 0, &vop->data->common->dsp_lut_en);
|
||||
}
|
||||
|
||||
static u32 vop_lut_buffer_index(struct vop *vop)
|
||||
{
|
||||
return vop_read_reg(vop, 0, &vop->data->common->lut_buffer_index);
|
||||
}
|
||||
|
||||
static void vop_crtc_write_gamma_lut(struct vop *vop, struct drm_crtc *crtc)
|
||||
{
|
||||
struct drm_color_lut *lut = crtc->state->gamma_lut->data;
|
||||
unsigned int i;
|
||||
unsigned int i, bpc = ilog2(vop->data->lut_size);
|
||||
|
||||
for (i = 0; i < crtc->gamma_size; i++) {
|
||||
u32 word;
|
||||
|
||||
word = (drm_color_lut_extract(lut[i].red, 10) << 20) |
|
||||
(drm_color_lut_extract(lut[i].green, 10) << 10) |
|
||||
drm_color_lut_extract(lut[i].blue, 10);
|
||||
word = (drm_color_lut_extract(lut[i].red, bpc) << (2 * bpc)) |
|
||||
(drm_color_lut_extract(lut[i].green, bpc) << bpc) |
|
||||
drm_color_lut_extract(lut[i].blue, bpc);
|
||||
writel(word, vop->lut_regs + i * 4);
|
||||
}
|
||||
}
|
||||
|
@ -1243,38 +1246,66 @@ static void vop_crtc_gamma_set(struct vop *vop, struct drm_crtc *crtc,
|
|||
{
|
||||
struct drm_crtc_state *state = crtc->state;
|
||||
unsigned int idle;
|
||||
u32 lut_idx, old_idx;
|
||||
int ret;
|
||||
|
||||
if (!vop->lut_regs)
|
||||
return;
|
||||
/*
|
||||
* To disable gamma (gamma_lut is null) or to write
|
||||
* an update to the LUT, clear dsp_lut_en.
|
||||
*/
|
||||
spin_lock(&vop->reg_lock);
|
||||
VOP_REG_SET(vop, common, dsp_lut_en, 0);
|
||||
vop_cfg_done(vop);
|
||||
spin_unlock(&vop->reg_lock);
|
||||
|
||||
/*
|
||||
* In order to write the LUT to the internal memory,
|
||||
* we need to first make sure the dsp_lut_en bit is cleared.
|
||||
*/
|
||||
ret = readx_poll_timeout(vop_dsp_lut_is_enabled, vop,
|
||||
idle, !idle, 5, 30 * 1000);
|
||||
if (ret) {
|
||||
DRM_DEV_ERROR(vop->dev, "display LUT RAM enable timeout!\n");
|
||||
return;
|
||||
if (!state->gamma_lut || !VOP_HAS_REG(vop, common, update_gamma_lut)) {
|
||||
/*
|
||||
* To disable gamma (gamma_lut is null) or to write
|
||||
* an update to the LUT, clear dsp_lut_en.
|
||||
*/
|
||||
spin_lock(&vop->reg_lock);
|
||||
VOP_REG_SET(vop, common, dsp_lut_en, 0);
|
||||
vop_cfg_done(vop);
|
||||
spin_unlock(&vop->reg_lock);
|
||||
|
||||
/*
|
||||
* In order to write the LUT to the internal memory,
|
||||
* we need to first make sure the dsp_lut_en bit is cleared.
|
||||
*/
|
||||
ret = readx_poll_timeout(vop_dsp_lut_is_enabled, vop,
|
||||
idle, !idle, 5, 30 * 1000);
|
||||
if (ret) {
|
||||
DRM_DEV_ERROR(vop->dev, "display LUT RAM enable timeout!\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!state->gamma_lut)
|
||||
return;
|
||||
} else {
|
||||
/*
|
||||
* On RK3399 the gamma LUT can updated without clearing dsp_lut_en,
|
||||
* by setting update_gamma_lut then waiting for lut_buffer_index change
|
||||
*/
|
||||
old_idx = vop_lut_buffer_index(vop);
|
||||
}
|
||||
|
||||
if (!state->gamma_lut)
|
||||
return;
|
||||
|
||||
spin_lock(&vop->reg_lock);
|
||||
vop_crtc_write_gamma_lut(vop, crtc);
|
||||
VOP_REG_SET(vop, common, dsp_lut_en, 1);
|
||||
VOP_REG_SET(vop, common, update_gamma_lut, 1);
|
||||
vop_cfg_done(vop);
|
||||
spin_unlock(&vop->reg_lock);
|
||||
|
||||
if (VOP_HAS_REG(vop, common, update_gamma_lut)) {
|
||||
ret = readx_poll_timeout(vop_lut_buffer_index, vop,
|
||||
lut_idx, lut_idx != old_idx, 5, 30 * 1000);
|
||||
if (ret) {
|
||||
DRM_DEV_ERROR(vop->dev, "gamma LUT update timeout!\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* update_gamma_lut is auto cleared by HW, but write 0 to clear the bit
|
||||
* in our backup of the regs.
|
||||
*/
|
||||
spin_lock(&vop->reg_lock);
|
||||
VOP_REG_SET(vop, common, update_gamma_lut, 0);
|
||||
spin_unlock(&vop->reg_lock);
|
||||
}
|
||||
}
|
||||
|
||||
static void vop_crtc_atomic_begin(struct drm_crtc *crtc,
|
||||
|
@ -1324,14 +1355,6 @@ static void vop_crtc_atomic_enable(struct drm_crtc *crtc,
|
|||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* If we have a GAMMA LUT in the state, then let's make sure
|
||||
* it's updated. We might be coming out of suspend,
|
||||
* which means the LUT internal memory needs to be re-written.
|
||||
*/
|
||||
if (crtc->state->gamma_lut)
|
||||
vop_crtc_gamma_set(vop, crtc, old_state);
|
||||
|
||||
mutex_lock(&vop->vop_lock);
|
||||
|
||||
WARN_ON(vop->event);
|
||||
|
@ -1422,6 +1445,14 @@ static void vop_crtc_atomic_enable(struct drm_crtc *crtc,
|
|||
|
||||
VOP_REG_SET(vop, common, standby, 0);
|
||||
mutex_unlock(&vop->vop_lock);
|
||||
|
||||
/*
|
||||
* If we have a GAMMA LUT in the state, then let's make sure
|
||||
* it's updated. We might be coming out of suspend,
|
||||
* which means the LUT internal memory needs to be re-written.
|
||||
*/
|
||||
if (crtc->state->gamma_lut)
|
||||
vop_crtc_gamma_set(vop, crtc, old_state);
|
||||
}
|
||||
|
||||
static bool vop_fs_irq_is_pending(struct vop *vop)
|
||||
|
@ -2147,8 +2178,8 @@ static int vop_bind(struct device *dev, struct device *master, void *data)
|
|||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
|
||||
if (res) {
|
||||
if (!vop_data->lut_size) {
|
||||
DRM_DEV_ERROR(dev, "no gamma LUT size defined\n");
|
||||
if (vop_data->lut_size != 1024 && vop_data->lut_size != 256) {
|
||||
DRM_DEV_ERROR(dev, "unsupported gamma LUT size %d\n", vop_data->lut_size);
|
||||
return -EINVAL;
|
||||
}
|
||||
vop->lut_regs = devm_ioremap_resource(dev, res);
|
||||
|
|
|
@ -113,6 +113,8 @@ struct vop_common {
|
|||
struct vop_reg dither_down_en;
|
||||
struct vop_reg dither_up;
|
||||
struct vop_reg dsp_lut_en;
|
||||
struct vop_reg update_gamma_lut;
|
||||
struct vop_reg lut_buffer_index;
|
||||
struct vop_reg gate_en;
|
||||
struct vop_reg mmu_en;
|
||||
struct vop_reg out_mode;
|
||||
|
|
|
@ -875,6 +875,24 @@ static const struct vop_output rk3399_output = {
|
|||
.mipi_dual_channel_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 3),
|
||||
};
|
||||
|
||||
static const struct vop_common rk3399_common = {
|
||||
.standby = VOP_REG_SYNC(RK3399_SYS_CTRL, 0x1, 22),
|
||||
.gate_en = VOP_REG(RK3399_SYS_CTRL, 0x1, 23),
|
||||
.mmu_en = VOP_REG(RK3399_SYS_CTRL, 0x1, 20),
|
||||
.dither_down_sel = VOP_REG(RK3399_DSP_CTRL1, 0x1, 4),
|
||||
.dither_down_mode = VOP_REG(RK3399_DSP_CTRL1, 0x1, 3),
|
||||
.dither_down_en = VOP_REG(RK3399_DSP_CTRL1, 0x1, 2),
|
||||
.pre_dither_down = VOP_REG(RK3399_DSP_CTRL1, 0x1, 1),
|
||||
.dither_up = VOP_REG(RK3399_DSP_CTRL1, 0x1, 6),
|
||||
.dsp_lut_en = VOP_REG(RK3399_DSP_CTRL1, 0x1, 0),
|
||||
.update_gamma_lut = VOP_REG(RK3399_DSP_CTRL1, 0x1, 7),
|
||||
.lut_buffer_index = VOP_REG(RK3399_DBG_POST_REG1, 0x1, 1),
|
||||
.data_blank = VOP_REG(RK3399_DSP_CTRL0, 0x1, 19),
|
||||
.dsp_blank = VOP_REG(RK3399_DSP_CTRL0, 0x3, 18),
|
||||
.out_mode = VOP_REG(RK3399_DSP_CTRL0, 0xf, 0),
|
||||
.cfg_done = VOP_REG_SYNC(RK3399_REG_CFG_DONE, 0x1, 0),
|
||||
};
|
||||
|
||||
static const struct vop_yuv2yuv_phy rk3399_yuv2yuv_win01_data = {
|
||||
.y2r_coefficients = {
|
||||
VOP_REG(RK3399_WIN0_YUV2YUV_Y2R + 0, 0xffff, 0),
|
||||
|
@ -957,7 +975,7 @@ static const struct vop_data rk3399_vop_big = {
|
|||
.version = VOP_VERSION(3, 5),
|
||||
.feature = VOP_FEATURE_OUTPUT_RGB10,
|
||||
.intr = &rk3366_vop_intr,
|
||||
.common = &rk3288_common,
|
||||
.common = &rk3399_common,
|
||||
.modeset = &rk3288_modeset,
|
||||
.output = &rk3399_output,
|
||||
.afbc = &rk3399_vop_afbc,
|
||||
|
@ -965,6 +983,7 @@ static const struct vop_data rk3399_vop_big = {
|
|||
.win = rk3399_vop_win_data,
|
||||
.win_size = ARRAY_SIZE(rk3399_vop_win_data),
|
||||
.win_yuv2yuv = rk3399_vop_big_win_yuv2yuv_data,
|
||||
.lut_size = 1024,
|
||||
};
|
||||
|
||||
static const struct vop_win_data rk3399_vop_lit_win_data[] = {
|
||||
|
@ -983,13 +1002,14 @@ static const struct vop_win_yuv2yuv_data rk3399_vop_lit_win_yuv2yuv_data[] = {
|
|||
static const struct vop_data rk3399_vop_lit = {
|
||||
.version = VOP_VERSION(3, 6),
|
||||
.intr = &rk3366_vop_intr,
|
||||
.common = &rk3288_common,
|
||||
.common = &rk3399_common,
|
||||
.modeset = &rk3288_modeset,
|
||||
.output = &rk3399_output,
|
||||
.misc = &rk3368_misc,
|
||||
.win = rk3399_vop_lit_win_data,
|
||||
.win_size = ARRAY_SIZE(rk3399_vop_lit_win_data),
|
||||
.win_yuv2yuv = rk3399_vop_lit_win_yuv2yuv_data,
|
||||
.lut_size = 256,
|
||||
};
|
||||
|
||||
static const struct vop_win_data rk3228_vop_win_data[] = {
|
||||
|
|
|
@ -628,6 +628,7 @@
|
|||
#define RK3399_YUV2YUV_WIN 0x02c0
|
||||
#define RK3399_YUV2YUV_POST 0x02c4
|
||||
#define RK3399_AUTO_GATING_EN 0x02cc
|
||||
#define RK3399_DBG_POST_REG1 0x036c
|
||||
#define RK3399_WIN0_CSC_COE 0x03a0
|
||||
#define RK3399_WIN1_CSC_COE 0x03c0
|
||||
#define RK3399_WIN2_CSC_COE 0x03e0
|
||||
|
|
|
@ -829,7 +829,7 @@ drm_sched_get_cleanup_job(struct drm_gpu_scheduler *sched)
|
|||
job = list_first_entry_or_null(&sched->pending_list,
|
||||
struct drm_sched_job, list);
|
||||
|
||||
if (job && dma_fence_is_signaled(&job->s_fence->finished)) {
|
||||
if (job && dma_fence_is_signaled(job->s_fence->parent)) {
|
||||
/* remove job from pending_list */
|
||||
list_del_init(&job->list);
|
||||
|
||||
|
@ -841,7 +841,7 @@ drm_sched_get_cleanup_job(struct drm_gpu_scheduler *sched)
|
|||
|
||||
if (next) {
|
||||
next->s_fence->scheduled.timestamp =
|
||||
job->s_fence->finished.timestamp;
|
||||
job->s_fence->parent->timestamp;
|
||||
/* start TO timer for next job */
|
||||
drm_sched_start_timeout(sched);
|
||||
}
|
||||
|
|
|
@ -252,9 +252,10 @@ int shmob_drm_plane_create(struct shmob_drm_device *sdev, unsigned int index)
|
|||
splane->index = index;
|
||||
splane->alpha = 255;
|
||||
|
||||
ret = drm_plane_init(sdev->ddev, &splane->plane, 1,
|
||||
&shmob_drm_plane_funcs, formats,
|
||||
ARRAY_SIZE(formats), false);
|
||||
ret = drm_universal_plane_init(sdev->ddev, &splane->plane, 1,
|
||||
&shmob_drm_plane_funcs,
|
||||
formats, ARRAY_SIZE(formats), NULL,
|
||||
DRM_PLANE_TYPE_OVERLAY, NULL);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -565,22 +565,6 @@ static int ssd130x_fb_blit_rect(struct drm_framebuffer *fb, const struct iosys_m
|
|||
return ret;
|
||||
}
|
||||
|
||||
static int ssd130x_primary_plane_helper_atomic_check(struct drm_plane *plane,
|
||||
struct drm_atomic_state *new_state)
|
||||
{
|
||||
struct drm_plane_state *new_plane_state = drm_atomic_get_new_plane_state(new_state, plane);
|
||||
struct drm_crtc *new_crtc = new_plane_state->crtc;
|
||||
struct drm_crtc_state *new_crtc_state = NULL;
|
||||
|
||||
if (new_crtc)
|
||||
new_crtc_state = drm_atomic_get_new_crtc_state(new_state, new_crtc);
|
||||
|
||||
return drm_atomic_helper_check_plane_state(new_plane_state, new_crtc_state,
|
||||
DRM_PLANE_NO_SCALING,
|
||||
DRM_PLANE_NO_SCALING,
|
||||
false, false);
|
||||
}
|
||||
|
||||
static void ssd130x_primary_plane_helper_atomic_update(struct drm_plane *plane,
|
||||
struct drm_atomic_state *old_state)
|
||||
{
|
||||
|
@ -623,7 +607,7 @@ static void ssd130x_primary_plane_helper_atomic_disable(struct drm_plane *plane,
|
|||
|
||||
static const struct drm_plane_helper_funcs ssd130x_primary_plane_helper_funcs = {
|
||||
DRM_GEM_SHADOW_PLANE_HELPER_FUNCS,
|
||||
.atomic_check = ssd130x_primary_plane_helper_atomic_check,
|
||||
.atomic_check = drm_plane_helper_atomic_check,
|
||||
.atomic_update = ssd130x_primary_plane_helper_atomic_update,
|
||||
.atomic_disable = ssd130x_primary_plane_helper_atomic_disable,
|
||||
};
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
|
||||
#include "../lib/drm_random.h"
|
||||
|
||||
#define IGT_TIMEOUT(name__) \
|
||||
#define TIMEOUT(name__) \
|
||||
unsigned long name__ = jiffies + MAX_SCHEDULE_TIMEOUT
|
||||
|
||||
static unsigned int random_seed;
|
||||
|
@ -24,7 +24,7 @@ static inline u64 get_size(int order, u64 chunk_size)
|
|||
}
|
||||
|
||||
__printf(2, 3)
|
||||
static bool __igt_timeout(unsigned long timeout, const char *fmt, ...)
|
||||
static bool __timeout(unsigned long timeout, const char *fmt, ...)
|
||||
{
|
||||
va_list va;
|
||||
|
||||
|
@ -43,8 +43,8 @@ static bool __igt_timeout(unsigned long timeout, const char *fmt, ...)
|
|||
return true;
|
||||
}
|
||||
|
||||
static void __igt_dump_block(struct kunit *test, struct drm_buddy *mm,
|
||||
struct drm_buddy_block *block, bool buddy)
|
||||
static void __dump_block(struct kunit *test, struct drm_buddy *mm,
|
||||
struct drm_buddy_block *block, bool buddy)
|
||||
{
|
||||
kunit_err(test, "block info: header=%llx, state=%u, order=%d, offset=%llx size=%llx root=%d buddy=%d\n",
|
||||
block->header, drm_buddy_block_state(block),
|
||||
|
@ -52,20 +52,20 @@ static void __igt_dump_block(struct kunit *test, struct drm_buddy *mm,
|
|||
drm_buddy_block_size(mm, block), !block->parent, buddy);
|
||||
}
|
||||
|
||||
static void igt_dump_block(struct kunit *test, struct drm_buddy *mm,
|
||||
struct drm_buddy_block *block)
|
||||
static void dump_block(struct kunit *test, struct drm_buddy *mm,
|
||||
struct drm_buddy_block *block)
|
||||
{
|
||||
struct drm_buddy_block *buddy;
|
||||
|
||||
__igt_dump_block(test, mm, block, false);
|
||||
__dump_block(test, mm, block, false);
|
||||
|
||||
buddy = drm_get_buddy(block);
|
||||
if (buddy)
|
||||
__igt_dump_block(test, mm, buddy, true);
|
||||
__dump_block(test, mm, buddy, true);
|
||||
}
|
||||
|
||||
static int igt_check_block(struct kunit *test, struct drm_buddy *mm,
|
||||
struct drm_buddy_block *block)
|
||||
static int check_block(struct kunit *test, struct drm_buddy *mm,
|
||||
struct drm_buddy_block *block)
|
||||
{
|
||||
struct drm_buddy_block *buddy;
|
||||
unsigned int block_state;
|
||||
|
@ -137,8 +137,8 @@ static int igt_check_block(struct kunit *test, struct drm_buddy *mm,
|
|||
return err;
|
||||
}
|
||||
|
||||
static int igt_check_blocks(struct kunit *test, struct drm_buddy *mm,
|
||||
struct list_head *blocks, u64 expected_size, bool is_contiguous)
|
||||
static int check_blocks(struct kunit *test, struct drm_buddy *mm,
|
||||
struct list_head *blocks, u64 expected_size, bool is_contiguous)
|
||||
{
|
||||
struct drm_buddy_block *block;
|
||||
struct drm_buddy_block *prev;
|
||||
|
@ -150,7 +150,7 @@ static int igt_check_blocks(struct kunit *test, struct drm_buddy *mm,
|
|||
total = 0;
|
||||
|
||||
list_for_each_entry(block, blocks, link) {
|
||||
err = igt_check_block(test, mm, block);
|
||||
err = check_block(test, mm, block);
|
||||
|
||||
if (!drm_buddy_block_is_allocated(block)) {
|
||||
kunit_err(test, "block not allocated\n");
|
||||
|
@ -190,16 +190,16 @@ static int igt_check_blocks(struct kunit *test, struct drm_buddy *mm,
|
|||
|
||||
if (prev) {
|
||||
kunit_err(test, "prev block, dump:\n");
|
||||
igt_dump_block(test, mm, prev);
|
||||
dump_block(test, mm, prev);
|
||||
}
|
||||
|
||||
kunit_err(test, "bad block, dump:\n");
|
||||
igt_dump_block(test, mm, block);
|
||||
dump_block(test, mm, block);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static int igt_check_mm(struct kunit *test, struct drm_buddy *mm)
|
||||
static int check_mm(struct kunit *test, struct drm_buddy *mm)
|
||||
{
|
||||
struct drm_buddy_block *root;
|
||||
struct drm_buddy_block *prev;
|
||||
|
@ -233,7 +233,7 @@ static int igt_check_mm(struct kunit *test, struct drm_buddy *mm)
|
|||
break;
|
||||
}
|
||||
|
||||
err = igt_check_block(test, mm, root);
|
||||
err = check_block(test, mm, root);
|
||||
|
||||
if (!drm_buddy_block_is_free(root)) {
|
||||
kunit_err(test, "root not free\n");
|
||||
|
@ -289,18 +289,18 @@ static int igt_check_mm(struct kunit *test, struct drm_buddy *mm)
|
|||
|
||||
if (prev) {
|
||||
kunit_err(test, "prev root(%u), dump:\n", i - 1);
|
||||
igt_dump_block(test, mm, prev);
|
||||
dump_block(test, mm, prev);
|
||||
}
|
||||
|
||||
if (root) {
|
||||
kunit_err(test, "bad root(%u), dump:\n", i);
|
||||
igt_dump_block(test, mm, root);
|
||||
dump_block(test, mm, root);
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static void igt_mm_config(u64 *size, u64 *chunk_size)
|
||||
static void mm_config(u64 *size, u64 *chunk_size)
|
||||
{
|
||||
DRM_RND_STATE(prng, random_seed);
|
||||
u32 s, ms;
|
||||
|
@ -321,7 +321,7 @@ static void igt_mm_config(u64 *size, u64 *chunk_size)
|
|||
*size = (u64)s << 12;
|
||||
}
|
||||
|
||||
static void igt_buddy_alloc_pathological(struct kunit *test)
|
||||
static void drm_test_buddy_alloc_pathological(struct kunit *test)
|
||||
{
|
||||
u64 mm_size, size, start = 0;
|
||||
struct drm_buddy_block *block;
|
||||
|
@ -402,7 +402,7 @@ static void igt_buddy_alloc_pathological(struct kunit *test)
|
|||
drm_buddy_fini(&mm);
|
||||
}
|
||||
|
||||
static void igt_buddy_alloc_smoke(struct kunit *test)
|
||||
static void drm_test_buddy_alloc_smoke(struct kunit *test)
|
||||
{
|
||||
u64 mm_size, chunk_size, start = 0;
|
||||
unsigned long flags = 0;
|
||||
|
@ -411,9 +411,9 @@ static void igt_buddy_alloc_smoke(struct kunit *test)
|
|||
int i;
|
||||
|
||||
DRM_RND_STATE(prng, random_seed);
|
||||
IGT_TIMEOUT(end_time);
|
||||
TIMEOUT(end_time);
|
||||
|
||||
igt_mm_config(&mm_size, &chunk_size);
|
||||
mm_config(&mm_size, &chunk_size);
|
||||
|
||||
KUNIT_ASSERT_FALSE_MSG(test, drm_buddy_init(&mm, mm_size, chunk_size),
|
||||
"buddy_init failed\n");
|
||||
|
@ -430,7 +430,7 @@ static void igt_buddy_alloc_smoke(struct kunit *test)
|
|||
LIST_HEAD(tmp);
|
||||
int order, err;
|
||||
|
||||
KUNIT_ASSERT_FALSE_MSG(test, igt_check_mm(test, &mm),
|
||||
KUNIT_ASSERT_FALSE_MSG(test, check_mm(test, &mm),
|
||||
"pre-mm check failed, abort\n");
|
||||
|
||||
order = max_order;
|
||||
|
@ -466,19 +466,19 @@ retry:
|
|||
|
||||
total += drm_buddy_block_size(&mm, block);
|
||||
|
||||
if (__igt_timeout(end_time, NULL)) {
|
||||
if (__timeout(end_time, NULL)) {
|
||||
timeout = true;
|
||||
break;
|
||||
}
|
||||
} while (total < mm.size);
|
||||
|
||||
if (!err)
|
||||
err = igt_check_blocks(test, &mm, &blocks, total, false);
|
||||
err = check_blocks(test, &mm, &blocks, total, false);
|
||||
|
||||
drm_buddy_free_list(&mm, &blocks);
|
||||
|
||||
if (!err) {
|
||||
KUNIT_EXPECT_FALSE_MSG(test, igt_check_mm(test, &mm),
|
||||
KUNIT_EXPECT_FALSE_MSG(test, check_mm(test, &mm),
|
||||
"post-mm check failed\n");
|
||||
}
|
||||
|
||||
|
@ -492,7 +492,7 @@ retry:
|
|||
drm_buddy_fini(&mm);
|
||||
}
|
||||
|
||||
static void igt_buddy_alloc_pessimistic(struct kunit *test)
|
||||
static void drm_test_buddy_alloc_pessimistic(struct kunit *test)
|
||||
{
|
||||
u64 mm_size, size, start = 0;
|
||||
struct drm_buddy_block *block, *bn;
|
||||
|
@ -587,7 +587,7 @@ static void igt_buddy_alloc_pessimistic(struct kunit *test)
|
|||
drm_buddy_fini(&mm);
|
||||
}
|
||||
|
||||
static void igt_buddy_alloc_optimistic(struct kunit *test)
|
||||
static void drm_test_buddy_alloc_optimistic(struct kunit *test)
|
||||
{
|
||||
u64 mm_size, size, start = 0;
|
||||
struct drm_buddy_block *block;
|
||||
|
@ -633,7 +633,7 @@ static void igt_buddy_alloc_optimistic(struct kunit *test)
|
|||
drm_buddy_fini(&mm);
|
||||
}
|
||||
|
||||
static void igt_buddy_alloc_range(struct kunit *test)
|
||||
static void drm_test_buddy_alloc_range(struct kunit *test)
|
||||
{
|
||||
unsigned long flags = DRM_BUDDY_RANGE_ALLOCATION;
|
||||
u64 offset, size, rem, chunk_size, end;
|
||||
|
@ -641,12 +641,12 @@ static void igt_buddy_alloc_range(struct kunit *test)
|
|||
struct drm_buddy mm;
|
||||
LIST_HEAD(blocks);
|
||||
|
||||
igt_mm_config(&size, &chunk_size);
|
||||
mm_config(&size, &chunk_size);
|
||||
|
||||
KUNIT_ASSERT_FALSE_MSG(test, drm_buddy_init(&mm, size, chunk_size),
|
||||
"buddy_init failed");
|
||||
|
||||
KUNIT_ASSERT_FALSE_MSG(test, igt_check_mm(test, &mm),
|
||||
KUNIT_ASSERT_FALSE_MSG(test, check_mm(test, &mm),
|
||||
"pre-mm check failed, abort!");
|
||||
|
||||
rem = mm.size;
|
||||
|
@ -671,7 +671,7 @@ static void igt_buddy_alloc_range(struct kunit *test)
|
|||
"alloc_range start offset mismatch, found=%llx, expected=%llx\n",
|
||||
drm_buddy_block_offset(block), offset);
|
||||
|
||||
KUNIT_ASSERT_FALSE(test, igt_check_blocks(test, &mm, &tmp, size, true));
|
||||
KUNIT_ASSERT_FALSE(test, check_blocks(test, &mm, &tmp, size, true));
|
||||
|
||||
list_splice_tail(&tmp, &blocks);
|
||||
|
||||
|
@ -686,12 +686,12 @@ static void igt_buddy_alloc_range(struct kunit *test)
|
|||
|
||||
drm_buddy_free_list(&mm, &blocks);
|
||||
|
||||
KUNIT_EXPECT_FALSE_MSG(test, igt_check_mm(test, &mm), "post-mm check failed\n");
|
||||
KUNIT_EXPECT_FALSE_MSG(test, check_mm(test, &mm), "post-mm check failed\n");
|
||||
|
||||
drm_buddy_fini(&mm);
|
||||
}
|
||||
|
||||
static void igt_buddy_alloc_limit(struct kunit *test)
|
||||
static void drm_test_buddy_alloc_limit(struct kunit *test)
|
||||
{
|
||||
u64 size = U64_MAX, start = 0;
|
||||
struct drm_buddy_block *block;
|
||||
|
@ -735,12 +735,12 @@ static int drm_buddy_init_test(struct kunit *test)
|
|||
}
|
||||
|
||||
static struct kunit_case drm_buddy_tests[] = {
|
||||
KUNIT_CASE(igt_buddy_alloc_limit),
|
||||
KUNIT_CASE(igt_buddy_alloc_range),
|
||||
KUNIT_CASE(igt_buddy_alloc_optimistic),
|
||||
KUNIT_CASE(igt_buddy_alloc_pessimistic),
|
||||
KUNIT_CASE(igt_buddy_alloc_smoke),
|
||||
KUNIT_CASE(igt_buddy_alloc_pathological),
|
||||
KUNIT_CASE(drm_test_buddy_alloc_limit),
|
||||
KUNIT_CASE(drm_test_buddy_alloc_range),
|
||||
KUNIT_CASE(drm_test_buddy_alloc_optimistic),
|
||||
KUNIT_CASE(drm_test_buddy_alloc_pessimistic),
|
||||
KUNIT_CASE(drm_test_buddy_alloc_smoke),
|
||||
KUNIT_CASE(drm_test_buddy_alloc_pathological),
|
||||
{}
|
||||
};
|
||||
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
|
||||
static const struct drm_connector no_connector = {};
|
||||
|
||||
static void drm_cmdline_test_force_e_only(struct kunit *test)
|
||||
static void drm_test_cmdline_force_e_only(struct kunit *test)
|
||||
{
|
||||
struct drm_cmdline_mode mode = { };
|
||||
const char *cmdline = "e";
|
||||
|
@ -29,7 +29,7 @@ static void drm_cmdline_test_force_e_only(struct kunit *test)
|
|||
KUNIT_EXPECT_EQ(test, mode.force, DRM_FORCE_ON);
|
||||
}
|
||||
|
||||
static void drm_cmdline_test_force_D_only_not_digital(struct kunit *test)
|
||||
static void drm_test_cmdline_force_D_only_not_digital(struct kunit *test)
|
||||
{
|
||||
struct drm_cmdline_mode mode = { };
|
||||
const char *cmdline = "D";
|
||||
|
@ -51,7 +51,7 @@ static const struct drm_connector connector_hdmi = {
|
|||
.connector_type = DRM_MODE_CONNECTOR_HDMIB,
|
||||
};
|
||||
|
||||
static void drm_cmdline_test_force_D_only_hdmi(struct kunit *test)
|
||||
static void drm_test_cmdline_force_D_only_hdmi(struct kunit *test)
|
||||
{
|
||||
struct drm_cmdline_mode mode = { };
|
||||
const char *cmdline = "D";
|
||||
|
@ -73,7 +73,7 @@ static const struct drm_connector connector_dvi = {
|
|||
.connector_type = DRM_MODE_CONNECTOR_DVII,
|
||||
};
|
||||
|
||||
static void drm_cmdline_test_force_D_only_dvi(struct kunit *test)
|
||||
static void drm_test_cmdline_force_D_only_dvi(struct kunit *test)
|
||||
{
|
||||
struct drm_cmdline_mode mode = { };
|
||||
const char *cmdline = "D";
|
||||
|
@ -91,7 +91,7 @@ static void drm_cmdline_test_force_D_only_dvi(struct kunit *test)
|
|||
KUNIT_EXPECT_EQ(test, mode.force, DRM_FORCE_ON_DIGITAL);
|
||||
}
|
||||
|
||||
static void drm_cmdline_test_force_d_only(struct kunit *test)
|
||||
static void drm_test_cmdline_force_d_only(struct kunit *test)
|
||||
{
|
||||
struct drm_cmdline_mode mode = { };
|
||||
const char *cmdline = "d";
|
||||
|
@ -109,7 +109,7 @@ static void drm_cmdline_test_force_d_only(struct kunit *test)
|
|||
KUNIT_EXPECT_EQ(test, mode.force, DRM_FORCE_OFF);
|
||||
}
|
||||
|
||||
static void drm_cmdline_test_res(struct kunit *test)
|
||||
static void drm_test_cmdline_res(struct kunit *test)
|
||||
{
|
||||
struct drm_cmdline_mode mode = { };
|
||||
const char *cmdline = "720x480";
|
||||
|
@ -131,7 +131,7 @@ static void drm_cmdline_test_res(struct kunit *test)
|
|||
KUNIT_EXPECT_EQ(test, mode.force, DRM_FORCE_UNSPECIFIED);
|
||||
}
|
||||
|
||||
static void drm_cmdline_test_res_vesa(struct kunit *test)
|
||||
static void drm_test_cmdline_res_vesa(struct kunit *test)
|
||||
{
|
||||
struct drm_cmdline_mode mode = { };
|
||||
const char *cmdline = "720x480M";
|
||||
|
@ -153,7 +153,7 @@ static void drm_cmdline_test_res_vesa(struct kunit *test)
|
|||
KUNIT_EXPECT_EQ(test, mode.force, DRM_FORCE_UNSPECIFIED);
|
||||
}
|
||||
|
||||
static void drm_cmdline_test_res_vesa_rblank(struct kunit *test)
|
||||
static void drm_test_cmdline_res_vesa_rblank(struct kunit *test)
|
||||
{
|
||||
struct drm_cmdline_mode mode = { };
|
||||
const char *cmdline = "720x480MR";
|
||||
|
@ -175,7 +175,7 @@ static void drm_cmdline_test_res_vesa_rblank(struct kunit *test)
|
|||
KUNIT_EXPECT_EQ(test, mode.force, DRM_FORCE_UNSPECIFIED);
|
||||
}
|
||||
|
||||
static void drm_cmdline_test_res_rblank(struct kunit *test)
|
||||
static void drm_test_cmdline_res_rblank(struct kunit *test)
|
||||
{
|
||||
struct drm_cmdline_mode mode = { };
|
||||
const char *cmdline = "720x480R";
|
||||
|
@ -197,7 +197,7 @@ static void drm_cmdline_test_res_rblank(struct kunit *test)
|
|||
KUNIT_EXPECT_EQ(test, mode.force, DRM_FORCE_UNSPECIFIED);
|
||||
}
|
||||
|
||||
static void drm_cmdline_test_res_bpp(struct kunit *test)
|
||||
static void drm_test_cmdline_res_bpp(struct kunit *test)
|
||||
{
|
||||
struct drm_cmdline_mode mode = { };
|
||||
const char *cmdline = "720x480-24";
|
||||
|
@ -220,7 +220,7 @@ static void drm_cmdline_test_res_bpp(struct kunit *test)
|
|||
KUNIT_EXPECT_EQ(test, mode.force, DRM_FORCE_UNSPECIFIED);
|
||||
}
|
||||
|
||||
static void drm_cmdline_test_res_refresh(struct kunit *test)
|
||||
static void drm_test_cmdline_res_refresh(struct kunit *test)
|
||||
{
|
||||
struct drm_cmdline_mode mode = { };
|
||||
const char *cmdline = "720x480@60";
|
||||
|
@ -243,7 +243,7 @@ static void drm_cmdline_test_res_refresh(struct kunit *test)
|
|||
KUNIT_EXPECT_EQ(test, mode.force, DRM_FORCE_UNSPECIFIED);
|
||||
}
|
||||
|
||||
static void drm_cmdline_test_res_bpp_refresh(struct kunit *test)
|
||||
static void drm_test_cmdline_res_bpp_refresh(struct kunit *test)
|
||||
{
|
||||
struct drm_cmdline_mode mode = { };
|
||||
const char *cmdline = "720x480-24@60";
|
||||
|
@ -267,7 +267,7 @@ static void drm_cmdline_test_res_bpp_refresh(struct kunit *test)
|
|||
KUNIT_EXPECT_EQ(test, mode.force, DRM_FORCE_UNSPECIFIED);
|
||||
}
|
||||
|
||||
static void drm_cmdline_test_res_bpp_refresh_interlaced(struct kunit *test)
|
||||
static void drm_test_cmdline_res_bpp_refresh_interlaced(struct kunit *test)
|
||||
{
|
||||
struct drm_cmdline_mode mode = { };
|
||||
const char *cmdline = "720x480-24@60i";
|
||||
|
@ -291,7 +291,7 @@ static void drm_cmdline_test_res_bpp_refresh_interlaced(struct kunit *test)
|
|||
KUNIT_EXPECT_EQ(test, mode.force, DRM_FORCE_UNSPECIFIED);
|
||||
}
|
||||
|
||||
static void drm_cmdline_test_res_bpp_refresh_margins(struct kunit *test)
|
||||
static void drm_test_cmdline_res_bpp_refresh_margins(struct kunit *test)
|
||||
{
|
||||
struct drm_cmdline_mode mode = { };
|
||||
const char *cmdline = "720x480-24@60m";
|
||||
|
@ -315,7 +315,7 @@ static void drm_cmdline_test_res_bpp_refresh_margins(struct kunit *test)
|
|||
KUNIT_EXPECT_EQ(test, mode.force, DRM_FORCE_UNSPECIFIED);
|
||||
}
|
||||
|
||||
static void drm_cmdline_test_res_bpp_refresh_force_off(struct kunit *test)
|
||||
static void drm_test_cmdline_res_bpp_refresh_force_off(struct kunit *test)
|
||||
{
|
||||
struct drm_cmdline_mode mode = { };
|
||||
const char *cmdline = "720x480-24@60d";
|
||||
|
@ -339,7 +339,7 @@ static void drm_cmdline_test_res_bpp_refresh_force_off(struct kunit *test)
|
|||
KUNIT_EXPECT_EQ(test, mode.force, DRM_FORCE_OFF);
|
||||
}
|
||||
|
||||
static void drm_cmdline_test_res_bpp_refresh_force_on(struct kunit *test)
|
||||
static void drm_test_cmdline_res_bpp_refresh_force_on(struct kunit *test)
|
||||
{
|
||||
struct drm_cmdline_mode mode = { };
|
||||
const char *cmdline = "720x480-24@60e";
|
||||
|
@ -363,7 +363,7 @@ static void drm_cmdline_test_res_bpp_refresh_force_on(struct kunit *test)
|
|||
KUNIT_EXPECT_EQ(test, mode.force, DRM_FORCE_ON);
|
||||
}
|
||||
|
||||
static void drm_cmdline_test_res_bpp_refresh_force_on_analog(struct kunit *test)
|
||||
static void drm_test_cmdline_res_bpp_refresh_force_on_analog(struct kunit *test)
|
||||
{
|
||||
struct drm_cmdline_mode mode = { };
|
||||
const char *cmdline = "720x480-24@60D";
|
||||
|
@ -387,7 +387,7 @@ static void drm_cmdline_test_res_bpp_refresh_force_on_analog(struct kunit *test)
|
|||
KUNIT_EXPECT_EQ(test, mode.force, DRM_FORCE_ON);
|
||||
}
|
||||
|
||||
static void drm_cmdline_test_res_bpp_refresh_force_on_digital(struct kunit *test)
|
||||
static void drm_test_cmdline_res_bpp_refresh_force_on_digital(struct kunit *test)
|
||||
{
|
||||
struct drm_cmdline_mode mode = { };
|
||||
static const struct drm_connector connector = {
|
||||
|
@ -414,7 +414,7 @@ static void drm_cmdline_test_res_bpp_refresh_force_on_digital(struct kunit *test
|
|||
KUNIT_EXPECT_EQ(test, mode.force, DRM_FORCE_ON_DIGITAL);
|
||||
}
|
||||
|
||||
static void drm_cmdline_test_res_bpp_refresh_interlaced_margins_force_on(struct kunit *test)
|
||||
static void drm_test_cmdline_res_bpp_refresh_interlaced_margins_force_on(struct kunit *test)
|
||||
{
|
||||
struct drm_cmdline_mode mode = { };
|
||||
const char *cmdline = "720x480-24@60ime";
|
||||
|
@ -438,7 +438,7 @@ static void drm_cmdline_test_res_bpp_refresh_interlaced_margins_force_on(struct
|
|||
KUNIT_EXPECT_EQ(test, mode.force, DRM_FORCE_ON);
|
||||
}
|
||||
|
||||
static void drm_cmdline_test_res_margins_force_on(struct kunit *test)
|
||||
static void drm_test_cmdline_res_margins_force_on(struct kunit *test)
|
||||
{
|
||||
struct drm_cmdline_mode mode = { };
|
||||
const char *cmdline = "720x480me";
|
||||
|
@ -460,7 +460,7 @@ static void drm_cmdline_test_res_margins_force_on(struct kunit *test)
|
|||
KUNIT_EXPECT_EQ(test, mode.force, DRM_FORCE_ON);
|
||||
}
|
||||
|
||||
static void drm_cmdline_test_res_vesa_margins(struct kunit *test)
|
||||
static void drm_test_cmdline_res_vesa_margins(struct kunit *test)
|
||||
{
|
||||
struct drm_cmdline_mode mode = { };
|
||||
const char *cmdline = "720x480Mm";
|
||||
|
@ -482,7 +482,7 @@ static void drm_cmdline_test_res_vesa_margins(struct kunit *test)
|
|||
KUNIT_EXPECT_EQ(test, mode.force, DRM_FORCE_UNSPECIFIED);
|
||||
}
|
||||
|
||||
static void drm_cmdline_test_name(struct kunit *test)
|
||||
static void drm_test_cmdline_name(struct kunit *test)
|
||||
{
|
||||
struct drm_cmdline_mode mode = { };
|
||||
const char *cmdline = "NTSC";
|
||||
|
@ -494,7 +494,7 @@ static void drm_cmdline_test_name(struct kunit *test)
|
|||
KUNIT_EXPECT_FALSE(test, mode.bpp_specified);
|
||||
}
|
||||
|
||||
static void drm_cmdline_test_name_bpp(struct kunit *test)
|
||||
static void drm_test_cmdline_name_bpp(struct kunit *test)
|
||||
{
|
||||
struct drm_cmdline_mode mode = { };
|
||||
const char *cmdline = "NTSC-24";
|
||||
|
@ -509,7 +509,7 @@ static void drm_cmdline_test_name_bpp(struct kunit *test)
|
|||
KUNIT_EXPECT_EQ(test, mode.bpp, 24);
|
||||
}
|
||||
|
||||
static void drm_cmdline_test_name_option(struct kunit *test)
|
||||
static void drm_test_cmdline_name_option(struct kunit *test)
|
||||
{
|
||||
struct drm_cmdline_mode mode = { };
|
||||
const char *cmdline = "NTSC,rotate=180";
|
||||
|
@ -521,7 +521,7 @@ static void drm_cmdline_test_name_option(struct kunit *test)
|
|||
KUNIT_EXPECT_EQ(test, mode.rotation_reflection, DRM_MODE_ROTATE_180);
|
||||
}
|
||||
|
||||
static void drm_cmdline_test_name_bpp_option(struct kunit *test)
|
||||
static void drm_test_cmdline_name_bpp_option(struct kunit *test)
|
||||
{
|
||||
struct drm_cmdline_mode mode = { };
|
||||
const char *cmdline = "NTSC-24,rotate=180";
|
||||
|
@ -535,7 +535,7 @@ static void drm_cmdline_test_name_bpp_option(struct kunit *test)
|
|||
KUNIT_EXPECT_EQ(test, mode.bpp, 24);
|
||||
}
|
||||
|
||||
static void drm_cmdline_test_rotate_0(struct kunit *test)
|
||||
static void drm_test_cmdline_rotate_0(struct kunit *test)
|
||||
{
|
||||
struct drm_cmdline_mode mode = { };
|
||||
const char *cmdline = "720x480,rotate=0";
|
||||
|
@ -558,7 +558,7 @@ static void drm_cmdline_test_rotate_0(struct kunit *test)
|
|||
KUNIT_EXPECT_EQ(test, mode.force, DRM_FORCE_UNSPECIFIED);
|
||||
}
|
||||
|
||||
static void drm_cmdline_test_rotate_90(struct kunit *test)
|
||||
static void drm_test_cmdline_rotate_90(struct kunit *test)
|
||||
{
|
||||
struct drm_cmdline_mode mode = { };
|
||||
const char *cmdline = "720x480,rotate=90";
|
||||
|
@ -581,7 +581,7 @@ static void drm_cmdline_test_rotate_90(struct kunit *test)
|
|||
KUNIT_EXPECT_EQ(test, mode.force, DRM_FORCE_UNSPECIFIED);
|
||||
}
|
||||
|
||||
static void drm_cmdline_test_rotate_180(struct kunit *test)
|
||||
static void drm_test_cmdline_rotate_180(struct kunit *test)
|
||||
{
|
||||
struct drm_cmdline_mode mode = { };
|
||||
const char *cmdline = "720x480,rotate=180";
|
||||
|
@ -604,7 +604,7 @@ static void drm_cmdline_test_rotate_180(struct kunit *test)
|
|||
KUNIT_EXPECT_EQ(test, mode.force, DRM_FORCE_UNSPECIFIED);
|
||||
}
|
||||
|
||||
static void drm_cmdline_test_rotate_270(struct kunit *test)
|
||||
static void drm_test_cmdline_rotate_270(struct kunit *test)
|
||||
{
|
||||
struct drm_cmdline_mode mode = { };
|
||||
const char *cmdline = "720x480,rotate=270";
|
||||
|
@ -627,7 +627,7 @@ static void drm_cmdline_test_rotate_270(struct kunit *test)
|
|||
KUNIT_EXPECT_EQ(test, mode.force, DRM_FORCE_UNSPECIFIED);
|
||||
}
|
||||
|
||||
static void drm_cmdline_test_hmirror(struct kunit *test)
|
||||
static void drm_test_cmdline_hmirror(struct kunit *test)
|
||||
{
|
||||
struct drm_cmdline_mode mode = { };
|
||||
const char *cmdline = "720x480,reflect_x";
|
||||
|
@ -650,7 +650,7 @@ static void drm_cmdline_test_hmirror(struct kunit *test)
|
|||
KUNIT_EXPECT_EQ(test, mode.force, DRM_FORCE_UNSPECIFIED);
|
||||
}
|
||||
|
||||
static void drm_cmdline_test_vmirror(struct kunit *test)
|
||||
static void drm_test_cmdline_vmirror(struct kunit *test)
|
||||
{
|
||||
struct drm_cmdline_mode mode = { };
|
||||
const char *cmdline = "720x480,reflect_y";
|
||||
|
@ -673,7 +673,7 @@ static void drm_cmdline_test_vmirror(struct kunit *test)
|
|||
KUNIT_EXPECT_EQ(test, mode.force, DRM_FORCE_UNSPECIFIED);
|
||||
}
|
||||
|
||||
static void drm_cmdline_test_margin_options(struct kunit *test)
|
||||
static void drm_test_cmdline_margin_options(struct kunit *test)
|
||||
{
|
||||
struct drm_cmdline_mode mode = { };
|
||||
const char *cmdline =
|
||||
|
@ -700,7 +700,7 @@ static void drm_cmdline_test_margin_options(struct kunit *test)
|
|||
KUNIT_EXPECT_EQ(test, mode.force, DRM_FORCE_UNSPECIFIED);
|
||||
}
|
||||
|
||||
static void drm_cmdline_test_multiple_options(struct kunit *test)
|
||||
static void drm_test_cmdline_multiple_options(struct kunit *test)
|
||||
{
|
||||
struct drm_cmdline_mode mode = { };
|
||||
const char *cmdline = "720x480,rotate=270,reflect_x";
|
||||
|
@ -723,7 +723,7 @@ static void drm_cmdline_test_multiple_options(struct kunit *test)
|
|||
KUNIT_EXPECT_EQ(test, mode.force, DRM_FORCE_UNSPECIFIED);
|
||||
}
|
||||
|
||||
static void drm_cmdline_test_bpp_extra_and_option(struct kunit *test)
|
||||
static void drm_test_cmdline_bpp_extra_and_option(struct kunit *test)
|
||||
{
|
||||
struct drm_cmdline_mode mode = { };
|
||||
const char *cmdline = "720x480-24e,rotate=180";
|
||||
|
@ -747,7 +747,7 @@ static void drm_cmdline_test_bpp_extra_and_option(struct kunit *test)
|
|||
KUNIT_EXPECT_EQ(test, mode.force, DRM_FORCE_ON);
|
||||
}
|
||||
|
||||
static void drm_cmdline_test_extra_and_option(struct kunit *test)
|
||||
static void drm_test_cmdline_extra_and_option(struct kunit *test)
|
||||
{
|
||||
struct drm_cmdline_mode mode = { };
|
||||
const char *cmdline = "720x480e,rotate=180";
|
||||
|
@ -769,7 +769,7 @@ static void drm_cmdline_test_extra_and_option(struct kunit *test)
|
|||
KUNIT_EXPECT_EQ(test, mode.force, DRM_FORCE_ON);
|
||||
}
|
||||
|
||||
static void drm_cmdline_test_freestanding_options(struct kunit *test)
|
||||
static void drm_test_cmdline_freestanding_options(struct kunit *test)
|
||||
{
|
||||
struct drm_cmdline_mode mode = { };
|
||||
const char *cmdline = "margin_right=14,margin_left=24,margin_bottom=36,margin_top=42";
|
||||
|
@ -792,7 +792,7 @@ static void drm_cmdline_test_freestanding_options(struct kunit *test)
|
|||
KUNIT_EXPECT_EQ(test, mode.force, DRM_FORCE_UNSPECIFIED);
|
||||
}
|
||||
|
||||
static void drm_cmdline_test_freestanding_force_e_and_options(struct kunit *test)
|
||||
static void drm_test_cmdline_freestanding_force_e_and_options(struct kunit *test)
|
||||
{
|
||||
struct drm_cmdline_mode mode = { };
|
||||
const char *cmdline = "e,margin_right=14,margin_left=24,margin_bottom=36,margin_top=42";
|
||||
|
@ -815,7 +815,7 @@ static void drm_cmdline_test_freestanding_force_e_and_options(struct kunit *test
|
|||
KUNIT_EXPECT_EQ(test, mode.force, DRM_FORCE_ON);
|
||||
}
|
||||
|
||||
static void drm_cmdline_test_panel_orientation(struct kunit *test)
|
||||
static void drm_test_cmdline_panel_orientation(struct kunit *test)
|
||||
{
|
||||
struct drm_cmdline_mode mode = { };
|
||||
const char *cmdline = "panel_orientation=upside_down";
|
||||
|
@ -840,7 +840,7 @@ struct drm_cmdline_invalid_test {
|
|||
const char *cmdline;
|
||||
};
|
||||
|
||||
static void drm_cmdline_test_invalid(struct kunit *test)
|
||||
static void drm_test_cmdline_invalid(struct kunit *test)
|
||||
{
|
||||
const struct drm_cmdline_invalid_test *params = test->param_value;
|
||||
struct drm_cmdline_mode mode = { };
|
||||
|
@ -938,45 +938,45 @@ static void drm_cmdline_invalid_desc(const struct drm_cmdline_invalid_test *t,
|
|||
KUNIT_ARRAY_PARAM(drm_cmdline_invalid, drm_cmdline_invalid_tests, drm_cmdline_invalid_desc);
|
||||
|
||||
static struct kunit_case drm_cmdline_parser_tests[] = {
|
||||
KUNIT_CASE(drm_cmdline_test_force_d_only),
|
||||
KUNIT_CASE(drm_cmdline_test_force_D_only_dvi),
|
||||
KUNIT_CASE(drm_cmdline_test_force_D_only_hdmi),
|
||||
KUNIT_CASE(drm_cmdline_test_force_D_only_not_digital),
|
||||
KUNIT_CASE(drm_cmdline_test_force_e_only),
|
||||
KUNIT_CASE(drm_cmdline_test_res),
|
||||
KUNIT_CASE(drm_cmdline_test_res_vesa),
|
||||
KUNIT_CASE(drm_cmdline_test_res_vesa_rblank),
|
||||
KUNIT_CASE(drm_cmdline_test_res_rblank),
|
||||
KUNIT_CASE(drm_cmdline_test_res_bpp),
|
||||
KUNIT_CASE(drm_cmdline_test_res_refresh),
|
||||
KUNIT_CASE(drm_cmdline_test_res_bpp_refresh),
|
||||
KUNIT_CASE(drm_cmdline_test_res_bpp_refresh_interlaced),
|
||||
KUNIT_CASE(drm_cmdline_test_res_bpp_refresh_margins),
|
||||
KUNIT_CASE(drm_cmdline_test_res_bpp_refresh_force_off),
|
||||
KUNIT_CASE(drm_cmdline_test_res_bpp_refresh_force_on),
|
||||
KUNIT_CASE(drm_cmdline_test_res_bpp_refresh_force_on_analog),
|
||||
KUNIT_CASE(drm_cmdline_test_res_bpp_refresh_force_on_digital),
|
||||
KUNIT_CASE(drm_cmdline_test_res_bpp_refresh_interlaced_margins_force_on),
|
||||
KUNIT_CASE(drm_cmdline_test_res_margins_force_on),
|
||||
KUNIT_CASE(drm_cmdline_test_res_vesa_margins),
|
||||
KUNIT_CASE(drm_cmdline_test_name),
|
||||
KUNIT_CASE(drm_cmdline_test_name_bpp),
|
||||
KUNIT_CASE(drm_cmdline_test_name_option),
|
||||
KUNIT_CASE(drm_cmdline_test_name_bpp_option),
|
||||
KUNIT_CASE(drm_cmdline_test_rotate_0),
|
||||
KUNIT_CASE(drm_cmdline_test_rotate_90),
|
||||
KUNIT_CASE(drm_cmdline_test_rotate_180),
|
||||
KUNIT_CASE(drm_cmdline_test_rotate_270),
|
||||
KUNIT_CASE(drm_cmdline_test_hmirror),
|
||||
KUNIT_CASE(drm_cmdline_test_vmirror),
|
||||
KUNIT_CASE(drm_cmdline_test_margin_options),
|
||||
KUNIT_CASE(drm_cmdline_test_multiple_options),
|
||||
KUNIT_CASE(drm_cmdline_test_bpp_extra_and_option),
|
||||
KUNIT_CASE(drm_cmdline_test_extra_and_option),
|
||||
KUNIT_CASE(drm_cmdline_test_freestanding_options),
|
||||
KUNIT_CASE(drm_cmdline_test_freestanding_force_e_and_options),
|
||||
KUNIT_CASE(drm_cmdline_test_panel_orientation),
|
||||
KUNIT_CASE_PARAM(drm_cmdline_test_invalid, drm_cmdline_invalid_gen_params),
|
||||
KUNIT_CASE(drm_test_cmdline_force_d_only),
|
||||
KUNIT_CASE(drm_test_cmdline_force_D_only_dvi),
|
||||
KUNIT_CASE(drm_test_cmdline_force_D_only_hdmi),
|
||||
KUNIT_CASE(drm_test_cmdline_force_D_only_not_digital),
|
||||
KUNIT_CASE(drm_test_cmdline_force_e_only),
|
||||
KUNIT_CASE(drm_test_cmdline_res),
|
||||
KUNIT_CASE(drm_test_cmdline_res_vesa),
|
||||
KUNIT_CASE(drm_test_cmdline_res_vesa_rblank),
|
||||
KUNIT_CASE(drm_test_cmdline_res_rblank),
|
||||
KUNIT_CASE(drm_test_cmdline_res_bpp),
|
||||
KUNIT_CASE(drm_test_cmdline_res_refresh),
|
||||
KUNIT_CASE(drm_test_cmdline_res_bpp_refresh),
|
||||
KUNIT_CASE(drm_test_cmdline_res_bpp_refresh_interlaced),
|
||||
KUNIT_CASE(drm_test_cmdline_res_bpp_refresh_margins),
|
||||
KUNIT_CASE(drm_test_cmdline_res_bpp_refresh_force_off),
|
||||
KUNIT_CASE(drm_test_cmdline_res_bpp_refresh_force_on),
|
||||
KUNIT_CASE(drm_test_cmdline_res_bpp_refresh_force_on_analog),
|
||||
KUNIT_CASE(drm_test_cmdline_res_bpp_refresh_force_on_digital),
|
||||
KUNIT_CASE(drm_test_cmdline_res_bpp_refresh_interlaced_margins_force_on),
|
||||
KUNIT_CASE(drm_test_cmdline_res_margins_force_on),
|
||||
KUNIT_CASE(drm_test_cmdline_res_vesa_margins),
|
||||
KUNIT_CASE(drm_test_cmdline_name),
|
||||
KUNIT_CASE(drm_test_cmdline_name_bpp),
|
||||
KUNIT_CASE(drm_test_cmdline_name_option),
|
||||
KUNIT_CASE(drm_test_cmdline_name_bpp_option),
|
||||
KUNIT_CASE(drm_test_cmdline_rotate_0),
|
||||
KUNIT_CASE(drm_test_cmdline_rotate_90),
|
||||
KUNIT_CASE(drm_test_cmdline_rotate_180),
|
||||
KUNIT_CASE(drm_test_cmdline_rotate_270),
|
||||
KUNIT_CASE(drm_test_cmdline_hmirror),
|
||||
KUNIT_CASE(drm_test_cmdline_vmirror),
|
||||
KUNIT_CASE(drm_test_cmdline_margin_options),
|
||||
KUNIT_CASE(drm_test_cmdline_multiple_options),
|
||||
KUNIT_CASE(drm_test_cmdline_bpp_extra_and_option),
|
||||
KUNIT_CASE(drm_test_cmdline_extra_and_option),
|
||||
KUNIT_CASE(drm_test_cmdline_freestanding_options),
|
||||
KUNIT_CASE(drm_test_cmdline_freestanding_force_e_and_options),
|
||||
KUNIT_CASE(drm_test_cmdline_panel_orientation),
|
||||
KUNIT_CASE_PARAM(drm_test_cmdline_invalid, drm_cmdline_invalid_gen_params),
|
||||
{}
|
||||
};
|
||||
|
||||
|
|
|
@ -59,6 +59,11 @@ static int drm_damage_helper_init(struct kunit *test)
|
|||
static void set_plane_src(struct drm_plane_state *state, int x1, int y1, int x2,
|
||||
int y2)
|
||||
{
|
||||
state->src_x = x1;
|
||||
state->src_y = y1;
|
||||
state->src_w = x2 - x1;
|
||||
state->src_h = y2 - y1;
|
||||
|
||||
state->src.x1 = x1;
|
||||
state->src.y1 = y1;
|
||||
state->src.x2 = x2;
|
||||
|
@ -111,7 +116,7 @@ static void check_damage_clip(struct kunit *test, struct drm_rect *r,
|
|||
r->x1, r->y1, r->x2, r->y2, x1, y1, x2, y2);
|
||||
}
|
||||
|
||||
static void igt_damage_iter_no_damage(struct kunit *test)
|
||||
static void drm_test_damage_iter_no_damage(struct kunit *test)
|
||||
{
|
||||
struct drm_damage_mock *mock = test->priv;
|
||||
struct drm_atomic_helper_damage_iter iter;
|
||||
|
@ -129,7 +134,7 @@ static void igt_damage_iter_no_damage(struct kunit *test)
|
|||
check_damage_clip(test, &clip, 0, 0, 2048, 2048);
|
||||
}
|
||||
|
||||
static void igt_damage_iter_no_damage_fractional_src(struct kunit *test)
|
||||
static void drm_test_damage_iter_no_damage_fractional_src(struct kunit *test)
|
||||
{
|
||||
struct drm_damage_mock *mock = test->priv;
|
||||
struct drm_atomic_helper_damage_iter iter;
|
||||
|
@ -150,7 +155,7 @@ static void igt_damage_iter_no_damage_fractional_src(struct kunit *test)
|
|||
check_damage_clip(test, &clip, 3, 3, 1028, 772);
|
||||
}
|
||||
|
||||
static void igt_damage_iter_no_damage_src_moved(struct kunit *test)
|
||||
static void drm_test_damage_iter_no_damage_src_moved(struct kunit *test)
|
||||
{
|
||||
struct drm_damage_mock *mock = test->priv;
|
||||
struct drm_atomic_helper_damage_iter iter;
|
||||
|
@ -169,7 +174,7 @@ static void igt_damage_iter_no_damage_src_moved(struct kunit *test)
|
|||
check_damage_clip(test, &clip, 10, 10, 1034, 778);
|
||||
}
|
||||
|
||||
static void igt_damage_iter_no_damage_fractional_src_moved(struct kunit *test)
|
||||
static void drm_test_damage_iter_no_damage_fractional_src_moved(struct kunit *test)
|
||||
{
|
||||
struct drm_damage_mock *mock = test->priv;
|
||||
struct drm_atomic_helper_damage_iter iter;
|
||||
|
@ -189,7 +194,7 @@ static void igt_damage_iter_no_damage_fractional_src_moved(struct kunit *test)
|
|||
check_damage_clip(test, &clip, 4, 4, 1029, 773);
|
||||
}
|
||||
|
||||
static void igt_damage_iter_no_damage_not_visible(struct kunit *test)
|
||||
static void drm_test_damage_iter_no_damage_not_visible(struct kunit *test)
|
||||
{
|
||||
struct drm_damage_mock *mock = test->priv;
|
||||
struct drm_atomic_helper_damage_iter iter;
|
||||
|
@ -207,7 +212,7 @@ static void igt_damage_iter_no_damage_not_visible(struct kunit *test)
|
|||
KUNIT_EXPECT_EQ_MSG(test, num_hits, 0, "Should have no damage.");
|
||||
}
|
||||
|
||||
static void igt_damage_iter_no_damage_no_crtc(struct kunit *test)
|
||||
static void drm_test_damage_iter_no_damage_no_crtc(struct kunit *test)
|
||||
{
|
||||
struct drm_damage_mock *mock = test->priv;
|
||||
struct drm_atomic_helper_damage_iter iter;
|
||||
|
@ -225,7 +230,7 @@ static void igt_damage_iter_no_damage_no_crtc(struct kunit *test)
|
|||
KUNIT_EXPECT_EQ_MSG(test, num_hits, 0, "Should have no damage.");
|
||||
}
|
||||
|
||||
static void igt_damage_iter_no_damage_no_fb(struct kunit *test)
|
||||
static void drm_test_damage_iter_no_damage_no_fb(struct kunit *test)
|
||||
{
|
||||
struct drm_damage_mock *mock = test->priv;
|
||||
struct drm_atomic_helper_damage_iter iter;
|
||||
|
@ -243,7 +248,7 @@ static void igt_damage_iter_no_damage_no_fb(struct kunit *test)
|
|||
KUNIT_EXPECT_EQ_MSG(test, num_hits, 0, "Should have no damage.");
|
||||
}
|
||||
|
||||
static void igt_damage_iter_simple_damage(struct kunit *test)
|
||||
static void drm_test_damage_iter_simple_damage(struct kunit *test)
|
||||
{
|
||||
struct drm_damage_mock *mock = test->priv;
|
||||
struct drm_atomic_helper_damage_iter iter;
|
||||
|
@ -266,7 +271,7 @@ static void igt_damage_iter_simple_damage(struct kunit *test)
|
|||
check_damage_clip(test, &clip, 0, 0, 1024, 768);
|
||||
}
|
||||
|
||||
static void igt_damage_iter_single_damage(struct kunit *test)
|
||||
static void drm_test_damage_iter_single_damage(struct kunit *test)
|
||||
{
|
||||
struct drm_damage_mock *mock = test->priv;
|
||||
struct drm_atomic_helper_damage_iter iter;
|
||||
|
@ -288,7 +293,7 @@ static void igt_damage_iter_single_damage(struct kunit *test)
|
|||
check_damage_clip(test, &clip, 256, 192, 768, 576);
|
||||
}
|
||||
|
||||
static void igt_damage_iter_single_damage_intersect_src(struct kunit *test)
|
||||
static void drm_test_damage_iter_single_damage_intersect_src(struct kunit *test)
|
||||
{
|
||||
struct drm_damage_mock *mock = test->priv;
|
||||
struct drm_atomic_helper_damage_iter iter;
|
||||
|
@ -311,7 +316,7 @@ static void igt_damage_iter_single_damage_intersect_src(struct kunit *test)
|
|||
check_damage_clip(test, &clip, 256, 192, 1024, 768);
|
||||
}
|
||||
|
||||
static void igt_damage_iter_single_damage_outside_src(struct kunit *test)
|
||||
static void drm_test_damage_iter_single_damage_outside_src(struct kunit *test)
|
||||
{
|
||||
struct drm_damage_mock *mock = test->priv;
|
||||
struct drm_atomic_helper_damage_iter iter;
|
||||
|
@ -333,7 +338,7 @@ static void igt_damage_iter_single_damage_outside_src(struct kunit *test)
|
|||
KUNIT_EXPECT_EQ_MSG(test, num_hits, 0, "Should have no damage.");
|
||||
}
|
||||
|
||||
static void igt_damage_iter_single_damage_fractional_src(struct kunit *test)
|
||||
static void drm_test_damage_iter_single_damage_fractional_src(struct kunit *test)
|
||||
{
|
||||
struct drm_damage_mock *mock = test->priv;
|
||||
struct drm_atomic_helper_damage_iter iter;
|
||||
|
@ -358,7 +363,7 @@ static void igt_damage_iter_single_damage_fractional_src(struct kunit *test)
|
|||
check_damage_clip(test, &clip, 10, 10, 256, 330);
|
||||
}
|
||||
|
||||
static void igt_damage_iter_single_damage_intersect_fractional_src(struct kunit *test)
|
||||
static void drm_test_damage_iter_single_damage_intersect_fractional_src(struct kunit *test)
|
||||
{
|
||||
struct drm_damage_mock *mock = test->priv;
|
||||
struct drm_atomic_helper_damage_iter iter;
|
||||
|
@ -385,7 +390,7 @@ static void igt_damage_iter_single_damage_intersect_fractional_src(struct kunit
|
|||
check_damage_clip(test, &clip, 10, 4, 1029, 330);
|
||||
}
|
||||
|
||||
static void igt_damage_iter_single_damage_outside_fractional_src(struct kunit *test)
|
||||
static void drm_test_damage_iter_single_damage_outside_fractional_src(struct kunit *test)
|
||||
{
|
||||
struct drm_damage_mock *mock = test->priv;
|
||||
struct drm_atomic_helper_damage_iter iter;
|
||||
|
@ -410,7 +415,7 @@ static void igt_damage_iter_single_damage_outside_fractional_src(struct kunit *t
|
|||
KUNIT_EXPECT_EQ_MSG(test, num_hits, 0, "Should have no damage.");
|
||||
}
|
||||
|
||||
static void igt_damage_iter_single_damage_src_moved(struct kunit *test)
|
||||
static void drm_test_damage_iter_single_damage_src_moved(struct kunit *test)
|
||||
{
|
||||
struct drm_damage_mock *mock = test->priv;
|
||||
struct drm_atomic_helper_damage_iter iter;
|
||||
|
@ -435,7 +440,7 @@ static void igt_damage_iter_single_damage_src_moved(struct kunit *test)
|
|||
check_damage_clip(test, &clip, 10, 10, 1034, 778);
|
||||
}
|
||||
|
||||
static void igt_damage_iter_single_damage_fractional_src_moved(struct kunit *test)
|
||||
static void drm_test_damage_iter_single_damage_fractional_src_moved(struct kunit *test)
|
||||
{
|
||||
struct drm_damage_mock *mock = test->priv;
|
||||
struct drm_atomic_helper_damage_iter iter;
|
||||
|
@ -462,7 +467,7 @@ static void igt_damage_iter_single_damage_fractional_src_moved(struct kunit *tes
|
|||
check_damage_clip(test, &clip, 4, 4, 1029, 773);
|
||||
}
|
||||
|
||||
static void igt_damage_iter_damage(struct kunit *test)
|
||||
static void drm_test_damage_iter_damage(struct kunit *test)
|
||||
{
|
||||
struct drm_damage_mock *mock = test->priv;
|
||||
struct drm_atomic_helper_damage_iter iter;
|
||||
|
@ -490,7 +495,7 @@ static void igt_damage_iter_damage(struct kunit *test)
|
|||
KUNIT_EXPECT_EQ_MSG(test, num_hits, 2, "Should return damage when set.");
|
||||
}
|
||||
|
||||
static void igt_damage_iter_damage_one_intersect(struct kunit *test)
|
||||
static void drm_test_damage_iter_damage_one_intersect(struct kunit *test)
|
||||
{
|
||||
struct drm_damage_mock *mock = test->priv;
|
||||
struct drm_atomic_helper_damage_iter iter;
|
||||
|
@ -520,7 +525,7 @@ static void igt_damage_iter_damage_one_intersect(struct kunit *test)
|
|||
KUNIT_EXPECT_EQ_MSG(test, num_hits, 2, "Should return damage when set.");
|
||||
}
|
||||
|
||||
static void igt_damage_iter_damage_one_outside(struct kunit *test)
|
||||
static void drm_test_damage_iter_damage_one_outside(struct kunit *test)
|
||||
{
|
||||
struct drm_damage_mock *mock = test->priv;
|
||||
struct drm_atomic_helper_damage_iter iter;
|
||||
|
@ -544,7 +549,7 @@ static void igt_damage_iter_damage_one_outside(struct kunit *test)
|
|||
check_damage_clip(test, &clip, 240, 200, 280, 250);
|
||||
}
|
||||
|
||||
static void igt_damage_iter_damage_src_moved(struct kunit *test)
|
||||
static void drm_test_damage_iter_damage_src_moved(struct kunit *test)
|
||||
{
|
||||
struct drm_damage_mock *mock = test->priv;
|
||||
struct drm_atomic_helper_damage_iter iter;
|
||||
|
@ -571,7 +576,7 @@ static void igt_damage_iter_damage_src_moved(struct kunit *test)
|
|||
check_damage_clip(test, &clip, 3, 3, 1028, 772);
|
||||
}
|
||||
|
||||
static void igt_damage_iter_damage_not_visible(struct kunit *test)
|
||||
static void drm_test_damage_iter_damage_not_visible(struct kunit *test)
|
||||
{
|
||||
struct drm_damage_mock *mock = test->priv;
|
||||
struct drm_atomic_helper_damage_iter iter;
|
||||
|
@ -599,27 +604,27 @@ static void igt_damage_iter_damage_not_visible(struct kunit *test)
|
|||
}
|
||||
|
||||
static struct kunit_case drm_damage_helper_tests[] = {
|
||||
KUNIT_CASE(igt_damage_iter_no_damage),
|
||||
KUNIT_CASE(igt_damage_iter_no_damage_fractional_src),
|
||||
KUNIT_CASE(igt_damage_iter_no_damage_src_moved),
|
||||
KUNIT_CASE(igt_damage_iter_no_damage_fractional_src_moved),
|
||||
KUNIT_CASE(igt_damage_iter_no_damage_not_visible),
|
||||
KUNIT_CASE(igt_damage_iter_no_damage_no_crtc),
|
||||
KUNIT_CASE(igt_damage_iter_no_damage_no_fb),
|
||||
KUNIT_CASE(igt_damage_iter_simple_damage),
|
||||
KUNIT_CASE(igt_damage_iter_single_damage),
|
||||
KUNIT_CASE(igt_damage_iter_single_damage_intersect_src),
|
||||
KUNIT_CASE(igt_damage_iter_single_damage_outside_src),
|
||||
KUNIT_CASE(igt_damage_iter_single_damage_fractional_src),
|
||||
KUNIT_CASE(igt_damage_iter_single_damage_intersect_fractional_src),
|
||||
KUNIT_CASE(igt_damage_iter_single_damage_outside_fractional_src),
|
||||
KUNIT_CASE(igt_damage_iter_single_damage_src_moved),
|
||||
KUNIT_CASE(igt_damage_iter_single_damage_fractional_src_moved),
|
||||
KUNIT_CASE(igt_damage_iter_damage),
|
||||
KUNIT_CASE(igt_damage_iter_damage_one_intersect),
|
||||
KUNIT_CASE(igt_damage_iter_damage_one_outside),
|
||||
KUNIT_CASE(igt_damage_iter_damage_src_moved),
|
||||
KUNIT_CASE(igt_damage_iter_damage_not_visible),
|
||||
KUNIT_CASE(drm_test_damage_iter_no_damage),
|
||||
KUNIT_CASE(drm_test_damage_iter_no_damage_fractional_src),
|
||||
KUNIT_CASE(drm_test_damage_iter_no_damage_src_moved),
|
||||
KUNIT_CASE(drm_test_damage_iter_no_damage_fractional_src_moved),
|
||||
KUNIT_CASE(drm_test_damage_iter_no_damage_not_visible),
|
||||
KUNIT_CASE(drm_test_damage_iter_no_damage_no_crtc),
|
||||
KUNIT_CASE(drm_test_damage_iter_no_damage_no_fb),
|
||||
KUNIT_CASE(drm_test_damage_iter_simple_damage),
|
||||
KUNIT_CASE(drm_test_damage_iter_single_damage),
|
||||
KUNIT_CASE(drm_test_damage_iter_single_damage_intersect_src),
|
||||
KUNIT_CASE(drm_test_damage_iter_single_damage_outside_src),
|
||||
KUNIT_CASE(drm_test_damage_iter_single_damage_fractional_src),
|
||||
KUNIT_CASE(drm_test_damage_iter_single_damage_intersect_fractional_src),
|
||||
KUNIT_CASE(drm_test_damage_iter_single_damage_outside_fractional_src),
|
||||
KUNIT_CASE(drm_test_damage_iter_single_damage_src_moved),
|
||||
KUNIT_CASE(drm_test_damage_iter_single_damage_fractional_src_moved),
|
||||
KUNIT_CASE(drm_test_damage_iter_damage),
|
||||
KUNIT_CASE(drm_test_damage_iter_damage_one_intersect),
|
||||
KUNIT_CASE(drm_test_damage_iter_damage_one_outside),
|
||||
KUNIT_CASE(drm_test_damage_iter_damage_src_moved),
|
||||
KUNIT_CASE(drm_test_damage_iter_damage_not_visible),
|
||||
{ }
|
||||
};
|
||||
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
|
||||
#include "../display/drm_dp_mst_topology_internal.h"
|
||||
|
||||
static void igt_dp_mst_calc_pbn_mode(struct kunit *test)
|
||||
static void drm_test_dp_mst_calc_pbn_mode(struct kunit *test)
|
||||
{
|
||||
int pbn, i;
|
||||
const struct {
|
||||
|
@ -177,7 +177,7 @@ out:
|
|||
return result;
|
||||
}
|
||||
|
||||
static void igt_dp_mst_sideband_msg_req_decode(struct kunit *test)
|
||||
static void drm_test_dp_mst_sideband_msg_req_decode(struct kunit *test)
|
||||
{
|
||||
struct drm_dp_sideband_msg_req_body in = { 0 };
|
||||
u8 data[] = { 0xff, 0x0, 0xdd };
|
||||
|
@ -271,8 +271,8 @@ static void igt_dp_mst_sideband_msg_req_decode(struct kunit *test)
|
|||
}
|
||||
|
||||
static struct kunit_case drm_dp_mst_helper_tests[] = {
|
||||
KUNIT_CASE(igt_dp_mst_calc_pbn_mode),
|
||||
KUNIT_CASE(igt_dp_mst_sideband_msg_req_decode),
|
||||
KUNIT_CASE(drm_test_dp_mst_calc_pbn_mode),
|
||||
KUNIT_CASE(drm_test_dp_mst_sideband_msg_req_decode),
|
||||
{ }
|
||||
};
|
||||
|
||||
|
|
|
@ -192,7 +192,7 @@ static void convert_xrgb8888_case_desc(struct convert_xrgb8888_case *t,
|
|||
KUNIT_ARRAY_PARAM(convert_xrgb8888, convert_xrgb8888_cases,
|
||||
convert_xrgb8888_case_desc);
|
||||
|
||||
static void xrgb8888_to_rgb332_test(struct kunit *test)
|
||||
static void drm_test_fb_xrgb8888_to_rgb332(struct kunit *test)
|
||||
{
|
||||
const struct convert_xrgb8888_case *params = test->param_value;
|
||||
const struct convert_to_rgb332_result *result = ¶ms->rgb332_result;
|
||||
|
@ -222,7 +222,7 @@ static void xrgb8888_to_rgb332_test(struct kunit *test)
|
|||
KUNIT_EXPECT_EQ(test, memcmp(buf, result->expected, dst_size), 0);
|
||||
}
|
||||
|
||||
static void xrgb8888_to_rgb565_test(struct kunit *test)
|
||||
static void drm_test_fb_xrgb8888_to_rgb565(struct kunit *test)
|
||||
{
|
||||
const struct convert_xrgb8888_case *params = test->param_value;
|
||||
const struct convert_to_rgb565_result *result = ¶ms->rgb565_result;
|
||||
|
@ -256,8 +256,8 @@ static void xrgb8888_to_rgb565_test(struct kunit *test)
|
|||
}
|
||||
|
||||
static struct kunit_case drm_format_helper_test_cases[] = {
|
||||
KUNIT_CASE_PARAM(xrgb8888_to_rgb332_test, convert_xrgb8888_gen_params),
|
||||
KUNIT_CASE_PARAM(xrgb8888_to_rgb565_test, convert_xrgb8888_gen_params),
|
||||
KUNIT_CASE_PARAM(drm_test_fb_xrgb8888_to_rgb332, convert_xrgb8888_gen_params),
|
||||
KUNIT_CASE_PARAM(drm_test_fb_xrgb8888_to_rgb565, convert_xrgb8888_gen_params),
|
||||
{}
|
||||
};
|
||||
|
||||
|
|
|
@ -9,103 +9,136 @@
|
|||
|
||||
#include <drm/drm_fourcc.h>
|
||||
|
||||
static void igt_check_drm_format_block_width(struct kunit *test)
|
||||
static void drm_test_format_block_width_invalid(struct kunit *test)
|
||||
{
|
||||
const struct drm_format_info *info = NULL;
|
||||
|
||||
/* Test invalid arguments */
|
||||
KUNIT_EXPECT_FALSE(test, drm_format_info_block_width(info, 0));
|
||||
KUNIT_EXPECT_FALSE(test, drm_format_info_block_width(info, -1));
|
||||
KUNIT_EXPECT_FALSE(test, drm_format_info_block_width(info, 1));
|
||||
KUNIT_EXPECT_EQ(test, drm_format_info_block_width(info, 0), 0);
|
||||
KUNIT_EXPECT_EQ(test, drm_format_info_block_width(info, -1), 0);
|
||||
KUNIT_EXPECT_EQ(test, drm_format_info_block_width(info, 1), 0);
|
||||
}
|
||||
|
||||
/* Test 1 plane format */
|
||||
info = drm_format_info(DRM_FORMAT_XRGB4444);
|
||||
KUNIT_EXPECT_TRUE(test, info);
|
||||
KUNIT_EXPECT_TRUE(test, drm_format_info_block_width(info, 0));
|
||||
KUNIT_EXPECT_FALSE(test, drm_format_info_block_width(info, 1));
|
||||
KUNIT_EXPECT_FALSE(test, drm_format_info_block_width(info, -1));
|
||||
static void drm_test_format_block_width_one_plane(struct kunit *test)
|
||||
{
|
||||
const struct drm_format_info *info = drm_format_info(DRM_FORMAT_XRGB4444);
|
||||
|
||||
/* Test 2 planes format */
|
||||
info = drm_format_info(DRM_FORMAT_NV12);
|
||||
KUNIT_EXPECT_TRUE(test, info);
|
||||
KUNIT_EXPECT_TRUE(test, drm_format_info_block_width(info, 0));
|
||||
KUNIT_EXPECT_TRUE(test, drm_format_info_block_width(info, 1));
|
||||
KUNIT_EXPECT_FALSE(test, drm_format_info_block_width(info, 2));
|
||||
KUNIT_EXPECT_FALSE(test, drm_format_info_block_width(info, -1));
|
||||
KUNIT_ASSERT_NOT_NULL(test, info);
|
||||
|
||||
/* Test 3 planes format */
|
||||
info = drm_format_info(DRM_FORMAT_YUV422);
|
||||
KUNIT_EXPECT_TRUE(test, info);
|
||||
KUNIT_EXPECT_TRUE(test, drm_format_info_block_width(info, 0));
|
||||
KUNIT_EXPECT_TRUE(test, drm_format_info_block_width(info, 1));
|
||||
KUNIT_EXPECT_TRUE(test, drm_format_info_block_width(info, 2));
|
||||
KUNIT_EXPECT_FALSE(test, drm_format_info_block_width(info, 3));
|
||||
KUNIT_EXPECT_FALSE(test, drm_format_info_block_width(info, -1));
|
||||
KUNIT_EXPECT_EQ(test, drm_format_info_block_width(info, 0), 1);
|
||||
KUNIT_EXPECT_EQ(test, drm_format_info_block_width(info, 1), 0);
|
||||
KUNIT_EXPECT_EQ(test, drm_format_info_block_width(info, -1), 0);
|
||||
}
|
||||
|
||||
static void drm_test_format_block_width_two_plane(struct kunit *test)
|
||||
{
|
||||
const struct drm_format_info *info = drm_format_info(DRM_FORMAT_NV12);
|
||||
|
||||
KUNIT_ASSERT_NOT_NULL(test, info);
|
||||
|
||||
KUNIT_EXPECT_EQ(test, drm_format_info_block_width(info, 0), 1);
|
||||
KUNIT_EXPECT_EQ(test, drm_format_info_block_width(info, 1), 1);
|
||||
KUNIT_EXPECT_EQ(test, drm_format_info_block_width(info, 2), 0);
|
||||
KUNIT_EXPECT_EQ(test, drm_format_info_block_width(info, -1), 0);
|
||||
}
|
||||
|
||||
static void drm_test_format_block_width_three_plane(struct kunit *test)
|
||||
{
|
||||
const struct drm_format_info *info = drm_format_info(DRM_FORMAT_YUV422);
|
||||
|
||||
KUNIT_ASSERT_NOT_NULL(test, info);
|
||||
|
||||
KUNIT_EXPECT_EQ(test, drm_format_info_block_width(info, 0), 1);
|
||||
KUNIT_EXPECT_EQ(test, drm_format_info_block_width(info, 1), 1);
|
||||
KUNIT_EXPECT_EQ(test, drm_format_info_block_width(info, 2), 1);
|
||||
KUNIT_EXPECT_EQ(test, drm_format_info_block_width(info, 3), 0);
|
||||
KUNIT_EXPECT_EQ(test, drm_format_info_block_width(info, -1), 0);
|
||||
}
|
||||
|
||||
static void drm_test_format_block_width_tiled(struct kunit *test)
|
||||
{
|
||||
const struct drm_format_info *info = drm_format_info(DRM_FORMAT_X0L0);
|
||||
|
||||
KUNIT_ASSERT_NOT_NULL(test, info);
|
||||
|
||||
/* Test a tiled format */
|
||||
info = drm_format_info(DRM_FORMAT_X0L0);
|
||||
KUNIT_EXPECT_TRUE(test, info);
|
||||
KUNIT_EXPECT_EQ(test, drm_format_info_block_width(info, 0), 2);
|
||||
KUNIT_EXPECT_FALSE(test, drm_format_info_block_width(info, 1));
|
||||
KUNIT_EXPECT_FALSE(test, drm_format_info_block_width(info, -1));
|
||||
KUNIT_EXPECT_EQ(test, drm_format_info_block_width(info, 1), 0);
|
||||
KUNIT_EXPECT_EQ(test, drm_format_info_block_width(info, -1), 0);
|
||||
}
|
||||
|
||||
static void igt_check_drm_format_block_height(struct kunit *test)
|
||||
static void drm_test_format_block_height_invalid(struct kunit *test)
|
||||
{
|
||||
const struct drm_format_info *info = NULL;
|
||||
|
||||
/* Test invalid arguments */
|
||||
KUNIT_EXPECT_FALSE(test, drm_format_info_block_height(info, 0));
|
||||
KUNIT_EXPECT_FALSE(test, drm_format_info_block_height(info, -1));
|
||||
KUNIT_EXPECT_FALSE(test, drm_format_info_block_height(info, 1));
|
||||
KUNIT_EXPECT_EQ(test, drm_format_info_block_height(info, 0), 0);
|
||||
KUNIT_EXPECT_EQ(test, drm_format_info_block_height(info, -1), 0);
|
||||
KUNIT_EXPECT_EQ(test, drm_format_info_block_height(info, 1), 0);
|
||||
}
|
||||
|
||||
/* Test 1 plane format */
|
||||
info = drm_format_info(DRM_FORMAT_XRGB4444);
|
||||
KUNIT_EXPECT_TRUE(test, info);
|
||||
KUNIT_EXPECT_TRUE(test, drm_format_info_block_height(info, 0));
|
||||
KUNIT_EXPECT_FALSE(test, drm_format_info_block_height(info, -1));
|
||||
KUNIT_EXPECT_FALSE(test, drm_format_info_block_height(info, 1));
|
||||
static void drm_test_format_block_height_one_plane(struct kunit *test)
|
||||
{
|
||||
const struct drm_format_info *info = drm_format_info(DRM_FORMAT_XRGB4444);
|
||||
|
||||
/* Test 2 planes format */
|
||||
info = drm_format_info(DRM_FORMAT_NV12);
|
||||
KUNIT_EXPECT_TRUE(test, info);
|
||||
KUNIT_EXPECT_TRUE(test, drm_format_info_block_height(info, 0));
|
||||
KUNIT_EXPECT_TRUE(test, drm_format_info_block_height(info, 1));
|
||||
KUNIT_EXPECT_FALSE(test, drm_format_info_block_height(info, 2));
|
||||
KUNIT_EXPECT_FALSE(test, drm_format_info_block_height(info, -1));
|
||||
KUNIT_ASSERT_NOT_NULL(test, info);
|
||||
|
||||
/* Test 3 planes format */
|
||||
info = drm_format_info(DRM_FORMAT_YUV422);
|
||||
KUNIT_EXPECT_TRUE(test, info);
|
||||
KUNIT_EXPECT_TRUE(test, drm_format_info_block_height(info, 0));
|
||||
KUNIT_EXPECT_TRUE(test, drm_format_info_block_height(info, 1));
|
||||
KUNIT_EXPECT_TRUE(test, drm_format_info_block_height(info, 2));
|
||||
KUNIT_EXPECT_FALSE(test, drm_format_info_block_height(info, 3));
|
||||
KUNIT_EXPECT_FALSE(test, drm_format_info_block_height(info, -1));
|
||||
KUNIT_EXPECT_EQ(test, drm_format_info_block_height(info, 0), 1);
|
||||
KUNIT_EXPECT_EQ(test, drm_format_info_block_height(info, -1), 0);
|
||||
KUNIT_EXPECT_EQ(test, drm_format_info_block_height(info, 1), 0);
|
||||
}
|
||||
|
||||
static void drm_test_format_block_height_two_plane(struct kunit *test)
|
||||
{
|
||||
const struct drm_format_info *info = drm_format_info(DRM_FORMAT_NV12);
|
||||
|
||||
KUNIT_ASSERT_NOT_NULL(test, info);
|
||||
|
||||
KUNIT_EXPECT_EQ(test, drm_format_info_block_height(info, 0), 1);
|
||||
KUNIT_EXPECT_EQ(test, drm_format_info_block_height(info, 1), 1);
|
||||
KUNIT_EXPECT_EQ(test, drm_format_info_block_height(info, 2), 0);
|
||||
KUNIT_EXPECT_EQ(test, drm_format_info_block_height(info, -1), 0);
|
||||
}
|
||||
|
||||
static void drm_test_format_block_height_three_plane(struct kunit *test)
|
||||
{
|
||||
const struct drm_format_info *info = drm_format_info(DRM_FORMAT_YUV422);
|
||||
|
||||
KUNIT_ASSERT_NOT_NULL(test, info);
|
||||
|
||||
KUNIT_EXPECT_EQ(test, drm_format_info_block_height(info, 0), 1);
|
||||
KUNIT_EXPECT_EQ(test, drm_format_info_block_height(info, 1), 1);
|
||||
KUNIT_EXPECT_EQ(test, drm_format_info_block_height(info, 2), 1);
|
||||
KUNIT_EXPECT_EQ(test, drm_format_info_block_height(info, 3), 0);
|
||||
KUNIT_EXPECT_EQ(test, drm_format_info_block_height(info, -1), 0);
|
||||
}
|
||||
|
||||
static void drm_test_format_block_height_tiled(struct kunit *test)
|
||||
{
|
||||
const struct drm_format_info *info = drm_format_info(DRM_FORMAT_X0L0);
|
||||
|
||||
KUNIT_ASSERT_NOT_NULL(test, info);
|
||||
|
||||
/* Test a tiled format */
|
||||
info = drm_format_info(DRM_FORMAT_X0L0);
|
||||
KUNIT_EXPECT_TRUE(test, info);
|
||||
KUNIT_EXPECT_EQ(test, drm_format_info_block_height(info, 0), 2);
|
||||
KUNIT_EXPECT_FALSE(test, drm_format_info_block_height(info, 1));
|
||||
KUNIT_EXPECT_FALSE(test, drm_format_info_block_height(info, -1));
|
||||
KUNIT_EXPECT_EQ(test, drm_format_info_block_height(info, 1), 0);
|
||||
KUNIT_EXPECT_EQ(test, drm_format_info_block_height(info, -1), 0);
|
||||
}
|
||||
|
||||
static void igt_check_drm_format_min_pitch_for_single_plane(struct kunit *test)
|
||||
static void drm_test_format_min_pitch_invalid(struct kunit *test)
|
||||
{
|
||||
const struct drm_format_info *info = NULL;
|
||||
|
||||
/* Test invalid arguments */
|
||||
KUNIT_EXPECT_FALSE(test, drm_format_info_min_pitch(info, 0, 0));
|
||||
KUNIT_EXPECT_FALSE(test, drm_format_info_min_pitch(info, -1, 0));
|
||||
KUNIT_EXPECT_FALSE(test, drm_format_info_min_pitch(info, 1, 0));
|
||||
KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 0, 0), 0);
|
||||
KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, -1, 0), 0);
|
||||
KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 1, 0), 0);
|
||||
}
|
||||
|
||||
/* Test 1 plane 8 bits per pixel format */
|
||||
info = drm_format_info(DRM_FORMAT_RGB332);
|
||||
KUNIT_EXPECT_TRUE(test, info);
|
||||
KUNIT_EXPECT_FALSE(test, drm_format_info_min_pitch(info, 0, 0));
|
||||
KUNIT_EXPECT_FALSE(test, drm_format_info_min_pitch(info, -1, 0));
|
||||
KUNIT_EXPECT_FALSE(test, drm_format_info_min_pitch(info, 1, 0));
|
||||
static void drm_test_format_min_pitch_one_plane_8bpp(struct kunit *test)
|
||||
{
|
||||
const struct drm_format_info *info = drm_format_info(DRM_FORMAT_RGB332);
|
||||
|
||||
KUNIT_ASSERT_NOT_NULL(test, info);
|
||||
|
||||
KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 0, 0), 0);
|
||||
KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, -1, 0), 0);
|
||||
KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 1, 0), 0);
|
||||
|
||||
KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 0, 1), 1);
|
||||
KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 0, 2), 2);
|
||||
|
@ -118,13 +151,17 @@ static void igt_check_drm_format_min_pitch_for_single_plane(struct kunit *test)
|
|||
(uint64_t)UINT_MAX);
|
||||
KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 0, (UINT_MAX - 1)),
|
||||
(uint64_t)(UINT_MAX - 1));
|
||||
}
|
||||
|
||||
/* Test 1 plane 16 bits per pixel format */
|
||||
info = drm_format_info(DRM_FORMAT_XRGB4444);
|
||||
KUNIT_EXPECT_TRUE(test, info);
|
||||
KUNIT_EXPECT_FALSE(test, drm_format_info_min_pitch(info, 0, 0));
|
||||
KUNIT_EXPECT_FALSE(test, drm_format_info_min_pitch(info, -1, 0));
|
||||
KUNIT_EXPECT_FALSE(test, drm_format_info_min_pitch(info, 1, 0));
|
||||
static void drm_test_format_min_pitch_one_plane_16bpp(struct kunit *test)
|
||||
{
|
||||
const struct drm_format_info *info = drm_format_info(DRM_FORMAT_XRGB4444);
|
||||
|
||||
KUNIT_ASSERT_NOT_NULL(test, info);
|
||||
|
||||
KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 0, 0), 0);
|
||||
KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, -1, 0), 0);
|
||||
KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 1, 0), 0);
|
||||
|
||||
KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 0, 1), 2);
|
||||
KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 0, 2), 4);
|
||||
|
@ -137,13 +174,17 @@ static void igt_check_drm_format_min_pitch_for_single_plane(struct kunit *test)
|
|||
(uint64_t)UINT_MAX * 2);
|
||||
KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 0, (UINT_MAX - 1)),
|
||||
(uint64_t)(UINT_MAX - 1) * 2);
|
||||
}
|
||||
|
||||
/* Test 1 plane 24 bits per pixel format */
|
||||
info = drm_format_info(DRM_FORMAT_RGB888);
|
||||
KUNIT_EXPECT_TRUE(test, info);
|
||||
KUNIT_EXPECT_FALSE(test, drm_format_info_min_pitch(info, 0, 0));
|
||||
KUNIT_EXPECT_FALSE(test, drm_format_info_min_pitch(info, -1, 0));
|
||||
KUNIT_EXPECT_FALSE(test, drm_format_info_min_pitch(info, 1, 0));
|
||||
static void drm_test_format_min_pitch_one_plane_24bpp(struct kunit *test)
|
||||
{
|
||||
const struct drm_format_info *info = drm_format_info(DRM_FORMAT_RGB888);
|
||||
|
||||
KUNIT_ASSERT_NOT_NULL(test, info);
|
||||
|
||||
KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 0, 0), 0);
|
||||
KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, -1, 0), 0);
|
||||
KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 1, 0), 0);
|
||||
|
||||
KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 0, 1), 3);
|
||||
KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 0, 2), 6);
|
||||
|
@ -154,15 +195,19 @@ static void igt_check_drm_format_min_pitch_for_single_plane(struct kunit *test)
|
|||
KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 0, 671), 2013);
|
||||
KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 0, UINT_MAX),
|
||||
(uint64_t)UINT_MAX * 3);
|
||||
KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 0, (UINT_MAX - 1)),
|
||||
KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 0, UINT_MAX - 1),
|
||||
(uint64_t)(UINT_MAX - 1) * 3);
|
||||
}
|
||||
|
||||
/* Test 1 plane 32 bits per pixel format */
|
||||
info = drm_format_info(DRM_FORMAT_ABGR8888);
|
||||
KUNIT_EXPECT_TRUE(test, info);
|
||||
KUNIT_EXPECT_FALSE(test, drm_format_info_min_pitch(info, 0, 0));
|
||||
KUNIT_EXPECT_FALSE(test, drm_format_info_min_pitch(info, -1, 0));
|
||||
KUNIT_EXPECT_FALSE(test, drm_format_info_min_pitch(info, 1, 0));
|
||||
static void drm_test_format_min_pitch_one_plane_32bpp(struct kunit *test)
|
||||
{
|
||||
const struct drm_format_info *info = drm_format_info(DRM_FORMAT_ABGR8888);
|
||||
|
||||
KUNIT_ASSERT_NOT_NULL(test, info);
|
||||
|
||||
KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 0, 0), 0);
|
||||
KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, -1, 0), 0);
|
||||
KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 1, 0), 0);
|
||||
|
||||
KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 0, 1), 4);
|
||||
KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 0, 2), 8);
|
||||
|
@ -173,21 +218,20 @@ static void igt_check_drm_format_min_pitch_for_single_plane(struct kunit *test)
|
|||
KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 0, 671), 2684);
|
||||
KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 0, UINT_MAX),
|
||||
(uint64_t)UINT_MAX * 4);
|
||||
KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 0, (UINT_MAX - 1)),
|
||||
KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 0, UINT_MAX - 1),
|
||||
(uint64_t)(UINT_MAX - 1) * 4);
|
||||
}
|
||||
|
||||
static void igt_check_drm_format_min_pitch_for_multi_planar(struct kunit *test)
|
||||
static void drm_test_format_min_pitch_two_plane(struct kunit *test)
|
||||
{
|
||||
const struct drm_format_info *info = NULL;
|
||||
const struct drm_format_info *info = drm_format_info(DRM_FORMAT_NV12);
|
||||
|
||||
/* Test 2 planes format */
|
||||
info = drm_format_info(DRM_FORMAT_NV12);
|
||||
KUNIT_EXPECT_TRUE(test, info);
|
||||
KUNIT_EXPECT_FALSE(test, drm_format_info_min_pitch(info, 0, 0));
|
||||
KUNIT_EXPECT_FALSE(test, drm_format_info_min_pitch(info, 1, 0));
|
||||
KUNIT_EXPECT_FALSE(test, drm_format_info_min_pitch(info, -1, 0));
|
||||
KUNIT_EXPECT_FALSE(test, drm_format_info_min_pitch(info, 2, 0));
|
||||
KUNIT_ASSERT_NOT_NULL(test, info);
|
||||
|
||||
KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 0, 0), 0);
|
||||
KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 1, 0), 0);
|
||||
KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, -1, 0), 0);
|
||||
KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 2, 0), 0);
|
||||
|
||||
KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 0, 1), 1);
|
||||
KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 1, 1), 2);
|
||||
|
@ -211,15 +255,19 @@ static void igt_check_drm_format_min_pitch_for_multi_planar(struct kunit *test)
|
|||
(uint64_t)(UINT_MAX - 1));
|
||||
KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 1, (UINT_MAX - 1) / 2),
|
||||
(uint64_t)(UINT_MAX - 1));
|
||||
}
|
||||
|
||||
/* Test 3 planes 8 bits per pixel format */
|
||||
info = drm_format_info(DRM_FORMAT_YUV422);
|
||||
KUNIT_EXPECT_TRUE(test, info);
|
||||
KUNIT_EXPECT_FALSE(test, drm_format_info_min_pitch(info, 0, 0));
|
||||
KUNIT_EXPECT_FALSE(test, drm_format_info_min_pitch(info, 1, 0));
|
||||
KUNIT_EXPECT_FALSE(test, drm_format_info_min_pitch(info, 2, 0));
|
||||
KUNIT_EXPECT_FALSE(test, drm_format_info_min_pitch(info, -1, 0));
|
||||
KUNIT_EXPECT_FALSE(test, drm_format_info_min_pitch(info, 3, 0));
|
||||
static void drm_test_format_min_pitch_three_plane_8bpp(struct kunit *test)
|
||||
{
|
||||
const struct drm_format_info *info = drm_format_info(DRM_FORMAT_YUV422);
|
||||
|
||||
KUNIT_ASSERT_NOT_NULL(test, info);
|
||||
|
||||
KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 0, 0), 0);
|
||||
KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 1, 0), 0);
|
||||
KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 2, 0), 0);
|
||||
KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, -1, 0), 0);
|
||||
KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 3, 0), 0);
|
||||
|
||||
KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 0, 1), 1);
|
||||
KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 1, 1), 1);
|
||||
|
@ -256,16 +304,15 @@ static void igt_check_drm_format_min_pitch_for_multi_planar(struct kunit *test)
|
|||
(uint64_t)(UINT_MAX - 1) / 2);
|
||||
}
|
||||
|
||||
static void igt_check_drm_format_min_pitch_for_tiled_format(struct kunit *test)
|
||||
static void drm_test_format_min_pitch_tiled(struct kunit *test)
|
||||
{
|
||||
const struct drm_format_info *info = NULL;
|
||||
const struct drm_format_info *info = drm_format_info(DRM_FORMAT_X0L2);
|
||||
|
||||
/* Test tiled format */
|
||||
info = drm_format_info(DRM_FORMAT_X0L2);
|
||||
KUNIT_EXPECT_TRUE(test, info);
|
||||
KUNIT_EXPECT_FALSE(test, drm_format_info_min_pitch(info, 0, 0));
|
||||
KUNIT_EXPECT_FALSE(test, drm_format_info_min_pitch(info, -1, 0));
|
||||
KUNIT_EXPECT_FALSE(test, drm_format_info_min_pitch(info, 1, 0));
|
||||
KUNIT_ASSERT_NOT_NULL(test, info);
|
||||
|
||||
KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 0, 0), 0);
|
||||
KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, -1, 0), 0);
|
||||
KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 1, 0), 0);
|
||||
|
||||
KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 0, 1), 2);
|
||||
KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 0, 2), 4);
|
||||
|
@ -281,12 +328,25 @@ static void igt_check_drm_format_min_pitch_for_tiled_format(struct kunit *test)
|
|||
}
|
||||
|
||||
static struct kunit_case drm_format_tests[] = {
|
||||
KUNIT_CASE(igt_check_drm_format_block_width),
|
||||
KUNIT_CASE(igt_check_drm_format_block_height),
|
||||
KUNIT_CASE(igt_check_drm_format_min_pitch_for_single_plane),
|
||||
KUNIT_CASE(igt_check_drm_format_min_pitch_for_multi_planar),
|
||||
KUNIT_CASE(igt_check_drm_format_min_pitch_for_tiled_format),
|
||||
{ }
|
||||
KUNIT_CASE(drm_test_format_block_width_invalid),
|
||||
KUNIT_CASE(drm_test_format_block_width_one_plane),
|
||||
KUNIT_CASE(drm_test_format_block_width_two_plane),
|
||||
KUNIT_CASE(drm_test_format_block_width_three_plane),
|
||||
KUNIT_CASE(drm_test_format_block_width_tiled),
|
||||
KUNIT_CASE(drm_test_format_block_height_invalid),
|
||||
KUNIT_CASE(drm_test_format_block_height_one_plane),
|
||||
KUNIT_CASE(drm_test_format_block_height_two_plane),
|
||||
KUNIT_CASE(drm_test_format_block_height_three_plane),
|
||||
KUNIT_CASE(drm_test_format_block_height_tiled),
|
||||
KUNIT_CASE(drm_test_format_min_pitch_invalid),
|
||||
KUNIT_CASE(drm_test_format_min_pitch_one_plane_8bpp),
|
||||
KUNIT_CASE(drm_test_format_min_pitch_one_plane_16bpp),
|
||||
KUNIT_CASE(drm_test_format_min_pitch_one_plane_24bpp),
|
||||
KUNIT_CASE(drm_test_format_min_pitch_one_plane_32bpp),
|
||||
KUNIT_CASE(drm_test_format_min_pitch_two_plane),
|
||||
KUNIT_CASE(drm_test_format_min_pitch_three_plane_8bpp),
|
||||
KUNIT_CASE(drm_test_format_min_pitch_tiled),
|
||||
{}
|
||||
};
|
||||
|
||||
static struct kunit_suite drm_format_test_suite = {
|
||||
|
|
|
@ -25,7 +25,7 @@ struct drm_framebuffer_test {
|
|||
const char *name;
|
||||
};
|
||||
|
||||
static struct drm_framebuffer_test createbuffer_tests[] = {
|
||||
static const struct drm_framebuffer_test drm_framebuffer_create_cases[] = {
|
||||
{ .buffer_created = 1, .name = "ABGR8888 normal sizes",
|
||||
.cmd = { .width = 600, .height = 600, .pixel_format = DRM_FORMAT_ABGR8888,
|
||||
.handles = { 1, 0, 0 }, .pitches = { 4 * 600, 0, 0 },
|
||||
|
@ -330,43 +330,50 @@ static struct drm_mode_config_funcs mock_config_funcs = {
|
|||
.fb_create = fb_create_mock,
|
||||
};
|
||||
|
||||
static struct drm_device mock_drm_device = {
|
||||
.mode_config = {
|
||||
.min_width = MIN_WIDTH,
|
||||
.max_width = MAX_WIDTH,
|
||||
.min_height = MIN_HEIGHT,
|
||||
.max_height = MAX_HEIGHT,
|
||||
.funcs = &mock_config_funcs,
|
||||
},
|
||||
};
|
||||
|
||||
static int execute_drm_mode_fb_cmd2(struct drm_mode_fb_cmd2 *r)
|
||||
static int drm_framebuffer_test_init(struct kunit *test)
|
||||
{
|
||||
struct drm_device *mock;
|
||||
|
||||
mock = kunit_kzalloc(test, sizeof(*mock), GFP_KERNEL);
|
||||
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, mock);
|
||||
|
||||
mock->mode_config.min_width = MIN_WIDTH;
|
||||
mock->mode_config.max_width = MAX_WIDTH;
|
||||
mock->mode_config.min_height = MIN_HEIGHT;
|
||||
mock->mode_config.max_height = MAX_HEIGHT;
|
||||
mock->mode_config.funcs = &mock_config_funcs;
|
||||
|
||||
test->priv = mock;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void drm_test_framebuffer_create(struct kunit *test)
|
||||
{
|
||||
const struct drm_framebuffer_test *params = test->param_value;
|
||||
struct drm_device *mock = test->priv;
|
||||
int buffer_created = 0;
|
||||
|
||||
mock_drm_device.dev_private = &buffer_created;
|
||||
drm_internal_framebuffer_create(&mock_drm_device, r, NULL);
|
||||
return buffer_created;
|
||||
mock->dev_private = &buffer_created;
|
||||
drm_internal_framebuffer_create(mock, ¶ms->cmd, NULL);
|
||||
KUNIT_EXPECT_EQ(test, params->buffer_created, buffer_created);
|
||||
}
|
||||
|
||||
static void igt_check_drm_framebuffer_create(struct kunit *test)
|
||||
static void drm_framebuffer_test_to_desc(const struct drm_framebuffer_test *t, char *desc)
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(createbuffer_tests); i++) {
|
||||
KUNIT_EXPECT_EQ_MSG(test, createbuffer_tests[i].buffer_created,
|
||||
execute_drm_mode_fb_cmd2(&createbuffer_tests[i].cmd),
|
||||
"Test %d: \"%s\" failed\n", i, createbuffer_tests[i].name);
|
||||
}
|
||||
strcpy(desc, t->name);
|
||||
}
|
||||
|
||||
KUNIT_ARRAY_PARAM(drm_framebuffer_create, drm_framebuffer_create_cases,
|
||||
drm_framebuffer_test_to_desc);
|
||||
|
||||
static struct kunit_case drm_framebuffer_tests[] = {
|
||||
KUNIT_CASE(igt_check_drm_framebuffer_create),
|
||||
KUNIT_CASE_PARAM(drm_test_framebuffer_create, drm_framebuffer_create_gen_params),
|
||||
{ }
|
||||
};
|
||||
|
||||
static struct kunit_suite drm_framebuffer_test_suite = {
|
||||
.name = "drm_framebuffer",
|
||||
.init = drm_framebuffer_test_init,
|
||||
.test_cases = drm_framebuffer_tests,
|
||||
};
|
||||
|
||||
|
|
|
@ -191,7 +191,7 @@ static bool assert_node(struct kunit *test, struct drm_mm_node *node, struct drm
|
|||
return ok;
|
||||
}
|
||||
|
||||
static void igt_mm_init(struct kunit *test)
|
||||
static void drm_test_mm_init(struct kunit *test)
|
||||
{
|
||||
const unsigned int size = 4096;
|
||||
struct drm_mm mm;
|
||||
|
@ -245,7 +245,7 @@ out:
|
|||
drm_mm_takedown(&mm);
|
||||
}
|
||||
|
||||
static void igt_mm_debug(struct kunit *test)
|
||||
static void drm_test_mm_debug(struct kunit *test)
|
||||
{
|
||||
struct drm_mm mm;
|
||||
struct drm_mm_node nodes[2];
|
||||
|
@ -341,7 +341,7 @@ static bool check_reserve_boundaries(struct kunit *test, struct drm_mm *mm,
|
|||
return true;
|
||||
}
|
||||
|
||||
static int __igt_reserve(struct kunit *test, unsigned int count, u64 size)
|
||||
static int __drm_test_mm_reserve(struct kunit *test, unsigned int count, u64 size)
|
||||
{
|
||||
DRM_RND_STATE(prng, random_seed);
|
||||
struct drm_mm mm;
|
||||
|
@ -349,7 +349,7 @@ static int __igt_reserve(struct kunit *test, unsigned int count, u64 size)
|
|||
unsigned int *order, n, m, o = 0;
|
||||
int ret, err;
|
||||
|
||||
/* For exercising drm_mm_reserve_node(struct kunit *test, ), we want to check that
|
||||
/* For exercising drm_mm_reserve_node(), we want to check that
|
||||
* reservations outside of the drm_mm range are rejected, and to
|
||||
* overlapping and otherwise already occupied ranges. Afterwards,
|
||||
* the tree and nodes should be intact.
|
||||
|
@ -463,7 +463,7 @@ err:
|
|||
return ret;
|
||||
}
|
||||
|
||||
static void igt_mm_reserve(struct kunit *test)
|
||||
static void drm_test_mm_reserve(struct kunit *test)
|
||||
{
|
||||
const unsigned int count = min_t(unsigned int, BIT(10), max_iterations);
|
||||
int n;
|
||||
|
@ -471,9 +471,9 @@ static void igt_mm_reserve(struct kunit *test)
|
|||
for_each_prime_number_from(n, 1, 54) {
|
||||
u64 size = BIT_ULL(n);
|
||||
|
||||
KUNIT_ASSERT_FALSE(test, __igt_reserve(test, count, size - 1));
|
||||
KUNIT_ASSERT_FALSE(test, __igt_reserve(test, count, size));
|
||||
KUNIT_ASSERT_FALSE(test, __igt_reserve(test, count, size + 1));
|
||||
KUNIT_ASSERT_FALSE(test, __drm_test_mm_reserve(test, count, size - 1));
|
||||
KUNIT_ASSERT_FALSE(test, __drm_test_mm_reserve(test, count, size));
|
||||
KUNIT_ASSERT_FALSE(test, __drm_test_mm_reserve(test, count, size + 1));
|
||||
|
||||
cond_resched();
|
||||
}
|
||||
|
@ -524,7 +524,7 @@ static bool expect_insert_fail(struct kunit *test, struct drm_mm *mm, u64 size)
|
|||
return false;
|
||||
}
|
||||
|
||||
static int __igt_insert(struct kunit *test, unsigned int count, u64 size, bool replace)
|
||||
static int __drm_test_mm_insert(struct kunit *test, unsigned int count, u64 size, bool replace)
|
||||
{
|
||||
DRM_RND_STATE(prng, random_seed);
|
||||
const struct insert_mode *mode;
|
||||
|
@ -660,7 +660,7 @@ err_nodes:
|
|||
return ret;
|
||||
}
|
||||
|
||||
static void igt_mm_insert(struct kunit *test)
|
||||
static void drm_test_mm_insert(struct kunit *test)
|
||||
{
|
||||
const unsigned int count = min_t(unsigned int, BIT(10), max_iterations);
|
||||
unsigned int n;
|
||||
|
@ -668,20 +668,20 @@ static void igt_mm_insert(struct kunit *test)
|
|||
for_each_prime_number_from(n, 1, 54) {
|
||||
u64 size = BIT_ULL(n);
|
||||
|
||||
KUNIT_ASSERT_FALSE(test, __igt_insert(test, count, size - 1, false));
|
||||
KUNIT_ASSERT_FALSE(test, __igt_insert(test, count, size, false));
|
||||
KUNIT_ASSERT_FALSE(test, __igt_insert(test, count, size + 1, false));
|
||||
KUNIT_ASSERT_FALSE(test, __drm_test_mm_insert(test, count, size - 1, false));
|
||||
KUNIT_ASSERT_FALSE(test, __drm_test_mm_insert(test, count, size, false));
|
||||
KUNIT_ASSERT_FALSE(test, __drm_test_mm_insert(test, count, size + 1, false));
|
||||
|
||||
cond_resched();
|
||||
}
|
||||
}
|
||||
|
||||
static void igt_mm_replace(struct kunit *test)
|
||||
static void drm_test_mm_replace(struct kunit *test)
|
||||
{
|
||||
const unsigned int count = min_t(unsigned int, BIT(10), max_iterations);
|
||||
unsigned int n;
|
||||
|
||||
/* Reuse igt_insert to exercise replacement by inserting a dummy node,
|
||||
/* Reuse __drm_test_mm_insert to exercise replacement by inserting a dummy node,
|
||||
* then replacing it with the intended node. We want to check that
|
||||
* the tree is intact and all the information we need is carried
|
||||
* across to the target node.
|
||||
|
@ -690,9 +690,9 @@ static void igt_mm_replace(struct kunit *test)
|
|||
for_each_prime_number_from(n, 1, 54) {
|
||||
u64 size = BIT_ULL(n);
|
||||
|
||||
KUNIT_ASSERT_FALSE(test, __igt_insert(test, count, size - 1, true));
|
||||
KUNIT_ASSERT_FALSE(test, __igt_insert(test, count, size, true));
|
||||
KUNIT_ASSERT_FALSE(test, __igt_insert(test, count, size + 1, true));
|
||||
KUNIT_ASSERT_FALSE(test, __drm_test_mm_insert(test, count, size - 1, true));
|
||||
KUNIT_ASSERT_FALSE(test, __drm_test_mm_insert(test, count, size, true));
|
||||
KUNIT_ASSERT_FALSE(test, __drm_test_mm_insert(test, count, size + 1, true));
|
||||
|
||||
cond_resched();
|
||||
}
|
||||
|
@ -808,7 +808,8 @@ static bool assert_contiguous_in_range(struct kunit *test, struct drm_mm *mm,
|
|||
return true;
|
||||
}
|
||||
|
||||
static int __igt_insert_range(struct kunit *test, unsigned int count, u64 size, u64 start, u64 end)
|
||||
static int __drm_test_mm_insert_range(struct kunit *test, unsigned int count, u64 size,
|
||||
u64 start, u64 end)
|
||||
{
|
||||
const struct insert_mode *mode;
|
||||
struct drm_mm mm;
|
||||
|
@ -820,7 +821,7 @@ static int __igt_insert_range(struct kunit *test, unsigned int count, u64 size,
|
|||
DRM_MM_BUG_ON(!size);
|
||||
DRM_MM_BUG_ON(end <= start);
|
||||
|
||||
/* Very similar to __igt_insert(struct kunit *test, ), but now instead of populating the
|
||||
/* Very similar to __drm_test_mm_insert(), but now instead of populating the
|
||||
* full range of the drm_mm, we try to fill a small portion of it.
|
||||
*/
|
||||
|
||||
|
@ -921,7 +922,7 @@ static int insert_outside_range(struct kunit *test)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void igt_mm_insert_range(struct kunit *test)
|
||||
static void drm_test_mm_insert_range(struct kunit *test)
|
||||
{
|
||||
const unsigned int count = min_t(unsigned int, BIT(13), max_iterations);
|
||||
unsigned int n;
|
||||
|
@ -933,21 +934,21 @@ static void igt_mm_insert_range(struct kunit *test)
|
|||
const u64 size = BIT_ULL(n);
|
||||
const u64 max = count * size;
|
||||
|
||||
KUNIT_ASSERT_FALSE(test, __igt_insert_range(test, count, size, 0, max));
|
||||
KUNIT_ASSERT_FALSE(test, __igt_insert_range(test, count, size, 1, max));
|
||||
KUNIT_ASSERT_FALSE(test, __igt_insert_range(test, count, size, 0, max - 1));
|
||||
KUNIT_ASSERT_FALSE(test, __igt_insert_range(test, count, size, 0, max / 2));
|
||||
KUNIT_ASSERT_FALSE(test, __igt_insert_range(test, count, size, max / 2, max / 2));
|
||||
KUNIT_ASSERT_FALSE(test, __igt_insert_range(test, count, size,
|
||||
max / 4 + 1, 3 * max / 4 - 1));
|
||||
KUNIT_ASSERT_FALSE(test, __drm_test_mm_insert_range(test, count, size, 0, max));
|
||||
KUNIT_ASSERT_FALSE(test, __drm_test_mm_insert_range(test, count, size, 1, max));
|
||||
KUNIT_ASSERT_FALSE(test, __drm_test_mm_insert_range(test, count, size, 0, max - 1));
|
||||
KUNIT_ASSERT_FALSE(test, __drm_test_mm_insert_range(test, count, size, 0, max / 2));
|
||||
KUNIT_ASSERT_FALSE(test, __drm_test_mm_insert_range(test, count, size,
|
||||
max / 2, max / 2));
|
||||
KUNIT_ASSERT_FALSE(test, __drm_test_mm_insert_range(test, count, size,
|
||||
max / 4 + 1, 3 * max / 4 - 1));
|
||||
|
||||
cond_resched();
|
||||
}
|
||||
}
|
||||
|
||||
static int prepare_igt_frag(struct kunit *test, struct drm_mm *mm,
|
||||
struct drm_mm_node *nodes, unsigned int num_insert,
|
||||
const struct insert_mode *mode)
|
||||
static int prepare_frag(struct kunit *test, struct drm_mm *mm, struct drm_mm_node *nodes,
|
||||
unsigned int num_insert, const struct insert_mode *mode)
|
||||
{
|
||||
unsigned int size = 4096;
|
||||
unsigned int i;
|
||||
|
@ -987,7 +988,7 @@ static u64 get_insert_time(struct kunit *test, struct drm_mm *mm,
|
|||
return ktime_to_ns(ktime_sub(ktime_get(), start));
|
||||
}
|
||||
|
||||
static void igt_mm_frag(struct kunit *test)
|
||||
static void drm_test_mm_frag(struct kunit *test)
|
||||
{
|
||||
struct drm_mm mm;
|
||||
const struct insert_mode *mode;
|
||||
|
@ -997,15 +998,15 @@ static void igt_mm_frag(struct kunit *test)
|
|||
|
||||
/* We need 4 * insert_size nodes to hold intermediate allocated
|
||||
* drm_mm nodes.
|
||||
* 1 times for prepare_igt_frag(struct kunit *test, )
|
||||
* 1 times for get_insert_time(struct kunit *test, )
|
||||
* 2 times for get_insert_time(struct kunit *test, )
|
||||
* 1 times for prepare_frag()
|
||||
* 1 times for get_insert_time()
|
||||
* 2 times for get_insert_time()
|
||||
*/
|
||||
nodes = vzalloc(array_size(insert_size * 4, sizeof(*nodes)));
|
||||
KUNIT_ASSERT_TRUE(test, nodes);
|
||||
|
||||
/* For BOTTOMUP and TOPDOWN, we first fragment the
|
||||
* address space using prepare_igt_frag(struct kunit *test, ) and then try to verify
|
||||
* address space using prepare_frag() and then try to verify
|
||||
* that insertions scale quadratically from 10k to 20k insertions
|
||||
*/
|
||||
drm_mm_init(&mm, 1, U64_MAX - 2);
|
||||
|
@ -1016,7 +1017,7 @@ static void igt_mm_frag(struct kunit *test)
|
|||
mode->mode != DRM_MM_INSERT_HIGH)
|
||||
continue;
|
||||
|
||||
if (prepare_igt_frag(test, &mm, nodes, insert_size, mode))
|
||||
if (prepare_frag(test, &mm, nodes, insert_size, mode))
|
||||
goto err;
|
||||
|
||||
insert_time1 = get_insert_time(test, &mm, insert_size,
|
||||
|
@ -1049,7 +1050,7 @@ err:
|
|||
vfree(nodes);
|
||||
}
|
||||
|
||||
static void igt_mm_align(struct kunit *test)
|
||||
static void drm_test_mm_align(struct kunit *test)
|
||||
{
|
||||
const struct insert_mode *mode;
|
||||
const unsigned int max_count = min(8192u, max_prime);
|
||||
|
@ -1096,7 +1097,7 @@ out:
|
|||
vfree(nodes);
|
||||
}
|
||||
|
||||
static void igt_align_pot(struct kunit *test, int max)
|
||||
static void drm_test_mm_align_pot(struct kunit *test, int max)
|
||||
{
|
||||
struct drm_mm mm;
|
||||
struct drm_mm_node *node, *next;
|
||||
|
@ -1133,14 +1134,14 @@ out:
|
|||
drm_mm_takedown(&mm);
|
||||
}
|
||||
|
||||
static void igt_mm_align32(struct kunit *test)
|
||||
static void drm_test_mm_align32(struct kunit *test)
|
||||
{
|
||||
igt_align_pot(test, 32);
|
||||
drm_test_mm_align_pot(test, 32);
|
||||
}
|
||||
|
||||
static void igt_mm_align64(struct kunit *test)
|
||||
static void drm_test_mm_align64(struct kunit *test)
|
||||
{
|
||||
igt_align_pot(test, 64);
|
||||
drm_test_mm_align_pot(test, 64);
|
||||
}
|
||||
|
||||
static void show_scan(struct kunit *test, const struct drm_mm_scan *scan)
|
||||
|
@ -1386,7 +1387,7 @@ static int evict_something(struct kunit *test, struct drm_mm *mm,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void igt_mm_evict(struct kunit *test)
|
||||
static void drm_test_mm_evict(struct kunit *test)
|
||||
{
|
||||
DRM_RND_STATE(prng, random_seed);
|
||||
const unsigned int size = 8192;
|
||||
|
@ -1477,7 +1478,7 @@ err_nodes:
|
|||
vfree(nodes);
|
||||
}
|
||||
|
||||
static void igt_mm_evict_range(struct kunit *test)
|
||||
static void drm_test_mm_evict_range(struct kunit *test)
|
||||
{
|
||||
DRM_RND_STATE(prng, random_seed);
|
||||
const unsigned int size = 8192;
|
||||
|
@ -1490,7 +1491,7 @@ static void igt_mm_evict_range(struct kunit *test)
|
|||
struct drm_mm_node *node, *next;
|
||||
unsigned int *order, n;
|
||||
|
||||
/* Like igt_evict() but now we are limiting the search to a
|
||||
/* Like drm_test_mm_evict() but now we are limiting the search to a
|
||||
* small portion of the full drm_mm.
|
||||
*/
|
||||
|
||||
|
@ -1564,7 +1565,7 @@ static unsigned int node_index(const struct drm_mm_node *node)
|
|||
return div64_u64(node->start, node->size);
|
||||
}
|
||||
|
||||
static void igt_mm_topdown(struct kunit *test)
|
||||
static void drm_test_mm_topdown(struct kunit *test)
|
||||
{
|
||||
const struct insert_mode *topdown = &insert_modes[TOPDOWN];
|
||||
|
||||
|
@ -1671,7 +1672,7 @@ err_nodes:
|
|||
vfree(nodes);
|
||||
}
|
||||
|
||||
static void igt_mm_bottomup(struct kunit *test)
|
||||
static void drm_test_mm_bottomup(struct kunit *test)
|
||||
{
|
||||
const struct insert_mode *bottomup = &insert_modes[BOTTOMUP];
|
||||
|
||||
|
@ -1683,7 +1684,7 @@ static void igt_mm_bottomup(struct kunit *test)
|
|||
struct drm_mm_node *nodes, *node, *next;
|
||||
unsigned int *order, n, m, o = 0;
|
||||
|
||||
/* Like igt_topdown, but instead of searching for the last hole,
|
||||
/* Like drm_test_mm_topdown, but instead of searching for the last hole,
|
||||
* we search for the first.
|
||||
*/
|
||||
|
||||
|
@ -1763,7 +1764,7 @@ err_nodes:
|
|||
vfree(nodes);
|
||||
}
|
||||
|
||||
static void __igt_once(struct kunit *test, unsigned int mode)
|
||||
static void drm_test_mm_once(struct kunit *test, unsigned int mode)
|
||||
{
|
||||
struct drm_mm mm;
|
||||
struct drm_mm_node rsvd_lo, rsvd_hi, node;
|
||||
|
@ -1806,14 +1807,14 @@ err:
|
|||
drm_mm_takedown(&mm);
|
||||
}
|
||||
|
||||
static void igt_mm_lowest(struct kunit *test)
|
||||
static void drm_test_mm_lowest(struct kunit *test)
|
||||
{
|
||||
__igt_once(test, DRM_MM_INSERT_LOW);
|
||||
drm_test_mm_once(test, DRM_MM_INSERT_LOW);
|
||||
}
|
||||
|
||||
static void igt_mm_highest(struct kunit *test)
|
||||
static void drm_test_mm_highest(struct kunit *test)
|
||||
{
|
||||
__igt_once(test, DRM_MM_INSERT_HIGH);
|
||||
drm_test_mm_once(test, DRM_MM_INSERT_HIGH);
|
||||
}
|
||||
|
||||
static void separate_adjacent_colors(const struct drm_mm_node *node,
|
||||
|
@ -1842,7 +1843,7 @@ static bool colors_abutt(struct kunit *test, const struct drm_mm_node *node)
|
|||
return false;
|
||||
}
|
||||
|
||||
static void igt_mm_color(struct kunit *test)
|
||||
static void drm_test_mm_color(struct kunit *test)
|
||||
{
|
||||
const unsigned int count = min(4096u, max_iterations);
|
||||
const struct insert_mode *mode;
|
||||
|
@ -2041,7 +2042,7 @@ static int evict_color(struct kunit *test, struct drm_mm *mm, u64 range_start,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void igt_mm_color_evict(struct kunit *test)
|
||||
static void drm_test_mm_color_evict(struct kunit *test)
|
||||
{
|
||||
DRM_RND_STATE(prng, random_seed);
|
||||
const unsigned int total_size = min(8192u, max_iterations);
|
||||
|
@ -2122,7 +2123,7 @@ err_nodes:
|
|||
vfree(nodes);
|
||||
}
|
||||
|
||||
static void igt_mm_color_evict_range(struct kunit *test)
|
||||
static void drm_test_mm_color_evict_range(struct kunit *test)
|
||||
{
|
||||
DRM_RND_STATE(prng, random_seed);
|
||||
const unsigned int total_size = 8192;
|
||||
|
@ -2136,7 +2137,7 @@ static void igt_mm_color_evict_range(struct kunit *test)
|
|||
struct drm_mm_node *node, *next;
|
||||
unsigned int *order, n;
|
||||
|
||||
/* Like igt_color_evict(), but limited to small portion of the full
|
||||
/* Like drm_test_mm_color_evict(), but limited to small portion of the full
|
||||
* drm_mm range.
|
||||
*/
|
||||
|
||||
|
@ -2221,25 +2222,25 @@ module_param(max_iterations, uint, 0400);
|
|||
module_param(max_prime, uint, 0400);
|
||||
|
||||
static struct kunit_case drm_mm_tests[] = {
|
||||
KUNIT_CASE(igt_mm_init),
|
||||
KUNIT_CASE(igt_mm_debug),
|
||||
KUNIT_CASE(igt_mm_reserve),
|
||||
KUNIT_CASE(igt_mm_insert),
|
||||
KUNIT_CASE(igt_mm_replace),
|
||||
KUNIT_CASE(igt_mm_insert_range),
|
||||
KUNIT_CASE(igt_mm_frag),
|
||||
KUNIT_CASE(igt_mm_align),
|
||||
KUNIT_CASE(igt_mm_align32),
|
||||
KUNIT_CASE(igt_mm_align64),
|
||||
KUNIT_CASE(igt_mm_evict),
|
||||
KUNIT_CASE(igt_mm_evict_range),
|
||||
KUNIT_CASE(igt_mm_topdown),
|
||||
KUNIT_CASE(igt_mm_bottomup),
|
||||
KUNIT_CASE(igt_mm_lowest),
|
||||
KUNIT_CASE(igt_mm_highest),
|
||||
KUNIT_CASE(igt_mm_color),
|
||||
KUNIT_CASE(igt_mm_color_evict),
|
||||
KUNIT_CASE(igt_mm_color_evict_range),
|
||||
KUNIT_CASE(drm_test_mm_init),
|
||||
KUNIT_CASE(drm_test_mm_debug),
|
||||
KUNIT_CASE(drm_test_mm_reserve),
|
||||
KUNIT_CASE(drm_test_mm_insert),
|
||||
KUNIT_CASE(drm_test_mm_replace),
|
||||
KUNIT_CASE(drm_test_mm_insert_range),
|
||||
KUNIT_CASE(drm_test_mm_frag),
|
||||
KUNIT_CASE(drm_test_mm_align),
|
||||
KUNIT_CASE(drm_test_mm_align32),
|
||||
KUNIT_CASE(drm_test_mm_align64),
|
||||
KUNIT_CASE(drm_test_mm_evict),
|
||||
KUNIT_CASE(drm_test_mm_evict_range),
|
||||
KUNIT_CASE(drm_test_mm_topdown),
|
||||
KUNIT_CASE(drm_test_mm_bottomup),
|
||||
KUNIT_CASE(drm_test_mm_lowest),
|
||||
KUNIT_CASE(drm_test_mm_highest),
|
||||
KUNIT_CASE(drm_test_mm_color),
|
||||
KUNIT_CASE(drm_test_mm_color_evict),
|
||||
KUNIT_CASE(drm_test_mm_color_evict_range),
|
||||
{}
|
||||
};
|
||||
|
||||
|
|
|
@ -73,7 +73,7 @@ static bool check_crtc_eq(struct drm_plane_state *plane_state,
|
|||
return true;
|
||||
}
|
||||
|
||||
static void igt_check_plane_state(struct kunit *test)
|
||||
static void drm_test_check_plane_state(struct kunit *test)
|
||||
{
|
||||
int ret;
|
||||
|
||||
|
@ -223,7 +223,7 @@ static void igt_check_plane_state(struct kunit *test)
|
|||
}
|
||||
|
||||
static struct kunit_case drm_plane_helper_test[] = {
|
||||
KUNIT_CASE(igt_check_plane_state),
|
||||
KUNIT_CASE(drm_test_check_plane_state),
|
||||
{}
|
||||
};
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
|
||||
#include <drm/drm_rect.h>
|
||||
|
||||
static void igt_drm_rect_clip_scaled_div_by_zero(struct kunit *test)
|
||||
static void drm_test_rect_clip_scaled_div_by_zero(struct kunit *test)
|
||||
{
|
||||
struct drm_rect src, dst, clip;
|
||||
bool visible;
|
||||
|
@ -35,7 +35,7 @@ static void igt_drm_rect_clip_scaled_div_by_zero(struct kunit *test)
|
|||
KUNIT_EXPECT_FALSE_MSG(test, drm_rect_visible(&src), "Source should not be visible\n");
|
||||
}
|
||||
|
||||
static void igt_drm_rect_clip_scaled_not_clipped(struct kunit *test)
|
||||
static void drm_test_rect_clip_scaled_not_clipped(struct kunit *test)
|
||||
{
|
||||
struct drm_rect src, dst, clip;
|
||||
bool visible;
|
||||
|
@ -83,7 +83,7 @@ static void igt_drm_rect_clip_scaled_not_clipped(struct kunit *test)
|
|||
KUNIT_EXPECT_TRUE_MSG(test, drm_rect_visible(&src), "Source should be visible\n");
|
||||
}
|
||||
|
||||
static void igt_drm_rect_clip_scaled_clipped(struct kunit *test)
|
||||
static void drm_test_rect_clip_scaled_clipped(struct kunit *test)
|
||||
{
|
||||
struct drm_rect src, dst, clip;
|
||||
bool visible;
|
||||
|
@ -173,7 +173,7 @@ static void igt_drm_rect_clip_scaled_clipped(struct kunit *test)
|
|||
KUNIT_EXPECT_TRUE_MSG(test, drm_rect_visible(&src), "Source should be visible\n");
|
||||
}
|
||||
|
||||
static void igt_drm_rect_clip_scaled_signed_vs_unsigned(struct kunit *test)
|
||||
static void drm_test_rect_clip_scaled_signed_vs_unsigned(struct kunit *test)
|
||||
{
|
||||
struct drm_rect src, dst, clip;
|
||||
bool visible;
|
||||
|
@ -197,10 +197,10 @@ static void igt_drm_rect_clip_scaled_signed_vs_unsigned(struct kunit *test)
|
|||
}
|
||||
|
||||
static struct kunit_case drm_rect_tests[] = {
|
||||
KUNIT_CASE(igt_drm_rect_clip_scaled_div_by_zero),
|
||||
KUNIT_CASE(igt_drm_rect_clip_scaled_not_clipped),
|
||||
KUNIT_CASE(igt_drm_rect_clip_scaled_clipped),
|
||||
KUNIT_CASE(igt_drm_rect_clip_scaled_signed_vs_unsigned),
|
||||
KUNIT_CASE(drm_test_rect_clip_scaled_div_by_zero),
|
||||
KUNIT_CASE(drm_test_rect_clip_scaled_not_clipped),
|
||||
KUNIT_CASE(drm_test_rect_clip_scaled_clipped),
|
||||
KUNIT_CASE(drm_test_rect_clip_scaled_signed_vs_unsigned),
|
||||
{ }
|
||||
};
|
||||
|
||||
|
|
|
@ -70,7 +70,7 @@ static int tidss_atomic_check(struct drm_device *ddev,
|
|||
* changes. This is needed for updating the plane positions in
|
||||
* tidss_crtc_position_planes() which is called from
|
||||
* crtc_atomic_enable() and crtc_atomic_flush(). We have an
|
||||
* extra flag to to mark x,y-position changes and together
|
||||
* extra flag to mark x,y-position changes and together
|
||||
* with zpos_changed the condition recognizes all the above
|
||||
* cases.
|
||||
*/
|
||||
|
|
|
@ -105,11 +105,10 @@ int tilcdc_plane_init(struct drm_device *dev,
|
|||
struct tilcdc_drm_private *priv = dev->dev_private;
|
||||
int ret;
|
||||
|
||||
ret = drm_plane_init(dev, plane, 1,
|
||||
&tilcdc_plane_funcs,
|
||||
priv->pixelformats,
|
||||
priv->num_pixelformats,
|
||||
true);
|
||||
ret = drm_universal_plane_init(dev, plane, 1, &tilcdc_plane_funcs,
|
||||
priv->pixelformats,
|
||||
priv->num_pixelformats,
|
||||
NULL, DRM_PLANE_TYPE_PRIMARY, NULL);
|
||||
if (ret) {
|
||||
dev_err(dev->dev, "Failed to initialize plane: %d\n", ret);
|
||||
return ret;
|
||||
|
|
|
@ -181,6 +181,7 @@ out_exit:
|
|||
}
|
||||
|
||||
static const struct drm_simple_display_pipe_funcs hx8357d_pipe_funcs = {
|
||||
.mode_valid = mipi_dbi_pipe_mode_valid,
|
||||
.enable = yx240qv29_enable,
|
||||
.disable = mipi_dbi_pipe_disable,
|
||||
.update = mipi_dbi_pipe_update,
|
||||
|
|
|
@ -100,6 +100,7 @@ out_exit:
|
|||
}
|
||||
|
||||
static const struct drm_simple_display_pipe_funcs ili9163_pipe_funcs = {
|
||||
.mode_valid = mipi_dbi_pipe_mode_valid,
|
||||
.enable = yx240qv29_enable,
|
||||
.disable = mipi_dbi_pipe_disable,
|
||||
.update = mipi_dbi_pipe_update,
|
||||
|
|
|
@ -137,6 +137,7 @@ out_exit:
|
|||
}
|
||||
|
||||
static const struct drm_simple_display_pipe_funcs ili9341_pipe_funcs = {
|
||||
.mode_valid = mipi_dbi_pipe_mode_valid,
|
||||
.enable = yx240qv29_enable,
|
||||
.disable = mipi_dbi_pipe_disable,
|
||||
.update = mipi_dbi_pipe_update,
|
||||
|
|
|
@ -150,6 +150,7 @@ static void waveshare_enable(struct drm_simple_display_pipe *pipe,
|
|||
}
|
||||
|
||||
static const struct drm_simple_display_pipe_funcs waveshare_pipe_funcs = {
|
||||
.mode_valid = mipi_dbi_pipe_mode_valid,
|
||||
.enable = waveshare_enable,
|
||||
.disable = mipi_dbi_pipe_disable,
|
||||
.update = mipi_dbi_pipe_update,
|
||||
|
|
|
@ -141,6 +141,7 @@ out_exit:
|
|||
}
|
||||
|
||||
static const struct drm_simple_display_pipe_funcs mi0283qt_pipe_funcs = {
|
||||
.mode_valid = mipi_dbi_pipe_mode_valid,
|
||||
.enable = mi0283qt_enable,
|
||||
.disable = mipi_dbi_pipe_disable,
|
||||
.update = mipi_dbi_pipe_update,
|
||||
|
|
|
@ -212,6 +212,7 @@ out_exit:
|
|||
}
|
||||
|
||||
static const struct drm_simple_display_pipe_funcs panel_mipi_dbi_pipe_funcs = {
|
||||
.mode_valid = mipi_dbi_pipe_mode_valid,
|
||||
.enable = panel_mipi_dbi_enable,
|
||||
.disable = mipi_dbi_pipe_disable,
|
||||
.update = mipi_dbi_pipe_update,
|
||||
|
|
|
@ -621,6 +621,15 @@ static void power_off(struct repaper_epd *epd)
|
|||
gpiod_set_value_cansleep(epd->discharge, 0);
|
||||
}
|
||||
|
||||
static enum drm_mode_status repaper_pipe_mode_valid(struct drm_simple_display_pipe *pipe,
|
||||
const struct drm_display_mode *mode)
|
||||
{
|
||||
struct drm_crtc *crtc = &pipe->crtc;
|
||||
struct repaper_epd *epd = drm_to_epd(crtc->dev);
|
||||
|
||||
return drm_crtc_helper_mode_valid_fixed(crtc, mode, epd->mode);
|
||||
}
|
||||
|
||||
static void repaper_pipe_enable(struct drm_simple_display_pipe *pipe,
|
||||
struct drm_crtc_state *crtc_state,
|
||||
struct drm_plane_state *plane_state)
|
||||
|
@ -831,6 +840,7 @@ static void repaper_pipe_update(struct drm_simple_display_pipe *pipe,
|
|||
}
|
||||
|
||||
static const struct drm_simple_display_pipe_funcs repaper_pipe_funcs = {
|
||||
.mode_valid = repaper_pipe_mode_valid,
|
||||
.enable = repaper_pipe_enable,
|
||||
.disable = repaper_pipe_disable,
|
||||
.update = repaper_pipe_update,
|
||||
|
@ -839,22 +849,8 @@ static const struct drm_simple_display_pipe_funcs repaper_pipe_funcs = {
|
|||
static int repaper_connector_get_modes(struct drm_connector *connector)
|
||||
{
|
||||
struct repaper_epd *epd = drm_to_epd(connector->dev);
|
||||
struct drm_display_mode *mode;
|
||||
|
||||
mode = drm_mode_duplicate(connector->dev, epd->mode);
|
||||
if (!mode) {
|
||||
DRM_ERROR("Failed to duplicate mode\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
drm_mode_set_name(mode);
|
||||
mode->type |= DRM_MODE_TYPE_PREFERRED;
|
||||
drm_mode_probed_add(connector, mode);
|
||||
|
||||
connector->display_info.width_mm = mode->width_mm;
|
||||
connector->display_info.height_mm = mode->height_mm;
|
||||
|
||||
return 1;
|
||||
return drm_connector_helper_get_modes_fixed(connector, epd->mode);
|
||||
}
|
||||
|
||||
static const struct drm_connector_helper_funcs repaper_connector_hfuncs = {
|
||||
|
|
|
@ -30,16 +30,6 @@
|
|||
#define DRIVER_MAJOR 1
|
||||
#define DRIVER_MINOR 0
|
||||
|
||||
/*
|
||||
* Assume a monitor resolution of 96 dpi to
|
||||
* get a somewhat reasonable screen size.
|
||||
*/
|
||||
#define RES_MM(d) \
|
||||
(((d) * 254ul) / (96ul * 10ul))
|
||||
|
||||
#define SIMPLEDRM_MODE(hd, vd) \
|
||||
DRM_SIMPLE_MODE(hd, vd, RES_MM(hd), RES_MM(vd))
|
||||
|
||||
/*
|
||||
* Helpers for simplefb
|
||||
*/
|
||||
|
@ -479,29 +469,6 @@ static const uint64_t simpledrm_primary_plane_format_modifiers[] = {
|
|||
DRM_FORMAT_MOD_INVALID
|
||||
};
|
||||
|
||||
static int simpledrm_primary_plane_helper_atomic_check(struct drm_plane *plane,
|
||||
struct drm_atomic_state *new_state)
|
||||
{
|
||||
struct drm_plane_state *new_plane_state = drm_atomic_get_new_plane_state(new_state, plane);
|
||||
struct drm_crtc *new_crtc = new_plane_state->crtc;
|
||||
struct drm_crtc_state *new_crtc_state = NULL;
|
||||
int ret;
|
||||
|
||||
if (new_crtc)
|
||||
new_crtc_state = drm_atomic_get_new_crtc_state(new_state, new_crtc);
|
||||
|
||||
ret = drm_atomic_helper_check_plane_state(new_plane_state, new_crtc_state,
|
||||
DRM_PLANE_NO_SCALING,
|
||||
DRM_PLANE_NO_SCALING,
|
||||
false, false);
|
||||
if (ret)
|
||||
return ret;
|
||||
else if (!new_plane_state->visible)
|
||||
return 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void simpledrm_primary_plane_helper_atomic_update(struct drm_plane *plane,
|
||||
struct drm_atomic_state *old_state)
|
||||
{
|
||||
|
@ -553,7 +520,7 @@ static void simpledrm_primary_plane_helper_atomic_disable(struct drm_plane *plan
|
|||
|
||||
static const struct drm_plane_helper_funcs simpledrm_primary_plane_helper_funcs = {
|
||||
DRM_GEM_SHADOW_PLANE_HELPER_FUNCS,
|
||||
.atomic_check = simpledrm_primary_plane_helper_atomic_check,
|
||||
.atomic_check = drm_plane_helper_atomic_check,
|
||||
.atomic_update = simpledrm_primary_plane_helper_atomic_update,
|
||||
.atomic_disable = simpledrm_primary_plane_helper_atomic_disable,
|
||||
};
|
||||
|
@ -570,15 +537,7 @@ static enum drm_mode_status simpledrm_crtc_helper_mode_valid(struct drm_crtc *cr
|
|||
{
|
||||
struct simpledrm_device *sdev = simpledrm_device_of_dev(crtc->dev);
|
||||
|
||||
if (mode->hdisplay != sdev->mode.hdisplay &&
|
||||
mode->vdisplay != sdev->mode.vdisplay)
|
||||
return MODE_ONE_SIZE;
|
||||
else if (mode->hdisplay != sdev->mode.hdisplay)
|
||||
return MODE_ONE_WIDTH;
|
||||
else if (mode->vdisplay != sdev->mode.vdisplay)
|
||||
return MODE_ONE_HEIGHT;
|
||||
|
||||
return MODE_OK;
|
||||
return drm_crtc_helper_mode_valid_fixed(crtc, mode, &sdev->mode);
|
||||
}
|
||||
|
||||
static int simpledrm_crtc_helper_atomic_check(struct drm_crtc *crtc,
|
||||
|
@ -620,24 +579,8 @@ static const struct drm_encoder_funcs simpledrm_encoder_funcs = {
|
|||
static int simpledrm_connector_helper_get_modes(struct drm_connector *connector)
|
||||
{
|
||||
struct simpledrm_device *sdev = simpledrm_device_of_dev(connector->dev);
|
||||
struct drm_display_mode *mode;
|
||||
|
||||
mode = drm_mode_duplicate(connector->dev, &sdev->mode);
|
||||
if (!mode)
|
||||
return 0;
|
||||
|
||||
if (mode->name[0] == '\0')
|
||||
drm_mode_set_name(mode);
|
||||
|
||||
mode->type |= DRM_MODE_TYPE_PREFERRED;
|
||||
drm_mode_probed_add(connector, mode);
|
||||
|
||||
if (mode->width_mm)
|
||||
connector->display_info.width_mm = mode->width_mm;
|
||||
if (mode->height_mm)
|
||||
connector->display_info.height_mm = mode->height_mm;
|
||||
|
||||
return 1;
|
||||
return drm_connector_helper_get_modes_fixed(connector, &sdev->mode);
|
||||
}
|
||||
|
||||
static const struct drm_connector_helper_funcs simpledrm_connector_helper_funcs = {
|
||||
|
@ -665,53 +608,19 @@ static const struct drm_mode_config_funcs simpledrm_mode_config_funcs = {
|
|||
static struct drm_display_mode simpledrm_mode(unsigned int width,
|
||||
unsigned int height)
|
||||
{
|
||||
struct drm_display_mode mode = { SIMPLEDRM_MODE(width, height) };
|
||||
|
||||
mode.clock = mode.hdisplay * mode.vdisplay * 60 / 1000 /* kHz */;
|
||||
drm_mode_set_name(&mode);
|
||||
/*
|
||||
* Assume a monitor resolution of 96 dpi to
|
||||
* get a somewhat reasonable screen size.
|
||||
*/
|
||||
const struct drm_display_mode mode = {
|
||||
DRM_MODE_INIT(60, width, height,
|
||||
DRM_MODE_RES_MM(width, 96ul),
|
||||
DRM_MODE_RES_MM(height, 96ul))
|
||||
};
|
||||
|
||||
return mode;
|
||||
}
|
||||
|
||||
static const uint32_t *simpledrm_device_formats(struct simpledrm_device *sdev,
|
||||
size_t *nformats_out)
|
||||
{
|
||||
struct drm_device *dev = &sdev->dev;
|
||||
size_t i;
|
||||
|
||||
if (sdev->nformats)
|
||||
goto out; /* don't rebuild list on recurring calls */
|
||||
|
||||
/* native format goes first */
|
||||
sdev->formats[0] = sdev->format->format;
|
||||
sdev->nformats = 1;
|
||||
|
||||
/* default formats go second */
|
||||
for (i = 0; i < ARRAY_SIZE(simpledrm_primary_plane_formats); ++i) {
|
||||
if (simpledrm_primary_plane_formats[i] == sdev->format->format)
|
||||
continue; /* native format already went first */
|
||||
sdev->formats[sdev->nformats] = simpledrm_primary_plane_formats[i];
|
||||
sdev->nformats++;
|
||||
}
|
||||
|
||||
/*
|
||||
* TODO: The simpledrm driver converts framebuffers to the native
|
||||
* format when copying them to device memory. If there are more
|
||||
* formats listed than supported by the driver, the native format
|
||||
* is not supported by the conversion helpers. Therefore *only*
|
||||
* support the native format and add a conversion helper ASAP.
|
||||
*/
|
||||
if (drm_WARN_ONCE(dev, i != sdev->nformats,
|
||||
"format conversion helpers required for %p4cc",
|
||||
&sdev->format->format)) {
|
||||
sdev->nformats = 1;
|
||||
}
|
||||
|
||||
out:
|
||||
*nformats_out = sdev->nformats;
|
||||
return sdev->formats;
|
||||
}
|
||||
|
||||
static struct simpledrm_device *simpledrm_device_create(struct drm_driver *drv,
|
||||
struct platform_device *pdev)
|
||||
{
|
||||
|
@ -728,7 +637,6 @@ static struct simpledrm_device *simpledrm_device_create(struct drm_driver *drv,
|
|||
struct drm_encoder *encoder;
|
||||
struct drm_connector *connector;
|
||||
unsigned long max_width, max_height;
|
||||
const uint32_t *formats;
|
||||
size_t nformats;
|
||||
int ret;
|
||||
|
||||
|
@ -840,11 +748,14 @@ static struct simpledrm_device *simpledrm_device_create(struct drm_driver *drv,
|
|||
|
||||
/* Primary plane */
|
||||
|
||||
formats = simpledrm_device_formats(sdev, &nformats);
|
||||
nformats = drm_fb_build_fourcc_list(dev, &format->format, 1,
|
||||
simpledrm_primary_plane_formats,
|
||||
ARRAY_SIZE(simpledrm_primary_plane_formats),
|
||||
sdev->formats, ARRAY_SIZE(sdev->formats));
|
||||
|
||||
primary_plane = &sdev->primary_plane;
|
||||
ret = drm_universal_plane_init(dev, primary_plane, 0, &simpledrm_primary_plane_funcs,
|
||||
formats, nformats,
|
||||
sdev->formats, nformats,
|
||||
simpledrm_primary_plane_format_modifiers,
|
||||
DRM_PLANE_TYPE_PRIMARY, NULL);
|
||||
if (ret)
|
||||
|
|
|
@ -133,6 +133,7 @@ out_exit:
|
|||
}
|
||||
|
||||
static const struct drm_simple_display_pipe_funcs st7735r_pipe_funcs = {
|
||||
.mode_valid = mipi_dbi_pipe_mode_valid,
|
||||
.enable = st7735r_pipe_enable,
|
||||
.disable = mipi_dbi_pipe_disable,
|
||||
.update = mipi_dbi_pipe_update,
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue