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:
Dave Airlie 2022-09-28 13:50:28 +10:00
commit 907cc346ff
129 changed files with 2313 additions and 2087 deletions

View File

@ -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

View File

@ -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

View File

@ -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
===========

View File

@ -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>

View File

@ -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

View File

@ -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(&register_count_mutex);
return ret;
@ -2245,6 +2276,7 @@ void acpi_video_unregister(void)
{
mutex_lock(&register_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(&register_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(&register_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();
}

View File

@ -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);

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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();

View File

@ -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) {

View File

@ -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.

View File

@ -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;
}

View File

@ -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

View File

@ -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;

View File

@ -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);

View File

@ -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;

View File

@ -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 */

View File

@ -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);

View File

@ -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);

View File

@ -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);
/*

View File

@ -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

View File

@ -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:

View File

@ -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
*

View File

@ -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;

View File

@ -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);

View File

@ -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 = {

View File

@ -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);

View File

@ -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"),

View File

@ -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

View File

@ -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);

View File

@ -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

View File

@ -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

View File

@ -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
}

View File

@ -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,

View File

@ -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,

View File

@ -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);

View File

@ -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,

View File

@ -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);
}

View File

@ -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;

View File

@ -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);
}

View File

@ -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_*/

View File

@ -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,

View File

@ -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,

View File

@ -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 */
};

View File

@ -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);

View File

@ -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)

View File

@ -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);

View File

@ -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

View 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);
}

View File

@ -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__ */

View File

@ -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;

View File

@ -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);

View File

@ -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 = {

View File

@ -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)

View File

@ -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);

View File

@ -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;

View File

@ -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();
}

View File

@ -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

View File

@ -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;
}

View File

@ -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;

View File

@ -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;
}

View File

@ -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;

View File

@ -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,

View File

@ -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");

View File

@ -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 */

View File

@ -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,

View File

@ -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

View File

@ -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");

View File

@ -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 *

View File

@ -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 */ }
};

View File

@ -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);

View File

@ -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;

View File

@ -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[] = {

View File

@ -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

View File

@ -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);
}

View File

@ -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;
}

View File

@ -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,
};

View File

@ -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),
{}
};

View File

@ -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),
{}
};

View File

@ -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),
{ }
};

View File

@ -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),
{ }
};

View File

@ -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 = &params->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 = &params->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),
{}
};

View File

@ -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 = {

View File

@ -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, &params->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,
};

View File

@ -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),
{}
};

View File

@ -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),
{}
};

View File

@ -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),
{ }
};

View File

@ -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.
*/

View File

@ -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;

View File

@ -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,

View File

@ -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,

View File

@ -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,

View File

@ -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,

View File

@ -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,

View File

@ -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,

View File

@ -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 = {

View File

@ -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)

View File

@ -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