]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/commitdiff
Merge tag 'sti-drm-next-2017-01-06' of https://github.com/vinceab/linux into drm...
authorDave Airlie <airlied@redhat.com>
Mon, 23 Jan 2017 00:15:44 +0000 (10:15 +1000)
committerDave Airlie <airlied@redhat.com>
Mon, 23 Jan 2017 00:15:44 +0000 (10:15 +1000)
stih410 cleanup, create fbdev at binding, HQVDP fixes.

* tag 'sti-drm-next-2017-01-06' of https://github.com/vinceab/linux:
  drm/sti: sti_vtg: Handle return NULL error from devm_ioremap_nocache
  drm/sti: remove deprecated sti_vtac.c file
  drm/sti: create fbdev at binding
  drm/sti: update fps debugfs entries
  drm/sti: do not post HQVDP command if no update
  drm/sti: load XP70 firmware only once
  drm/sti: allow audio playback on HDMI even if disabled.

1  2 
drivers/gpu/drm/sti/sti_hdmi.c
drivers/gpu/drm/sti/sti_hqvdp.c

index f0af1ae82ee92e405d9c41a88940fef93607754c,9c0025e9699e58c3376d344800a0cec9192d99c3..5ef1d1fce6d130139becb2df3d028396fc5bf4a9
@@@ -788,6 -788,95 +788,95 @@@ static void sti_hdmi_disable(struct drm
        hdmi->enabled = false;
  }
  
+ /**
+  * sti_hdmi_audio_get_non_coherent_n() - get N parameter for non-coherent
+  * clocks. None-coherent clocks means that audio and TMDS clocks have not the
+  * same source (drifts between clocks). In this case assumption is that CTS is
+  * automatically calculated by hardware.
+  *
+  * @audio_fs: audio frame clock frequency in Hz
+  *
+  * Values computed are based on table described in HDMI specification 1.4b
+  *
+  * Returns n value.
+  */
+ static int sti_hdmi_audio_get_non_coherent_n(unsigned int audio_fs)
+ {
+       unsigned int n;
+       switch (audio_fs) {
+       case 32000:
+               n = 4096;
+               break;
+       case 44100:
+               n = 6272;
+               break;
+       case 48000:
+               n = 6144;
+               break;
+       case 88200:
+               n = 6272 * 2;
+               break;
+       case 96000:
+               n = 6144 * 2;
+               break;
+       case 176400:
+               n = 6272 * 4;
+               break;
+       case 192000:
+               n = 6144 * 4;
+               break;
+       default:
+               /* Not pre-defined, recommended value: 128 * fs / 1000 */
+               n = (audio_fs * 128) / 1000;
+       }
+       return n;
+ }
+ static int hdmi_audio_configure(struct sti_hdmi *hdmi)
+ {
+       int audio_cfg, n;
+       struct hdmi_audio_params *params = &hdmi->audio;
+       struct hdmi_audio_infoframe *info = &params->cea;
+       DRM_DEBUG_DRIVER("\n");
+       if (!hdmi->enabled)
+               return 0;
+       /* update N parameter */
+       n = sti_hdmi_audio_get_non_coherent_n(params->sample_rate);
+       DRM_DEBUG_DRIVER("Audio rate = %d Hz, TMDS clock = %d Hz, n = %d\n",
+                        params->sample_rate, hdmi->mode.clock * 1000, n);
+       hdmi_write(hdmi, n, HDMI_AUDN);
+       /* update HDMI registers according to configuration */
+       audio_cfg = HDMI_AUD_CFG_SPDIF_DIV_2 | HDMI_AUD_CFG_DTS_INVALID |
+                   HDMI_AUD_CFG_ONE_BIT_INVALID;
+       switch (info->channels) {
+       case 8:
+               audio_cfg |= HDMI_AUD_CFG_CH78_VALID;
+       case 6:
+               audio_cfg |= HDMI_AUD_CFG_CH56_VALID;
+       case 4:
+               audio_cfg |= HDMI_AUD_CFG_CH34_VALID | HDMI_AUD_CFG_8CH;
+       case 2:
+               audio_cfg |= HDMI_AUD_CFG_CH12_VALID;
+               break;
+       default:
+               DRM_ERROR("ERROR: Unsupported number of channels (%d)!\n",
+                         info->channels);
+               return -EINVAL;
+       }
+       hdmi_write(hdmi, audio_cfg, HDMI_AUDIO_CFG);
+       return hdmi_audio_infoframe_config(hdmi);
+ }
  static void sti_hdmi_pre_enable(struct drm_bridge *bridge)
  {
        struct sti_hdmi *hdmi = bridge->driver_private;
        if (hdmi_avi_infoframe_config(hdmi))
                DRM_ERROR("Unable to configure AVI infoframe\n");
  
-       /* Program AUDIO infoframe */
-       if (hdmi_audio_infoframe_config(hdmi))
-               DRM_ERROR("Unable to configure AUDIO infoframe\n");
+       if (hdmi->audio.enabled) {
+               if (hdmi_audio_configure(hdmi))
+                       DRM_ERROR("Unable to configure audio\n");
+       } else {
+               hdmi_audio_infoframe_config(hdmi);
+       }
  
        /* Program VS infoframe */
        if (hdmi_vendor_infoframe_config(hdmi))
@@@ -1078,97 -1170,6 +1170,6 @@@ static struct drm_encoder *sti_hdmi_fin
        return NULL;
  }
  
