File Index
Files and directories
Sign in
FILE

amdgpu_display.c

File preview with syntax highlighting.

linux-6.19.14/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c C
   1/*
   2 * Copyright 2007-8 Advanced Micro Devices, Inc.
   3 * Copyright 2008 Red Hat Inc.
   4 *
   5 * Permission is hereby granted, free of charge, to any person obtaining a
   6 * copy of this software and associated documentation files (the "Software"),
   7 * to deal in the Software without restriction, including without limitation
   8 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
   9 * and/or sell copies of the Software, and to permit persons to whom the
  10 * Software is furnished to do so, subject to the following conditions:
  11 *
  12 * The above copyright notice and this permission notice shall be included in
  13 * all copies or substantial portions of the Software.
  14 *
  15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
  18 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
  19 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
  20 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  21 * OTHER DEALINGS IN THE SOFTWARE.
  22 *
  23 * Authors: Dave Airlie
  24 *          Alex Deucher
  25 */
  26
  27#include <drm/amdgpu_drm.h>
  28#include "amdgpu.h"
  29#include "amdgpu_i2c.h"
  30#include "atom.h"
  31#include "amdgpu_connectors.h"
  32#include "amdgpu_display.h"
  33#include "soc15_common.h"
  34#include "gc/gc_11_0_0_offset.h"
  35#include "gc/gc_11_0_0_sh_mask.h"
  36#include "bif/bif_4_1_d.h"
  37#include <asm/div64.h>
  38
  39#include <linux/pci.h>
  40#include <linux/pm_runtime.h>
  41#include <drm/drm_crtc_helper.h>
  42#include <drm/drm_damage_helper.h>
  43#include <drm/drm_drv.h>
  44#include <drm/drm_edid.h>
  45#include <drm/drm_fb_helper.h>
  46#include <drm/drm_gem_framebuffer_helper.h>
  47#include <drm/drm_fourcc.h>
  48#include <drm/drm_modeset_helper.h>
  49#include <drm/drm_vblank.h>
  50
  51/**
  52 * amdgpu_display_hotplug_work_func - work handler for display hotplug event
  53 *
  54 * @work: work struct pointer
  55 *
  56 * This is the hotplug event work handler (all ASICs).
  57 * The work gets scheduled from the IRQ handler if there
  58 * was a hotplug interrupt.  It walks through the connector table
  59 * and calls hotplug handler for each connector. After this, it sends
  60 * a DRM hotplug event to alert userspace.
  61 *
  62 * This design approach is required in order to defer hotplug event handling
  63 * from the IRQ handler to a work handler because hotplug handler has to use
  64 * mutexes which cannot be locked in an IRQ handler (since &mutex_lock may
  65 * sleep).
  66 */
  67void amdgpu_display_hotplug_work_func(struct work_struct *work)
  68{
  69	struct amdgpu_device *adev = container_of(work, struct amdgpu_device,
  70						  hotplug_work.work);
  71	struct drm_device *dev = adev_to_drm(adev);
  72	struct drm_mode_config *mode_config = &dev->mode_config;
  73	struct drm_connector *connector;
  74	struct drm_connector_list_iter iter;
  75
  76	mutex_lock(&mode_config->mutex);
  77	drm_connector_list_iter_begin(dev, &iter);
  78	drm_for_each_connector_iter(connector, &iter)
  79		amdgpu_connector_hotplug(connector);
  80	drm_connector_list_iter_end(&iter);
  81	mutex_unlock(&mode_config->mutex);
  82	/* Just fire off a uevent and let userspace tell us what to do */
  83	drm_helper_hpd_irq_event(dev);
  84}
  85
  86static int amdgpu_display_framebuffer_init(struct drm_device *dev,
  87					   struct amdgpu_framebuffer *rfb,
  88					   const struct drm_mode_fb_cmd2 *mode_cmd,
  89					   struct drm_gem_object *obj);
  90
  91static void amdgpu_display_flip_callback(struct dma_fence *f,
  92					 struct dma_fence_cb *cb)
  93{
  94	struct amdgpu_flip_work *work =
  95		container_of(cb, struct amdgpu_flip_work, cb);
  96
  97	dma_fence_put(f);
  98	schedule_work(&work->flip_work.work);
  99}
 100
 101static bool amdgpu_display_flip_handle_fence(struct amdgpu_flip_work *work,
 102					     struct dma_fence **f)
 103{
 104	struct dma_fence *fence = *f;
 105
 106	if (fence == NULL)
 107		return false;
 108
 109	*f = NULL;
 110
 111	if (!dma_fence_add_callback(fence, &work->cb,
 112				    amdgpu_display_flip_callback))
 113		return true;
 114
 115	dma_fence_put(fence);
 116	return false;
 117}
 118
 119static void amdgpu_display_flip_work_func(struct work_struct *__work)
 120{
 121	struct delayed_work *delayed_work =
 122		container_of(__work, struct delayed_work, work);
 123	struct amdgpu_flip_work *work =
 124		container_of(delayed_work, struct amdgpu_flip_work, flip_work);
 125	struct amdgpu_device *adev = work->adev;
 126	struct amdgpu_crtc *amdgpu_crtc = adev->mode_info.crtcs[work->crtc_id];
 127
 128	struct drm_crtc *crtc = &amdgpu_crtc->base;
 129	unsigned long flags;
 130	unsigned int i;
 131	int vpos, hpos;
 132
 133	for (i = 0; i < work->shared_count; ++i)
 134		if (amdgpu_display_flip_handle_fence(work, &work->shared[i]))
 135			return;
 136
 137	/* Wait until we're out of the vertical blank period before the one
 138	 * targeted by the flip
 139	 */
 140	if (amdgpu_crtc->enabled &&
 141	    (amdgpu_display_get_crtc_scanoutpos(adev_to_drm(adev), work->crtc_id, 0,
 142						&vpos, &hpos, NULL, NULL,
 143						&crtc->hwmode)
 144	     & (DRM_SCANOUTPOS_VALID | DRM_SCANOUTPOS_IN_VBLANK)) ==
 145	    (DRM_SCANOUTPOS_VALID | DRM_SCANOUTPOS_IN_VBLANK) &&
 146	    (int)(work->target_vblank -
 147		  amdgpu_get_vblank_counter_kms(crtc)) > 0) {
 148		schedule_delayed_work(&work->flip_work, usecs_to_jiffies(1000));
 149		return;
 150	}
 151
 152	/* We borrow the event spin lock for protecting flip_status */
 153	spin_lock_irqsave(&crtc->dev->event_lock, flags);
 154
 155	/* Do the flip (mmio) */
 156	adev->mode_info.funcs->page_flip(adev, work->crtc_id, work->base, work->async);
 157
 158	/* Set the flip status */
 159	amdgpu_crtc->pflip_status = AMDGPU_FLIP_SUBMITTED;
 160	spin_unlock_irqrestore(&crtc->dev->event_lock, flags);
 161
 162
 163	drm_dbg_vbl(adev_to_drm(adev),
 164		    "crtc:%d[%p], pflip_stat:AMDGPU_FLIP_SUBMITTED, work: %p,\n",
 165		    amdgpu_crtc->crtc_id, amdgpu_crtc, work);
 166
 167}
 168
 169/*
 170 * Handle unpin events outside the interrupt handler proper.
 171 */
 172static void amdgpu_display_unpin_work_func(struct work_struct *__work)
 173{
 174	struct amdgpu_flip_work *work =
 175		container_of(__work, struct amdgpu_flip_work, unpin_work);
 176	int r;
 177
 178	/* unpin of the old buffer */
 179	r = amdgpu_bo_reserve(work->old_abo, true);
 180	if (likely(r == 0)) {
 181		amdgpu_bo_unpin(work->old_abo);
 182		amdgpu_bo_unreserve(work->old_abo);
 183	} else
 184		DRM_ERROR("failed to reserve buffer after flip\n");
 185
 186	amdgpu_bo_unref(&work->old_abo);
 187	kfree(work->shared);
 188	kfree(work);
 189}
 190
 191int amdgpu_display_crtc_page_flip_target(struct drm_crtc *crtc,
 192				struct drm_framebuffer *fb,
 193				struct drm_pending_vblank_event *event,
 194				uint32_t page_flip_flags, uint32_t target,
 195				struct drm_modeset_acquire_ctx *ctx)
 196{
 197	struct drm_device *dev = crtc->dev;
 198	struct amdgpu_device *adev = drm_to_adev(dev);
 199	struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc);
 200	struct drm_gem_object *obj;
 201	struct amdgpu_flip_work *work;
 202	struct amdgpu_bo *new_abo;
 203	unsigned long flags;
 204	u64 tiling_flags;
 205	int i, r;
 206
 207	work = kzalloc(sizeof(*work), GFP_KERNEL);
 208	if (work == NULL)
 209		return -ENOMEM;
 210
 211	INIT_DELAYED_WORK(&work->flip_work, amdgpu_display_flip_work_func);
 212	INIT_WORK(&work->unpin_work, amdgpu_display_unpin_work_func);
 213
 214	work->event = event;
 215	work->adev = adev;
 216	work->crtc_id = amdgpu_crtc->crtc_id;
 217	work->async = (page_flip_flags & DRM_MODE_PAGE_FLIP_ASYNC) != 0;
 218
 219	/* schedule unpin of the old buffer */
 220	obj = crtc->primary->fb->obj[0];
 221
 222	/* take a reference to the old object */
 223	work->old_abo = gem_to_amdgpu_bo(obj);
 224	amdgpu_bo_ref(work->old_abo);
 225
 226	obj = fb->obj[0];
 227	new_abo = gem_to_amdgpu_bo(obj);
 228
 229	/* pin the new buffer */
 230	r = amdgpu_bo_reserve(new_abo, false);
 231	if (unlikely(r != 0)) {
 232		DRM_ERROR("failed to reserve new abo buffer before flip\n");
 233		goto cleanup;
 234	}
 235
 236	if (!adev->enable_virtual_display) {
 237		new_abo->flags |= AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS;
 238		r = amdgpu_bo_pin(new_abo,
 239				  amdgpu_display_supported_domains(adev, new_abo->flags));
 240		if (unlikely(r != 0)) {
 241			DRM_ERROR("failed to pin new abo buffer before flip\n");
 242			goto unreserve;
 243		}
 244	}
 245
 246	r = amdgpu_ttm_alloc_gart(&new_abo->tbo);
 247	if (unlikely(r != 0)) {
 248		DRM_ERROR("%p bind failed\n", new_abo);
 249		goto unpin;
 250	}
 251
 252	r = dma_resv_get_fences(new_abo->tbo.base.resv, DMA_RESV_USAGE_WRITE,
 253				&work->shared_count,
 254				&work->shared);
 255	if (unlikely(r != 0)) {
 256		DRM_ERROR("failed to get fences for buffer\n");
 257		goto unpin;
 258	}
 259
 260	amdgpu_bo_get_tiling_flags(new_abo, &tiling_flags);
 261	amdgpu_bo_unreserve(new_abo);
 262
 263	if (!adev->enable_virtual_display)
 264		work->base = amdgpu_bo_gpu_offset(new_abo);
 265	work->target_vblank = target - (uint32_t)drm_crtc_vblank_count(crtc) +
 266		amdgpu_get_vblank_counter_kms(crtc);
 267
 268	/* we borrow the event spin lock for protecting flip_wrok */
 269	spin_lock_irqsave(&crtc->dev->event_lock, flags);
 270	if (amdgpu_crtc->pflip_status != AMDGPU_FLIP_NONE) {
 271		DRM_DEBUG_DRIVER("flip queue: crtc already busy\n");
 272		spin_unlock_irqrestore(&crtc->dev->event_lock, flags);
 273		r = -EBUSY;
 274		goto pflip_cleanup;
 275	}
 276
 277	amdgpu_crtc->pflip_status = AMDGPU_FLIP_PENDING;
 278	amdgpu_crtc->pflip_works = work;
 279
 280
 281	DRM_DEBUG_DRIVER("crtc:%d[%p], pflip_stat:AMDGPU_FLIP_PENDING, work: %p,\n",
 282					 amdgpu_crtc->crtc_id, amdgpu_crtc, work);
 283	/* update crtc fb */
 284	crtc->primary->fb = fb;
 285	spin_unlock_irqrestore(&crtc->dev->event_lock, flags);
 286	amdgpu_display_flip_work_func(&work->flip_work.work);
 287	return 0;
 288
 289pflip_cleanup:
 290	if (unlikely(amdgpu_bo_reserve(new_abo, false) != 0)) {
 291		DRM_ERROR("failed to reserve new abo in error path\n");
 292		goto cleanup;
 293	}
 294unpin:
 295	if (!adev->enable_virtual_display)
 296		amdgpu_bo_unpin(new_abo);
 297
 298unreserve:
 299	amdgpu_bo_unreserve(new_abo);
 300
 301cleanup:
 302	amdgpu_bo_unref(&work->old_abo);
 303	for (i = 0; i < work->shared_count; ++i)
 304		dma_fence_put(work->shared[i]);
 305	kfree(work->shared);
 306	kfree(work);
 307
 308	return r;
 309}
 310
 311int amdgpu_display_crtc_set_config(struct drm_mode_set *set,
 312				   struct drm_modeset_acquire_ctx *ctx)
 313{
 314	struct drm_device *dev;
 315	struct amdgpu_device *adev;
 316	struct drm_crtc *crtc;
 317	bool active = false;
 318	int ret;
 319
 320	if (!set || !set->crtc)
 321		return -EINVAL;
 322
 323	dev = set->crtc->dev;
 324
 325	ret = pm_runtime_get_sync(dev->dev);
 326	if (ret < 0)
 327		goto out;
 328
 329	ret = drm_crtc_helper_set_config(set, ctx);
 330
 331	list_for_each_entry(crtc, &dev->mode_config.crtc_list, head)
 332		if (crtc->enabled)
 333			active = true;
 334
 335	adev = drm_to_adev(dev);
 336	/* if we have active crtcs and we don't have a power ref,
 337	 * take the current one
 338	 */
 339	if (active && !adev->have_disp_power_ref) {
 340		adev->have_disp_power_ref = true;
 341		return ret;
 342	}
 343	/* if we have no active crtcs, then go to
 344	 * drop the power ref we got before
 345	 */
 346	if (!active && adev->have_disp_power_ref)
 347		adev->have_disp_power_ref = false;
 348out:
 349	/* drop the power reference we got coming in here */
 350	pm_runtime_put_autosuspend(dev->dev);
 351	return ret;
 352}
 353
 354static const char *encoder_names[41] = {
 355	"NONE",
 356	"INTERNAL_LVDS",
 357	"INTERNAL_TMDS1",
 358	"INTERNAL_TMDS2",
 359	"INTERNAL_DAC1",
 360	"INTERNAL_DAC2",
 361	"INTERNAL_SDVOA",
 362	"INTERNAL_SDVOB",
 363	"SI170B",
 364	"CH7303",
 365	"CH7301",
 366	"INTERNAL_DVO1",
 367	"EXTERNAL_SDVOA",
 368	"EXTERNAL_SDVOB",
 369	"TITFP513",
 370	"INTERNAL_LVTM1",
 371	"VT1623",
 372	"HDMI_SI1930",
 373	"HDMI_INTERNAL",
 374	"INTERNAL_KLDSCP_TMDS1",
 375	"INTERNAL_KLDSCP_DVO1",
 376	"INTERNAL_KLDSCP_DAC1",
 377	"INTERNAL_KLDSCP_DAC2",
 378	"SI178",
 379	"MVPU_FPGA",
 380	"INTERNAL_DDI",
 381	"VT1625",
 382	"HDMI_SI1932",
 383	"DP_AN9801",
 384	"DP_DP501",
 385	"INTERNAL_UNIPHY",
 386	"INTERNAL_KLDSCP_LVTMA",
 387	"INTERNAL_UNIPHY1",
 388	"INTERNAL_UNIPHY2",
 389	"NUTMEG",
 390	"TRAVIS",
 391	"INTERNAL_VCE",
 392	"INTERNAL_UNIPHY3",
 393	"HDMI_ANX9805",
 394	"INTERNAL_AMCLK",
 395	"VIRTUAL",
 396};
 397
 398static const char *hpd_names[6] = {
 399	"HPD1",
 400	"HPD2",
 401	"HPD3",
 402	"HPD4",
 403	"HPD5",
 404	"HPD6",
 405};
 406
 407void amdgpu_display_print_display_setup(struct drm_device *dev)
 408{
 409	struct drm_connector *connector;
 410	struct amdgpu_connector *amdgpu_connector;
 411	struct drm_encoder *encoder;
 412	struct amdgpu_encoder *amdgpu_encoder;
 413	struct drm_connector_list_iter iter;
 414	uint32_t devices;
 415	int i = 0;
 416
 417	drm_connector_list_iter_begin(dev, &iter);
 418	DRM_INFO("AMDGPU Display Connectors\n");
 419	drm_for_each_connector_iter(connector, &iter) {
 420		amdgpu_connector = to_amdgpu_connector(connector);
 421		DRM_INFO("Connector %d:\n", i);
 422		DRM_INFO("  %s\n", connector->name);
 423		if (amdgpu_connector->hpd.hpd != AMDGPU_HPD_NONE)
 424			DRM_INFO("  %s\n", hpd_names[amdgpu_connector->hpd.hpd]);
 425		if (amdgpu_connector->ddc_bus) {
 426			DRM_INFO("  DDC: 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n",
 427				 amdgpu_connector->ddc_bus->rec.mask_clk_reg,
 428				 amdgpu_connector->ddc_bus->rec.mask_data_reg,
 429				 amdgpu_connector->ddc_bus->rec.a_clk_reg,
 430				 amdgpu_connector->ddc_bus->rec.a_data_reg,
 431				 amdgpu_connector->ddc_bus->rec.en_clk_reg,
 432				 amdgpu_connector->ddc_bus->rec.en_data_reg,
 433				 amdgpu_connector->ddc_bus->rec.y_clk_reg,
 434				 amdgpu_connector->ddc_bus->rec.y_data_reg);
 435			if (amdgpu_connector->router.ddc_valid)
 436				DRM_INFO("  DDC Router 0x%x/0x%x\n",
 437					 amdgpu_connector->router.ddc_mux_control_pin,
 438					 amdgpu_connector->router.ddc_mux_state);
 439			if (amdgpu_connector->router.cd_valid)
 440				DRM_INFO("  Clock/Data Router 0x%x/0x%x\n",
 441					 amdgpu_connector->router.cd_mux_control_pin,
 442					 amdgpu_connector->router.cd_mux_state);
 443		} else {
 444			if (connector->connector_type == DRM_MODE_CONNECTOR_VGA ||
 445			    connector->connector_type == DRM_MODE_CONNECTOR_DVII ||
 446			    connector->connector_type == DRM_MODE_CONNECTOR_DVID ||
 447			    connector->connector_type == DRM_MODE_CONNECTOR_DVIA ||
 448			    connector->connector_type == DRM_MODE_CONNECTOR_HDMIA ||
 449			    connector->connector_type == DRM_MODE_CONNECTOR_HDMIB)
 450				DRM_INFO("  DDC: no ddc bus - possible BIOS bug - please report to xorg-driver-ati@lists.x.org\n");
 451		}
 452		DRM_INFO("  Encoders:\n");
 453		list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
 454			amdgpu_encoder = to_amdgpu_encoder(encoder);
 455			devices = amdgpu_encoder->devices & amdgpu_connector->devices;
 456			if (devices) {
 457				if (devices & ATOM_DEVICE_CRT1_SUPPORT)
 458					DRM_INFO("    CRT1: %s\n", encoder_names[amdgpu_encoder->encoder_id]);
 459				if (devices & ATOM_DEVICE_CRT2_SUPPORT)
 460					DRM_INFO("    CRT2: %s\n", encoder_names[amdgpu_encoder->encoder_id]);
 461				if (devices & ATOM_DEVICE_LCD1_SUPPORT)
 462					DRM_INFO("    LCD1: %s\n", encoder_names[amdgpu_encoder->encoder_id]);
 463				if (devices & ATOM_DEVICE_DFP1_SUPPORT)
 464					DRM_INFO("    DFP1: %s\n", encoder_names[amdgpu_encoder->encoder_id]);
 465				if (devices & ATOM_DEVICE_DFP2_SUPPORT)
 466					DRM_INFO("    DFP2: %s\n", encoder_names[amdgpu_encoder->encoder_id]);
 467				if (devices & ATOM_DEVICE_DFP3_SUPPORT)
 468					DRM_INFO("    DFP3: %s\n", encoder_names[amdgpu_encoder->encoder_id]);
 469				if (devices & ATOM_DEVICE_DFP4_SUPPORT)
 470					DRM_INFO("    DFP4: %s\n", encoder_names[amdgpu_encoder->encoder_id]);
 471				if (devices & ATOM_DEVICE_DFP5_SUPPORT)
 472					DRM_INFO("    DFP5: %s\n", encoder_names[amdgpu_encoder->encoder_id]);
 473				if (devices & ATOM_DEVICE_DFP6_SUPPORT)
 474					DRM_INFO("    DFP6: %s\n", encoder_names[amdgpu_encoder->encoder_id]);
 475				if (devices & ATOM_DEVICE_TV1_SUPPORT)
 476					DRM_INFO("    TV1: %s\n", encoder_names[amdgpu_encoder->encoder_id]);
 477				if (devices & ATOM_DEVICE_CV_SUPPORT)
 478					DRM_INFO("    CV: %s\n", encoder_names[amdgpu_encoder->encoder_id]);
 479			}
 480		}
 481		i++;
 482	}
 483	drm_connector_list_iter_end(&iter);
 484}
 485
 486bool amdgpu_display_ddc_probe(struct amdgpu_connector *amdgpu_connector,
 487			      bool use_aux)
 488{
 489	u8 out = 0x0;
 490	u8 buf[8];
 491	int ret;
 492	struct i2c_msg msgs[] = {
 493		{
 494			.addr = DDC_ADDR,
 495			.flags = 0,
 496			.len = 1,
 497			.buf = &out,
 498		},
 499		{
 500			.addr = DDC_ADDR,
 501			.flags = I2C_M_RD,
 502			.len = 8,
 503			.buf = buf,
 504		}
 505	};
 506
 507	/* on hw with routers, select right port */
 508	if (amdgpu_connector->router.ddc_valid)
 509		amdgpu_i2c_router_select_ddc_port(amdgpu_connector);
 510
 511	if (use_aux)
 512		ret = i2c_transfer(&amdgpu_connector->ddc_bus->aux.ddc, msgs, 2);
 513	else
 514		ret = i2c_transfer(&amdgpu_connector->ddc_bus->adapter, msgs, 2);
 515
 516	if (ret != 2)
 517		/* Couldn't find an accessible DDC on this connector */
 518		return false;
 519	/* Probe also for valid EDID header
 520	 * EDID header starts with:
 521	 * 0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x00.
 522	 * Only the first 6 bytes must be valid as
 523	 * drm_edid_block_valid() can fix the last 2 bytes
 524	 */
 525	if (drm_edid_header_is_valid(buf) < 6) {
 526		/* Couldn't find an accessible EDID on this
 527		 * connector
 528		 */
 529		return false;
 530	}
 531	return true;
 532}
 533
 534static int amdgpu_dirtyfb(struct drm_framebuffer *fb, struct drm_file *file,
 535			  unsigned int flags, unsigned int color,
 536			  struct drm_clip_rect *clips, unsigned int num_clips)
 537{
 538
 539	if (file)
 540		return -ENOSYS;
 541
 542	return drm_atomic_helper_dirtyfb(fb, file, flags, color, clips,
 543					 num_clips);
 544}
 545
 546static const struct drm_framebuffer_funcs amdgpu_fb_funcs = {
 547	.destroy = drm_gem_fb_destroy,
 548	.create_handle = drm_gem_fb_create_handle,
 549};
 550
 551static const struct drm_framebuffer_funcs amdgpu_fb_funcs_atomic = {
 552	.destroy = drm_gem_fb_destroy,
 553	.create_handle = drm_gem_fb_create_handle,
 554	.dirty = amdgpu_dirtyfb
 555};
 556
 557uint32_t amdgpu_display_supported_domains(struct amdgpu_device *adev,
 558					  uint64_t bo_flags)
 559{
 560	uint32_t domain = AMDGPU_GEM_DOMAIN_VRAM;
 561
 562#if defined(CONFIG_DRM_AMD_DC)
 563	/*
 564	 * if amdgpu_bo_support_uswc returns false it means that USWC mappings
 565	 * is not supported for this board. But this mapping is required
 566	 * to avoid hang caused by placement of scanout BO in GTT on certain
 567	 * APUs. So force the BO placement to VRAM in case this architecture
 568	 * will not allow USWC mappings.
 569	 * Also, don't allow GTT domain if the BO doesn't have USWC flag set.
 570	 */
 571	if ((bo_flags & AMDGPU_GEM_CREATE_CPU_GTT_USWC) &&
 572	    amdgpu_bo_support_uswc(bo_flags) &&
 573	    adev->dc_enabled &&
 574	    adev->mode_info.gpu_vm_support)
 575		domain |= AMDGPU_GEM_DOMAIN_GTT;
 576#endif
 577
 578	return domain;
 579}
 580
 581static const struct drm_format_info dcc_formats[] = {
 582	{ .format = DRM_FORMAT_XRGB8888, .depth = 24, .num_planes = 2,
 583	  .cpp = { 4, 0, }, .block_w = {1, 1, 1}, .block_h = {1, 1, 1}, .hsub = 1, .vsub = 1, },
 584	 { .format = DRM_FORMAT_XBGR8888, .depth = 24, .num_planes = 2,
 585	  .cpp = { 4, 0, }, .block_w = {1, 1, 1}, .block_h = {1, 1, 1}, .hsub = 1, .vsub = 1, },
 586	{ .format = DRM_FORMAT_ARGB8888, .depth = 32, .num_planes = 2,
 587	  .cpp = { 4, 0, }, .block_w = {1, 1, 1}, .block_h = {1, 1, 1}, .hsub = 1, .vsub = 1,
 588	   .has_alpha = true, },
 589	{ .format = DRM_FORMAT_ABGR8888, .depth = 32, .num_planes = 2,
 590	  .cpp = { 4, 0, }, .block_w = {1, 1, 1}, .block_h = {1, 1, 1}, .hsub = 1, .vsub = 1,
 591	  .has_alpha = true, },
 592	{ .format = DRM_FORMAT_BGRA8888, .depth = 32, .num_planes = 2,
 593	  .cpp = { 4, 0, }, .block_w = {1, 1, 1}, .block_h = {1, 1, 1}, .hsub = 1, .vsub = 1,
 594	  .has_alpha = true, },
 595	{ .format = DRM_FORMAT_XRGB2101010, .depth = 30, .num_planes = 2,
 596	  .cpp = { 4, 0, }, .block_w = {1, 1, 1}, .block_h = {1, 1, 1}, .hsub = 1, .vsub = 1, },
 597	{ .format = DRM_FORMAT_XBGR2101010, .depth = 30, .num_planes = 2,
 598	  .cpp = { 4, 0, }, .block_w = {1, 1, 1}, .block_h = {1, 1, 1}, .hsub = 1, .vsub = 1, },
 599	{ .format = DRM_FORMAT_ARGB2101010, .depth = 30, .num_planes = 2,
 600	  .cpp = { 4, 0, }, .block_w = {1, 1, 1}, .block_h = {1, 1, 1}, .hsub = 1, .vsub = 1,
 601	  .has_alpha = true, },
 602	{ .format = DRM_FORMAT_ABGR2101010, .depth = 30, .num_planes = 2,
 603	  .cpp = { 4, 0, }, .block_w = {1, 1, 1}, .block_h = {1, 1, 1}, .hsub = 1, .vsub = 1,
 604	  .has_alpha = true, },
 605	{ .format = DRM_FORMAT_RGB565, .depth = 16, .num_planes = 2,
 606	  .cpp = { 2, 0, }, .block_w = {1, 1, 1}, .block_h = {1, 1, 1}, .hsub = 1, .vsub = 1, },
 607};
 608
 609static const struct drm_format_info dcc_retile_formats[] = {
 610	{ .format = DRM_FORMAT_XRGB8888, .depth = 24, .num_planes = 3,
 611	  .cpp = { 4, 0, 0 }, .block_w = {1, 1, 1}, .block_h = {1, 1, 1}, .hsub = 1, .vsub = 1, },
 612	 { .format = DRM_FORMAT_XBGR8888, .depth = 24, .num_planes = 3,
 613	  .cpp = { 4, 0, 0 }, .block_w = {1, 1, 1}, .block_h = {1, 1, 1}, .hsub = 1, .vsub = 1, },
 614	{ .format = DRM_FORMAT_ARGB8888, .depth = 32, .num_planes = 3,
 615	  .cpp = { 4, 0, 0 }, .block_w = {1, 1, 1}, .block_h = {1, 1, 1}, .hsub = 1, .vsub = 1,
 616	   .has_alpha = true, },
 617	{ .format = DRM_FORMAT_ABGR8888, .depth = 32, .num_planes = 3,
 618	  .cpp = { 4, 0, 0 }, .block_w = {1, 1, 1}, .block_h = {1, 1, 1}, .hsub = 1, .vsub = 1,
 619	  .has_alpha = true, },
 620	{ .format = DRM_FORMAT_BGRA8888, .depth = 32, .num_planes = 3,
 621	  .cpp = { 4, 0, 0 }, .block_w = {1, 1, 1}, .block_h = {1, 1, 1}, .hsub = 1, .vsub = 1,
 622	  .has_alpha = true, },
 623	{ .format = DRM_FORMAT_XRGB2101010, .depth = 30, .num_planes = 3,
 624	  .cpp = { 4, 0, 0 }, .block_w = {1, 1, 1}, .block_h = {1, 1, 1}, .hsub = 1, .vsub = 1, },
 625	{ .format = DRM_FORMAT_XBGR2101010, .depth = 30, .num_planes = 3,
 626	  .cpp = { 4, 0, 0 }, .block_w = {1, 1, 1}, .block_h = {1, 1, 1}, .hsub = 1, .vsub = 1, },
 627	{ .format = DRM_FORMAT_ARGB2101010, .depth = 30, .num_planes = 3,
 628	  .cpp = { 4, 0, 0 }, .block_w = {1, 1, 1}, .block_h = {1, 1, 1}, .hsub = 1, .vsub = 1,
 629	  .has_alpha = true, },
 630	{ .format = DRM_FORMAT_ABGR2101010, .depth = 30, .num_planes = 3,
 631	  .cpp = { 4, 0, 0 }, .block_w = {1, 1, 1}, .block_h = {1, 1, 1}, .hsub = 1, .vsub = 1,
 632	  .has_alpha = true, },
 633	{ .format = DRM_FORMAT_RGB565, .depth = 16, .num_planes = 3,
 634	  .cpp = { 2, 0, 0 }, .block_w = {1, 1, 1}, .block_h = {1, 1, 1}, .hsub = 1, .vsub = 1, },
 635};
 636
 637static const struct drm_format_info *
 638lookup_format_info(const struct drm_format_info formats[],
 639		  int num_formats, u32 format)
 640{
 641	int i;
 642
 643	for (i = 0; i < num_formats; i++) {
 644		if (formats[i].format == format)
 645			return &formats[i];
 646	}
 647
 648	return NULL;
 649}
 650
 651const struct drm_format_info *
 652amdgpu_lookup_format_info(u32 format, uint64_t modifier)
 653{
 654	if (!IS_AMD_FMT_MOD(modifier))
 655		return NULL;
 656
 657	if (AMD_FMT_MOD_GET(TILE_VERSION, modifier) < AMD_FMT_MOD_TILE_VER_GFX9 ||
 658	    AMD_FMT_MOD_GET(TILE_VERSION, modifier) >= AMD_FMT_MOD_TILE_VER_GFX12)
 659		return NULL;
 660
 661	if (AMD_FMT_MOD_GET(DCC_RETILE, modifier))
 662		return lookup_format_info(dcc_retile_formats,
 663					  ARRAY_SIZE(dcc_retile_formats),
 664					  format);
 665
 666	if (AMD_FMT_MOD_GET(DCC, modifier))
 667		return lookup_format_info(dcc_formats, ARRAY_SIZE(dcc_formats),
 668					  format);
 669
 670	/* returning NULL will cause the default format structs to be used. */
 671	return NULL;
 672}
 673
 674
 675/*
 676 * Tries to extract the renderable DCC offset from the opaque metadata attached
 677 * to the buffer.
 678 */
 679static int
 680extract_render_dcc_offset(struct amdgpu_device *adev,
 681			  struct drm_gem_object *obj,
 682			  uint64_t *offset)
 683{
 684	struct amdgpu_bo *rbo;
 685	int r = 0;
 686	uint32_t metadata[10]; /* Something that fits a descriptor + header. */
 687	uint32_t size;
 688
 689	rbo = gem_to_amdgpu_bo(obj);
 690	r = amdgpu_bo_reserve(rbo, false);
 691
 692	if (unlikely(r)) {
 693		/* Don't show error message when returning -ERESTARTSYS */
 694		if (r != -ERESTARTSYS)
 695			DRM_ERROR("Unable to reserve buffer: %d\n", r);
 696		return r;
 697	}
 698
 699	r = amdgpu_bo_get_metadata(rbo, metadata, sizeof(metadata), &size, NULL);
 700	amdgpu_bo_unreserve(rbo);
 701
 702	if (r)
 703		return r;
 704
 705	/*
 706	 * The first word is the metadata version, and we need space for at least
 707	 * the version + pci vendor+device id + 8 words for a descriptor.
 708	 */
 709	if (size < 40  || metadata[0] != 1)
 710		return -EINVAL;
 711
 712	if (adev->family >= AMDGPU_FAMILY_NV) {
 713		/* resource word 6/7 META_DATA_ADDRESS{_LO} */
 714		*offset = ((u64)metadata[9] << 16u) |
 715			  ((metadata[8] & 0xFF000000u) >> 16);
 716	} else {
 717		/* resource word 5/7 META_DATA_ADDRESS */
 718		*offset = ((u64)metadata[9] << 8u) |
 719			  ((u64)(metadata[7] & 0x1FE0000u) << 23);
 720	}
 721
 722	return 0;
 723}
 724
 725static int convert_tiling_flags_to_modifier_gfx12(struct amdgpu_framebuffer *afb)
 726{
 727	u64 modifier = 0;
 728	int swizzle_mode = AMDGPU_TILING_GET(afb->tiling_flags, GFX12_SWIZZLE_MODE);
 729
 730	if (!swizzle_mode) {
 731		modifier = DRM_FORMAT_MOD_LINEAR;
 732	} else {
 733		int max_comp_block =
 734			AMDGPU_TILING_GET(afb->tiling_flags, GFX12_DCC_MAX_COMPRESSED_BLOCK);
 735
 736		modifier =
 737			AMD_FMT_MOD |
 738			AMD_FMT_MOD_SET(TILE_VERSION, AMD_FMT_MOD_TILE_VER_GFX12) |
 739			AMD_FMT_MOD_SET(TILE, swizzle_mode) |
 740			AMD_FMT_MOD_SET(DCC, afb->gfx12_dcc) |
 741			AMD_FMT_MOD_SET(DCC_MAX_COMPRESSED_BLOCK, max_comp_block);
 742	}
 743
 744	afb->base.modifier = modifier;
 745	afb->base.flags |= DRM_MODE_FB_MODIFIERS;
 746	return 0;
 747}
 748
 749static int convert_tiling_flags_to_modifier(struct amdgpu_framebuffer *afb)
 750{
 751	struct amdgpu_device *adev = drm_to_adev(afb->base.dev);
 752	uint64_t modifier = 0;
 753	int num_pipes = 0;
 754	int num_pkrs = 0;
 755
 756	num_pkrs = adev->gfx.config.gb_addr_config_fields.num_pkrs;
 757	num_pipes = adev->gfx.config.gb_addr_config_fields.num_pipes;
 758
 759	if (!afb->tiling_flags || !AMDGPU_TILING_GET(afb->tiling_flags, SWIZZLE_MODE)) {
 760		modifier = DRM_FORMAT_MOD_LINEAR;
 761	} else {
 762		int swizzle = AMDGPU_TILING_GET(afb->tiling_flags, SWIZZLE_MODE);
 763		bool has_xor = swizzle >= 16;
 764		int block_size_bits;
 765		int version;
 766		int pipe_xor_bits = 0;
 767		int bank_xor_bits = 0;
 768		int packers = 0;
 769		int rb = 0;
 770		int pipes = ilog2(num_pipes);
 771		uint32_t dcc_offset = AMDGPU_TILING_GET(afb->tiling_flags, DCC_OFFSET_256B);
 772
 773		switch (swizzle >> 2) {
 774		case 0: /* 256B */
 775			block_size_bits = 8;
 776			break;
 777		case 1: /* 4KiB */
 778		case 5: /* 4KiB _X */
 779			block_size_bits = 12;
 780			break;
 781		case 2: /* 64KiB */
 782		case 4: /* 64 KiB _T */
 783		case 6: /* 64 KiB _X */
 784			block_size_bits = 16;
 785			break;
 786		case 7: /* 256 KiB */
 787			block_size_bits = 18;
 788			break;
 789		default:
 790			/* RESERVED or VAR */
 791			return -EINVAL;
 792		}
 793
 794		if (amdgpu_ip_version(adev, GC_HWIP, 0) >= IP_VERSION(11, 0, 0))
 795			version = AMD_FMT_MOD_TILE_VER_GFX11;
 796		else if (amdgpu_ip_version(adev, GC_HWIP, 0) >=
 797			 IP_VERSION(10, 3, 0))
 798			version = AMD_FMT_MOD_TILE_VER_GFX10_RBPLUS;
 799		else if (amdgpu_ip_version(adev, GC_HWIP, 0) >=
 800			 IP_VERSION(10, 0, 0))
 801			version = AMD_FMT_MOD_TILE_VER_GFX10;
 802		else
 803			version = AMD_FMT_MOD_TILE_VER_GFX9;
 804
 805		switch (swizzle & 3) {
 806		case 0: /* Z microtiling */
 807			return -EINVAL;
 808		case 1: /* S microtiling */
 809			if (amdgpu_ip_version(adev, GC_HWIP, 0) <
 810			    IP_VERSION(11, 0, 0)) {
 811				if (!has_xor)
 812					version = AMD_FMT_MOD_TILE_VER_GFX9;
 813			}
 814			break;
 815		case 2:
 816			if (amdgpu_ip_version(adev, GC_HWIP, 0) <
 817			    IP_VERSION(11, 0, 0)) {
 818				if (!has_xor && afb->base.format->cpp[0] != 4)
 819					version = AMD_FMT_MOD_TILE_VER_GFX9;
 820			}
 821			break;
 822		case 3:
 823			break;
 824		}
 825
 826		if (has_xor) {
 827			if (num_pipes == num_pkrs && num_pkrs == 0) {
 828				DRM_ERROR("invalid number of pipes and packers\n");
 829				return -EINVAL;
 830			}
 831
 832			switch (version) {
 833			case AMD_FMT_MOD_TILE_VER_GFX11:
 834				pipe_xor_bits = min(block_size_bits - 8, pipes);
 835				packers = ilog2(adev->gfx.config.gb_addr_config_fields.num_pkrs);
 836				break;
 837			case AMD_FMT_MOD_TILE_VER_GFX10_RBPLUS:
 838				pipe_xor_bits = min(block_size_bits - 8, pipes);
 839				packers = min(block_size_bits - 8 - pipe_xor_bits,
 840					      ilog2(adev->gfx.config.gb_addr_config_fields.num_pkrs));
 841				break;
 842			case AMD_FMT_MOD_TILE_VER_GFX10:
 843				pipe_xor_bits = min(block_size_bits - 8, pipes);
 844				break;
 845			case AMD_FMT_MOD_TILE_VER_GFX9:
 846				rb = ilog2(adev->gfx.config.gb_addr_config_fields.num_se) +
 847				     ilog2(adev->gfx.config.gb_addr_config_fields.num_rb_per_se);
 848				pipe_xor_bits = min(block_size_bits - 8, pipes +
 849						    ilog2(adev->gfx.config.gb_addr_config_fields.num_se));
 850				bank_xor_bits = min(block_size_bits - 8 - pipe_xor_bits,
 851						    ilog2(adev->gfx.config.gb_addr_config_fields.num_banks));
 852				break;
 853			}
 854		}
 855
 856		modifier = AMD_FMT_MOD |
 857			   AMD_FMT_MOD_SET(TILE, AMDGPU_TILING_GET(afb->tiling_flags, SWIZZLE_MODE)) |
 858			   AMD_FMT_MOD_SET(TILE_VERSION, version) |
 859			   AMD_FMT_MOD_SET(PIPE_XOR_BITS, pipe_xor_bits) |
 860			   AMD_FMT_MOD_SET(BANK_XOR_BITS, bank_xor_bits) |
 861			   AMD_FMT_MOD_SET(PACKERS, packers);
 862
 863		if (dcc_offset != 0) {
 864			bool dcc_i64b = AMDGPU_TILING_GET(afb->tiling_flags, DCC_INDEPENDENT_64B) != 0;
 865			bool dcc_i128b = version >= AMD_FMT_MOD_TILE_VER_GFX10_RBPLUS;
 866			const struct drm_format_info *format_info;
 867			u64 render_dcc_offset;
 868
 869			/* Enable constant encode on RAVEN2 and later. */
 870			bool dcc_constant_encode =
 871				(adev->asic_type > CHIP_RAVEN ||
 872				 (adev->asic_type == CHIP_RAVEN &&
 873				  adev->external_rev_id >= 0x81)) &&
 874				amdgpu_ip_version(adev, GC_HWIP, 0) <
 875					IP_VERSION(11, 0, 0);
 876
 877			int max_cblock_size = dcc_i64b ? AMD_FMT_MOD_DCC_BLOCK_64B :
 878					      dcc_i128b ? AMD_FMT_MOD_DCC_BLOCK_128B :
 879					      AMD_FMT_MOD_DCC_BLOCK_256B;
 880
 881			modifier |= AMD_FMT_MOD_SET(DCC, 1) |
 882				    AMD_FMT_MOD_SET(DCC_CONSTANT_ENCODE, dcc_constant_encode) |
 883				    AMD_FMT_MOD_SET(DCC_INDEPENDENT_64B, dcc_i64b) |
 884				    AMD_FMT_MOD_SET(DCC_INDEPENDENT_128B, dcc_i128b) |
 885				    AMD_FMT_MOD_SET(DCC_MAX_COMPRESSED_BLOCK, max_cblock_size);
 886
 887			afb->base.offsets[1] = dcc_offset * 256 + afb->base.offsets[0];
 888			afb->base.pitches[1] =
 889				AMDGPU_TILING_GET(afb->tiling_flags, DCC_PITCH_MAX) + 1;
 890
 891			/*
 892			 * If the userspace driver uses retiling the tiling flags do not contain
 893			 * info on the renderable DCC buffer. Luckily the opaque metadata contains
 894			 * the info so we can try to extract it. The kernel does not use this info
 895			 * but we should convert it to a modifier plane for getfb2, so the
 896			 * userspace driver that gets it doesn't have to juggle around another DCC
 897			 * plane internally.
 898			 */
 899			if (extract_render_dcc_offset(adev, afb->base.obj[0],
 900						      &render_dcc_offset) == 0 &&
 901			    render_dcc_offset != 0 &&
 902			    render_dcc_offset != afb->base.offsets[1] &&
 903			    render_dcc_offset < UINT_MAX) {
 904				uint32_t dcc_block_bits;  /* of base surface data */
 905
 906				modifier |= AMD_FMT_MOD_SET(DCC_RETILE, 1);
 907				afb->base.offsets[2] = render_dcc_offset;
 908
 909				if (adev->family >= AMDGPU_FAMILY_NV) {
 910					int extra_pipe = 0;
 911
 912					if ((amdgpu_ip_version(adev, GC_HWIP,
 913							       0) >=
 914					     IP_VERSION(10, 3, 0)) &&
 915					    pipes == packers && pipes > 1)
 916						extra_pipe = 1;
 917
 918					dcc_block_bits = max(20, 16 + pipes + extra_pipe);
 919				} else {
 920					modifier |= AMD_FMT_MOD_SET(RB, rb) |
 921						    AMD_FMT_MOD_SET(PIPE, pipes);
 922					dcc_block_bits = max(20, 18 + rb);
 923				}
 924
 925				dcc_block_bits -= ilog2(afb->base.format->cpp[0]);
 926				afb->base.pitches[2] = ALIGN(afb->base.width,
 927							     1u << ((dcc_block_bits + 1) / 2));
 928			}
 929			format_info = amdgpu_lookup_format_info(afb->base.format->format,
 930								modifier);
 931			if (!format_info)
 932				return -EINVAL;
 933
 934			afb->base.format = format_info;
 935		}
 936	}
 937
 938	afb->base.modifier = modifier;
 939	afb->base.flags |= DRM_MODE_FB_MODIFIERS;
 940	return 0;
 941}
 942
 943/* Mirrors the is_displayable check in radeonsi's gfx6_compute_surface */
 944static int check_tiling_flags_gfx6(struct amdgpu_framebuffer *afb)
 945{
 946	u64 micro_tile_mode;
 947
 948	if (AMDGPU_TILING_GET(afb->tiling_flags, ARRAY_MODE) == 1) /* LINEAR_ALIGNED */
 949		return 0;
 950
 951	micro_tile_mode = AMDGPU_TILING_GET(afb->tiling_flags, MICRO_TILE_MODE);
 952	switch (micro_tile_mode) {
 953	case 0: /* DISPLAY */
 954	case 3: /* RENDER */
 955		return 0;
 956	default:
 957		drm_dbg_kms(afb->base.dev,
 958			    "Micro tile mode %llu not supported for scanout\n",
 959			    micro_tile_mode);
 960		return -EINVAL;
 961	}
 962}
 963
 964static void get_block_dimensions(unsigned int block_log2, unsigned int cpp,
 965				 unsigned int *width, unsigned int *height)
 966{
 967	unsigned int cpp_log2 = ilog2(cpp);
 968	unsigned int pixel_log2 = block_log2 - cpp_log2;
 969	unsigned int width_log2 = (pixel_log2 + 1) / 2;
 970	unsigned int height_log2 = pixel_log2 - width_log2;
 971
 972	*width = 1 << width_log2;
 973	*height = 1 << height_log2;
 974}
 975
 976static unsigned int get_dcc_block_size(uint64_t modifier, bool rb_aligned,
 977				       bool pipe_aligned)
 978{
 979	unsigned int ver = AMD_FMT_MOD_GET(TILE_VERSION, modifier);
 980
 981	switch (ver) {
 982	case AMD_FMT_MOD_TILE_VER_GFX9: {
 983		/*
 984		 * TODO: for pipe aligned we may need to check the alignment of the
 985		 * total size of the surface, which may need to be bigger than the
 986		 * natural alignment due to some HW workarounds
 987		 */
 988		return max(10 + (rb_aligned ? (int)AMD_FMT_MOD_GET(RB, modifier) : 0), 12);
 989	}
 990	case AMD_FMT_MOD_TILE_VER_GFX10:
 991	case AMD_FMT_MOD_TILE_VER_GFX10_RBPLUS:
 992	case AMD_FMT_MOD_TILE_VER_GFX11: {
 993		int pipes_log2 = AMD_FMT_MOD_GET(PIPE_XOR_BITS, modifier);
 994
 995		if (ver >= AMD_FMT_MOD_TILE_VER_GFX10_RBPLUS && pipes_log2 > 1 &&
 996		    AMD_FMT_MOD_GET(PACKERS, modifier) == pipes_log2)
 997			++pipes_log2;
 998
 999		return max(8 + (pipe_aligned ? pipes_log2 : 0), 12);
1000	}
1001	default:
1002		return 0;
1003	}
1004}
1005
1006static int amdgpu_display_verify_plane(struct amdgpu_framebuffer *rfb, int plane,
1007				       const struct drm_format_info *format,
1008				       unsigned int block_width, unsigned int block_height,
1009				       unsigned int block_size_log2)
1010{
1011	unsigned int width = rfb->base.width /
1012		((plane && plane < format->num_planes) ? format->hsub : 1);
1013	unsigned int height = rfb->base.height /
1014		((plane && plane < format->num_planes) ? format->vsub : 1);
1015	unsigned int cpp = plane < format->num_planes ? format->cpp[plane] : 1;
1016	unsigned int block_pitch = block_width * cpp;
1017	unsigned int min_pitch = ALIGN(width * cpp, block_pitch);
1018	unsigned int block_size = 1 << block_size_log2;
1019	uint64_t size;
1020
1021	if (rfb->base.pitches[plane] % block_pitch) {
1022		drm_dbg_kms(rfb->base.dev,
1023			    "pitch %d for plane %d is not a multiple of block pitch %d\n",
1024			    rfb->base.pitches[plane], plane, block_pitch);
1025		return -EINVAL;
1026	}
1027	if (rfb->base.pitches[plane] < min_pitch) {
1028		drm_dbg_kms(rfb->base.dev,
1029			    "pitch %d for plane %d is less than minimum pitch %d\n",
1030			    rfb->base.pitches[plane], plane, min_pitch);
1031		return -EINVAL;
1032	}
1033
1034	/* Force at least natural alignment. */
1035	if (rfb->base.offsets[plane] % block_size) {
1036		drm_dbg_kms(rfb->base.dev,
1037			    "offset 0x%x for plane %d is not a multiple of block pitch 0x%x\n",
1038			    rfb->base.offsets[plane], plane, block_size);
1039		return -EINVAL;
1040	}
1041
1042	size = rfb->base.offsets[plane] +
1043		(uint64_t)rfb->base.pitches[plane] / block_pitch *
1044		block_size * DIV_ROUND_UP(height, block_height);
1045
1046	if (rfb->base.obj[0]->size < size) {
1047		drm_dbg_kms(rfb->base.dev,
1048			    "BO size 0x%zx is less than 0x%llx required for plane %d\n",
1049			    rfb->base.obj[0]->size, size, plane);
1050		return -EINVAL;
1051	}
1052
1053	return 0;
1054}
1055
1056
1057static int amdgpu_display_verify_sizes(struct amdgpu_framebuffer *rfb)
1058{
1059	const struct drm_format_info *format_info = drm_format_info(rfb->base.format->format);
1060	uint64_t modifier = rfb->base.modifier;
1061	int ret;
1062	unsigned int i, block_width, block_height, block_size_log2;
1063
1064	if (rfb->base.dev->mode_config.fb_modifiers_not_supported)
1065		return 0;
1066
1067	for (i = 0; i < format_info->num_planes; ++i) {
1068		if (modifier == DRM_FORMAT_MOD_LINEAR) {
1069			block_width = 256 / format_info->cpp[i];
1070			block_height = 1;
1071			block_size_log2 = 8;
1072		} else if (AMD_FMT_MOD_GET(TILE_VERSION, modifier) >= AMD_FMT_MOD_TILE_VER_GFX12) {
1073			int swizzle = AMD_FMT_MOD_GET(TILE, modifier);
1074
1075			switch (swizzle) {
1076			case AMD_FMT_MOD_TILE_GFX12_256B_2D:
1077				block_size_log2 = 8;
1078				break;
1079			case AMD_FMT_MOD_TILE_GFX12_4K_2D:
1080				block_size_log2 = 12;
1081				break;
1082			case AMD_FMT_MOD_TILE_GFX12_64K_2D:
1083				block_size_log2 = 16;
1084				break;
1085			case AMD_FMT_MOD_TILE_GFX12_256K_2D:
1086				block_size_log2 = 18;
1087				break;
1088			default:
1089				drm_dbg_kms(rfb->base.dev,
1090					    "Gfx12 swizzle mode with unknown block size: %d\n", swizzle);
1091				return -EINVAL;
1092			}
1093
1094			get_block_dimensions(block_size_log2, format_info->cpp[i],
1095					     &block_width, &block_height);
1096		} else {
1097			int swizzle = AMD_FMT_MOD_GET(TILE, modifier);
1098
1099			switch ((swizzle & ~3) + 1) {
1100			case DC_SW_256B_S:
1101				block_size_log2 = 8;
1102				break;
1103			case DC_SW_4KB_S:
1104			case DC_SW_4KB_S_X:
1105				block_size_log2 = 12;
1106				break;
1107			case DC_SW_64KB_S:
1108			case DC_SW_64KB_S_T:
1109			case DC_SW_64KB_S_X:
1110				block_size_log2 = 16;
1111				break;
1112			case DC_SW_VAR_S_X:
1113				block_size_log2 = 18;
1114				break;
1115			default:
1116				drm_dbg_kms(rfb->base.dev,
1117					    "Swizzle mode with unknown block size: %d\n", swizzle);
1118				return -EINVAL;
1119			}
1120
1121			get_block_dimensions(block_size_log2, format_info->cpp[i],
1122					     &block_width, &block_height);
1123		}
1124
1125		ret = amdgpu_display_verify_plane(rfb, i, format_info,
1126						  block_width, block_height, block_size_log2);
1127		if (ret)
1128			return ret;
1129	}
1130
1131	if (AMD_FMT_MOD_GET(TILE_VERSION, modifier) <= AMD_FMT_MOD_TILE_VER_GFX11 &&
1132	    AMD_FMT_MOD_GET(DCC, modifier)) {
1133		if (AMD_FMT_MOD_GET(DCC_RETILE, modifier)) {
1134			block_size_log2 = get_dcc_block_size(modifier, false, false);
1135			get_block_dimensions(block_size_log2 + 8, format_info->cpp[0],
1136					     &block_width, &block_height);
1137			ret = amdgpu_display_verify_plane(rfb, i, format_info,
1138							  block_width, block_height,
1139							  block_size_log2);
1140			if (ret)
1141				return ret;
1142
1143			++i;
1144			block_size_log2 = get_dcc_block_size(modifier, true, true);
1145		} else {
1146			bool pipe_aligned = AMD_FMT_MOD_GET(DCC_PIPE_ALIGN, modifier);
1147
1148			block_size_log2 = get_dcc_block_size(modifier, true, pipe_aligned);
1149		}
1150		get_block_dimensions(block_size_log2 + 8, format_info->cpp[0],
1151				     &block_width, &block_height);
1152		ret = amdgpu_display_verify_plane(rfb, i, format_info,
1153						  block_width, block_height, block_size_log2);
1154		if (ret)
1155			return ret;
1156	}
1157
1158	return 0;
1159}
1160
1161static int amdgpu_display_get_fb_info(const struct amdgpu_framebuffer *amdgpu_fb,
1162				      uint64_t *tiling_flags, bool *tmz_surface,
1163				      bool *gfx12_dcc)
1164{
1165	struct amdgpu_bo *rbo;
1166	int r;
1167
1168	if (!amdgpu_fb) {
1169		*tiling_flags = 0;
1170		*tmz_surface = false;
1171		*gfx12_dcc = false;
1172		return 0;
1173	}
1174
1175	rbo = gem_to_amdgpu_bo(amdgpu_fb->base.obj[0]);
1176	r = amdgpu_bo_reserve(rbo, false);
1177
1178	if (unlikely(r)) {
1179		/* Don't show error message when returning -ERESTARTSYS */
1180		if (r != -ERESTARTSYS)
1181			DRM_ERROR("Unable to reserve buffer: %d\n", r);
1182		return r;
1183	}
1184
1185	amdgpu_bo_get_tiling_flags(rbo, tiling_flags);
1186	*tmz_surface = amdgpu_bo_encrypted(rbo);
1187	*gfx12_dcc = rbo->flags & AMDGPU_GEM_CREATE_GFX12_DCC;
1188
1189	amdgpu_bo_unreserve(rbo);
1190
1191	return r;
1192}
1193
1194static int amdgpu_display_gem_fb_verify_and_init(struct drm_device *dev,
1195						 struct amdgpu_framebuffer *rfb,
1196						 struct drm_file *file_priv,
1197						 const struct drm_format_info *info,
1198						 const struct drm_mode_fb_cmd2 *mode_cmd,
1199						 struct drm_gem_object *obj)
1200{
1201	int ret;
1202
1203	rfb->base.obj[0] = obj;
1204	drm_helper_mode_fill_fb_struct(dev, &rfb->base, info, mode_cmd);
1205	/* Verify that the modifier is supported. */
1206	if (!drm_any_plane_has_format(dev, mode_cmd->pixel_format,
1207				      mode_cmd->modifier[0])) {
1208		drm_dbg_kms(dev,
1209			    "unsupported pixel format %p4cc / modifier 0x%llx\n",
1210			    &mode_cmd->pixel_format, mode_cmd->modifier[0]);
1211
1212		ret = -EINVAL;
1213		goto err;
1214	}
1215
1216	ret = amdgpu_display_framebuffer_init(dev, rfb, mode_cmd, obj);
1217	if (ret)
1218		goto err;
1219
1220	if (drm_drv_uses_atomic_modeset(dev))
1221		ret = drm_framebuffer_init(dev, &rfb->base,
1222					   &amdgpu_fb_funcs_atomic);
1223	else
1224		ret = drm_framebuffer_init(dev, &rfb->base, &amdgpu_fb_funcs);
1225
1226	if (ret)
1227		goto err;
1228
1229	return 0;
1230err:
1231	drm_dbg_kms(dev, "Failed to verify and init gem fb: %d\n", ret);
1232	rfb->base.obj[0] = NULL;
1233	return ret;
1234}
1235
1236static int amdgpu_display_framebuffer_init(struct drm_device *dev,
1237					   struct amdgpu_framebuffer *rfb,
1238					   const struct drm_mode_fb_cmd2 *mode_cmd,
1239					   struct drm_gem_object *obj)
1240{
1241	struct amdgpu_device *adev = drm_to_adev(dev);
1242	int ret, i;
1243
1244	/*
1245	 * This needs to happen before modifier conversion as that might change
1246	 * the number of planes.
1247	 */
1248	for (i = 1; i < rfb->base.format->num_planes; ++i) {
1249		if (mode_cmd->handles[i] != mode_cmd->handles[0]) {
1250			drm_dbg_kms(dev, "Plane 0 and %d have different BOs: %u vs. %u\n",
1251				    i, mode_cmd->handles[0], mode_cmd->handles[i]);
1252			ret = -EINVAL;
1253			return ret;
1254		}
1255	}
1256
1257	ret = amdgpu_display_get_fb_info(rfb, &rfb->tiling_flags, &rfb->tmz_surface,
1258					 &rfb->gfx12_dcc);
1259	if (ret)
1260		return ret;
1261
1262	if (dev->mode_config.fb_modifiers_not_supported && !adev->enable_virtual_display) {
1263		drm_WARN_ONCE(dev, adev->family >= AMDGPU_FAMILY_AI,
1264			      "GFX9+ requires FB check based on format modifier\n");
1265		ret = check_tiling_flags_gfx6(rfb);
1266		if (ret)
1267			return ret;
1268	}
1269
1270	if (!dev->mode_config.fb_modifiers_not_supported &&
1271	    !(rfb->base.flags & DRM_MODE_FB_MODIFIERS)) {
1272		if (amdgpu_ip_version(adev, GC_HWIP, 0) >= IP_VERSION(12, 0, 0))
1273			ret = convert_tiling_flags_to_modifier_gfx12(rfb);
1274		else
1275			ret = convert_tiling_flags_to_modifier(rfb);
1276
1277		if (ret) {
1278			drm_dbg_kms(dev, "Failed to convert tiling flags 0x%llX to a modifier",
1279				    rfb->tiling_flags);
1280			return ret;
1281		}
1282	}
1283
1284	ret = amdgpu_display_verify_sizes(rfb);
1285	if (ret)
1286		return ret;
1287
1288	for (i = 0; i < rfb->base.format->num_planes; ++i) {
1289		drm_gem_object_get(rfb->base.obj[0]);
1290		rfb->base.obj[i] = rfb->base.obj[0];
1291	}
1292
1293	return 0;
1294}
1295
1296struct drm_framebuffer *
1297amdgpu_display_user_framebuffer_create(struct drm_device *dev,
1298				       struct drm_file *file_priv,
1299				       const struct drm_format_info *info,
1300				       const struct drm_mode_fb_cmd2 *mode_cmd)
1301{
1302	struct amdgpu_framebuffer *amdgpu_fb;
1303	struct drm_gem_object *obj;
1304	struct amdgpu_bo *bo;
1305	uint32_t domains;
1306	int ret;
1307
1308	obj = drm_gem_object_lookup(file_priv, mode_cmd->handles[0]);
1309	if (obj ==  NULL) {
1310		drm_dbg_kms(dev,
1311			    "No GEM object associated to handle 0x%08X, can't create framebuffer\n",
1312			    mode_cmd->handles[0]);
1313
1314		return ERR_PTR(-ENOENT);
1315	}
1316
1317	/* Handle is imported dma-buf, so cannot be migrated to VRAM for scanout */
1318	bo = gem_to_amdgpu_bo(obj);
1319	domains = amdgpu_display_supported_domains(drm_to_adev(dev), bo->flags);
1320	if (drm_gem_is_imported(obj) && !(domains & AMDGPU_GEM_DOMAIN_GTT)) {
1321		drm_dbg_kms(dev, "Cannot create framebuffer from imported dma_buf\n");
1322		drm_gem_object_put(obj);
1323		return ERR_PTR(-EINVAL);
1324	}
1325
1326	amdgpu_fb = kzalloc(sizeof(*amdgpu_fb), GFP_KERNEL);
1327	if (amdgpu_fb == NULL) {
1328		drm_gem_object_put(obj);
1329		return ERR_PTR(-ENOMEM);
1330	}
1331
1332	ret = amdgpu_display_gem_fb_verify_and_init(dev, amdgpu_fb, file_priv,
1333						    info, mode_cmd, obj);
1334	if (ret) {
1335		kfree(amdgpu_fb);
1336		drm_gem_object_put(obj);
1337		return ERR_PTR(ret);
1338	}
1339
1340	drm_gem_object_put(obj);
1341	return &amdgpu_fb->base;
1342}
1343
1344const struct drm_mode_config_funcs amdgpu_mode_funcs = {
1345	.fb_create = amdgpu_display_user_framebuffer_create,
1346};
1347
1348static const struct drm_prop_enum_list amdgpu_underscan_enum_list[] = {
1349	{ UNDERSCAN_OFF, "off" },
1350	{ UNDERSCAN_ON, "on" },
1351	{ UNDERSCAN_AUTO, "auto" },
1352};
1353
1354static const struct drm_prop_enum_list amdgpu_audio_enum_list[] = {
1355	{ AMDGPU_AUDIO_DISABLE, "off" },
1356	{ AMDGPU_AUDIO_ENABLE, "on" },
1357	{ AMDGPU_AUDIO_AUTO, "auto" },
1358};
1359
1360/* XXX support different dither options? spatial, temporal, both, etc. */
1361static const struct drm_prop_enum_list amdgpu_dither_enum_list[] = {
1362	{ AMDGPU_FMT_DITHER_DISABLE, "off" },
1363	{ AMDGPU_FMT_DITHER_ENABLE, "on" },
1364};
1365
1366/**
1367 * DOC: property for adaptive backlight modulation
1368 *
1369 * The 'adaptive backlight modulation' property is used for the compositor to
1370 * directly control the adaptive backlight modulation power savings feature
1371 * that is part of DCN hardware.
1372 *
1373 * The property will be attached specifically to eDP panels that support it.
1374 *
1375 * The property is by default set to 'sysfs' to allow the sysfs file 'panel_power_savings'
1376 * to be able to control it.
1377 * If set to 'off' the compositor will ensure it stays off.
1378 * The other values 'min', 'bias min', 'bias max', and 'max' will control the
1379 * intensity of the power savings.
1380 *
1381 * Modifying this value can have implications on color accuracy, so tread
1382 * carefully.
1383 */
1384static int amdgpu_display_setup_abm_prop(struct amdgpu_device *adev)
1385{
1386	const struct drm_prop_enum_list props[] = {
1387		{ ABM_SYSFS_CONTROL, "sysfs" },
1388		{ ABM_LEVEL_OFF, "off" },
1389		{ ABM_LEVEL_MIN, "min" },
1390		{ ABM_LEVEL_BIAS_MIN, "bias min" },
1391		{ ABM_LEVEL_BIAS_MAX, "bias max" },
1392		{ ABM_LEVEL_MAX, "max" },
1393	};
1394	struct drm_property *prop;
1395	int i;
1396
1397	if (!adev->dc_enabled)
1398		return 0;
1399
1400	prop = drm_property_create(adev_to_drm(adev), DRM_MODE_PROP_ENUM,
1401				"adaptive backlight modulation",
1402				6);
1403	if (!prop)
1404		return -ENOMEM;
1405
1406	for (i = 0; i < ARRAY_SIZE(props); i++) {
1407		int ret;
1408
1409		ret = drm_property_add_enum(prop, props[i].type,
1410						props[i].name);
1411
1412		if (ret) {
1413			drm_property_destroy(adev_to_drm(adev), prop);
1414
1415			return ret;
1416		}
1417	}
1418
1419	adev->mode_info.abm_level_property = prop;
1420
1421	return 0;
1422}
1423
1424int amdgpu_display_modeset_create_props(struct amdgpu_device *adev)
1425{
1426	int sz;
1427
1428	adev->mode_info.coherent_mode_property =
1429		drm_property_create_range(adev_to_drm(adev), 0, "coherent", 0, 1);
1430	if (!adev->mode_info.coherent_mode_property)
1431		return -ENOMEM;
1432
1433	adev->mode_info.load_detect_property =
1434		drm_property_create_range(adev_to_drm(adev), 0, "load detection", 0, 1);
1435	if (!adev->mode_info.load_detect_property)
1436		return -ENOMEM;
1437
1438	drm_mode_create_scaling_mode_property(adev_to_drm(adev));
1439
1440	sz = ARRAY_SIZE(amdgpu_underscan_enum_list);
1441	adev->mode_info.underscan_property =
1442		drm_property_create_enum(adev_to_drm(adev), 0,
1443					 "underscan",
1444					 amdgpu_underscan_enum_list, sz);
1445
1446	adev->mode_info.underscan_hborder_property =
1447		drm_property_create_range(adev_to_drm(adev), 0,
1448					  "underscan hborder", 0, 128);
1449	if (!adev->mode_info.underscan_hborder_property)
1450		return -ENOMEM;
1451
1452	adev->mode_info.underscan_vborder_property =
1453		drm_property_create_range(adev_to_drm(adev), 0,
1454					  "underscan vborder", 0, 128);
1455	if (!adev->mode_info.underscan_vborder_property)
1456		return -ENOMEM;
1457
1458	sz = ARRAY_SIZE(amdgpu_audio_enum_list);
1459	adev->mode_info.audio_property =
1460		drm_property_create_enum(adev_to_drm(adev), 0,
1461					 "audio",
1462					 amdgpu_audio_enum_list, sz);
1463
1464	sz = ARRAY_SIZE(amdgpu_dither_enum_list);
1465	adev->mode_info.dither_property =
1466		drm_property_create_enum(adev_to_drm(adev), 0,
1467					 "dither",
1468					 amdgpu_dither_enum_list, sz);
1469
1470	return amdgpu_display_setup_abm_prop(adev);
1471}
1472
1473void amdgpu_display_update_priority(struct amdgpu_device *adev)
1474{
1475	/* adjustment options for the display watermarks */
1476	if ((amdgpu_disp_priority == 0) || (amdgpu_disp_priority > 2))
1477		adev->mode_info.disp_priority = 0;
1478	else
1479		adev->mode_info.disp_priority = amdgpu_disp_priority;
1480
1481}
1482
1483static bool amdgpu_display_is_hdtv_mode(const struct drm_display_mode *mode)
1484{
1485	/* try and guess if this is a tv or a monitor */
1486	if ((mode->vdisplay == 480 && mode->hdisplay == 720) || /* 480p */
1487	    (mode->vdisplay == 576) || /* 576p */
1488	    (mode->vdisplay == 720) || /* 720p */
1489	    (mode->vdisplay == 1080)) /* 1080p */
1490		return true;
1491	else
1492		return false;
1493}
1494
1495bool amdgpu_display_crtc_scaling_mode_fixup(struct drm_crtc *crtc,
1496					const struct drm_display_mode *mode,
1497					struct drm_display_mode *adjusted_mode)
1498{
1499	struct drm_device *dev = crtc->dev;
1500	struct drm_encoder *encoder;
1501	struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc);
1502	struct amdgpu_encoder *amdgpu_encoder;
1503	struct drm_connector *connector;
1504	u32 src_v = 1, dst_v = 1;
1505	u32 src_h = 1, dst_h = 1;
1506
1507	amdgpu_crtc->h_border = 0;
1508	amdgpu_crtc->v_border = 0;
1509
1510	list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
1511		if (encoder->crtc != crtc)
1512			continue;
1513		amdgpu_encoder = to_amdgpu_encoder(encoder);
1514		connector = amdgpu_get_connector_for_encoder(encoder);
1515
1516		/* set scaling */
1517		if (amdgpu_encoder->rmx_type == RMX_OFF)
1518			amdgpu_crtc->rmx_type = RMX_OFF;
1519		else if (mode->hdisplay < amdgpu_encoder->native_mode.hdisplay ||
1520			 mode->vdisplay < amdgpu_encoder->native_mode.vdisplay)
1521			amdgpu_crtc->rmx_type = amdgpu_encoder->rmx_type;
1522		else
1523			amdgpu_crtc->rmx_type = RMX_OFF;
1524		/* copy native mode */
1525		memcpy(&amdgpu_crtc->native_mode,
1526		       &amdgpu_encoder->native_mode,
1527		       sizeof(struct drm_display_mode));
1528		src_v = crtc->mode.vdisplay;
1529		dst_v = amdgpu_crtc->native_mode.vdisplay;
1530		src_h = crtc->mode.hdisplay;
1531		dst_h = amdgpu_crtc->native_mode.hdisplay;
1532
1533		/* fix up for overscan on hdmi */
1534		if ((!(mode->flags & DRM_MODE_FLAG_INTERLACE)) &&
1535		    ((amdgpu_encoder->underscan_type == UNDERSCAN_ON) ||
1536		     ((amdgpu_encoder->underscan_type == UNDERSCAN_AUTO) &&
1537		      connector && connector->display_info.is_hdmi &&
1538		      amdgpu_display_is_hdtv_mode(mode)))) {
1539			if (amdgpu_encoder->underscan_hborder != 0)
1540				amdgpu_crtc->h_border = amdgpu_encoder->underscan_hborder;
1541			else
1542				amdgpu_crtc->h_border = (mode->hdisplay >> 5) + 16;
1543			if (amdgpu_encoder->underscan_vborder != 0)
1544				amdgpu_crtc->v_border = amdgpu_encoder->underscan_vborder;
1545			else
1546				amdgpu_crtc->v_border = (mode->vdisplay >> 5) + 16;
1547			amdgpu_crtc->rmx_type = RMX_FULL;
1548			src_v = crtc->mode.vdisplay;
1549			dst_v = crtc->mode.vdisplay - (amdgpu_crtc->v_border * 2);
1550			src_h = crtc->mode.hdisplay;
1551			dst_h = crtc->mode.hdisplay - (amdgpu_crtc->h_border * 2);
1552		}
1553	}
1554	if (amdgpu_crtc->rmx_type != RMX_OFF) {
1555		fixed20_12 a, b;
1556
1557		a.full = dfixed_const(src_v);
1558		b.full = dfixed_const(dst_v);
1559		amdgpu_crtc->vsc.full = dfixed_div(a, b);
1560		a.full = dfixed_const(src_h);
1561		b.full = dfixed_const(dst_h);
1562		amdgpu_crtc->hsc.full = dfixed_div(a, b);
1563	} else {
1564		amdgpu_crtc->vsc.full = dfixed_const(1);
1565		amdgpu_crtc->hsc.full = dfixed_const(1);
1566	}
1567	return true;
1568}
1569
1570/*
1571 * Retrieve current video scanout position of crtc on a given gpu, and
1572 * an optional accurate timestamp of when query happened.
1573 *
1574 * \param dev Device to query.
1575 * \param pipe Crtc to query.
1576 * \param flags from caller (DRM_CALLED_FROM_VBLIRQ or 0).
1577 *              For driver internal use only also supports these flags:
1578 *
1579 *              USE_REAL_VBLANKSTART to use the real start of vblank instead
1580 *              of a fudged earlier start of vblank.
1581 *
1582 *              GET_DISTANCE_TO_VBLANKSTART to return distance to the
1583 *              fudged earlier start of vblank in *vpos and the distance
1584 *              to true start of vblank in *hpos.
1585 *
1586 * \param *vpos Location where vertical scanout position should be stored.
1587 * \param *hpos Location where horizontal scanout position should go.
1588 * \param *stime Target location for timestamp taken immediately before
1589 *               scanout position query. Can be NULL to skip timestamp.
1590 * \param *etime Target location for timestamp taken immediately after
1591 *               scanout position query. Can be NULL to skip timestamp.
1592 *
1593 * Returns vpos as a positive number while in active scanout area.
1594 * Returns vpos as a negative number inside vblank, counting the number
1595 * of scanlines to go until end of vblank, e.g., -1 means "one scanline
1596 * until start of active scanout / end of vblank."
1597 *
1598 * \return Flags, or'ed together as follows:
1599 *
1600 * DRM_SCANOUTPOS_VALID = Query successful.
1601 * DRM_SCANOUTPOS_INVBL = Inside vblank.
1602 * DRM_SCANOUTPOS_ACCURATE = Returned position is accurate. A lack of
1603 * this flag means that returned position may be offset by a constant but
1604 * unknown small number of scanlines wrt. real scanout position.
1605 *
1606 */
1607int amdgpu_display_get_crtc_scanoutpos(struct drm_device *dev,
1608			unsigned int pipe, unsigned int flags, int *vpos,
1609			int *hpos, ktime_t *stime, ktime_t *etime,
1610			const struct drm_display_mode *mode)
1611{
1612	u32 vbl = 0, position = 0;
1613	int vbl_start, vbl_end, vtotal, ret = 0;
1614	bool in_vbl = true;
1615
1616	struct amdgpu_device *adev = drm_to_adev(dev);
1617
1618	/* preempt_disable_rt() should go right here in PREEMPT_RT patchset. */
1619
1620	/* Get optional system timestamp before query. */
1621	if (stime)
1622		*stime = ktime_get();
1623
1624	if (amdgpu_display_page_flip_get_scanoutpos(adev, pipe, &vbl, &position) == 0)
1625		ret |= DRM_SCANOUTPOS_VALID;
1626
1627	/* Get optional system timestamp after query. */
1628	if (etime)
1629		*etime = ktime_get();
1630
1631	/* preempt_enable_rt() should go right here in PREEMPT_RT patchset. */
1632
1633	/* Decode into vertical and horizontal scanout position. */
1634	*vpos = position & 0x1fff;
1635	*hpos = (position >> 16) & 0x1fff;
1636
1637	/* Valid vblank area boundaries from gpu retrieved? */
1638	if (vbl > 0) {
1639		/* Yes: Decode. */
1640		ret |= DRM_SCANOUTPOS_ACCURATE;
1641		vbl_start = vbl & 0x1fff;
1642		vbl_end = (vbl >> 16) & 0x1fff;
1643	} else {
1644		/* No: Fake something reasonable which gives at least ok results. */
1645		vbl_start = mode->crtc_vdisplay;
1646		vbl_end = 0;
1647	}
1648
1649	/* Called from driver internal vblank counter query code? */
1650	if (flags & GET_DISTANCE_TO_VBLANKSTART) {
1651		/* Caller wants distance from real vbl_start in *hpos */
1652		*hpos = *vpos - vbl_start;
1653	}
1654
1655	/* Fudge vblank to start a few scanlines earlier to handle the
1656	 * problem that vblank irqs fire a few scanlines before start
1657	 * of vblank. Some driver internal callers need the true vblank
1658	 * start to be used and signal this via the USE_REAL_VBLANKSTART flag.
1659	 *
1660	 * The cause of the "early" vblank irq is that the irq is triggered
1661	 * by the line buffer logic when the line buffer read position enters
1662	 * the vblank, whereas our crtc scanout position naturally lags the
1663	 * line buffer read position.
1664	 */
1665	if (!(flags & USE_REAL_VBLANKSTART))
1666		vbl_start -= adev->mode_info.crtcs[pipe]->lb_vblank_lead_lines;
1667
1668	/* Test scanout position against vblank region. */
1669	if ((*vpos < vbl_start) && (*vpos >= vbl_end))
1670		in_vbl = false;
1671
1672	/* In vblank? */
1673	if (in_vbl)
1674		ret |= DRM_SCANOUTPOS_IN_VBLANK;
1675
1676	/* Called from driver internal vblank counter query code? */
1677	if (flags & GET_DISTANCE_TO_VBLANKSTART) {
1678		/* Caller wants distance from fudged earlier vbl_start */
1679		*vpos -= vbl_start;
1680		return ret;
1681	}
1682
1683	/* Check if inside vblank area and apply corrective offsets:
1684	 * vpos will then be >=0 in video scanout area, but negative
1685	 * within vblank area, counting down the number of lines until
1686	 * start of scanout.
1687	 */
1688
1689	/* Inside "upper part" of vblank area? Apply corrective offset if so: */
1690	if (in_vbl && (*vpos >= vbl_start)) {
1691		vtotal = mode->crtc_vtotal;
1692
1693		/* With variable refresh rate displays the vpos can exceed
1694		 * the vtotal value. Clamp to 0 to return -vbl_end instead
1695		 * of guessing the remaining number of lines until scanout.
1696		 */
1697		*vpos = (*vpos < vtotal) ? (*vpos - vtotal) : 0;
1698	}
1699
1700	/* Correct for shifted end of vbl at vbl_end. */
1701	*vpos = *vpos - vbl_end;
1702
1703	return ret;
1704}
1705
1706int amdgpu_display_crtc_idx_to_irq_type(struct amdgpu_device *adev, int crtc)
1707{
1708	if (crtc < 0 || crtc >= adev->mode_info.num_crtc)
1709		return AMDGPU_CRTC_IRQ_NONE;
1710
1711	switch (crtc) {
1712	case 0:
1713		return AMDGPU_CRTC_IRQ_VBLANK1;
1714	case 1:
1715		return AMDGPU_CRTC_IRQ_VBLANK2;
1716	case 2:
1717		return AMDGPU_CRTC_IRQ_VBLANK3;
1718	case 3:
1719		return AMDGPU_CRTC_IRQ_VBLANK4;
1720	case 4:
1721		return AMDGPU_CRTC_IRQ_VBLANK5;
1722	case 5:
1723		return AMDGPU_CRTC_IRQ_VBLANK6;
1724	default:
1725		return AMDGPU_CRTC_IRQ_NONE;
1726	}
1727}
1728
1729bool amdgpu_crtc_get_scanout_position(struct drm_crtc *crtc,
1730			bool in_vblank_irq, int *vpos,
1731			int *hpos, ktime_t *stime, ktime_t *etime,
1732			const struct drm_display_mode *mode)
1733{
1734	struct drm_device *dev = crtc->dev;
1735	unsigned int pipe = crtc->index;
1736
1737	return amdgpu_display_get_crtc_scanoutpos(dev, pipe, 0, vpos, hpos,
1738						  stime, etime, mode);
1739}
1740
1741static bool
1742amdgpu_display_robj_is_fb(struct amdgpu_device *adev, struct amdgpu_bo *robj)
1743{
1744	struct drm_device *dev = adev_to_drm(adev);
1745	struct drm_fb_helper *fb_helper = dev->fb_helper;
1746
1747	if (!fb_helper || !fb_helper->buffer)
1748		return false;
1749
1750	if (gem_to_amdgpu_bo(fb_helper->buffer->gem) != robj)
1751		return false;
1752
1753	return true;
1754}
1755
1756int amdgpu_display_suspend_helper(struct amdgpu_device *adev)
1757{
1758	struct drm_device *dev = adev_to_drm(adev);
1759	struct drm_crtc *crtc;
1760	struct drm_connector *connector;
1761	struct drm_connector_list_iter iter;
1762	int r;
1763
1764	drm_kms_helper_poll_disable(dev);
1765
1766	/* turn off display hw */
1767	drm_modeset_lock_all(dev);
1768	drm_connector_list_iter_begin(dev, &iter);
1769	drm_for_each_connector_iter(connector, &iter)
1770		drm_helper_connector_dpms(connector,
1771					  DRM_MODE_DPMS_OFF);
1772	drm_connector_list_iter_end(&iter);
1773	drm_modeset_unlock_all(dev);
1774	/* unpin the front buffers and cursors */
1775	list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
1776		struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc);
1777		struct drm_framebuffer *fb = crtc->primary->fb;
1778		struct amdgpu_bo *robj;
1779
1780		if (amdgpu_crtc->cursor_bo && !adev->enable_virtual_display) {
1781			struct amdgpu_bo *aobj = gem_to_amdgpu_bo(amdgpu_crtc->cursor_bo);
1782
1783			r = amdgpu_bo_reserve(aobj, true);
1784			if (r == 0) {
1785				amdgpu_bo_unpin(aobj);
1786				amdgpu_bo_unreserve(aobj);
1787			}
1788		}
1789
1790		if (!fb || !fb->obj[0])
1791			continue;
1792
1793		robj = gem_to_amdgpu_bo(fb->obj[0]);
1794		if (!amdgpu_display_robj_is_fb(adev, robj)) {
1795			r = amdgpu_bo_reserve(robj, true);
1796			if (r == 0) {
1797				amdgpu_bo_unpin(robj);
1798				amdgpu_bo_unreserve(robj);
1799			}
1800		}
1801	}
1802	return 0;
1803}
1804
1805int amdgpu_display_resume_helper(struct amdgpu_device *adev)
1806{
1807	struct drm_device *dev = adev_to_drm(adev);
1808	struct drm_connector *connector;
1809	struct drm_connector_list_iter iter;
1810	struct drm_crtc *crtc;
1811	int r;
1812
1813	/* pin cursors */
1814	list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
1815		struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc);
1816
1817		if (amdgpu_crtc->cursor_bo && !adev->enable_virtual_display) {
1818			struct amdgpu_bo *aobj = gem_to_amdgpu_bo(amdgpu_crtc->cursor_bo);
1819
1820			r = amdgpu_bo_reserve(aobj, true);
1821			if (r == 0) {
1822				aobj->flags |= AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS;
1823				r = amdgpu_bo_pin(aobj, AMDGPU_GEM_DOMAIN_VRAM);
1824				if (r != 0)
1825					dev_err(adev->dev, "Failed to pin cursor BO (%d)\n", r);
1826				amdgpu_crtc->cursor_addr = amdgpu_bo_gpu_offset(aobj);
1827				amdgpu_bo_unreserve(aobj);
1828			}
1829		}
1830	}
1831
1832	drm_helper_resume_force_mode(dev);
1833
1834	/* turn on display hw */
1835	drm_modeset_lock_all(dev);
1836
1837	drm_connector_list_iter_begin(dev, &iter);
1838	drm_for_each_connector_iter(connector, &iter)
1839		drm_helper_connector_dpms(connector,
1840					  DRM_MODE_DPMS_ON);
1841	drm_connector_list_iter_end(&iter);
1842
1843	drm_modeset_unlock_all(dev);
1844
1845	drm_kms_helper_poll_enable(dev);
1846
1847	return 0;
1848}
1849
1850/* panic_bo is set in amdgpu_dm_plane_get_scanout_buffer() and only used in amdgpu_dm_set_pixel()
1851 * they are called from the panic handler, and protected by the drm_panic spinlock.
1852 */
1853static struct amdgpu_bo *panic_abo;
1854
1855/* Use the indirect MMIO to write each pixel to the GPU VRAM,
1856 * This is a simplified version of amdgpu_device_mm_access()
1857 */
1858static void amdgpu_display_set_pixel(struct drm_scanout_buffer *sb,
1859				     unsigned int x,
1860				     unsigned int y,
1861				     u32 color)
1862{
1863	struct amdgpu_res_cursor cursor;
1864	unsigned long offset;
1865	struct amdgpu_bo *abo = panic_abo;
1866	struct amdgpu_device *adev = amdgpu_ttm_adev(abo->tbo.bdev);
1867	uint32_t tmp;
1868
1869	offset = x * 4 + y * sb->pitch[0];
1870	amdgpu_res_first(abo->tbo.resource, offset, 4, &cursor);
1871
1872	tmp = cursor.start >> 31;
1873	WREG32_NO_KIQ(mmMM_INDEX, ((uint32_t) cursor.start) | 0x80000000);
1874	if (tmp != 0xffffffff)
1875		WREG32_NO_KIQ(mmMM_INDEX_HI, tmp);
1876	WREG32_NO_KIQ(mmMM_DATA, color);
1877}
1878
1879int amdgpu_display_get_scanout_buffer(struct drm_plane *plane,
1880				      struct drm_scanout_buffer *sb)
1881{
1882	struct amdgpu_bo *abo;
1883	struct drm_framebuffer *fb;
1884
1885	if (drm_drv_uses_atomic_modeset(plane->dev))
1886		fb = plane->state->fb;
1887	else
1888		fb = plane->fb;
1889
1890	if (!fb)
1891		return -EINVAL;
1892
1893	DRM_DEBUG_KMS("Framebuffer %dx%d %p4cc\n", fb->width, fb->height, &fb->format->format);
1894
1895	abo = gem_to_amdgpu_bo(fb->obj[0]);
1896	if (!abo)
1897		return -EINVAL;
1898
1899	sb->width = fb->width;
1900	sb->height = fb->height;
1901	/* Use the generic linear format, because tiling will be disabled in panic_flush() */
1902	sb->format = drm_format_info(fb->format->format);
1903	if (!sb->format)
1904		return -EINVAL;
1905
1906	sb->pitch[0] = fb->pitches[0];
1907
1908	if (abo->flags & AMDGPU_GEM_CREATE_NO_CPU_ACCESS) {
1909		if (abo->tbo.resource->mem_type != TTM_PL_VRAM) {
1910			drm_warn(plane->dev, "amdgpu panic, framebuffer not in VRAM\n");
1911			return -EINVAL;
1912		}
1913		/* Only handle 32bits format, to simplify mmio access */
1914		if (fb->format->cpp[0] != 4) {
1915			drm_warn(plane->dev, "amdgpu panic, pixel format is not 32bits\n");
1916			return -EINVAL;
1917		}
1918		sb->set_pixel = amdgpu_display_set_pixel;
1919		panic_abo = abo;
1920		return 0;
1921	}
1922	if (!abo->kmap.virtual &&
1923	    ttm_bo_kmap(&abo->tbo, 0, PFN_UP(abo->tbo.base.size), &abo->kmap)) {
1924		drm_warn(plane->dev, "amdgpu bo map failed, panic won't be displayed\n");
1925		return -ENOMEM;
1926	}
1927	if (abo->kmap.bo_kmap_type & TTM_BO_MAP_IOMEM_MASK)
1928		iosys_map_set_vaddr_iomem(&sb->map[0], abo->kmap.virtual);
1929	else
1930		iosys_map_set_vaddr(&sb->map[0], abo->kmap.virtual);
1931
1932	return 0;
1933}
~/ Read-only file preview.