Setting a dev_pm_ops suspend/resume pair but not a set of hibernation
functions means those pm functions will not be called upon hibernation.
Fix this by using SIMPLE_DEV_PM_OPS, which appropriately assigns the
suspend and hibernation handlers and move
omap_drm_suspend/omap_drm_resume under CONFIG_PM_SLEEP to avoid build
warnings.
Signed-off-by: Grygorii Strashko <Grygorii.Strashko@linaro.org>
[tomi.valkeinen@ti.com: fix conflict, clean up description]
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
We store the fb being page-flipped to 'old_fb' field, but we don't
increase the ref count of the fb when doing that. While I am not
sure if it can cause problem in practice, it's still safer to keep a ref
when storing a pointer to a fb.
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
The omapdrm DMM code sometimes crashes with:
WARNING: CPU: 0 PID: 1235 at lib/list_debug.c:36 __list_add+0x8c/0xbc()
list_add double add: new=e9265368, prev=e90139c4, next=e9265368.
This is caused by the code calling release_engine() twice for the same
engine.
dmm_txn_commit(wait=true) call is supposed to wait until the DMM
transaction has been finished. And it does that, but it does not wait
for the irq handler to finish.
What happens is that the irq handler is triggered, and it either wakes
up the thread that called dmm_txn_commit(), or that thread never even
slept because the transaction was finished in the HW very quickly. That
thread then continues executing, even if the irq handler is not yet
finished, and a new transaction may be initiated. If that transaction is
async (i.e. wait=false), a 'async' flag is set to true. The original irq
handler, which has yet not finished, then sees the transaction as
'async', even if it was supposed to be 'sync'.
When that happens, the irq handler does an extra release_engine() call
because it thinks it need to release the engine, leading to the crash.
This patch fixes the issue by using completion to ensure that the irq
handler has finished before a dmm_txn_commit(wait=true) may continue.
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
omap_gem_objects are added to dev->obj_list in omap_gem_new, and removed
in omap_gem_free_object. Unfortunately there's no locking for
dev->obj_list, which eventually leads to a crash:
WARNING: CPU: 1 PID: 1123 at lib/list_debug.c:59 __list_del_entry+0xa4/0xe0()
list_del corruption. prev->next should be e9281344, but was ea722b84
Add a spinlock to protect dev->obj_list.
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
spin_is_locked(x) returns always 0 on uniprocessor, triggering BUG() in
omapdrm.
Change it to use assert_spin_locked() to fix the issue.
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
We need to ignore DIGIT SYNC LOST error when enabling/disabling TV
output. The code does that, but it ignores the DIGI SYNC LOST when
enabling any output. Normally this does no harm, but it could make us
miss DIGIT SYNC LOST on some rare occasions.
Fix the code to only ignore DIGIT SYNC LOST when enabling/disabling TV.
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
omapdrm tries to avoid error floods by unregistering the error irq when
an error happens, and then registering the error irq again later.
However, the code is racy, as it sometimes tries to unregister the error
irq when it's already unregistered, leading to WARN().
Also, the code only registers the error irq again when something is done
on that particular output, i.e. if only TV is used to flip the buffers,
and LCD is showing a same buffer, an error on LCD will cause the LCD
error irq to be unregistered and never registered again.
To fix this, let's keep the error irqs always enabled and trust the
DRM_ERROR_RATELIMITED to limit the flood.
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
omapdrm uses normal DRM_ERROR() print when the HW reports an error. As
we sometimes may get a flood of errors, let's rather use
DRM_ERROR_RATELIMITED().
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
When not using proper hotplug detection, DRM polls periodically the
connectors to find out if a cable is connected. This polling can happen
at any time, even very late in the suspend process.
This causes a problem with omapdrm, when the poll happens during the
suspend process after GPIOs have been disabled, leading to a crash in
gpio_get().
This patch fixes the issue by adding suspend and resume hooks to
omapdrm, in which we disable and enable, respectively, the polling.
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
omapdrm has dummy functions for platform_device's
suspend/resume/shutdown. The functions don't do anything, and those
platform device functions are deprecated, so remove them from omapdrm.
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
The tiler irq handler uses engine->async value, but the code that sets
engine->async and enables the interrupt does not have a barrier. This
may cause the irq handler to see the old value of engine->async, causing
memory corruption.
Reported-by: Harinarayan Bhatta <harinarayan@ti.com>
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
omap_plane_pre_apply() sets the plane's output channel too late, only
after the plane has already been otherwise configured and enabled. This
causes problems, as at the configuration stage we need to make decisions
based on the output channel.
This may lead to bad plane settings or failing to setup the plane.
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
On OMAP5 it is not possible to use TILER buffer with CPU when caching or
write-combining is used. Doing so leads to errors from the memory
manager.
However, on OMAP4, write-combining works fine.
This patch adds platform specific data for the TILER, and a function
tiler_get_cpu_cache_flags() which can be used to get the caching mode to
be used.
Note that without write-combining the use of the TILER buffer with CPU
is unusably slow. It's still good to have it operational for testing
purposes.
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
omapdrm doesn't check if the pitch of the framebuffer and the color
format's bits-per-pixel are compatible. omapdss requires that the stride
of a buffer is an integer number of pixels
For example, when using modetest with a display that has x resolution of
1280, and using packed 24 RGB mode (3 bytes per pixel), modetest
allocates a buffer with a byte stride of 4 * 1280 = 5120. But 5120 / 3 =
1706.666... pixels, which causes wrong colors and a tilt on the screen.
Add a check into omapdrm to return an error if the user tries to use
such a combination.
Note: this is not a HW requirement at least for non-rotation use cases,
but a SW driver requirement. In the future we should study if also
rotation use cases are fine with any stride size, and if so, change the
driver to allow these strides.
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
When an error happens in omap_framebuffer_create(),
omap_framebuffer_create() calls omap_framebuffer_destroy() if the fb
struct has been allocated. However, that crashes, as
omap_framebuffer_destroy(), which calls drm_framebuffer_cleanup(),
should only be called after drm_framebuffer_init()
Fix this by just calling kfree() for the allocated fb when an error
happens.
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
omapdrm should work fine even if fbdev is missing. The current driver
crashes in that case, though, as it is missing checks for the fbdev.
Add the checks so that we don't free fbdev or restore fbdev mode when
there's no fbdev.
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
unpin_worker() calls omap_framebuffer_unpin() without any locks, which
looks very suspicious. However, both pin and unpin are always called via
the driver's private workqueue, so the access is synchronized that way.
Add a comment to make this clear.
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
omap_framebuffer_pin() and omap_framebuffer_unpin() are currently
broken, as they cannot be called multiple times (i.e. pin, pin, unpin,
unpin), which is what happens in certain cases. This issue causes the
driver to possibly use 0 as an address for a displayed buffer, leading
to OCP error from DSS.
This patch fixes the issue by adding a simple pin_count, used to track
the number of pins.
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
Clear omap_obj's paddr when unmapping the memory, so that it's easier to
catch bad use of the paddr.
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
The DRM documentation says:
"If a page flip is already pending, the page_flip operation must return
-EBUSY."
Currently omapdrm returns -EINVAL instead. Fix omapdrm by returning
-EBUSY.
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
OMAP DSS hardware supports changing the output port to which an overlay
manager's video stream goes. For example, DPI video stream can come from
any of the four overlay managers on OMAP5.
However, as it's difficult to manage the change in the driver, the
omapdss driver does not support that at the moment, and has a hardcoded
overlay manager per output.
omapdrm, on the other hand, uses the hardware features to find out which
overlay manager to use for an output, which causes problems. For
example, on OMAP5, omapdrm tries to use DIGIT overlay manager for DPI
output, instead of the LCD3 required by the omapdss driver.
This patch changes the omapdrm to use the omapdss driver's hardcoded
overlay managers, which fixes the issue.
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
The next commit will need functions to be reordered. Do it separately to
help review.
This only moves functions without any change to the code.
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Planes are destroyed after framebuffers, which has the side effect of
disabling all planes. There is thus no need to disable planes explicitly
when destroying them.
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
The function will convert the Q16 source coordinates to integers, avoid
converting integers to Q16 first and perform the opposite conversion.
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Move the set_enabled function to avoid the forward declaration. While at
it prefix it with omap_crtc_ like most other functions in the file, and
fix the comment stating in which contexts the function is called.
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
The full_update field is always set to true before calling
omap_crtc_appy(), resulting in its value always being true in the single
location where it is tested, in omap_crtc_pre_apply(). Remove it.
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
All the manual update display code implements eventually ends up to just
calls to omap_connector_flush(), currently implemented as an empty TODO
stub. Remove it, the code can always be revived and implemented later if
interest in manual update displays becomes a reality.
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
The vblank interrupt is used by the driver as a completion signal when
applying new settings.
A race condition exist between enabling the vblank interrupt and
applying new settings to the hardware by setting the GO bit. If a vblank
interrupt occurs in-between, the driver will incorrectly consider the
new settings to be applied. Fix this by enabling the interrupt after
setting the GO bit.
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Whether to reset plane properties at disable time isn't well-defined in
DRM, but resetting only part of them is probably as bad as it can get.
Make the behaviour coherent by resetting the zorder property in addition
to the rotation property.
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
The planes don't care about DPMS states, don't propagate it
unnecessarily to the plane functions.
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Remove the CRTC private planes by switching to the universal plane API.
This results in a merge of the CRTC private plane created by the driver
(omap_crtc->plane) and the CRTC primary plane created by the DRM core
(crtc->primary).
Reference counting of the framebuffers in the update plane operation is
thus simplified as no reference needs to be stored in the private plane
anymore.
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
The ilace variable is unused and the replication variable is assigned to
false and just passed to a function. Remove them.
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Create a omap_modeset_create_crtc() function to avoid duplicating plane
and CRTC creation code.
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
rockchip fixes.
* 'drm_next' of https://github.com/markyzq/kernel-drm-rockchip:
drm/rockchip: vop: power off until vop standby take effect
drm/rockchip: vop: set vop enabled after enable iommu
drm/rockchip: vop use is_enabled instead of dpms mode
drm/rockchip: vop: fix vop vsync/hsync polarity
drm/rockchip: Only alloc a kmap for fbdev gem object
Be warned if primary or cursor planes haven't the correct type
Signed-off-by: Benjamin Gaignard <benjamin.gaignard@linaro.org>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
This wasn't too harmful since we already look at connector,
which has the same effect as the loop for any non-cloned configs.
Only when we have a cloned configuration is it important to look
at other connectors. Furthermore existing userspace always changes
dpms on all of them anyway.
Signed-off-by: JohnHunter <zhjwpku@gmail.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
There are some mistakes that the function name in the annotaions
is not matching the real function name.
And some duplication word in annotations
Signed-off-by: John Hunter <zhjwpku@gmail.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Vop standby will take effect at end of current frame,
if dsp_hold_valid_irq happen, it means vop standby complete.
we must wait standby complete when we want to disable aclk,
if not, memory bus maybe dead.
Reviewed-by: Heiko Stuebner <heiko@sntech.de>
Reviewed-by: Daniel Kurtz <djkurtz@chromium.org>
Signed-off-by: Mark Yao <mark.yao@rock-chips.com>
there is a Bug that:
vop_enable()->drm_vblank_on, drm_vblank_on may call vop
enable vblank. if it happen, vblank enable would failed,
then cause irq status error. because is_enabled value is set
after drm_vblank_on.
after enable vop clocks and iommu regs, we can sure that
R/W vop regs and do vop plane flip is safe, so place
is_enabled = true after enable iommu is suitable.
Signed-off-by: Mark Yao <mark.yao@rock-chips.com>
drm dpms have many power modes: ON,OFF,SUSPEND,STANDBY, etc.
but vop only have enable/disable mode, maybe case such bug:
--> DRM_DPMS_ON: power on vop
--> DRM_DPMS_SUSPEND: power off vop
--> DRM_DPMS_OFF: already power off at SUSPEND, crash
so use a bool val is more suitable.
Signed-off-by: Mark Yao <mark.yao@rock-chips.com>
Vop set wrong vsync/hsync polarity, it may cause some
display problem. known problem is that caused HDMI hdcp
authenticate failed, caused pixel offset with hdmi display.
the polarity description at RK3288 TRM doc:
dsp_vsync_pol
VSYNC polarity
1'b0 : negative
1'b1 : positive
dsp_hsync_pol
HSYNC polarity
1'b0 : negative
1'b1 : positive
Signed-off-by: Mark Yao <mark.yao@rock-chips.com>
Reviewed-by: Daniel Kurtz <djkurtz@chromium.org>
Tested-by: Caesar Wang <wxt@rock-chips.com>
Tested-by: Heiko Stuebner <heiko@sntech.de>
In general, the data in drm/rockchip GEM objects is never accessed by
the kernel. The objects are either accessed by a GPU, by display
controller DMA, or by mmap'ing them to user space. Thus, these
buffers need not be mapped into kernel address space.
The only exception is the fbdev framebuffer(s), which may be written
in-kernel by fbcon.
Signed-off-by: Daniel Kurtz <djkurtz@chromium.org>
Signed-off-by: Mark Yao <mark.yao@rock-chips.com>
../drivers/gpu/drm/drm_vm.c:405:6: warning: symbol 'drm_vm_open_locked' was not declared. Should it be static?
../drivers/gpu/drm/drm_vm.c:431:6: warning: symbol 'drm_vm_close_locked' was not declared. Should it be static?
../drivers/gpu/drm/drm_vm.c:681:5: warning: symbol 'drm_vma_info' was not declared. Should it be static?
../drivers/gpu/drm/drm_pci.c:146:5: warning: symbol 'drm_pci_set_unique' was not declared. Should it be static?
../drivers/gpu/drm/drm_pci.c:216:5: warning: symbol 'drm_irq_by_busid' was not declared. Should it be static?
../drivers/gpu/drm/drm_info.c:47:5: warning: symbol 'drm_name_info' was not declared. Should it be static?
../drivers/gpu/drm/drm_info.c:72:5: warning: symbol 'drm_vm_info' was not declared. Should it be static?
../drivers/gpu/drm/drm_info.c:116:5: warning: symbol 'drm_bufs_info' was not declared. Should it be static?
../drivers/gpu/drm/drm_info.c:159:5: warning: symbol 'drm_clients_info' was not declared. Should it be static?
../drivers/gpu/drm/drm_info.c:209:5: warning: symbol 'drm_gem_name_info' was not declared. Should it be static?
../drivers/gpu/drm/drm_ioc32.c:1019:20: warning: symbol 'drm_compat_ioctls' was not declared. Should it be static?
../drivers/gpu/drm/drm_bridge.c:52:12: warning: function 'drm_bridge_attach' with external linkage has definition
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Use %pS for actual addresses, otherwise you'll get bad output
on arches like ppc64 where %pF expects a function descriptor.
Signed-off-by: Scott Wood <scottwood@freescale.com>
Cc: dri-devel@lists.freedesktop.org
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
We don't want tile 0,0 to artificially constrain the size of the legacy
fbdev device. Instead when reducing fb_size to be the minimum of all
displays, only consider the rightmost and bottommost tiles.
Signed-off-by: Rob Clark <robdclark@gmail.com>
Tested-by: Hai Li <hali@codeaurora.org>
Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Flip conditional to reduce indentation level of rest of fxn, and use
min/max to make the code clearer.
v2: surface_width -> surface_height typo
Signed-off-by: Rob Clark <robdclark@gmail.com>
Reviewed-by: Daniel Kurtz <djkurtz@chromium.org>
Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
What is passed to drm_fb_helper_fill_var() should be fb_width/fb_height,
rather than the surface size.
Signed-off-by: Rob Clark <robdclark@gmail.com>
Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
Acked-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
What is passed to drm_fb_helper_fill_var() should be fb_width/fb_height,
rather than the surface size.
Signed-off-by: Rob Clark <robdclark@gmail.com>
Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
Acked-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>