Commit f20c665c authored by Ben Skeggs's avatar Ben Skeggs

drm/nouveau/kms/nv50: clean-up encoder functions

Just a shuffle of blocks into an order consistent with the rest of the
code, renaming hdmi/audio funtions for atomic, and removal of unused
code.
Signed-off-by: default avatarBen Skeggs <bskeggs@redhat.com>
parent 354d3508
...@@ -58,14 +58,14 @@ nouveau_dp_detect(struct nouveau_encoder *nv_encoder) ...@@ -58,14 +58,14 @@ nouveau_dp_detect(struct nouveau_encoder *nv_encoder)
struct drm_device *dev = nv_encoder->base.base.dev; struct drm_device *dev = nv_encoder->base.base.dev;
struct nouveau_drm *drm = nouveau_drm(dev); struct nouveau_drm *drm = nouveau_drm(dev);
struct nvkm_i2c_aux *aux; struct nvkm_i2c_aux *aux;
u8 *dpcd = nv_encoder->dp.dpcd; u8 dpcd[8];
int ret; int ret;
aux = nv_encoder->aux; aux = nv_encoder->aux;
if (!aux) if (!aux)
return -ENODEV; return -ENODEV;
ret = nvkm_rdaux(aux, DP_DPCD_REV, dpcd, 8); ret = nvkm_rdaux(aux, DP_DPCD_REV, dpcd, sizeof(dpcd));
if (ret) if (ret)
return ret; return ret;
......
...@@ -59,10 +59,8 @@ struct nouveau_encoder { ...@@ -59,10 +59,8 @@ struct nouveau_encoder {
union { union {
struct { struct {
struct nv50_mstm *mstm; struct nv50_mstm *mstm;
u8 dpcd[8];
int link_nr; int link_nr;
int link_bw; int link_bw;
u32 datarate;
} dp; } dp;
}; };
......
...@@ -2835,8 +2835,30 @@ nv50_dac_dpms(struct drm_encoder *encoder, int mode) ...@@ -2835,8 +2835,30 @@ nv50_dac_dpms(struct drm_encoder *encoder, int mode)
} }
static void static void
nv50_dac_commit(struct drm_encoder *encoder) nv50_dac_disconnect(struct drm_encoder *encoder)
{ {
struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
struct nv50_mast *mast = nv50_mast(encoder->dev);
const int or = nv_encoder->or;
u32 *push;
if (nv_encoder->crtc) {
nv50_crtc_prepare(nv_encoder->crtc);
push = evo_wait(mast, 4);
if (push) {
if (nv50_vers(mast) < GF110_DISP_CORE_CHANNEL_DMA) {
evo_mthd(push, 0x0400 + (or * 0x080), 1);
evo_data(push, 0x00000000);
} else {
evo_mthd(push, 0x0180 + (or * 0x020), 1);
evo_data(push, 0x00000000);
}
evo_kick(push, mast);
}
}
nv_encoder->crtc = NULL;
} }
static void static void
...@@ -2888,33 +2910,6 @@ nv50_dac_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode, ...@@ -2888,33 +2910,6 @@ nv50_dac_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode,
nv_encoder->crtc = encoder->crtc; nv_encoder->crtc = encoder->crtc;
} }
static void
nv50_dac_disconnect(struct drm_encoder *encoder)
{
struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
struct nv50_mast *mast = nv50_mast(encoder->dev);
const int or = nv_encoder->or;
u32 *push;
if (nv_encoder->crtc) {
nv50_crtc_prepare(nv_encoder->crtc);
push = evo_wait(mast, 4);
if (push) {
if (nv50_vers(mast) < GF110_DISP_CORE_CHANNEL_DMA) {
evo_mthd(push, 0x0400 + (or * 0x080), 1);
evo_data(push, 0x00000000);
} else {
evo_mthd(push, 0x0180 + (or * 0x020), 1);
evo_data(push, 0x00000000);
}
evo_kick(push, mast);
}
}
nv_encoder->crtc = NULL;
}
static enum drm_connector_status static enum drm_connector_status
nv50_dac_detect(struct drm_encoder *encoder, struct drm_connector *connector) nv50_dac_detect(struct drm_encoder *encoder, struct drm_connector *connector)
{ {
...@@ -2942,25 +2937,26 @@ nv50_dac_detect(struct drm_encoder *encoder, struct drm_connector *connector) ...@@ -2942,25 +2937,26 @@ nv50_dac_detect(struct drm_encoder *encoder, struct drm_connector *connector)
return connector_status_connected; return connector_status_connected;
} }
static void static const struct drm_encoder_helper_funcs
nv50_dac_destroy(struct drm_encoder *encoder) nv50_dac_help = {
{
drm_encoder_cleanup(encoder);
kfree(encoder);
}
static const struct drm_encoder_helper_funcs nv50_dac_hfunc = {
.dpms = nv50_dac_dpms, .dpms = nv50_dac_dpms,
.mode_fixup = nv50_encoder_mode_fixup, .mode_fixup = nv50_encoder_mode_fixup,
.prepare = nv50_dac_disconnect, .prepare = nv50_dac_disconnect,
.commit = nv50_dac_commit,
.mode_set = nv50_dac_mode_set, .mode_set = nv50_dac_mode_set,
.disable = nv50_dac_disconnect, .disable = nv50_dac_disconnect,
.get_crtc = nv50_display_crtc_get, .get_crtc = nv50_display_crtc_get,
.detect = nv50_dac_detect .detect = nv50_dac_detect
}; };
static const struct drm_encoder_funcs nv50_dac_func = { static void
nv50_dac_destroy(struct drm_encoder *encoder)
{
drm_encoder_cleanup(encoder);
kfree(encoder);
}
static const struct drm_encoder_funcs
nv50_dac_func = {
.destroy = nv50_dac_destroy, .destroy = nv50_dac_destroy,
}; };
...@@ -2989,7 +2985,7 @@ nv50_dac_create(struct drm_connector *connector, struct dcb_output *dcbe) ...@@ -2989,7 +2985,7 @@ nv50_dac_create(struct drm_connector *connector, struct dcb_output *dcbe)
encoder->possible_clones = 0; encoder->possible_clones = 0;
drm_encoder_init(connector->dev, encoder, &nv50_dac_func, type, drm_encoder_init(connector->dev, encoder, &nv50_dac_func, type,
"dac-%04x-%04x", dcbe->hasht, dcbe->hashm); "dac-%04x-%04x", dcbe->hasht, dcbe->hashm);
drm_encoder_helper_add(encoder, &nv50_dac_hfunc); drm_encoder_helper_add(encoder, &nv50_dac_help);
drm_mode_connector_attach_encoder(connector, encoder); drm_mode_connector_attach_encoder(connector, encoder);
return 0; return 0;
...@@ -2999,7 +2995,26 @@ nv50_dac_create(struct drm_connector *connector, struct dcb_output *dcbe) ...@@ -2999,7 +2995,26 @@ nv50_dac_create(struct drm_connector *connector, struct dcb_output *dcbe)
* Audio * Audio
*****************************************************************************/ *****************************************************************************/
static void static void
nv50_audio_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode) nv50_audio_disable(struct drm_encoder *encoder, struct nouveau_crtc *nv_crtc)
{
struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
struct nv50_disp *disp = nv50_disp(encoder->dev);
struct {
struct nv50_disp_mthd_v1 base;
struct nv50_disp_sor_hda_eld_v0 eld;
} args = {
.base.version = 1,
.base.method = NV50_DISP_MTHD_V1_SOR_HDA_ELD,
.base.hasht = nv_encoder->dcb->hasht,
.base.hashm = (0xf0ff & nv_encoder->dcb->hashm) |
(0x0100 << nv_crtc->index),
};
nvif_mthd(disp->disp, 0, &args, sizeof(args));
}
static void
nv50_audio_enable(struct drm_encoder *encoder, struct drm_display_mode *mode)
{ {
struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
struct nouveau_crtc *nv_crtc = nouveau_crtc(encoder->crtc); struct nouveau_crtc *nv_crtc = nouveau_crtc(encoder->crtc);
...@@ -3030,17 +3045,20 @@ nv50_audio_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode) ...@@ -3030,17 +3045,20 @@ nv50_audio_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode)
sizeof(args.base) + drm_eld_size(args.data)); sizeof(args.base) + drm_eld_size(args.data));
} }
/******************************************************************************
* HDMI
*****************************************************************************/
static void static void
nv50_audio_disconnect(struct drm_encoder *encoder, struct nouveau_crtc *nv_crtc) nv50_hdmi_disable(struct drm_encoder *encoder, struct nouveau_crtc *nv_crtc)
{ {
struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
struct nv50_disp *disp = nv50_disp(encoder->dev); struct nv50_disp *disp = nv50_disp(encoder->dev);
struct { struct {
struct nv50_disp_mthd_v1 base; struct nv50_disp_mthd_v1 base;
struct nv50_disp_sor_hda_eld_v0 eld; struct nv50_disp_sor_hdmi_pwr_v0 pwr;
} args = { } args = {
.base.version = 1, .base.version = 1,
.base.method = NV50_DISP_MTHD_V1_SOR_HDA_ELD, .base.method = NV50_DISP_MTHD_V1_SOR_HDMI_PWR,
.base.hasht = nv_encoder->dcb->hasht, .base.hasht = nv_encoder->dcb->hasht,
.base.hashm = (0xf0ff & nv_encoder->dcb->hashm) | .base.hashm = (0xf0ff & nv_encoder->dcb->hashm) |
(0x0100 << nv_crtc->index), (0x0100 << nv_crtc->index),
...@@ -3049,11 +3067,8 @@ nv50_audio_disconnect(struct drm_encoder *encoder, struct nouveau_crtc *nv_crtc) ...@@ -3049,11 +3067,8 @@ nv50_audio_disconnect(struct drm_encoder *encoder, struct nouveau_crtc *nv_crtc)
nvif_mthd(disp->disp, 0, &args, sizeof(args)); nvif_mthd(disp->disp, 0, &args, sizeof(args));
} }
/******************************************************************************
* HDMI
*****************************************************************************/
static void static void
nv50_hdmi_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode) nv50_hdmi_enable(struct drm_encoder *encoder, struct drm_display_mode *mode)
{ {
struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
struct nouveau_crtc *nv_crtc = nouveau_crtc(encoder->crtc); struct nouveau_crtc *nv_crtc = nouveau_crtc(encoder->crtc);
...@@ -3083,26 +3098,7 @@ nv50_hdmi_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode) ...@@ -3083,26 +3098,7 @@ nv50_hdmi_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode)
args.pwr.max_ac_packet = max_ac_packet / 32; args.pwr.max_ac_packet = max_ac_packet / 32;
nvif_mthd(disp->disp, 0, &args, sizeof(args)); nvif_mthd(disp->disp, 0, &args, sizeof(args));
nv50_audio_mode_set(encoder, mode); nv50_audio_enable(encoder, mode);
}
static void
nv50_hdmi_disconnect(struct drm_encoder *encoder, struct nouveau_crtc *nv_crtc)
{
struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
struct nv50_disp *disp = nv50_disp(encoder->dev);
struct {
struct nv50_disp_mthd_v1 base;
struct nv50_disp_sor_hdmi_pwr_v0 pwr;
} args = {
.base.version = 1,
.base.method = NV50_DISP_MTHD_V1_SOR_HDMI_PWR,
.base.hasht = nv_encoder->dcb->hasht,
.base.hashm = (0xf0ff & nv_encoder->dcb->hashm) |
(0x0100 << nv_crtc->index),
};
nvif_mthd(disp->disp, 0, &args, sizeof(args));
} }
/****************************************************************************** /******************************************************************************
...@@ -3292,16 +3288,11 @@ nv50_sor_disconnect(struct drm_encoder *encoder) ...@@ -3292,16 +3288,11 @@ nv50_sor_disconnect(struct drm_encoder *encoder)
if (nv_crtc) { if (nv_crtc) {
nv50_crtc_prepare(&nv_crtc->base); nv50_crtc_prepare(&nv_crtc->base);
nv50_sor_ctrl(nv_encoder, 1 << nv_crtc->index, 0); nv50_sor_ctrl(nv_encoder, 1 << nv_crtc->index, 0);
nv50_audio_disconnect(encoder, nv_crtc); nv50_audio_disable(encoder, nv_crtc);
nv50_hdmi_disconnect(&nv_encoder->base.base, nv_crtc); nv50_hdmi_disable(&nv_encoder->base.base, nv_crtc);
} }
} }
static void
nv50_sor_commit(struct drm_encoder *encoder)
{
}
static void static void
nv50_sor_mode_set(struct drm_encoder *encoder, struct drm_display_mode *umode, nv50_sor_mode_set(struct drm_encoder *encoder, struct drm_display_mode *umode,
struct drm_display_mode *mode) struct drm_display_mode *mode)
...@@ -3349,7 +3340,7 @@ nv50_sor_mode_set(struct drm_encoder *encoder, struct drm_display_mode *umode, ...@@ -3349,7 +3340,7 @@ nv50_sor_mode_set(struct drm_encoder *encoder, struct drm_display_mode *umode,
proto = 0x2; proto = 0x2;
} }
nv50_hdmi_mode_set(&nv_encoder->base.base, mode); nv50_hdmi_enable(&nv_encoder->base.base, mode);
break; break;
case DCB_OUTPUT_LVDS: case DCB_OUTPUT_LVDS:
proto = 0x0; proto = 0x0;
...@@ -3383,23 +3374,20 @@ nv50_sor_mode_set(struct drm_encoder *encoder, struct drm_display_mode *umode, ...@@ -3383,23 +3374,20 @@ nv50_sor_mode_set(struct drm_encoder *encoder, struct drm_display_mode *umode,
nvif_mthd(disp->disp, 0, &lvds, sizeof(lvds)); nvif_mthd(disp->disp, 0, &lvds, sizeof(lvds));
break; break;
case DCB_OUTPUT_DP: case DCB_OUTPUT_DP:
if (nv_connector->base.display_info.bpc == 6) { if (nv_connector->base.display_info.bpc == 6)
nv_encoder->dp.datarate = mode->clock * 18 / 8;
depth = 0x2; depth = 0x2;
} else else
if (nv_connector->base.display_info.bpc == 8) { if (nv_connector->base.display_info.bpc == 8)
nv_encoder->dp.datarate = mode->clock * 24 / 8;
depth = 0x5; depth = 0x5;
} else { else
nv_encoder->dp.datarate = mode->clock * 30 / 8;
depth = 0x6; depth = 0x6;
}
if (nv_encoder->dcb->sorconf.link & 1) if (nv_encoder->dcb->sorconf.link & 1)
proto = 0x8; proto = 0x8;
else else
proto = 0x9; proto = 0x9;
nv50_audio_mode_set(encoder, mode);
nv50_audio_enable(encoder, mode);
break; break;
default: default:
BUG_ON(1); BUG_ON(1);
...@@ -3442,6 +3430,16 @@ nv50_sor_mode_set(struct drm_encoder *encoder, struct drm_display_mode *umode, ...@@ -3442,6 +3430,16 @@ nv50_sor_mode_set(struct drm_encoder *encoder, struct drm_display_mode *umode,
nv50_sor_ctrl(nv_encoder, mask | owner, ctrl | owner); nv50_sor_ctrl(nv_encoder, mask | owner, ctrl | owner);
} }
static const struct drm_encoder_helper_funcs
nv50_sor_help = {
.dpms = nv50_sor_dpms,
.mode_fixup = nv50_encoder_mode_fixup,
.prepare = nv50_sor_disconnect,
.mode_set = nv50_sor_mode_set,
.disable = nv50_sor_disconnect,
.get_crtc = nv50_display_crtc_get,
};
static void static void
nv50_sor_destroy(struct drm_encoder *encoder) nv50_sor_destroy(struct drm_encoder *encoder)
{ {
...@@ -3451,17 +3449,8 @@ nv50_sor_destroy(struct drm_encoder *encoder) ...@@ -3451,17 +3449,8 @@ nv50_sor_destroy(struct drm_encoder *encoder)
kfree(encoder); kfree(encoder);
} }
static const struct drm_encoder_helper_funcs nv50_sor_hfunc = { static const struct drm_encoder_funcs
.dpms = nv50_sor_dpms, nv50_sor_func = {
.mode_fixup = nv50_encoder_mode_fixup,
.prepare = nv50_sor_disconnect,
.commit = nv50_sor_commit,
.mode_set = nv50_sor_mode_set,
.disable = nv50_sor_disconnect,
.get_crtc = nv50_display_crtc_get,
};
static const struct drm_encoder_funcs nv50_sor_func = {
.destroy = nv50_sor_destroy, .destroy = nv50_sor_destroy,
}; };
...@@ -3496,7 +3485,7 @@ nv50_sor_create(struct drm_connector *connector, struct dcb_output *dcbe) ...@@ -3496,7 +3485,7 @@ nv50_sor_create(struct drm_connector *connector, struct dcb_output *dcbe)
encoder->possible_clones = 0; encoder->possible_clones = 0;
drm_encoder_init(connector->dev, encoder, &nv50_sor_func, type, drm_encoder_init(connector->dev, encoder, &nv50_sor_func, type,
"sor-%04x-%04x", dcbe->hasht, dcbe->hashm); "sor-%04x-%04x", dcbe->hasht, dcbe->hashm);
drm_encoder_helper_add(encoder, &nv50_sor_hfunc); drm_encoder_helper_add(encoder, &nv50_sor_help);
drm_mode_connector_attach_encoder(connector, encoder); drm_mode_connector_attach_encoder(connector, encoder);
...@@ -3529,7 +3518,6 @@ nv50_sor_create(struct drm_connector *connector, struct dcb_output *dcbe) ...@@ -3529,7 +3518,6 @@ nv50_sor_create(struct drm_connector *connector, struct dcb_output *dcbe)
/****************************************************************************** /******************************************************************************
* PIOR * PIOR
*****************************************************************************/ *****************************************************************************/
static void static void
nv50_pior_dpms(struct drm_encoder *encoder, int mode) nv50_pior_dpms(struct drm_encoder *encoder, int mode)
{ {
...@@ -3562,8 +3550,27 @@ nv50_pior_mode_fixup(struct drm_encoder *encoder, ...@@ -3562,8 +3550,27 @@ nv50_pior_mode_fixup(struct drm_encoder *encoder,
} }
static void static void
nv50_pior_commit(struct drm_encoder *encoder) nv50_pior_disconnect(struct drm_encoder *encoder)
{ {
struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
struct nv50_mast *mast = nv50_mast(encoder->dev);
const int or = nv_encoder->or;
u32 *push;
if (nv_encoder->crtc) {
nv50_crtc_prepare(nv_encoder->crtc);
push = evo_wait(mast, 4);
if (push) {
if (nv50_vers(mast) < GF110_DISP_CORE_CHANNEL_DMA) {
evo_mthd(push, 0x0700 + (or * 0x040), 1);
evo_data(push, 0x00000000);
}
evo_kick(push, mast);
}
}
nv_encoder->crtc = NULL;
} }
static void static void
...@@ -3616,48 +3623,25 @@ nv50_pior_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode, ...@@ -3616,48 +3623,25 @@ nv50_pior_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode,
nv_encoder->crtc = encoder->crtc; nv_encoder->crtc = encoder->crtc;
} }
static void static const struct drm_encoder_helper_funcs
nv50_pior_disconnect(struct drm_encoder *encoder) nv50_pior_help = {
{
struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
struct nv50_mast *mast = nv50_mast(encoder->dev);
const int or = nv_encoder->or;
u32 *push;
if (nv_encoder->crtc) {
nv50_crtc_prepare(nv_encoder->crtc);
push = evo_wait(mast, 4);
if (push) {
if (nv50_vers(mast) < GF110_DISP_CORE_CHANNEL_DMA) {
evo_mthd(push, 0x0700 + (or * 0x040), 1);
evo_data(push, 0x00000000);
}
evo_kick(push, mast);
}
}
nv_encoder->crtc = NULL;
}
static void
nv50_pior_destroy(struct drm_encoder *encoder)
{
drm_encoder_cleanup(encoder);
kfree(encoder);
}
static const struct drm_encoder_helper_funcs nv50_pior_hfunc = {
.dpms = nv50_pior_dpms, .dpms = nv50_pior_dpms,
.mode_fixup = nv50_pior_mode_fixup, .mode_fixup = nv50_pior_mode_fixup,
.prepare = nv50_pior_disconnect, .prepare = nv50_pior_disconnect,
.commit = nv50_pior_commit,
.mode_set = nv50_pior_mode_set, .mode_set = nv50_pior_mode_set,
.disable = nv50_pior_disconnect, .disable = nv50_pior_disconnect,
.get_crtc = nv50_display_crtc_get, .get_crtc = nv50_display_crtc_get,
}; };
static const struct drm_encoder_funcs nv50_pior_func = { static void
nv50_pior_destroy(struct drm_encoder *encoder)
{
drm_encoder_cleanup(encoder);
kfree(encoder);
}
static const struct drm_encoder_funcs
nv50_pior_func = {
.destroy = nv50_pior_destroy, .destroy = nv50_pior_destroy,
}; };
...@@ -3701,7 +3685,7 @@ nv50_pior_create(struct drm_connector *connector, struct dcb_output *dcbe) ...@@ -3701,7 +3685,7 @@ nv50_pior_create(struct drm_connector *connector, struct dcb_output *dcbe)
encoder->possible_clones = 0; encoder->possible_clones = 0;
drm_encoder_init(connector->dev, encoder, &nv50_pior_func, type, drm_encoder_init(connector->dev, encoder, &nv50_pior_func, type,
"pior-%04x-%04x", dcbe->hasht, dcbe->hashm); "pior-%04x-%04x", dcbe->hasht, dcbe->hashm);
drm_encoder_helper_add(encoder, &nv50_pior_hfunc); drm_encoder_helper_add(encoder, &nv50_pior_help);
drm_mode_connector_attach_encoder(connector, encoder); drm_mode_connector_attach_encoder(connector, encoder);
return 0; return 0;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment