# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
# Copyright 2019 Bootlin
%YAML 1.2
---
$id: http://devicetree.org/schemas/display/xylon,logicvc-display.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#

title: Xylon LogiCVC display controller

maintainers:
  - Paul Kocialkowski <paul.kocialkowski@bootlin.com>

description: |
  The Xylon LogiCVC is a display controller that supports multiple layers.
  It is usually implemented as programmable logic and was optimized for use
  with Xilinx Zynq-7000 SoCs and Xilinx FPGAs.

  Because the controller is intended for use in a FPGA, most of the
  configuration of the controller takes place at logic configuration bitstream
  synthesis time. As a result, many of the device-tree bindings are meant to
  reflect the synthesis configuration and must not be configured differently.
  Matching synthesis parameters are provided when applicable.

  Layers are declared in the "layers" sub-node and have dedicated configuration.
  In version 3 of the controller, each layer has fixed memory offset and address
  starting from the video memory base address for its framebuffer. In version 4,
  framebuffers are configured with a direct memory address instead.

properties:
  compatible:
    enum:
      - xylon,logicvc-3.02.a-display
      - xylon,logicvc-4.01.a-display

  reg:
    maxItems: 1

  clocks:
    minItems: 1
    maxItems: 4

  clock-names:
    minItems: 1
    items:
      # vclk is required and must be provided as first item.
      - const: vclk
      # Other clocks are optional and can be provided in any order.
      - enum:
          - vclk2
          - lvdsclk
          - lvdsclkn
      - enum:
          - vclk2
          - lvdsclk
          - lvdsclkn
      - enum:
          - vclk2
          - lvdsclk
          - lvdsclkn

  interrupts:
    maxItems: 1

  memory-region:
    maxItems: 1

  xylon,display-interface:
    enum:
      # Parallel RGB interface (C_DISPLAY_INTERFACE == 0)
      - parallel-rgb
      # ITU-T BR656 interface (C_DISPLAY_INTERFACE == 1)
      - bt656
      # 4-bit LVDS interface (C_DISPLAY_INTERFACE == 2)
      - lvds-4bits
      # 3-bit LVDS interface (C_DISPLAY_INTERFACE == 4)
      - lvds-3bits
      # DVI interface (C_DISPLAY_INTERFACE == 5)
      - dvi
    description: Display output interface (C_DISPLAY_INTERFACE).

  xylon,display-colorspace:
    enum:
      # RGB colorspace (C_DISPLAY_COLOR_SPACE == 0)
      - rgb
      # YUV 4:2:2 colorspace (C_DISPLAY_COLOR_SPACE == 1)
      - yuv422
      # YUV 4:4:4 colorspace (C_DISPLAY_COLOR_SPACE == 2)
      - yuv444
    description: Display output colorspace (C_DISPLAY_COLOR_SPACE).

  xylon,display-depth:
    $ref: /schemas/types.yaml#/definitions/uint32
    description: Display output depth (C_PIXEL_DATA_WIDTH).

  xylon,row-stride:
    $ref: /schemas/types.yaml#/definitions/uint32
    description: Fixed number of pixels in a framebuffer row (C_ROW_STRIDE).

  xylon,dithering:
    $ref: /schemas/types.yaml#/definitions/flag
    description: Dithering module is enabled (C_XCOLOR)

  xylon,background-layer:
    $ref: /schemas/types.yaml#/definitions/flag
    description: |
      The last layer is used to display a black background (C_USE_BACKGROUND).
      The layer must still be registered.

  xylon,layers-configurable:
    $ref: /schemas/types.yaml#/definitions/flag
    description: |
      Configuration of layers' size, position and offset is enabled
      (C_USE_SIZE_POSITION).

  layers:
    type: object

    properties:
      "#address-cells":
        const: 1

      "#size-cells":
        const: 0

    patternProperties:
      "^layer@[0-9]+$":
        type: object

        properties:
          reg:
            maxItems: 1

          xylon,layer-depth:
            $ref: /schemas/types.yaml#/definitions/uint32
            description: Layer depth (C_LAYER_X_DATA_WIDTH).

          xylon,layer-colorspace:
            enum:
              # RGB colorspace (C_LAYER_X_TYPE == 0)
              - rgb
              # YUV packed colorspace (C_LAYER_X_TYPE == 0)
              - yuv
            description: Layer colorspace (C_LAYER_X_TYPE).

          xylon,layer-alpha-mode:
            enum:
              # Alpha is configured layer-wide (C_LAYER_X_ALPHA_MODE == 0)
              - layer
              # Alpha is configured per-pixel (C_LAYER_X_ALPHA_MODE == 1)
              - pixel
            description: Alpha mode for the layer (C_LAYER_X_ALPHA_MODE).

          xylon,layer-base-offset:
            $ref: /schemas/types.yaml#/definitions/uint32
            description: |
              Offset in number of lines (C_LAYER_X_OFFSET) starting from the
              video RAM base (C_VMEM_BASEADDR), only for version 3.

          xylon,layer-buffer-offset:
            $ref: /schemas/types.yaml#/definitions/uint32
            description: |
              Offset in number of lines (C_BUFFER_*_OFFSET) starting from the
              layer base offset for the second buffer used in double-buffering.

          xylon,layer-primary:
            $ref: /schemas/types.yaml#/definitions/flag
            description: |
              Layer should be registered as a primary plane (exactly one is
              required).

        additionalProperties: false

        required:
          - reg
          - xylon,layer-depth
          - xylon,layer-colorspace
          - xylon,layer-alpha-mode

    required:
      - "#address-cells"
      - "#size-cells"
      - layer@0

    additionalProperties: false

    description: |
      The description of the display controller layers, containing layer
      sub-nodes that each describe a registered layer.

  port:
    $ref: /schemas/graph.yaml#/properties/port
    description: |
      Video output port, typically connected to a panel or bridge.

