xref: /OK3568_Linux_fs/external/camera_engine_rkaiq/rkisp_demo/demo/drmDsp/modeset.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 
5 #include <xf86drm.h>
6 #include <xf86drmMode.h>
7 #include <drm_fourcc.h>
8 
9 #include "modeset.h"
10 #include "bo.h"
11 #include "dev.h"
12 
initialize_screens(struct sp_dev * dev)13 int initialize_screens(struct sp_dev* dev) {
14   int ret, i, j;
15 
16   for (i = 0; i < dev->num_connectors; i++) {
17     drmModeConnectorPtr c = dev->connectors[i];
18     drmModeModeInfoPtr m = NULL;
19     drmModeEncoderPtr e = NULL;
20     struct sp_crtc* cr = NULL;
21 
22     if (c->connection != DRM_MODE_CONNECTED)
23       continue;
24 
25     if (!c->count_modes) {
26       printf("connector has no modes, skipping\n");
27       continue;
28     }
29 
30     /* Take the first unless there's a preferred mode */
31     m = &c->modes[0];
32     for (j = 0; j < c->count_modes; j++) {
33       drmModeModeInfoPtr tmp_m = &c->modes[j];
34 
35       if (!(tmp_m->type & DRM_MODE_TYPE_PREFERRED))
36         continue;
37 
38       m = tmp_m;
39       break;
40     }
41 
42     if (!c->encoder_id) {
43       /*
44        * default drm encoder not attached connector, just
45        * select the first one.
46        */
47       if (dev->num_encoders) {
48         e = dev->encoders[0];
49         c->encoder_id = e->encoder_id;
50       } else {
51         printf("no encoder attached to the connector\n");
52         continue;
53       }
54     }
55 
56     for (j = 0; j < dev->num_encoders; j++) {
57       e = dev->encoders[j];
58       if (e->encoder_id == c->encoder_id)
59         break;
60     }
61     if (j == dev->num_encoders) {
62       printf("could not find encoder for the connector\n");
63       continue;
64     }
65 
66     if (!e->crtc_id) {
67       /*
68        * default drm crtc not attached encoder, just
69        * select the first one.
70        */
71       if (dev->num_crtcs) {
72         cr = &dev->crtcs[j];
73         e->crtc_id = cr->crtc->crtc_id;
74       } else {
75         printf("no crtc attached to the encoder\n");
76         continue;
77       }
78     }
79 
80     for (j = 0; j < dev->num_crtcs; j++) {
81       cr = &dev->crtcs[j];
82 
83       if (cr->crtc->crtc_id == e->crtc_id)
84         break;
85     }
86     if (j == dev->num_crtcs) {
87       printf("could not find crtc for the encoder\n");
88       continue;
89     }
90     if (cr->scanout) {
91       printf("crtc already in use\n");
92       continue;
93     }
94 
95     /* XXX: Hardcoding the format here... :| */
96     cr->scanout = create_sp_bo(dev, m->hdisplay, m->vdisplay,
97                                24, 32, DRM_FORMAT_XRGB8888, 0);
98     if (!cr->scanout) {
99       printf("failed to create new scanout bo\n");
100       continue;
101     }
102 
103     ret = add_fb_sp_bo(cr->scanout, DRM_FORMAT_XRGB8888);
104     if (ret) {
105       printf("failed to add fb ret=%d\n", ret);
106       continue;
107     }
108 
109     //fill_bo(cr->scanout, 0xFF, 0x0, 0x0, 0xFF);
110 
111     ret = drmModeSetCrtc(dev->fd, cr->crtc->crtc_id,
112                          cr->scanout->fb_id, 0, 0, &c->connector_id,
113                          1, m);
114     if (ret) {
115       printf("failed to set crtc mode ret=%d\n", ret);
116       continue;
117     }
118     cr->crtc = drmModeGetCrtc(dev->fd, cr->crtc->crtc_id);
119     /*
120      * Todo:
121      * I don't know why crtc mode is empty, just copy PREFERRED mode
122      * for it.
123      */
124     memcpy(&cr->crtc->mode, m, sizeof(*m));
125   }
126   return 0;
127 }
128 
get_sp_plane(struct sp_dev * dev,struct sp_crtc * crtc)129 struct sp_plane* get_sp_plane(struct sp_dev* dev, struct sp_crtc* crtc) {
130   int i;
131 
132   for (i = 0; i < dev->num_planes; i++) {
133     struct sp_plane* p = &dev->planes[i];
134 
135     if (p->in_use)
136       continue;
137 
138     if (!(p->plane->possible_crtcs & (1 << crtc->pipe)))
139       continue;
140 
141     p->in_use = 1;
142     return p;
143   }
144   return NULL;
145 }
146 
put_sp_plane(struct sp_plane * plane)147 void put_sp_plane(struct sp_plane* plane) {
148   drmModePlanePtr p;
149 
150   /* Get the latest plane information (most notably the crtc_id) */
151   p = drmModeGetPlane(plane->dev->fd, plane->plane->plane_id);
152   if (p)
153     plane->plane = p;
154 
155   if (plane->plane->crtc_id)
156     drmModeSetPlane(plane->dev->fd, plane->plane->plane_id,
157                     plane->plane->crtc_id, 0, 0,
158                     0, 0, 0, 0, 0, 0, 0, 0);
159 
160   if (plane->bo) {
161     free_sp_bo(plane->bo);
162     plane->bo = NULL;
163   }
164   plane->in_use = 0;
165 }
166 
set_sp_plane(struct sp_dev * dev,struct sp_plane * plane,struct sp_crtc * crtc,int x,int y)167 int set_sp_plane(struct sp_dev* dev, struct sp_plane* plane,
168                  struct sp_crtc* crtc, int x, int y) {
169   int ret;
170   uint32_t w, h;
171 
172   w = plane->bo->width;
173   h = plane->bo->height;
174 
175   if ((w + x) > crtc->crtc->mode.hdisplay)
176     w = crtc->crtc->mode.hdisplay - x;
177   if ((h + y) > crtc->crtc->mode.vdisplay)
178     h = crtc->crtc->mode.vdisplay - y;
179 
180   ret = drmModeSetPlane(dev->fd, plane->plane->plane_id,
181                         crtc->crtc->crtc_id, plane->bo->fb_id, 0, x, y, w, h,
182                         0, 0, w << 16, h << 16);
183   if (ret) {
184     printf("failed to set plane to crtc ret=%d\n", ret);
185     return ret;
186   }
187 
188   return ret;
189 }
190 #ifdef USE_ATOMIC_API
set_sp_plane_pset(struct sp_dev * dev,struct sp_plane * plane,drmModePropertySetPtr pset,struct sp_crtc * crtc,int x,int y)191 int set_sp_plane_pset(struct sp_dev* dev, struct sp_plane* plane,
192                       drmModePropertySetPtr pset, struct sp_crtc* crtc, int x, int y) {
193   int ret;
194   uint32_t w, h;
195 
196   w = plane->bo->width;
197   h = plane->bo->height;
198 
199   if ((w + x) > crtc->crtc->mode.hdisplay)
200     w = crtc->crtc->mode.hdisplay - x;
201   if ((h + y) > crtc->crtc->mode.vdisplay)
202     h = crtc->crtc->mode.vdisplay - y;
203 
204   ret = drmModePropertySetAdd(pset, plane->plane->plane_id,
205                               plane->crtc_pid, crtc->crtc->crtc_id)
206         || drmModePropertySetAdd(pset, plane->plane->plane_id,
207                                  plane->fb_pid, plane->bo->fb_id)
208         || drmModePropertySetAdd(pset, plane->plane->plane_id,
209                                  plane->crtc_x_pid, x)
210         || drmModePropertySetAdd(pset, plane->plane->plane_id,
211                                  plane->crtc_y_pid, y)
212         || drmModePropertySetAdd(pset, plane->plane->plane_id,
213                                  plane->crtc_w_pid, w)
214         || drmModePropertySetAdd(pset, plane->plane->plane_id,
215                                  plane->crtc_h_pid, h)
216         || drmModePropertySetAdd(pset, plane->plane->plane_id,
217                                  plane->src_x_pid, 0)
218         || drmModePropertySetAdd(pset, plane->plane->plane_id,
219                                  plane->src_y_pid, 0)
220         || drmModePropertySetAdd(pset, plane->plane->plane_id,
221                                  plane->src_w_pid, w << 16)
222         || drmModePropertySetAdd(pset, plane->plane->plane_id,
223                                  plane->src_h_pid, h << 16);
224   if (ret) {
225     printf("failed to add properties to the set\n");
226     return -1;
227   }
228 
229   return ret;
230 }
231 #endif
232