drm/connector: Allow max possible encoders to attach to a connector
[sfrench/cifs-2.6.git] / include / drm / drm_connector.h
index 02a131202adde10648228c080b261c0dcb799a10..c6e993e78dbd14d924f2e2e7de5fd2daa9d9e93e 100644 (file)
@@ -41,6 +41,7 @@ struct drm_property;
 struct drm_property_blob;
 struct drm_printer;
 struct edid;
+struct i2c_adapter;
 
 enum drm_connector_force {
        DRM_FORCE_UNSPECIFIED,
@@ -323,6 +324,8 @@ enum drm_panel_orientation {
  *                                     edge of the pixel clock
  * @DRM_BUS_FLAG_SYNC_SAMPLE_NEGEDGE:  Sync signals are sampled on the falling
  *                                     edge of the pixel clock
+ * @DRM_BUS_FLAG_SHARP_SIGNALS:                Set if the Sharp-specific signals
+ *                                     (SPL, CLS, PS, REV) must be used
  */
 enum drm_bus_flags {
        DRM_BUS_FLAG_DE_LOW = BIT(0),
@@ -341,6 +344,7 @@ enum drm_bus_flags {
        DRM_BUS_FLAG_SYNC_DRIVE_NEGEDGE = DRM_BUS_FLAG_SYNC_NEGEDGE,
        DRM_BUS_FLAG_SYNC_SAMPLE_POSEDGE = DRM_BUS_FLAG_SYNC_NEGEDGE,
        DRM_BUS_FLAG_SYNC_SAMPLE_NEGEDGE = DRM_BUS_FLAG_SYNC_POSEDGE,
+       DRM_BUS_FLAG_SHARP_SIGNALS = BIT(8),
 };
 
 /**
@@ -463,14 +467,38 @@ int drm_display_info_set_bus_formats(struct drm_display_info *info,
                                     const u32 *formats,
                                     unsigned int num_formats);
 
+/**
+ * struct drm_connector_tv_margins - TV connector related margins
+ *
+ * Describes the margins in pixels to put around the image on TV
+ * connectors to deal with overscan.
+ */
+struct drm_connector_tv_margins {
+       /**
+        * @bottom: Bottom margin in pixels.
+        */
+       unsigned int bottom;
+
+       /**
+        * @left: Left margin in pixels.
+        */
+       unsigned int left;
+
+       /**
+        * @right: Right margin in pixels.
+        */
+       unsigned int right;
+
+       /**
+        * @top: Top margin in pixels.
+        */
+       unsigned int top;
+};
+
 /**
  * struct drm_tv_connector_state - TV connector related states
  * @subconnector: selected subconnector
- * @margins: margins (all margins are expressed in pixels)
- * @margins.left: left margin
- * @margins.right: right margin
- * @margins.top: top margin
- * @margins.bottom: bottom margin
+ * @margins: TV margins
  * @mode: TV mode
  * @brightness: brightness in percent
  * @contrast: contrast in percent
@@ -481,12 +509,7 @@ int drm_display_info_set_bus_formats(struct drm_display_info *info,
  */
 struct drm_tv_connector_state {
        enum drm_mode_subconnector subconnector;
-       struct {
-               unsigned int left;
-               unsigned int right;
-               unsigned int top;
-               unsigned int bottom;
-       } margins;
+       struct drm_connector_tv_margins margins;
        unsigned int mode;
        unsigned int brightness;
        unsigned int contrast;
@@ -517,6 +540,15 @@ struct drm_connector_state {
         * Used by the atomic helpers to select the encoder, through the
         * &drm_connector_helper_funcs.atomic_best_encoder or
         * &drm_connector_helper_funcs.best_encoder callbacks.
+        *
+        * This is also used in the atomic helpers to map encoders to their
+        * current and previous connectors, see
+        * drm_atomic_get_old_connector_for_encoder() and
+        * drm_atomic_get_new_connector_for_encoder().
+        *
+        * NOTE: Atomic drivers must fill this out (either themselves or through
+        * helpers), for otherwise the GETCONNECTOR and GETENCODER IOCTLs will
+        * not return correct data to userspace.
         */
        struct drm_encoder *best_encoder;
 
@@ -539,6 +571,20 @@ struct drm_connector_state {
        /** @tv: TV connector state */
        struct drm_tv_connector_state tv;
 
+       /**
+        * @self_refresh_aware:
+        *
+        * This tracks whether a connector is aware of the self refresh state.
+        * It should be set to true for those connector implementations which
+        * understand the self refresh state. This is needed since the crtc
+        * registers the self refresh helpers and it doesn't know if the
+        * connectors downstream have implemented self refresh entry/exit.
+        *
+        * Drivers should set this to true in atomic_check if they know how to
+        * handle self_refresh requests.
+        */
+       bool self_refresh_aware;
+
        /**
         * @picture_aspect_ratio: Connector property to control the
         * HDMI infoframe aspect ratio setting.
@@ -556,6 +602,12 @@ struct drm_connector_state {
         */
        unsigned int content_type;
 
+       /**
+        * @hdcp_content_type: Connector property to pass the type of
+        * protected content. This is most commonly used for HDCP.
+        */
+       unsigned int hdcp_content_type;
+
        /**
         * @scaling_mode: Connector property to control the
         * upscaling, mostly used for built-in panels.
@@ -599,6 +651,12 @@ struct drm_connector_state {
         * and the connector bpc limitations obtained from edid.
         */
        u8 max_bpc;
+
+       /**
+        * @hdr_output_metadata:
+        * DRM blob property for HDR output metadata
+        */
+       struct drm_property_blob *hdr_output_metadata;
 };
 
 /**
@@ -894,19 +952,123 @@ struct drm_connector_funcs {
                                   const struct drm_connector_state *state);
 };
 
-/* mode specified on the command line */
+/**
+ * struct drm_cmdline_mode - DRM Mode passed through the kernel command-line
+ *
+ * Each connector can have an initial mode with additional options
+ * passed through the kernel command line. This structure allows to
+ * express those parameters and will be filled by the command-line
+ * parser.
+ */
 struct drm_cmdline_mode {
+       /**
+        * @name:
+        *
+        * Name of the mode.
+        */
+       char name[DRM_DISPLAY_MODE_LEN];
+
+       /**
+        * @specified:
+        *
+        * Has a mode been read from the command-line?
+        */
        bool specified;
+
+       /**
+        * @refresh_specified:
+        *
+        * Did the mode have a preferred refresh rate?
+        */
        bool refresh_specified;
+
+       /**
+        * @bpp_specified:
+        *
+        * Did the mode have a preferred BPP?
+        */
        bool bpp_specified;
-       int xres, yres;
+
+       /**
+        * @xres:
+        *
+        * Active resolution on the X axis, in pixels.
+        */
+       int xres;
+
+       /**
+        * @yres:
+        *
+        * Active resolution on the Y axis, in pixels.
+        */
+       int yres;
+
+       /**
+        * @bpp:
+        *
+        * Bits per pixels for the mode.
+        */
        int bpp;
+
+       /**
+        * @refresh:
+        *
+        * Refresh rate, in Hertz.
+        */
        int refresh;
+
+       /**
+        * @rb:
+        *
+        * Do we need to use reduced blanking?
+        */
        bool rb;
+
+       /**
+        * @interlace:
+        *
+        * The mode is interlaced.
+        */
        bool interlace;
+
+       /**
+        * @cvt:
+        *
+        * The timings will be calculated using the VESA Coordinated
+        * Video Timings instead of looking up the mode from a table.
+        */
        bool cvt;
+
+       /**
+        * @margins:
+        *
+        * Add margins to the mode calculation (1.8% of xres rounded
+        * down to 8 pixels and 1.8% of yres).
+        */
        bool margins;
+
+       /**
+        * @force:
+        *
+        * Ignore the hotplug state of the connector, and force its
+        * state to one of the DRM_FORCE_* values.
+        */
        enum drm_connector_force force;
+
+       /**
+        * @rotation_reflection:
+        *
+        * Initial rotation and reflection of the mode setup from the
+        * command line. See DRM_MODE_ROTATE_* and
+        * DRM_MODE_REFLECT_*. The only rotations supported are
+        * DRM_MODE_ROTATE_0 and DRM_MODE_ROTATE_180.
+        */
+       unsigned int rotation_reflection;
+
+       /**
+        * @tv_margins: TV margins to apply to the mode.
+        */
+       struct drm_connector_tv_margins tv_margins;
 };
 
 /**
@@ -1061,12 +1223,6 @@ struct drm_connector {
         */
        struct drm_property *vrr_capable_property;
 
-       /**
-        * @content_protection_property: DRM ENUM property for content
-        * protection. See drm_connector_attach_content_protection_property().
-        */
-       struct drm_property *content_protection_property;
-
        /**
         * @colorspace_property: Connector property to set the suitable
         * colorspace supported by the sink.
@@ -1132,12 +1288,12 @@ struct drm_connector {
        /** @override_edid: has the EDID been overwritten through debugfs for testing? */
        bool override_edid;
 
-#define DRM_CONNECTOR_MAX_ENCODER 3
        /**
-        * @encoder_ids: Valid encoders for this connector. Please only use
-        * drm_connector_for_each_possible_encoder() to enumerate these.
+        * @possible_encoders: Bit mask of encoders that can drive this
+        * connector, drm_encoder_index() determines the index into the bitfield
+        * and the bits are set with drm_connector_attach_encoder().
         */
-       uint32_t encoder_ids[DRM_CONNECTOR_MAX_ENCODER];
+       u32 possible_encoders;
 
        /**
         * @encoder: Currently bound encoder driving this connector, if any.
@@ -1162,6 +1318,18 @@ struct drm_connector {
         * [0]: progressive, [1]: interlaced
         */
        int audio_latency[2];
+
+       /**
+        * @ddc: associated ddc adapter.
+        * A connector usually has its associated ddc adapter. If a driver uses
+        * this field, then an appropriate symbolic link is created in connector
+        * sysfs directory to make it easy for the user to tell which i2c
+        * adapter is for a particular display.
+        *
+        * The field should be set by calling drm_connector_init_with_ddc().
+        */
+       struct i2c_adapter *ddc;
+
        /**
         * @null_edid_counter: track sinks that give us all zeros for the EDID.
         * Needed to workaround some HW bugs where we get all 0s
@@ -1239,6 +1407,9 @@ struct drm_connector {
         * &drm_mode_config.connector_free_work.
         */
        struct llist_node free_node;
+
+       /** @hdr_sink_metadata: HDR Metadata Information read from sink */
+       struct hdr_sink_metadata hdr_sink_metadata;
 };
 
 #define obj_to_connector(x) container_of(x, struct drm_connector, base)
@@ -1247,6 +1418,11 @@ int drm_connector_init(struct drm_device *dev,
                       struct drm_connector *connector,
                       const struct drm_connector_funcs *funcs,
                       int connector_type);
+int drm_connector_init_with_ddc(struct drm_device *dev,
+                               struct drm_connector *connector,
+                               const struct drm_connector_funcs *funcs,
+                               int connector_type,
+                               struct i2c_adapter *ddc);
 void drm_connector_attach_edid_property(struct drm_connector *connector);
 int drm_connector_register(struct drm_connector *connector);
 void drm_connector_unregister(struct drm_connector *connector);
@@ -1332,6 +1508,7 @@ const char *drm_get_dvi_i_select_name(int val);
 const char *drm_get_tv_subconnector_name(int val);
 const char *drm_get_tv_select_name(int val);
 const char *drm_get_content_protection_name(int val);
+const char *drm_get_hdcp_content_type_name(int val);
 
 int drm_mode_create_dvi_i_properties(struct drm_device *dev);
 int drm_mode_create_tv_margin_properties(struct drm_device *dev);
@@ -1345,8 +1522,6 @@ int drm_connector_attach_scaling_mode_property(struct drm_connector *connector,
                                               u32 scaling_mode_mask);
 int drm_connector_attach_vrr_capable_property(
                struct drm_connector *connector);
-int drm_connector_attach_content_protection_property(
-               struct drm_connector *connector);
 int drm_mode_create_aspect_ratio_property(struct drm_device *dev);
 int drm_mode_create_colorspace_property(struct drm_connector *connector);
 int drm_mode_create_content_type_property(struct drm_device *dev);
@@ -1433,13 +1608,9 @@ bool drm_connector_has_possible_encoder(struct drm_connector *connector,
  * drm_connector_for_each_possible_encoder - iterate connector's possible encoders
  * @connector: &struct drm_connector pointer
  * @encoder: &struct drm_encoder pointer used as cursor
- * @__i: int iteration cursor, for macro-internal use
  */
-#define drm_connector_for_each_possible_encoder(connector, encoder, __i) \
-       for ((__i) = 0; (__i) < ARRAY_SIZE((connector)->encoder_ids) && \
-                    (connector)->encoder_ids[(__i)] != 0; (__i)++) \
-               for_each_if((encoder) = \
-                           drm_encoder_find((connector)->dev, NULL, \
-                                            (connector)->encoder_ids[(__i)])) \
+#define drm_connector_for_each_possible_encoder(connector, encoder) \
+       drm_for_each_encoder_mask(encoder, (connector)->dev, \
+                                 (connector)->possible_encoders)
 
 #endif