additionalProperties: false

required:
  - compatible
  - reg
  - clocks
  - clock-names
  - interrupts
  - xylon,display-interface
  - xylon,display-colorspace
  - xylon,display-depth
  - xylon,row-stride
  - layers
  - port

examples:
  - |
    #include <dt-bindings/interrupt-controller/irq.h>

    logicvc: logicvc@43c00000 {
      compatible = "xylon,logicvc-3.02.a", "syscon", "simple-mfd";
      reg = <0x43c00000 0x6000>;

      #address-cells = <1>;
      #size-cells = <1>;

      logicvc_display: display@0 {
        compatible = "xylon,logicvc-3.02.a-display";
        reg = <0x0 0x6000>;

        memory-region = <&logicvc_cma>;

        clocks = <&logicvc_vclk 0>, <&logicvc_lvdsclk 0>;
        clock-names = "vclk", "lvdsclk";

        interrupt-parent = <&intc>;
        interrupts = <0 34 IRQ_TYPE_LEVEL_HIGH>;

        xylon,display-interface = "lvds-4bits";
        xylon,display-colorspace = "rgb";
        xylon,display-depth = <16>;
        xylon,row-stride = <1024>;

        xylon,layers-configurable;

        layers {
          #address-cells = <1>;
          #size-cells = <0>;

          layer@0 {
            reg = <0>;
            xylon,layer-depth = <16>;
            xylon,layer-colorspace = "rgb";
            xylon,layer-alpha-mode = "layer";
            xylon,layer-base-offset = <0>;
            xylon,layer-buffer-offset = <480>;
            xylon,layer-primary;
          };

          layer@1 {
            reg = <1>;
            xylon,layer-depth = <16>;
            xylon,layer-colorspace = "rgb";
            xylon,layer-alpha-mode = "layer";
            xylon,layer-base-offset = <2400>;
            xylon,layer-buffer-offset = <480>;
          };

          layer@2 {
            reg = <2>;
            xylon,layer-depth = <16>;
            xylon,layer-colorspace = "rgb";
            xylon,layer-alpha-mode = "layer";
            xylon,layer-base-offset = <960>;
            xylon,layer-buffer-offset = <480>;
          };

          layer@3 {
            reg = <3>;
            xylon,layer-depth = <16>;
            xylon,layer-colorspace = "rgb";
            xylon,layer-alpha-mode = "layer";
            xylon,layer-base-offset = <480>;
            xylon,layer-buffer-offset = <480>;
          };

          layer@4 {
            reg = <4>;
            xylon,layer-depth = <16>;
            xylon,layer-colorspace = "rgb";
            xylon,layer-alpha-mode = "layer";
            xylon,layer-base-offset = <8192>;
            xylon,layer-buffer-offset = <480>;
          };
        };

        port {
          #address-cells = <1>;
          #size-cells = <0>;

          logicvc_output: endpoint@0 {
            reg = <0>;
            remote-endpoint = <&panel_input>;
          };
        };
      };
    };