Back to home page

OSCL-LXR

 
 

    


0001 /*
0002  * Copyright (C) 2008 Maarten Maathuis.
0003  * All Rights Reserved.
0004  *
0005  * Permission is hereby granted, free of charge, to any person obtaining
0006  * a copy of this software and associated documentation files (the
0007  * "Software"), to deal in the Software without restriction, including
0008  * without limitation the rights to use, copy, modify, merge, publish,
0009  * distribute, sublicense, and/or sell copies of the Software, and to
0010  * permit persons to whom the Software is furnished to do so, subject to
0011  * the following conditions:
0012  *
0013  * The above copyright notice and this permission notice (including the
0014  * next paragraph) shall be included in all copies or substantial
0015  * portions of the Software.
0016  *
0017  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
0018  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
0019  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
0020  * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
0021  * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
0022  * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
0023  * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
0024  *
0025  */
0026 
0027 #ifndef __NOUVEAU_ENCODER_H__
0028 #define __NOUVEAU_ENCODER_H__
0029 #include <nvif/outp.h>
0030 #include <subdev/bios/dcb.h>
0031 
0032 #include <drm/display/drm_dp_helper.h>
0033 #include <drm/display/drm_dp_mst_helper.h>
0034 #include <drm/drm_encoder_slave.h>
0035 
0036 #include "dispnv04/disp.h"
0037 
0038 struct nv50_head_atom;
0039 struct nouveau_connector;
0040 
0041 #define NV_DPMS_CLEARED 0x80
0042 
0043 struct nvkm_i2c_port;
0044 
0045 struct nouveau_encoder {
0046     struct drm_encoder_slave base;
0047 
0048     struct dcb_output *dcb;
0049     struct nvif_outp outp;
0050     int or;
0051     int link;
0052 
0053     struct i2c_adapter *i2c;
0054     struct nvkm_i2c_aux *aux;
0055 
0056     /* different to drm_encoder.crtc, this reflects what's
0057      * actually programmed on the hw, not the proposed crtc */
0058     struct drm_crtc *crtc;
0059     u32 ctrl;
0060 
0061     /* Protected by nouveau_drm.audio.lock */
0062     struct {
0063         bool enabled;
0064         struct drm_connector *connector;
0065     } audio;
0066 
0067     struct drm_display_mode mode;
0068     int last_dpms;
0069 
0070     struct nv04_output_reg restore;
0071 
0072     union {
0073         struct {
0074             struct nv50_mstm *mstm;
0075             int link_nr;
0076             int link_bw;
0077 
0078             /* Protects DP state that needs to be accessed outside
0079              * connector reprobing contexts
0080              */
0081             struct mutex hpd_irq_lock;
0082 
0083             u8 dpcd[DP_RECEIVER_CAP_SIZE];
0084             u8 downstream_ports[DP_MAX_DOWNSTREAM_PORTS];
0085             struct drm_dp_desc desc;
0086 
0087             u8 sink_count;
0088         } dp;
0089     };
0090 
0091     struct {
0092         bool dp_interlace : 1;
0093     } caps;
0094 
0095     void (*enc_save)(struct drm_encoder *encoder);
0096     void (*enc_restore)(struct drm_encoder *encoder);
0097     void (*update)(struct nouveau_encoder *, u8 head,
0098                struct nv50_head_atom *, u8 proto, u8 depth);
0099 };
0100 
0101 struct nv50_mstm {
0102     struct nouveau_encoder *outp;
0103 
0104     struct drm_dp_mst_topology_mgr mgr;
0105 
0106     /* Protected under nouveau_encoder->dp.hpd_irq_lock */
0107     bool can_mst;
0108     bool is_mst;
0109     bool suspended;
0110 
0111     bool modified;
0112     bool disabled;
0113     int links;
0114 };
0115 
0116 struct nouveau_encoder *
0117 find_encoder(struct drm_connector *connector, int type);
0118 
0119 static inline struct nouveau_encoder *nouveau_encoder(struct drm_encoder *enc)
0120 {
0121     struct drm_encoder_slave *slave = to_encoder_slave(enc);
0122 
0123     return container_of(slave, struct nouveau_encoder, base);
0124 }
0125 
0126 static inline struct drm_encoder *to_drm_encoder(struct nouveau_encoder *enc)
0127 {
0128     return &enc->base.base;
0129 }
0130 
0131 static inline const struct drm_encoder_slave_funcs *
0132 get_slave_funcs(struct drm_encoder *enc)
0133 {
0134     return to_encoder_slave(enc)->slave_funcs;
0135 }
0136 
0137 /* nouveau_dp.c */
0138 enum nouveau_dp_status {
0139     NOUVEAU_DP_NONE,
0140     NOUVEAU_DP_SST,
0141     NOUVEAU_DP_MST,
0142 };
0143 
0144 int nouveau_dp_detect(struct nouveau_connector *, struct nouveau_encoder *);
0145 void nouveau_dp_irq(struct nouveau_drm *drm,
0146             struct nouveau_connector *nv_connector);
0147 enum drm_mode_status nv50_dp_mode_valid(struct drm_connector *,
0148                     struct nouveau_encoder *,
0149                     const struct drm_display_mode *,
0150                     unsigned *clock);
0151 
0152 struct nouveau_connector *
0153 nv50_outp_get_new_connector(struct drm_atomic_state *state, struct nouveau_encoder *outp);
0154 struct nouveau_connector *
0155 nv50_outp_get_old_connector(struct drm_atomic_state *state, struct nouveau_encoder *outp);
0156 
0157 int nv50_mstm_detect(struct nouveau_encoder *encoder);
0158 void nv50_mstm_remove(struct nv50_mstm *mstm);
0159 bool nv50_mstm_service(struct nouveau_drm *drm,
0160                struct nouveau_connector *nv_connector,
0161                struct nv50_mstm *mstm);
0162 #endif /* __NOUVEAU_ENCODER_H__ */