Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b0654103 authored by Dave Airlie's avatar Dave Airlie
Browse files

Merge tag 'drm/tegra/for-3.19-rc1' of git://people.freedesktop.org/~tagr/linux into drm-next

drm/tegra: Changes for v3.19-rc1

The highlights in this pull request are:

  * IOMMU support: The Tegra DRM driver can now deal with discontiguous
    buffers if an IOMMU exists in the system. That means it can allocate
    using drm_gem_get_pages() and will map them into IOVA space via the
    IOMMU API. Similarly, non-contiguous PRIME buffers can be imported
    from a different driver, which allows better integration with gk20a
    (nouveau) and less hacks.

  * Universal planes: This is precursory work for atomic modesetting and
    will allow hardware cursor support to be implemented on pre-Tegra114
    where RGB cursors were not supported.

  * DSI ganged-mode support: The DSI controller can now gang up with a
    second DSI controller to drive high resolution DSI panels.

Besides those bigger changes there is a slew of fixes, cleanups, plugged
memory leaks and so on.

* tag 'drm/tegra/for-3.19-rc1' of git://people.freedesktop.org/~tagr/linux: (44 commits)
  drm/tegra: gem: Check before freeing CMA memory
  drm/tegra: fb: Add error codes to error messages
  drm/tegra: fb: Properly release GEM objects on failure
  drm/tegra: Detach panel when a connector is removed
  drm/tegra: Plug memory leak
  drm/tegra: gem: Use more consistent data types
  drm/tegra: fb: Do not destroy framebuffer
  drm/tegra: gem: dumb: pitch and size are outputs
  drm/tegra: Enable the hotplug interrupt only when necessary
  drm/tegra: dc: Universal plane support
  drm/tegra: dc: Registers are 32 bits wide
  drm/tegra: dc: Factor out DC, window and cursor commit
  drm/tegra: Add IOMMU support
  drm/tegra: Fix error handling cleanup
  drm/tegra: gem: Use dma_mmap_writecombine()
  drm/tegra: gem: Remove redundant drm_gem_free_mmap_offset()
  drm/tegra: gem: Cleanup tegra_bo_create_with_handle()
  drm/tegra: gem: Extract tegra_bo_alloc_object()
  drm/tegra: dsi: Set up PHY_TIMING & BTA_TIMING registers earlier
  drm/tegra: dsi: Replace 1000000 by USEC_PER_SEC
  ...
parents 4fb2ac6e 7e0180e3
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -191,6 +191,8 @@ of the following host1x client modules:
  - nvidia,hpd-gpio: specifies a GPIO used for hotplug detection
  - nvidia,edid: supplies a binary EDID blob
  - nvidia,panel: phandle of a display panel
  - nvidia,ganged-mode: contains a phandle to a second DSI controller to gang
    up with in order to support up to 8 data lanes

- sor: serial output resource

+1 −0
Original line number Diff line number Diff line
config DRM_TEGRA
	tristate "NVIDIA Tegra DRM"
	depends on ARCH_TEGRA || (ARM && COMPILE_TEST)
	depends on COMMON_CLK
	depends on DRM
	depends on RESET_CONTROLLER
	select DRM_KMS_HELPER
+413 −180

File changed.

Preview size limit exceeded, changes collapsed.

+42 −4
Original line number Diff line number Diff line
@@ -8,6 +8,7 @@
 */

#include <linux/host1x.h>
#include <linux/iommu.h>

#include "drm.h"
#include "gem.h"
@@ -33,6 +34,17 @@ static int tegra_drm_load(struct drm_device *drm, unsigned long flags)
	if (!tegra)
		return -ENOMEM;

	if (iommu_present(&platform_bus_type)) {
		tegra->domain = iommu_domain_alloc(&platform_bus_type);
		if (IS_ERR(tegra->domain)) {
			err = PTR_ERR(tegra->domain);
			goto free;
		}

		DRM_DEBUG("IOMMU context initialized\n");
		drm_mm_init(&tegra->mm, 0, SZ_2G);
	}

	mutex_init(&tegra->clients_lock);
	INIT_LIST_HEAD(&tegra->clients);
	drm->dev_private = tegra;
