From 5ed502096f698b978c12a435f04be5afb195b485 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Mon, 11 Feb 2013 20:15:03 +1000 Subject: [PATCH] drm/nouveau: store i2c port pointer directly in nouveau_encoder This is about to become somewhat more complicated to determine in a number of cases, so store the "common" case (DDC/AUX) directly inside the encoder structure. Pre-nv50 code not touched except to fill the pointer, don't care. Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_connector.c | 4 +--- drivers/gpu/drm/nouveau/nouveau_dp.c | 10 +++------ drivers/gpu/drm/nouveau/nouveau_encoder.h | 9 +------- drivers/gpu/drm/nouveau/nv04_display.c | 8 +++++++ drivers/gpu/drm/nouveau/nv50_display.c | 24 +++++++++++++++++---- 5 files changed, 33 insertions(+), 22 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nouveau_connector.c b/drivers/gpu/drm/nouveau/nouveau_connector.c index 9c4b3f5fba01..4dd7ae2ac6c6 100644 --- a/drivers/gpu/drm/nouveau/nouveau_connector.c +++ b/drivers/gpu/drm/nouveau/nouveau_connector.c @@ -112,7 +112,6 @@ nouveau_connector_ddc_detect(struct drm_connector *connector, struct nouveau_connector *nv_connector = nouveau_connector(connector); struct nouveau_drm *drm = nouveau_drm(dev); struct nouveau_gpio *gpio = nouveau_gpio(drm->device); - struct nouveau_i2c *i2c = nouveau_i2c(drm->device); struct nouveau_i2c_port *port = NULL; int i, panel = -ENODEV; @@ -142,8 +141,7 @@ nouveau_connector_ddc_detect(struct drm_connector *connector, continue; nv_encoder = nouveau_encoder(obj_to_encoder(obj)); - if (nv_encoder->dcb->i2c_index < 0xf) - port = i2c->find(i2c, nv_encoder->dcb->i2c_index); + port = nv_encoder->i2c; if (port && nv_probe_i2c(port, 0x50)) { *pnv_encoder = nv_encoder; break; diff --git a/drivers/gpu/drm/nouveau/nouveau_dp.c b/drivers/gpu/drm/nouveau/nouveau_dp.c index a87c3674157f..d4da57f21258 100644 --- a/drivers/gpu/drm/nouveau/nouveau_dp.c +++ b/drivers/gpu/drm/nouveau/nouveau_dp.c @@ -238,13 +238,12 @@ nouveau_dp_link_train(struct drm_encoder *encoder, u32 datarate, nouveau_encoder_connector_get(nv_encoder); struct drm_device *dev = encoder->dev; struct nouveau_drm *drm = nouveau_drm(dev); - struct nouveau_i2c *i2c = nouveau_i2c(drm->device); struct nouveau_gpio *gpio = nouveau_gpio(drm->device); const u32 bw_list[] = { 270000, 162000, 0 }; const u32 *link_bw = bw_list; struct dp_state dp; - dp.auxch = i2c->find(i2c, nv_encoder->dcb->i2c_index); + dp.auxch = nv_encoder->i2c; if (!dp.auxch) return false; @@ -311,12 +310,10 @@ nouveau_dp_dpms(struct drm_encoder *encoder, int mode, u32 datarate, struct nouveau_object *core) { struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); - struct nouveau_drm *drm = nouveau_drm(encoder->dev); - struct nouveau_i2c *i2c = nouveau_i2c(drm->device); struct nouveau_i2c_port *auxch; u8 status; - auxch = i2c->find(i2c, nv_encoder->dcb->i2c_index); + auxch = nv_encoder->i2c; if (!auxch) return; @@ -357,12 +354,11 @@ nouveau_dp_detect(struct drm_encoder *encoder) struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); struct drm_device *dev = encoder->dev; struct nouveau_drm *drm = nouveau_drm(dev); - struct nouveau_i2c *i2c = nouveau_i2c(drm->device); struct nouveau_i2c_port *auxch; u8 *dpcd = nv_encoder->dp.dpcd; int ret; - auxch = i2c->find(i2c, nv_encoder->dcb->i2c_index); + auxch = nv_encoder->i2c; if (!auxch) return false; diff --git a/drivers/gpu/drm/nouveau/nouveau_encoder.h b/drivers/gpu/drm/nouveau/nouveau_encoder.h index d0d95bd511ab..e24341229d5e 100644 --- a/drivers/gpu/drm/nouveau/nouveau_encoder.h +++ b/drivers/gpu/drm/nouveau/nouveau_encoder.h @@ -36,19 +36,12 @@ struct nouveau_i2c_port; -struct dp_train_func { - void (*link_set)(struct drm_device *, struct dcb_output *, int crtc, - int nr, u32 bw, bool enhframe); - void (*train_set)(struct drm_device *, struct dcb_output *, u8 pattern); - void (*train_adj)(struct drm_device *, struct dcb_output *, - u8 lane, u8 swing, u8 preem); -}; - struct nouveau_encoder { struct drm_encoder_slave base; struct dcb_output *dcb; int or; + struct nouveau_i2c_port *i2c; /* different to drm_encoder.crtc, this reflects what's * actually programmed on the hw, not the proposed crtc */ diff --git a/drivers/gpu/drm/nouveau/nv04_display.c b/drivers/gpu/drm/nouveau/nv04_display.c index edc31560b848..e61f7406fefa 100644 --- a/drivers/gpu/drm/nouveau/nv04_display.c +++ b/drivers/gpu/drm/nouveau/nv04_display.c @@ -34,6 +34,8 @@ #include "nouveau_encoder.h" #include "nouveau_connector.h" +#include + int nv04_display_early_init(struct drm_device *dev) { @@ -56,6 +58,7 @@ int nv04_display_create(struct drm_device *dev) { struct nouveau_drm *drm = nouveau_drm(dev); + struct nouveau_i2c *i2c = nouveau_i2c(drm->device); struct dcb_table *dcb = &drm->vbios.dcb; struct drm_connector *connector, *ct; struct drm_encoder *encoder; @@ -122,6 +125,11 @@ nv04_display_create(struct drm_device *dev) } } + list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { + struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); + nv_encoder->i2c = i2c->find(i2c, nv_encoder->dcb->i2c_index); + } + /* Save previous state */ list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) crtc->funcs->save(crtc); diff --git a/drivers/gpu/drm/nouveau/nv50_display.c b/drivers/gpu/drm/nouveau/nv50_display.c index 102a8734d377..75d116137c0a 100644 --- a/drivers/gpu/drm/nouveau/nv50_display.c +++ b/drivers/gpu/drm/nouveau/nv50_display.c @@ -43,6 +43,7 @@ #include #include #include +#include #define EVO_DMA_NR 9 @@ -1554,20 +1555,23 @@ static const struct drm_encoder_funcs nv50_dac_func = { static int nv50_dac_create(struct drm_connector *connector, struct dcb_output *dcbe) { - struct drm_device *dev = connector->dev; + struct nouveau_drm *drm = nouveau_drm(connector->dev); + struct nouveau_i2c *i2c = nouveau_i2c(drm->device); struct nouveau_encoder *nv_encoder; struct drm_encoder *encoder; + int type = DRM_MODE_ENCODER_DAC; nv_encoder = kzalloc(sizeof(*nv_encoder), GFP_KERNEL); if (!nv_encoder) return -ENOMEM; nv_encoder->dcb = dcbe; nv_encoder->or = ffs(dcbe->or) - 1; + nv_encoder->i2c = i2c->find(i2c, dcbe->i2c_index); encoder = to_drm_encoder(nv_encoder); encoder->possible_crtcs = dcbe->heads; encoder->possible_clones = 0; - drm_encoder_init(dev, encoder, &nv50_dac_func, DRM_MODE_ENCODER_DAC); + drm_encoder_init(connector->dev, encoder, &nv50_dac_func, type); drm_encoder_helper_add(encoder, &nv50_dac_hfunc); drm_mode_connector_attach_encoder(connector, encoder); @@ -1893,21 +1897,33 @@ static const struct drm_encoder_funcs nv50_sor_func = { static int nv50_sor_create(struct drm_connector *connector, struct dcb_output *dcbe) { - struct drm_device *dev = connector->dev; + struct nouveau_drm *drm = nouveau_drm(connector->dev); + struct nouveau_i2c *i2c = nouveau_i2c(drm->device); struct nouveau_encoder *nv_encoder; struct drm_encoder *encoder; + int type; + + switch (dcbe->type) { + case DCB_OUTPUT_LVDS: type = DRM_MODE_ENCODER_LVDS; break; + case DCB_OUTPUT_TMDS: + case DCB_OUTPUT_DP: + default: + type = DRM_MODE_ENCODER_TMDS; + break; + } nv_encoder = kzalloc(sizeof(*nv_encoder), GFP_KERNEL); if (!nv_encoder) return -ENOMEM; nv_encoder->dcb = dcbe; nv_encoder->or = ffs(dcbe->or) - 1; + nv_encoder->i2c = i2c->find(i2c, dcbe->i2c_index); nv_encoder->last_dpms = DRM_MODE_DPMS_OFF; encoder = to_drm_encoder(nv_encoder); encoder->possible_crtcs = dcbe->heads; encoder->possible_clones = 0; - drm_encoder_init(dev, encoder, &nv50_sor_func, DRM_MODE_ENCODER_TMDS); + drm_encoder_init(connector->dev, encoder, &nv50_sor_func, type); drm_encoder_helper_add(encoder, &nv50_sor_hfunc); drm_mode_connector_attach_encoder(connector, encoder);