drm/tegra: dsi: Add ganged mode support

Implement ganged mode support for the Tegra DSI driver. The DSI host
controller to gang up with is specified via a phandle in the device tree
and the resolved DSI host controller used for the programming of the
ganged-mode registers.

Signed-off-by: Thierry Reding <treding@nvidia.com>
---
Changes in v3:
- split off host-driven command mode changes into a separate patch

Changes in v2:
- keep track of the number of bytes transferred to/from peripheral
- use newly introduced mipi_dsi_create_packet()
- extract FIFO write into separate function
drm/tegra: dsi: Replace 1000000000UL by NSEC_PER_SEC

Using the symbolic constant instantly provides a lot more context.

Signed-off-by: Thierry Reding <treding@nvidia.com>
drm/tegra: dsi: Implement host-driven command mode

Add support for sending MIPI DSI command packets from the host to a
peripheral. This is required for panels that need configuration before
they accept video data.

Signed-off-by: Thierry Reding <treding@nvidia.com>
drm/tegra: dsi: Set up PHY_TIMING & BTA_TIMING registers earlier

Make sure the DSI PHY_TIMING and BTA_TIMING registers are initialized
when the clocks are set up as opposed to when the output is enabled.
This makes sure that the PHY timings are properly set up when the panel
is prepared and that DCS commands sent at that time use the appropriate
timings.

Signed-off-by: Sean Paul <seanpaul@chromium.org>
Signed-off-by: Thierry Reding <treding@nvidia.com>
drm/tegra: dc: Add missing call to drm_vblank_on()

When the CRTC is enabled, make sure the VBLANK machinery is enabled.
Failure to do so will cause drm_vblank_get() to not enable the VBLANK on
the CRTC and VBLANK-synchronized page-flips won't work.

While at it, get rid of the legacy drm_vblank_pre_modeset() and
drm_vblank_post_modeset() calls that are replaced by drm_vblank_on()
and drm_vblank_off().

Reported-by: Alexandre Courbot <acourbot@nvidia.com>
Tested-by: Alexandre Courbot <acourbot@nvidia.com>
Signed-off-by: Thierry Reding <treding@nvidia.com>
---
Changes in v2:
- call drm_crtc_vblank_off() in the CRTC's .prepare() callback to
  properly reset the vblank counter
drm/tegra: gem: Extract tegra_bo_alloc_object()

This function implements the common buffer object allocation used for
both allocation and import paths.

Signed-off-by: Thierry Reding <treding@nvidia.com>
drm/tegra: gem: Cleanup tegra_bo_create_with_handle()

There is only a single location where the function needs to do cleanup.
Skip the error unwinding path and call the cleanup function directly
instead.

Signed-off-by: Thierry Reding <treding@nvidia.com>
drm/tegra: gem: Remove redundant drm_gem_free_mmap_offset()

The drm_gem_object_release() function already performs this cleanup, so
there is no reason to do it explicitly.

Signed-off-by: Thierry Reding <treding@nvidia.com>
drm/tegra: gem: Use dma_mmap_writecombine()

Use the existing API rather than open-coding equivalent functionality
in the driver.

Signed-off-by: Thierry Reding <treding@nvidia.com>
drm/tegra: Fix error handling cleanup

The DRM driver's ->load() implementation didn't do a good job (no job at
all really) cleaning up on failure. Fix that by undoing any prior setup
when an error occurs. This requires a bit of rework to make it possible
to clean up fbdev midway.

This was tested by injecting errors at various points during the
initialization sequence and verifying that error cleanup didn't crash
and no memory leaked (using kmemleak).

Reported-by: Stéphane Marchesin <marcheu@chromium.org>
Reported-by: Sean Paul <seanpaul@chromium.org>
Reviewed-by: Sean Paul <seanpaul@chromium.org>
Signed-off-by: Thierry Reding <treding@nvidia.com>
drm/tegra: Add IOMMU support

When an IOMMU device is available on the platform bus, allocate an IOMMU
domain and attach the display controllers to it. The display controllers
can then scan out non-contiguous buffers by mapping them through the
IOMMU.

Signed-off-by: Thierry Reding <treding@nvidia.com>
---
Changes in v6:
- clean up IOMMU resources on initialization failure

Changes in v5:
- fix PRIME export of physically non-contiguous buffers
- refactor and fix error cleanup paths
- fix checking for failed allocations
- fix build warnings on 64-bit

Changes in v4:
- error out if IOMMU attachment fails

Changes in v3:
- create write-combined mappings for mmap()
- keep non-IOMMU fallback path working
- no longer rely on iommu_attach()

Changes in v2:
- don't pass GFP_KERNEL to drm_gem_get_pages()
drm/tegra: dc: Factor out DC, window and cursor commit

The sequence to commit changes to the DC, window or cursor configuration
is repetitive and can be extracted into separate functions for ease of
use.

Signed-off-by: Thierry Reding <treding@nvidia.com>
drm/tegra: dc: Registers are 32 bits wide

Using an unsigned long type will cause these variables to become 64-bit
on 64-bit SoCs. In practice this should always work, but there's no need
for carrying around the additional 32 bits.

Signed-off-by: Thierry Reding <treding@nvidia.com>
drm/tegra: dc: Universal plane support

This allows the primary plane and cursor to be exposed as regular
DRM/KMS planes, which is a prerequisite for atomic modesetting and gives
userspace more flexibility over controlling them.

Signed-off-by: Thierry Reding <treding@nvidia.com>
drm/tegra: Fix potential bug on driver unload

The HDMI hotplug signal may toggle after the DRM driver has been
unloaded. Make sure not to call into DRM if that's the case.

Signed-off-by: Thierry Reding <treding@nvidia.com>
drm/tegra: Enable the hotplug interrupt only when necessary

The hotplug handling needs access to the DRM device, which only appears
at ->init() time. Disable interrupts up until that time. Similarly, when
an output is removed, disable the hotplug interrupt again because the
DRM device (and with it the hotplug infrastructure) is going away.

Signed-off-by: Thierry Reding <treding@nvidia.com>
drm/tegra: gem: dumb: pitch and size are outputs

When creating a dumb buffer object using the DRM_IOCTL_MODE_CREATE_DUMB
IOCTL, only the width, height, bpp and flags parameters are inputs. The
caller is not guaranteed to zero out or set handle, pitch and size, so
the driver must not treat these values as possible inputs.

Fixes a bug where running the Weston compositor on Tegra DRM would cause
an attempt to allocate a 3 GiB framebuffer to be allocated.

Fixes: de2ba664c30f ("gpu: host1x: drm: Add memory manager and fb")
Cc: stable@vger.kernel.org
Signed-off-by: Thierry Reding <treding@nvidia.com>
drm/tegra: fb: Do not destroy framebuffer

Drop a reference instead of directly calling the framebuffer .destroy()
callback at fbdev free time. This is necessary to make sure the object
isn't destroyed if anyone else still has a reference.

Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Signed-off-by: Thierry Reding <treding@nvidia.com>
---
Changes in v2:
- use drm_framebuffer_remove() instead of drm_framebuffer_unreference()
drm/tegra: gem: Use more consistent data types

Use size_t consistently for sizes and u32/u64 instead of uint32_t and
uint64_t.

Signed-off-by: Thierry Reding <treding@nvidia.com>
drm/tegra: gem: function signature fixups for 64-bit