@@ -42,13 +54,13 @@ static int tegra_drm_load(struct drm_device *drm, unsigned long flags)

	err = tegra_drm_fb_prepare(drm);
	if (err < 0)
		return err;
		goto config;

	drm_kms_helper_poll_init(drm);

	err = host1x_device_init(device);
	if (err < 0)
		return err;
		goto fbdev;

	/*
	 * We don't use the drm_irq_install() helpers provided by the DRM
@@ -59,18 +71,37 @@ static int tegra_drm_load(struct drm_device *drm, unsigned long flags)

	err = drm_vblank_init(drm, drm->mode_config.num_crtc);
	if (err < 0)
		return err;
		goto device;

	err = tegra_drm_fb_init(drm);
	if (err < 0)
		return err;
		goto vblank;

	return 0;

vblank:
	drm_vblank_cleanup(drm);
device:
	host1x_device_exit(device);
fbdev:
	drm_kms_helper_poll_fini(drm);
	tegra_drm_fb_free(drm);
config:
	drm_mode_config_cleanup(drm);

	if (tegra->domain) {
		iommu_domain_free(tegra->domain);
		drm_mm_takedown(&tegra->mm);
	}
free:
	kfree(tegra);
	return err;
}

static int tegra_drm_unload(struct drm_device *drm)
{
	struct host1x_device *device = to_host1x_device(drm->dev);
	struct tegra_drm *tegra = drm->dev_private;
	int err;

	drm_kms_helper_poll_fini(drm);
@@ -82,6 +113,13 @@ static int tegra_drm_unload(struct drm_device *drm)
	if (err < 0)
		return err;

	if (tegra->domain) {
		iommu_domain_free(tegra->domain);
		drm_mm_takedown(&tegra->mm);
	}

	kfree(tegra);

	return 0;
}

+12 −6
Original line number Diff line number Diff line
@@ -39,6 +39,9 @@ struct tegra_fbdev {
struct tegra_drm {
	struct drm_device *drm;

	struct iommu_domain *domain;
	struct drm_mm mm;

	struct mutex clients_lock;
	struct list_head clients;

@@ -101,6 +104,7 @@ struct tegra_dc {
	spinlock_t lock;

	struct drm_crtc base;
	int powergate;
	int pipe;

	struct clk *clk;
@@ -120,6 +124,8 @@ struct tegra_dc {
	struct drm_pending_vblank_event *event;

	const struct tegra_dc_soc_info *soc;

	struct iommu_domain *domain;
};

static inline struct tegra_dc *
@@ -133,16 +139,15 @@ static inline struct tegra_dc *to_tegra_dc(struct drm_crtc *crtc)
	return crtc ? container_of(crtc, struct tegra_dc, base) : NULL;
}

static inline void tegra_dc_writel(struct tegra_dc *dc, unsigned long value,
				   unsigned long reg)
static inline void tegra_dc_writel(struct tegra_dc *dc, u32 value,
				   unsigned long offset)
{
	writel(value, dc->regs + (reg << 2));
	writel(value, dc->regs + (offset << 2));
}

static inline unsigned long tegra_dc_readl(struct tegra_dc *dc,
					   unsigned long reg)
static inline u32 tegra_dc_readl(struct tegra_dc *dc, unsigned long offset)
{
	return readl(dc->regs + (reg << 2));
	return readl(dc->regs + (offset << 2));
}

struct tegra_dc_window {
@@ -287,6 +292,7 @@ bool tegra_fb_is_bottom_up(struct drm_framebuffer *framebuffer);
int tegra_fb_get_tiling(struct drm_framebuffer *framebuffer,
			struct tegra_bo_tiling *tiling);
int tegra_drm_fb_prepare(struct drm_device *drm);
void tegra_drm_fb_free(struct drm_device *drm);
int tegra_drm_fb_init(struct drm_device *drm);
void tegra_drm_fb_exit(struct drm_device *drm);
#ifdef CONFIG_DRM_TEGRA_FBDEV
Loading