cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

test-drm_damage_helper.c (19432B)


      1// SPDX-License-Identifier: GPL-2.0
      2/*
      3 * Test case for drm_damage_helper functions
      4 */
      5
      6#define pr_fmt(fmt) "drm_damage_helper: " fmt
      7
      8#include <drm/drm_damage_helper.h>
      9#include <drm/drm_plane.h>
     10#include <drm/drm_drv.h>
     11
     12#include "test-drm_modeset_common.h"
     13
     14struct drm_driver mock_driver;
     15static struct drm_device mock_device;
     16static struct drm_object_properties mock_obj_props;
     17static struct drm_plane mock_plane;
     18static struct drm_property mock_prop;
     19
     20static void mock_setup(struct drm_plane_state *state)
     21{
     22	static bool setup_done = false;
     23
     24	state->plane = &mock_plane;
     25
     26	if (setup_done)
     27		return;
     28
     29	/* just enough so that drm_plane_enable_fb_damage_clips() works */
     30	mock_device.driver = &mock_driver;
     31	mock_device.mode_config.prop_fb_damage_clips = &mock_prop;
     32	mock_plane.dev = &mock_device;
     33	mock_obj_props.count = 0;
     34	mock_plane.base.properties = &mock_obj_props;
     35	mock_prop.base.id = 1; /* 0 is an invalid id */
     36	mock_prop.dev = &mock_device;
     37
     38	drm_plane_enable_fb_damage_clips(&mock_plane);
     39}
     40
     41static void set_plane_src(struct drm_plane_state *state, int x1, int y1, int x2,
     42			  int y2)
     43{
     44	state->src.x1 = x1;
     45	state->src.y1 = y1;
     46	state->src.x2 = x2;
     47	state->src.y2 = y2;
     48}
     49
     50static void set_damage_clip(struct drm_mode_rect *r, int x1, int y1, int x2,
     51			    int y2)
     52{
     53	r->x1 = x1;
     54	r->y1 = y1;
     55	r->x2 = x2;
     56	r->y2 = y2;
     57}
     58
     59static void set_damage_blob(struct drm_property_blob *damage_blob,
     60			    struct drm_mode_rect *r, uint32_t size)
     61{
     62	damage_blob->length = size;
     63	damage_blob->data = r;
     64}
     65
     66static void set_plane_damage(struct drm_plane_state *state,
     67			     struct drm_property_blob *damage_blob)
     68{
     69	state->fb_damage_clips = damage_blob;
     70}
     71
     72static bool check_damage_clip(struct drm_plane_state *state, struct drm_rect *r,
     73			      int x1, int y1, int x2, int y2)
     74{
     75	/*
     76	 * Round down x1/y1 and round up x2/y2. This is because damage is not in
     77	 * 16.16 fixed point so to catch all pixels.
     78	 */
     79	int src_x1 = state->src.x1 >> 16;
     80	int src_y1 = state->src.y1 >> 16;
     81	int src_x2 = (state->src.x2 >> 16) + !!(state->src.x2 & 0xFFFF);
     82	int src_y2 = (state->src.y2 >> 16) + !!(state->src.y2 & 0xFFFF);
     83
     84	if (x1 >= x2 || y1 >= y2) {
     85		pr_err("Cannot have damage clip with no dimension.\n");
     86		return false;
     87	}
     88
     89	if (x1 < src_x1 || y1 < src_y1 || x2 > src_x2 || y2 > src_y2) {
     90		pr_err("Damage cannot be outside rounded plane src.\n");
     91		return false;
     92	}
     93
     94	if (r->x1 != x1 || r->y1 != y1 || r->x2 != x2 || r->y2 != y2) {
     95		pr_err("Damage = %d %d %d %d\n", r->x1, r->y1, r->x2, r->y2);
     96		return false;
     97	}
     98
     99	return true;
    100}
    101
    102const struct drm_framebuffer fb = {
    103	.width = 2048,
    104	.height = 2048
    105};
    106
    107/* common mocked structs many tests need */
    108#define MOCK_VARIABLES() \
    109	struct drm_plane_state old_state; \
    110	struct drm_plane_state state = { \
    111		.crtc = ZERO_SIZE_PTR, \
    112		.fb = (struct drm_framebuffer *) &fb, \
    113		.visible = true, \
    114	}; \
    115	mock_setup(&old_state); \
    116	mock_setup(&state);
    117
    118int igt_damage_iter_no_damage(void *ignored)
    119{
    120	struct drm_atomic_helper_damage_iter iter;
    121	struct drm_rect clip;
    122	uint32_t num_hits = 0;
    123
    124	MOCK_VARIABLES();
    125
    126	/* Plane src same as fb size. */
    127	set_plane_src(&old_state, 0, 0, fb.width << 16, fb.height << 16);
    128	set_plane_src(&state, 0, 0, fb.width << 16, fb.height << 16);
    129	drm_atomic_helper_damage_iter_init(&iter, &old_state, &state);
    130	drm_atomic_for_each_plane_damage(&iter, &clip)
    131		num_hits++;
    132
    133	FAIL(num_hits != 1, "Should return plane src as damage.");
    134	FAIL_ON(!check_damage_clip(&state, &clip, 0, 0, 2048, 2048));
    135
    136	return 0;
    137}
    138
    139int igt_damage_iter_no_damage_fractional_src(void *ignored)
    140{
    141	struct drm_atomic_helper_damage_iter iter;
    142	struct drm_rect clip;
    143	uint32_t num_hits = 0;
    144
    145	MOCK_VARIABLES();
    146
    147	/* Plane src has fractional part. */
    148	set_plane_src(&old_state, 0x3fffe, 0x3fffe,
    149		      0x3fffe + (1024 << 16), 0x3fffe + (768 << 16));
    150	set_plane_src(&state, 0x3fffe, 0x3fffe,
    151		      0x3fffe + (1024 << 16), 0x3fffe + (768 << 16));
    152	drm_atomic_helper_damage_iter_init(&iter, &old_state, &state);
    153	drm_atomic_for_each_plane_damage(&iter, &clip)
    154		num_hits++;
    155
    156	FAIL(num_hits != 1, "Should return rounded off plane src as damage.");
    157	FAIL_ON(!check_damage_clip(&state, &clip, 3, 3, 1028, 772));
    158
    159	return 0;
    160}
    161
    162int igt_damage_iter_no_damage_src_moved(void *ignored)
    163{
    164	struct drm_atomic_helper_damage_iter iter;
    165	struct drm_rect clip;
    166	uint32_t num_hits = 0;
    167
    168	MOCK_VARIABLES();
    169
    170	/* Plane src moved since old plane state. */
    171	set_plane_src(&old_state, 0, 0, 1024 << 16, 768 << 16);
    172	set_plane_src(&state, 10 << 16, 10 << 16,
    173		      (10 + 1024) << 16, (10 + 768) << 16);
    174	drm_atomic_helper_damage_iter_init(&iter, &old_state, &state);
    175	drm_atomic_for_each_plane_damage(&iter, &clip)
    176		num_hits++;
    177
    178	FAIL(num_hits != 1, "Should return plane src as damage.");
    179	FAIL_ON(!check_damage_clip(&state, &clip, 10, 10, 1034, 778));
    180
    181	return 0;
    182}
    183
    184int igt_damage_iter_no_damage_fractional_src_moved(void *ignored)
    185{
    186	struct drm_atomic_helper_damage_iter iter;
    187	struct drm_rect clip;
    188	uint32_t num_hits = 0;
    189
    190	MOCK_VARIABLES();
    191
    192	/* Plane src has fractional part and it moved since old plane state. */
    193	set_plane_src(&old_state, 0x3fffe, 0x3fffe,
    194		      0x3fffe + (1024 << 16), 0x3fffe + (768 << 16));
    195	set_plane_src(&state, 0x40002, 0x40002,
    196		      0x40002 + (1024 << 16), 0x40002 + (768 << 16));
    197	drm_atomic_helper_damage_iter_init(&iter, &old_state, &state);
    198	drm_atomic_for_each_plane_damage(&iter, &clip)
    199		num_hits++;
    200
    201	FAIL(num_hits != 1, "Should return plane src as damage.");
    202	FAIL_ON(!check_damage_clip(&state, &clip, 4, 4, 1029, 773));
    203
    204	return 0;
    205}
    206
    207int igt_damage_iter_no_damage_not_visible(void *ignored)
    208{
    209	struct drm_atomic_helper_damage_iter iter;
    210	struct drm_rect clip;
    211	uint32_t num_hits = 0;
    212
    213	MOCK_VARIABLES();
    214
    215	state.visible = false;
    216
    217	mock_setup(&old_state);
    218
    219	set_plane_src(&old_state, 0, 0, 1024 << 16, 768 << 16);
    220	set_plane_src(&state, 0, 0, 1024 << 16, 768 << 16);
    221	drm_atomic_helper_damage_iter_init(&iter, &old_state, &state);
    222	drm_atomic_for_each_plane_damage(&iter, &clip)
    223		num_hits++;
    224
    225	FAIL(num_hits != 0, "Should have no damage.");
    226
    227	return 0;
    228}
    229
    230int igt_damage_iter_no_damage_no_crtc(void *ignored)
    231{
    232	struct drm_atomic_helper_damage_iter iter;
    233	struct drm_rect clip;
    234	uint32_t num_hits = 0;
    235
    236	MOCK_VARIABLES();
    237
    238	state.crtc = NULL;
    239
    240	set_plane_src(&old_state, 0, 0, 1024 << 16, 768 << 16);
    241	set_plane_src(&state, 0, 0, 1024 << 16, 768 << 16);
    242	drm_atomic_helper_damage_iter_init(&iter, &old_state, &state);
    243	drm_atomic_for_each_plane_damage(&iter, &clip)
    244		num_hits++;
    245
    246	FAIL(num_hits != 0, "Should have no damage.");
    247
    248	return 0;
    249}
    250
    251int igt_damage_iter_no_damage_no_fb(void *ignored)
    252{
    253	struct drm_atomic_helper_damage_iter iter;
    254	struct drm_plane_state old_state;
    255	struct drm_rect clip;
    256	uint32_t num_hits = 0;
    257
    258	struct drm_plane_state state = {
    259		.crtc = ZERO_SIZE_PTR,
    260		.fb = 0,
    261	};
    262
    263	mock_setup(&old_state);
    264
    265	set_plane_src(&old_state, 0, 0, 1024 << 16, 768 << 16);
    266	set_plane_src(&state, 0, 0, 1024 << 16, 768 << 16);
    267	drm_atomic_helper_damage_iter_init(&iter, &old_state, &state);
    268	drm_atomic_for_each_plane_damage(&iter, &clip)
    269		num_hits++;
    270
    271	FAIL(num_hits != 0, "Should have no damage.");
    272
    273	return 0;
    274}
    275
    276int igt_damage_iter_simple_damage(void *ignored)
    277{
    278	struct drm_atomic_helper_damage_iter iter;
    279	struct drm_property_blob damage_blob;
    280	struct drm_mode_rect damage;
    281	struct drm_rect clip;
    282	uint32_t num_hits = 0;
    283
    284	MOCK_VARIABLES();
    285
    286	set_plane_src(&old_state, 0, 0, 1024 << 16, 768 << 16);
    287	set_plane_src(&state, 0, 0, 1024 << 16, 768 << 16);
    288	/* Damage set to plane src */
    289	set_damage_clip(&damage, 0, 0, 1024, 768);
    290	set_damage_blob(&damage_blob, &damage, sizeof(damage));
    291	set_plane_damage(&state, &damage_blob);
    292	drm_atomic_helper_damage_iter_init(&iter, &old_state, &state);
    293	drm_atomic_for_each_plane_damage(&iter, &clip)
    294		num_hits++;
    295
    296	FAIL(num_hits != 1, "Should return damage when set.");
    297	FAIL_ON(!check_damage_clip(&state, &clip, 0, 0, 1024, 768));
    298
    299	return 0;
    300}
    301
    302int igt_damage_iter_single_damage(void *ignored)
    303{
    304	struct drm_atomic_helper_damage_iter iter;
    305	struct drm_property_blob damage_blob;
    306	struct drm_mode_rect damage;
    307	struct drm_rect clip;
    308	uint32_t num_hits = 0;
    309
    310	MOCK_VARIABLES();
    311
    312	set_plane_src(&old_state, 0, 0, 1024 << 16, 768 << 16);
    313	set_plane_src(&state, 0, 0, 1024 << 16, 768 << 16);
    314	set_damage_clip(&damage, 256, 192, 768, 576);
    315	set_damage_blob(&damage_blob, &damage, sizeof(damage));
    316	set_plane_damage(&state, &damage_blob);
    317	drm_atomic_helper_damage_iter_init(&iter, &old_state, &state);
    318	drm_atomic_for_each_plane_damage(&iter, &clip)
    319		num_hits++;
    320
    321	FAIL(num_hits != 1, "Should return damage when set.");
    322	FAIL_ON(!check_damage_clip(&state, &clip, 256, 192, 768, 576));
    323
    324	return 0;
    325}
    326
    327int igt_damage_iter_single_damage_intersect_src(void *ignored)
    328{
    329	struct drm_atomic_helper_damage_iter iter;
    330	struct drm_property_blob damage_blob;
    331	struct drm_mode_rect damage;
    332	struct drm_rect clip;
    333	uint32_t num_hits = 0;
    334
    335	MOCK_VARIABLES();
    336
    337	set_plane_src(&old_state, 0, 0, 1024 << 16, 768 << 16);
    338	set_plane_src(&state, 0, 0, 1024 << 16, 768 << 16);
    339	/* Damage intersect with plane src. */
    340	set_damage_clip(&damage, 256, 192, 1360, 768);
    341	set_damage_blob(&damage_blob, &damage, sizeof(damage));
    342	set_plane_damage(&state, &damage_blob);
    343	drm_atomic_helper_damage_iter_init(&iter, &old_state, &state);
    344	drm_atomic_for_each_plane_damage(&iter, &clip)
    345		num_hits++;
    346
    347	FAIL(num_hits != 1, "Should return damage clipped to src.");
    348	FAIL_ON(!check_damage_clip(&state, &clip, 256, 192, 1024, 768));
    349
    350	return 0;
    351}
    352
    353int igt_damage_iter_single_damage_outside_src(void *ignored)
    354{
    355	struct drm_atomic_helper_damage_iter iter;
    356	struct drm_property_blob damage_blob;
    357	struct drm_mode_rect damage;
    358	struct drm_rect clip;
    359	uint32_t num_hits = 0;
    360
    361	MOCK_VARIABLES();
    362
    363	set_plane_src(&old_state, 0, 0, 1024 << 16, 768 << 16);
    364	set_plane_src(&state, 0, 0, 1024 << 16, 768 << 16);
    365	/* Damage clip outside plane src */
    366	set_damage_clip(&damage, 1360, 1360, 1380, 1380);
    367	set_damage_blob(&damage_blob, &damage, sizeof(damage));
    368	set_plane_damage(&state, &damage_blob);
    369	drm_atomic_helper_damage_iter_init(&iter, &old_state, &state);
    370	drm_atomic_for_each_plane_damage(&iter, &clip)
    371		num_hits++;
    372
    373	FAIL(num_hits != 0, "Should have no damage.");
    374
    375	return 0;
    376}
    377
    378int igt_damage_iter_single_damage_fractional_src(void *ignored)
    379{
    380	struct drm_atomic_helper_damage_iter iter;
    381	struct drm_property_blob damage_blob;
    382	struct drm_mode_rect damage;
    383	struct drm_rect clip;
    384	uint32_t num_hits = 0;
    385
    386	MOCK_VARIABLES();
    387
    388	/* Plane src has fractional part. */
    389	set_plane_src(&old_state, 0x40002, 0x40002,
    390		      0x40002 + (1024 << 16), 0x40002 + (768 << 16));
    391	set_plane_src(&state, 0x40002, 0x40002,
    392		      0x40002 + (1024 << 16), 0x40002 + (768 << 16));
    393	set_damage_clip(&damage, 10, 10, 256, 330);
    394	set_damage_blob(&damage_blob, &damage, sizeof(damage));
    395	set_plane_damage(&state, &damage_blob);
    396	drm_atomic_helper_damage_iter_init(&iter, &old_state, &state);
    397	drm_atomic_for_each_plane_damage(&iter, &clip)
    398		num_hits++;
    399
    400	FAIL(num_hits != 1, "Should return damage when set.");
    401	FAIL_ON(!check_damage_clip(&state, &clip, 10, 10, 256, 330));
    402
    403	return 0;
    404}
    405
    406int igt_damage_iter_single_damage_intersect_fractional_src(void *ignored)
    407{
    408	struct drm_atomic_helper_damage_iter iter;
    409	struct drm_property_blob damage_blob;
    410	struct drm_mode_rect damage;
    411	struct drm_rect clip;
    412	uint32_t num_hits = 0;
    413
    414	MOCK_VARIABLES();
    415
    416	/* Plane src has fractional part. */
    417	set_plane_src(&old_state, 0x40002, 0x40002,
    418		      0x40002 + (1024 << 16), 0x40002 + (768 << 16));
    419	set_plane_src(&state, 0x40002, 0x40002,
    420		      0x40002 + (1024 << 16), 0x40002 + (768 << 16));
    421	/* Damage intersect with plane src. */
    422	set_damage_clip(&damage, 10, 1, 1360, 330);
    423	set_damage_blob(&damage_blob, &damage, sizeof(damage));
    424	set_plane_damage(&state, &damage_blob);
    425	drm_atomic_helper_damage_iter_init(&iter, &old_state, &state);
    426	drm_atomic_for_each_plane_damage(&iter, &clip)
    427		num_hits++;
    428
    429	FAIL(num_hits != 1, "Should return damage clipped to rounded off src.");
    430	FAIL_ON(!check_damage_clip(&state, &clip, 10, 4, 1029, 330));
    431
    432	return 0;
    433}
    434
    435int igt_damage_iter_single_damage_outside_fractional_src(void *ignored)
    436{
    437	struct drm_atomic_helper_damage_iter iter;
    438	struct drm_property_blob damage_blob;
    439	struct drm_mode_rect damage;
    440	struct drm_rect clip;
    441	uint32_t num_hits = 0;
    442
    443	MOCK_VARIABLES();
    444
    445	/* Plane src has fractional part. */
    446	set_plane_src(&old_state, 0x40002, 0x40002,
    447		      0x40002 + (1024 << 16), 0x40002 + (768 << 16));
    448	set_plane_src(&state, 0x40002, 0x40002,
    449		      0x40002 + (1024 << 16), 0x40002 + (768 << 16));
    450	/* Damage clip outside plane src */
    451	set_damage_clip(&damage, 1360, 1360, 1380, 1380);
    452	set_damage_blob(&damage_blob, &damage, sizeof(damage));
    453	set_plane_damage(&state, &damage_blob);
    454	drm_atomic_helper_damage_iter_init(&iter, &old_state, &state);
    455	drm_atomic_for_each_plane_damage(&iter, &clip)
    456		num_hits++;
    457
    458	FAIL(num_hits != 0, "Should have no damage.");
    459
    460	return 0;
    461}
    462
    463int igt_damage_iter_single_damage_src_moved(void *ignored)
    464{
    465	struct drm_atomic_helper_damage_iter iter;
    466	struct drm_property_blob damage_blob;
    467	struct drm_mode_rect damage;
    468	struct drm_rect clip;
    469	uint32_t num_hits = 0;
    470
    471	MOCK_VARIABLES();
    472
    473	/* Plane src moved since old plane state. */
    474	set_plane_src(&old_state, 0, 0, 1024 << 16, 768 << 16);
    475	set_plane_src(&state, 10 << 16, 10 << 16,
    476		      (10 + 1024) << 16, (10 + 768) << 16);
    477	set_damage_clip(&damage, 20, 30, 256, 256);
    478	set_damage_blob(&damage_blob, &damage, sizeof(damage));
    479	set_plane_damage(&state, &damage_blob);
    480	drm_atomic_helper_damage_iter_init(&iter, &old_state, &state);
    481	drm_atomic_for_each_plane_damage(&iter, &clip)
    482		num_hits++;
    483
    484	FAIL(num_hits != 1, "Should return plane src as damage.");
    485	FAIL_ON(!check_damage_clip(&state, &clip, 10, 10, 1034, 778));
    486
    487	return 0;
    488}
    489
    490int igt_damage_iter_single_damage_fractional_src_moved(void *ignored)
    491{
    492	struct drm_atomic_helper_damage_iter iter;
    493	struct drm_property_blob damage_blob;
    494	struct drm_mode_rect damage;
    495	struct drm_rect clip;
    496	uint32_t num_hits = 0;
    497
    498	MOCK_VARIABLES();
    499
    500	/* Plane src with fractional part moved since old plane state. */
    501	set_plane_src(&old_state, 0x3fffe, 0x3fffe,
    502		      0x3fffe + (1024 << 16), 0x3fffe + (768 << 16));
    503	set_plane_src(&state, 0x40002, 0x40002,
    504		      0x40002 + (1024 << 16), 0x40002 + (768 << 16));
    505	/* Damage intersect with plane src. */
    506	set_damage_clip(&damage, 20, 30, 1360, 256);
    507	set_damage_blob(&damage_blob, &damage, sizeof(damage));
    508	set_plane_damage(&state, &damage_blob);
    509	drm_atomic_helper_damage_iter_init(&iter, &old_state, &state);
    510	drm_atomic_for_each_plane_damage(&iter, &clip)
    511		num_hits++;
    512
    513	FAIL(num_hits != 1, "Should return rounded off plane src as damage.");
    514	FAIL_ON(!check_damage_clip(&state, &clip, 4, 4, 1029, 773));
    515
    516	return 0;
    517}
    518
    519int igt_damage_iter_damage(void *ignored)
    520{
    521	struct drm_atomic_helper_damage_iter iter;
    522	struct drm_property_blob damage_blob;
    523	struct drm_mode_rect damage[2];
    524	struct drm_rect clip;
    525	uint32_t num_hits = 0;
    526
    527	MOCK_VARIABLES();
    528
    529	set_plane_src(&old_state, 0, 0, 1024 << 16, 768 << 16);
    530	set_plane_src(&state, 0, 0, 1024 << 16, 768 << 16);
    531	/* 2 damage clips. */
    532	set_damage_clip(&damage[0], 20, 30, 200, 180);
    533	set_damage_clip(&damage[1], 240, 200, 280, 250);
    534	set_damage_blob(&damage_blob, &damage[0], sizeof(damage));
    535	set_plane_damage(&state, &damage_blob);
    536	drm_atomic_helper_damage_iter_init(&iter, &old_state, &state);
    537	drm_atomic_for_each_plane_damage(&iter, &clip) {
    538		if (num_hits == 0)
    539			FAIL_ON(!check_damage_clip(&state, &clip, 20, 30, 200, 180));
    540		if (num_hits == 1)
    541			FAIL_ON(!check_damage_clip(&state, &clip, 240, 200, 280, 250));
    542		num_hits++;
    543	}
    544
    545	FAIL(num_hits != 2, "Should return damage when set.");
    546
    547	return 0;
    548}
    549
    550int igt_damage_iter_damage_one_intersect(void *ignored)
    551{
    552	struct drm_atomic_helper_damage_iter iter;
    553	struct drm_property_blob damage_blob;
    554	struct drm_mode_rect damage[2];
    555	struct drm_rect clip;
    556	uint32_t num_hits = 0;
    557
    558	MOCK_VARIABLES();
    559
    560	set_plane_src(&old_state, 0x40002, 0x40002,
    561		      0x40002 + (1024 << 16), 0x40002 + (768 << 16));
    562	set_plane_src(&state, 0x40002, 0x40002,
    563		      0x40002 + (1024 << 16), 0x40002 + (768 << 16));
    564	/* 2 damage clips, one intersect plane src. */
    565	set_damage_clip(&damage[0], 20, 30, 200, 180);
    566	set_damage_clip(&damage[1], 2, 2, 1360, 1360);
    567	set_damage_blob(&damage_blob, &damage[0], sizeof(damage));
    568	set_plane_damage(&state, &damage_blob);
    569	drm_atomic_helper_damage_iter_init(&iter, &old_state, &state);
    570	drm_atomic_for_each_plane_damage(&iter, &clip) {
    571		if (num_hits == 0)
    572			FAIL_ON(!check_damage_clip(&state, &clip, 20, 30, 200, 180));
    573		if (num_hits == 1)
    574			FAIL_ON(!check_damage_clip(&state, &clip, 4, 4, 1029, 773));
    575		num_hits++;
    576	}
    577
    578	FAIL(num_hits != 2, "Should return damage when set.");
    579
    580	return 0;
    581}
    582
    583int igt_damage_iter_damage_one_outside(void *ignored)
    584{
    585	struct drm_atomic_helper_damage_iter iter;
    586	struct drm_property_blob damage_blob;
    587	struct drm_mode_rect damage[2];
    588	struct drm_rect clip;
    589	uint32_t num_hits = 0;
    590
    591	MOCK_VARIABLES();
    592
    593	set_plane_src(&old_state, 0, 0, 1024 << 16, 768 << 16);
    594	set_plane_src(&state, 0, 0, 1024 << 16, 768 << 16);
    595	/* 2 damage clips, one outside plane src. */
    596	set_damage_clip(&damage[0], 1360, 1360, 1380, 1380);
    597	set_damage_clip(&damage[1], 240, 200, 280, 250);
    598	set_damage_blob(&damage_blob, &damage[0], sizeof(damage));
    599	set_plane_damage(&state, &damage_blob);
    600	drm_atomic_helper_damage_iter_init(&iter, &old_state, &state);
    601	drm_atomic_for_each_plane_damage(&iter, &clip)
    602		num_hits++;
    603
    604	FAIL(num_hits != 1, "Should return damage when set.");
    605	FAIL_ON(!check_damage_clip(&state, &clip, 240, 200, 280, 250));
    606
    607	return 0;
    608}
    609
    610int igt_damage_iter_damage_src_moved(void *ignored)
    611{
    612	struct drm_atomic_helper_damage_iter iter;
    613	struct drm_property_blob damage_blob;
    614	struct drm_mode_rect damage[2];
    615	struct drm_rect clip;
    616	uint32_t num_hits = 0;
    617
    618	MOCK_VARIABLES();
    619
    620	set_plane_src(&old_state, 0x40002, 0x40002,
    621		      0x40002 + (1024 << 16), 0x40002 + (768 << 16));
    622	set_plane_src(&state, 0x3fffe, 0x3fffe,
    623		      0x3fffe + (1024 << 16), 0x3fffe + (768 << 16));
    624	/* 2 damage clips, one outside plane src. */
    625	set_damage_clip(&damage[0], 1360, 1360, 1380, 1380);
    626	set_damage_clip(&damage[1], 240, 200, 280, 250);
    627	set_damage_blob(&damage_blob, &damage[0], sizeof(damage));
    628	set_plane_damage(&state, &damage_blob);
    629	drm_atomic_helper_damage_iter_init(&iter, &old_state, &state);
    630	drm_atomic_for_each_plane_damage(&iter, &clip)
    631		num_hits++;
    632
    633	FAIL(num_hits != 1, "Should return round off plane src as damage.");
    634	FAIL_ON(!check_damage_clip(&state, &clip, 3, 3, 1028, 772));
    635
    636	return 0;
    637}
    638
    639int igt_damage_iter_damage_not_visible(void *ignored)
    640{
    641	struct drm_atomic_helper_damage_iter iter;
    642	struct drm_property_blob damage_blob;
    643	struct drm_mode_rect damage[2];
    644	struct drm_rect clip;
    645	uint32_t num_hits = 0;
    646
    647	MOCK_VARIABLES();
    648
    649	state.visible = false;
    650
    651	set_plane_src(&old_state, 0x40002, 0x40002,
    652		      0x40002 + (1024 << 16), 0x40002 + (768 << 16));
    653	set_plane_src(&state, 0x3fffe, 0x3fffe,
    654		      0x3fffe + (1024 << 16), 0x3fffe + (768 << 16));
    655	/* 2 damage clips, one outside plane src. */
    656	set_damage_clip(&damage[0], 1360, 1360, 1380, 1380);
    657	set_damage_clip(&damage[1], 240, 200, 280, 250);
    658	set_damage_blob(&damage_blob, &damage[0], sizeof(damage));
    659	set_plane_damage(&state, &damage_blob);
    660	drm_atomic_helper_damage_iter_init(&iter, &old_state, &state);
    661	drm_atomic_for_each_plane_damage(&iter, &clip)
    662		num_hits++;
    663
    664	FAIL(num_hits != 0, "Should not return any damage.");
    665
    666	return 0;
    667}