summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/nouveau/nouveau_connector.h
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/nouveau/nouveau_connector.h')
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_connector.h208
1 files changed, 154 insertions, 54 deletions
diff --git a/drivers/gpu/drm/nouveau/nouveau_connector.h b/drivers/gpu/drm/nouveau/nouveau_connector.h
index a4d1a059bd3d..0608cabed058 100644
--- a/drivers/gpu/drm/nouveau/nouveau_connector.h
+++ b/drivers/gpu/drm/nouveau/nouveau_connector.h
@@ -26,64 +26,36 @@
#ifndef __NOUVEAU_CONNECTOR_H__
#define __NOUVEAU_CONNECTOR_H__
+#include <nvif/conn.h>
+#include <nvif/event.h>
-#include <nvif/notify.h>
+#include <nvhw/class/cl507d.h>
+#include <nvhw/class/cl907d.h>
+#include <nvhw/drf.h>
-#include <drm/drm_edid.h>
+#include <drm/display/drm_dp_helper.h>
+#include <drm/drm_crtc.h>
#include <drm/drm_encoder.h>
-#include <drm/drm_dp_helper.h>
+#include <drm/drm_util.h>
+
#include "nouveau_crtc.h"
+#include "nouveau_encoder.h"
struct nvkm_i2c_port;
+struct dcb_output;
+struct edid;
-struct nouveau_connector {
- struct drm_connector base;
- enum dcb_connector_type type;
- u8 index;
- u8 *dcb;
-
- struct nvif_notify hpd;
-
- struct drm_dp_aux aux;
+#ifdef CONFIG_DRM_NOUVEAU_BACKLIGHT
+struct nouveau_backlight {
+ struct backlight_device *dev;
- int dithering_mode;
- int scaling_mode;
+ struct drm_edp_backlight_info edp_info;
+ bool uses_dpcd : 1;
- struct nouveau_encoder *detected_encoder;
- struct edid *edid;
- struct drm_display_mode *native_mode;
+ int id;
};
+#endif
-static inline struct nouveau_connector *nouveau_connector(
- struct drm_connector *con)
-{
- return container_of(con, struct nouveau_connector, base);
-}
-
-static inline struct nouveau_connector *
-nouveau_crtc_connector_get(struct nouveau_crtc *nv_crtc)
-{
- struct drm_device *dev = nv_crtc->base.dev;
- struct drm_connector *connector;
- struct drm_crtc *crtc = to_drm_crtc(nv_crtc);
-
- list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
- if (connector->encoder && connector->encoder->crtc == crtc)
- return nouveau_connector(connector);
- }
-
- return NULL;
-}
-
-struct drm_connector *
-nouveau_connector_create(struct drm_device *, int index);
-
-extern int nouveau_tv_disable;
-extern int nouveau_ignorelid;
-extern int nouveau_duallink;
-extern int nouveau_hdmimhz;
-
-#include <drm/drm_crtc.h>
#define nouveau_conn_atom(p) \
container_of((p), struct nouveau_conn_atom, state)
@@ -95,16 +67,23 @@ struct nouveau_conn_atom {
* hw values, and the code relies on this.
*/
enum {
- DITHERING_MODE_OFF = 0x00,
- DITHERING_MODE_ON = 0x01,
- DITHERING_MODE_DYNAMIC2X2 = 0x10 | DITHERING_MODE_ON,
- DITHERING_MODE_STATIC2X2 = 0x18 | DITHERING_MODE_ON,
- DITHERING_MODE_TEMPORAL = 0x20 | DITHERING_MODE_ON,
+ DITHERING_MODE_OFF =
+ NVDEF(NV507D, HEAD_SET_DITHER_CONTROL, ENABLE, DISABLE),
+ DITHERING_MODE_ON =
+ NVDEF(NV507D, HEAD_SET_DITHER_CONTROL, ENABLE, ENABLE),
+ DITHERING_MODE_DYNAMIC2X2 = DITHERING_MODE_ON |
+ NVDEF(NV507D, HEAD_SET_DITHER_CONTROL, MODE, DYNAMIC_2X2),
+ DITHERING_MODE_STATIC2X2 = DITHERING_MODE_ON |
+ NVDEF(NV507D, HEAD_SET_DITHER_CONTROL, MODE, STATIC_2X2),
+ DITHERING_MODE_TEMPORAL = DITHERING_MODE_ON |
+ NVDEF(NV907D, HEAD_SET_DITHER_CONTROL, MODE, TEMPORAL),
DITHERING_MODE_AUTO
} mode;
enum {
- DITHERING_DEPTH_6BPC = 0x00,
- DITHERING_DEPTH_8BPC = 0x02,
+ DITHERING_DEPTH_6BPC =
+ NVDEF(NV507D, HEAD_SET_DITHER_CONTROL, BITS, DITHER_TO_6_BITS),
+ DITHERING_DEPTH_8BPC =
+ NVDEF(NV507D, HEAD_SET_DITHER_CONTROL, BITS, DITHER_TO_8_BITS),
DITHERING_DEPTH_AUTO
} depth;
} dither;
@@ -138,6 +117,96 @@ struct nouveau_conn_atom {
} set;
};
+struct nouveau_connector {
+ struct drm_connector base;
+ enum dcb_connector_type type;
+ u8 index;
+
+ struct nvif_conn conn;
+ u64 hpd_pending;
+ struct nvif_event hpd;
+ struct nvif_event irq;
+ struct work_struct irq_work;
+
+ struct drm_dp_aux aux;
+
+ /* The fixed DP encoder for this connector, if there is one */
+ struct nouveau_encoder *dp_encoder;
+
+ int dithering_mode;
+ int scaling_mode;
+
+ struct nouveau_encoder *detected_encoder;
+ struct edid *edid;
+ struct drm_display_mode *native_mode;
+#ifdef CONFIG_DRM_NOUVEAU_BACKLIGHT
+ struct nouveau_backlight *backlight;
+#endif
+ /*
+ * Our connector property code expects a nouveau_conn_atom struct
+ * even on pre-nv50 where we do not support atomic. This embedded
+ * version gets used in the non atomic modeset case.
+ */
+ struct nouveau_conn_atom properties_state;
+};
+
+static inline struct nouveau_connector *nouveau_connector(
+ struct drm_connector *con)
+{
+ return container_of(con, struct nouveau_connector, base);
+}
+
+static inline bool
+nouveau_connector_is_mst(struct drm_connector *connector)
+{
+ const struct nouveau_encoder *nv_encoder;
+ const struct drm_encoder *encoder;
+
+ if (connector->connector_type != DRM_MODE_CONNECTOR_DisplayPort)
+ return false;
+
+ nv_encoder = find_encoder(connector, DCB_OUTPUT_ANY);
+ if (!nv_encoder)
+ return false;
+
+ encoder = &nv_encoder->base.base;
+ return encoder->encoder_type == DRM_MODE_ENCODER_DPMST;
+}
+
+#define nouveau_for_each_non_mst_connector_iter(connector, iter) \
+ drm_for_each_connector_iter(connector, iter) \
+ for_each_if(!nouveau_connector_is_mst(connector))
+
+static inline struct nouveau_connector *
+nouveau_crtc_connector_get(struct nouveau_crtc *nv_crtc)
+{
+ struct drm_device *dev = nv_crtc->base.dev;
+ struct drm_connector *connector;
+ struct drm_connector_list_iter conn_iter;
+ struct nouveau_connector *nv_connector = NULL;
+ struct drm_crtc *crtc = to_drm_crtc(nv_crtc);
+
+ drm_connector_list_iter_begin(dev, &conn_iter);
+ nouveau_for_each_non_mst_connector_iter(connector, &conn_iter) {
+ if (connector->encoder && connector->encoder->crtc == crtc) {
+ nv_connector = nouveau_connector(connector);
+ break;
+ }
+ }
+ drm_connector_list_iter_end(&conn_iter);
+
+ return nv_connector;
+}
+
+struct drm_connector *
+nouveau_connector_create(struct drm_device *, int id);
+void nouveau_connector_hpd(struct nouveau_connector *, u64 bits);
+
+extern int nouveau_tv_disable;
+extern int nouveau_ignorelid;
+extern int nouveau_duallink;
+extern int nouveau_hdmimhz;
+
void nouveau_conn_attach_properties(struct drm_connector *);
void nouveau_conn_reset(struct drm_connector *);
struct drm_connector_state *
@@ -151,4 +220,35 @@ int nouveau_conn_atomic_get_property(struct drm_connector *,
const struct drm_connector_state *,
struct drm_property *, u64 *);
struct drm_display_mode *nouveau_conn_native_mode(struct drm_connector *);
+enum drm_mode_status
+nouveau_conn_mode_clock_valid(const struct drm_display_mode *,
+ const unsigned min_clock,
+ const unsigned max_clock,
+ unsigned *clock);
+
+#ifdef CONFIG_DRM_NOUVEAU_BACKLIGHT
+extern int nouveau_backlight_init(struct drm_connector *);
+extern void nouveau_backlight_fini(struct drm_connector *);
+extern void nouveau_backlight_ctor(void);
+extern void nouveau_backlight_dtor(void);
+#else
+static inline int
+nouveau_backlight_init(struct drm_connector *connector)
+{
+ return 0;
+}
+
+static inline void
+nouveau_backlight_fini(struct drm_connector *connector) {
+}
+
+static inline void
+nouveau_backlight_ctor(void) {
+}
+
+static inline void
+nouveau_backlight_dtor(void) {
+}
+#endif
+
#endif /* __NOUVEAU_CONNECTOR_H__ */