Merge tag 'drm-misc-next-2020-03-17' of git://anongit.freedesktop.org/drm/drm-misc...
authorDave Airlie <airlied@redhat.com>
Thu, 19 Mar 2020 01:00:48 +0000 (11:00 +1000)
committerDave Airlie <airlied@redhat.com>
Thu, 19 Mar 2020 01:01:58 +0000 (11:01 +1000)
drm-misc-next for 5.7:

UAPI Changes:

Cross-subsystem Changes:

Core Changes:
  - dp-mst: Remove register_connector callback, add drm_dp_destroy_connector
  - Changes to scnprintf on multiple instances

Driver Changes:
  - meson: Support for YUV420
  - panel: Support Ortustech COM37H3M, idk-1110wr and idk-2121wr,
           multiple dotclock fixes

Signed-off-by: Dave Airlie <airlied@redhat.com>
From: Maxime Ripard <maxime@cerno.tech>
Link: https://patchwork.freedesktop.org/patch/msgid/20200317082858.lubmvlmvoprn2tuh@gilmour.lan
44 files changed:
Documentation/devicetree/bindings/display/panel/advantech,idk-1110wr.yaml [new file with mode: 0644]
Documentation/devicetree/bindings/display/panel/advantech,idk-2121wr.yaml [new file with mode: 0644]
Documentation/devicetree/bindings/display/panel/elida,kd35t133.yaml
Documentation/devicetree/bindings/display/panel/leadtek,ltk500hd1829.yaml
Documentation/devicetree/bindings/display/panel/novatek,nt35510.yaml
Documentation/devicetree/bindings/display/panel/orisetech,otm8009a.yaml
Documentation/devicetree/bindings/display/panel/panel-dpi.yaml
Documentation/devicetree/bindings/display/panel/panel-simple-dsi.yaml
Documentation/devicetree/bindings/display/panel/raydium,rm68200.yaml
Documentation/devicetree/bindings/display/panel/xinpeng,xpp055c272.yaml
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
drivers/gpu/drm/drm_bufs.c
drivers/gpu/drm/drm_context.c
drivers/gpu/drm/drm_dp_mst_topology.c
drivers/gpu/drm/drm_edid.c
drivers/gpu/drm/drm_gem.c
drivers/gpu/drm/drm_lock.c
drivers/gpu/drm/drm_mm.c
drivers/gpu/drm/drm_sysfs.c
drivers/gpu/drm/drm_vm.c
drivers/gpu/drm/i915/display/intel_dp_mst.c
drivers/gpu/drm/meson/meson_dw_hdmi.c
drivers/gpu/drm/meson/meson_vclk.c
drivers/gpu/drm/meson/meson_vclk.h
drivers/gpu/drm/meson/meson_venc.c
drivers/gpu/drm/meson/meson_venc.h
drivers/gpu/drm/meson/meson_venc_cvbs.c
drivers/gpu/drm/nouveau/dispnv50/disp.c
drivers/gpu/drm/panel/panel-ilitek-ili9322.c
drivers/gpu/drm/panel/panel-lg-lg4573.c
drivers/gpu/drm/panel/panel-novatek-nt35510.c
drivers/gpu/drm/panel/panel-simple.c
drivers/gpu/drm/panel/panel-sony-acx424akp.c
drivers/gpu/drm/radeon/radeon_dp_mst.c
drivers/gpu/drm/rockchip/rockchip_rgb.c
drivers/gpu/drm/tiny/ili9486.c
drivers/gpu/drm/ttm/ttm_bo.c
drivers/gpu/drm/ttm/ttm_page_alloc_dma.c
include/drm/bridge/dw_hdmi.h
include/drm/drm_connector.h
include/drm/drm_dp_mst_helper.h
include/drm/drm_edid.h
include/drm/drm_mm.h

diff --git a/Documentation/devicetree/bindings/display/panel/advantech,idk-1110wr.yaml b/Documentation/devicetree/bindings/display/panel/advantech,idk-1110wr.yaml
new file mode 100644 (file)
index 0000000..93878c2
--- /dev/null
@@ -0,0 +1,69 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/panel/advantech,idk-1110wr.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Advantech IDK-1110WR 10.1" WSVGA LVDS Display Panel
+
+maintainers:
+  - Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>
+  - Thierry Reding <thierry.reding@gmail.com>
+
+allOf:
+  - $ref: lvds.yaml#
+
+properties:
+  compatible:
+    items:
+      - const: advantech,idk-1110wr
+      - {} # panel-lvds, but not listed here to avoid false select
+
+  data-mapping:
+    const: jeida-24
+
+  width-mm:
+    const: 223
+
+  height-mm:
+    const: 125
+
+  panel-timing: true
+  port: true
+
+additionalProperties: false
+
+required:
+  - compatible
+
+examples:
+  - |+
+    panel {
+      compatible = "advantech,idk-1110wr", "panel-lvds";
+
+      width-mm = <223>;
+      height-mm = <125>;
+
+      data-mapping = "jeida-24";
+
+      panel-timing {
+        /* 1024x600 @60Hz */
+        clock-frequency = <51200000>;
+        hactive = <1024>;
+        vactive = <600>;
+        hsync-len = <240>;
+        hfront-porch = <40>;
+        hback-porch = <40>;
+        vsync-len = <10>;
+        vfront-porch = <15>;
+        vback-porch = <10>;
+      };
+
+      port {
+        panel_in: endpoint {
+          remote-endpoint = <&lvds_encoder>;
+        };
+      };
+    };
+
+...
diff --git a/Documentation/devicetree/bindings/display/panel/advantech,idk-2121wr.yaml b/Documentation/devicetree/bindings/display/panel/advantech,idk-2121wr.yaml
new file mode 100644 (file)
index 0000000..6b7fddc
--- /dev/null
@@ -0,0 +1,122 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/panel/advantech,idk-2121wr.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Advantech IDK-2121WR 21.5" Full-HD dual-LVDS panel
+
+maintainers:
+  - Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>
+  - Thierry Reding <thierry.reding@gmail.com>
+
+description: |
+  The IDK-2121WR from Advantech is a Full-HD dual-LVDS panel.
+  A dual-LVDS interface is a dual-link connection with even pixels traveling
+  on one link, and with odd pixels traveling on the other link.
+
+  The panel expects odd pixels on the first port, and even pixels on the
+  second port, therefore the ports must be marked accordingly (with either
+  dual-lvds-odd-pixels or dual-lvds-even-pixels).
+
+properties:
+  compatible:
+    items:
+      - const: advantech,idk-2121wr
+      - {} # panel-lvds, but not listed here to avoid false select
+
+  width-mm:
+    const: 476
+
+  height-mm:
+    const: 268
+
+  data-mapping:
+    const: vesa-24
+
+  panel-timing: true
+
+  ports:
+    type: object
+    properties:
+      port@0:
+        type: object
+        description: The sink for odd pixels.
+        properties:
+          reg:
+            const: 0
+
+          dual-lvds-odd-pixels: true
+
+        required:
+          - reg
+          - dual-lvds-odd-pixels
+
+      port@1:
+        type: object
+        description: The sink for even pixels.
+        properties:
+          reg:
+            const: 1
+
+          dual-lvds-even-pixels: true
+
+        required:
+          - reg
+          - dual-lvds-even-pixels
+
+additionalProperties: false
+
+required:
+  - compatible
+  - width-mm
+  - height-mm
+  - data-mapping
+  - panel-timing
+  - ports
+
+examples:
+  - |+
+    panel-lvds {
+      compatible = "advantech,idk-2121wr", "panel-lvds";
+
+      width-mm = <476>;
+      height-mm = <268>;
+
+      data-mapping = "vesa-24";
+
+      panel-timing {
+        clock-frequency = <148500000>;
+        hactive = <1920>;
+        vactive = <1080>;
+        hsync-len = <44>;
+        hfront-porch = <88>;
+        hback-porch = <148>;
+        vfront-porch = <4>;
+        vback-porch = <36>;
+        vsync-len = <5>;
+      };
+
+      ports {
+        #address-cells = <1>;
+        #size-cells = <0>;
+
+        port@0 {
+          reg = <0>;
+          dual-lvds-odd-pixels;
+          panel_in0: endpoint {
+            remote-endpoint = <&lvds0_out>;
+          };
+        };
+
+        port@1 {
+          reg = <1>;
+          dual-lvds-even-pixels;
+          panel_in1: endpoint {
+            remote-endpoint = <&lvds1_out>;
+          };
+        };
+      };
+    };
+
+...
index 4bd74eaa61be352d3428e97d42100e5cd5802db1..aa761f697b7ae52305d58a2cef70668719dc0e24 100644 (file)
@@ -34,7 +34,7 @@ additionalProperties: false
 
 examples:
   - |
