Commit bd7a61bc authored by Ben Skeggs's avatar Ben Skeggs Committed by Lyude Paul
Browse files

drm/nouveau/disp: add dp aux xfer method

parent 0bd4e9f7
Loading
Loading
Loading
Loading
+15 −17
Original line number Diff line number Diff line
@@ -1704,14 +1704,13 @@ nv50_sor_destroy(struct drm_encoder *encoder)
{
	struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);

	nvif_outp_dtor(&nv_encoder->outp);

	nv50_mstm_del(&nv_encoder->dp.mstm);
	drm_encoder_cleanup(encoder);

	if (nv_encoder->dcb->type == DCB_OUTPUT_DP)
		mutex_destroy(&nv_encoder->dp.hpd_irq_lock);

	nvif_outp_dtor(&nv_encoder->outp);
	kfree(encoder);
}

@@ -1764,23 +1763,23 @@ nv50_sor_create(struct nouveau_encoder *nv_encoder)
	nv50_outp_dump_caps(drm, nv_encoder);

	if (dcbe->type == DCB_OUTPUT_DP) {
		struct nvkm_i2c_aux *aux =
			nvkm_i2c_aux_find(i2c, dcbe->i2c_index);

		mutex_init(&nv_encoder->dp.hpd_irq_lock);

		if (aux) {
		if (disp->disp->object.oclass < GF110_DISP) {
			/* HW has no support for address-only
			 * transactions, so we're required to
			 * use custom I2C-over-AUX code.
			 */
			struct nvkm_i2c_aux *aux;

			aux = nvkm_i2c_aux_find(i2c, dcbe->i2c_index);
			if (!aux)
				return -EINVAL;

			nv_encoder->i2c = &aux->i2c;
		} else {
			nv_encoder->i2c = &nv_connector->aux.ddc;
		}
			nv_encoder->aux = aux;
		}

		if (nv_connector->type != DCB_CONNECTOR_eDP &&
		    nv50_has_mst(drm)) {
@@ -1925,7 +1924,6 @@ nv50_pior_create(struct nouveau_encoder *nv_encoder)
	}

	nv_encoder->i2c = ddc;
	nv_encoder->aux = aux;

	encoder = to_drm_encoder(nv_encoder);
	drm_encoder_init(connector->dev, encoder, &nv50_pior_func, type,
+12 −0
Original line number Diff line number Diff line
@@ -32,6 +32,7 @@ union nvif_outp_args {
#define NVIF_OUTP_V0_HDA_ELD       0x61

#define NVIF_OUTP_V0_DP_AUX_PWR    0x70
#define NVIF_OUTP_V0_DP_AUX_XFER   0x71
#define NVIF_OUTP_V0_DP_RETRAIN    0x73
#define NVIF_OUTP_V0_DP_MST_VCPI   0x78

@@ -182,6 +183,17 @@ union nvif_outp_dp_aux_pwr_args {
	} v0;
};

union nvif_outp_dp_aux_xfer_args {
	struct nvif_outp_dp_aux_xfer_v0 {
		__u8  version;
		__u8  pad01;
		__u8  type;
		__u8  size;
		__u32 addr;
		__u8  data[16];
	} v0;
};

union nvif_outp_dp_retrain_args {
	struct nvif_outp_dp_retrain_vn {
	} vn;
+2 −0
Original line number Diff line number Diff line
@@ -56,7 +56,9 @@ int nvif_outp_hdmi(struct nvif_outp *, int head, bool enable, u8 max_ac_packet,

int nvif_outp_infoframe(struct nvif_outp *, u8 type, struct nvif_outp_infoframe_v0 *, u32 size);
int nvif_outp_hda_eld(struct nvif_outp *, int head, void *data, u32 size);

int nvif_outp_dp_aux_pwr(struct nvif_outp *, bool enable);
int nvif_outp_dp_aux_xfer(struct nvif_outp *, u8 type, u8 *size, u32 addr, u8 *data);
int nvif_outp_dp_retrain(struct nvif_outp *);
int nvif_outp_dp_mst_vcpi(struct nvif_outp *, int head,
			  u8 start_slot, u8 num_slots, u16 pbn, u16 aligned_pbn);
+3 −9
Original line number Diff line number Diff line
@@ -1226,23 +1226,17 @@ nouveau_connector_aux_xfer(struct drm_dp_aux *obj, struct drm_dp_aux_msg *msg)
	struct nouveau_connector *nv_connector =
		container_of(obj, typeof(*nv_connector), aux);
	struct nouveau_encoder *nv_encoder;
	struct nvkm_i2c_aux *aux;
	u8 size = msg->size;
	int ret;

	nv_encoder = find_encoder(&nv_connector->base, DCB_OUTPUT_DP);
	if (!nv_encoder || !(aux = nv_encoder->aux))
	if (!nv_encoder)
		return -ENODEV;
	if (WARN_ON(msg->size > 16))
		return -E2BIG;

	ret = nvkm_i2c_aux_acquire(aux);
	if (ret)
		return ret;

	ret = nvkm_i2c_aux_xfer(aux, false, msg->request, msg->address,
				msg->buffer, &size);
	nvkm_i2c_aux_release(aux);
	ret = nvif_outp_dp_aux_xfer(&nv_encoder->outp,
				    msg->request, &size, msg->address, msg->buffer);
	if (ret >= 0) {
		msg->reply = ret;
		return size;
+0 −1
Original line number Diff line number Diff line
@@ -52,7 +52,6 @@ struct nouveau_encoder {
	struct nouveau_connector *conn;

	struct i2c_adapter *i2c;
	struct nvkm_i2c_aux *aux;

	/* different to drm_encoder.crtc, this reflects what's
	 * actually programmed on the hw, not the proposed crtc */
Loading