2 * Copyright (c) 2014 The Chromium OS Authors. All rights reserved.
3 * Use of this source code is governed by a BSD-style license that can be
4 * found in the LICENSE file.
20 struct gbm_i915_device
26 static int get_gen(int device_id)
28 const uint16_t gen3_ids[] = {0x2582, 0x2592, 0x2772, 0x27A2, 0x27AE,
29 0x29C2, 0x29B2, 0x29D2, 0xA001, 0xA011};
31 for(i = 0; i < ARRAY_SIZE(gen3_ids); i++)
32 if (gen3_ids[i] == device_id)
38 int gbm_i915_init(struct gbm_device *gbm)
40 struct gbm_i915_device *i915_gbm;
41 drm_i915_getparam_t get_param;
45 i915_gbm = (struct gbm_i915_device*)malloc(sizeof(*i915_gbm));
49 memset(&get_param, 0, sizeof(get_param));
50 get_param.param = I915_PARAM_CHIPSET_ID;
51 get_param.value = &device_id;
52 ret = drmIoctl(gbm->fd, DRM_IOCTL_I915_GETPARAM, &get_param);
54 fprintf(stderr, "minigbm: DRM_IOCTL_I915_GETPARAM failed\n");
59 i915_gbm->gen = get_gen(device_id);
66 void gbm_i915_close(struct gbm_device *gbm)
72 static void i915_align_dimensions(struct gbm_device *gbm, uint32_t tiling_mode,
73 uint32_t *width, uint32_t *height, int bpp)
75 struct gbm_i915_device *i915_gbm = (struct gbm_i915_device *)gbm->priv;
76 uint32_t width_alignment = 4, height_alignment = 4;
80 case I915_TILING_NONE:
81 width_alignment = 64 / bpp;
85 width_alignment = 512 / bpp;
90 if (i915_gbm->gen == 3) {
91 width_alignment = 512 / bpp;
94 width_alignment = 128 / bpp;
95 height_alignment = 32;
100 if (i915_gbm->gen > 3) {
101 *width = ALIGN(*width, width_alignment);
102 *height = ALIGN(*height, height_alignment);
105 for (w = width_alignment; w < *width; w <<= 1)
108 *height = ALIGN(*height, height_alignment);
112 static int i915_verify_dimensions(struct gbm_device *gbm, uint32_t stride,
115 struct gbm_i915_device *i915_gbm = (struct gbm_i915_device *)gbm->priv;
116 if (i915_gbm->gen <= 3 && stride > 8192)
122 int gbm_i915_bo_create(struct gbm_bo *bo, uint32_t width, uint32_t height,
123 uint32_t format, uint32_t flags)
125 struct gbm_device *gbm = bo->gbm;
126 int bpp = gbm_stride_from_format(format, 1);
127 struct drm_i915_gem_create gem_create;
128 struct drm_i915_gem_set_tiling gem_set_tiling;
129 uint32_t tiling_mode = I915_TILING_NONE;
133 if (flags & (GBM_BO_USE_CURSOR | GBM_BO_USE_LINEAR))
134 tiling_mode = I915_TILING_NONE;
135 else if (flags & GBM_BO_USE_SCANOUT)
136 tiling_mode = I915_TILING_X;
137 else if (flags & GBM_BO_USE_RENDERING)
138 tiling_mode = I915_TILING_Y;
140 i915_align_dimensions(gbm, tiling_mode, &width, &height, bpp);
142 bo->strides[0] = width * bpp;
144 if (!i915_verify_dimensions(gbm, bo->strides[0], height))
147 memset(&gem_create, 0, sizeof(gem_create));
148 size = width * height * bpp;
149 gem_create.size = size;
151 ret = drmIoctl(gbm->fd, DRM_IOCTL_I915_GEM_CREATE, &gem_create);
153 fprintf(stderr, "minigbm: DRM_IOCTL_I915_GEM_CREATE failed "
154 "(size=%zu)\n", size);
157 bo->handles[0].u32 = gem_create.handle;
161 memset(&gem_set_tiling, 0, sizeof(gem_set_tiling));
163 gem_set_tiling.handle = bo->handles[0].u32;
164 gem_set_tiling.tiling_mode = tiling_mode;
165 gem_set_tiling.stride = bo->strides[0];
166 ret = drmIoctl(gbm->fd, DRM_IOCTL_I915_GEM_SET_TILING,
168 } while (ret == -1 && (errno == EINTR || errno == EAGAIN));
171 struct drm_gem_close gem_close;
172 gem_close.handle = bo->handles[0].u32;
173 fprintf(stderr, "minigbm: DRM_IOCTL_I915_GEM_SET_TILING failed "
174 "errno=%x (handle=%x, tiling=%x, stride=%x)\n",
176 gem_set_tiling.handle,
177 gem_set_tiling.tiling_mode,
178 gem_set_tiling.stride);
179 drmIoctl(gbm->fd, DRM_IOCTL_GEM_CLOSE, &gem_close);
186 const struct gbm_driver gbm_driver_i915 =
189 .init = gbm_i915_init,
190 .close = gbm_i915_close,
191 .bo_create = gbm_i915_bo_create,
192 .bo_destroy = gbm_gem_bo_destroy,
194 {GBM_FORMAT_XRGB8888, GBM_BO_USE_SCANOUT | GBM_BO_USE_CURSOR | GBM_BO_USE_RENDERING | GBM_BO_USE_WRITE},
195 {GBM_FORMAT_XRGB8888, GBM_BO_USE_SCANOUT | GBM_BO_USE_CURSOR | GBM_BO_USE_WRITE | GBM_BO_USE_LINEAR},
196 {GBM_FORMAT_ARGB8888, GBM_BO_USE_SCANOUT | GBM_BO_USE_CURSOR | GBM_BO_USE_RENDERING | GBM_BO_USE_WRITE},
197 {GBM_FORMAT_ARGB8888, GBM_BO_USE_SCANOUT | GBM_BO_USE_CURSOR | GBM_BO_USE_WRITE | GBM_BO_USE_LINEAR},
198 {GBM_FORMAT_XBGR8888, GBM_BO_USE_SCANOUT | GBM_BO_USE_CURSOR | GBM_BO_USE_RENDERING | GBM_BO_USE_WRITE},
199 {GBM_FORMAT_ABGR8888, GBM_BO_USE_SCANOUT | GBM_BO_USE_CURSOR | GBM_BO_USE_RENDERING | GBM_BO_USE_WRITE},
200 {GBM_FORMAT_XRGB1555, GBM_BO_USE_SCANOUT | GBM_BO_USE_CURSOR | GBM_BO_USE_RENDERING | GBM_BO_USE_WRITE},
201 {GBM_FORMAT_ARGB1555, GBM_BO_USE_SCANOUT | GBM_BO_USE_CURSOR | GBM_BO_USE_RENDERING | GBM_BO_USE_WRITE},
202 {GBM_FORMAT_RGB565, GBM_BO_USE_SCANOUT | GBM_BO_USE_CURSOR | GBM_BO_USE_RENDERING | GBM_BO_USE_WRITE},
203 {GBM_FORMAT_UYVY, GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING | GBM_BO_USE_WRITE},
204 {GBM_FORMAT_UYVY, GBM_BO_USE_SCANOUT | GBM_BO_USE_WRITE | GBM_BO_USE_LINEAR},
205 {GBM_FORMAT_YUYV, GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING | GBM_BO_USE_WRITE},
206 {GBM_FORMAT_YUYV, GBM_BO_USE_SCANOUT | GBM_BO_USE_WRITE | GBM_BO_USE_LINEAR},