- /**
-  * sti_hdmi_audio_get_non_coherent_n() - get N parameter for non-coherent
-  * clocks. None-coherent clocks means that audio and TMDS clocks have not the
-  * same source (drifts between clocks). In this case assumption is that CTS is
-  * automatically calculated by hardware.
-  *
-  * @audio_fs: audio frame clock frequency in Hz
-  *
-  * Values computed are based on table described in HDMI specification 1.4b
-  *
-  * Returns n value.
-  */
- static int sti_hdmi_audio_get_non_coherent_n(unsigned int audio_fs)
- {
-       unsigned int n;
-       switch (audio_fs) {
-       case 32000:
-               n = 4096;
-               break;
-       case 44100:
-               n = 6272;
-               break;
-       case 48000:
-               n = 6144;
-               break;
-       case 88200:
-               n = 6272 * 2;
-               break;
-       case 96000:
-               n = 6144 * 2;
-               break;
-       case 176400:
-               n = 6272 * 4;
-               break;
-       case 192000:
-               n = 6144 * 4;
-               break;
-       default:
-               /* Not pre-defined, recommended value: 128 * fs / 1000 */
-               n = (audio_fs * 128) / 1000;
-       }
-       return n;
- }
- static int hdmi_audio_configure(struct sti_hdmi *hdmi,
-                               struct hdmi_audio_params *params)
- {
-       int audio_cfg, n;
-       struct hdmi_audio_infoframe *info = &params->cea;
-       DRM_DEBUG_DRIVER("\n");
-       if (!hdmi->enabled)
-               return 0;
-       /* update N parameter */
-       n = sti_hdmi_audio_get_non_coherent_n(params->sample_rate);
-       DRM_DEBUG_DRIVER("Audio rate = %d Hz, TMDS clock = %d Hz, n = %d\n",
-                        params->sample_rate, hdmi->mode.clock * 1000, n);
-       hdmi_write(hdmi, n, HDMI_AUDN);
-       /* update HDMI registers according to configuration */
-       audio_cfg = HDMI_AUD_CFG_SPDIF_DIV_2 | HDMI_AUD_CFG_DTS_INVALID |
-                   HDMI_AUD_CFG_ONE_BIT_INVALID;
-       switch (info->channels) {
-       case 8:
-               audio_cfg |= HDMI_AUD_CFG_CH78_VALID;
-       case 6:
-               audio_cfg |= HDMI_AUD_CFG_CH56_VALID;
-       case 4:
-               audio_cfg |= HDMI_AUD_CFG_CH34_VALID | HDMI_AUD_CFG_8CH;
-       case 2:
-               audio_cfg |= HDMI_AUD_CFG_CH12_VALID;
-               break;
-       default:
-               DRM_ERROR("ERROR: Unsupported number of channels (%d)!\n",
-                         info->channels);
-               return -EINVAL;
-       }
-       hdmi_write(hdmi, audio_cfg, HDMI_AUDIO_CFG);
-       hdmi->audio = *params;
-       return hdmi_audio_infoframe_config(hdmi);
- }
  static void hdmi_audio_shutdown(struct device *dev, void *data)
  {
        struct sti_hdmi *hdmi = dev_get_drvdata(dev);
@@@ -1192,17 -1193,9 +1193,9 @@@ static int hdmi_audio_hw_params(struct 
  {
        struct sti_hdmi *hdmi = dev_get_drvdata(dev);
        int ret;
-       struct hdmi_audio_params audio = {
-               .sample_width = params->sample_width,
-               .sample_rate = params->sample_rate,
-               .cea = params->cea,
-       };
  
        DRM_DEBUG_DRIVER("\n");
  
-       if (!hdmi->enabled)
-               return 0;
        if ((daifmt->fmt != HDMI_I2S) || daifmt->bit_clk_inv ||
            daifmt->frame_clk_inv || daifmt->bit_clk_master ||
            daifmt->frame_clk_master) {
                return -EINVAL;
        }
  
-       audio.enabled = true;
+       hdmi->audio.sample_width = params->sample_width;
+       hdmi->audio.sample_rate = params->sample_rate;
+       hdmi->audio.cea = params->cea;
+       hdmi->audio.enabled = true;
  
-       ret = hdmi_audio_configure(hdmi, &audio);
+       ret = hdmi_audio_configure(hdmi);
        if (ret < 0)
                return ret;
  
@@@ -1308,8 -1305,9 +1305,8 @@@ static int sti_hdmi_bind(struct device 
  
        bridge->driver_private = hdmi;
        bridge->funcs = &sti_hdmi_bridge_funcs;
 -      drm_bridge_attach(drm_dev, bridge);
 +      drm_bridge_attach(encoder, bridge, NULL);
  
 -      encoder->bridge = bridge;
        connector->encoder = encoder;
  
        drm_connector = (struct drm_connector *)connector;
index becf10d255c49634dca6cb95fb6c188fc33d69f5,55cbaea1d49d7b1c9d1f15b90cb3cd65b4ede449..4376fd8a8e529b17ecddffecb21fb6ce9ccf01f0
@@@ -332,6 -332,7 +332,7 @@@ struct sti_hqvdp_cmd 
   * @hqvdp_cmd_paddr:   physical address of hqvdp_cmd
   * @vtg:               vtg for main data path
   * @xp70_initialized:  true if xp70 is already initialized
+  * @vtg_registered:    true if registered to VTG
   */
  struct sti_hqvdp {
        struct device *dev;
        u32 hqvdp_cmd_paddr;
        struct sti_vtg *vtg;
        bool xp70_initialized;
+       bool vtg_registered;
  };
  
  #define to_sti_hqvdp(x) container_of(x, struct sti_hqvdp, plane)
@@@ -771,7 -773,7 +773,7 @@@ static void sti_hqvdp_disable(struct st
                DRM_ERROR("XP70 could not revert to idle\n");
  
        hqvdp->plane.status = STI_PLANE_DISABLED;
-       hqvdp->xp70_initialized = false;
+       hqvdp->vtg_registered = false;
  }
  
  /**
@@@ -1064,10 -1066,11 +1066,11 @@@ static int sti_hqvdp_atomic_check(struc
                return -EINVAL;
        }
  
-       if (!hqvdp->xp70_initialized) {
+       if (!hqvdp->xp70_initialized)
                /* Start HQVDP XP70 coprocessor */
                sti_hqvdp_start_xp70(hqvdp);
  
+       if (!hqvdp->vtg_registered) {
                /* Prevent VTG shutdown */
                if (clk_prepare_enable(hqvdp->clk_pix_main)) {
                        DRM_ERROR("Failed to prepare/enable pix main clk\n");
                        DRM_ERROR("Cannot register VTG notifier\n");
                        return -EINVAL;
                }
+               hqvdp->vtg_registered = true;
        }
  
        DRM_DEBUG_KMS("CRTC:%d (%s) drm plane:%d (%s)\n",
@@@ -1113,6 -1117,21 +1117,21 @@@ static void sti_hqvdp_atomic_update(str
        if (!crtc || !fb)
                return;
  
+       if ((oldstate->fb == state->fb) &&
+           (oldstate->crtc_x == state->crtc_x) &&
+           (oldstate->crtc_y == state->crtc_y) &&
+           (oldstate->crtc_w == state->crtc_w) &&
+           (oldstate->crtc_h == state->crtc_h) &&
+           (oldstate->src_x == state->src_x) &&
+           (oldstate->src_y == state->src_y) &&
+           (oldstate->src_w == state->src_w) &&
+           (oldstate->src_h == state->src_h)) {
+               /* No change since last update, do not post cmd */
+               DRM_DEBUG_DRIVER("No change, not posting cmd\n");
+               plane->status = STI_PLANE_UPDATED;
+               return;
+       }
        mode = &crtc->mode;
        dst_x = state->crtc_x;
        dst_y = state->crtc_y;
        cma_obj = drm_fb_cma_get_gem_obj(fb, 0);
  
        DRM_DEBUG_DRIVER("drm FB:%d format:%.4s phys@:0x%lx\n", fb->base.id,
 -                       (char *)&fb->pixel_format,
 +                       (char *)&fb->format->format,
                         (unsigned long)cma_obj->paddr);
  
        /* Buffer planes address */