drm/nouveau/dp: move core link training calls to common code
authorBen Skeggs <bskeggs@redhat.com>
Thu, 15 Nov 2012 08:56:02 +0000 (18:56 +1000)
committerBen Skeggs <bskeggs@redhat.com>
Wed, 28 Nov 2012 23:57:53 +0000 (09:57 +1000)
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
drivers/gpu/drm/nouveau/nouveau_dp.c
drivers/gpu/drm/nouveau/nouveau_encoder.h
drivers/gpu/drm/nouveau/nv50_sor.c
drivers/gpu/drm/nouveau/nvd0_display.c

index 978a108ba7a1b32c10d299f2ced9554b6bffa2dc..e3f6550ae7728b9ff16be0391f0d3604f2789010 100644 (file)
@@ -30,6 +30,8 @@
 #include "nouveau_encoder.h"
 #include "nouveau_crtc.h"
 
+#include <core/class.h>
+
 #include <subdev/gpio.h>
 #include <subdev/i2c.h>
 
@@ -83,7 +85,7 @@ nouveau_dp_bios_data(struct drm_device *dev, struct dcb_output *dcb, u8 **entry)
  *****************************************************************************/
 struct dp_state {
        struct nouveau_i2c_port *auxch;
-       struct dp_train_func *func;
+       struct nouveau_object *core;
        struct dcb_output *dcb;
        int crtc;
        u8 *dpcd;
@@ -97,13 +99,20 @@ static void
 dp_set_link_config(struct drm_device *dev, struct dp_state *dp)
 {
        struct nouveau_drm *drm = nouveau_drm(dev);
+       struct dcb_output *dcb = dp->dcb;
+       const u32 or = ffs(dcb->or) - 1, link = !(dcb->sorconf.link & 1);
+       const u32 moff = (dp->crtc << 3) | (link << 2) | or;
        u8 sink[2];
+       u32 data;
 
        NV_DEBUG(drm, "%d lanes at %d KB/s\n", dp->link_nr, dp->link_bw);
 
        /* set desired link configuration on the source */
-       dp->func->link_set(dev, dp->dcb, dp->crtc, dp->link_nr, dp->link_bw,
-                          dp->dpcd[2] & DP_ENHANCED_FRAME_CAP);
+       data = ((dp->link_bw / 27000) << 8) | dp->link_nr;
+       if (dp->dpcd[2] & DP_ENHANCED_FRAME_CAP)
+               data |= NV94_DISP_SOR_DP_LNKCTL_FRAME_ENH;
+
+       nv_call(dp->core, NV94_DISP_SOR_DP_LNKCTL + moff, data);
 
        /* inform the sink of the new configuration */
        sink[0] = dp->link_bw / 27000;
@@ -118,11 +127,14 @@ static void
 dp_set_training_pattern(struct drm_device *dev, struct dp_state *dp, u8 pattern)
 {
        struct nouveau_drm *drm = nouveau_drm(dev);
+       struct dcb_output *dcb = dp->dcb;
+       const u32 or = ffs(dcb->or) - 1, link = !(dcb->sorconf.link & 1);
+       const u32 moff = (dp->crtc << 3) | (link << 2) | or;
        u8 sink_tp;
 
        NV_DEBUG(drm, "training pattern %d\n", pattern);
 
-       dp->func->train_set(dev, dp->dcb, pattern);
+       nv_call(dp->core, NV94_DISP_SOR_DP_TRAIN + moff, pattern);
 
        nv_rdaux(dp->auxch, DP_TRAINING_PATTERN_SET, &sink_tp, 1);
        sink_tp &= ~DP_TRAINING_PATTERN_MASK;
@@ -134,6 +146,9 @@ static int
 dp_link_train_commit(struct drm_device *dev, struct dp_state *dp)
 {
        struct nouveau_drm *drm = nouveau_drm(dev);
+       struct dcb_output *dcb = dp->dcb;
+       const u32 or = ffs(dcb->or) - 1, link = !(dcb->sorconf.link & 1);
+       const u32 moff = (dp->crtc << 3) | (link << 2) | or;
        int i;
 
        for (i = 0; i < dp->link_nr; i++) {
@@ -148,7 +163,8 @@ dp_link_train_commit(struct drm_device *dev, struct dp_state *dp)
                        dp->conf[i] |= DP_TRAIN_MAX_PRE_EMPHASIS_REACHED;
 
                NV_DEBUG(drm, "config lane %d %02x\n", i, dp->conf[i]);
-               dp->func->train_adj(dev, dp->dcb, i, lvsw, lpre);
+
+               nv_call(dp->core, NV94_DISP_SOR_DP_DRVCTL(i) + moff, (lvsw << 8) | lpre);
        }
 
        return nv_wraux(dp->auxch, DP_TRAINING_LANE0_SET, dp->conf, 4);
@@ -286,7 +302,7 @@ dp_link_train_fini(struct drm_device *dev, struct dp_state *dp)
 
 static bool
 nouveau_dp_link_train(struct drm_encoder *encoder, u32 datarate,
-                     struct dp_train_func *func)
+                     struct nouveau_object *core)
 {
        struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
        struct nouveau_crtc *nv_crtc = nouveau_crtc(encoder->crtc);
@@ -304,7 +320,7 @@ nouveau_dp_link_train(struct drm_encoder *encoder, u32 datarate,
        if (!dp.auxch)
                return false;
 
-       dp.func = func;
+       dp.core = core;
        dp.dcb = nv_encoder->dcb;
        dp.crtc = nv_crtc->index;
        dp.dpcd = nv_encoder->dp.dpcd;
@@ -365,7 +381,7 @@ nouveau_dp_link_train(struct drm_encoder *encoder, u32 datarate,
 
 void
 nouveau_dp_dpms(struct drm_encoder *encoder, int mode, u32 datarate,
-               struct dp_train_func *func)
+               struct nouveau_object *core)
 {
        struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
        struct nouveau_drm *drm = nouveau_drm(encoder->dev);
@@ -385,7 +401,7 @@ nouveau_dp_dpms(struct drm_encoder *encoder, int mode, u32 datarate,
        nv_wraux(auxch, DP_SET_POWER, &status, 1);
 
        if (mode == DRM_MODE_DPMS_ON)
-               nouveau_dp_link_train(encoder, datarate, func);
+               nouveau_dp_link_train(encoder, datarate, core);
 }
 
 static void
index 6a17bf2ba9a414467c6767cd5ead8e5a097ec6a6..06c1bb3a2f2afab759c0d17fe2e2179d666f8be0 100644 (file)
@@ -93,7 +93,7 @@ get_slave_funcs(struct drm_encoder *enc)
 /* nouveau_dp.c */
 bool nouveau_dp_detect(struct drm_encoder *);
 void nouveau_dp_dpms(struct drm_encoder *, int mode, u32 datarate,
-                    struct dp_train_func *);
+                    struct nouveau_object *);
 u8 *nouveau_dp_bios_data(struct drm_device *, struct dcb_output *, u8 **);
 
 struct nouveau_connector *
index ae4f24a0a54c7c3257d6cc778ee42cb1a7b8732d..5499c23cb795587af4d22b833f6b1f1b1f836f81 100644 (file)
 
 #include <subdev/timer.h>
 
-static void
-nv50_sor_dp_train_set(struct drm_device *dev, struct dcb_output *dcb, u8 pattern)
-{
-       struct nv50_display *disp = nv50_display(dev);
-       const u32 or = ffs(dcb->or) - 1, link = !(dcb->sorconf.link & 1);
-       const u32 moff = (link << 2) | or;
-       nv_call(disp->core, NV94_DISP_SOR_DP_TRAIN + moff, pattern);
-}
-
-static void
-nv50_sor_dp_train_adj(struct drm_device *dev, struct dcb_output *dcb,
-                     u8 lane, u8 swing, u8 preem)
-{
-       struct nv50_display *disp = nv50_display(dev);
-       const u32 or = ffs(dcb->or) - 1, link = !(dcb->sorconf.link & 1);
-       const u32 moff = (link << 2) | or;
-       const u32 data = (swing << 8) | preem;
-       nv_call(disp->core, NV94_DISP_SOR_DP_DRVCTL(lane) + moff, data);
-}
-
-static void
-nv50_sor_dp_link_set(struct drm_device *dev, struct dcb_output *dcb, int crtc,
-                    int link_nr, u32 link_bw, bool enhframe)
-{
-       struct nv50_display *disp = nv50_display(dev);
-       const u32 or = ffs(dcb->or) - 1, link = !(dcb->sorconf.link & 1);
-       const u32 moff = (crtc << 3) | (link << 2) | or;
-       u32 data = ((link_bw / 27000) << 8) | link_nr;
-       if (enhframe)
-               data |= NV94_DISP_SOR_DP_LNKCTL_FRAME_ENH;
-       nv_call(disp->core, NV94_DISP_SOR_DP_LNKCTL + moff, data);
-}
-
 static void
 nv50_sor_disconnect(struct drm_encoder *encoder)
 {
@@ -133,15 +100,8 @@ nv50_sor_dpms(struct drm_encoder *encoder, int mode)
 
        nv_call(priv->core, NV50_DISP_SOR_PWR + or, (mode == DRM_MODE_DPMS_ON));
 
-       if (nv_encoder->dcb->type == DCB_OUTPUT_DP) {
-               struct dp_train_func func = {
-                       .link_set = nv50_sor_dp_link_set,
-                       .train_set = nv50_sor_dp_train_set,
-                       .train_adj = nv50_sor_dp_train_adj
-               };
-
-               nouveau_dp_dpms(encoder, mode, nv_encoder->dp.datarate, &func);
-       }
+       if (nv_encoder->dcb->type == DCB_OUTPUT_DP)
+               nouveau_dp_dpms(encoder, mode, nv_encoder->dp.datarate, priv->core);
 }
 
 static void
index 518f1a5342aa3a76909ce34cb9d1c87aefedb70c..98c93513189d3142846d3529b929a1d9df790ef0 100644 (file)
@@ -1305,39 +1305,6 @@ nvd0_hdmi_disconnect(struct drm_encoder *encoder)
 /******************************************************************************
  * SOR
  *****************************************************************************/
-static void
-nvd0_sor_dp_train_set(struct drm_device *dev, struct dcb_output *dcb, u8 pattern)
-{
-       struct nvd0_disp *disp = nvd0_disp(dev);
-       const u32 or = ffs(dcb->or) - 1, link = !(dcb->sorconf.link & 1);
-       const u32 moff = (link << 2) | or;
-       nv_call(disp->core, NV94_DISP_SOR_DP_TRAIN + moff, pattern);
-}
-
-static void
-nvd0_sor_dp_train_adj(struct drm_device *dev, struct dcb_output *dcb,
-                     u8 lane, u8 swing, u8 preem)
-{
-       struct nvd0_disp *disp = nvd0_disp(dev);
-       const u32 or = ffs(dcb->or) - 1, link = !(dcb->sorconf.link & 1);
-       const u32 moff = (link << 2) | or;
-       const u32 data = (swing << 8) | preem;
-       nv_call(disp->core, NV94_DISP_SOR_DP_DRVCTL(lane) + moff, data);
-}
-
-static void
-nvd0_sor_dp_link_set(struct drm_device *dev, struct dcb_output *dcb, int crtc,
-                    int link_nr, u32 link_bw, bool enhframe)
-{
-       struct nvd0_disp *disp = nvd0_disp(dev);
-       const u32 or = ffs(dcb->or) - 1, link = !(dcb->sorconf.link & 1);
-       const u32 moff = (crtc << 3) | (link << 2) | or;
-       u32 data = ((link_bw / 27000) << 8) | link_nr;
-       if (enhframe)
-               data |= NV94_DISP_SOR_DP_LNKCTL_FRAME_ENH;
-       nv_call(disp->core, NV94_DISP_SOR_DP_LNKCTL + moff, data);
-}
-
 static void
 nvd0_sor_dpms(struct drm_encoder *encoder, int mode)
 {
@@ -1365,15 +1332,8 @@ nvd0_sor_dpms(struct drm_encoder *encoder, int mode)
 
        nv_call(disp->core, NV50_DISP_SOR_PWR + or, (mode == DRM_MODE_DPMS_ON));
 
-       if (nv_encoder->dcb->type == DCB_OUTPUT_DP) {
-               struct dp_train_func func = {
-                       .link_set = nvd0_sor_dp_link_set,
-                       .train_set = nvd0_sor_dp_train_set,
-                       .train_adj = nvd0_sor_dp_train_adj
-               };
-
-               nouveau_dp_dpms(encoder, mode, nv_encoder->dp.datarate, &func);
-       }
+       if (nv_encoder->dcb->type == DCB_OUTPUT_DP)
+               nouveau_dp_dpms(encoder, mode, nv_encoder->dp.datarate, disp->core);
 }
 
 static bool