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 <bskeggs@redhat.com>
This commit is contained in:
parent
df3ef6a109
commit
5ed502096f
|
@ -112,7 +112,6 @@ nouveau_connector_ddc_detect(struct drm_connector *connector,
|
||||||
struct nouveau_connector *nv_connector = nouveau_connector(connector);
|
struct nouveau_connector *nv_connector = nouveau_connector(connector);
|
||||||
struct nouveau_drm *drm = nouveau_drm(dev);
|
struct nouveau_drm *drm = nouveau_drm(dev);
|
||||||
struct nouveau_gpio *gpio = nouveau_gpio(drm->device);
|
struct nouveau_gpio *gpio = nouveau_gpio(drm->device);
|
||||||
struct nouveau_i2c *i2c = nouveau_i2c(drm->device);
|
|
||||||
struct nouveau_i2c_port *port = NULL;
|
struct nouveau_i2c_port *port = NULL;
|
||||||
int i, panel = -ENODEV;
|
int i, panel = -ENODEV;
|
||||||
|
|
||||||
|
@ -142,8 +141,7 @@ nouveau_connector_ddc_detect(struct drm_connector *connector,
|
||||||
continue;
|
continue;
|
||||||
nv_encoder = nouveau_encoder(obj_to_encoder(obj));
|
nv_encoder = nouveau_encoder(obj_to_encoder(obj));
|
||||||
|
|
||||||
if (nv_encoder->dcb->i2c_index < 0xf)
|
port = nv_encoder->i2c;
|
||||||
port = i2c->find(i2c, nv_encoder->dcb->i2c_index);
|
|
||||||
if (port && nv_probe_i2c(port, 0x50)) {
|
if (port && nv_probe_i2c(port, 0x50)) {
|
||||||
*pnv_encoder = nv_encoder;
|
*pnv_encoder = nv_encoder;
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -238,13 +238,12 @@ nouveau_dp_link_train(struct drm_encoder *encoder, u32 datarate,
|
||||||
nouveau_encoder_connector_get(nv_encoder);
|
nouveau_encoder_connector_get(nv_encoder);
|
||||||
struct drm_device *dev = encoder->dev;
|
struct drm_device *dev = encoder->dev;
|
||||||
struct nouveau_drm *drm = nouveau_drm(dev);
|
struct nouveau_drm *drm = nouveau_drm(dev);
|
||||||
struct nouveau_i2c *i2c = nouveau_i2c(drm->device);
|
|
||||||
struct nouveau_gpio *gpio = nouveau_gpio(drm->device);
|
struct nouveau_gpio *gpio = nouveau_gpio(drm->device);
|
||||||
const u32 bw_list[] = { 270000, 162000, 0 };
|
const u32 bw_list[] = { 270000, 162000, 0 };
|
||||||
const u32 *link_bw = bw_list;
|
const u32 *link_bw = bw_list;
|
||||||
struct dp_state dp;
|
struct dp_state dp;
|
||||||
|
|
||||||
dp.auxch = i2c->find(i2c, nv_encoder->dcb->i2c_index);
|
dp.auxch = nv_encoder->i2c;
|
||||||
if (!dp.auxch)
|
if (!dp.auxch)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
@ -311,12 +310,10 @@ nouveau_dp_dpms(struct drm_encoder *encoder, int mode, u32 datarate,
|
||||||
struct nouveau_object *core)
|
struct nouveau_object *core)
|
||||||
{
|
{
|
||||||
struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
|
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;
|
struct nouveau_i2c_port *auxch;
|
||||||
u8 status;
|
u8 status;
|
||||||
|
|
||||||
auxch = i2c->find(i2c, nv_encoder->dcb->i2c_index);
|
auxch = nv_encoder->i2c;
|
||||||
if (!auxch)
|
if (!auxch)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -357,12 +354,11 @@ nouveau_dp_detect(struct drm_encoder *encoder)
|
||||||
struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
|
struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
|
||||||
struct drm_device *dev = encoder->dev;
|
struct drm_device *dev = encoder->dev;
|
||||||
struct nouveau_drm *drm = nouveau_drm(dev);
|
struct nouveau_drm *drm = nouveau_drm(dev);
|
||||||
struct nouveau_i2c *i2c = nouveau_i2c(drm->device);
|
|
||||||
struct nouveau_i2c_port *auxch;
|
struct nouveau_i2c_port *auxch;
|
||||||
u8 *dpcd = nv_encoder->dp.dpcd;
|
u8 *dpcd = nv_encoder->dp.dpcd;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
auxch = i2c->find(i2c, nv_encoder->dcb->i2c_index);
|
auxch = nv_encoder->i2c;
|
||||||
if (!auxch)
|
if (!auxch)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
|
|
@ -36,19 +36,12 @@
|
||||||
|
|
||||||
struct nouveau_i2c_port;
|
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 nouveau_encoder {
|
||||||
struct drm_encoder_slave base;
|
struct drm_encoder_slave base;
|
||||||
|
|
||||||
struct dcb_output *dcb;
|
struct dcb_output *dcb;
|
||||||
int or;
|
int or;
|
||||||
|
struct nouveau_i2c_port *i2c;
|
||||||
|
|
||||||
/* different to drm_encoder.crtc, this reflects what's
|
/* different to drm_encoder.crtc, this reflects what's
|
||||||
* actually programmed on the hw, not the proposed crtc */
|
* actually programmed on the hw, not the proposed crtc */
|
||||||
|
|
|
@ -34,6 +34,8 @@
|
||||||
#include "nouveau_encoder.h"
|
#include "nouveau_encoder.h"
|
||||||
#include "nouveau_connector.h"
|
#include "nouveau_connector.h"
|
||||||
|
|
||||||
|
#include <subdev/i2c.h>
|
||||||
|
|
||||||
int
|
int
|
||||||
nv04_display_early_init(struct drm_device *dev)
|
nv04_display_early_init(struct drm_device *dev)
|
||||||
{
|
{
|
||||||
|
@ -56,6 +58,7 @@ int
|
||||||
nv04_display_create(struct drm_device *dev)
|
nv04_display_create(struct drm_device *dev)
|
||||||
{
|
{
|
||||||
struct nouveau_drm *drm = nouveau_drm(dev);
|
struct nouveau_drm *drm = nouveau_drm(dev);
|
||||||
|
struct nouveau_i2c *i2c = nouveau_i2c(drm->device);
|
||||||
struct dcb_table *dcb = &drm->vbios.dcb;
|
struct dcb_table *dcb = &drm->vbios.dcb;
|
||||||
struct drm_connector *connector, *ct;
|
struct drm_connector *connector, *ct;
|
||||||
struct drm_encoder *encoder;
|
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 */
|
/* Save previous state */
|
||||||
list_for_each_entry(crtc, &dev->mode_config.crtc_list, head)
|
list_for_each_entry(crtc, &dev->mode_config.crtc_list, head)
|
||||||
crtc->funcs->save(crtc);
|
crtc->funcs->save(crtc);
|
||||||
|
|
|
@ -43,6 +43,7 @@
|
||||||
#include <subdev/timer.h>
|
#include <subdev/timer.h>
|
||||||
#include <subdev/bar.h>
|
#include <subdev/bar.h>
|
||||||
#include <subdev/fb.h>
|
#include <subdev/fb.h>
|
||||||
|
#include <subdev/i2c.h>
|
||||||
|
|
||||||
#define EVO_DMA_NR 9
|
#define EVO_DMA_NR 9
|
||||||
|
|
||||||
|
@ -1554,20 +1555,23 @@ static const struct drm_encoder_funcs nv50_dac_func = {
|
||||||
static int
|
static int
|
||||||
nv50_dac_create(struct drm_connector *connector, struct dcb_output *dcbe)
|
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 nouveau_encoder *nv_encoder;
|
||||||
struct drm_encoder *encoder;
|
struct drm_encoder *encoder;
|
||||||
|
int type = DRM_MODE_ENCODER_DAC;
|
||||||
|
|
||||||
nv_encoder = kzalloc(sizeof(*nv_encoder), GFP_KERNEL);
|
nv_encoder = kzalloc(sizeof(*nv_encoder), GFP_KERNEL);
|
||||||
if (!nv_encoder)
|
if (!nv_encoder)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
nv_encoder->dcb = dcbe;
|
nv_encoder->dcb = dcbe;
|
||||||
nv_encoder->or = ffs(dcbe->or) - 1;
|
nv_encoder->or = ffs(dcbe->or) - 1;
|
||||||
|
nv_encoder->i2c = i2c->find(i2c, dcbe->i2c_index);
|
||||||
|
|
||||||
encoder = to_drm_encoder(nv_encoder);
|
encoder = to_drm_encoder(nv_encoder);
|
||||||
encoder->possible_crtcs = dcbe->heads;
|
encoder->possible_crtcs = dcbe->heads;
|
||||||
encoder->possible_clones = 0;
|
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_encoder_helper_add(encoder, &nv50_dac_hfunc);
|
||||||
|
|
||||||
drm_mode_connector_attach_encoder(connector, encoder);
|
drm_mode_connector_attach_encoder(connector, encoder);
|
||||||
|
@ -1893,21 +1897,33 @@ static const struct drm_encoder_funcs nv50_sor_func = {
|
||||||
static int
|
static int
|
||||||
nv50_sor_create(struct drm_connector *connector, struct dcb_output *dcbe)
|
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 nouveau_encoder *nv_encoder;
|
||||||
struct drm_encoder *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);
|
nv_encoder = kzalloc(sizeof(*nv_encoder), GFP_KERNEL);
|
||||||
if (!nv_encoder)
|
if (!nv_encoder)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
nv_encoder->dcb = dcbe;
|
nv_encoder->dcb = dcbe;
|
||||||
nv_encoder->or = ffs(dcbe->or) - 1;
|
nv_encoder->or = ffs(dcbe->or) - 1;
|
||||||
|
nv_encoder->i2c = i2c->find(i2c, dcbe->i2c_index);
|
||||||
nv_encoder->last_dpms = DRM_MODE_DPMS_OFF;
|
nv_encoder->last_dpms = DRM_MODE_DPMS_OFF;
|
||||||
|
|
||||||
encoder = to_drm_encoder(nv_encoder);
|
encoder = to_drm_encoder(nv_encoder);
|
||||||
encoder->possible_crtcs = dcbe->heads;
|
encoder->possible_crtcs = dcbe->heads;
|
||||||
encoder->possible_clones = 0;
|
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_encoder_helper_add(encoder, &nv50_sor_hfunc);
|
||||||
|
|
||||||
drm_mode_connector_attach_encoder(connector, encoder);
|
drm_mode_connector_attach_encoder(connector, encoder);
|
||||||
|
|
Loading…
Reference in New Issue