blob: a40f88f8f46658081a34c9971aa697e119de01ce [file] [log] [blame]
Stéphane Marchesin25a26062014-09-12 16:18:59 -07001/*
Daniele Castagna7a755de2016-12-16 17:32:30 -05002 * Copyright 2014 The Chromium OS Authors. All rights reserved.
Stéphane Marchesin25a26062014-09-12 16:18:59 -07003 * Use of this source code is governed by a BSD-style license that can be
4 * found in the LICENSE file.
5 */
6
Gurchetan Singh46faf6b2016-08-05 14:40:07 -07007#ifdef DRV_I915
Stéphane Marchesin25a26062014-09-12 16:18:59 -07008
Kristian H. Kristensene8778f02018-04-04 14:21:41 -07009#include <assert.h>
Stéphane Marchesin25a26062014-09-12 16:18:59 -070010#include <errno.h>
Kristian H. Kristensen9c3fb322018-04-11 15:55:13 -070011#include <stdbool.h>
Gurchetan Singhcc015e82017-01-17 16:15:25 -080012#include <stdio.h>
Stéphane Marchesin25a26062014-09-12 16:18:59 -070013#include <string.h>
Gurchetan Singhef920532016-08-12 16:38:25 -070014#include <sys/mman.h>
Gurchetan Singhcc35e692019-02-28 15:44:54 -080015#include <unistd.h>
Stéphane Marchesin25a26062014-09-12 16:18:59 -070016#include <xf86drm.h>
Stéphane Marchesin25a26062014-09-12 16:18:59 -070017
Yiwei Zhangb7a64442021-09-30 05:13:10 +000018#include "drv_helpers.h"
Gurchetan Singh46faf6b2016-08-05 14:40:07 -070019#include "drv_priv.h"
Gurchetan Singh13b00122020-10-07 14:31:20 -070020#include "external/i915_drm.h"
Stéphane Marchesin25a26062014-09-12 16:18:59 -070021#include "util.h"
22
Gurchetan Singh68af9c22017-01-18 13:48:11 -080023#define I915_CACHELINE_SIZE 64
24#define I915_CACHELINE_MASK (I915_CACHELINE_SIZE - 1)
25
Ilja H. Friedelf39dcbc2020-02-26 02:50:51 +000026static const uint32_t scanout_render_formats[] = { DRM_FORMAT_ABGR2101010, DRM_FORMAT_ABGR8888,
27 DRM_FORMAT_ARGB2101010, DRM_FORMAT_ARGB8888,
28 DRM_FORMAT_RGB565, DRM_FORMAT_XBGR2101010,
29 DRM_FORMAT_XBGR8888, DRM_FORMAT_XRGB2101010,
30 DRM_FORMAT_XRGB8888 };
Gurchetan Singh6b41fb52017-03-01 20:14:39 -080031
Ilja H. Friedelf39dcbc2020-02-26 02:50:51 +000032static const uint32_t render_formats[] = { DRM_FORMAT_ABGR16161616F };
33
34static const uint32_t texture_only_formats[] = { DRM_FORMAT_R8, DRM_FORMAT_NV12, DRM_FORMAT_P010,
35 DRM_FORMAT_YVU420, DRM_FORMAT_YVU420_ANDROID };
Gurchetan Singh179687e2016-10-28 10:07:35 -070036
Mark Yacoub6e277082020-12-07 16:36:17 -050037static const uint64_t gen_modifier_order[] = { I915_FORMAT_MOD_Y_TILED_CCS, I915_FORMAT_MOD_Y_TILED,
38 I915_FORMAT_MOD_X_TILED, DRM_FORMAT_MOD_LINEAR };
Binu R S8d705182020-07-20 10:36:53 +053039
Vipin Ananda0af3092020-06-17 10:53:02 +053040static const uint64_t gen12_modifier_order[] = { I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS,
41 I915_FORMAT_MOD_Y_TILED, I915_FORMAT_MOD_X_TILED,
42 DRM_FORMAT_MOD_LINEAR };
43
Cooper Chiouc8c61d32021-10-27 12:18:30 +080044static const uint64_t gen11_modifier_order[] = { I915_FORMAT_MOD_Y_TILED, I915_FORMAT_MOD_X_TILED,
45 DRM_FORMAT_MOD_LINEAR };
46
Vipin Anand97e07de2022-08-12 04:47:34 +000047static const uint64_t xe_lpdp_modifier_order[] = { I915_FORMAT_MOD_4_TILED, I915_FORMAT_MOD_X_TILED,
48 DRM_FORMAT_MOD_LINEAR};
49
Binu R S8d705182020-07-20 10:36:53 +053050struct modifier_support_t {
51 const uint64_t *order;
52 uint32_t count;
53};
54
Gurchetan Singh1b1d56a2017-03-10 16:25:23 -080055struct i915_device {
Ap, Kamal1d54c832022-08-11 16:49:35 +000056 uint32_t graphics_version;
Gurchetan Singh68af9c22017-01-18 13:48:11 -080057 int32_t has_llc;
Gurchetan Singhf98d1c12020-10-07 15:46:23 -070058 int32_t has_hw_protection;
Binu R S8d705182020-07-20 10:36:53 +053059 struct modifier_support_t modifier;
Nathan Ciobanu87ec79b2021-01-21 21:26:54 -080060 int device_id;
Juston Li89875822022-06-28 10:42:23 -070061 bool is_xelpd;
Ap, Kamal1d54c832022-08-11 16:49:35 +000062 /*TODO : cleanup is_mtl to avoid adding variables for every new platforms */
63 bool is_mtl;
Mohanram Meenakshisundaram03776352022-08-11 17:14:04 +000064 int32_t num_fences_avail;
Stéphane Marchesin25a26062014-09-12 16:18:59 -070065};
66
Nathan Ciobanu87ec79b2021-01-21 21:26:54 -080067static void i915_info_from_device_id(struct i915_device *i915)
Stéphane Marchesin25a26062014-09-12 16:18:59 -070068{
Gurchetan Singh1b1d56a2017-03-10 16:25:23 -080069 const uint16_t gen3_ids[] = { 0x2582, 0x2592, 0x2772, 0x27A2, 0x27AE,
70 0x29C2, 0x29B2, 0x29D2, 0xA001, 0xA011 };
Nicholas Bishopa2047242021-10-29 12:42:33 -040071 const uint16_t gen4_ids[] = { 0x29A2, 0x2992, 0x2982, 0x2972, 0x2A02, 0x2A12, 0x2A42,
72 0x2E02, 0x2E12, 0x2E22, 0x2E32, 0x2E42, 0x2E92 };
73 const uint16_t gen5_ids[] = { 0x0042, 0x0046 };
74 const uint16_t gen6_ids[] = { 0x0102, 0x0112, 0x0122, 0x0106, 0x0116, 0x0126, 0x010A };
75 const uint16_t gen7_ids[] = {
76 0x0152, 0x0162, 0x0156, 0x0166, 0x015a, 0x016a, 0x0402, 0x0412, 0x0422,
77 0x0406, 0x0416, 0x0426, 0x040A, 0x041A, 0x042A, 0x040B, 0x041B, 0x042B,
78 0x040E, 0x041E, 0x042E, 0x0C02, 0x0C12, 0x0C22, 0x0C06, 0x0C16, 0x0C26,
79 0x0C0A, 0x0C1A, 0x0C2A, 0x0C0B, 0x0C1B, 0x0C2B, 0x0C0E, 0x0C1E, 0x0C2E,
80 0x0A02, 0x0A12, 0x0A22, 0x0A06, 0x0A16, 0x0A26, 0x0A0A, 0x0A1A, 0x0A2A,
81 0x0A0B, 0x0A1B, 0x0A2B, 0x0A0E, 0x0A1E, 0x0A2E, 0x0D02, 0x0D12, 0x0D22,
82 0x0D06, 0x0D16, 0x0D26, 0x0D0A, 0x0D1A, 0x0D2A, 0x0D0B, 0x0D1B, 0x0D2B,
83 0x0D0E, 0x0D1E, 0x0D2E, 0x0F31, 0x0F32, 0x0F33, 0x0157, 0x0155
84 };
85 const uint16_t gen8_ids[] = { 0x22B0, 0x22B1, 0x22B2, 0x22B3, 0x1602, 0x1606,
86 0x160A, 0x160B, 0x160D, 0x160E, 0x1612, 0x1616,
87 0x161A, 0x161B, 0x161D, 0x161E, 0x1622, 0x1626,
88 0x162A, 0x162B, 0x162D, 0x162E };
89 const uint16_t gen9_ids[] = {
90 0x1902, 0x1906, 0x190A, 0x190B, 0x190E, 0x1912, 0x1913, 0x1915, 0x1916, 0x1917,
91 0x191A, 0x191B, 0x191D, 0x191E, 0x1921, 0x1923, 0x1926, 0x1927, 0x192A, 0x192B,
92 0x192D, 0x1932, 0x193A, 0x193B, 0x193D, 0x0A84, 0x1A84, 0x1A85, 0x5A84, 0x5A85,
93 0x3184, 0x3185, 0x5902, 0x5906, 0x590A, 0x5908, 0x590B, 0x590E, 0x5913, 0x5915,
94 0x5917, 0x5912, 0x5916, 0x591A, 0x591B, 0x591D, 0x591E, 0x5921, 0x5923, 0x5926,
95 0x5927, 0x593B, 0x591C, 0x87C0, 0x87CA, 0x3E90, 0x3E93, 0x3E99, 0x3E9C, 0x3E91,
96 0x3E92, 0x3E96, 0x3E98, 0x3E9A, 0x3E9B, 0x3E94, 0x3EA9, 0x3EA5, 0x3EA6, 0x3EA7,
97 0x3EA8, 0x3EA1, 0x3EA4, 0x3EA0, 0x3EA3, 0x3EA2, 0x9B21, 0x9BA0, 0x9BA2, 0x9BA4,
98 0x9BA5, 0x9BA8, 0x9BAA, 0x9BAB, 0x9BAC, 0x9B41, 0x9BC0, 0x9BC2, 0x9BC4, 0x9BC5,
99 0x9BC6, 0x9BC8, 0x9BCA, 0x9BCB, 0x9BCC, 0x9BE6, 0x9BF6
100 };
101 const uint16_t gen11_ids[] = { 0x8A50, 0x8A51, 0x8A52, 0x8A53, 0x8A54, 0x8A56, 0x8A57,
102 0x8A58, 0x8A59, 0x8A5A, 0x8A5B, 0x8A5C, 0x8A5D, 0x8A71,
103 0x4500, 0x4541, 0x4551, 0x4555, 0x4557, 0x4571, 0x4E51,
104 0x4E55, 0x4E57, 0x4E61, 0x4E71 };
105 const uint16_t gen12_ids[] = {
106 0x4c8a, 0x4c8b, 0x4c8c, 0x4c90, 0x4c9a, 0x4680, 0x4681, 0x4682, 0x4683, 0x4688,
107 0x4689, 0x4690, 0x4691, 0x4692, 0x4693, 0x4698, 0x4699, 0x4626, 0x4628, 0x462a,
108 0x46a0, 0x46a1, 0x46a2, 0x46a3, 0x46a6, 0x46a8, 0x46aa, 0x46b0, 0x46b1, 0x46b2,
109 0x46b3, 0x46c0, 0x46c1, 0x46c2, 0x46c3, 0x9A40, 0x9A49, 0x9A59, 0x9A60, 0x9A68,
110 0x9A70, 0x9A78, 0x9AC0, 0x9AC9, 0x9AD9, 0x9AF8, 0x4905, 0x4906, 0x4907, 0x4908
111 };
Yiwei Zhang7648f062022-07-13 23:15:22 +0000112 const uint16_t adlp_ids[] = { 0x46A0, 0x46A1, 0x46A2, 0x46A3, 0x46A6, 0x46A8, 0x46AA,
113 0x462A, 0x4626, 0x4628, 0x46B0, 0x46B1, 0x46B2, 0x46B3,
114 0x46C0, 0x46C1, 0x46C2, 0x46C3, 0x46D0, 0x46D1, 0x46D2 };
Juston Lie18552a2022-06-27 13:32:45 -0700115
116 const uint16_t rplp_ids[] = { 0xA720, 0xA721, 0xA7A0, 0xA7A1, 0xA7A8, 0xA7A9 };
Ap, Kamal1d54c832022-08-11 16:49:35 +0000117
118 const uint16_t mtl_ids[] = { 0x7D40, 0x7D60, 0x7D45, 0x7D55, 0x7DD5 };
119
Stéphane Marchesina39dfde2014-09-15 15:38:25 -0700120 unsigned i;
Ap, Kamal1d54c832022-08-11 16:49:35 +0000121 i915->graphics_version = 4;
Juston Li89875822022-06-28 10:42:23 -0700122 i915->is_xelpd = false;
Ap, Kamal1d54c832022-08-11 16:49:35 +0000123 i915->is_mtl = false;
Nathan Ciobanu87ec79b2021-01-21 21:26:54 -0800124
Gurchetan Singh1b1d56a2017-03-10 16:25:23 -0800125 for (i = 0; i < ARRAY_SIZE(gen3_ids); i++)
Nathan Ciobanu87ec79b2021-01-21 21:26:54 -0800126 if (gen3_ids[i] == i915->device_id)
Ap, Kamal1d54c832022-08-11 16:49:35 +0000127 i915->graphics_version = 3;
Nathan Ciobanu87ec79b2021-01-21 21:26:54 -0800128
Nicholas Bishopa2047242021-10-29 12:42:33 -0400129 /* Gen 4 */
130 for (i = 0; i < ARRAY_SIZE(gen4_ids); i++)
131 if (gen4_ids[i] == i915->device_id)
Ap, Kamal1d54c832022-08-11 16:49:35 +0000132 i915->graphics_version = 4;
Nicholas Bishopa2047242021-10-29 12:42:33 -0400133
134 /* Gen 5 */
135 for (i = 0; i < ARRAY_SIZE(gen5_ids); i++)
136 if (gen5_ids[i] == i915->device_id)
Ap, Kamal1d54c832022-08-11 16:49:35 +0000137 i915->graphics_version = 5;
Nicholas Bishopa2047242021-10-29 12:42:33 -0400138
139 /* Gen 6 */
140 for (i = 0; i < ARRAY_SIZE(gen6_ids); i++)
141 if (gen6_ids[i] == i915->device_id)
Ap, Kamal1d54c832022-08-11 16:49:35 +0000142 i915->graphics_version = 6;
Nicholas Bishopa2047242021-10-29 12:42:33 -0400143
144 /* Gen 7 */
145 for (i = 0; i < ARRAY_SIZE(gen7_ids); i++)
146 if (gen7_ids[i] == i915->device_id)
Ap, Kamal1d54c832022-08-11 16:49:35 +0000147 i915->graphics_version = 7;
Nicholas Bishopa2047242021-10-29 12:42:33 -0400148
149 /* Gen 8 */
150 for (i = 0; i < ARRAY_SIZE(gen8_ids); i++)
151 if (gen8_ids[i] == i915->device_id)
Ap, Kamal1d54c832022-08-11 16:49:35 +0000152 i915->graphics_version = 8;
Nicholas Bishopa2047242021-10-29 12:42:33 -0400153
154 /* Gen 9 */
155 for (i = 0; i < ARRAY_SIZE(gen9_ids); i++)
156 if (gen9_ids[i] == i915->device_id)
Ap, Kamal1d54c832022-08-11 16:49:35 +0000157 i915->graphics_version = 9;
Nicholas Bishopa2047242021-10-29 12:42:33 -0400158
Binu R S8d705182020-07-20 10:36:53 +0530159 /* Gen 11 */
160 for (i = 0; i < ARRAY_SIZE(gen11_ids); i++)
Nathan Ciobanu87ec79b2021-01-21 21:26:54 -0800161 if (gen11_ids[i] == i915->device_id)
Ap, Kamal1d54c832022-08-11 16:49:35 +0000162 i915->graphics_version = 11;
Stéphane Marchesin25a26062014-09-12 16:18:59 -0700163
Sushma Venkatesh Reddy20604be2020-10-08 10:18:01 -0700164 /* Gen 12 */
165 for (i = 0; i < ARRAY_SIZE(gen12_ids); i++)
Nathan Ciobanu87ec79b2021-01-21 21:26:54 -0800166 if (gen12_ids[i] == i915->device_id)
Ap, Kamal1d54c832022-08-11 16:49:35 +0000167 i915->graphics_version = 12;
Sushma Venkatesh Reddy20604be2020-10-08 10:18:01 -0700168
Nathan Ciobanu87ec79b2021-01-21 21:26:54 -0800169 for (i = 0; i < ARRAY_SIZE(adlp_ids); i++)
170 if (adlp_ids[i] == i915->device_id) {
Juston Li89875822022-06-28 10:42:23 -0700171 i915->is_xelpd = true;
Ap, Kamal1d54c832022-08-11 16:49:35 +0000172 i915->graphics_version = 12;
Nathan Ciobanu87ec79b2021-01-21 21:26:54 -0800173 }
Juston Lie18552a2022-06-27 13:32:45 -0700174
175 for (i = 0; i < ARRAY_SIZE(rplp_ids); i++)
176 if (rplp_ids[i] == i915->device_id) {
177 i915->is_xelpd = true;
Ap, Kamal1d54c832022-08-11 16:49:35 +0000178 i915->graphics_version = 12;
179 }
180
181 for (i = 0; i < ARRAY_SIZE(mtl_ids); i++)
182 if (mtl_ids[i] == i915->device_id) {
183 i915->graphics_version = 12;
184 i915->is_mtl = true;
Juston Lie18552a2022-06-27 13:32:45 -0700185 }
Stéphane Marchesin25a26062014-09-12 16:18:59 -0700186}
187
Binu R S8d705182020-07-20 10:36:53 +0530188static void i915_get_modifier_order(struct i915_device *i915)
189{
Vipin Anand97e07de2022-08-12 04:47:34 +0000190 if (i915->is_mtl) {
191 i915->modifier.order = xe_lpdp_modifier_order;
192 i915->modifier.count = ARRAY_SIZE(xe_lpdp_modifier_order);
193 } else if (i915->graphics_version == 12) {
Vipin Ananda0af3092020-06-17 10:53:02 +0530194 i915->modifier.order = gen12_modifier_order;
195 i915->modifier.count = ARRAY_SIZE(gen12_modifier_order);
Ap, Kamal1d54c832022-08-11 16:49:35 +0000196 } else if (i915->graphics_version == 11) {
Cooper Chiouc8c61d32021-10-27 12:18:30 +0800197 i915->modifier.order = gen11_modifier_order;
198 i915->modifier.count = ARRAY_SIZE(gen11_modifier_order);
Vipin Ananda0af3092020-06-17 10:53:02 +0530199 } else {
200 i915->modifier.order = gen_modifier_order;
201 i915->modifier.count = ARRAY_SIZE(gen_modifier_order);
202 }
Binu R S8d705182020-07-20 10:36:53 +0530203}
204
Ilja H. Friedelf39dcbc2020-02-26 02:50:51 +0000205static uint64_t unset_flags(uint64_t current_flags, uint64_t mask)
Kristian H. Kristensen9c3fb322018-04-11 15:55:13 -0700206{
Ilja H. Friedelf39dcbc2020-02-26 02:50:51 +0000207 uint64_t value = current_flags & ~mask;
208 return value;
Gurchetan Singh6b41fb52017-03-01 20:14:39 -0800209}
210
211static int i915_add_combinations(struct driver *drv)
212{
Gurchetan Singhf98d1c12020-10-07 15:46:23 -0700213 struct i915_device *i915 = drv->priv;
Gurchetan Singh8ac0c9a2017-05-15 09:34:22 -0700214
Miguel Casasda47b7d2021-04-15 21:46:33 -0400215 const uint64_t scanout_and_render = BO_USE_RENDER_MASK | BO_USE_SCANOUT;
216 const uint64_t render = BO_USE_RENDER_MASK;
217 const uint64_t texture_only = BO_USE_TEXTURE_MASK;
Jeffrey Kardatzkedba19872020-12-04 16:58:28 -0800218 // HW protected buffers also need to be scanned out.
Miguel Casasda47b7d2021-04-15 21:46:33 -0400219 const uint64_t hw_protected =
220 i915->has_hw_protection ? (BO_USE_PROTECTED | BO_USE_SCANOUT) : 0;
Gurchetan Singhf98d1c12020-10-07 15:46:23 -0700221
Miguel Casasabeadde2021-04-16 14:49:18 -0400222 const uint64_t linear_mask = BO_USE_RENDERSCRIPT | BO_USE_LINEAR | BO_USE_SW_READ_OFTEN |
223 BO_USE_SW_WRITE_OFTEN | BO_USE_SW_READ_RARELY |
224 BO_USE_SW_WRITE_RARELY;
Gurchetan Singh6b41fb52017-03-01 20:14:39 -0800225
Gurchetan Singh45ca4492021-04-28 17:12:52 -0700226 struct format_metadata metadata_linear = { .tiling = I915_TILING_NONE,
227 .priority = 1,
228 .modifier = DRM_FORMAT_MOD_LINEAR };
Gurchetan Singh6b41fb52017-03-01 20:14:39 -0800229
Ilja H. Friedelf39dcbc2020-02-26 02:50:51 +0000230 drv_add_combinations(drv, scanout_render_formats, ARRAY_SIZE(scanout_render_formats),
Miguel Casasf2dc08e2021-04-15 20:51:24 -0400231 &metadata_linear, scanout_and_render);
Gurchetan Singh1b1d56a2017-03-10 16:25:23 -0800232
Gurchetan Singh45ca4492021-04-28 17:12:52 -0700233 drv_add_combinations(drv, render_formats, ARRAY_SIZE(render_formats), &metadata_linear,
234 render);
Gurchetan Singh8ac0c9a2017-05-15 09:34:22 -0700235
Gurchetan Singh45ca4492021-04-28 17:12:52 -0700236 drv_add_combinations(drv, texture_only_formats, ARRAY_SIZE(texture_only_formats),
237 &metadata_linear, texture_only);
Ilja H. Friedelf39dcbc2020-02-26 02:50:51 +0000238
239 drv_modify_linear_combinations(drv);
Hirokazu Hondafd8b8ab2020-06-16 15:28:56 +0900240
Hirokazu Honda3bd681c2020-06-23 17:52:20 +0900241 /* NV12 format for camera, display, decoding and encoding. */
Ilja H. Friedelf39dcbc2020-02-26 02:50:51 +0000242 /* IPU3 camera ISP supports only NV12 output. */
Miguel Casasf2dc08e2021-04-15 20:51:24 -0400243 drv_modify_combination(drv, DRM_FORMAT_NV12, &metadata_linear,
Hirokazu Honda3bd681c2020-06-23 17:52:20 +0900244 BO_USE_CAMERA_READ | BO_USE_CAMERA_WRITE | BO_USE_SCANOUT |
Gurchetan Singhf98d1c12020-10-07 15:46:23 -0700245 BO_USE_HW_VIDEO_DECODER | BO_USE_HW_VIDEO_ENCODER |
246 hw_protected);
Hirokazu Honda3b8d4d02019-07-31 16:35:52 +0900247
Gurchetan Singh71bc6652018-09-17 17:42:05 -0700248 /* Android CTS tests require this. */
Miguel Casasf2dc08e2021-04-15 20:51:24 -0400249 drv_add_combination(drv, DRM_FORMAT_BGR888, &metadata_linear, BO_USE_SW_MASK);
Gurchetan Singh71bc6652018-09-17 17:42:05 -0700250
Tomasz Figad30c0a52017-07-05 17:50:18 +0900251 /*
252 * R8 format is used for Android's HAL_PIXEL_FORMAT_BLOB and is used for JPEG snapshots
David Stevens49518142020-06-15 13:48:48 +0900253 * from camera and input/output from hardware decoder/encoder.
Tomasz Figad30c0a52017-07-05 17:50:18 +0900254 */
Miguel Casasf2dc08e2021-04-15 20:51:24 -0400255 drv_modify_combination(drv, DRM_FORMAT_R8, &metadata_linear,
David Stevens49518142020-06-15 13:48:48 +0900256 BO_USE_CAMERA_READ | BO_USE_CAMERA_WRITE | BO_USE_HW_VIDEO_DECODER |
Jason Macnak80f664c2022-07-19 16:44:22 -0700257 BO_USE_HW_VIDEO_ENCODER | BO_USE_GPU_DATA_BUFFER |
258 BO_USE_SENSOR_DIRECT_DATA);
Tomasz Figad30c0a52017-07-05 17:50:18 +0900259
Miguel Casasda47b7d2021-04-15 21:46:33 -0400260 const uint64_t render_not_linear = unset_flags(render, linear_mask);
Miguel Casasb5a95bb2021-04-16 14:52:59 -0400261 const uint64_t scanout_and_render_not_linear = render_not_linear | BO_USE_SCANOUT;
Gurchetan Singh6b41fb52017-03-01 20:14:39 -0800262
Gurchetan Singh45ca4492021-04-28 17:12:52 -0700263 struct format_metadata metadata_x_tiled = { .tiling = I915_TILING_X,
264 .priority = 2,
265 .modifier = I915_FORMAT_MOD_X_TILED };
Gurchetan Singh6b41fb52017-03-01 20:14:39 -0800266
Gurchetan Singh45ca4492021-04-28 17:12:52 -0700267 drv_add_combinations(drv, render_formats, ARRAY_SIZE(render_formats), &metadata_x_tiled,
268 render_not_linear);
Ilja H. Friedelf39dcbc2020-02-26 02:50:51 +0000269 drv_add_combinations(drv, scanout_render_formats, ARRAY_SIZE(scanout_render_formats),
Miguel Casasda47b7d2021-04-15 21:46:33 -0400270 &metadata_x_tiled, scanout_and_render_not_linear);
Gurchetan Singh8ac0c9a2017-05-15 09:34:22 -0700271
Vipin Anand97e07de2022-08-12 04:47:34 +0000272 if (i915->is_mtl) {
273 struct format_metadata metadata_4_tiled = { .tiling = I915_TILING_4,
274 .priority = 3,
275 .modifier = I915_FORMAT_MOD_4_TILED };
276/* Support tile4 NV12 and P010 for libva */
277#ifdef I915_SCANOUT_4_TILED
278 const uint64_t nv12_usage =
279 BO_USE_TEXTURE | BO_USE_HW_VIDEO_DECODER | BO_USE_SCANOUT | hw_protected;
280 const uint64_t p010_usage = BO_USE_TEXTURE | BO_USE_HW_VIDEO_DECODER | hw_protected |
281 BO_USE_SCANOUT;
282#else
283 const uint64_t nv12_usage = BO_USE_TEXTURE | BO_USE_HW_VIDEO_DECODER;
284 const uint64_t p010_usage = nv12_usage;
285#endif
286 drv_add_combination(drv, DRM_FORMAT_NV12, &metadata_4_tiled, nv12_usage);
287 drv_add_combination(drv, DRM_FORMAT_P010, &metadata_4_tiled, p010_usage);
288 drv_add_combinations(drv, render_formats, ARRAY_SIZE(render_formats), &metadata_4_tiled,
289 render_not_linear);
290 drv_add_combinations(drv, scanout_render_formats, ARRAY_SIZE(scanout_render_formats),
291 &metadata_4_tiled, render_not_linear);
292 } else {
293 struct format_metadata metadata_y_tiled = { .tiling = I915_TILING_Y,
Gurchetan Singh45ca4492021-04-28 17:12:52 -0700294 .priority = 3,
295 .modifier = I915_FORMAT_MOD_Y_TILED };
Ilja H. Friedelf39dcbc2020-02-26 02:50:51 +0000296/* Support y-tiled NV12 and P010 for libva */
297#ifdef I915_SCANOUT_Y_TILED
Vipin Anand97e07de2022-08-12 04:47:34 +0000298 const uint64_t nv12_usage =
299 BO_USE_TEXTURE | BO_USE_HW_VIDEO_DECODER | BO_USE_SCANOUT | hw_protected;
300 const uint64_t p010_usage = BO_USE_TEXTURE | BO_USE_HW_VIDEO_DECODER | hw_protected |
301 (i915->graphics_version >= 11 ? BO_USE_SCANOUT : 0);
Ilja H. Friedelf39dcbc2020-02-26 02:50:51 +0000302#else
Vipin Anand97e07de2022-08-12 04:47:34 +0000303 const uint64_t nv12_usage = BO_USE_TEXTURE | BO_USE_HW_VIDEO_DECODER;
304 const uint64_t p010_usage = nv12_usage;
Ilja H. Friedelf39dcbc2020-02-26 02:50:51 +0000305#endif
Vipin Anand97e07de2022-08-12 04:47:34 +0000306 drv_add_combination(drv, DRM_FORMAT_NV12, &metadata_y_tiled, nv12_usage);
307 drv_add_combination(drv, DRM_FORMAT_P010, &metadata_y_tiled, p010_usage);
308 drv_add_combinations(drv, render_formats, ARRAY_SIZE(render_formats), &metadata_y_tiled,
Gurchetan Singh45ca4492021-04-28 17:12:52 -0700309 render_not_linear);
Vipin Anand97e07de2022-08-12 04:47:34 +0000310 /* Y-tiled scanout isn't available on old platforms so we add
311 * |scanout_render_formats| without that USE flag.
312 */
313 drv_add_combinations(drv, scanout_render_formats, ARRAY_SIZE(scanout_render_formats),
Miguel Casasb5a95bb2021-04-16 14:52:59 -0400314 &metadata_y_tiled, render_not_linear);
Vipin Anand97e07de2022-08-12 04:47:34 +0000315 }
Gurchetan Singh6b41fb52017-03-01 20:14:39 -0800316 return 0;
317}
318
Gurchetan Singh1b1d56a2017-03-10 16:25:23 -0800319static int i915_align_dimensions(struct bo *bo, uint32_t tiling, uint32_t *stride,
320 uint32_t *aligned_height)
Stéphane Marchesin25a26062014-09-12 16:18:59 -0700321{
Gurchetan Singh6423ecb2017-03-29 08:23:40 -0700322 struct i915_device *i915 = bo->drv->priv;
Kristian H. Kristensene8778f02018-04-04 14:21:41 -0700323 uint32_t horizontal_alignment;
324 uint32_t vertical_alignment;
Stéphane Marchesin25a26062014-09-12 16:18:59 -0700325
Gurchetan Singh6423ecb2017-03-29 08:23:40 -0700326 switch (tiling) {
Gurchetan Singhd6fb5772016-08-29 19:13:51 -0700327 default:
328 case I915_TILING_NONE:
Kristian H. Kristensene8778f02018-04-04 14:21:41 -0700329 /*
330 * The Intel GPU doesn't need any alignment in linear mode,
331 * but libva requires the allocation stride to be aligned to
332 * 16 bytes and height to 4 rows. Further, we round up the
333 * horizontal alignment so that row start on a cache line (64
334 * bytes).
335 */
Dominik Behr1c6e70a2020-11-05 18:58:06 -0800336#ifdef LINEAR_ALIGN_256
337 /*
338 * If we want to import these buffers to amdgpu they need to
339 * their match LINEAR_ALIGNED requirement of 256 byte alignement.
340 */
341 horizontal_alignment = 256;
342#else
Gurchetan Singh6423ecb2017-03-29 08:23:40 -0700343 horizontal_alignment = 64;
Dominik Behr1c6e70a2020-11-05 18:58:06 -0800344#endif
Kristian H. Kristensene8778f02018-04-04 14:21:41 -0700345 vertical_alignment = 4;
Gurchetan Singhd6fb5772016-08-29 19:13:51 -0700346 break;
Stéphane Marchesin5d867a42014-11-24 17:09:49 -0800347
Gurchetan Singhd6fb5772016-08-29 19:13:51 -0700348 case I915_TILING_X:
Gurchetan Singh6423ecb2017-03-29 08:23:40 -0700349 horizontal_alignment = 512;
350 vertical_alignment = 8;
Gurchetan Singhd6fb5772016-08-29 19:13:51 -0700351 break;
352
353 case I915_TILING_Y:
Vipin Anand97e07de2022-08-12 04:47:34 +0000354 case I915_TILING_4:
Ap, Kamal1d54c832022-08-11 16:49:35 +0000355 if (i915->graphics_version == 3) {
Chad Versace0f9bd722022-01-20 11:36:02 -0800356 horizontal_alignment = 512;
357 vertical_alignment = 8;
Yiwei Zhang17fa1a82022-02-04 00:39:06 +0000358 } else {
359 horizontal_alignment = 128;
360 vertical_alignment = 32;
Gurchetan Singhd6fb5772016-08-29 19:13:51 -0700361 }
362 break;
Stéphane Marchesin25a26062014-09-12 16:18:59 -0700363 }
Stéphane Marchesin5d867a42014-11-24 17:09:49 -0800364
David Stevens793675a2019-09-25 11:17:48 +0900365 *aligned_height = ALIGN(*aligned_height, vertical_alignment);
Ap, Kamal1d54c832022-08-11 16:49:35 +0000366 if (i915->graphics_version > 3) {
Gurchetan Singh6423ecb2017-03-29 08:23:40 -0700367 *stride = ALIGN(*stride, horizontal_alignment);
Stéphane Marchesin5d867a42014-11-24 17:09:49 -0800368 } else {
Gurchetan Singh6423ecb2017-03-29 08:23:40 -0700369 while (*stride > horizontal_alignment)
370 horizontal_alignment <<= 1;
371
372 *stride = horizontal_alignment;
Stéphane Marchesin5d867a42014-11-24 17:09:49 -0800373 }
Stéphane Marchesin5d867a42014-11-24 17:09:49 -0800374
Ap, Kamal1d54c832022-08-11 16:49:35 +0000375 if (i915->graphics_version <= 3 && *stride > 8192)
Gurchetan Singh6423ecb2017-03-29 08:23:40 -0700376 return -EINVAL;
Stéphane Marchesin5d867a42014-11-24 17:09:49 -0800377
Gurchetan Singh6423ecb2017-03-29 08:23:40 -0700378 return 0;
Stéphane Marchesin25a26062014-09-12 16:18:59 -0700379}
380
Gurchetan Singh68af9c22017-01-18 13:48:11 -0800381static void i915_clflush(void *start, size_t size)
382{
383 void *p = (void *)(((uintptr_t)start) & ~I915_CACHELINE_MASK);
384 void *end = (void *)((uintptr_t)start + size);
385
386 __builtin_ia32_mfence();
387 while (p < end) {
388 __builtin_ia32_clflush(p);
389 p = (void *)((uintptr_t)p + I915_CACHELINE_SIZE);
390 }
391}
392
Gurchetan Singh3eb8d8f2017-01-03 13:36:13 -0800393static int i915_init(struct driver *drv)
394{
Gurchetan Singh3eb8d8f2017-01-03 13:36:13 -0800395 int ret;
Gurchetan Singhcc015e82017-01-17 16:15:25 -0800396 struct i915_device *i915;
Gurchetan Singh99644382020-10-07 15:28:11 -0700397 drm_i915_getparam_t get_param = { 0 };
Gurchetan Singh3eb8d8f2017-01-03 13:36:13 -0800398
Gurchetan Singhcc015e82017-01-17 16:15:25 -0800399 i915 = calloc(1, sizeof(*i915));
400 if (!i915)
401 return -ENOMEM;
Gurchetan Singh3eb8d8f2017-01-03 13:36:13 -0800402
Gurchetan Singh3eb8d8f2017-01-03 13:36:13 -0800403 get_param.param = I915_PARAM_CHIPSET_ID;
Nathan Ciobanu87ec79b2021-01-21 21:26:54 -0800404 get_param.value = &(i915->device_id);
Gurchetan Singh3eb8d8f2017-01-03 13:36:13 -0800405 ret = drmIoctl(drv->fd, DRM_IOCTL_I915_GETPARAM, &get_param);
406 if (ret) {
Yiwei Zhang04954732022-07-13 23:34:33 +0000407 drv_loge("Failed to get I915_PARAM_CHIPSET_ID\n");
Gurchetan Singhcc015e82017-01-17 16:15:25 -0800408 free(i915);
Gurchetan Singh82a8eed2017-01-03 13:01:37 -0800409 return -EINVAL;
Gurchetan Singh3eb8d8f2017-01-03 13:36:13 -0800410 }
Ap, Kamal1d54c832022-08-11 16:49:35 +0000411 /* must call before i915->graphics_version is used anywhere else */
Nathan Ciobanu87ec79b2021-01-21 21:26:54 -0800412 i915_info_from_device_id(i915);
Gurchetan Singh3eb8d8f2017-01-03 13:36:13 -0800413
Binu R S8d705182020-07-20 10:36:53 +0530414 i915_get_modifier_order(i915);
Gurchetan Singh68af9c22017-01-18 13:48:11 -0800415
416 memset(&get_param, 0, sizeof(get_param));
417 get_param.param = I915_PARAM_HAS_LLC;
418 get_param.value = &i915->has_llc;
419 ret = drmIoctl(drv->fd, DRM_IOCTL_I915_GETPARAM, &get_param);
420 if (ret) {
Yiwei Zhang04954732022-07-13 23:34:33 +0000421 drv_loge("Failed to get I915_PARAM_HAS_LLC\n");
Gurchetan Singh68af9c22017-01-18 13:48:11 -0800422 free(i915);
423 return -EINVAL;
424 }
425
Mohanram Meenakshisundaram03776352022-08-11 17:14:04 +0000426 memset(&get_param, 0, sizeof(get_param));
427 get_param.param = I915_PARAM_NUM_FENCES_AVAIL;
428 get_param.value = &i915->num_fences_avail;
429 ret = drmIoctl(drv->fd, DRM_IOCTL_I915_GETPARAM, &get_param);
430 if (ret) {
431 drv_loge("Failed to get I915_PARAM_NUM_FENCES_AVAIL\n");
432 return -EINVAL;
433 }
434
Ap, Kamal1d54c832022-08-11 16:49:35 +0000435 if (i915->graphics_version >= 12)
Gurchetan Singhf98d1c12020-10-07 15:46:23 -0700436 i915->has_hw_protection = 1;
Gurchetan Singh3eb8d8f2017-01-03 13:36:13 -0800437
Gurchetan Singhf98d1c12020-10-07 15:46:23 -0700438 drv->priv = i915;
Gurchetan Singh6b41fb52017-03-01 20:14:39 -0800439 return i915_add_combinations(drv);
Gurchetan Singh3eb8d8f2017-01-03 13:36:13 -0800440}
441
Sushma Venkatesh Reddy0b57ebf2021-03-22 17:10:05 -0700442/*
443 * Returns true if the height of a buffer of the given format should be aligned
444 * to the largest coded unit (LCU) assuming that it will be used for video. This
445 * is based on gmmlib's GmmIsYUVFormatLCUAligned().
446 */
Drew Davenport862d36f2021-06-09 19:54:04 -0600447static bool i915_format_needs_LCU_alignment(uint32_t format, size_t plane,
448 const struct i915_device *i915)
Sushma Venkatesh Reddy0b57ebf2021-03-22 17:10:05 -0700449{
450 switch (format) {
451 case DRM_FORMAT_NV12:
452 case DRM_FORMAT_P010:
453 case DRM_FORMAT_P016:
Ap, Kamal1d54c832022-08-11 16:49:35 +0000454 return (i915->graphics_version == 11 || i915->graphics_version == 12) && plane == 1;
Sushma Venkatesh Reddy0b57ebf2021-03-22 17:10:05 -0700455 }
456 return false;
457}
458
Kristian H. Kristensene8778f02018-04-04 14:21:41 -0700459static int i915_bo_from_format(struct bo *bo, uint32_t width, uint32_t height, uint32_t format)
460{
461 uint32_t offset;
462 size_t plane;
Gurchetan Singhcc35e692019-02-28 15:44:54 -0800463 int ret, pagesize;
Sushma Venkatesh Reddy0b57ebf2021-03-22 17:10:05 -0700464 struct i915_device *i915 = bo->drv->priv;
Kristian H. Kristensene8778f02018-04-04 14:21:41 -0700465
466 offset = 0;
Gurchetan Singhcc35e692019-02-28 15:44:54 -0800467 pagesize = getpagesize();
Sushma Venkatesh Reddy0b57ebf2021-03-22 17:10:05 -0700468
Kristian H. Kristensene8778f02018-04-04 14:21:41 -0700469 for (plane = 0; plane < drv_num_planes_from_format(format); plane++) {
470 uint32_t stride = drv_stride_from_format(format, width, plane);
471 uint32_t plane_height = drv_height_from_format(format, height, plane);
472
Gurchetan Singh298b7572019-09-19 09:55:18 -0700473 if (bo->meta.tiling != I915_TILING_NONE)
Gurchetan Singhcc35e692019-02-28 15:44:54 -0800474 assert(IS_ALIGNED(offset, pagesize));
Kristian H. Kristensene8778f02018-04-04 14:21:41 -0700475
Gurchetan Singh298b7572019-09-19 09:55:18 -0700476 ret = i915_align_dimensions(bo, bo->meta.tiling, &stride, &plane_height);
Kristian H. Kristensene8778f02018-04-04 14:21:41 -0700477 if (ret)
478 return ret;
479
Sushma Venkatesh Reddy0b57ebf2021-03-22 17:10:05 -0700480 if (i915_format_needs_LCU_alignment(format, plane, i915)) {
481 /*
482 * Align the height of the V plane for certain formats to the
483 * largest coded unit (assuming that this BO may be used for video)
484 * to be consistent with gmmlib.
485 */
486 plane_height = ALIGN(plane_height, 64);
487 }
488
Gurchetan Singh298b7572019-09-19 09:55:18 -0700489 bo->meta.strides[plane] = stride;
490 bo->meta.sizes[plane] = stride * plane_height;
491 bo->meta.offsets[plane] = offset;
492 offset += bo->meta.sizes[plane];
Kristian H. Kristensene8778f02018-04-04 14:21:41 -0700493 }
494
Gurchetan Singh298b7572019-09-19 09:55:18 -0700495 bo->meta.total_size = ALIGN(offset, pagesize);
Kristian H. Kristensene8778f02018-04-04 14:21:41 -0700496
497 return 0;
498}
499
Yiwei Zhang7648f062022-07-13 23:15:22 +0000500static size_t i915_num_planes_from_modifier(struct driver *drv, uint32_t format, uint64_t modifier)
Robert Mader96058f92022-04-05 12:15:11 +0200501{
502 size_t num_planes = drv_num_planes_from_format(format);
503 if (modifier == I915_FORMAT_MOD_Y_TILED_CCS ||
504 modifier == I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS) {
505 assert(num_planes == 1);
506 return 2;
507 }
508
509 return num_planes;
510}
511
David Stevens26fe6822020-03-09 12:23:42 +0000512static int i915_bo_compute_metadata(struct bo *bo, uint32_t width, uint32_t height, uint32_t format,
513 uint64_t use_flags, const uint64_t *modifiers, uint32_t count)
Stéphane Marchesin25a26062014-09-12 16:18:59 -0700514{
David Stevens26fe6822020-03-09 12:23:42 +0000515 uint64_t modifier;
Sean Paula9d3f772020-05-19 10:17:07 -0400516 struct i915_device *i915 = bo->drv->priv;
Ap, Kamal1d54c832022-08-11 16:49:35 +0000517 bool huge_bo = (i915->graphics_version < 11) && (width > 4096);
David Stevens26fe6822020-03-09 12:23:42 +0000518
519 if (modifiers) {
520 modifier =
Binu R S8d705182020-07-20 10:36:53 +0530521 drv_pick_modifier(modifiers, count, i915->modifier.order, i915->modifier.count);
David Stevens26fe6822020-03-09 12:23:42 +0000522 } else {
523 struct combination *combo = drv_get_combination(bo->drv, format, use_flags);
524 if (!combo)
525 return -EINVAL;
526 modifier = combo->metadata.modifier;
527 }
Stéphane Marchesin25a26062014-09-12 16:18:59 -0700528
Sean Paula9d3f772020-05-19 10:17:07 -0400529 /*
Abhishek Kumar6085bf32020-10-12 16:24:03 +0530530 * i915 only supports linear/x-tiled above 4096 wide on Gen9/Gen10 GPU.
531 * VAAPI decode in NV12 Y tiled format so skip modifier change for NV12/P010 huge bo.
Sean Paula9d3f772020-05-19 10:17:07 -0400532 */
Abhishek Kumar6085bf32020-10-12 16:24:03 +0530533 if (huge_bo && format != DRM_FORMAT_NV12 && format != DRM_FORMAT_P010 &&
534 modifier != I915_FORMAT_MOD_X_TILED && modifier != DRM_FORMAT_MOD_LINEAR) {
Sean Paula9d3f772020-05-19 10:17:07 -0400535 uint32_t i;
536 for (i = 0; modifiers && i < count; i++) {
537 if (modifiers[i] == I915_FORMAT_MOD_X_TILED)
538 break;
539 }
540 if (i == count)
541 modifier = DRM_FORMAT_MOD_LINEAR;
542 else
543 modifier = I915_FORMAT_MOD_X_TILED;
544 }
545
Pilar Molina Lopez28cf2f12020-11-12 18:19:42 -0500546 /*
547 * Skip I915_FORMAT_MOD_Y_TILED_CCS modifier if compression is disabled
548 * Pick y tiled modifier if it has been passed in, otherwise use linear
549 */
550 if (!bo->drv->compression && modifier == I915_FORMAT_MOD_Y_TILED_CCS) {
551 uint32_t i;
552 for (i = 0; modifiers && i < count; i++) {
553 if (modifiers[i] == I915_FORMAT_MOD_Y_TILED)
554 break;
555 }
556 if (i == count)
557 modifier = DRM_FORMAT_MOD_LINEAR;
558 else
559 modifier = I915_FORMAT_MOD_Y_TILED;
560 }
561
Nicholas Bishopa2047242021-10-29 12:42:33 -0400562 /* Prevent gen 8 and earlier from trying to use a tiling modifier */
Ap, Kamal1d54c832022-08-11 16:49:35 +0000563 if (i915->graphics_version <= 8 && format == DRM_FORMAT_ARGB8888) {
Nicholas Bishopa2047242021-10-29 12:42:33 -0400564 modifier = DRM_FORMAT_MOD_LINEAR;
565 }
566
Kristian H. Kristensen6061eab2017-10-03 13:53:19 -0700567 switch (modifier) {
568 case DRM_FORMAT_MOD_LINEAR:
Gurchetan Singh298b7572019-09-19 09:55:18 -0700569 bo->meta.tiling = I915_TILING_NONE;
Kristian H. Kristensen6061eab2017-10-03 13:53:19 -0700570 break;
571 case I915_FORMAT_MOD_X_TILED:
Gurchetan Singh298b7572019-09-19 09:55:18 -0700572 bo->meta.tiling = I915_TILING_X;
Kristian H. Kristensen6061eab2017-10-03 13:53:19 -0700573 break;
574 case I915_FORMAT_MOD_Y_TILED:
Mark Yacoubc9565642020-02-07 11:02:22 -0500575 case I915_FORMAT_MOD_Y_TILED_CCS:
Vipin Ananda0af3092020-06-17 10:53:02 +0530576 /* For now support only I915_TILING_Y as this works with all
577 * IPs(render/media/display)
578 */
579 case I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS:
Gurchetan Singh298b7572019-09-19 09:55:18 -0700580 bo->meta.tiling = I915_TILING_Y;
Kristian H. Kristensen6061eab2017-10-03 13:53:19 -0700581 break;
Vipin Anand97e07de2022-08-12 04:47:34 +0000582 case I915_FORMAT_MOD_4_TILED:
583 bo->meta.tiling = I915_TILING_4;
584 break;
Kristian H. Kristensen6061eab2017-10-03 13:53:19 -0700585 }
Owen Linbbb69fd2017-06-05 14:33:08 +0800586
Gurchetan Singh52155b42021-01-27 17:55:17 -0800587 bo->meta.format_modifier = modifier;
Kristian H. Kristensen2b8f89e2018-02-07 16:10:06 -0800588
Kristian H. Kristensene8778f02018-04-04 14:21:41 -0700589 if (format == DRM_FORMAT_YVU420_ANDROID) {
590 /*
591 * We only need to be able to use this as a linear texture,
592 * which doesn't put any HW restrictions on how we lay it
593 * out. The Android format does require the stride to be a
594 * multiple of 16 and expects the Cr and Cb stride to be
595 * ALIGN(Y_stride / 2, 16), which we can make happen by
596 * aligning to 32 bytes here.
597 */
598 uint32_t stride = ALIGN(width, 32);
599 drv_bo_from_format(bo, stride, height, format);
Mark Yacoubc9565642020-02-07 11:02:22 -0500600 } else if (modifier == I915_FORMAT_MOD_Y_TILED_CCS) {
601 /*
602 * For compressed surfaces, we need a color control surface
603 * (CCS). Color compression is only supported for Y tiled
604 * surfaces, and for each 32x16 tiles in the main surface we
605 * need a tile in the control surface. Y tiles are 128 bytes
606 * wide and 32 lines tall and we use that to first compute the
607 * width and height in tiles of the main surface. stride and
608 * height are already multiples of 128 and 32, respectively:
609 */
610 uint32_t stride = drv_stride_from_format(format, width, 0);
611 uint32_t width_in_tiles = DIV_ROUND_UP(stride, 128);
612 uint32_t height_in_tiles = DIV_ROUND_UP(height, 32);
613 uint32_t size = width_in_tiles * height_in_tiles * 4096;
614 uint32_t offset = 0;
615
616 bo->meta.strides[0] = width_in_tiles * 128;
617 bo->meta.sizes[0] = size;
618 bo->meta.offsets[0] = offset;
619 offset += size;
620
621 /*
622 * Now, compute the width and height in tiles of the control
623 * surface by dividing and rounding up.
624 */
625 uint32_t ccs_width_in_tiles = DIV_ROUND_UP(width_in_tiles, 32);
626 uint32_t ccs_height_in_tiles = DIV_ROUND_UP(height_in_tiles, 16);
627 uint32_t ccs_size = ccs_width_in_tiles * ccs_height_in_tiles * 4096;
628
629 /*
630 * With stride and height aligned to y tiles, offset is
631 * already a multiple of 4096, which is the required alignment
632 * of the CCS.
633 */
634 bo->meta.strides[1] = ccs_width_in_tiles * 128;
635 bo->meta.sizes[1] = ccs_size;
636 bo->meta.offsets[1] = offset;
637 offset += ccs_size;
638
Robert Mader96058f92022-04-05 12:15:11 +0200639 bo->meta.num_planes = i915_num_planes_from_modifier(bo->drv, format, modifier);
Mark Yacoubc9565642020-02-07 11:02:22 -0500640 bo->meta.total_size = offset;
Vipin Ananda0af3092020-06-17 10:53:02 +0530641 } else if (modifier == I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS) {
642
643 /*
644 * considering only 128 byte compression and one cache line of
645 * aux buffer(64B) contains compression status of 4-Y tiles.
646 * Which is 4 * (128B * 32L).
647 * line stride(bytes) is 4 * 128B
648 * and tile stride(lines) is 32L
649 */
650 uint32_t stride = ALIGN(drv_stride_from_format(format, width, 0), 512);
651
652 height = ALIGN(drv_height_from_format(format, height, 0), 32);
653
Juston Li89875822022-06-28 10:42:23 -0700654 if (i915->is_xelpd && (stride > 1)) {
Vipin Ananda0af3092020-06-17 10:53:02 +0530655 stride = 1 << (32 - __builtin_clz(stride - 1));
656 height = ALIGN(drv_height_from_format(format, height, 0), 128);
657 }
658
659 bo->meta.strides[0] = stride;
660 /* size calculation and alignment are 64KB aligned
661 * size as per spec
662 */
663 bo->meta.sizes[0] = ALIGN(stride * height, 65536);
664 bo->meta.offsets[0] = 0;
665
666 /* Aux buffer is linear and page aligned. It is placed after
667 * other planes and aligned to main buffer stride.
668 */
669 bo->meta.strides[1] = bo->meta.strides[0] / 8;
670 /* Aligned to page size */
671 bo->meta.sizes[1] = ALIGN(bo->meta.sizes[0] / 256, getpagesize());
672 bo->meta.offsets[1] = bo->meta.sizes[0];
673 /* Total number of planes & sizes */
Robert Mader96058f92022-04-05 12:15:11 +0200674 bo->meta.num_planes = i915_num_planes_from_modifier(bo->drv, format, modifier);
Vipin Ananda0af3092020-06-17 10:53:02 +0530675 bo->meta.total_size = bo->meta.sizes[0] + bo->meta.sizes[1];
Kristian H. Kristensene8778f02018-04-04 14:21:41 -0700676 } else {
677 i915_bo_from_format(bo, width, height, format);
678 }
David Stevens26fe6822020-03-09 12:23:42 +0000679 return 0;
680}
681
682static int i915_bo_create_from_metadata(struct bo *bo)
683{
684 int ret;
685 size_t plane;
Gurchetan Singhf98d1c12020-10-07 15:46:23 -0700686 uint32_t gem_handle;
Gurchetan Singh99644382020-10-07 15:28:11 -0700687 struct drm_i915_gem_set_tiling gem_set_tiling = { 0 };
Gurchetan Singhf98d1c12020-10-07 15:46:23 -0700688 struct i915_device *i915 = bo->drv->priv;
Stéphane Marchesin5d867a42014-11-24 17:09:49 -0800689
Gurchetan Singhf98d1c12020-10-07 15:46:23 -0700690 if (i915->has_hw_protection && (bo->meta.use_flags & BO_USE_PROTECTED)) {
Juston Lief852e02021-08-02 11:02:45 -0700691 struct drm_i915_gem_create_ext_protected_content protected_content = {
692 .base = { .name = I915_GEM_CREATE_EXT_PROTECTED_CONTENT },
693 .flags = 0,
Gurchetan Singhf98d1c12020-10-07 15:46:23 -0700694 };
695
696 struct drm_i915_gem_create_ext create_ext = {
697 .size = bo->meta.total_size,
Juston Lief852e02021-08-02 11:02:45 -0700698 .extensions = (uintptr_t)&protected_content,
Gurchetan Singhf98d1c12020-10-07 15:46:23 -0700699 };
700
701 ret = drmIoctl(bo->drv->fd, DRM_IOCTL_I915_GEM_CREATE_EXT, &create_ext);
702 if (ret) {
Yiwei Zhang04954732022-07-13 23:34:33 +0000703 drv_loge("DRM_IOCTL_I915_GEM_CREATE_EXT failed (size=%llu) (ret=%d) \n",
704 create_ext.size, ret);
Gurchetan Singhf98d1c12020-10-07 15:46:23 -0700705 return -errno;
706 }
707
708 gem_handle = create_ext.handle;
709 } else {
710 struct drm_i915_gem_create gem_create = { 0 };
711 gem_create.size = bo->meta.total_size;
712 ret = drmIoctl(bo->drv->fd, DRM_IOCTL_I915_GEM_CREATE, &gem_create);
713 if (ret) {
Yiwei Zhang04954732022-07-13 23:34:33 +0000714 drv_loge("DRM_IOCTL_I915_GEM_CREATE failed (size=%llu)\n", gem_create.size);
Gurchetan Singhf98d1c12020-10-07 15:46:23 -0700715 return -errno;
716 }
717
718 gem_handle = gem_create.handle;
Ilja H. Friedelf9d2ab72015-04-09 14:08:36 -0700719 }
Gurchetan Singh83dc4fb2016-07-19 15:52:33 -0700720
Gurchetan Singh298b7572019-09-19 09:55:18 -0700721 for (plane = 0; plane < bo->meta.num_planes; plane++)
Gurchetan Singhf98d1c12020-10-07 15:46:23 -0700722 bo->handles[plane].u32 = gem_handle;
Daniel Nicoara1de26dc2014-09-25 18:53:19 -0400723
Mohanram Meenakshisundaram03776352022-08-11 17:14:04 +0000724 /* Set/Get tiling ioctl not supported based on fence availability
725 Refer : "https://patchwork.freedesktop.org/patch/325343/"
726 */
727 if (i915->num_fences_avail) {
728 gem_set_tiling.handle = bo->handles[0].u32;
729 gem_set_tiling.tiling_mode = bo->meta.tiling;
730 gem_set_tiling.stride = bo->meta.strides[0];
Stéphane Marchesin25a26062014-09-12 16:18:59 -0700731
Mohanram Meenakshisundaram03776352022-08-11 17:14:04 +0000732 ret = drmIoctl(bo->drv->fd, DRM_IOCTL_I915_GEM_SET_TILING, &gem_set_tiling);
733 if (ret) {
734 struct drm_gem_close gem_close = { 0 };
735 gem_close.handle = bo->handles[0].u32;
736 drmIoctl(bo->drv->fd, DRM_IOCTL_GEM_CLOSE, &gem_close);
Gurchetan Singh82a8eed2017-01-03 13:01:37 -0800737
Mohanram Meenakshisundaram03776352022-08-11 17:14:04 +0000738 drv_loge("DRM_IOCTL_I915_GEM_SET_TILING failed with %d\n", errno);
739 return -errno;
740 }
Stéphane Marchesin25a26062014-09-12 16:18:59 -0700741 }
Stéphane Marchesin25a26062014-09-12 16:18:59 -0700742 return 0;
743}
744
Gurchetan Singhcc015e82017-01-17 16:15:25 -0800745static void i915_close(struct driver *drv)
Gurchetan Singh82a8eed2017-01-03 13:01:37 -0800746{
Gurchetan Singhcc015e82017-01-17 16:15:25 -0800747 free(drv->priv);
748 drv->priv = NULL;
Gurchetan Singh82a8eed2017-01-03 13:01:37 -0800749}
750
Gurchetan Singhfcad5ad2017-01-05 20:39:31 -0800751static int i915_bo_import(struct bo *bo, struct drv_import_fd_data *data)
752{
753 int ret;
Gurchetan Singh99644382020-10-07 15:28:11 -0700754 struct drm_i915_gem_get_tiling gem_get_tiling = { 0 };
Mohanram Meenakshisundaram03776352022-08-11 17:14:04 +0000755 struct i915_device *i915 = bo->drv->priv;
Gurchetan Singhfcad5ad2017-01-05 20:39:31 -0800756
Yiwei Zhang7648f062022-07-13 23:15:22 +0000757 bo->meta.num_planes =
758 i915_num_planes_from_modifier(bo->drv, data->format, data->format_modifier);
Robert Mader96058f92022-04-05 12:15:11 +0200759
Gurchetan Singhfcad5ad2017-01-05 20:39:31 -0800760 ret = drv_prime_bo_import(bo, data);
761 if (ret)
762 return ret;
763
Mohanram Meenakshisundaram03776352022-08-11 17:14:04 +0000764 /* Set/Get tiling ioctl not supported based on fence availability
765 Refer : "https://patchwork.freedesktop.org/patch/325343/"
766 */
767 if (i915->num_fences_avail) {
768 /* TODO(gsingh): export modifiers and get rid of backdoor tiling. */
769 gem_get_tiling.handle = bo->handles[0].u32;
Gurchetan Singhfcad5ad2017-01-05 20:39:31 -0800770
Mohanram Meenakshisundaram03776352022-08-11 17:14:04 +0000771 ret = drmIoctl(bo->drv->fd, DRM_IOCTL_I915_GEM_GET_TILING, &gem_get_tiling);
772 if (ret) {
773 drv_gem_bo_destroy(bo);
774 drv_loge("DRM_IOCTL_I915_GEM_GET_TILING failed.\n");
775 return ret;
776 }
777 bo->meta.tiling = gem_get_tiling.tiling_mode;
Gurchetan Singhfcad5ad2017-01-05 20:39:31 -0800778 }
Gurchetan Singhfcad5ad2017-01-05 20:39:31 -0800779 return 0;
780}
781
Gurchetan Singhee43c302017-11-14 18:20:27 -0800782static void *i915_bo_map(struct bo *bo, struct vma *vma, size_t plane, uint32_t map_flags)
Gurchetan Singhef920532016-08-12 16:38:25 -0700783{
784 int ret;
Kristian H. Kristensen8e9c2412020-11-19 19:20:04 +0000785 void *addr = MAP_FAILED;
Gurchetan Singhef920532016-08-12 16:38:25 -0700786
Vipin Anand97e07de2022-08-12 04:47:34 +0000787 if ((bo->meta.format_modifier == I915_FORMAT_MOD_Y_TILED_CCS) ||
788 (bo->meta.format_modifier == I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS) ||
789 (bo->meta.format_modifier == I915_FORMAT_MOD_4_TILED))
Vipin Ananda0af3092020-06-17 10:53:02 +0530790 return MAP_FAILED;
791
Gurchetan Singh298b7572019-09-19 09:55:18 -0700792 if (bo->meta.tiling == I915_TILING_NONE) {
Gurchetan Singh99644382020-10-07 15:28:11 -0700793 struct drm_i915_gem_mmap gem_map = { 0 };
Tomasz Figa39eb9512018-11-01 00:45:31 +0900794 /* TODO(b/118799155): We don't seem to have a good way to
795 * detect the use cases for which WC mapping is really needed.
796 * The current heuristic seems overly coarse and may be slowing
797 * down some other use cases unnecessarily.
798 *
799 * For now, care must be taken not to use WC mappings for
800 * Renderscript and camera use cases, as they're
801 * performance-sensitive. */
Gurchetan Singh298b7572019-09-19 09:55:18 -0700802 if ((bo->meta.use_flags & BO_USE_SCANOUT) &&
803 !(bo->meta.use_flags &
Tomasz Figa39eb9512018-11-01 00:45:31 +0900804 (BO_USE_RENDERSCRIPT | BO_USE_CAMERA_READ | BO_USE_CAMERA_WRITE)))
Gurchetan Singh5af20232017-09-19 15:10:58 -0700805 gem_map.flags = I915_MMAP_WC;
806
Gurchetan Singhfcad5ad2017-01-05 20:39:31 -0800807 gem_map.handle = bo->handles[0].u32;
808 gem_map.offset = 0;
Gurchetan Singh298b7572019-09-19 09:55:18 -0700809 gem_map.size = bo->meta.total_size;
Gurchetan Singhfcad5ad2017-01-05 20:39:31 -0800810
811 ret = drmIoctl(bo->drv->fd, DRM_IOCTL_I915_GEM_MMAP, &gem_map);
Kristian H. Kristensen8e9c2412020-11-19 19:20:04 +0000812 /* DRM_IOCTL_I915_GEM_MMAP mmaps the underlying shm
813 * file and returns a user space address directly, ie,
814 * doesn't go through mmap. If we try that on a
815 * dma-buf that doesn't have a shm file, i915.ko
816 * returns ENXIO. Fall through to
817 * DRM_IOCTL_I915_GEM_MMAP_GTT in that case, which
818 * will mmap on the drm fd instead. */
819 if (ret == 0)
820 addr = (void *)(uintptr_t)gem_map.addr_ptr;
821 }
Gurchetan Singhfcad5ad2017-01-05 20:39:31 -0800822
Kristian H. Kristensen8e9c2412020-11-19 19:20:04 +0000823 if (addr == MAP_FAILED) {
Gurchetan Singh99644382020-10-07 15:28:11 -0700824 struct drm_i915_gem_mmap_gtt gem_map = { 0 };
Gurchetan Singhfcad5ad2017-01-05 20:39:31 -0800825
826 gem_map.handle = bo->handles[0].u32;
Gurchetan Singhfcad5ad2017-01-05 20:39:31 -0800827 ret = drmIoctl(bo->drv->fd, DRM_IOCTL_I915_GEM_MMAP_GTT, &gem_map);
828 if (ret) {
Yiwei Zhang04954732022-07-13 23:34:33 +0000829 drv_loge("DRM_IOCTL_I915_GEM_MMAP_GTT failed\n");
Gurchetan Singhfcad5ad2017-01-05 20:39:31 -0800830 return MAP_FAILED;
831 }
832
Gurchetan Singh298b7572019-09-19 09:55:18 -0700833 addr = mmap(0, bo->meta.total_size, drv_get_prot(map_flags), MAP_SHARED,
834 bo->drv->fd, gem_map.offset);
Gurchetan Singhfcad5ad2017-01-05 20:39:31 -0800835 }
836
837 if (addr == MAP_FAILED) {
Yiwei Zhang04954732022-07-13 23:34:33 +0000838 drv_loge("i915 GEM mmap failed\n");
Gurchetan Singhfcad5ad2017-01-05 20:39:31 -0800839 return addr;
840 }
841
Gurchetan Singh298b7572019-09-19 09:55:18 -0700842 vma->length = bo->meta.total_size;
Gurchetan Singhfcad5ad2017-01-05 20:39:31 -0800843 return addr;
844}
Gurchetan Singh1a31e602016-10-06 10:58:00 -0700845
Gurchetan Singh47e629b2017-11-02 14:07:18 -0700846static int i915_bo_invalidate(struct bo *bo, struct mapping *mapping)
Gurchetan Singh2d1877f2017-10-10 14:12:46 -0700847{
848 int ret;
Gurchetan Singh99644382020-10-07 15:28:11 -0700849 struct drm_i915_gem_set_domain set_domain = { 0 };
Gurchetan Singh2d1877f2017-10-10 14:12:46 -0700850
Gurchetan Singh2d1877f2017-10-10 14:12:46 -0700851 set_domain.handle = bo->handles[0].u32;
Gurchetan Singh298b7572019-09-19 09:55:18 -0700852 if (bo->meta.tiling == I915_TILING_NONE) {
Gurchetan Singh2d1877f2017-10-10 14:12:46 -0700853 set_domain.read_domains = I915_GEM_DOMAIN_CPU;
Gurchetan Singh47e629b2017-11-02 14:07:18 -0700854 if (mapping->vma->map_flags & BO_MAP_WRITE)
Gurchetan Singh2d1877f2017-10-10 14:12:46 -0700855 set_domain.write_domain = I915_GEM_DOMAIN_CPU;
856 } else {
857 set_domain.read_domains = I915_GEM_DOMAIN_GTT;
Gurchetan Singh47e629b2017-11-02 14:07:18 -0700858 if (mapping->vma->map_flags & BO_MAP_WRITE)
Gurchetan Singh2d1877f2017-10-10 14:12:46 -0700859 set_domain.write_domain = I915_GEM_DOMAIN_GTT;
860 }
861
862 ret = drmIoctl(bo->drv->fd, DRM_IOCTL_I915_GEM_SET_DOMAIN, &set_domain);
863 if (ret) {
Yiwei Zhang04954732022-07-13 23:34:33 +0000864 drv_loge("DRM_IOCTL_I915_GEM_SET_DOMAIN with %d\n", ret);
Gurchetan Singh2d1877f2017-10-10 14:12:46 -0700865 return ret;
866 }
867
868 return 0;
869}
870
Gurchetan Singh47e629b2017-11-02 14:07:18 -0700871static int i915_bo_flush(struct bo *bo, struct mapping *mapping)
Gurchetan Singhfcad5ad2017-01-05 20:39:31 -0800872{
Gurchetan Singh68af9c22017-01-18 13:48:11 -0800873 struct i915_device *i915 = bo->drv->priv;
Gurchetan Singh298b7572019-09-19 09:55:18 -0700874 if (!i915->has_llc && bo->meta.tiling == I915_TILING_NONE)
Gurchetan Singh47e629b2017-11-02 14:07:18 -0700875 i915_clflush(mapping->vma->addr, mapping->vma->length);
Gurchetan Singhfcad5ad2017-01-05 20:39:31 -0800876
Gurchetan Singh8e02e052017-09-14 14:18:43 -0700877 return 0;
Gurchetan Singhef920532016-08-12 16:38:25 -0700878}
879
Gurchetan Singh3e9d3832017-10-31 10:36:25 -0700880const struct backend backend_i915 = {
Stéphane Marchesin25a26062014-09-12 16:18:59 -0700881 .name = "i915",
Gurchetan Singhd7c84fd2016-08-16 18:18:24 -0700882 .init = i915_init,
883 .close = i915_close,
David Stevens26fe6822020-03-09 12:23:42 +0000884 .bo_compute_metadata = i915_bo_compute_metadata,
885 .bo_create_from_metadata = i915_bo_create_from_metadata,
Gurchetan Singhcc015e82017-01-17 16:15:25 -0800886 .bo_destroy = drv_gem_bo_destroy,
Gurchetan Singhfcad5ad2017-01-05 20:39:31 -0800887 .bo_import = i915_bo_import,
Gurchetan Singhd7c84fd2016-08-16 18:18:24 -0700888 .bo_map = i915_bo_map,
Gurchetan Singh8e02e052017-09-14 14:18:43 -0700889 .bo_unmap = drv_bo_munmap,
Gurchetan Singh2d1877f2017-10-10 14:12:46 -0700890 .bo_invalidate = i915_bo_invalidate,
Gurchetan Singh8e02e052017-09-14 14:18:43 -0700891 .bo_flush = i915_bo_flush,
Yiwei Zhangb8ad7b82021-10-01 17:55:14 +0000892 .resolve_format_and_use_flags = drv_resolve_format_and_use_flags_helper,
Robert Mader96058f92022-04-05 12:15:11 +0200893 .num_planes_from_modifier = i915_num_planes_from_modifier,
Stéphane Marchesin25a26062014-09-12 16:18:59 -0700894};
895
896#endif