blob: 93acd8310dbc25542020490fed802a3f24fff1e8 [file] [log] [blame]
leng.fang91856072024-06-07 14:12:54 +08001#include <pthread.h>
2
3#include "modepolicyfunc.h"
4#include "DisplayAdapter.h"
5#include "modepolicy_aml.h"
6
7weston_ctx *gCtx = NULL;
8static int g_activeLevel = 3;
9
leng.fang13fd3982024-07-03 19:09:58 +080010static char *prop_changed_and_mode[] = {
11 "color_space",
12 "color_depth"
13};
14
leng.fang91856072024-06-07 14:12:54 +080015weston_ctx *weston_get_ctx()
16{
17 if (!gCtx) {
18 gCtx = (weston_ctx *)calloc(1, sizeof(*gCtx));
19 gCtx->need_update_hdmi_param = false;
leng.fangb1081a32024-06-25 14:41:37 +080020 gCtx->scaling = -1;
leng.fang91856072024-06-07 14:12:54 +080021 wl_list_init(&gCtx->prop_list);
22 }
23 return gCtx;
24}
25
26static void weston_prop_list_init(weston_ctx *ctx)
27{
28 prop_info *info, *tmp;
29 if (!wl_list_empty(&ctx->prop_list)) {
30 wl_list_for_each_safe(info, tmp, &ctx->prop_list, link) {
31 wl_list_remove(&info->link);
32 free(info);
33 }
34 }
35 wl_list_init(&ctx->prop_list);
36}
37
38static int weston_add_property_item(weston_ctx *ctx,
39 const char *name, int id, int prop_id)
40{
41 prop_info *info;
42
43 wl_list_for_each(info, &ctx->prop_list, link) {
44 if (!strcmp(name, info->name) && info->item_id == id)
45 return 0;
46 }
47
48 info = (prop_info *)calloc(1, sizeof(*info));
49 memcpy(info->name, name, sizeof(info->name));
50 info->item_id = id;
51 info->prop_id = prop_id;
52 info->need_change = 0;
53 MESON_LOGD("ctx: %p, name: %s, id: %d, prop_id: %d\n", ctx, name, id, prop_id);
54 wl_list_insert(&ctx->prop_list, &info->link);
55 return 0;
56}
57
58static int weston_add_property(weston_ctx *ctx, int id, int type)
59{
60 int i, len;
61 int value = 0;
62 drmModePropertyRes *propRes;
63 drmModeObjectProperties *props;
64
65 props = drmModeObjectGetProperties( ctx->drm_fd, id, type );
66 if ( props ) {
67 for ( i= 0; i < props->count_props; ++i ) {
68 propRes = drmModeGetProperty( ctx->drm_fd, props->props[i] );
69 if ( propRes ) {
70 weston_add_property_item(ctx, propRes->name, id, props->props[i]);
71 drmModeFreeProperty( propRes );
72 propRes = 0;
73 }
74 }
75 drmModeFreeObjectProperties( props );
76 props = 0;
77 }
78 return value;
79}
80
81static int weston_get_property_value(weston_ctx *ctx, const char * key, int id, int type)
82{
83 int i, len;
84 int value = 0;
85 drmModePropertyRes *propRes;
86 drmModeObjectProperties *props;
87
88 props = drmModeObjectGetProperties( ctx->drm_fd, id, type );
89 if ( props ) {
90 for ( i= 0; i < props->count_props; ++i ) {
91 propRes = drmModeGetProperty( ctx->drm_fd, props->props[i] );
92 if ( propRes ) {
93 len = strlen(propRes->name);
94 if ( !strncmp( propRes->name, key, len) ) {
95 MESON_LOGD("property %d name (%s) value (%lld)",
96 props->props[i], propRes->name, props->prop_values[i] );
97 value = props->prop_values[i];
98 drmModeFreeProperty( propRes );
99 propRes = 0;
100 break;
101 }
102 drmModeFreeProperty( propRes );
103 propRes = 0;
104 }
105 }
106 drmModeFreeObjectProperties( props );
107 props = 0;
108 }
109 return value;
110}
111
112static int weston_get_connector_property(const char * key)
113{
114 weston_ctx *ctx = weston_get_ctx();
115
116 return weston_get_property_value(ctx, key, ctx->conn->connector_id, DRM_MODE_OBJECT_CONNECTOR);
117}
118
119static int weston_get_crtc_property(const char * key)
120{
121 weston_ctx *ctx = weston_get_ctx();
122
123 return weston_get_property_value(ctx, key, ctx->crtc->crtc_id, DRM_MODE_OBJECT_CRTC);
124}
125
126static bool get_mode_name_for_weston_mode(
127 weston_ctx *ctx,
128 struct weston_mode *mode,
129 char *out)
130{
131 int i;
132 int current_interlaced;
133 const char *value;
134
135 if (mode && getModeNameForPix(out, mode->width, mode->height, mode->refresh, mode->flags))
136 return true;
137
138 value = bootenv_get("hdmimode");
139 if (value)
140 strcpy(out, value);
141 else
142 strcpy(out, "none");
143 MESON_LOGD("out: %s", out);
144 return false;
145}
146
147static bool weston_get_mode(char *mode)
148{
149 weston_ctx *ctx = weston_get_ctx();
150 struct weston_mode *wmode = NULL;
151
152 if (!wmode && ctx->current_mode.width != 0)
153 wmode = &ctx->current_mode;
154
155 return get_mode_name_for_weston_mode(ctx, wmode, mode);
156}
157
leng.fang9cf09e22024-07-17 20:01:11 +0800158bool WestonGetUbootIsBestmode()
leng.fang91856072024-06-07 14:12:54 +0800159{
160 const char *isbestmode = bootenv_get("is.bestmode");
161 if ( isbestmode != NULL ) {
162 if (strcmp("false", isbestmode) == 0)
163 return false;
164 else
165 return true;
166 } else
167 return true;
168}
169
170bool westonGetDrmModeInfoByName( weston_ctx *ctx, const char *mode, drmModeModeInfo *out_mode )
171{
172 bool result= false;
173
174 if ( ctx && mode && out_mode ) {
175 int width = -1, height = -1, rate = -1;
176 bool interlaced = false;
177 bool haveTarget = false;
178 bool useBestRate = true;
179
180 MESON_LOGD("%s: mode (%s)", __func__, mode);
181
182 if ( sscanf( mode, "%dx%dp%d", &width, &height, &rate ) == 3 ) {
183 interlaced = false;
184 } else if ( sscanf( mode, "%dx%di%d", &width, &height, &rate ) == 3 ) {
185 interlaced = true;
186 } else if ( sscanf( mode, "%dx%dx%d", &width, &height, &rate ) == 3 ) {
187 interlaced = false;
188 } else if ( sscanf( mode, "%dx%d", &width, &height ) == 2 ) {
189 int len = strlen(mode);
190 interlaced = (mode[len - 1] == 'i');
191 } else if (sscanf( mode, "%dp%dhz", &height,&rate ) == 2) {
192 interlaced = false;
193 width = -1;
194 } else if (sscanf( mode, "%di%dhz", &height,&rate ) == 2) {
195 interlaced = true;
196 width = -1;
197 } else if ( sscanf( mode, "%dp", &height ) == 1 ) {
198 int len = strlen(mode);
199 interlaced = (mode[len - 1] == 'i');
200 width = -1;
201 } else if (sscanf( mode, "smpte%dhz", &rate ) == 1) {
202 interlaced = false;
203 height = 2160;
204 width = 4096;
205 }
206
207 if ( height > 0 ) {
208 if ( width < 0 ) {
209 switch ( height ) {
210 case 480:
211 case 576:
212 width = 720;
213 break;
214 case 720:
215 width = 1280;
216 break;
217 case 1080:
218 width = 1920;
219 break;
220 case 1440:
221 width = 2560;
222 break;
223 case 2160:
224 width = 3840;
225 break;
226 case 2880:
227 width = 5120;
228 break;
229 case 4320:
230 width = 7680;
231 break;
232 default:
233 break;
234 }
235 }
236 }
237 MESON_LOGD("%s w %d h %d rate %d", __func__, width, height, rate);
238 if ( rate >= 0 )
239 useBestRate = false;
240
241 if ( (width > 0) && (height > 0) ) {
242 if ( ctx->drm_fd >= 0 ) {
243 drmModeRes *res = 0;
244 drmModeConnector *conn = 0;
245
246 res = drmModeGetResources( ctx->drm_fd );
247 if ( res ) {
248 int i;
249 for ( i = 0; i < res->count_connectors; ++i ) {
250 conn = drmModeGetConnector( ctx->drm_fd, res->connectors[i] );
251 if ( conn ) {
252 if ( conn->count_modes && (conn->connection == DRM_MODE_CONNECTED) )
253 break;
254 drmModeFreeConnector(conn);
255 conn = 0;
256 }
257 }
258 if ( conn ) {
259 uint32_t rateBest = 0;
260 int miBest = -1;
261
262 MESON_LOGD("%s: want %dx%dx%d interlaced %d use best rate %d",
263 __func__, width, height, rate, interlaced, useBestRate);
264 for ( i = 0; i < conn->count_modes; ++i ) {
265 MESON_LOGD("%s: consider mode %d: %dx%dx%d (%s) type 0x%x flags 0x%x",
266 __func__, i, conn->modes[i].hdisplay, conn->modes[i].vdisplay,
267 conn->modes[i].vrefresh, conn->modes[i].name,
268 conn->modes[i].type, conn->modes[i].flags );
269
270 if ( (conn->modes[i].hdisplay == width) &&
271 (conn->modes[i].vdisplay == height) ) {
272 bool modeIsInterlaced = (conn->modes[i].flags & DRM_MODE_FLAG_INTERLACE);
273 if ( modeIsInterlaced != interlaced )
274 continue;
275
276 if ( useBestRate ) {
277 if ( conn->modes[i].vrefresh > rateBest ) {
278 rateBest = conn->modes[i].vrefresh;
279 miBest = i;
280 }
281 } else if ( conn->modes[i].vrefresh == rate ) {
282 miBest = i;
283 break;
284 }
285 }
286 }
287
288 if ( miBest >= 0 ) {
289 *out_mode = conn->modes[miBest];
290
291 MESON_LOGI("%s: choosing output mode: %dx%dx%d (%s) flags 0x%x",
292 __func__,
293 out_mode->hdisplay,
294 out_mode->vdisplay,
295 out_mode->vrefresh,
296 out_mode->name,
297 out_mode->flags );
298
299 result= true;
300 } else {
301 MESON_LOGE("%s: failed to find a mode matching (%s)", __func__, mode);
302 }
303
304 drmModeFreeConnector( conn );
305 } else {
306 MESON_LOGE("%s: unable to get connector for card", __func__);
307 }
308 drmModeFreeResources(res);
309 } else {
310 MESON_LOGE("%s: unable to get card resources", __func__);
311 }
312 } else {
313 MESON_LOGE("%s: no open device", __func__);
314 }
315 } else {
316 MESON_LOGE("%s: unable to parse mode (%s)", __func__, mode);
317 }
318 }
319
320 return result;
321}
322
323static bool weston_set_mode(const char *mode)
324{
325 weston_ctx *ctx = weston_get_ctx();
326 drmModeModeInfo info = {0};
327
328 if (westonGetDrmModeInfoByName(ctx, mode, &info)) {
329 ctx->next_mode.width = info.hdisplay;
330 ctx->next_mode.height = info.vdisplay;
331 ctx->next_mode.refresh = info.vrefresh * 1000;
332 ctx->next_mode.flags = info.flags;
333 setBootConfig(info.name, WestonGetUbootIsBestmode());
334 ctx->mode_update = true;
335 ctx->mode_changed = true;
336 }
337 return 0;
338}
339
340static int weston_get_property(int id, const char *name, char *buf)
341{
342 weston_ctx *ctx = weston_get_ctx();
343 int value = 0;
344
345 if (!ctx->crtc || !ctx->conn)
346 return 0;
347
348 if (ctx->crtc->crtc_id == id)
349 value = weston_get_crtc_property(name);
350
351 if (ctx->conn->connector_id == id)
352 value = weston_get_connector_property(name);
353
354 snprintf(buf, MAX_BUF_LEN, "%d", value);
355 return 0;
356}
357
358static int weston_set_property(int id, const char *name, int value)
359{
360 prop_info *info;
361 weston_ctx *ctx = weston_get_ctx();
362
363 wl_list_for_each(info, &ctx->prop_list, link) {
364 if (!strcmp(name, info->name) && info->item_id == id) {
365 MESON_LOGD("name: %s, id: %d, prop: %d, value: %d\n",
366 name, id, info->prop_id, value);
367 info->value = value;
368 info->need_change = 1;
369 ctx->prop_changed = true;
370 break;
371 }
372 }
373
374 return 0;
375}
376
377static bool weston_set_colorattribute(const char *attr)
378{
379 weston_ctx *ctx = weston_get_ctx();
380 int depth = -1, value = -1; // default none
381
382 if ( attr && strlen(attr) > 3 ) {
383 if ( strstr (attr, "rgb") )
384 value = 0;
385 else if ( strstr (attr, "422") )
386 value = 1;
387 else if ( strstr (attr, "444") )
388 value = 2;
389 else if ( strstr (attr, "420") )
390 value = 3;
391 sscanf(attr + 4, "%dbit", &depth);
392 }
393 if (ctx && ctx->conn && ctx->conn->connector_type == DRM_MODE_CONNECTOR_HDMIA) {
394 weston_set_property(ctx->conn->connector_id, "color_space", value);
395 weston_set_property(ctx->conn->connector_id, "color_depth", depth);
396 }
397 return 0;
398}
399
400void weston_set_scaling_position(int x, int y, int w, int h)
401{
402 weston_ctx *ctx = weston_get_ctx();
403 const char *value = bootenv_get("scaling");
404 int scaling = 1;
405
406 if (value)
407 scaling = atoi(value);
408
leng.fangb1081a32024-06-25 14:41:37 +0800409 if (ctx && ctx->scaling != scaling)
410 ctx->scaling = scaling;
leng.fang91856072024-06-07 14:12:54 +0800411}
412
413CompositorFunctionCallBack callback = {
414 .get_mode = weston_get_mode,
415 .set_mode = weston_set_mode,
416 .set_colorattribute = weston_set_colorattribute,
417 .get_property = weston_get_property,
418 .set_property = weston_set_property,
419 .set_scaling_position = weston_set_scaling_position,
420};
421
leng.fangb1081a32024-06-25 14:41:37 +0800422static char *get_color_space_by_value(int value)
423{
424 char *str;
425
426 switch ( value ) {
427 case 0:
428 str = "rgb";
429 break;
430 case 1:
431 str = "422";
432 break;
433 case 2:
434 str = "444";
435 break;
436 case 3:
437 default:
438 str = "420";
439 break;
440 }
441 return str;
442}
443
444static int get_property_value(char *name)
445{
446 prop_info *info;
447 weston_ctx *ctx = weston_get_ctx();
448
449 wl_list_for_each(info, &ctx->prop_list, link) {
450 if (!strcmp(name, info->name)) {
451 if (info->need_change == 1)
452 return info->value;
453 }
454 }
455 return -1;
456}
457
458static int get_id_by_name(const char *name)
459{
460 prop_info *info;
461 weston_ctx *ctx = weston_get_ctx();
462
463 wl_list_for_each(info, &ctx->prop_list, link) {
464 if (!strcmp(name, info->name))
465 return info->item_id;
466 }
467 return -1;
468}
469
470static int mode_policy_parse_other(const char *name, int value)
471{
472 weston_ctx *ctx = weston_get_ctx();
473 char attrvalue[32] = { 0 };
474
475 if (STRCMPS(name, "scaling") == 0) {
476 if (ctx && ctx->scaling != value)
477 ctx->scaling = value;
478
479 sprintf(attrvalue, "%d", value);
480 bootenv_update("scaling", attrvalue);
481 return 0;
482 }
483 return -1;
484}
485
leng.fang13fd3982024-07-03 19:09:58 +0800486static void set_color_attribute(char *space, int depth)
487{
488 weston_ctx *ctx = weston_get_ctx();
489 char attrvalue[32] = { 0 };
490 char mode[] = { 0 };
491
492 sprintf(attrvalue, "%s,%dbit", space, depth);
493 setColorSpace(attrvalue);
494 weston_get_mode(mode);
495 setBootConfig(mode, false);
496}
497
leng.fangb1081a32024-06-25 14:41:37 +0800498int mode_policy_set_property(const char *name, int value)
499{
500 char attrvalue[32] = { 0 };
501 int color_space = 0;
502 int color_depth = 0;
503 int id = get_id_by_name(name);
504 MESON_LOGI("id: %d, name: %s, value: %d", id, name, value);
505
506 if (value < 0 || id < 0)
507 return mode_policy_parse_other(name, value);
508
509 if (strncmp(name, "dv_mode", sizeof("dv_mode")) == 0) {
510 setDvMode(value == 0 ? 1 : (value == 1 ? 2 : 0));
511 return 0;
512 } else if (strncmp(name, "color_depth", sizeof("color_depth")) == 0) {
513 color_space = get_property_value("color_space");
514 if (color_space >= 0) {
leng.fang13fd3982024-07-03 19:09:58 +0800515 set_color_attribute(get_color_space_by_value(color_space), value);
leng.fangb1081a32024-06-25 14:41:37 +0800516 return 0;
517 }
518 } else if (strncmp(name, "color_space", sizeof("color_space")) == 0) {
519 color_depth = get_property_value("color_depth");
520 if (color_depth >= 0) {
leng.fang13fd3982024-07-03 19:09:58 +0800521 set_color_attribute(get_color_space_by_value(value), color_depth);
leng.fangb1081a32024-06-25 14:41:37 +0800522 return 0;
523 }
524 } else if (strncmp(name, "meson.crtc.hdr_policy", sizeof("meson.crtc.hdr_policy")) == 0) {
525 sprintf(attrvalue, "%d", value);
526 bootenv_update("hdr_policy", attrvalue);
527 }
528
529 return weston_set_property(id, name, value);
530}
531
532int mode_policy_get_scaling()
533{
534 weston_ctx *ctx = weston_get_ctx();
535
536 if (ctx->scaling < 0)
537 return 100;
538
539 return ctx->scaling;
540}
541
leng.fang13fd3982024-07-03 19:09:58 +0800542static struct weston_mode
543drm_mode_to_weston_mode(drmModeModeInfoPtr info)
544{
545 struct weston_mode m;
546
547 m.width = info->hdisplay;
548 m.height = info->vdisplay;
549 //mhz:refresh * 1000
550 m.refresh = info->vrefresh * 1000;
551 //hack: use weston_mode's flags as drm_mode's flags.
552 m.flags = info->flags;
553 m.aspect_ratio = WESTON_MODE_PIC_AR_NONE;
554
555 return m;
556}
557
leng.fang91856072024-06-07 14:12:54 +0800558static drmModeCrtc *weston_get_crtc_for_conn(int drm_fd, drmModeConnector *conn)
559{
560 drmModeEncoder *encoder;
561 drmModeCrtc *crtc = NULL;
chen.wang19f2f82b2024-07-16 11:43:59 +0000562 drmModeRes *res = 0;
563 int i, j, k;
leng.fang91856072024-06-07 14:12:54 +0800564 /* Get the current mode on the crtc that's currently driving
565 * this connector. */
chen.wang19f2f82b2024-07-16 11:43:59 +0000566 res = drmModeGetResources(drm_fd);
567 if ( res ) {
568 for (i= 0; i < res->count_encoders; ++i ) {
569 uint32_t crtcId= 0;
570 bool found= false;
571 encoder = drmModeGetEncoder(drm_fd, res->encoders[i]);
572 if (encoder && conn && (encoder->encoder_id == conn->encoder_id)) {
573 found = true;
574 break;
575 }
576 for (j = 0; j < res->count_crtcs; j++) {
577 if (encoder->possible_crtcs & (1 << j)) {
578 crtcId= res->crtcs[j];
579 for (k = 0; k < res->count_crtcs; k++) {
580 if (res->crtcs[k] == crtcId) {
581 drmModeFreeEncoder(encoder);
582 encoder= drmModeGetEncoder(drm_fd, res->encoders[k]);
583 encoder->crtc_id= crtcId;
584 MESON_LOGD("got enc %p crtc id %d", drm_fd, crtcId);
585 found = true;
586 break;
587 }
588 }
589 if (found) {
590 break;
591 }
592 }
593 }
594 if (!found) {
595 drmModeFreeEncoder(encoder);
596 encoder= 0;
597 }
598 if (found) {
599 break;
600 }
601 }
602 if (encoder != NULL) {
603 crtc = drmModeGetCrtc(drm_fd, encoder->crtc_id);
604 drmModeFreeEncoder(encoder);
605 }
606 drmModeFreeResources( res );
607 res = 0;
608 } else {
609 MESON_LOGD("unable to get card resources");
leng.fang91856072024-06-07 14:12:54 +0800610 }
611 return crtc;
612}
613
614void init_mode_policy_without_mode(struct weston_head *head, int fd, drmModeConnector *conn)
615{
616 weston_ctx *ctx = weston_get_ctx();
617 drmModeCrtc *crtc = NULL;
leng.fange9d800e2024-07-12 13:31:59 +0800618 bool changed = false;
leng.fang91856072024-06-07 14:12:54 +0800619
leng.fange9d800e2024-07-12 13:31:59 +0800620 if (conn && conn->connector_type != DRM_MODE_CONNECTOR_TV) {
leng.fang91856072024-06-07 14:12:54 +0800621 crtc = weston_get_crtc_for_conn(fd, conn);
622 if (!crtc)
623 return;
624
625 initModePolicyFun(crtc, conn, callback);
leng.fange9d800e2024-07-12 13:31:59 +0800626 if ((ctx->crtc && ctx->crtc->crtc_id != crtc->crtc_id) || !ctx->crtc)
627 changed = true;
628
leng.fang91856072024-06-07 14:12:54 +0800629 if (ctx->crtc)
630 drmModeFreeCrtc(ctx->crtc);
631 ctx->drm_fd = fd;
632 ctx->crtc = crtc;
633 ctx->conn = conn;
634 ctx->head = head;
leng.fang13fd3982024-07-03 19:09:58 +0800635 ctx->current_mode = drm_mode_to_weston_mode(&ctx->crtc->mode);
leng.fange9d800e2024-07-12 13:31:59 +0800636 if (changed) {
637 weston_prop_list_init(ctx);
638 weston_add_property(ctx, ctx->crtc->crtc_id, DRM_MODE_OBJECT_CRTC);
639 weston_add_property(ctx, ctx->conn->connector_id, DRM_MODE_OBJECT_CONNECTOR);
640 }
leng.fang91856072024-06-07 14:12:54 +0800641 }
642}
643
644void init_mode_policy(int fd, drmModeConnector *conn)
645{
646 weston_ctx *ctx = weston_get_ctx();
647 drmModeCrtc *crtc = weston_get_crtc_for_conn(fd, conn);
648 if (ctx->crtc)
649 drmModeFreeCrtc(ctx->crtc);
650 ctx->drm_fd = fd;
651 ctx->crtc = crtc;
652 ctx->conn = conn;
653 initModePolicy(crtc, conn, callback);
654}
655
leng.fang13fd3982024-07-03 19:09:58 +0800656static bool need_mode_changed(char *name)
657{
658 int size = sizeof(prop_changed_and_mode) / sizeof(prop_changed_and_mode[0]);
659 int i;
660
661 for (i = 0; i < size; i++) {
662 if (STRCMPS(name, prop_changed_and_mode[i]) == 0)
663 return true;
664 }
665 return false;
666}
667
668int mode_policy_add_prop(drmModeAtomicReq *req, bool mode_changed)
leng.fang91856072024-06-07 14:12:54 +0800669{
670 weston_ctx *ctx = weston_get_ctx();
671 prop_info *info;
672 int err = 0, ret = 0;
leng.fangb1081a32024-06-25 14:41:37 +0800673 int count = 0;
leng.fang91856072024-06-07 14:12:54 +0800674
675 wl_list_for_each(info, &ctx->prop_list, link) {
676 if (info->need_change) {
leng.fang13fd3982024-07-03 19:09:58 +0800677 if (need_mode_changed(info->name) && !mode_changed)
678 continue;
679
leng.fang91856072024-06-07 14:12:54 +0800680 err = drmModeAtomicAddProperty(req, info->item_id, info->prop_id, info->value);
681 if (!err)
682 MESON_LOGE("drmModeAtomicAddProperty %s fail: %d(%d)\n",
683 info->name, err, errno);
684 info->need_change = 0;
685 ret |= (err <= 0) ? -1 : 0;
leng.fangb1081a32024-06-25 14:41:37 +0800686 if (!ret)
687 count++;
leng.fang91856072024-06-07 14:12:54 +0800688 ctx->need_update_hdmi_param = true;
689 }
690 }
leng.fangb1081a32024-06-25 14:41:37 +0800691 return ret >= 0 ? count : ret;
leng.fang91856072024-06-07 14:12:54 +0800692}
693
leng.fang13fd3982024-07-03 19:09:58 +0800694void mode_policy_set_hotplug(int plug, bool force)
leng.fang91856072024-06-07 14:12:54 +0800695{
696 weston_ctx *ctx = weston_get_ctx();
leng.fang13fd3982024-07-03 19:09:58 +0800697
698 if (force) {
leng.fang91856072024-06-07 14:12:54 +0800699 ctx->hotplug = plug;
leng.fang13fd3982024-07-03 19:09:58 +0800700 } else {
701 if (ctx->hotplug & plug)
702 ctx->hotplug = plug;
703 }
leng.fang91856072024-06-07 14:12:54 +0800704}
705
706void mode_policy_update_mode(struct weston_mode *mode)
707{
708 weston_ctx *ctx = weston_get_ctx();
709 if (mode)
710 ctx->current_mode = *mode;
leng.fang13fd3982024-07-03 19:09:58 +0800711 else if (ctx->mode_changed)
leng.fang91856072024-06-07 14:12:54 +0800712 ctx->current_mode = ctx->next_mode;
713 MESON_LOGD("curr: %dx%d@%d",
714 ctx->current_mode.width,
715 ctx->current_mode.height,
716 ctx->current_mode.refresh);
717}
718
719struct weston_mode *mode_policy_choose_mode(struct weston_mode *mode)
720{
721 weston_ctx *ctx = weston_get_ctx();
722 char name[32] = { 0 };
leng.fang91856072024-06-07 14:12:54 +0800723
724 if (mode) {
725 if (get_mode_name_for_weston_mode(ctx, mode, name))
726 setActiveConfig(name);
727 } else {
728 if (ctx->hotplug & (AML_WESTON_HOTPLUG_PLUG | AML_WESTON_HOTPLUG_UNPLUG))
729 onHotplug(ctx->hotplug & AML_WESTON_HOTPLUG_PLUG);
leng.fangb1081a32024-06-25 14:41:37 +0800730 else if (ctx->hotplug & (AML_WESTON_HOTPLUG_BOOT | AML_WESTON_HOTPLUG_SET))
leng.fang91856072024-06-07 14:12:54 +0800731 initModePolicy(NULL, NULL, callback);
732 ctx->hotplug = AML_WESTON_HOTPLUG_INIT;
733 }
734 if (ctx->mode_update)
735 return &ctx->next_mode;
leng.fang13fd3982024-07-03 19:09:58 +0800736 return &ctx->current_mode;
leng.fang91856072024-06-07 14:12:54 +0800737}
738
leng.fangb1081a32024-06-25 14:41:37 +0800739void mode_policy_update_bestmode(bool bestmode)
740{
741 bootenv_update("is.bestmode", bestmode ? "true" : "false");
742}
743
leng.fang13fd3982024-07-03 19:09:58 +0800744void mode_policy_update_modeset(bool *state, bool *modeset)
745{
746 weston_ctx *ctx = weston_get_ctx();
747
748 MESON_LOGI("state: %d, modeset: %d, mode_changed: %d", *state, *modeset, ctx->mode_changed);
749 if (ctx->mode_changed) {
750 if (!*state)
751 *state = true;
752 if (!*modeset)
753 *modeset = true;
754 }
755}
756
leng.fange9d800e2024-07-12 13:31:59 +0800757void mode_policy_resume()
758{
759 weston_ctx *ctx = weston_get_ctx();
760 int flag;
761
762 flag = (ctx->conn &&
763 (ctx->conn->connector_type == DRM_MODE_CONNECTOR_HDMIA ||
764 ctx->conn->connector_type == DRM_MODE_CONNECTOR_TV)) ?
765 AML_WESTON_HOTPLUG_PLUG : AML_WESTON_HOTPLUG_SET;
766
767 mode_policy_set_hotplug(flag, true);
768}
769
leng.fang91856072024-06-07 14:12:54 +0800770static void * wstUpdatenvThread(void *arg )
771{
772 long long delay = 16667LL;
773 weston_ctx *ctx = (weston_ctx *)arg;
leng.fang13fd3982024-07-03 19:09:58 +0800774
leng.fang91856072024-06-07 14:12:54 +0800775 while (!ctx->update_env_thread_stop_requested)
776 {
777 if ((ctx->mode_changed && !ctx->prop_changed) ||
778 (ctx->prop_changed && ctx->need_update_hdmi_param))
779 {
780 weston_log("%s[%d]\n", __func__, __LINE__);
781 updateEnv();
782 ctx->need_update_hdmi_param = false;
783 ctx->mode_changed = false;
784 ctx->prop_changed = false;
785 }
786 usleep( delay );
787 }
788 MESON_LOGD("update env thread exit");
789 return NULL;
790}
791
792void weston_start_update_env_thread()
793{
794 int rc;
795 weston_ctx *ctx = weston_get_ctx();
796
797 ctx->update_env_thread_stop_requested = false;
798 rc = pthread_create(&ctx->update_env_thread_id, NULL, wstUpdatenvThread, ctx);
799 if ( rc )
800 MESON_LOGE("unable to start updatenv thread: rc %d errno %d", rc, errno);
801}