Merge tag 'drm-misc-next-2017-03-31' of git://anongit.freedesktop.org/git/drm-misc into drm-next

drm-misc for 4.12:

Core:
- Removed some fb subsampling dimension checks from core (Ville)
- Some MST slot cleanup (Dhinakaran)
- Extracted drm_debugfs.h & drm_ioctl.h from drmP.h (Daniel)
- Added drm_atomic_helper_shutdown() to compliment suspend/resume counterparts
  (Daniel)
- Pipe context through legacy modeset to remove legacy_backoff nasties (Daniel)
- Cleanups around vblank as well as allowing lockless counter reads (Chris W.)
- VGA Switcheroo added to MAINTAINERS with Lukas Wunner as reviewer (Lukas)

Drivers:
- Enhancements to rockchip driver probe (Jeffy) and dsi (Chris Z.)
- Thunderbolt external GPU awareness added (Lukas)

* tag 'drm-misc-next-2017-03-31' of git://anongit.freedesktop.org/git/drm-misc: (63 commits)
  apple-gmux: Don't switch external DP port on 2011+ MacBook Pros
  drm/nouveau: Don't register Thunderbolt eGPU with vga_switcheroo
  drm/amdgpu: Don't register Thunderbolt eGPU with vga_switcheroo
  drm/radeon: Don't register Thunderbolt eGPU with vga_switcheroo
  PCI: Recognize Thunderbolt devices
  MAINTAINERS: Add Lukas Wunner as reviewer for vga_switcheroo
  drm: Fix locking gotcha in page_flip ioctl
  drm: Clarify the role of plane_state argument to drm_simple update().
  drm: Clear e after kfree in drm_mode_page_flip_ioctl
  drm: Convert cmpxchg(bool) back to a two step operation
  drm/bridge: ti-tfp410: support hpd via gpio
  drm: use .hword to represent 16-bit numbers
  Revert unrelated part of "drm: simplify the locking in the GETCRTC ioctl"
  drm: Fixup failure paths in drm_atomic_helper_set_config
  drm: Peek at the current counter/timestamp for vblank queries
  drm: Refactor vblank sequence number comparison
  drm: vblank cannot be enabled if dev->irq_enabled is false
  drm: Mark up accesses of vblank->enabled outside of its spinlock
  drm: Make the decision to keep vblank irq enabled earlier
  drm/atomic-helper: Remove the backoff hack from set_config
  ...
