linux/drivers/gpu/drm/xylon/xylon_crtc.c
<<
>>
Prefs
   1/*
   2 * Xylon DRM driver CRTC functions
   3 *
   4 * Copyright (C) 2014 Xylon d.o.o.
   5 * Author: Davor Joja <davor.joja@logicbricks.com>
   6 *
   7 * Based on Xilinx DRM crtc driver.
   8 * Copyright (C) 2013 Xilinx, Inc.
   9 *
  10 * This software is licensed under the terms of the GNU General Public
  11 * License version 2, as published by the Free Software Foundation, and
  12 * may be copied, distributed, and modified under those terms.
  13 *
  14 * This program is distributed in the hope that it will be useful,
  15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  17 * GNU General Public License for more details.
  18 */
  19
  20#include <drm/drmP.h>
  21#include <drm/drm_crtc.h>
  22#include <drm/drm_crtc_helper.h>
  23#include <drm/drm_gem_cma_helper.h>
  24
  25#include <linux/clk.h>
  26#include <linux/delay.h>
  27#include <linux/device.h>
  28
  29#include <video/videomode.h>
  30
  31#include "xylon_crtc.h"
  32#include "xylon_drv.h"
  33#include "xylon_logicvc_helper.h"
  34#include "xylon_logicvc_hw.h"
  35#include "xylon_plane.h"
  36#include "xylon_property.h"
  37
  38struct xylon_drm_crtc_properties {
  39        struct drm_property *bg_color;
  40        struct drm_property *layer_update;
  41        bool layer_update_initval;
  42        struct drm_property *pixel_data_polarity;
  43        bool pixel_data_polarity_initval;
  44        struct drm_property *pixel_data_trigger;
  45        bool pixel_data_trigger_initval;
  46};
  47
  48struct xylon_drm_crtc {
  49        struct drm_crtc base;
  50        struct drm_pending_vblank_event *event;
  51        struct xylon_drm_crtc_properties properties;
  52        struct xylon_cvc *cvc;
  53        struct xylon_drm_plane_manager *manager;
  54        struct clk *pixel_clock;
  55        struct xylon_cvc_fix fix;
  56        struct videomode vmode;
  57        u32 primary_id;
  58        int dpms;
  59};
  60
  61#define to_xylon_crtc(x) container_of(x, struct xylon_drm_crtc, base)
  62
  63static int xylon_drm_crtc_clk_set(struct xylon_drm_crtc *crtc)
  64{
  65        int ret;
  66
  67        ret = clk_set_rate(crtc->pixel_clock, crtc->vmode.pixelclock);
  68        if (ret) {
  69                DRM_ERROR("failed set pixel clock\n");
  70                return ret;
  71        }
  72        DRM_DEBUG("pixel clock %ld -> %ld\n", crtc->vmode.pixelclock,
  73                 clk_get_rate(crtc->pixel_clock));
  74
  75        return 0;
  76}
  77
  78static void xylon_drm_crtc_dpms(struct drm_crtc *base_crtc, int dpms)
  79{
  80        struct xylon_drm_crtc *crtc = to_xylon_crtc(base_crtc);
  81
  82        if (crtc->dpms == dpms)
  83                return;
  84
  85        crtc->dpms = dpms;
  86
  87        switch (dpms) {
  88        case DRM_MODE_DPMS_ON:
  89        case DRM_MODE_DPMS_STANDBY:
  90                xylon_drm_plane_dpms(base_crtc->primary, dpms);
  91                break;
  92        default:
  93                xylon_cvc_disable(crtc->cvc);
  94                break;
  95        }
  96}
  97
  98static void xylon_drm_crtc_prepare(struct drm_crtc *base_crtc)
  99{
 100        xylon_drm_crtc_dpms(base_crtc, DRM_MODE_DPMS_STANDBY);
 101}
 102
 103static void xylon_drm_crtc_commit(struct drm_crtc *base_crtc)
 104{
 105        struct xylon_drm_crtc *crtc = to_xylon_crtc(base_crtc);
 106
 107        xylon_drm_crtc_clk_set(crtc);
 108
 109        xylon_drm_plane_commit(base_crtc->primary);
 110
 111        xylon_cvc_enable(crtc->cvc, &crtc->vmode);
 112
 113        xylon_drm_crtc_dpms(base_crtc, DRM_MODE_DPMS_ON);
 114}
 115
 116static bool xylon_drm_crtc_mode_fixup(struct drm_crtc *base_crtc,
 117                                      const struct drm_display_mode *mode,
 118                                      struct drm_display_mode *adjusted_mode)
 119{
 120        struct xylon_drm_crtc *crtc = to_xylon_crtc(base_crtc);
 121
 122        if ((mode->hdisplay >= crtc->fix.hres_min &&
 123             mode->hdisplay <= crtc->fix.hres_max) &&
 124            (mode->vdisplay >= crtc->fix.vres_min &&
 125             mode->vdisplay <= crtc->fix.vres_max))
 126                return true;
 127
 128        return false;
 129}
 130
 131static int xylon_drm_crtc_mode_set(struct drm_crtc *base_crtc,
 132                                   struct drm_display_mode *mode,
 133                                   struct drm_display_mode *adjusted_mode,
 134                                   int x, int y,
 135                                   struct drm_framebuffer *old_fb)
 136{
 137        struct xylon_drm_crtc *crtc = to_xylon_crtc(base_crtc);
 138        struct drm_display_mode *dm = adjusted_mode;
 139        int ret;
 140
 141        crtc->vmode.pixelclock = dm->clock * KHZ;
 142        crtc->vmode.hactive = dm->hdisplay;
 143        crtc->vmode.hfront_porch = dm->hsync_start - dm->hdisplay;
 144        crtc->vmode.hback_porch = dm->htotal - dm->hsync_end;
 145        crtc->vmode.hsync_len = dm->hsync_end - dm->hsync_start;
 146        crtc->vmode.vactive = dm->vdisplay;
 147        crtc->vmode.vfront_porch = dm->vsync_start - dm->vdisplay;
 148        crtc->vmode.vback_porch = dm->vtotal - dm->vsync_end;
 149        crtc->vmode.vsync_len = dm->vsync_end - dm->vsync_start;
 150
 151        ret = xylon_drm_plane_fb_set(base_crtc->primary, base_crtc->primary->fb,
 152                                     0, 0, dm->hdisplay, dm->vdisplay,
 153                                     x, y, dm->hdisplay, dm->vdisplay);
 154        if (ret) {
 155                DRM_ERROR("failed set plane mode\n");
 156                return ret;
 157        }
 158
 159        return 0;
 160}
 161
 162static int xylon_drm_crtc_mode_set_base(struct drm_crtc *base_crtc,
 163                                        int x, int y,
 164                                        struct drm_framebuffer *old_fb)
 165{
 166        const struct drm_plane_funcs *funcs = base_crtc->primary->funcs;
 167        int ret;
 168
 169        ret = funcs->update_plane(base_crtc->primary,
 170                                  base_crtc,
 171                                  base_crtc->primary->fb,
 172                                  0, 0,
 173                                  base_crtc->hwmode.hdisplay,
 174                                  base_crtc->hwmode.vdisplay,
 175                                  x << 16, y << 16,
 176                                  base_crtc->hwmode.hdisplay << 16,
 177                                  base_crtc->hwmode.vdisplay << 16);
 178        if (ret) {
 179                DRM_ERROR("failed set plane mode\n");
 180                return ret;
 181        }
 182
 183        return 0;
 184}
 185
 186static void xylon_drm_crtc_load_lut(struct drm_crtc *base_crtc)
 187{
 188}
 189
 190static struct drm_crtc_helper_funcs xylon_drm_crtc_helper_funcs = {
 191        .dpms = xylon_drm_crtc_dpms,
 192        .prepare = xylon_drm_crtc_prepare,
 193        .commit = xylon_drm_crtc_commit,
 194        .mode_fixup = xylon_drm_crtc_mode_fixup,
 195        .mode_set = xylon_drm_crtc_mode_set,
 196        .mode_set_base = xylon_drm_crtc_mode_set_base,
 197        .load_lut = xylon_drm_crtc_load_lut,
 198};
 199
 200static void xylon_drm_crtc_destroy(struct drm_crtc *base_crtc)
 201{
 202        struct xylon_drm_crtc *crtc = to_xylon_crtc(base_crtc);
 203
 204        xylon_drm_crtc_dpms(base_crtc, DRM_MODE_DPMS_OFF);
 205
 206        drm_crtc_cleanup(base_crtc);
 207
 208        clk_disable_unprepare(crtc->pixel_clock);
 209}
 210
 211void xylon_drm_crtc_cancel_page_flip(struct drm_crtc *base_crtc,
 212                                     struct drm_file *file)
 213{
 214        struct drm_device *dev = base_crtc->dev;
 215        struct drm_pending_vblank_event *event;
 216        struct xylon_drm_crtc *crtc = to_xylon_crtc(base_crtc);
 217        unsigned long flags;
 218
 219        spin_lock_irqsave(&dev->event_lock, flags);
 220        event = crtc->event;
 221        if (event && (event->base.file_priv == file)) {
 222                crtc->event = NULL;
 223                event->base.destroy(&event->base);
 224                drm_vblank_put(dev, 0);
 225        }
 226        spin_unlock_irqrestore(&dev->event_lock, flags);
 227}
 228
 229static int xylon_drm_crtc_page_flip(struct drm_crtc *base_crtc,
 230                                    struct drm_framebuffer *fb,
 231                                    struct drm_pending_vblank_event *event,
 232                                    u32 page_flip_flags)
 233{
 234        struct drm_device *dev = base_crtc->dev;
 235        struct xylon_drm_crtc *crtc = to_xylon_crtc(base_crtc);
 236        unsigned long flags;
 237        int ret;
 238
 239        spin_lock_irqsave(&dev->event_lock, flags);
 240        if (crtc->event != NULL) {
 241                spin_unlock_irqrestore(&dev->event_lock, flags);
 242                return -EBUSY;
 243        }
 244        spin_unlock_irqrestore(&dev->event_lock, flags);
 245
 246        ret = xylon_drm_plane_fb_set(base_crtc->primary, fb,
 247                                     0, 0,
 248                                     base_crtc->hwmode.hdisplay,
 249                                     base_crtc->hwmode.vdisplay,
 250                                     base_crtc->x, base_crtc->y,
 251                                     base_crtc->hwmode.hdisplay,
 252                                     base_crtc->hwmode.vdisplay);
 253        if (ret) {
 254                DRM_ERROR("failed mode set plane\n");
 255                return ret;
 256        }
 257
 258        xylon_drm_plane_commit(base_crtc->primary);
 259
 260        base_crtc->primary->fb = fb;
 261
 262        if (event) {
 263                event->pipe = 0;
 264                drm_vblank_get(dev, 0);
 265                spin_lock_irqsave(&dev->event_lock, flags);
 266                crtc->event = event;
 267                spin_unlock_irqrestore(&dev->event_lock, flags);
 268        }
 269
 270        return 0;
 271}
 272
 273static int xylon_drm_crtc_set_property(struct drm_crtc *base_crtc,
 274                                       struct drm_property *property,
 275                                       u64 value)
 276{
 277        struct xylon_drm_crtc *crtc = to_xylon_crtc(base_crtc);
 278        struct xylon_drm_crtc_properties *props = &crtc->properties;
 279        struct xylon_drm_plane_op op;
 280        u32 val = (u32)value;
 281        s64 x = -1;
 282        s64 y = -1;
 283
 284        if (property == props->bg_color) {
 285                op.id = XYLON_DRM_PLANE_OP_ID_BACKGROUND_COLOR;
 286                op.param = val;
 287        } else if (property == props->layer_update) {
 288                xylon_cvc_ctrl(crtc->cvc, LOGICVC_LAYER_UPDATE,
 289                               (bool)val);
 290        } else if (property == props->pixel_data_polarity) {
 291                xylon_cvc_ctrl(crtc->cvc, LOGICVC_PIXEL_DATA_INVERT,
 292                               (bool)val);
 293        } else if (property == props->pixel_data_trigger) {
 294                xylon_cvc_ctrl(crtc->cvc, LOGICVC_PIXEL_DATA_TRIGGER_INVERT,
 295                               (bool)val);
 296        } else {
 297                return -EINVAL;
 298        }
 299
 300        if (x > -1 && y > -1) {
 301                if (xylon_drm_plane_fb_set(base_crtc->primary,
 302                                           base_crtc->primary->fb,
 303                                           (u32)x, (u32)y,
 304                                           base_crtc->hwmode.hdisplay - x,
 305                                           base_crtc->hwmode.vdisplay - y,
 306                                           base_crtc->x, base_crtc->y,
 307                                           base_crtc->hwmode.hdisplay - x,
 308                                           base_crtc->hwmode.vdisplay - y))
 309                        DRM_ERROR("failed set position\n");
 310                else
 311                        xylon_drm_plane_commit(base_crtc->primary);
 312        } else {
 313                xylon_drm_plane_op(base_crtc->primary, &op);
 314        }
 315
 316        return 0;
 317}
 318
 319static struct drm_crtc_funcs xylon_drm_crtc_funcs = {
 320        .destroy = xylon_drm_crtc_destroy,
 321        .set_config = drm_crtc_helper_set_config,
 322        .page_flip = xylon_drm_crtc_page_flip,
 323        .set_property = xylon_drm_crtc_set_property,
 324};
 325
 326static void xylon_drm_crtc_vblank_handler(struct drm_crtc *base_crtc)
 327{
 328        struct drm_device *dev = base_crtc->dev;
 329        struct drm_pending_vblank_event *event;
 330        struct xylon_drm_crtc *crtc = to_xylon_crtc(base_crtc);
 331        unsigned long flags;
 332
 333        drm_handle_vblank(dev, 0);
 334
 335        spin_lock_irqsave(&dev->event_lock, flags);
 336        event = crtc->event;
 337        crtc->event = NULL;
 338        if (event) {
 339                drm_send_vblank_event(dev, 0, event);
 340                drm_vblank_put(dev, 0);
 341        }
 342        spin_unlock_irqrestore(&dev->event_lock, flags);
 343}
 344
 345void xylon_drm_crtc_vblank(struct drm_crtc *base_crtc, bool enabled)
 346{
 347        struct xylon_drm_crtc *crtc = to_xylon_crtc(base_crtc);
 348
 349        xylon_cvc_int_state(crtc->cvc, LOGICVC_INT_V_SYNC, enabled);
 350}
 351
 352void xylon_drm_crtc_int_handle(struct drm_crtc *base_crtc)
 353{
 354        struct xylon_drm_crtc *crtc = to_xylon_crtc(base_crtc);
 355        u32 active = xylon_cvc_int_get_active(crtc->cvc);
 356        u32 handled = 0;
 357
 358        if (active & LOGICVC_INT_V_SYNC) {
 359                xylon_drm_crtc_vblank_handler(base_crtc);
 360                handled |= LOGICVC_INT_V_SYNC;
 361        }
 362
 363        xylon_cvc_int_clear_active(crtc->cvc, handled);
 364}
 365
 366void xylon_drm_crtc_int_hw_enable(struct drm_crtc *base_crtc)
 367{
 368        struct xylon_drm_crtc *crtc = to_xylon_crtc(base_crtc);
 369
 370        xylon_cvc_int_hw_enable(crtc->cvc);
 371}
 372
 373void xylon_drm_crtc_int_hw_disable(struct drm_crtc *base_crtc)
 374{
 375        struct xylon_drm_crtc *crtc = to_xylon_crtc(base_crtc);
 376
 377        xylon_cvc_int_hw_disable(crtc->cvc);
 378}
 379
 380int xylon_drm_crtc_int_request(struct drm_crtc *base_crtc, unsigned long flags,
 381                               irq_handler_t handler, void *dev)
 382{
 383        struct xylon_drm_crtc *crtc = to_xylon_crtc(base_crtc);
 384
 385        return xylon_cvc_int_request(crtc->cvc, flags, handler, dev);
 386}
 387
 388void xylon_drm_crtc_int_free(struct drm_crtc *base_crtc, void *dev)
 389{
 390        struct xylon_drm_crtc *crtc = to_xylon_crtc(base_crtc);
 391
 392        xylon_cvc_int_free(crtc->cvc, dev);
 393}
 394
 395bool xylon_drm_crtc_check_format(struct drm_crtc *base_crtc, u32 fourcc)
 396{
 397        struct xylon_drm_crtc *crtc = to_xylon_crtc(base_crtc);
 398
 399        return xylon_drm_plane_check_format(crtc->manager, fourcc);
 400}
 401
 402void xylon_drm_crtc_get_fix_parameters(struct drm_crtc *base_crtc)
 403{
 404        struct drm_device *dev = base_crtc->dev;
 405        struct xylon_drm_crtc *crtc = to_xylon_crtc(base_crtc);
 406
 407        xylon_cvc_get_fix_parameters(crtc->cvc, &crtc->fix);
 408
 409        dev->mode_config.min_width = crtc->fix.x_min;
 410        dev->mode_config.min_height = crtc->fix.y_min;
 411        dev->mode_config.max_width = crtc->fix.x_max;
 412        dev->mode_config.max_height = crtc->fix.y_max;
 413}
 414
 415int xylon_drm_crtc_get_param(struct drm_crtc *base_crtc, unsigned int *p,
 416                             enum xylon_drm_crtc_buff param)
 417{
 418        struct xylon_drm_crtc *crtc = to_xylon_crtc(base_crtc);
 419
 420        if (crtc->fix.x_max == 0)
 421                return -ENODEV;
 422
 423        switch (param) {
 424        case XYLON_DRM_CRTC_BUFF_BPP:
 425                *p = xylon_drm_plane_get_bits_per_pixel(base_crtc->primary);
 426                break;
 427        case XYLON_DRM_CRTC_BUFF_WIDTH:
 428                *p = crtc->fix.x_max;
 429                break;
 430        case XYLON_DRM_CRTC_BUFF_HEIGHT:
 431                *p = crtc->fix.y_max;
 432                break;
 433        }
 434
 435        return 0;
 436}
 437
 438static int xylon_drm_crtc_create_properties(struct drm_crtc *base_crtc)
 439{
 440        struct drm_device *dev = base_crtc->dev;
 441        struct drm_mode_object *obj = &base_crtc->base;
 442        struct xylon_drm_crtc *crtc = to_xylon_crtc(base_crtc);
 443        struct xylon_drm_crtc_properties *props = &crtc->properties;
 444        bool bg_prop = xylon_cvc_get_info(crtc->cvc,
 445                                          LOGICVC_INFO_BACKGROUND_LAYER,
 446                                          0);
 447        int size;
 448
 449        size = xylon_drm_property_size(property_layer_update);
 450        if (xylon_drm_property_create_list(dev, obj,
 451                                           &props->layer_update,
 452                                           property_layer_update,
 453                                           "layer_update",
 454                                           size))
 455                return -EINVAL;
 456        size = xylon_drm_property_size(property_pixel_data_polarity);
 457        if (xylon_drm_property_create_list(dev, obj,
 458                                           &props->pixel_data_polarity,
 459                                           property_pixel_data_polarity,
 460                                           "pixel_data_polarity",
 461                                           size))
 462                return -EINVAL;
 463        size = xylon_drm_property_size(property_pixel_data_trigger);
 464        if (xylon_drm_property_create_list(dev, obj,
 465                                           &props->pixel_data_trigger,
 466                                           property_pixel_data_trigger,
 467                                           "pixel_data_trigger",
 468                                           size))
 469                return -EINVAL;
 470        if (bg_prop &&
 471            xylon_drm_property_create_range(dev, obj,
 472                                            &props->bg_color,
 473                                            "background_color",
 474                                            XYLON_DRM_PROPERTY_COLOR_MIN,
 475                                            XYLON_DRM_PROPERTY_COLOR_MAX,
 476                                            XYLON_DRM_PROPERTY_COLOR_MIN))
 477                return -EINVAL;
 478
 479        return 0;
 480}
 481
 482static void xylon_drm_crtc_properties_initial_value(struct drm_crtc *base_crtc)
 483{
 484        struct drm_mode_object *obj = &base_crtc->base;
 485        struct xylon_drm_crtc *crtc = to_xylon_crtc(base_crtc);
 486        struct xylon_drm_crtc_properties *props = &crtc->properties;
 487        bool *val;
 488
 489        val = &props->layer_update_initval;
 490        *val = xylon_cvc_get_info(crtc->cvc, LOGICVC_INFO_LAYER_UPDATE, 0);
 491        drm_object_property_set_value(obj, props->layer_update, *val);
 492
 493        val = &props->pixel_data_polarity_initval;
 494        *val = xylon_cvc_get_info(crtc->cvc, LOGICVC_INFO_PIXEL_DATA_INVERT, 0);
 495        drm_object_property_set_value(obj, props->pixel_data_polarity, *val);
 496
 497        val = &props->pixel_data_trigger_initval;
 498        *val = xylon_cvc_get_info(crtc->cvc,
 499                                  LOGICVC_INFO_PIXEL_DATA_TRIGGER_INVERT, 0);
 500        drm_object_property_set_value(obj, props->pixel_data_trigger, *val);
 501}
 502
 503struct drm_crtc *xylon_drm_crtc_create(struct drm_device *dev)
 504{
 505        struct device_node *sub_node;
 506        struct drm_plane *primary;
 507        struct xylon_drm_crtc *crtc;
 508        int ret;
 509
 510        sub_node = of_parse_phandle(dev->dev->of_node, "device", 0);
 511        if (!sub_node) {
 512                DRM_ERROR("failed get logicvc\n");
 513                return ERR_PTR(-ENODEV);
 514        }
 515
 516        crtc = devm_kzalloc(dev->dev, sizeof(*crtc), GFP_KERNEL);
 517        if (!crtc)
 518                return ERR_PTR(-ENOMEM);
 519
 520        crtc->cvc = xylon_cvc_probe(dev->dev, sub_node);
 521        of_node_put(sub_node);
 522        if (IS_ERR(crtc->cvc)) {
 523                DRM_ERROR("failed probe logicvc\n");
 524                return ERR_CAST(crtc->cvc);
 525        }
 526
 527        crtc->manager = xylon_drm_plane_probe_manager(dev, crtc->cvc);
 528        if (IS_ERR(crtc->manager)) {
 529                DRM_ERROR("failed probe plane manager\n");
 530                return ERR_CAST(crtc->manager);
 531        }
 532
 533        ret = of_property_read_u32(dev->dev->of_node, "primary-plane",
 534                                   &crtc->primary_id);
 535        if (ret)
 536                DRM_INFO("no private-plane property\n");
 537
 538        ret = xylon_drm_plane_create_all(crtc->manager, 1, crtc->primary_id);
 539        if (ret) {
 540                DRM_ERROR("failed create planes\n");
 541                goto err_out;
 542        }
 543
 544        crtc->pixel_clock = devm_clk_get(dev->dev, NULL);
 545        if (IS_ERR(crtc->pixel_clock)) {
 546                DRM_ERROR("failed get pixel clock\n");
 547                ret = -EPROBE_DEFER;
 548                goto err_out;
 549        }
 550
 551        ret = clk_prepare_enable(crtc->pixel_clock);
 552        if (ret) {
 553                DRM_ERROR("failed prepare/enable clock\n");
 554                goto err_out;
 555        }
 556
 557        primary = xylon_drm_plane_get_base(crtc->manager, crtc->primary_id);
 558        ret = drm_crtc_init_with_planes(dev, &crtc->base, primary, NULL,
 559                                        &xylon_drm_crtc_funcs, NULL);
 560        if (ret) {
 561                DRM_ERROR("failed initialize crtc\n");
 562                goto err_out;
 563        }
 564        drm_crtc_helper_add(&crtc->base, &xylon_drm_crtc_helper_funcs);
 565
 566        ret = xylon_drm_crtc_create_properties(&crtc->base);
 567        if (ret) {
 568                DRM_ERROR("failed initialize crtc properties\n");
 569                goto err_out;
 570        }
 571
 572        xylon_drm_crtc_properties_initial_value(&crtc->base);
 573
 574        return &crtc->base;
 575
 576err_out:
 577        return ERR_PTR(ret);
 578}
 579
 580void xylon_drm_crtc_properties_restore(struct drm_crtc *base_crtc)
 581{
 582        struct drm_mode_object *obj = &base_crtc->base;
 583        struct xylon_drm_crtc *crtc = to_xylon_crtc(base_crtc);
 584        struct xylon_drm_crtc_properties *props = &crtc->properties;
 585
 586        xylon_drm_crtc_set_property(base_crtc, props->layer_update,
 587                                    props->layer_update_initval);
 588        drm_object_property_set_value(obj, props->layer_update,
 589                                      props->layer_update_initval);
 590        xylon_drm_crtc_set_property(base_crtc, props->pixel_data_polarity,
 591                                    props->pixel_data_polarity_initval);
 592        drm_object_property_set_value(obj, props->pixel_data_polarity,
 593                                      props->pixel_data_polarity_initval);
 594        xylon_drm_crtc_set_property(base_crtc, props->pixel_data_trigger,
 595                                    props->pixel_data_trigger_initval);
 596        drm_object_property_set_value(obj, props->pixel_data_trigger,
 597                                      props->pixel_data_trigger_initval);
 598
 599        xylon_drm_plane_properties_restore(crtc->manager);
 600}
 601