diff options
Diffstat (limited to 'drivers/gpu/drm/tegra/plane.c')
| -rw-r--r-- | drivers/gpu/drm/tegra/plane.c | 36 | 
1 files changed, 34 insertions, 2 deletions
| diff --git a/drivers/gpu/drm/tegra/plane.c b/drivers/gpu/drm/tegra/plane.c index 539d14935728..2e11b4b1f702 100644 --- a/drivers/gpu/drm/tegra/plane.c +++ b/drivers/gpu/drm/tegra/plane.c @@ -8,7 +8,7 @@  #include <drm/drm_atomic.h>  #include <drm/drm_atomic_helper.h>  #include <drm/drm_fourcc.h> -#include <drm/drm_gem_framebuffer_helper.h> +#include <drm/drm_gem_atomic_helper.h>  #include <drm/drm_plane_helper.h>  #include "dc.h" @@ -83,6 +83,22 @@ static void tegra_plane_atomic_destroy_state(struct drm_plane *plane,  	kfree(state);  } +static bool tegra_plane_supports_sector_layout(struct drm_plane *plane) +{ +	struct drm_crtc *crtc; + +	drm_for_each_crtc(crtc, plane->dev) { +		if (plane->possible_crtcs & drm_crtc_mask(crtc)) { +			struct tegra_dc *dc = to_tegra_dc(crtc); + +			if (!dc->soc->supports_sector_layout) +				return false; +		} +	} + +	return true; +} +  static bool tegra_plane_format_mod_supported(struct drm_plane *plane,  					     uint32_t format,  					     uint64_t modifier) @@ -92,6 +108,14 @@ static bool tegra_plane_format_mod_supported(struct drm_plane *plane,  	if (modifier == DRM_FORMAT_MOD_LINEAR)  		return true; +	/* check for the sector layout bit */ +	if ((modifier >> 56) == DRM_FORMAT_MOD_VENDOR_NVIDIA) { +		if (modifier & DRM_FORMAT_MOD_NVIDIA_SECTOR_LAYOUT) { +			if (!tegra_plane_supports_sector_layout(plane)) +				return false; +		} +	} +  	if (info->num_planes == 1)  		return true; @@ -119,6 +143,14 @@ static int tegra_dc_pin(struct tegra_dc *dc, struct tegra_plane_state *state)  		dma_addr_t phys_addr, *phys;  		struct sg_table *sgt; +		/* +		 * If we're not attached to a domain, we already stored the +		 * physical address when the buffer was allocated. If we're +		 * part of a group that's shared between all display +		 * controllers, we've also already mapped the framebuffer +		 * through the SMMU. In both cases we can short-circuit the +		 * code below and retrieve the stored IOV address. +		 */  		if (!domain || dc->client.group)  			phys = &phys_addr;  		else @@ -198,7 +230,7 @@ int tegra_plane_prepare_fb(struct drm_plane *plane,  	if (!state->fb)  		return 0; -	drm_gem_fb_prepare_fb(plane, state); +	drm_gem_plane_helper_prepare_fb(plane, state);  	return tegra_dc_pin(dc, to_tegra_plane_state(state));  } | 
