blob: 1dd67a039b7085f850cf1a86620e1adba2529ca0 [file] [log] [blame]
Stéphane Marchesin25a26062014-09-12 16:18:59 -07001/*
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.
5 */
6
7#ifdef GBM_I915
8
9#include <errno.h>
10#include <string.h>
11#include <stdio.h>
12#include <xf86drm.h>
13#include <i915_drm.h>
14
15#include "gbm_priv.h"
16#include "helpers.h"
17#include "util.h"
18
19struct gbm_i915_device
20{
21 int gen;
22};
23
24
25static int get_gen(int device_id)
26{
27 const uint16_t gen3_ids[] = {0x2582, 0x2592, 0x2772, 0x27A2, 0x27AE, 0x29C2, 0x29B2, 0x29D2, 0xA001, 0xA011};
Stéphane Marchesina39dfde2014-09-15 15:38:25 -070028 unsigned i;
Stéphane Marchesin25a26062014-09-12 16:18:59 -070029 for(i = 0; i < ARRAY_SIZE(gen3_ids); i++)
30 if (gen3_ids[i] == device_id)
31 return 3;
32
33 return 4;
34}
35
36int gbm_i915_init(struct gbm_device *gbm)
37{
38 struct gbm_i915_device *i915_gbm;
39 drm_i915_getparam_t get_param;
40 int device_id;
41 int ret;
42
43 i915_gbm = (struct gbm_i915_device*)malloc(sizeof(*i915_gbm));
44 if (!i915_gbm)
45 return -1;
46
47 memset(&get_param, 0, sizeof(get_param));
48 get_param.param = I915_PARAM_CHIPSET_ID;
49 get_param.value = &device_id;
50 ret = drmIoctl(gbm->fd, DRM_IOCTL_I915_GETPARAM, &get_param);
51 if (ret) {
52 free(i915_gbm);
53 return -1;
54 }
55
56 i915_gbm->gen = get_gen(device_id);
57
58 gbm->priv = i915_gbm;
59
60 return 0;
61}
62
63void gbm_i915_close(struct gbm_device *gbm)
64{
65 free(gbm->priv);
66 gbm->priv = NULL;
67}
68
69static int i915_get_pitch(struct gbm_device *gbm, uint32_t pitch, int tiling_mode)
70{
71 struct gbm_i915_device *dev_priv = (struct gbm_i915_device *)gbm->priv;
72 if (tiling_mode == I915_TILING_NONE)
73 return ALIGN(pitch, 64);
74
75 if (dev_priv->gen >= 4) {
76 uint32_t tile_width = tiling_mode == I915_TILING_X ? 512 : 128;
77 return ALIGN(pitch, tile_width);
78 } else {
79 uint32_t i = 128;
80 while(i < pitch)
81 i <<= 1;
82 return i;
83 }
84}
85
86int gbm_i915_bo_create(struct gbm_bo *bo, uint32_t width, uint32_t height, uint32_t format, uint32_t flags)
87{
88 size_t size = width * height * gbm_bytes_from_format(format);
89 struct drm_i915_gem_create gem_create;
90 struct drm_i915_gem_set_tiling gem_set_tiling;
91 uint32_t tiling_mode = I915_TILING_NONE;
92 int ret;
93
94 memset(&gem_create, 0, sizeof(gem_create));
95 gem_create.size = size;
96
97 ret = drmIoctl(bo->gbm->fd, DRM_IOCTL_I915_GEM_CREATE, &gem_create);
98 if (ret)
99 return ret;
100
101 bo->handle.u32 = gem_create.handle;
102 bo->size = size;
103
104 if (flags & GBM_BO_USE_CURSOR)
105 tiling_mode = I915_TILING_NONE;
106 else if (flags & GBM_BO_USE_SCANOUT)
107 tiling_mode = I915_TILING_X;
108 else if (flags & GBM_BO_USE_RENDERING)
109 tiling_mode = I915_TILING_Y;
110
111 memset(&gem_set_tiling, 0, sizeof(gem_set_tiling));
112 do {
113 gem_set_tiling.handle = bo->handle.u32;
114 gem_set_tiling.tiling_mode = tiling_mode;
115 gem_set_tiling.stride = i915_get_pitch(bo->gbm,
116 width * gbm_bytes_from_format(format),
117 tiling_mode);
118 ret = drmIoctl(bo->gbm->fd, DRM_IOCTL_I915_GEM_SET_TILING, &gem_set_tiling);
119 } while (ret == -1 && (errno == EINTR || errno == EAGAIN));
120
121 if (ret == -1) {
122 struct drm_gem_close gem_close;
123 gem_close.handle = bo->handle.u32;
124 drmIoctl(bo->gbm->fd, DRM_IOCTL_GEM_CLOSE, &gem_close);
125 return -errno;
126 }
127
128 return 0;
129}
130
131const struct gbm_driver gbm_driver_i915 =
132{
133 .name = "i915",
134 .init = gbm_i915_init,
135 .close = gbm_i915_close,
136 .bo_create = gbm_i915_bo_create,
137 .bo_destroy = gbm_gem_bo_destroy,
138 .format_list = {
139 {GBM_FORMAT_XRGB8888, GBM_BO_USE_SCANOUT | GBM_BO_USE_CURSOR | GBM_BO_USE_RENDERING | GBM_BO_USE_WRITE},
140 {GBM_FORMAT_ARGB8888, GBM_BO_USE_SCANOUT | GBM_BO_USE_CURSOR | GBM_BO_USE_RENDERING | GBM_BO_USE_WRITE},
141 {GBM_FORMAT_XBGR8888, GBM_BO_USE_SCANOUT | GBM_BO_USE_CURSOR | GBM_BO_USE_RENDERING | GBM_BO_USE_WRITE},
142 {GBM_FORMAT_ABGR8888, GBM_BO_USE_SCANOUT | GBM_BO_USE_CURSOR | GBM_BO_USE_RENDERING | GBM_BO_USE_WRITE},
143 {GBM_FORMAT_XRGB1555, GBM_BO_USE_SCANOUT | GBM_BO_USE_CURSOR | GBM_BO_USE_RENDERING | GBM_BO_USE_WRITE},
144 {GBM_FORMAT_ARGB1555, GBM_BO_USE_SCANOUT | GBM_BO_USE_CURSOR | GBM_BO_USE_RENDERING | GBM_BO_USE_WRITE},
145 {GBM_FORMAT_RGB565, GBM_BO_USE_SCANOUT | GBM_BO_USE_CURSOR | GBM_BO_USE_RENDERING | GBM_BO_USE_WRITE},
146 }
147};
148
149#endif