-    dsi@ff450000 {
+    dsi {
         #address-cells = <1>;
         #size-cells = <0>;
         panel@0 {
index a614644c9849dfa96836caa6850f14618126f12e..fd931b29381670bcf271f926b9543522f06d260c 100644 (file)
@@ -34,7 +34,7 @@ additionalProperties: false
 
 examples:
   - |
-    dsi@ff450000 {
+    dsi {
         #address-cells = <1>;
         #size-cells = <0>;
         reg = <0xff450000 0x1000>;
index 791fc9daa68b5d10d5044ff735a5edc4184fd863..73d2ff3baaff16d5df0d5a9b8a039b834ea4c758 100644 (file)
@@ -40,10 +40,10 @@ examples:
   - |
     #include <dt-bindings/gpio/gpio.h>
 
-    dsi@a0351000 {
+    dsi {
         #address-cells = <1>;
         #size-cells = <0>;
-        panel {
+        panel@0 {
             compatible = "hydis,hva40wv1", "novatek,nt35510";
             reg = <0>;
             vdd-supply = <&ab8500_ldo_aux4_reg>;
index 6e6ac995c27b896ccb67ddbfe540de1788dad8dc..4b6dda6dbc0f9a3cccd65d8b00e6ce39d2cae0b2 100644 (file)
@@ -39,7 +39,7 @@ required:
 
 examples:
   - |
-    dsi@0 {
+    dsi {
       #address-cells = <1>;
       #size-cells = <0>;
       panel@0 {
index 5275d350f8cb380aa56e50abf0351f4d61e4342a..f63870384c00f113689a116f082b7795f2b2a885 100644 (file)
@@ -48,7 +48,7 @@ additionalProperties: false
 
 examples:
   - |
-    panel@0 {
+    panel {
         compatible = "osddisplays,osd057T0559-34ts", "panel-dpi";
         label = "osddisplay";
         power-supply = <&vcc_supply>;
index 8b60368a24254735d36f9550fc77ad016579c87f..b2e8742fd6af8cc9f099517f4b7abdd54da5c306 100644 (file)
@@ -50,7 +50,7 @@ required:
 
 examples:
   - |
-    mdss_dsi@fd922800 {
+    dsi {
       #address-cells = <1>;
       #size-cells = <0>;
       panel@0 {
index 09149f140d5fdbba5136f303ce91f72e590f0ae4..a35ba16fc000e49114debfa1924ec95bc17cdfa1 100644 (file)
@@ -42,7 +42,7 @@ required:
 
 examples:
   - |
-    dsi@0 {
+    dsi {
       #address-cells = <1>;
       #size-cells = <0>;
       panel@0 {
index 22c91beb054103d197f4c16e487b264ca5f7ddd5..d9fdb58e06b4218bc1db4d2b9b8534085903f336 100644 (file)
@@ -34,7 +34,7 @@ additionalProperties: false
 
 examples:
   - |
-    dsi@ff450000 {
+    dsi {
         #address-cells = <1>;
         #size-cells = <0>;
         reg = <0xff450000 0x1000>;
index a9108e46f5176ae67fef1efac2c9e1e08916b71c..e8208df420d9d786b9f7ae777a5f66d80bc134b9 100644 (file)
@@ -458,15 +458,9 @@ static void dm_dp_destroy_mst_connector(struct drm_dp_mst_topology_mgr *mgr,
        drm_connector_put(connector);
 }
 
-static void dm_dp_mst_register_connector(struct drm_connector *connector)
-{
-       drm_connector_register(connector);
-}
-
 static const struct drm_dp_mst_topology_cbs dm_mst_cbs = {
        .add_connector = dm_dp_add_mst_connector,
        .destroy_connector = dm_dp_destroy_mst_connector,
-       .register_connector = dm_dp_mst_register_connector
 };
 
 void amdgpu_dm_initialize_dp_connector(struct amdgpu_display_manager *dm,
index 9bad194cfd0aea3a1efde82fa3d93f21b0f022f3..f85c15ad8486e61486139b659355ad3f863ba74b 100644 (file)
@@ -1814,13 +1814,32 @@ static void hdmi_av_composer(struct dw_hdmi *hdmi,
        int hblank, vblank, h_de_hs, v_de_vs, hsync_len, vsync_len;
        unsigned int vdisplay, hdisplay;
 
-       vmode->mtmdsclock = vmode->mpixelclock = mode->clock * 1000;
+       vmode->mpixelclock = mode->clock * 1000;
 
        dev_dbg(hdmi->dev, "final pixclk = %d\n", vmode->mpixelclock);
 
+       vmode->mtmdsclock = vmode->mpixelclock;
+
+       if (!hdmi_bus_fmt_is_yuv422(hdmi->hdmi_data.enc_out_bus_format)) {
+               switch (hdmi_bus_fmt_color_depth(
+                               hdmi->hdmi_data.enc_out_bus_format)) {
+               case 16:
+                       vmode->mtmdsclock = vmode->mpixelclock * 2;
+                       break;
+               case 12:
+                       vmode->mtmdsclock = vmode->mpixelclock * 3 / 2;
+                       break;
+               case 10:
+                       vmode->mtmdsclock = vmode->mpixelclock * 5 / 4;
+                       break;
+               }
+       }
+
        if (hdmi_bus_fmt_is_yuv420(hdmi->hdmi_data.enc_out_bus_format))
                vmode->mtmdsclock /= 2;
 
+       dev_dbg(hdmi->dev, "final tmdsclock = %d\n", vmode->mtmdsclock);
+
        /* Set up HDMI_FC_INVIDCONF */
        inv_val = (hdmi->hdmi_data.hdcp_enable ||
                   (dw_hdmi_support_scdc(hdmi) &&
@@ -2078,11 +2097,10 @@ static int dw_hdmi_setup(struct dw_hdmi *hdmi, struct drm_display_mode *mode)
        hdmi->hdmi_data.video_mode.mpixelrepetitionoutput = 0;
        hdmi->hdmi_data.video_mode.mpixelrepetitioninput = 0;
 
-       /* TOFIX: Get input format from plat data or fallback to RGB888 */
        if (hdmi->plat_data->input_bus_format)
                hdmi->hdmi_data.enc_in_bus_format =
                        hdmi->plat_data->input_bus_format;
-       else
+       else if (hdmi->hdmi_data.enc_in_bus_format == MEDIA_BUS_FMT_FIXED)
                hdmi->hdmi_data.enc_in_bus_format = MEDIA_BUS_FMT_RGB888_1X24;
 
        /* TOFIX: Get input encoding from plat data or fallback to none */
@@ -2092,8 +2110,8 @@ static int dw_hdmi_setup(struct dw_hdmi *hdmi, struct drm_display_mode *mode)
        else
                hdmi->hdmi_data.enc_in_encoding = V4L2_YCBCR_ENC_DEFAULT;
 
-       /* TOFIX: Default to RGB888 output format */
-       hdmi->hdmi_data.enc_out_bus_format = MEDIA_BUS_FMT_RGB888_1X24;
+       if (hdmi->hdmi_data.enc_out_bus_format == MEDIA_BUS_FMT_FIXED)
+               hdmi->hdmi_data.enc_out_bus_format = MEDIA_BUS_FMT_RGB888_1X24;
 
        hdmi->hdmi_data.pix_repet_factor = 0;
        hdmi->hdmi_data.hdcp_enable = 0;
@@ -2371,6 +2389,277 @@ static const struct drm_connector_helper_funcs dw_hdmi_connector_helper_funcs =
        .atomic_check = dw_hdmi_connector_atomic_check,
 };
 
+/*
+ * Possible output formats :
+ * - MEDIA_BUS_FMT_UYYVYY16_0_5X48,
+ * - MEDIA_BUS_FMT_UYYVYY12_0_5X36,
+ * - MEDIA_BUS_FMT_UYYVYY10_0_5X30,
+ * - MEDIA_BUS_FMT_UYYVYY8_0_5X24,
+ * - MEDIA_BUS_FMT_YUV16_1X48,
+ * - MEDIA_BUS_FMT_RGB161616_1X48,
+ * - MEDIA_BUS_FMT_UYVY12_1X24,
+ * - MEDIA_BUS_FMT_YUV12_1X36,
+ * - MEDIA_BUS_FMT_RGB121212_1X36,
+ * - MEDIA_BUS_FMT_UYVY10_1X20,
+ * - MEDIA_BUS_FMT_YUV10_1X30,
+ * - MEDIA_BUS_FMT_RGB101010_1X30,
+ * - MEDIA_BUS_FMT_UYVY8_1X16,
+ * - MEDIA_BUS_FMT_YUV8_1X24,
+ * - MEDIA_BUS_FMT_RGB888_1X24,
+ */
+
+/* Can return a maximum of 11 possible output formats for a mode/connector */
+#define MAX_OUTPUT_SEL_FORMATS 11
+
+static u32 *dw_hdmi_bridge_atomic_get_output_bus_fmts(struct drm_bridge *bridge,
+                                       struct drm_bridge_state *bridge_state,
+                                       struct drm_crtc_state *crtc_state,
+                                       struct drm_connector_state *conn_state,
+                                       unsigned int *num_output_fmts)
+{
+       struct drm_connector *conn = conn_state->connector;
+       struct drm_display_info *info = &conn->display_info;
+       struct drm_display_mode *mode = &crtc_state->mode;
+       u8 max_bpc = conn_state->max_requested_bpc;
+       bool is_hdmi2_sink = info->hdmi.scdc.supported ||
+                            (info->color_formats & DRM_COLOR_FORMAT_YCRCB420);
+       u32 *output_fmts;
+       unsigned int i = 0;
+
+       *num_output_fmts = 0;
+
+       output_fmts = kcalloc(MAX_OUTPUT_SEL_FORMATS, sizeof(*output_fmts),
+                             GFP_KERNEL);
+       if (!output_fmts)
+               return NULL;
+
+       /* If dw-hdmi is the only bridge, avoid negociating with ourselves */
+       if (list_is_singular(&bridge->encoder->bridge_chain)) {
+               *num_output_fmts = 1;
+               output_fmts[0] = MEDIA_BUS_FMT_FIXED;
+
+               return output_fmts;
+       }
+
+       /*
+        * If the current mode enforces 4:2:0, force the output but format
+        * to 4:2:0 and do not add the YUV422/444/RGB formats
+        */
+       if (conn->ycbcr_420_allowed &&
+           (drm_mode_is_420_only(info, mode) ||
+            (is_hdmi2_sink && drm_mode_is_420_also(info, mode)))) {
+
+               /* Order bus formats from 16bit to 8bit if supported */
+               if (max_bpc >= 16 && info->bpc == 16 &&
+                   (info->hdmi.y420_dc_modes & DRM_EDID_YCBCR420_DC_48))
+                       output_fmts[i++] = MEDIA_BUS_FMT_UYYVYY16_0_5X48;
+
+               if (max_bpc >= 12 && info->bpc >= 12 &&
+                   (info->hdmi.y420_dc_modes & DRM_EDID_YCBCR420_DC_36))
+                       output_fmts[i++] = MEDIA_BUS_FMT_UYYVYY12_0_5X36;
+
+               if (max_bpc >= 10 && info->bpc >= 10 &&
+                   (info->hdmi.y420_dc_modes & DRM_EDID_YCBCR420_DC_30))
+                       output_fmts[i++] = MEDIA_BUS_FMT_UYYVYY10_0_5X30;
+
+               /* Default 8bit fallback */
+               output_fmts[i++] = MEDIA_BUS_FMT_UYYVYY8_0_5X24;
+
+               *num_output_fmts = i;
+
+               return output_fmts;
+       }
+
+       /*
+        * Order bus formats from 16bit to 8bit and from YUV422 to RGB
+        * if supported. In any case the default RGB888 format is added
+        */
+
+       if (max_bpc >= 16 && info->bpc == 16) {
+               if (info->color_formats & DRM_COLOR_FORMAT_YCRCB444)
+                       output_fmts[i++] = MEDIA_BUS_FMT_YUV16_1X48;
+
+               output_fmts[i++] = MEDIA_BUS_FMT_RGB161616_1X48;
+       }
+
+       if (max_bpc >= 12 && info->bpc >= 12) {
+               if (info->color_formats & DRM_COLOR_FORMAT_YCRCB422)
+                       output_fmts[i++] = MEDIA_BUS_FMT_UYVY12_1X24;
+
+               if (info->color_formats & DRM_COLOR_FORMAT_YCRCB444)
+                       output_fmts[i++] = MEDIA_BUS_FMT_YUV12_1X36;
+
+               output_fmts[i++] = MEDIA_BUS_FMT_RGB121212_1X36;
+       }
+
+       if (max_bpc >= 10 && info->bpc >= 10) {
+               if (info->color_formats & DRM_COLOR_FORMAT_YCRCB422)
+                       output_fmts[i++] = MEDIA_BUS_FMT_UYVY10_1X20;
+
+               if (info->color_formats & DRM_COLOR_FORMAT_YCRCB444)
+                       output_fmts[i++] = MEDIA_BUS_FMT_YUV10_1X30;
+
+               output_fmts[i++] = MEDIA_BUS_FMT_RGB101010_1X30;
+       }
+
+       if (info->color_formats & DRM_COLOR_FORMAT_YCRCB422)
+               output_fmts[i++] = MEDIA_BUS_FMT_UYVY8_1X16;
+
+       if (info->color_formats & DRM_COLOR_FORMAT_YCRCB444)
+               output_fmts[i++] = MEDIA_BUS_FMT_YUV8_1X24;
+
+       /* Default 8bit RGB fallback */
+       output_fmts[i++] = MEDIA_BUS_FMT_RGB888_1X24;
+
+       *num_output_fmts = i;
+
+       return output_fmts;
+}
+
+/*
+ * Possible input formats :
+ * - MEDIA_BUS_FMT_RGB888_1X24
+ * - MEDIA_BUS_FMT_YUV8_1X24
+ * - MEDIA_BUS_FMT_UYVY8_1X16
+ * - MEDIA_BUS_FMT_UYYVYY8_0_5X24
+ * - MEDIA_BUS_FMT_RGB101010_1X30
+ * - MEDIA_BUS_FMT_YUV10_1X30
+ * - MEDIA_BUS_FMT_UYVY10_1X20
+ * - MEDIA_BUS_FMT_UYYVYY10_0_5X30
+ * - MEDIA_BUS_FMT_RGB121212_1X36
+ * - MEDIA_BUS_FMT_YUV12_1X36
+ * - MEDIA_BUS_FMT_UYVY12_1X24
+ * - MEDIA_BUS_FMT_UYYVYY12_0_5X36
+ * - MEDIA_BUS_FMT_RGB161616_1X48
+ * - MEDIA_BUS_FMT_YUV16_1X48
+ * - MEDIA_BUS_FMT_UYYVYY16_0_5X48
+ */
+
+/* Can return a maximum of 3 possible input formats for an output format */
+#define MAX_INPUT_SEL_FORMATS  3
+
+static u32 *dw_hdmi_bridge_atomic_get_input_bus_fmts(struct drm_bridge *bridge,
+                                       struct drm_bridge_state *bridge_state,
+                                       struct drm_crtc_state *crtc_state,
+                                       struct drm_connector_state *conn_state,
+                                       u32 output_fmt,
+                                       unsigned int *num_input_fmts)
+{
+       u32 *input_fmts;
+       unsigned int i = 0;
+
+       *num_input_fmts = 0;
+
+       input_fmts = kcalloc(MAX_INPUT_SEL_FORMATS, sizeof(*input_fmts),
+                            GFP_KERNEL);
+       if (!input_fmts)
+               return NULL;
+
+       switch (output_fmt) {
+       /* If MEDIA_BUS_FMT_FIXED is tested, return default bus format */
+       case MEDIA_BUS_FMT_FIXED:
+               input_fmts[i++] = MEDIA_BUS_FMT_RGB888_1X24;
+               break;
+       /* 8bit */
+       case MEDIA_BUS_FMT_RGB888_1X24:
+               input_fmts[i++] = MEDIA_BUS_FMT_RGB888_1X24;
+               input_fmts[i++] = MEDIA_BUS_FMT_YUV8_1X24;
+               input_fmts[i++] = MEDIA_BUS_FMT_UYVY8_1X16;
+               break;
+       case MEDIA_BUS_FMT_YUV8_1X24:
+               input_fmts[i++] = MEDIA_BUS_FMT_YUV8_1X24;
+               input_fmts[i++] = MEDIA_BUS_FMT_UYVY8_1X16;
+               input_fmts[i++] = MEDIA_BUS_FMT_RGB888_1X24;
+               break;
+       case MEDIA_BUS_FMT_UYVY8_1X16:
+               input_fmts[i++] = MEDIA_BUS_FMT_UYVY8_1X16;
+               input_fmts[i++] = MEDIA_BUS_FMT_YUV8_1X24;
+               input_fmts[i++] = MEDIA_BUS_FMT_RGB888_1X24;
+               break;
+
+       /* 10bit */
+       case MEDIA_BUS_FMT_RGB101010_1X30:
+               input_fmts[i++] = MEDIA_BUS_FMT_RGB101010_1X30;
+               input_fmts[i++] = MEDIA_BUS_FMT_YUV10_1X30;
+               input_fmts[i++] = MEDIA_BUS_FMT_UYVY10_1X20;
+               break;
+       case MEDIA_BUS_FMT_YUV10_1X30:
+               input_fmts[i++] = MEDIA_BUS_FMT_YUV10_1X30;
+               input_fmts[i++] = MEDIA_BUS_FMT_UYVY10_1X20;
+               input_fmts[i++] = MEDIA_BUS_FMT_RGB101010_1X30;
+               break;
+       case MEDIA_BUS_FMT_UYVY10_1X20:
+               input_fmts[i++] = MEDIA_BUS_FMT_UYVY10_1X20;
+               input_fmts[i++] = MEDIA_BUS_FMT_YUV10_1X30;
+               input_fmts[i++] = MEDIA_BUS_FMT_RGB101010_1X30;
+               break;
+
+       /* 12bit */
+       case MEDIA_BUS_FMT_RGB121212_1X36:
+               input_fmts[i++] = MEDIA_BUS_FMT_RGB121212_1X36;
+               input_fmts[i++] = MEDIA_BUS_FMT_YUV12_1X36;
+               input_fmts[i++] = MEDIA_BUS_FMT_UYVY12_1X24;
+               break;
+       case MEDIA_BUS_FMT_YUV12_1X36:
+               input_fmts[i++] = MEDIA_BUS_FMT_YUV12_1X36;
+               input_fmts[i++] = MEDIA_BUS_FMT_UYVY12_1X24;
+               input_fmts[i++] = MEDIA_BUS_FMT_RGB121212_1X36;
+               break;
+       case MEDIA_BUS_FMT_UYVY12_1X24:
+               input_fmts[i++] = MEDIA_BUS_FMT_UYVY12_1X24;
+               input_fmts[i++] = MEDIA_BUS_FMT_YUV12_1X36;
+               input_fmts[i++] = MEDIA_BUS_FMT_RGB121212_1X36;
+               break;
+
+       /* 16bit */
+       case MEDIA_BUS_FMT_RGB161616_1X48:
+               input_fmts[i++] = MEDIA_BUS_FMT_RGB161616_1X48;
+               input_fmts[i++] = MEDIA_BUS_FMT_YUV16_1X48;
+               break;
+       case MEDIA_BUS_FMT_YUV16_1X48:
+               input_fmts[i++] = MEDIA_BUS_FMT_YUV16_1X48;
+               input_fmts[i++] = MEDIA_BUS_FMT_RGB161616_1X48;
+               break;
+
+       /*YUV 4:2:0 */
+       case MEDIA_BUS_FMT_UYYVYY8_0_5X24:
+       case MEDIA_BUS_FMT_UYYVYY10_0_5X30:
+       case MEDIA_BUS_FMT_UYYVYY12_0_5X36:
+       case MEDIA_BUS_FMT_UYYVYY16_0_5X48:
+               input_fmts[i++] = output_fmt;
+               break;
+       }
+
+       *num_input_fmts = i;
+
+       if (*num_input_fmts == 0) {
+               kfree(input_fmts);
+               input_fmts = NULL;
+       }
+
+       return input_fmts;
+}
+
+static int dw_hdmi_bridge_atomic_check(struct drm_bridge *bridge,
+                                      struct drm_bridge_state *bridge_state,
+                                      struct drm_crtc_state *crtc_state,
+                                      struct drm_connector_state *conn_state)
+{
+       struct dw_hdmi *hdmi = bridge->driver_private;
+
+       hdmi->hdmi_data.enc_out_bus_format =
+                       bridge_state->output_bus_cfg.format;
+
+       hdmi->hdmi_data.enc_in_bus_format =
+                       bridge_state->input_bus_cfg.format;
+
+       dev_dbg(hdmi->dev, "input format 0x%04x, output format 0x%04x\n",
+               bridge_state->input_bus_cfg.format,
+               bridge_state->output_bus_cfg.format);
+
+       return 0;
+}
+
 static int dw_hdmi_bridge_attach(struct drm_bridge *bridge,
                                 enum drm_bridge_attach_flags flags)
 {
@@ -2395,6 +2684,14 @@ static int dw_hdmi_bridge_attach(struct drm_bridge *bridge,
                                    DRM_MODE_CONNECTOR_HDMIA,
                                    hdmi->ddc);
 
+       /*
+        * drm_connector_attach_max_bpc_property() requires the
+        * connector to have a state.
+        */
+       drm_atomic_helper_connector_reset(connector);
+
+       drm_connector_attach_max_bpc_property(connector, 8, 16);
+
        if (hdmi->version >= 0x200a && hdmi->plat_data->use_drm_infoframe)
                drm_object_attach_property(&connector->base,
                        connector->dev->mode_config.hdr_output_metadata_property, 0);
@@ -2479,8 +2776,14 @@ static void dw_hdmi_bridge_enable(struct drm_bridge *bridge)
 }
 
 static const struct drm_bridge_funcs dw_hdmi_bridge_funcs = {
+       .atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state,
+       .atomic_destroy_state = drm_atomic_helper_bridge_destroy_state,
+       .atomic_reset = drm_atomic_helper_bridge_reset,
        .attach = dw_hdmi_bridge_attach,
        .detach = dw_hdmi_bridge_detach,
+       .atomic_check = dw_hdmi_bridge_atomic_check,
+       .atomic_get_output_bus_fmts = dw_hdmi_bridge_atomic_get_output_bus_fmts,
+       .atomic_get_input_bus_fmts = dw_hdmi_bridge_atomic_get_input_bus_fmts,
        .enable = dw_hdmi_bridge_enable,
        .disable = dw_hdmi_bridge_disable,
        .mode_set = dw_hdmi_bridge_mode_set,
@@ -2949,6 +3252,12 @@ __dw_hdmi_probe(struct platform_device *pdev,
        hdmi->bridge.of_node = pdev->dev.of_node;
 #endif
 
+       if (hdmi->version >= 0x200a)
+               hdmi->connector.ycbcr_420_allowed =
+                       hdmi->plat_data->ycbcr_420_allowed;
+       else
+               hdmi->connector.ycbcr_420_allowed = false;
+
        memset(&pdevinfo, 0, sizeof(pdevinfo));
        pdevinfo.parent = dev;
        pdevinfo.id = PLATFORM_DEVID_AUTO;
index 19297e58b23225cb590e96f80075f8693c5e7396..dcabf56983336d1055d59e81fa12d2cfc9ff2b9a 100644 (file)
@@ -134,7 +134,7 @@ static int drm_map_handle(struct drm_device *dev, struct drm_hash_item *hash,
                                         shift, add);
 }
 
-/**
+/*
  * Core function to create a range of memory available for mapping by a
  * non-root process.
  *
@@ -398,7 +398,7 @@ struct drm_local_map *drm_legacy_findmap(struct drm_device *dev,
 }
 EXPORT_SYMBOL(drm_legacy_findmap);
 
-/**
+/*
  * Ioctl to specify a range of memory that is available for mapping by a
  * non-root process.
  *
@@ -499,7 +499,7 @@ int drm_legacy_getmap_ioctl(struct drm_device *dev, void *data,
        return 0;
 }
 
-/**
+/*
  * Remove a map private from list and deallocate resources if the mapping
  * isn't in use.
  *
@@ -659,7 +659,7 @@ int drm_legacy_rmmap_ioctl(struct drm_device *dev, void *data,
        return ret;
 }
 
-/**
+/*
  * Cleanup after an error on one of the addbufs() functions.
  *
  * \param dev DRM device.
@@ -694,7 +694,7 @@ static void drm_cleanup_buf_error(struct drm_device *dev,
 }
 
 #if IS_ENABLED(CONFIG_AGP)
-/**
+/*
  * Add AGP buffers for DMA transfers.
  *
  * \param dev struct drm_device to which the buffers are to be added.
@@ -1230,7 +1230,7 @@ static int drm_legacy_addbufs_sg(struct drm_device *dev,
        return 0;
 }
 
-/**
+/*
  * Add buffers for DMA transfers (ioctl).
  *
  * \param inode device inode.
@@ -1271,7 +1271,7 @@ int drm_legacy_addbufs(struct drm_device *dev, void *data,
        return ret;
 }
 
-/**
+/*
  * Get information about the buffer mappings.
  *
  * This was originally mean for debugging purposes, or by a sophisticated
@@ -1362,7 +1362,7 @@ int drm_legacy_infobufs(struct drm_device *dev, void *data,
        return __drm_legacy_infobufs(dev, data, &request->count, copy_one_buf);
 }
 
-/**
+/*
  * Specifies a low and high water mark for buffer allocation
  *
  * \param inode device inode.
@@ -1411,7 +1411,7 @@ int drm_legacy_markbufs(struct drm_device *dev, void *data,
        return 0;
 }
 
-/**
+/*
  * Unreserve the buffers in list, previously reserved using drmDMA.
  *
  * \param inode device inode.
@@ -1463,7 +1463,7 @@ int drm_legacy_freebufs(struct drm_device *dev, void *data,
        return 0;
 }
 
-/**
+/*
  * Maps all of the DMA buffers into client-virtual space (ioctl).
  *
  * \param inode device inode.
index 1f802d8e5681e621b27467d4d16675b1f1beca56..c99be950bf17752ff1fbc90136397ad8d10e65da 100644 (file)
@@ -47,7 +47,7 @@ struct drm_ctx_list {
 /** \name Context bitmap support */
 /*@{*/
 
-/**
+/*
  * Free a handle from the context bitmap.
  *
  * \param dev DRM device.
@@ -68,7 +68,7 @@ void drm_legacy_ctxbitmap_free(struct drm_device * dev, int ctx_handle)
        mutex_unlock(&dev->struct_mutex);
 }
 
-/**
+/*
  * Context bitmap allocation.
  *
  * \param dev DRM device.
@@ -88,7 +88,7 @@ static int drm_legacy_ctxbitmap_next(struct drm_device * dev)
        return ret;
 }
 
-/**
+/*
  * Context bitmap initialization.
  *
  * \param dev DRM device.
@@ -104,7 +104,7 @@ void drm_legacy_ctxbitmap_init(struct drm_device * dev)
        idr_init(&dev->ctx_idr);
 }
 
-/**
+/*
  * Context bitmap cleanup.
  *
  * \param dev DRM device.
@@ -163,7 +163,7 @@ void drm_legacy_ctxbitmap_flush(struct drm_device *dev, struct drm_file *file)
 /** \name Per Context SAREA Support */
 /*@{*/
 
-/**
+/*
  * Get per-context SAREA.
  *
  * \param inode device inode.
@@ -211,7 +211,7 @@ int drm_legacy_getsareactx(struct drm_device *dev, void *data,
        return 0;
 }
 
-/**
+/*
  * Set per-context SAREA.
  *
  * \param inode device inode.
@@ -263,7 +263,7 @@ int drm_legacy_setsareactx(struct drm_device *dev, void *data,
 /** \name The actual DRM context handling routines */
 /*@{*/
 
-/**
+/*
  * Switch context.
  *
  * \param dev DRM device.
@@ -290,7 +290,7 @@ static int drm_context_switch(struct drm_device * dev, int old, int new)
        return 0;
 }
 
-/**
+/*
  * Complete context switch.
  *
  * \param dev DRM device.
@@ -318,7 +318,7 @@ static int drm_context_switch_complete(struct drm_device *dev,
        return 0;
 }
 
-/**
+/*
  * Reserve contexts.
  *
  * \param inode device inode.
@@ -351,7 +351,7 @@ int drm_legacy_resctx(struct drm_device *dev, void *data,
        return 0;
 }
 
-/**
+/*
  * Add context.
  *
  * \param inode device inode.
@@ -404,7 +404,7 @@ int drm_legacy_addctx(struct drm_device *dev, void *data,
        return 0;
 }
 
-/**
+/*
  * Get context.
  *
  * \param inode device inode.
@@ -428,7 +428,7 @@ int drm_legacy_getctx(struct drm_device *dev, void *data,
        return 0;
 }
 
-/**
+/*
  * Switch context.
  *
  * \param inode device inode.
@@ -452,7 +452,7 @@ int drm_legacy_switchctx(struct drm_device *dev, void *data,
        return drm_context_switch(dev, dev->last_context, ctx->handle);
 }
 
-/**
+/*
  * New context.
  *
  * \param inode device inode.
@@ -478,7 +478,7 @@ int drm_legacy_newctx(struct drm_device *dev, void *data,
        return 0;
 }
 
-/**
+/*
  * Remove context.
  *
  * \param inode device inode.
index 6c62ad8f44142f9e36b308cf37dd94181a35955a..4b255e25e4a14668004d77ab9fa1d49f022e06ff 100644 (file)
@@ -2063,7 +2063,7 @@ ssize_t drm_dp_mst_dpcd_read(struct drm_dp_aux *aux,
  * sideband messaging as drm_dp_dpcd_write() does for local
  * devices via actual AUX CH.
  *
- * Return: 0 on success, negative error code on failure.
+ * Return: number of bytes written on success, negative error code on failure.
  */
 ssize_t drm_dp_mst_dpcd_write(struct drm_dp_aux *aux,
                              unsigned int offset, void *buffer, size_t size)
@@ -2092,7 +2092,10 @@ static int drm_dp_check_mstb_guid(struct drm_dp_mst_branch *mstb, u8 *guid)
                }
        }
 
-       return ret;
+       if (ret < 16 && ret > 0)
+               return -EPROTO;
+
+       return ret == 16 ? 0 : ret;
 }
 
 static void build_mst_prop_path(const struct drm_dp_mst_branch *mstb,
@@ -2175,7 +2178,7 @@ drm_dp_mst_port_add_connector(struct drm_dp_mst_branch *mstb,
                drm_connector_set_tile_property(port->connector);
        }
 
-       mgr->cbs->register_connector(port->connector);
+       drm_connector_register(port->connector);
        return;
 
 error:
@@ -2907,8 +2910,14 @@ static int drm_dp_send_link_address(struct drm_dp_mst_topology_mgr *mgr,
        drm_dp_dump_link_address(reply);
 
        ret = drm_dp_check_mstb_guid(mstb, reply->guid);
-       if (ret)
+       if (ret) {
+               char buf[64];
+
+               drm_dp_mst_rad_to_str(mstb->rad, mstb->lct, buf, sizeof(buf));
+               DRM_ERROR("GUID check on %s failed: %d\n",
+                         buf, ret);
                goto out;
+       }
 
        for (i = 0; i < reply->nports; i++) {
                port_mask |= BIT(reply->ports[i].port_number);
@@ -3428,12 +3437,9 @@ static int drm_dp_send_dpcd_write(struct drm_dp_mst_topology_mgr *mgr,
        drm_dp_queue_down_tx(mgr, txmsg);
 
        ret = drm_dp_mst_wait_tx_reply(mstb, txmsg);
-       if (ret > 0) {
-               if (txmsg->reply.reply_type == DP_SIDEBAND_REPLY_NAK)
-                       ret = -EIO;
-               else
-                       ret = 0;
-       }
+       if (ret > 0 && txmsg->reply.reply_type == DP_SIDEBAND_REPLY_NAK)
+               ret = -EIO;
+
        kfree(txmsg);
 fail_put:
        drm_dp_mst_topology_put_mstb(mstb);
@@ -4667,11 +4673,23 @@ static void drm_dp_tx_work(struct work_struct *work)
        mutex_unlock(&mgr->qlock);
 }
 
+static inline void drm_dp_destroy_connector(struct drm_dp_mst_port *port)
+{
+       if (!port->connector)
+               return;
+
+       if (port->mgr->cbs->destroy_connector) {
+               port->mgr->cbs->destroy_connector(port->mgr, port->connector);
+       } else {
+               drm_connector_unregister(port->connector);
+               drm_connector_put(port->connector);
+       }
+}
+
 static inline void
 drm_dp_delayed_destroy_port(struct drm_dp_mst_port *port)
 {
-       if (port->connector)
-               port->mgr->cbs->destroy_connector(port->mgr, port->connector);
+       drm_dp_destroy_connector(port);
 
        drm_dp_port_set_pdt(port, DP_PEER_DEVICE_NONE, port->mcs);
        drm_dp_mst_put_port_malloc(port);
index ad41764a4ebe5e2187565c18608681ca65bc74c1..116451101426d40e7acf0c8b002ed4bba823378e 100644 (file)
@@ -4434,6 +4434,7 @@ static void drm_edid_to_eld(struct drm_connector *connector, struct edid *edid)
 
        if (cea_revision(cea) >= 3) {
                int i, start, end;
+               int sad_count;
 
                if (cea_db_offsets(cea, &start, &end)) {
                        start = 0;
@@ -4445,8 +4446,6 @@ static void drm_edid_to_eld(struct drm_connector *connector, struct edid *edid)
                        dbl = cea_db_payload_len(db);
 
                        switch (cea_db_tag(db)) {
-                               int sad_count;
-
                        case AUDIO_BLOCK:
                                /* Audio Data Block, contains SADs */
                                sad_count = min(dbl / 3, 15 - total_sad_count);
@@ -4938,6 +4937,47 @@ static void drm_parse_cea_ext(struct drm_connector *connector,
        }
 }
 
+static
+void get_monitor_range(struct detailed_timing *timing,
+                      void *info_monitor_range)
+{
+       struct drm_monitor_range_info *monitor_range = info_monitor_range;
+       const struct detailed_non_pixel *data = &timing->data.other_data;
+       const struct detailed_data_monitor_range *range = &data->data.range;
+
+       if (!is_display_descriptor((const u8 *)timing, EDID_DETAIL_MONITOR_RANGE))
+               return;
+
+       /*
+        * Check for flag range limits only. If flag == 1 then
+        * no additional timing information provided.
+        * Default GTF, GTF Secondary curve and CVT are not
+        * supported
+        */
+       if (range->flags != DRM_EDID_RANGE_LIMITS_ONLY_FLAG)
+               return;
+
+       monitor_range->min_vfreq = range->min_vfreq;
+       monitor_range->max_vfreq = range->max_vfreq;
+}
+
+static
+void drm_get_monitor_range(struct drm_connector *connector,
+                          const struct edid *edid)
+{
+       struct drm_display_info *info = &connector->display_info;
+
+       if (!version_greater(edid, 1, 1))
+               return;
+
+       drm_for_each_detailed_block((u8 *)edid, get_monitor_range,
+                                   &info->monitor_range);
+
+       DRM_DEBUG_KMS("Supported Monitor Refresh rate range is %d Hz - %d Hz\n",
+                     info->monitor_range.min_vfreq,
+                     info->monitor_range.max_vfreq);
+}
+
 /* A connector has no EDID information, so we've got no EDID to compute quirks from. Reset
  * all of the values which would have been set from EDID
  */
@@ -4960,6 +5000,7 @@ drm_reset_display_info(struct drm_connector *connector)
        memset(&info->hdmi, 0, sizeof(info->hdmi));
 
        info->non_desktop = 0;
+       memset(&info->monitor_range, 0, sizeof(info->monitor_range));
 }
 
 u32 drm_add_display_info(struct drm_connector *connector, const struct edid *edid)
@@ -4975,6 +5016,8 @@ u32 drm_add_display_info(struct drm_connector *connector, const struct edid *edi
 
        info->non_desktop = !!(quirks & EDID_QUIRK_NON_DESKTOP);
 
+       drm_get_monitor_range(connector, edid);
+
        DRM_DEBUG_KMS("non_desktop set to %d\n", info->non_desktop);
 
        if (edid->revision < 3)
index a9e4a610445ac06dcf29c44829eeef60fa0c020e..37627d06fb0609e4dc9dcab6b33f981a280087b9 100644 (file)
@@ -218,7 +218,7 @@ drm_gem_object_handle_put_unlocked(struct drm_gem_object *obj)
        struct drm_device *dev = obj->dev;
        bool final = false;
 
-       if (WARN_ON(obj->handle_count == 0))
+       if (WARN_ON(READ_ONCE(obj->handle_count) == 0))
                return;
 
        /*
index 2c79e8199e3cec4d62e390f4684d792f76f0b155..f16eefbf2829260ed1cf2ceff5357d4ebc9d6795 100644 (file)
@@ -46,7 +46,7 @@
 
 static int drm_lock_take(struct drm_lock_data *lock_data, unsigned int context);
 
-/**
+/*
  * Take the heavyweight lock.
  *
  * \param lock lock pointer.
@@ -93,7 +93,7 @@ int drm_lock_take(struct drm_lock_data *lock_data,
        return 0;
 }
 
-/**
+/*
  * This takes a lock forcibly and hands it to context. Should ONLY be used
  * inside *_unlock to give lock to kernel before calling *_dma_schedule.
  *
@@ -150,7 +150,7 @@ static int drm_legacy_lock_free(struct drm_lock_data *lock_data,
        return 0;
 }
 
-/**
+/*
  * Lock ioctl.
  *
  * \param inode device inode.
@@ -243,7 +243,7 @@ int drm_legacy_lock(struct drm_device *dev, void *data,
        return 0;
 }
 
-/**
+/*
  * Unlock ioctl.
  *
  * \param inode device inode.
@@ -275,7 +275,7 @@ int drm_legacy_unlock(struct drm_device *dev, void *data, struct drm_file *file_
        return 0;
 }
 
-/**
+/*
  * This function returns immediately and takes the hw lock
  * with the kernel context if it is free, otherwise it gets the highest priority when and if
  * it is eventually released.
@@ -287,7 +287,6 @@ int drm_legacy_unlock(struct drm_device *dev, void *data, struct drm_file *file_
  * This should be sufficient to wait for GPU idle without
  * having to worry about starvation.
  */
-
 void drm_legacy_idlelock_take(struct drm_lock_data *lock_data)
 {
        int ret;
index 47d5de9ca0a8d767f22e81ce6b081ec6c2500537..bc6e208949e85fb69e5f9661de16832fabeecdce 100644 (file)
@@ -405,10 +405,10 @@ next_hole(struct drm_mm *mm,
  */
 int drm_mm_reserve_node(struct drm_mm *mm, struct drm_mm_node *node)
 {
-       u64 end = node->start + node->size;
        struct drm_mm_node *hole;
        u64 hole_start, hole_end;
        u64 adj_start, adj_end;
+       u64 end;
 
        end = node->start + node->size;
        if (unlikely(end <= node->start))
index 2e83c3d72af9793ca06b7e6411cb0d2f08d2ce96..939f0032aab18b00e837109ad1b16b81d73c8b19 100644 (file)
@@ -228,7 +228,7 @@ static ssize_t modes_show(struct device *device,
 
        mutex_lock(&connector->dev->mode_config.mutex);
        list_for_each_entry(mode, &connector->modes, head) {
-               written += snprintf(buf + written, PAGE_SIZE - written, "%s\n",
+               written += scnprintf(buf + written, PAGE_SIZE - written, "%s\n",
                                    mode->name);
        }
        mutex_unlock(&connector->dev->mode_config.mutex);
index 64619fe9004621577f6060c83176903bbbaace65..aa88911bbc06d48aea6c664a25f3bbb47deb1115 100644 (file)
@@ -102,7 +102,7 @@ static pgprot_t drm_dma_prot(uint32_t map_type, struct vm_area_struct *vma)
        return tmp;
 }
 
-/**
+/*
  * \c fault method for AGP virtual memory.
  *
  * \param vma virtual memory area.
@@ -192,7 +192,7 @@ static vm_fault_t drm_vm_fault(struct vm_fault *vmf)
 }
 #endif
 
-/**
+/*
  * \c nopage method for shared virtual memory.
  *
  * \param vma virtual memory area.
@@ -225,7 +225,7 @@ static vm_fault_t drm_vm_shm_fault(struct vm_fault *vmf)
        return 0;
 }
 
-/**
+/*
  * \c close method for shared virtual memory.
  *
  * \param vma virtual memory area.
@@ -294,7 +294,7 @@ static void drm_vm_shm_close(struct vm_area_struct *vma)
        mutex_unlock(&dev->struct_mutex);
 }
 
-/**
+/*
  * \c fault method for DMA virtual memory.
  *
  * \param address access address.
@@ -329,7 +329,7 @@ static vm_fault_t drm_vm_dma_fault(struct vm_fault *vmf)
        return 0;
 }
 
-/**
+/*
  * \c fault method for scatter-gather virtual memory.
  *
  * \param address access address.
@@ -435,7 +435,7 @@ static void drm_vm_close_locked(struct drm_device *dev,
        }
 }
 
-/**
+/*
  * \c close method for all virtual memory types.
  *
  * \param vma virtual memory area.
@@ -453,7 +453,7 @@ static void drm_vm_close(struct vm_area_struct *vma)
        mutex_unlock(&dev->struct_mutex);
 }
 
-/**
+/*
  * mmap DMA memory.
  *
  * \param file_priv DRM file private.
@@ -513,7 +513,7 @@ static resource_size_t drm_core_get_reg_ofs(struct drm_device *dev)
 #endif
 }
 
-/**
+/*
  * mmap DMA memory.
  *
  * \param file_priv DRM file private.
index e08caca658c606e2cbf4bc4b5a8a88c6ab1d0d99..44f3fd251ca1f1ccc4bd9600c7ba50a26b0efd67 100644 (file)
@@ -748,24 +748,8 @@ err:
        return NULL;
 }
 
-static void intel_dp_register_mst_connector(struct drm_connector *connector)
-{
-       drm_connector_register(connector);
-}
-
-static void intel_dp_destroy_mst_connector(struct drm_dp_mst_topology_mgr *mgr,
-                                          struct drm_connector *connector)
-{
-       DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n", connector->base.id, connector->name);
-       drm_connector_unregister(connector);
-
-       drm_connector_put(connector);
-}
-
 static const struct drm_dp_mst_topology_cbs mst_cbs = {
        .add_connector = intel_dp_add_mst_connector,
-       .register_connector = intel_dp_register_mst_connector,
-       .destroy_connector = intel_dp_destroy_mst_connector,
 };
 
 static struct intel_dp_mst_encoder *
index 3bb7ffe5fc39124a3aa645f82524152282e21c6e..e8c94915a4fcf3936f7a18c7fc9bdabcaa8e6016 100644 (file)
@@ -16,6 +16,7 @@
 
 #include <drm/bridge/dw_hdmi.h>
 #include <drm/drm_atomic_helper.h>
+#include <drm/drm_bridge.h>
 #include <drm/drm_device.h>
 #include <drm/drm_edid.h>
 #include <drm/drm_probe_helper.h>
@@ -135,6 +136,7 @@ struct meson_dw_hdmi_data {
 
 struct meson_dw_hdmi {
        struct drm_encoder encoder;
+       struct drm_bridge bridge;
        struct dw_hdmi_plat_data dw_plat_data;
        struct meson_drm *priv;
        struct device *dev;
@@ -148,9 +150,12 @@ struct meson_dw_hdmi {
        struct regulator *hdmi_supply;
        u32 irq_stat;
        struct dw_hdmi *hdmi;
+       unsigned long output_bus_fmt;
 };
 #define encoder_to_meson_dw_hdmi(x) \
        container_of(x, struct meson_dw_hdmi, encoder)
+#define bridge_to_meson_dw_hdmi(x) \
+       container_of(x, struct meson_dw_hdmi, bridge)
 
 static inline int dw_hdmi_is_compatible(struct meson_dw_hdmi *dw_hdmi,
                                        const char *compat)
@@ -297,6 +302,10 @@ static void meson_hdmi_phy_setup_mode(struct meson_dw_hdmi *dw_hdmi,
        struct meson_drm *priv = dw_hdmi->priv;
        unsigned int pixel_clock = mode->clock;
 
+       /* For 420, pixel clock is half unlike venc clock */
+       if (dw_hdmi->output_bus_fmt == MEDIA_BUS_FMT_UYYVYY8_0_5X24)
+               pixel_clock /= 2;
+
        if (dw_hdmi_is_compatible(dw_hdmi, "amlogic,meson-gxl-dw-hdmi") ||
            dw_hdmi_is_compatible(dw_hdmi, "amlogic,meson-gxm-dw-hdmi")) {
                if (pixel_clock >= 371250) {
@@ -368,29 +377,40 @@ static inline void meson_dw_hdmi_phy_reset(struct meson_dw_hdmi *dw_hdmi)
 }
 
 static void dw_hdmi_set_vclk(struct meson_dw_hdmi *dw_hdmi,
-                            struct drm_display_mode *mode)
+                            const struct drm_display_mode *mode)
 {
        struct meson_drm *priv = dw_hdmi->priv;
        int vic = drm_match_cea_mode(mode);
+       unsigned int phy_freq;
        unsigned int vclk_freq;
        unsigned int venc_freq;
        unsigned int hdmi_freq;
 
        vclk_freq = mode->clock;
 
+       /* For 420, pixel clock is half unlike venc clock */
+       if (dw_hdmi->output_bus_fmt == MEDIA_BUS_FMT_UYYVYY8_0_5X24)
+               vclk_freq /= 2;
+
+       /* TMDS clock is pixel_clock * 10 */
+       phy_freq = vclk_freq * 10;
+
        if (!vic) {
-               meson_vclk_setup(priv, MESON_VCLK_TARGET_DMT, vclk_freq,
-                                vclk_freq, vclk_freq, false);
+               meson_vclk_setup(priv, MESON_VCLK_TARGET_DMT, phy_freq,
+                                vclk_freq, vclk_freq, vclk_freq, false);
                return;
        }
 
+       /* 480i/576i needs global pixel doubling */
        if (mode->flags & DRM_MODE_FLAG_DBLCLK)
                vclk_freq *= 2;
 
        venc_freq = vclk_freq;
        hdmi_freq = vclk_freq;
 
-       if (meson_venc_hdmi_venc_repeat(vic))
+       /* VENC double pixels for 1080i, 720p and YUV420 modes */
+       if (meson_venc_hdmi_venc_repeat(vic) ||
+           dw_hdmi->output_bus_fmt == MEDIA_BUS_FMT_UYYVYY8_0_5X24)
                venc_freq *= 2;
 
        vclk_freq = max(venc_freq, hdmi_freq);
@@ -398,11 +418,11 @@ static void dw_hdmi_set_vclk(struct meson_dw_hdmi *dw_hdmi,
        if (mode->flags & DRM_MODE_FLAG_DBLCLK)
                venc_freq /= 2;
 
-       DRM_DEBUG_DRIVER("vclk:%d venc=%d hdmi=%d enci=%d\n",
-               vclk_freq, venc_freq, hdmi_freq,
+       DRM_DEBUG_DRIVER("vclk:%d phy=%d venc=%d hdmi=%d enci=%d\n",
+               phy_freq, vclk_freq, venc_freq, hdmi_freq,
                priv->venc.hdmi_use_enci);
 
-       meson_vclk_setup(priv, MESON_VCLK_TARGET_HDMI, vclk_freq,
+       meson_vclk_setup(priv, MESON_VCLK_TARGET_HDMI, phy_freq, vclk_freq,
                         venc_freq, hdmi_freq, priv->venc.hdmi_use_enci);
 }
 
@@ -437,8 +457,9 @@ static int dw_hdmi_phy_init(struct dw_hdmi *hdmi, void *data,
        /* Enable normal output to PHY */
        dw_hdmi->data->top_write(dw_hdmi, HDMITX_TOP_BIST_CNTL, BIT(12));
 
-       /* TMDS pattern setup (TOFIX Handle the YUV420 case) */
-       if (mode->clock > 340000) {
+       /* TMDS pattern setup */
+       if (mode->clock > 340000 &&
+           dw_hdmi->output_bus_fmt == MEDIA_BUS_FMT_YUV8_1X24) {
                dw_hdmi->data->top_write(dw_hdmi, HDMITX_TOP_TMDS_CLK_PTTN_01,
                                  0);
                dw_hdmi->data->top_write(dw_hdmi, HDMITX_TOP_TMDS_CLK_PTTN_23,
@@ -613,6 +634,8 @@ dw_hdmi_mode_valid(struct drm_connector *connector,
                   const struct drm_display_mode *mode)
 {
        struct meson_drm *priv = connector->dev->dev_private;
+       bool is_hdmi2_sink = connector->display_info.hdmi.scdc.supported;
+       unsigned int phy_freq;
        unsigned int vclk_freq;
        unsigned int venc_freq;
        unsigned int hdmi_freq;
@@ -621,9 +644,11 @@ dw_hdmi_mode_valid(struct drm_connector *connector,
 
        DRM_DEBUG_DRIVER("Modeline " DRM_MODE_FMT "\n", DRM_MODE_ARG(mode));
 
-       /* If sink max TMDS clock, we reject the mode */
+       /* If sink does not support 540MHz, reject the non-420 HDMI2 modes */
        if (connector->display_info.max_tmds_clock &&
-           mode->clock > connector->display_info.max_tmds_clock)
+           mode->clock > connector->display_info.max_tmds_clock &&
+           !drm_mode_is_420_only(&connector->display_info, mode) &&
+           !drm_mode_is_420_also(&connector->display_info, mode))
                return MODE_BAD;
 
        /* Check against non-VIC supported modes */
@@ -639,6 +664,15 @@ dw_hdmi_mode_valid(struct drm_connector *connector,
 
        vclk_freq = mode->clock;
 
+       /* For 420, pixel clock is half unlike venc clock */
+       if (drm_mode_is_420_only(&connector->display_info, mode) ||
+           (!is_hdmi2_sink &&
+            drm_mode_is_420_also(&connector->display_info, mode)))
+               vclk_freq /= 2;
+
+       /* TMDS clock is pixel_clock * 10 */
+       phy_freq = vclk_freq * 10;
+
        /* 480i/576i needs global pixel doubling */
        if (mode->flags & DRM_MODE_FLAG_DBLCLK)
                vclk_freq *= 2;
@@ -646,8 +680,11 @@ dw_hdmi_mode_valid(struct drm_connector *connector,
        venc_freq = vclk_freq;
        hdmi_freq = vclk_freq;
 
-       /* VENC double pixels for 1080i and 720p modes */
-       if (meson_venc_hdmi_venc_repeat(vic))
+       /* VENC double pixels for 1080i, 720p and YUV420 modes */
+       if (meson_venc_hdmi_venc_repeat(vic) ||
+           drm_mode_is_420_only(&connector->display_info, mode) ||
+           (!is_hdmi2_sink &&
+            drm_mode_is_420_also(&connector->display_info, mode)))
                venc_freq *= 2;
 
        vclk_freq = max(venc_freq, hdmi_freq);
@@ -655,14 +692,19 @@ dw_hdmi_mode_valid(struct drm_connector *connector,
        if (mode->flags & DRM_MODE_FLAG_DBLCLK)
                venc_freq /= 2;
 
-       dev_dbg(connector->dev->dev, "%s: vclk:%d venc=%d hdmi=%d\n", __func__,
-               vclk_freq, venc_freq, hdmi_freq);
+       dev_dbg(connector->dev->dev, "%s: vclk:%d phy=%d venc=%d hdmi=%d\n",
+               __func__, phy_freq, vclk_freq, venc_freq, hdmi_freq);
 
-       return meson_vclk_vic_supported_freq(vclk_freq);
+       return meson_vclk_vic_supported_freq(phy_freq, vclk_freq);
 }
 
 /* Encoder */
 
+static const u32 meson_dw_hdmi_out_bus_fmts[] = {
+       MEDIA_BUS_FMT_YUV8_1X24,
+       MEDIA_BUS_FMT_UYYVYY8_0_5X24,
+};
+
 static void meson_venc_hdmi_encoder_destroy(struct drm_encoder *encoder)
 {
        drm_encoder_cleanup(encoder);
@@ -672,16 +714,54 @@ static const struct drm_encoder_funcs meson_venc_hdmi_encoder_funcs = {
        .destroy        = meson_venc_hdmi_encoder_destroy,
 };
 
-static int meson_venc_hdmi_encoder_atomic_check(struct drm_encoder *encoder,
+static u32 *
+meson_venc_hdmi_encoder_get_inp_bus_fmts(struct drm_bridge *bridge,
+                                       struct drm_bridge_state *bridge_state,
+                                       struct drm_crtc_state *crtc_state,
+                                       struct drm_connector_state *conn_state,
+                                       u32 output_fmt,
+                                       unsigned int *num_input_fmts)
+{
+       u32 *input_fmts = NULL;
+       int i;
+
+       *num_input_fmts = 0;
+
+       for (i = 0 ; i < ARRAY_SIZE(meson_dw_hdmi_out_bus_fmts) ; ++i) {
+               if (output_fmt == meson_dw_hdmi_out_bus_fmts[i]) {
+                       *num_input_fmts = 1;
+                       input_fmts = kcalloc(*num_input_fmts,
+                                            sizeof(*input_fmts),
+                                            GFP_KERNEL);
+                       if (!input_fmts)
+                               return NULL;
+
+                       input_fmts[0] = output_fmt;
+
+                       break;
+               }
+       }
+
+       return input_fmts;
+}
+
+static int meson_venc_hdmi_encoder_atomic_check(struct drm_bridge *bridge,
+                                       struct drm_bridge_state *bridge_state,
                                        struct drm_crtc_state *crtc_state,
                                        struct drm_connector_state *conn_state)
 {
+       struct meson_dw_hdmi *dw_hdmi = bridge_to_meson_dw_hdmi(bridge);
+
+       dw_hdmi->output_bus_fmt = bridge_state->output_bus_cfg.format;
+
+       DRM_DEBUG_DRIVER("output_bus_fmt %lx\n", dw_hdmi->output_bus_fmt);
+
        return 0;
 }
 
-static void meson_venc_hdmi_encoder_disable(struct drm_encoder *encoder)
+static void meson_venc_hdmi_encoder_disable(struct drm_bridge *bridge)
 {
-       struct meson_dw_hdmi *dw_hdmi = encoder_to_meson_dw_hdmi(encoder);
+       struct meson_dw_hdmi *dw_hdmi = bridge_to_meson_dw_hdmi(bridge);
        struct meson_drm *priv = dw_hdmi->priv;
 
        DRM_DEBUG_DRIVER("\n");
@@ -693,9 +773,9 @@ static void meson_venc_hdmi_encoder_disable(struct drm_encoder *encoder)
        writel_relaxed(0, priv->io_base + _REG(ENCP_VIDEO_EN));
 }
 
-static void meson_venc_hdmi_encoder_enable(struct drm_encoder *encoder)
+static void meson_venc_hdmi_encoder_enable(struct drm_bridge *bridge)
 {
-       struct meson_dw_hdmi *dw_hdmi = encoder_to_meson_dw_hdmi(encoder);
+       struct meson_dw_hdmi *dw_hdmi = bridge_to_meson_dw_hdmi(bridge);
        struct meson_drm *priv = dw_hdmi->priv;
 
        DRM_DEBUG_DRIVER("%s\n", priv->venc.hdmi_use_enci ? "VENCI" : "VENCP");
@@ -706,32 +786,47 @@ static void meson_venc_hdmi_encoder_enable(struct drm_encoder *encoder)
                writel_relaxed(1, priv->io_base + _REG(ENCP_VIDEO_EN));
 }
 
-static void meson_venc_hdmi_encoder_mode_set(struct drm_encoder *encoder,
-                                  struct drm_display_mode *mode,
-                                  struct drm_display_mode *adjusted_mode)
+static void meson_venc_hdmi_encoder_mode_set(struct drm_bridge *bridge,
+                                  const struct drm_display_mode *mode,
+                                  const struct drm_display_mode *adjusted_mode)
 {
-       struct meson_dw_hdmi *dw_hdmi = encoder_to_meson_dw_hdmi(encoder);
+       struct meson_dw_hdmi *dw_hdmi = bridge_to_meson_dw_hdmi(bridge);
        struct meson_drm *priv = dw_hdmi->priv;
        int vic = drm_match_cea_mode(mode);
+       unsigned int ycrcb_map = VPU_HDMI_OUTPUT_CBYCR;
+       bool yuv420_mode = false;
 
        DRM_DEBUG_DRIVER("\"%s\" vic %d\n", mode->name, vic);
 
+       if (dw_hdmi->output_bus_fmt == MEDIA_BUS_FMT_UYYVYY8_0_5X24) {
+               ycrcb_map = VPU_HDMI_OUTPUT_CRYCB;
+               yuv420_mode = true;
+       }
+
        /* VENC + VENC-DVI Mode setup */
-       meson_venc_hdmi_mode_set(priv, vic, mode);
+       meson_venc_hdmi_mode_set(priv, vic, ycrcb_map, yuv420_mode, mode);
 
        /* VCLK Set clock */
        dw_hdmi_set_vclk(dw_hdmi, mode);
 
-       /* Setup YUV444 to HDMI-TX, no 10bit diphering */
-       writel_relaxed(0, priv->io_base + _REG(VPU_HDMI_FMT_CTRL));
+       if (dw_hdmi->output_bus_fmt == MEDIA_BUS_FMT_UYYVYY8_0_5X24)
+               /* Setup YUV420 to HDMI-TX, no 10bit diphering */
+               writel_relaxed(2 | (2 << 2),
+                              priv->io_base + _REG(VPU_HDMI_FMT_CTRL));
+       else
+               /* Setup YUV444 to HDMI-TX, no 10bit diphering */
+               writel_relaxed(0, priv->io_base + _REG(VPU_HDMI_FMT_CTRL));
 }
 
-static const struct drm_encoder_helper_funcs
-                               meson_venc_hdmi_encoder_helper_funcs = {
-       .atomic_check   = meson_venc_hdmi_encoder_atomic_check,
-       .disable        = meson_venc_hdmi_encoder_disable,
-       .enable         = meson_venc_hdmi_encoder_enable,
-       .mode_set       = meson_venc_hdmi_encoder_mode_set,
+static const struct drm_bridge_funcs meson_venc_hdmi_encoder_bridge_funcs = {
+       .atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state,
+       .atomic_destroy_state = drm_atomic_helper_bridge_destroy_state,
+       .atomic_get_input_bus_fmts = meson_venc_hdmi_encoder_get_inp_bus_fmts,
+       .atomic_reset = drm_atomic_helper_bridge_reset,
+       .atomic_check = meson_venc_hdmi_encoder_atomic_check,
+       .enable = meson_venc_hdmi_encoder_enable,
+       .disable = meson_venc_hdmi_encoder_disable,
+       .mode_set = meson_venc_hdmi_encoder_mode_set,
 };
 
 /* DW HDMI Regmap */
@@ -852,6 +947,7 @@ static int meson_dw_hdmi_bind(struct device *dev, struct device *master,
        struct drm_device *drm = data;
        struct meson_drm *priv = drm->dev_private;
        struct dw_hdmi_plat_data *dw_plat_data;
+       struct drm_bridge *next_bridge;
        struct drm_encoder *encoder;
        struct resource *res;
        int irq;
@@ -953,8 +1049,6 @@ static int meson_dw_hdmi_bind(struct device *dev, struct device *master,
 
        /* Encoder */
 
-       drm_encoder_helper_add(encoder, &meson_venc_hdmi_encoder_helper_funcs);
-
        ret = drm_encoder_init(drm, encoder, &meson_venc_hdmi_encoder_funcs,
                               DRM_MODE_ENCODER_TMDS, "meson_hdmi");
        if (ret) {
@@ -962,6 +1056,9 @@ static int meson_dw_hdmi_bind(struct device *dev, struct device *master,
                return ret;
        }
 
+       meson_dw_hdmi->bridge.funcs = &meson_venc_hdmi_encoder_bridge_funcs;
+       drm_bridge_attach(encoder, &meson_dw_hdmi->bridge, NULL, 0);
+
        encoder->possible_crtcs = BIT(0);
 
        DRM_DEBUG_DRIVER("encoder initialized\n");
@@ -974,8 +1071,8 @@ static int meson_dw_hdmi_bind(struct device *dev, struct device *master,
        dw_plat_data->phy_ops = &meson_dw_hdmi_phy_ops;
        dw_plat_data->phy_name = "meson_dw_hdmi_phy";
        dw_plat_data->phy_data = meson_dw_hdmi;
-       dw_plat_data->input_bus_format = MEDIA_BUS_FMT_YUV8_1X24;
        dw_plat_data->input_bus_encoding = V4L2_YCBCR_ENC_709;
+       dw_plat_data->ycbcr_420_allowed = true;
 
        if (dw_hdmi_is_compatible(meson_dw_hdmi, "amlogic,meson-gxl-dw-hdmi") ||
            dw_hdmi_is_compatible(meson_dw_hdmi, "amlogic,meson-gxm-dw-hdmi") ||
@@ -984,11 +1081,16 @@ static int meson_dw_hdmi_bind(struct device *dev, struct device *master,
 
        platform_set_drvdata(pdev, meson_dw_hdmi);
 
-       meson_dw_hdmi->hdmi = dw_hdmi_bind(pdev, encoder,
-                                          &meson_dw_hdmi->dw_plat_data);
+       meson_dw_hdmi->hdmi = dw_hdmi_probe(pdev,
+                                           &meson_dw_hdmi->dw_plat_data);
        if (IS_ERR(meson_dw_hdmi->hdmi))
                return PTR_ERR(meson_dw_hdmi->hdmi);
 
+       next_bridge = of_drm_find_bridge(pdev->dev.of_node);
+       if (next_bridge)
+               drm_bridge_attach(encoder, next_bridge,
+                                 &meson_dw_hdmi->bridge, 0);
+
        DRM_DEBUG_DRIVER("HDMI controller initialized\n");
 
        return 0;
index f690793ae2d573f8cd01dfe54fa02bf6867e34f8..fdf26dac9fa8ed8f7c0f9b56e83b48b790f5bc1e 100644 (file)
@@ -354,12 +354,17 @@ enum {
 /* 2970 /1 /1 /1 /5 /2  => /1 /1 */
        MESON_VCLK_HDMI_297000,
 /* 5940 /1 /1 /2 /5 /1  => /1 /1 */
-       MESON_VCLK_HDMI_594000
+       MESON_VCLK_HDMI_594000,
+/* 2970 /1 /1 /1 /5 /1  => /1 /2 */
+       MESON_VCLK_HDMI_594000_YUV420,
 };
 
 struct meson_vclk_params {
+       unsigned int pll_freq;
+       unsigned int phy_freq;
+       unsigned int vclk_freq;
+       unsigned int venc_freq;
        unsigned int pixel_freq;
-       unsigned int pll_base_freq;
        unsigned int pll_od1;
        unsigned int pll_od2;
        unsigned int pll_od3;
@@ -367,8 +372,11 @@ struct meson_vclk_params {
        unsigned int vclk_div;
 } params[] = {
        [MESON_VCLK_HDMI_ENCI_54000] = {
+               .pll_freq = 4320000,
+               .phy_freq = 270000,
+               .vclk_freq = 54000,
+               .venc_freq = 54000,
                .pixel_freq = 54000,
-               .pll_base_freq = 4320000,
                .pll_od1 = 4,
                .pll_od2 = 4,
                .pll_od3 = 1,
@@ -376,8 +384,11 @@ struct meson_vclk_params {
                .vclk_div = 1,
        },
        [MESON_VCLK_HDMI_DDR_54000] = {
-               .pixel_freq = 54000,
-               .pll_base_freq = 4320000,
+               .pll_freq = 4320000,
+               .phy_freq = 270000,
+               .vclk_freq = 54000,
+               .venc_freq = 54000,
+               .pixel_freq = 27000,
                .pll_od1 = 4,
                .pll_od2 = 4,
                .pll_od3 = 1,
@@ -385,8 +396,11 @@ struct meson_vclk_params {
                .vclk_div = 1,
        },
        [MESON_VCLK_HDMI_DDR_148500] = {
-               .pixel_freq = 148500,
-               .pll_base_freq = 2970000,
+               .pll_freq = 2970000,
+               .phy_freq = 742500,
+               .vclk_freq = 148500,
+               .venc_freq = 148500,
+               .pixel_freq = 74250,
                .pll_od1 = 4,
                .pll_od2 = 1,
                .pll_od3 = 1,
@@ -394,8 +408,11 @@ struct meson_vclk_params {
                .vclk_div = 1,
        },
        [MESON_VCLK_HDMI_74250] = {
+               .pll_freq = 2970000,
+               .phy_freq = 742500,
+               .vclk_freq = 74250,
+               .venc_freq = 74250,
                .pixel_freq = 74250,
-               .pll_base_freq = 2970000,
                .pll_od1 = 2,
                .pll_od2 = 2,
                .pll_od3 = 2,
@@ -403,8 +420,11 @@ struct meson_vclk_params {
                .vclk_div = 1,
        },
        [MESON_VCLK_HDMI_148500] = {
+               .pll_freq = 2970000,
+               .phy_freq = 1485000,
+               .vclk_freq = 148500,
+               .venc_freq = 148500,
                .pixel_freq = 148500,
-               .pll_base_freq = 2970000,
                .pll_od1 = 1,
                .pll_od2 = 2,
                .pll_od3 = 2,
@@ -412,8 +432,11 @@ struct meson_vclk_params {
                .vclk_div = 1,
        },
        [MESON_VCLK_HDMI_297000] = {
+               .pll_freq = 5940000,
+               .phy_freq = 2970000,
+               .venc_freq = 297000,
+               .vclk_freq = 297000,
                .pixel_freq = 297000,
-               .pll_base_freq = 5940000,
                .pll_od1 = 2,
                .pll_od2 = 1,
                .pll_od3 = 1,
@@ -421,14 +444,29 @@ struct meson_vclk_params {
                .vclk_div = 2,
        },
        [MESON_VCLK_HDMI_594000] = {
+               .pll_freq = 5940000,
+               .phy_freq = 5940000,
+               .venc_freq = 594000,
+               .vclk_freq = 594000,
                .pixel_freq = 594000,
-               .pll_base_freq = 5940000,
                .pll_od1 = 1,
                .pll_od2 = 1,
                .pll_od3 = 2,
                .vid_pll_div = VID_PLL_DIV_5,
                .vclk_div = 1,
        },
+       [MESON_VCLK_HDMI_594000_YUV420] = {
+               .pll_freq = 5940000,
+               .phy_freq = 2970000,
+               .venc_freq = 594000,
+               .vclk_freq = 594000,
+               .pixel_freq = 297000,
+               .pll_od1 = 2,
+               .pll_od2 = 1,
+               .pll_od3 = 1,
+               .vid_pll_div = VID_PLL_DIV_5,
+               .vclk_div = 1,
+       },
        { /* sentinel */ },
 };
 
@@ -701,6 +739,7 @@ static void meson_hdmi_pll_generic_set(struct meson_drm *priv,
        unsigned int od, m, frac, od1, od2, od3;
 
        if (meson_hdmi_pll_find_params(priv, pll_freq, &m, &frac, &od)) {
+               /* OD2 goes to the PHY, and needs to be *10, so keep OD3=1 */
                od3 = 1;
                if (od < 4) {
                        od1 = 2;
@@ -723,21 +762,28 @@ static void meson_hdmi_pll_generic_set(struct meson_drm *priv,
 }
 
 enum drm_mode_status
-meson_vclk_vic_supported_freq(unsigned int freq)
+meson_vclk_vic_supported_freq(unsigned int phy_freq,
+                             unsigned int vclk_freq)
 {
        int i;
 
-       DRM_DEBUG_DRIVER("freq = %d\n", freq);
+       DRM_DEBUG_DRIVER("phy_freq = %d vclk_freq = %d\n",
+                        phy_freq, vclk_freq);
 
        for (i = 0 ; params[i].pixel_freq ; ++i) {
                DRM_DEBUG_DRIVER("i = %d pixel_freq = %d alt = %d\n",
                                 i, params[i].pixel_freq,
                                 FREQ_1000_1001(params[i].pixel_freq));
+               DRM_DEBUG_DRIVER("i = %d phy_freq = %d alt = %d\n",
+                                i, params[i].phy_freq,
+                                FREQ_1000_1001(params[i].phy_freq/10)*10);
                /* Match strict frequency */
-               if (freq == params[i].pixel_freq)
+               if (phy_freq == params[i].phy_freq &&
+                   vclk_freq == params[i].vclk_freq)
                        return MODE_OK;
                /* Match 1000/1001 variant */
-               if (freq == FREQ_1000_1001(params[i].pixel_freq))
+               if (phy_freq == (FREQ_1000_1001(params[i].phy_freq/10)*10) &&
+                   vclk_freq == FREQ_1000_1001(params[i].vclk_freq))
                        return MODE_OK;
        }
 
@@ -965,8 +1011,9 @@ static void meson_vclk_set(struct meson_drm *priv, unsigned int pll_base_freq,
 }
 
 void meson_vclk_setup(struct meson_drm *priv, unsigned int target,
-                     unsigned int vclk_freq, unsigned int venc_freq,
-                     unsigned int dac_freq, bool hdmi_use_enci)
+                     unsigned int phy_freq, unsigned int vclk_freq,
+                     unsigned int venc_freq, unsigned int dac_freq,
+                     bool hdmi_use_enci)
 {
        bool vic_alternate_clock = false;
        unsigned int freq;
@@ -986,7 +1033,7 @@ void meson_vclk_setup(struct meson_drm *priv, unsigned int target,
                 * - venc_div = 1
                 * - encp encoder
                 */
-               meson_vclk_set(priv, vclk_freq * 10, 0, 0, 0,
+               meson_vclk_set(priv, phy_freq, 0, 0, 0,
                               VID_PLL_DIV_5, 2, 1, 1, false, false);
                return;
        }
@@ -1008,9 +1055,11 @@ void meson_vclk_setup(struct meson_drm *priv, unsigned int target,
        }
 
        for (freq = 0 ; params[freq].pixel_freq ; ++freq) {
-               if (vclk_freq == params[freq].pixel_freq ||
-                   vclk_freq == FREQ_1000_1001(params[freq].pixel_freq)) {
-                       if (vclk_freq != params[freq].pixel_freq)
+               if ((phy_freq == params[freq].phy_freq ||
+                    phy_freq == FREQ_1000_1001(params[freq].phy_freq/10)*10) &&
+                   (vclk_freq == params[freq].vclk_freq ||
+                    vclk_freq == FREQ_1000_1001(params[freq].vclk_freq))) {
+                       if (vclk_freq != params[freq].vclk_freq)
                                vic_alternate_clock = true;
                        else
                                vic_alternate_clock = false;
@@ -1039,7 +1088,7 @@ void meson_vclk_setup(struct meson_drm *priv, unsigned int target,
                return;
        }
 
-       meson_vclk_set(priv, params[freq].pll_base_freq,
+       meson_vclk_set(priv, params[freq].pll_freq,
                       params[freq].pll_od1, params[freq].pll_od2,
                       params[freq].pll_od3, params[freq].vid_pll_div,
                       params[freq].vclk_div, hdmi_tx_div, venc_div,
index b62125540aeffa300c0ce338c2075db6fe12d836..aed0ab2efa71dbf349cc1c365c27542666ecb754 100644 (file)
@@ -25,10 +25,11 @@ enum {
 enum drm_mode_status
 meson_vclk_dmt_supported_freq(struct meson_drm *priv, unsigned int freq);
 enum drm_mode_status
-meson_vclk_vic_supported_freq(unsigned int freq);
+meson_vclk_vic_supported_freq(unsigned int phy_freq, unsigned int vclk_freq);
 
 void meson_vclk_setup(struct meson_drm *priv, unsigned int target,
-                     unsigned int vclk_freq, unsigned int venc_freq,
-                     unsigned int dac_freq, bool hdmi_use_enci);
+                     unsigned int phy_freq, unsigned int vclk_freq,
+                     unsigned int venc_freq, unsigned int dac_freq,
+                     bool hdmi_use_enci);
 
 #endif /* __MESON_VCLK_H */
index 4efd7864d5bf328707de89250bf2966056fec8c1..f93c725b6f02d1abafa29db0c81d266126bd01bd 100644 (file)
@@ -946,7 +946,9 @@ bool meson_venc_hdmi_venc_repeat(int vic)
 EXPORT_SYMBOL_GPL(meson_venc_hdmi_venc_repeat);
 
 void meson_venc_hdmi_mode_set(struct meson_drm *priv, int vic,
-                             struct drm_display_mode *mode)
+                             unsigned int ycrcb_map,
+                             bool yuv420_mode,
+                             const struct drm_display_mode *mode)
 {
        union meson_hdmi_venc_mode *vmode = NULL;
        union meson_hdmi_venc_mode vmode_dmt;
@@ -1528,14 +1530,14 @@ void meson_venc_hdmi_mode_set(struct meson_drm *priv, int vic,
        if (mode->flags & DRM_MODE_FLAG_PVSYNC)
                reg |= VPU_HDMI_INV_VSYNC;
 
-       /* Output data format: CbYCr */
-       reg |= VPU_HDMI_OUTPUT_CBYCR;
+       /* Output data format */
+       reg |= ycrcb_map;
 
        /*
         * Write rate to the async FIFO between VENC and HDMI.
         * One write every 2 wr_clk.
         */
-       if (venc_repeat)
+       if (venc_repeat || yuv420_mode)
                reg |= VPU_HDMI_WR_RATE(2);
 
        /*
index 576768bdd08d4ee8f28c465bb3ee08c0de3e24ae..9138255ffc9eeec6aef59964bca8ddc2cc132374 100644 (file)
@@ -60,7 +60,9 @@ extern struct meson_cvbs_enci_mode meson_cvbs_enci_ntsc;
 void meson_venci_cvbs_mode_set(struct meson_drm *priv,
                               struct meson_cvbs_enci_mode *mode);
 void meson_venc_hdmi_mode_set(struct meson_drm *priv, int vic,
-                             struct drm_display_mode *mode);
+                             unsigned int ycrcb_map,
+                             bool yuv420_mode,
+                             const struct drm_display_mode *mode);
 unsigned int meson_venci_get_field(struct meson_drm *priv);
 
 void meson_venc_enable_vsync(struct meson_drm *priv);
index 1bd6b6d15ffb304d38c9cb3bfb718e2964e7a75f..541f9eb2a1352180a9709eddcddb240b84588225 100644 (file)
@@ -213,8 +213,10 @@ static void meson_venc_cvbs_encoder_mode_set(struct drm_encoder *encoder,
                meson_venci_cvbs_mode_set(priv, meson_mode->enci);
 
                /* Setup 27MHz vclk2 for ENCI and VDAC */
-               meson_vclk_setup(priv, MESON_VCLK_TARGET_CVBS, MESON_VCLK_CVBS,
-                                MESON_VCLK_CVBS, MESON_VCLK_CVBS, true);
+               meson_vclk_setup(priv, MESON_VCLK_TARGET_CVBS,
+                                MESON_VCLK_CVBS, MESON_VCLK_CVBS,
+                                MESON_VCLK_CVBS, MESON_VCLK_CVBS,
+                                true);
        }
 }
 
index 4e164ad8003fe23aa1b321210e3cf9b97be8b0b5..4d1c58468dbcaf71541b1bf04265659b6723a17b 100644 (file)
@@ -1256,23 +1256,6 @@ nv50_mstm_prepare(struct nv50_mstm *mstm)
        }
 }
 
-static void
-nv50_mstm_destroy_connector(struct drm_dp_mst_topology_mgr *mgr,
-                           struct drm_connector *connector)
-{
-       struct nv50_mstc *mstc = nv50_mstc(connector);
-
-       drm_connector_unregister(&mstc->connector);
-
-       drm_connector_put(&mstc->connector);
-}
-
-static void
-nv50_mstm_register_connector(struct drm_connector *connector)
-{
-       drm_connector_register(connector);
-}
-
 static struct drm_connector *
 nv50_mstm_add_connector(struct drm_dp_mst_topology_mgr *mgr,
                        struct drm_dp_mst_port *port, const char *path)
@@ -1291,8 +1274,6 @@ nv50_mstm_add_connector(struct drm_dp_mst_topology_mgr *mgr,
 static const struct drm_dp_mst_topology_cbs
 nv50_mstm = {
        .add_connector = nv50_mstm_add_connector,
-       .register_connector = nv50_mstm_register_connector,
-       .destroy_connector = nv50_mstm_destroy_connector,
 };
 
 void
index f394d53a7da4f6145e4cd6faf720eb1cc5287d83..09935520e606359a7ad0fe28e19dc065698e29a7 100644 (file)
@@ -540,7 +540,7 @@ static int ili9322_enable(struct drm_panel *panel)
 
 /* Serial RGB modes */
 static const struct drm_display_mode srgb_320x240_mode = {
-       .clock = 2453500,
+       .clock = 24535,
        .hdisplay = 320,
        .hsync_start = 320 + 359,
        .hsync_end = 320 + 359 + 1,
@@ -554,7 +554,7 @@ static const struct drm_display_mode srgb_320x240_mode = {
 };
 
 static const struct drm_display_mode srgb_360x240_mode = {
-       .clock = 2700000,
+       .clock = 27000,
        .hdisplay = 360,
        .hsync_start = 360 + 35,
        .hsync_end = 360 + 35 + 1,
@@ -569,7 +569,7 @@ static const struct drm_display_mode srgb_360x240_mode = {
 
 /* This is the only mode listed for parallel RGB in the datasheet */
 static const struct drm_display_mode prgb_320x240_mode = {
-       .clock = 6400000,
+       .clock = 64000,
        .hdisplay = 320,
        .hsync_start = 320 + 38,
        .hsync_end = 320 + 38 + 1,
@@ -584,7 +584,7 @@ static const struct drm_display_mode prgb_320x240_mode = {
 
 /* YUV modes */
 static const struct drm_display_mode yuv_640x320_mode = {
-       .clock = 2454000,
+       .clock = 24540,
        .hdisplay = 640,
        .hsync_start = 640 + 252,
        .hsync_end = 640 + 252 + 1,
@@ -598,7 +598,7 @@ static const struct drm_display_mode yuv_640x320_mode = {
 };
 
 static const struct drm_display_mode yuv_720x360_mode = {
-       .clock = 2700000,
+       .clock = 27000,
        .hdisplay = 720,
        .hsync_start = 720 + 252,
        .hsync_end = 720 + 252 + 1,
@@ -613,7 +613,7 @@ static const struct drm_display_mode yuv_720x360_mode = {
 
 /* BT.656 VGA mode, 640x480 */
 static const struct drm_display_mode itu_r_bt_656_640_mode = {
-       .clock = 2454000,
+       .clock = 24540,
        .hdisplay = 640,
        .hsync_start = 640 + 3,
        .hsync_end = 640 + 3 + 1,
@@ -628,7 +628,7 @@ static const struct drm_display_mode itu_r_bt_656_640_mode = {
 
 /* BT.656 D1 mode 720x480 */
 static const struct drm_display_mode itu_r_bt_656_720_mode = {
-       .clock = 2700000,
+       .clock = 27000,
        .hdisplay = 720,
        .hsync_start = 720 + 3,
        .hsync_end = 720 + 3 + 1,
index b262b53dbd859aa2c9dc20606cb9260ccc9a2d37..5907f2503755424a8d838c1c5f6a23dd1dea0665 100644 (file)
@@ -197,7 +197,7 @@ static int lg4573_enable(struct drm_panel *panel)
 }
 
 static const struct drm_display_mode default_mode = {
-       .clock = 27000,
+       .clock = 28341,
        .hdisplay = 480,
        .hsync_start = 480 + 10,
        .hsync_end = 480 + 10 + 59,
index b4c014126781d42b6b8930b321fb89f6e63a05e0..4a8fa908a2cf55ba04335c8a6d9dd2ad8c597b8d 100644 (file)
@@ -1019,7 +1019,7 @@ static const struct nt35510_config nt35510_hydis_hva40wv1 = {
         */
        .mode = {
                /* The internal pixel clock of the NT35510 is 20 MHz */
-               .clock = 20000000,
+               .clock = 20000,
                .hdisplay = 480,
                .hsync_start = 480 + 2, /* HFP = 2 */
                .hsync_end = 480 + 2 + 0, /* HSync = 0 */
index 7505b81ecb77f931e014a7c2835767405348aeee..0ce81b1f36afaa0f1280c52fd51ebad7631a006a 100644 (file)
@@ -2277,7 +2277,7 @@ static const struct drm_display_mode mitsubishi_aa070mc01_mode = {
 };
 
 static const struct drm_display_mode logicpd_type_28_mode = {
-       .clock = 9000,
+       .clock = 9107,
        .hdisplay = 480,
        .hsync_start = 480 + 3,
        .hsync_end = 480 + 3 + 42,
@@ -2617,15 +2617,15 @@ static const struct panel_desc ontat_yx700wv03 = {
 };
 
 static const struct drm_display_mode ortustech_com37h3m_mode  = {
-       .clock = 22153,
+       .clock = 22230,
        .hdisplay = 480,
-       .hsync_start = 480 + 8,
-       .hsync_end = 480 + 8 + 10,
-       .htotal = 480 + 8 + 10 + 10,
+       .hsync_start = 480 + 40,
+       .hsync_end = 480 + 40 + 10,
+       .htotal = 480 + 40 + 10 + 40,
        .vdisplay = 640,
        .vsync_start = 640 + 4,
-       .vsync_end = 640 + 4 + 3,
-       .vtotal = 640 + 4 + 3 + 4,
+       .vsync_end = 640 + 4 + 2,
+       .vtotal = 640 + 4 + 2 + 4,
        .vrefresh = 60,
        .flags = DRM_MODE_FLAG_NVSYNC | DRM_MODE_FLAG_NHSYNC,
 };
@@ -2666,6 +2666,7 @@ static const struct panel_desc ortustech_com43h4m85ulc = {
        },
        .bus_format = MEDIA_BUS_FMT_RGB888_1X24,
        .bus_flags = DRM_BUS_FLAG_DE_HIGH | DRM_BUS_FLAG_PIXDATA_DRIVE_POSEDGE,
+       .connector_type = DRM_MODE_CONNECTOR_DPI,
 };
 
 static const struct drm_display_mode osddisplays_osd070t1718_19ts_mode  = {
index de0abf76ae6fd7e86963647c8d20c5205e673483..c91e55b2d7a3b608ce205adc3288f7a8a3429be1 100644 (file)
@@ -48,7 +48,7 @@ struct acx424akp {
 };
 
 static const struct drm_display_mode sony_acx424akp_vid_mode = {
-       .clock = 330000,
+       .clock = 27234,
        .hdisplay = 480,
        .hsync_start = 480 + 15,
        .hsync_end = 480 + 15 + 0,
@@ -68,7 +68,7 @@ static const struct drm_display_mode sony_acx424akp_vid_mode = {
  * command mode using the maximum HS frequency.
  */
 static const struct drm_display_mode sony_acx424akp_cmd_mode = {
-       .clock = 420160,
+       .clock = 35478,
        .hdisplay = 480,
        .hsync_start = 480 + 154,
        .hsync_end = 480 + 154 + 16,
index 5a9fb0ad175a0552f22b77474278f1e00db82a90..008308780443c83bbaa9f51c5a1856c76d4ff213 100644 (file)
@@ -301,25 +301,8 @@ static struct drm_connector *radeon_dp_add_mst_connector(struct drm_dp_mst_topol
        return connector;
 }
 
-static void radeon_dp_register_mst_connector(struct drm_connector *connector)
-{
-       drm_connector_register(connector);
-}
-
-static void radeon_dp_destroy_mst_connector(struct drm_dp_mst_topology_mgr *mgr,
-                                           struct drm_connector *connector)
-{
-       drm_connector_unregister(connector);
-       drm_connector_cleanup(connector);
-
-       kfree(connector);
-       DRM_DEBUG_KMS("\n");
-}
-
 static const struct drm_dp_mst_topology_cbs mst_cbs = {
        .add_connector = radeon_dp_add_mst_connector,
-       .register_connector = radeon_dp_register_mst_connector,
-       .destroy_connector = radeon_dp_destroy_mst_connector,
 };
 
 static struct
index 3e2484985955356b73d73cb454d7568fe81e7bb0..90784781e51596499677e95821c4c1a5e181b92d 100644 (file)
@@ -98,7 +98,8 @@ struct rockchip_rgb *rockchip_rgb_init(struct device *dev,
                if (of_property_read_u32(endpoint, "reg", &endpoint_id))
                        endpoint_id = 0;
 
-               if (rockchip_drm_endpoint_is_subdriver(endpoint) > 0)
+               /* if subdriver (> 0) or error case (< 0), ignore entry */
+               if (rockchip_drm_endpoint_is_subdriver(endpoint) != 0)
                        continue;
 
                child_count++;
index 5084b38c1a7166d6ea47dd7d0271365dfe65cd36..532560aebb1e0fa2f08ec33e5f500588f054facf 100644 (file)
@@ -45,7 +45,7 @@ static int waveshare_command(struct mipi_dbi *mipi, u8 *cmd, u8 *par,
        void *data = par;
        u32 speed_hz;
        int i, ret;
-       u16 *buf;
+       __be16 *buf;
 
        buf = kmalloc(32 * sizeof(u16), GFP_KERNEL);
        if (!buf)
index 6d1e91be9c7884d6d302621bfc8b226c94fee89e..9e07c3f75156ba1d7a48bccea82528eca1c7359b 100644 (file)
@@ -151,8 +151,6 @@ static void ttm_bo_add_mem_to_lru(struct ttm_buffer_object *bo,
        struct ttm_bo_device *bdev = bo->bdev;
        struct ttm_mem_type_manager *man;
 
-       dma_resv_assert_held(bo->base.resv);
-
        if (!list_empty(&bo->lru))
                return;
 
@@ -604,7 +602,8 @@ static void ttm_bo_release(struct kref *kref)
                 */
                if (bo->mem.placement & TTM_PL_FLAG_NO_EVICT) {
                        bo->mem.placement &= ~TTM_PL_FLAG_NO_EVICT;
-                       ttm_bo_move_to_lru_tail(bo, NULL);
+                       ttm_bo_del_from_lru(bo);
+                       ttm_bo_add_mem_to_lru(bo, &bo->mem);
                }
 
                kref_init(&bo->kref);
index bf876faea5921f9bed2358d736d7983a3d3270ba..faefaaef79099d48d7a2b775eab08b9db70aee50 100644 (file)
@@ -604,7 +604,7 @@ static struct dma_pool *ttm_dma_pool_init(struct device *dev, gfp_t flags,
        p = pool->name;
        for (i = 0; i < ARRAY_SIZE(t); i++) {
                if (type & t[i]) {
-                       p += snprintf(p, sizeof(pool->name) - (p - pool->name),
+                       p += scnprintf(p, sizeof(pool->name) - (p - pool->name),
                                      "%s", n[i]);
                }
        }
index 9d4d5cc47969761b1c469e5b92dca0ff57052b80..0b34a12c4a1c7366f3417917c0eab33d7f0f9684 100644 (file)
@@ -129,6 +129,7 @@ struct dw_hdmi_plat_data {
        unsigned long input_bus_format;
        unsigned long input_bus_encoding;
        bool use_drm_infoframe;
+       bool ycbcr_420_allowed;
 
        /* Vendor PHY support */
        const struct dw_hdmi_phy_ops *phy_ops;
index 0df7a95ca5d96fc34f0c61a40ad61f345f7417c0..19ae6bb5c85be15d15b7589bf17591332bc0e653 100644 (file)
@@ -254,6 +254,23 @@ enum drm_panel_orientation {
        DRM_MODE_PANEL_ORIENTATION_RIGHT_UP,
 };
 
+/**
+ * struct drm_monitor_range_info - Panel's Monitor range in EDID for
+ * &drm_display_info
+ *
+ * This struct is used to store a frequency range supported by panel
+ * as parsed from EDID's detailed monitor range descriptor block.
+ *
+ * @min_vfreq: This is the min supported refresh rate in Hz from
+ *             EDID's detailed monitor range.
+ * @max_vfreq: This is the max supported refresh rate in Hz from
+ *             EDID's detailed monitor range
+ */
+struct drm_monitor_range_info {
+       u8 min_vfreq;
+       u8 max_vfreq;
+};
+
 /*
  * This is a consolidated colorimetry list supported by HDMI and
  * DP protocol standard. The respective connectors will register
@@ -473,6 +490,11 @@ struct drm_display_info {
         * @non_desktop: Non desktop display (HMD).
         */
        bool non_desktop;
+
+       /**
+        * @monitor_range: Frequency range supported by monitor range descriptor
+        */
+       struct drm_monitor_range_info monitor_range;
 };
 
 int drm_display_info_set_bus_formats(struct drm_display_info *info,
index 5483f888712ad3b19ecb81bcda681025af0e14cc..9a1e8ba4f83966c0abeab9066f4b4ffaaf6b0ae5 100644 (file)
@@ -479,7 +479,6 @@ struct drm_dp_mst_topology_mgr;
 struct drm_dp_mst_topology_cbs {
        /* create a connector for a port */
        struct drm_connector *(*add_connector)(struct drm_dp_mst_topology_mgr *mgr, struct drm_dp_mst_port *port, const char *path);
-       void (*register_connector)(struct drm_connector *connector);
        void (*destroy_connector)(struct drm_dp_mst_topology_mgr *mgr,
                                  struct drm_connector *connector);
 };
@@ -590,6 +589,11 @@ struct drm_dp_mst_topology_mgr {
         */
        bool payload_id_table_cleared : 1;
 
+       /**
+        * @is_waiting_for_dwn_reply: whether we're waiting for a down reply.
+        */
+       bool is_waiting_for_dwn_reply : 1;
+
        /**
         * @mst_primary: Pointer to the primary/first branch device.
         */
@@ -619,11 +623,6 @@ struct drm_dp_mst_topology_mgr {
         */
        struct mutex qlock;
 
-       /**
-        * @is_waiting_for_dwn_reply: indicate whether is waiting for down reply
-        */
-       bool is_waiting_for_dwn_reply;
-
        /**
         * @tx_msg_downq: List of pending down replies.
         */
index f0b03d401c278f00e43e40f67a3ae2356661d2d8..34b15e3d070c62cb496efb5d55359bfb7fde75be 100644 (file)
@@ -91,6 +91,11 @@ struct detailed_data_string {
        u8 str[13];
 } __attribute__((packed));
 
+#define DRM_EDID_DEFAULT_GTF_SUPPORT_FLAG   0x00
+#define DRM_EDID_RANGE_LIMITS_ONLY_FLAG     0x01
+#define DRM_EDID_SECONDARY_GTF_SUPPORT_FLAG 0x02
+#define DRM_EDID_CVT_SUPPORT_FLAG           0x04
+
 struct detailed_data_monitor_range {
        u8 min_vfreq;
        u8 max_vfreq;
index d7939c0542599bc42711fa6773f450189e83aa7f..ee8b0e80ca90b72d34e10dffc50b5562a52144ae 100644 (file)
@@ -272,7 +272,7 @@ static inline bool drm_mm_node_allocated(const struct drm_mm_node *node)
  */
 static inline bool drm_mm_initialized(const struct drm_mm *mm)
 {
-       return mm->hole_stack.next;
+       return READ_ONCE(mm->hole_stack.next);
 }
 
 /**