This commit is contained in:
Dave Airlie
2017-04-03 16:30:24 +10:00
101 changed files with 1596 additions and 769 deletions
+3 -3
View File
@@ -59,9 +59,9 @@
/* Fixed header pattern */
header: .byte 0x00,0xff,0xff,0xff,0xff,0xff,0xff,0x00
mfg_id: .word swap16(mfgname2id(MFG_LNX1, MFG_LNX2, MFG_LNX3))
mfg_id: .hword swap16(mfgname2id(MFG_LNX1, MFG_LNX2, MFG_LNX3))
prod_code: .word 0
prod_code: .hword 0
/* Serial number. 32 bits, little endian. */
serial_number: .long SERIAL
@@ -177,7 +177,7 @@ std_vres: .byte (XY_RATIO<<6)+VFREQ-60
descriptor1:
/* Pixel clock in 10 kHz units. (0.-655.35 MHz, little-endian) */
clock: .word CLOCK/10
clock: .hword CLOCK/10
/* Horizontal active pixels 8 lsbits (0-4095) */
x_act_lsb: .byte XPIX&0xff
@@ -10,7 +10,7 @@ Required properties:
- interrupts: Represent the controller's interrupt to the CPU(s).
- clocks, clock-names: Phandles to the controller's pll reference
clock(ref) and APB clock(pclk). For RK3399, a phy config clock
(phy_cfg) is additional required. As described in [1].
(phy_cfg) and a grf clock(grf) are required. As described in [1].
- rockchip,grf: this soc should set GRF regs to mux vopl/vopb.
- ports: contain a port node with endpoint definitions as defined in [2].
For vopb,set the reg = <0> and set the reg = <1> for vopl.
+12
View File
@@ -207,6 +207,18 @@ Display CRC Support
.. kernel-doc:: drivers/gpu/drm/drm_debugfs_crc.c
:doc: CRC ABI
.. kernel-doc:: drivers/gpu/drm/drm_debugfs_crc.c
:export:
Debugfs Support
---------------
.. kernel-doc:: include/drm/drm_debugfs.h
:internal:
.. kernel-doc:: drivers/gpu/drm/drm_debugfs.c
:export:
VBlank event handling
=====================
+25
View File
@@ -60,3 +60,28 @@ checkpatch or sparse. We welcome such contributions.
Anyone looking to kick it up a notch can find a list of janitorial tasks on
the :ref:`TODO list <todo>`.
Contribution Process
====================
Mostly the DRM subsystem works like any other kernel subsystem, see :ref:`the
main process guidelines and documentation <process_index>` for how things work.
Here we just document some of the specialities of the GPU subsystem.
Feature Merge Deadlines
-----------------------
All feature work must be in the linux-next tree by the -rc6 release of the
current release cycle, otherwise they must be postponed and can't reach the next
merge window. All patches must have landed in the drm-next tree by latest -rc7,
but if your branch is not in linux-next then this must have happened by -rc6
already.
After that point only bugfixes (like after the upstream merge window has closed
with the -rc1 release) are allowed. No new platform enabling or new drivers are
allowed.
This means that there's a blackout-period of about one month where feature work
can't be merged. The recommended way to deal with that is having a -next tree
that's always open, but making sure to not feed it into linux-next during the
blackout period. As an example, drm-misc works like that.
-5
View File
@@ -1,10 +1,5 @@
Owner Module/Drivers,Group,Property Name,Type,Property Values,Object attached,Description/Restrictions
,,“scaling mode”,ENUM,"{ ""None"", ""Full"", ""Center"", ""Full aspect"" }",Connector,"Supported by: amdgpu, gma500, i915, nouveau and radeon."
,Connector,“EDID”,BLOB | IMMUTABLE,0,Connector,Contains id of edid blob ptr object.
,,“DPMS”,ENUM,"{ “On”, “Standby”, “Suspend”, “Off” }",Connector,Contains DPMS operation mode value.
,,“PATH”,BLOB | IMMUTABLE,0,Connector,Contains topology path to a connector.
,,“TILE”,BLOB | IMMUTABLE,0,Connector,Contains tiling information for a connector.
,,“CRTC_ID”,OBJECT,DRM_MODE_OBJECT_CRTC,Connector,CRTC that connector is attached to (atomic)
,DVI-I,“subconnector”,ENUM,"{ “Unknown”, “DVI-D”, “DVI-A” }",Connector,TBD
,,“select subconnector”,ENUM,"{ “Automatic”, “DVI-D”, “DVI-A” }",Connector,TBD
,TV,“subconnector”,ENUM,"{ ""Unknown"", ""Composite"", ""SVIDEO"", ""Component"", ""SCART"" }",Connector,TBD
1 Owner Module/Drivers Group Property Name Type Property Values Object attached Description/Restrictions
2 “scaling mode” ENUM { "None", "Full", "Center", "Full aspect" } Connector Supported by: amdgpu, gma500, i915, nouveau and radeon.
Connector “EDID” BLOB | IMMUTABLE 0 Connector Contains id of edid blob ptr object.
“DPMS” ENUM { “On”, “Standby”, “Suspend”, “Off” } Connector Contains DPMS operation mode value.
“PATH” BLOB | IMMUTABLE 0 Connector Contains topology path to a connector.
“TILE” BLOB | IMMUTABLE 0 Connector Contains tiling information for a connector.
“CRTC_ID” OBJECT DRM_MODE_OBJECT_CRTC Connector CRTC that connector is attached to (atomic)
3 DVI-I “subconnector” ENUM { “Unknown”, “DVI-D”, “DVI-A” } Connector TBD
4 “select subconnector” ENUM { “Automatic”, “DVI-D”, “DVI-A” } Connector TBD
5 TV “subconnector” ENUM { "Unknown", "Composite", "SVIDEO", "Component", "SCART" } Connector TBD
+96
View File
@@ -99,6 +99,30 @@ events for atomic commits correctly. But fixing these bugs is good anyway.
Contact: Daniel Vetter, respective driver maintainers
Better manual-upload support for atomic
---------------------------------------
This would be especially useful for tinydrm:
- Add a struct drm_rect dirty_clip to drm_crtc_state. When duplicating the
crtc state, clear that to the max values, x/y = 0 and w/h = MAX_INT, in
__drm_atomic_helper_crtc_duplicate_state().
- Move tinydrm_merge_clips into drm_framebuffer.c, dropping the tinydrm_
prefix ofc and using drm_fb_. drm_framebuffer.c makes sense since this
is a function useful to implement the fb->dirty function.
- Create a new drm_fb_dirty function which does essentially what e.g.
mipi_dbi_fb_dirty does. You can use e.g. drm_atomic_helper_update_plane as the
template. But instead of doing a simple full-screen plane update, this new
helper also sets crtc_state->dirty_clip to the right coordinates. And of
course it needs to check whether the fb is actually active (and maybe where),
so there's some book-keeping involved. There's also some good fun involved in
scaling things appropriately. For that case we might simply give up and
declare the entire area covered by the plane as dirty.
Contact: Noralf Trønnes, Daniel Vetter
Fallout from atomic KMS
-----------------------
@@ -272,6 +296,32 @@ This is a really varied tasks with lots of little bits and pieces:
Contact: Daniel Vetter
Clean up the debugfs support
----------------------------
There's a bunch of issues with it:
- The drm_info_list ->show() function doesn't even bother to cast to the drm
structure for you. This is lazy.
- We probably want to have some support for debugfs files on crtc/connectors and
maybe other kms objects directly in core. There's even drm_print support in
the funcs for these objects to dump kms state, so it's all there. And then the
->show() functions should obviously give you a pointer to the right object.
- The drm_info_list stuff is centered on drm_minor instead of drm_device. For
anything we want to print drm_device (or maybe drm_file) is the right thing.
- The drm_driver->debugfs_init hooks we have is just an artifact of the old
midlayered load sequence. DRM debugfs should work more like sysfs, where you
can create properties/files for an object anytime you want, and the core
takes care of publishing/unpuplishing all the files at register/unregister
time. Drivers shouldn't need to worry about these technicalities, and fixing
this (together with the drm_minor->drm_device move) would allow us to remove
debugfs_init.
Contact: Daniel Vetter
Better Testing
==============
@@ -310,6 +360,52 @@ Contact: Daniel Vetter
Driver Specific
===============
tinydrm
-------
Tinydrm is the helper driver for really simple fb drivers. The goal is to make
those drivers as simple as possible, so lots of room for refactoring:
- backlight helpers, probably best to put them into a new drm_backlight.c.
This is because drivers/video is de-facto unmaintained. We could also
move drivers/video/backlight to drivers/gpu/backlight and take it all
over within drm-misc, but that's more work.
- spi helpers, probably best put into spi core/helper code. Thierry said
the spi maintainer is fast&reactive, so shouldn't be a big issue.
- extract the mipi-dbi helper (well, the non-tinydrm specific parts at
least) into a separate helper, like we have for mipi-dsi already. Or follow
one of the ideas for having a shared dsi/dbi helper, abstracting away the
transport details more.
- tinydrm_lastclose could be drm_fb_helper_lastclose. Only thing we need
for that is to store the drm_fb_helper pointer somewhere in
drm_device->mode_config. And then we could roll that out to all the
drivers.
- tinydrm_gem_cma_prime_import_sg_table should probably go into the cma
helpers, as a _vmapped variant (since not every driver needs the vmap).
And tinydrm_gem_cma_free_object could the be merged into
drm_gem_cma_free_object().
- tinydrm_fb_create we could move into drm_simple_pipe, only need to add
the fb_create hook to drm_simple_pipe_funcs, which would again simplify a
bunch of things (since it gives you a one-stop vfunc for simple drivers).
- Quick aside: The unregister devm stuff is kinda getting the lifetimes of
a drm_device wrong. Doesn't matter, since everyone else gets it wrong
too :-)
- With the fbdev pointer in dev->mode_config we could also make
suspend/resume helpers entirely generic, at least if we add a
dev->mode_config.suspend_state. We could even provide a generic pm_ops
structure with those.
- also rework the drm_framebuffer_funcs->dirty hook wire-up, see above.
Contact: Noralf Trønnes, Daniel Vetter
Outside DRM
===========
+1
View File
@@ -3,6 +3,7 @@
\renewcommand\thesection*
\renewcommand\thesubsection*
.. _process_index:
Working with the kernel development community
=============================================
+10
View File
@@ -4145,6 +4145,7 @@ F: Documentation/devicetree/bindings/video/
F: Documentation/gpu/
F: include/drm/
F: include/uapi/drm/
F: include/linux/vga*
DRM DRIVERS AND MISC GPU PATCHES
M: Daniel Vetter <daniel.vetter@intel.com>
@@ -4158,6 +4159,7 @@ F: drivers/gpu/vga/
F: drivers/gpu/drm/*
F: include/drm/drm*
F: include/uapi/drm/drm*
F: include/linux/vga*
DRM DRIVER FOR AST SERVER GRAPHICS CHIPS
M: Dave Airlie <airlied@redhat.com>
@@ -13257,6 +13259,14 @@ L: kvm@vger.kernel.org
S: Maintained
F: drivers/vfio/platform/
VGA_SWITCHEROO
R: Lukas Wunner <lukas@wunner.de>
S: Maintained
F: Documentation/gpu/vga-switcheroo.rst
F: drivers/gpu/vga/vga_switcheroo.c
F: include/linux/vga_switcheroo.h
T: git git://anongit.freedesktop.org/drm/drm-misc
VIDEOBUF2 FRAMEWORK
M: Pawel Osciak <pawel@osciak.com>
M: Marek Szyprowski <m.szyprowski@samsung.com>
+5 -2
View File
@@ -1929,7 +1929,9 @@ int amdgpu_device_init(struct amdgpu_device *adev,
runtime = true;
if (amdgpu_device_is_px(ddev))
runtime = true;
vga_switcheroo_register_client(adev->pdev, &amdgpu_switcheroo_ops, runtime);
if (!pci_is_thunderbolt_attached(adev->pdev))
vga_switcheroo_register_client(adev->pdev,
&amdgpu_switcheroo_ops, runtime);
if (runtime)
vga_switcheroo_init_domain_pm_ops(adev->dev, &adev->vga_pm_domain);
@@ -2084,7 +2086,8 @@ void amdgpu_device_fini(struct amdgpu_device *adev)
amdgpu_atombios_fini(adev);
kfree(adev->bios);
adev->bios = NULL;
vga_switcheroo_unregister_client(adev->pdev);
if (!pci_is_thunderbolt_attached(adev->pdev))
vga_switcheroo_unregister_client(adev->pdev);
if (adev->flags & AMD_IS_PX)
vga_switcheroo_fini_domain_pm_ops(adev->dev);
vga_client_register(adev->pdev, NULL, NULL, NULL);
+5 -3
View File
@@ -311,7 +311,8 @@ int amdgpu_crtc_page_flip_target(struct drm_crtc *crtc,
struct drm_framebuffer *fb,
struct drm_pending_vblank_event *event,
uint32_t page_flip_flags,
uint32_t target)
uint32_t target,
struct drm_modeset_acquire_ctx *ctx)
{
struct amdgpu_bo *new_abo;
struct amdgpu_flip_work *work;
@@ -332,7 +333,8 @@ int amdgpu_crtc_page_flip_target(struct drm_crtc *crtc,
return 0;
}
int amdgpu_crtc_set_config(struct drm_mode_set *set)
int amdgpu_crtc_set_config(struct drm_mode_set *set,
struct drm_modeset_acquire_ctx *ctx)
{
struct drm_device *dev;
struct amdgpu_device *adev;
@@ -349,7 +351,7 @@ int amdgpu_crtc_set_config(struct drm_mode_set *set)
if (ret < 0)
return ret;
ret = drm_crtc_helper_set_config(set);
ret = drm_crtc_helper_set_config(set, ctx);
list_for_each_entry(crtc, &dev->mode_config.crtc_list, head)
if (crtc->enabled)
+2 -1
View File
@@ -103,7 +103,8 @@ int amdgpu_driver_load_kms(struct drm_device *dev, unsigned long flags)
amdgpu_has_atpx() &&
(amdgpu_is_atpx_hybrid() ||
amdgpu_has_atpx_dgpu_power_cntl()) &&
((flags & AMD_IS_APU) == 0))
((flags & AMD_IS_APU) == 0) &&
!pci_is_thunderbolt_attached(dev->pdev))
flags |= AMD_IS_PX;
/* amdgpu_device_init should report only fatal error
+4 -2
View File
@@ -590,11 +590,13 @@ int amdgpu_align_pitch(struct amdgpu_device *adev, int width, int bpp, bool tile
/* amdgpu_display.c */
void amdgpu_print_display_setup(struct drm_device *dev);
int amdgpu_modeset_create_props(struct amdgpu_device *adev);
int amdgpu_crtc_set_config(struct drm_mode_set *set);
int amdgpu_crtc_set_config(struct drm_mode_set *set,
struct drm_modeset_acquire_ctx *ctx);
int amdgpu_crtc_page_flip_target(struct drm_crtc *crtc,
struct drm_framebuffer *fb,
struct drm_pending_vblank_event *event,
uint32_t page_flip_flags, uint32_t target);
uint32_t page_flip_flags, uint32_t target,
struct drm_modeset_acquire_ctx *ctx);
void amdgpu_crtc_cleanup_flip_ctx(struct amdgpu_flip_work *work,
struct amdgpu_bo *new_abo);
int amdgpu_crtc_prepare_flip(struct drm_crtc *crtc,
+2 -1
View File
@@ -1027,7 +1027,8 @@ static void armada_drm_crtc_destroy(struct drm_crtc *crtc)
* and a mode_set.
*/
static int armada_drm_crtc_page_flip(struct drm_crtc *crtc,
struct drm_framebuffer *fb, struct drm_pending_vblank_event *event, uint32_t page_flip_flags)
struct drm_framebuffer *fb, struct drm_pending_vblank_event *event, uint32_t page_flip_flags,
struct drm_modeset_acquire_ctx *ctx)
{
struct armada_crtc *dcrtc = drm_to_armada_crtc(crtc);
struct armada_frame_work *work;
+4 -2
View File
@@ -94,7 +94,8 @@ static int
armada_ovl_plane_update(struct drm_plane *plane, struct drm_crtc *crtc,
struct drm_framebuffer *fb,
int crtc_x, int crtc_y, unsigned crtc_w, unsigned crtc_h,
uint32_t src_x, uint32_t src_y, uint32_t src_w, uint32_t src_h)
uint32_t src_x, uint32_t src_y, uint32_t src_w, uint32_t src_h,
struct drm_modeset_acquire_ctx *ctx)
{
struct armada_ovl_plane *dplane = drm_to_armada_ovl_plane(plane);
struct armada_crtc *dcrtc = drm_to_armada_crtc(crtc);
@@ -257,7 +258,8 @@ armada_ovl_plane_update(struct drm_plane *plane, struct drm_crtc *crtc,
return 0;
}
static int armada_ovl_plane_disable(struct drm_plane *plane)
static int armada_ovl_plane_disable(struct drm_plane *plane,
struct drm_modeset_acquire_ctx *ctx)
{
struct armada_ovl_plane *dplane = drm_to_armada_ovl_plane(plane);
struct drm_framebuffer *fb;
+3 -1
View File
@@ -192,6 +192,8 @@ void bochs_fbdev_fini(struct bochs_device *bochs)
if (bochs->fb.initialized)
bochs_fbdev_destroy(bochs);
drm_fb_helper_fini(&bochs->fb.helper);
if (bochs->fb.helper.fbdev)
drm_fb_helper_fini(&bochs->fb.helper);
bochs->fb.initialized = false;
}
+2 -1
View File
@@ -96,7 +96,8 @@ static void bochs_crtc_commit(struct drm_crtc *crtc)
static int bochs_crtc_page_flip(struct drm_crtc *crtc,
struct drm_framebuffer *fb,
struct drm_pending_vblank_event *event,
uint32_t page_flip_flags)
uint32_t page_flip_flags,
struct drm_modeset_acquire_ctx *ctx)
{
struct bochs_device *bochs =
container_of(crtc, struct bochs_device, crtc);
+1 -1
View File
@@ -1916,7 +1916,7 @@ static irqreturn_t dw_hdmi_irq(int irq, void *dev_id)
if (intr_stat &
(HDMI_IH_PHY_STAT0_RX_SENSE | HDMI_IH_PHY_STAT0_HPD)) {
mutex_lock(&hdmi->mutex);
if (!hdmi->disabled && !hdmi->force) {
if (!hdmi->force) {
/*
* If the RX sense status indicates we're disconnected,
* clear the software rxsense status.
+70 -2
View File
@@ -8,6 +8,10 @@
*
*/
#include <linux/delay.h>
#include <linux/fwnode.h>
#include <linux/gpio/consumer.h>
#include <linux/irq.h>
#include <linux/module.h>
#include <linux/of_graph.h>
#include <linux/platform_device.h>
@@ -18,11 +22,15 @@
#include <drm/drm_crtc.h>
#include <drm/drm_crtc_helper.h>
#define HOTPLUG_DEBOUNCE_MS 1100
struct tfp410 {
struct drm_bridge bridge;
struct drm_connector connector;
struct i2c_adapter *ddc;
struct gpio_desc *hpd;
struct delayed_work hpd_work;
struct device *dev;
};
@@ -76,6 +84,13 @@ tfp410_connector_detect(struct drm_connector *connector, bool force)
{
struct tfp410 *dvi = drm_connector_to_tfp410(connector);
if (dvi->hpd) {
if (gpiod_get_value_cansleep(dvi->hpd))
return connector_status_connected;
else
return connector_status_disconnected;
}
if (dvi->ddc) {
if (drm_probe_ddc(dvi->ddc))
return connector_status_connected;
@@ -106,6 +121,9 @@ static int tfp410_attach(struct drm_bridge *bridge)
return -ENODEV;
}
if (dvi->hpd)
dvi->connector.polled = DRM_CONNECTOR_POLL_HPD;
drm_connector_helper_add(&dvi->connector,
&tfp410_con_helper_funcs);
ret = drm_connector_init(bridge->dev, &dvi->connector,
@@ -125,7 +143,27 @@ static const struct drm_bridge_funcs tfp410_bridge_funcs = {
.attach = tfp410_attach,
};
static int tfp410_get_connector_ddc(struct tfp410 *dvi)
static void tfp410_hpd_work_func(struct work_struct *work)
{
struct tfp410 *dvi;
dvi = container_of(work, struct tfp410, hpd_work.work);
if (dvi->bridge.dev)
drm_helper_hpd_irq_event(dvi->bridge.dev);
}
static irqreturn_t tfp410_hpd_irq_thread(int irq, void *arg)
{
struct tfp410 *dvi = arg;
mod_delayed_work(system_wq, &dvi->hpd_work,
msecs_to_jiffies(HOTPLUG_DEBOUNCE_MS));
return IRQ_HANDLED;
}
static int tfp410_get_connector_properties(struct tfp410 *dvi)
{
struct device_node *ep = NULL, *connector_node = NULL;
struct device_node *ddc_phandle = NULL;
@@ -140,6 +178,17 @@ static int tfp410_get_connector_ddc(struct tfp410 *dvi)
if (!connector_node)
goto fail;
dvi->hpd = fwnode_get_named_gpiod(&connector_node->fwnode,
"hpd-gpios", 0, GPIOD_IN, "hpd");
if (IS_ERR(dvi->hpd)) {
ret = PTR_ERR(dvi->hpd);
dvi->hpd = NULL;
if (ret == -ENOENT)
ret = 0;
else
goto fail;
}
ddc_phandle = of_parse_phandle(connector_node, "ddc-i2c-bus", 0);
if (!ddc_phandle)
goto fail;
@@ -176,10 +225,23 @@ static int tfp410_init(struct device *dev)
dvi->bridge.of_node = dev->of_node;
dvi->dev = dev;
ret = tfp410_get_connector_ddc(dvi);
ret = tfp410_get_connector_properties(dvi);
if (ret)
goto fail;
if (dvi->hpd) {
INIT_DELAYED_WORK(&dvi->hpd_work, tfp410_hpd_work_func);
ret = devm_request_threaded_irq(dev, gpiod_to_irq(dvi->hpd),
NULL, tfp410_hpd_irq_thread, IRQF_TRIGGER_RISING |
IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
"hdmi-hpd", dvi);
if (ret) {
DRM_ERROR("failed to register hpd interrupt\n");
goto fail;
}
}
ret = drm_bridge_add(&dvi->bridge);
if (ret) {
dev_err(dev, "drm_bridge_add() failed: %d\n", ret);
@@ -189,6 +251,8 @@ static int tfp410_init(struct device *dev)
return 0;
fail:
i2c_put_adapter(dvi->ddc);
if (dvi->hpd)
gpiod_put(dvi->hpd);
return ret;
}
@@ -196,10 +260,14 @@ static int tfp410_fini(struct device *dev)
{
struct tfp410 *dvi = dev_get_drvdata(dev);
cancel_delayed_work_sync(&dvi->hpd_work);
drm_bridge_remove(&dvi->bridge);
if (dvi->ddc)
i2c_put_adapter(dvi->ddc);
if (dvi->hpd)
gpiod_put(dvi->hpd);
return 0;
}
+61 -110
View File
@@ -2077,6 +2077,7 @@ EXPORT_SYMBOL(drm_atomic_helper_swap_state);
* @src_y: y offset of @fb for panning
* @src_w: width of source rectangle in @fb
* @src_h: height of source rectangle in @fb
* @ctx: lock acquire context
*
* Provides a default plane update handler using the atomic driver interface.
*
@@ -2089,7 +2090,8 @@ int drm_atomic_helper_update_plane(struct drm_plane *plane,
int crtc_x, int crtc_y,
unsigned int crtc_w, unsigned int crtc_h,
uint32_t src_x, uint32_t src_y,
uint32_t src_w, uint32_t src_h)
uint32_t src_w, uint32_t src_h,
struct drm_modeset_acquire_ctx *ctx)
{
struct drm_atomic_state *state;
struct drm_plane_state *plane_state;
@@ -2099,8 +2101,7 @@ int drm_atomic_helper_update_plane(struct drm_plane *plane,
if (!state)
return -ENOMEM;
state->acquire_ctx = drm_modeset_legacy_acquire_ctx(crtc);
retry:
state->acquire_ctx = ctx;
plane_state = drm_atomic_get_plane_state(state, plane);
if (IS_ERR(plane_state)) {
ret = PTR_ERR(plane_state);
@@ -2125,59 +2126,33 @@ retry:
ret = drm_atomic_commit(state);
fail:
if (ret == -EDEADLK)
goto backoff;
drm_atomic_state_put(state);
return ret;
backoff:
drm_atomic_state_clear(state);
drm_atomic_legacy_backoff(state);
/*
* Someone might have exchanged the framebuffer while we dropped locks
* in the backoff code. We need to fix up the fb refcount tracking the
* core does for us.
*/
plane->old_fb = plane->fb;
goto retry;
}
EXPORT_SYMBOL(drm_atomic_helper_update_plane);
/**
* drm_atomic_helper_disable_plane - Helper for primary plane disable using * atomic
* @plane: plane to disable
* @ctx: lock acquire context
*
* Provides a default plane disable handler using the atomic driver interface.
*
* RETURNS:
* Zero on success, error code on failure
*/
int drm_atomic_helper_disable_plane(struct drm_plane *plane)
int drm_atomic_helper_disable_plane(struct drm_plane *plane,
struct drm_modeset_acquire_ctx *ctx)
{
struct drm_atomic_state *state;
struct drm_plane_state *plane_state;
int ret = 0;
/*
* FIXME: Without plane->crtc set we can't get at the implicit legacy
* acquire context. The real fix will be to wire the acquire ctx through
* everywhere we need it, but meanwhile prevent chaos by just skipping
* this noop. The critical case is the cursor ioctls which a) only grab
* crtc/cursor-plane locks (so we need the crtc to get at the right
* acquire context) and b) can try to disable the plane multiple times.
*/
if (!plane->crtc)
return 0;
state = drm_atomic_state_alloc(plane->dev);
if (!state)
return -ENOMEM;
state->acquire_ctx = drm_modeset_legacy_acquire_ctx(plane->crtc);
retry:
state->acquire_ctx = ctx;
plane_state = drm_atomic_get_plane_state(state, plane);
if (IS_ERR(plane_state)) {
ret = PTR_ERR(plane_state);
@@ -2193,24 +2168,8 @@ retry:
ret = drm_atomic_commit(state);
fail:
if (ret == -EDEADLK)
goto backoff;
drm_atomic_state_put(state);
return ret;
backoff:
drm_atomic_state_clear(state);
drm_atomic_legacy_backoff(state);
/*
* Someone might have exchanged the framebuffer while we dropped locks
* in the backoff code. We need to fix up the fb refcount tracking the
* core does for us.
*/
plane->old_fb = plane->fb;
goto retry;
}
EXPORT_SYMBOL(drm_atomic_helper_disable_plane);
@@ -2306,6 +2265,7 @@ static int update_output_state(struct drm_atomic_state *state,
/**
* drm_atomic_helper_set_config - set a new config from userspace
* @set: mode set configuration
* @ctx: lock acquisition context
*
* Provides a default crtc set_config handler using the atomic driver interface.
*
@@ -2318,7 +2278,8 @@ static int update_output_state(struct drm_atomic_state *state,
* Returns:
* Returns 0 on success, negative errno numbers on failure.
*/
int drm_atomic_helper_set_config(struct drm_mode_set *set)
int drm_atomic_helper_set_config(struct drm_mode_set *set,
struct drm_modeset_acquire_ctx *ctx)
{
struct drm_atomic_state *state;
struct drm_crtc *crtc = set->crtc;
@@ -2329,32 +2290,16 @@ int drm_atomic_helper_set_config(struct drm_mode_set *set)
return -ENOMEM;
state->legacy_set_config = true;
state->acquire_ctx = drm_modeset_legacy_acquire_ctx(crtc);
retry:
state->acquire_ctx = ctx;
ret = __drm_atomic_helper_set_config(set, state);
if (ret != 0)
goto fail;
ret = drm_atomic_commit(state);
fail:
if (ret == -EDEADLK)
goto backoff;
fail:
drm_atomic_state_put(state);
return ret;
backoff:
drm_atomic_state_clear(state);
drm_atomic_legacy_backoff(state);
/*
* Someone might have exchanged the framebuffer while we dropped locks
* in the backoff code. We need to fix up the fb refcount tracking the
* core does for us.
*/
crtc->primary->old_fb = crtc->primary->fb;
goto retry;
}
EXPORT_SYMBOL(drm_atomic_helper_set_config);
@@ -2443,7 +2388,8 @@ commit:
* that they are connected to.
*
* This is used for example in suspend/resume to disable all currently active
* functions when suspending.
* functions when suspending. If you just want to shut down everything at e.g.
* driver unload, look at drm_atomic_helper_shutdown().
*
* Note that if callers haven't already acquired all modeset locks this might
* return -EDEADLK, which must be handled by calling drm_modeset_backoff().
@@ -2452,7 +2398,8 @@ commit:
* 0 on success or a negative error code on failure.
*
* See also:
* drm_atomic_helper_suspend(), drm_atomic_helper_resume()
* drm_atomic_helper_suspend(), drm_atomic_helper_resume() and
* drm_atomic_helper_shutdown().
*/
int drm_atomic_helper_disable_all(struct drm_device *dev,
struct drm_modeset_acquire_ctx *ctx)
@@ -2516,6 +2463,42 @@ free:
EXPORT_SYMBOL(drm_atomic_helper_disable_all);
/**
* drm_atomic_helper_shutdown - shutdown all CRTC
* @dev: DRM device
*
* This shuts down all CRTC, which is useful for driver unloading. Shutdown on
* suspend should instead be handled with drm_atomic_helper_suspend(), since
* that also takes a snapshot of the modeset state to be restored on resume.
*
* This is just a convenience wrapper around drm_atomic_helper_disable_all(),
* and it is the atomic version of drm_crtc_force_disable_all().
*/
void drm_atomic_helper_shutdown(struct drm_device *dev)
{
struct drm_modeset_acquire_ctx ctx;
int ret;
drm_modeset_acquire_init(&ctx, 0);
while (1) {
ret = drm_modeset_lock_all_ctx(dev, &ctx);
if (!ret)
ret = drm_atomic_helper_disable_all(dev, &ctx);
if (ret != -EDEADLK)
break;
drm_modeset_backoff(&ctx);
}
if (ret)
DRM_ERROR("Disabling all crtc's during unload failed with %i\n", ret);
drm_modeset_drop_locks(&ctx);
drm_modeset_acquire_fini(&ctx);
}
EXPORT_SYMBOL(drm_atomic_helper_shutdown);
/**
* drm_atomic_helper_suspend - subsystem-level suspend helper
* @dev: DRM device
@@ -2862,6 +2845,7 @@ static int page_flip_common(
* @fb: DRM framebuffer
* @event: optional DRM event to signal upon completion
* @flags: flip flags for non-vblank sync'ed updates
* @ctx: lock acquisition context
*
* Provides a default &drm_crtc_funcs.page_flip implementation
* using the atomic driver interface.
@@ -2875,7 +2859,8 @@ static int page_flip_common(
int drm_atomic_helper_page_flip(struct drm_crtc *crtc,
struct drm_framebuffer *fb,
struct drm_pending_vblank_event *event,
uint32_t flags)
uint32_t flags,
struct drm_modeset_acquire_ctx *ctx)
{
struct drm_plane *plane = crtc->primary;
struct drm_atomic_state *state;
@@ -2885,34 +2870,16 @@ int drm_atomic_helper_page_flip(struct drm_crtc *crtc,
if (!state)
return -ENOMEM;
state->acquire_ctx = drm_modeset_legacy_acquire_ctx(crtc);
state->acquire_ctx = ctx;
retry:
ret = page_flip_common(state, crtc, fb, event, flags);
if (ret != 0)
goto fail;
ret = drm_atomic_nonblocking_commit(state);
fail:
if (ret == -EDEADLK)
goto backoff;
drm_atomic_state_put(state);
return ret;
backoff:
drm_atomic_state_clear(state);
drm_atomic_legacy_backoff(state);
/*
* Someone might have exchanged the framebuffer while we dropped locks
* in the backoff code. We need to fix up the fb refcount tracking the
* core does for us.
*/
plane->old_fb = plane->fb;
goto retry;
}
EXPORT_SYMBOL(drm_atomic_helper_page_flip);
@@ -2923,6 +2890,7 @@ EXPORT_SYMBOL(drm_atomic_helper_page_flip);
* @event: optional DRM event to signal upon completion
* @flags: flip flags for non-vblank sync'ed updates
* @target: specifying the target vblank period when the flip to take effect
* @ctx: lock acquisition context
*
* Provides a default &drm_crtc_funcs.page_flip_target implementation.
* Similar to drm_atomic_helper_page_flip() with extra parameter to specify
@@ -2936,7 +2904,8 @@ int drm_atomic_helper_page_flip_target(
struct drm_framebuffer *fb,
struct drm_pending_vblank_event *event,
uint32_t flags,
uint32_t target)
uint32_t target,
struct drm_modeset_acquire_ctx *ctx)
{
struct drm_plane *plane = crtc->primary;
struct drm_atomic_state *state;
@@ -2947,9 +2916,8 @@ int drm_atomic_helper_page_flip_target(
if (!state)
return -ENOMEM;
state->acquire_ctx = drm_modeset_legacy_acquire_ctx(crtc);
state->acquire_ctx = ctx;
retry:
ret = page_flip_common(state, crtc, fb, event, flags);
if (ret != 0)
goto fail;
@@ -2962,26 +2930,9 @@ retry:
crtc_state->target_vblank = target;
ret = drm_atomic_nonblocking_commit(state);
fail:
if (ret == -EDEADLK)
goto backoff;
drm_atomic_state_put(state);
return ret;
backoff:
drm_atomic_state_clear(state);
drm_atomic_legacy_backoff(state);
/*
* Someone might have exchanged the framebuffer while we dropped locks
* in the backoff code. We need to fix up the fb refcount tracking the
* core does for us.
*/
plane->old_fb = plane->fb;
goto retry;
}
EXPORT_SYMBOL(drm_atomic_helper_page_flip_target);
+52 -21
View File
@@ -94,6 +94,8 @@ EXPORT_SYMBOL(drm_crtc_from_index);
* drm_crtc_force_disable - Forcibly turn off a CRTC
* @crtc: CRTC to turn off
*
* Note: This should only be used by non-atomic legacy drivers.
*
* Returns:
* Zero on success, error code on failure.
*/
@@ -103,6 +105,8 @@ int drm_crtc_force_disable(struct drm_crtc *crtc)
.crtc = crtc,
};
WARN_ON(drm_drv_uses_atomic_modeset(crtc->dev));
return drm_mode_set_config_internal(&set);
}
EXPORT_SYMBOL(drm_crtc_force_disable);
@@ -114,6 +118,9 @@ EXPORT_SYMBOL(drm_crtc_force_disable);
* Drivers may want to call this on unload to ensure that all displays are
* unlit and the GPU is in a consistent, low power state. Takes modeset locks.
*
* Note: This should only be used by non-atomic legacy drivers. For an atomic
* version look at drm_atomic_helper_shutdown().
*
* Returns:
* Zero on success, error code on failure.
*/
@@ -399,9 +406,9 @@ int drm_mode_getcrtc(struct drm_device *dev,
if (!crtc)
return -ENOENT;
drm_modeset_lock_crtc(crtc, crtc->primary);
crtc_resp->gamma_size = crtc->gamma_size;
drm_modeset_lock(&crtc->primary->mutex, NULL);
if (crtc->primary->state && crtc->primary->state->fb)
crtc_resp->fb_id = crtc->primary->state->fb->base.id;
else if (!crtc->primary->state && crtc->primary->fb)
@@ -409,9 +416,14 @@ int drm_mode_getcrtc(struct drm_device *dev,
else
crtc_resp->fb_id = 0;
if (crtc->state) {
if (crtc->primary->state) {
crtc_resp->x = crtc->primary->state->src_x >> 16;
crtc_resp->y = crtc->primary->state->src_y >> 16;
}
drm_modeset_unlock(&crtc->primary->mutex);
drm_modeset_lock(&crtc->mutex, NULL);
if (crtc->state) {
if (crtc->state->enable) {
drm_mode_convert_to_umode(&crtc_resp->mode, &crtc->state->mode);
crtc_resp->mode_valid = 1;
@@ -430,23 +442,13 @@ int drm_mode_getcrtc(struct drm_device *dev,
crtc_resp->mode_valid = 0;
}
}
drm_modeset_unlock_crtc(crtc);
drm_modeset_unlock(&crtc->mutex);
return 0;
}
/**
* drm_mode_set_config_internal - helper to call &drm_mode_config_funcs.set_config
* @set: modeset config to set
*
* This is a little helper to wrap internal calls to the
* &drm_mode_config_funcs.set_config driver interface. The only thing it adds is
* correct refcounting dance.
*
* Returns:
* Zero on success, negative errno on failure.
*/
int drm_mode_set_config_internal(struct drm_mode_set *set)
static int __drm_mode_set_config_internal(struct drm_mode_set *set,
struct drm_modeset_acquire_ctx *ctx)
{
struct drm_crtc *crtc = set->crtc;
struct drm_framebuffer *fb;
@@ -463,7 +465,7 @@ int drm_mode_set_config_internal(struct drm_mode_set *set)
fb = set->fb;
ret = crtc->funcs->set_config(set);
ret = crtc->funcs->set_config(set, ctx);
if (ret == 0) {
crtc->primary->crtc = crtc;
crtc->primary->fb = fb;
@@ -479,6 +481,25 @@ int drm_mode_set_config_internal(struct drm_mode_set *set)
return ret;
}
/**
* drm_mode_set_config_internal - helper to call &drm_mode_config_funcs.set_config
* @set: modeset config to set
*
* This is a little helper to wrap internal calls to the
* &drm_mode_config_funcs.set_config driver interface. The only thing it adds is
* correct refcounting dance.
*
* This should only be used by non-atomic legacy drivers.
*
* Returns:
* Zero on success, negative errno on failure.
*/
int drm_mode_set_config_internal(struct drm_mode_set *set)
{
WARN_ON(drm_drv_uses_atomic_modeset(set->crtc->dev));
return __drm_mode_set_config_internal(set, NULL);
}
EXPORT_SYMBOL(drm_mode_set_config_internal);
/**
@@ -534,6 +555,7 @@ int drm_mode_setcrtc(struct drm_device *dev, void *data,
struct drm_display_mode *mode = NULL;
struct drm_mode_set set;
uint32_t __user *set_connectors_ptr;
struct drm_modeset_acquire_ctx ctx;
int ret;
int i;
@@ -547,15 +569,18 @@ int drm_mode_setcrtc(struct drm_device *dev, void *data,
if (crtc_req->x & 0xffff0000 || crtc_req->y & 0xffff0000)
return -ERANGE;
drm_modeset_lock_all(dev);
crtc = drm_crtc_find(dev, crtc_req->crtc_id);
if (!crtc) {
DRM_DEBUG_KMS("Unknown CRTC ID %d\n", crtc_req->crtc_id);
ret = -ENOENT;
goto out;
return -ENOENT;
}
DRM_DEBUG_KMS("[CRTC:%d:%s]\n", crtc->base.id, crtc->name);
drm_modeset_acquire_init(&ctx, 0);
retry:
ret = drm_modeset_lock_all_ctx(crtc->dev, &ctx);
if (ret)
goto out;
if (crtc_req->mode_valid) {
/* If we have a mode we need a framebuffer. */
/* If we pass -1, set the mode with the currently bound fb */
@@ -676,7 +701,7 @@ int drm_mode_setcrtc(struct drm_device *dev, void *data,
set.connectors = connector_set;
set.num_connectors = crtc_req->count_connectors;
set.fb = fb;
ret = drm_mode_set_config_internal(&set);
ret = __drm_mode_set_config_internal(&set, &ctx);
out:
if (fb)
@@ -690,7 +715,13 @@ out:
}
kfree(connector_set);
drm_mode_destroy(dev, mode);
drm_modeset_unlock_all(dev);
if (ret == -EDEADLK) {
drm_modeset_backoff(&ctx);
goto retry;
}
drm_modeset_drop_locks(&ctx);
drm_modeset_acquire_fini(&ctx);
return ret;
}

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