Merge remote-tracking branch 'drm/drm-next' into drm-misc-next
authorMaarten Lankhorst <maarten.lankhorst@linux.intel.com>
Wed, 19 Jun 2019 10:32:13 +0000 (12:32 +0200)
committerMaarten Lankhorst <maarten.lankhorst@linux.intel.com>
Wed, 19 Jun 2019 10:32:13 +0000 (12:32 +0200)
remove-fbcon-notifiers topic branch is based on rc4, so we need a fresh
backmerge of drm-next to pull it in.

Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
1  2 
drivers/gpu/drm/rockchip/cdn-dp-reg.c
drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
drivers/gpu/drm/rockchip/rockchip_drm_vop.c

index 0a2aebecc151ea8ce7c99ae9abeb4966b7217328,66b2d4466eabc18d7cbaeac5af0beffc0a4e30b3..077c870219081afc4954bea1589c0e54e3539c12
@@@ -1,15 -1,7 +1,7 @@@
+ // SPDX-License-Identifier: GPL-2.0-only
  /*
   * Copyright (C) Fuzhou Rockchip Electronics Co.Ltd
   * Author: Chris Zhong <zyw@rock-chips.com>
-  *
-  * This software is licensed under the terms of the GNU General Public
-  * License version 2, as published by the Free Software Foundation, and
-  * may be copied, distributed, and modified under those terms.
-  *
-  * This program is distributed in the hope that it will be useful,
-  * but WITHOUT ANY WARRANTY; without even the implied warranty of
-  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-  * GNU General Public License for more details.
   */
  
  #include <linux/clk.h>
@@@ -543,7 -535,7 +535,7 @@@ static int cdn_dp_get_training_status(s
        if (ret)
                goto err_get_training_status;
  
 -      dp->link.rate = status[0];
 +      dp->link.rate = drm_dp_bw_code_to_link_rate(status[0]);
        dp->link.num_lanes = status[1];
  
  err_get_training_status:
@@@ -647,7 -639,7 +639,7 @@@ int cdn_dp_config_video(struct cdn_dp_d
        bit_per_pix = (video->color_fmt == YCBCR_4_2_2) ?
                      (video->color_depth * 2) : (video->color_depth * 3);
  
 -      link_rate = drm_dp_bw_code_to_link_rate(dp->link.rate) / 1000;
 +      link_rate = dp->link.rate / 1000;
  
        ret = cdn_dp_reg_write(dp, BND_HSYNC2VSYNC, VIF_BYPASS_INTERLACE);
        if (ret)
index d7629ffd026ab814cdff1003eea036af4c89ad6b,40f3a4c538483547fd10d60f1200d8bd96be411c..cdc304d4cd02b1edcfd310e19da12b5b150f0b2f
@@@ -1,10 -1,6 +1,6 @@@
+ // SPDX-License-Identifier: GPL-2.0-or-later
  /*
   * Copyright (c) 2014, Fuzhou Rockchip Electronics Co., Ltd
-  *
-  * This program is free software; you can redistribute it and/or modify
-  * it under the terms of the GNU General Public License as published by
-  * the Free Software Foundation; either version 2 of the License, or
-  * (at your option) any later version.
   */
  
  #include <linux/clk.h>
  #include "rockchip_drm_drv.h"
  #include "rockchip_drm_vop.h"
  
 +#define RK3228_GRF_SOC_CON2           0x0408
 +#define RK3228_HDMI_SDAIN_MSK         BIT(14)
 +#define RK3228_HDMI_SCLIN_MSK         BIT(13)
 +#define RK3228_GRF_SOC_CON6           0x0418
 +#define RK3228_HDMI_HPD_VSEL          BIT(6)
 +#define RK3228_HDMI_SDA_VSEL          BIT(5)
 +#define RK3228_HDMI_SCL_VSEL          BIT(4)
 +
  #define RK3288_GRF_SOC_CON6           0x025C
  #define RK3288_HDMI_LCDC_SEL          BIT(4)
  #define RK3328_GRF_SOC_CON2           0x0408
@@@ -333,25 -321,6 +329,25 @@@ static void dw_hdmi_rockchip_genphy_dis
        phy_power_off(hdmi->phy);
  }
  
 +static void dw_hdmi_rk3228_setup_hpd(struct dw_hdmi *dw_hdmi, void *data)
 +{
 +      struct rockchip_hdmi *hdmi = (struct rockchip_hdmi *)data;
 +
 +      dw_hdmi_phy_setup_hpd(dw_hdmi, data);
 +
 +      regmap_write(hdmi->regmap,
 +              RK3228_GRF_SOC_CON6,
 +              HIWORD_UPDATE(RK3228_HDMI_HPD_VSEL | RK3228_HDMI_SDA_VSEL |
 +                            RK3228_HDMI_SCL_VSEL,
 +                            RK3228_HDMI_HPD_VSEL | RK3228_HDMI_SDA_VSEL |
 +                            RK3228_HDMI_SCL_VSEL));
 +
 +      regmap_write(hdmi->regmap,
 +              RK3228_GRF_SOC_CON2,
 +              HIWORD_UPDATE(RK3228_HDMI_SDAIN_MSK | RK3228_HDMI_SCLIN_MSK,
 +                            RK3228_HDMI_SDAIN_MSK | RK3228_HDMI_SCLIN_MSK));
 +}
 +
  static enum drm_connector_status
  dw_hdmi_rk3328_read_hpd(struct dw_hdmi *dw_hdmi, void *data)
  {
@@@ -397,29 -366,6 +393,29 @@@ static void dw_hdmi_rk3328_setup_hpd(st
                              RK3328_HDMI_HPD_IOE));
  }
  
 +static const struct dw_hdmi_phy_ops rk3228_hdmi_phy_ops = {
 +      .init           = dw_hdmi_rockchip_genphy_init,
 +      .disable        = dw_hdmi_rockchip_genphy_disable,
 +      .read_hpd       = dw_hdmi_phy_read_hpd,
 +      .update_hpd     = dw_hdmi_phy_update_hpd,
 +      .setup_hpd      = dw_hdmi_rk3228_setup_hpd,
 +};
 +
 +static struct rockchip_hdmi_chip_data rk3228_chip_data = {
 +      .lcdsel_grf_reg = -1,
 +};
 +
 +static const struct dw_hdmi_plat_data rk3228_hdmi_drv_data = {
 +      .mode_valid = dw_hdmi_rockchip_mode_valid,
 +      .mpll_cfg = rockchip_mpll_cfg,
 +      .cur_ctr = rockchip_cur_ctr,
 +      .phy_config = rockchip_phy_config,
 +      .phy_data = &rk3228_chip_data,
 +      .phy_ops = &rk3228_hdmi_phy_ops,
 +      .phy_name = "inno_dw_hdmi_phy2",
 +      .phy_force_vendor = true,
 +};
 +
  static struct rockchip_hdmi_chip_data rk3288_chip_data = {
        .lcdsel_grf_reg = RK3288_GRF_SOC_CON6,
        .lcdsel_big = HIWORD_UPDATE(0, RK3288_HDMI_LCDC_SEL),
@@@ -472,9 -418,6 +468,9 @@@ static const struct dw_hdmi_plat_data r
  };
  
  static const struct of_device_id dw_hdmi_rockchip_dt_ids[] = {
 +      { .compatible = "rockchip,rk3228-dw-hdmi",
 +        .data = &rk3228_hdmi_drv_data
 +      },
        { .compatible = "rockchip,rk3288-dw-hdmi",
          .data = &rk3288_hdmi_drv_data
        },
index 2a5e2c67b02a240ea581bc2552f750dff96ab05b,e4580d8f21e1e858e43ff3d9e1f51d6607622889..09a790c2f3a1ead32cd7360b645eca62a1d2f1a0
@@@ -1,15 -1,7 +1,7 @@@
+ // SPDX-License-Identifier: GPL-2.0-only
  /*
   * Copyright (C) Fuzhou Rockchip Electronics Co.Ltd
   * Author:Mark Yao <mark.yao@rock-chips.com>
-  *
-  * This software is licensed under the terms of the GNU General Public
-  * License version 2, as published by the Free Software Foundation, and
-  * may be copied, distributed, and modified under those terms.
-  *
-  * This program is distributed in the hope that it will be useful,
-  * but WITHOUT ANY WARRANTY; without even the implied warranty of
-  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-  * GNU General Public License for more details.
   */
  
  #include <drm/drm.h>
@@@ -919,29 -911,17 +911,17 @@@ static void vop_plane_atomic_async_upda
                                          struct drm_plane_state *new_state)
  {
        struct vop *vop = to_vop(plane->state->crtc);
-       struct drm_plane_state *plane_state;
-       plane_state = plane->funcs->atomic_duplicate_state(plane);
-       plane_state->crtc_x = new_state->crtc_x;
-       plane_state->crtc_y = new_state->crtc_y;
-       plane_state->crtc_h = new_state->crtc_h;
-       plane_state->crtc_w = new_state->crtc_w;
-       plane_state->src_x = new_state->src_x;
-       plane_state->src_y = new_state->src_y;
-       plane_state->src_h = new_state->src_h;
-       plane_state->src_w = new_state->src_w;
-       if (plane_state->fb != new_state->fb)
-               drm_atomic_set_fb_for_plane(plane_state, new_state->fb);
-       swap(plane_state, plane->state);
-       if (plane->state->fb && plane->state->fb != new_state->fb) {
-               drm_framebuffer_get(plane->state->fb);
-               WARN_ON(drm_crtc_vblank_get(plane->state->crtc) != 0);
-               drm_flip_work_queue(&vop->fb_unref_work, plane->state->fb);
-               set_bit(VOP_PENDING_FB_UNREF, &vop->pending);
-       }
+       struct drm_framebuffer *old_fb = plane->state->fb;
+       plane->state->crtc_x = new_state->crtc_x;
+       plane->state->crtc_y = new_state->crtc_y;
+       plane->state->crtc_h = new_state->crtc_h;
+       plane->state->crtc_w = new_state->crtc_w;
+       plane->state->src_x = new_state->src_x;
+       plane->state->src_y = new_state->src_y;
+       plane->state->src_h = new_state->src_h;
+       plane->state->src_w = new_state->src_w;
+       swap(plane->state->fb, new_state->fb);
  
        if (vop->is_enabled) {
                rockchip_drm_psr_inhibit_get_state(new_state->state);
                vop_cfg_done(vop);
                spin_unlock(&vop->reg_lock);
                rockchip_drm_psr_inhibit_put_state(new_state->state);
-       }
  
-       plane->funcs->atomic_destroy_state(plane, plane_state);
+               /*
+                * A scanout can still be occurring, so we can't drop the
+                * reference to the old framebuffer. To solve this we get a
+                * reference to old_fb and set a worker to release it later.
+                * FIXME: if we perform 500 async_update calls before the
+                * vblank, then we can have 500 different framebuffers waiting
+                * to be released.
+                */
+               if (old_fb && plane->state->fb != old_fb) {
+                       drm_framebuffer_get(old_fb);
+                       WARN_ON(drm_crtc_vblank_get(plane->state->crtc) != 0);
+                       drm_flip_work_queue(&vop->fb_unref_work, old_fb);
+                       set_bit(VOP_PENDING_FB_UNREF, &vop->pending);
+               }
+       }
  }
  
  static const struct drm_plane_helper_funcs plane_helper_funcs = {
@@@ -1013,8 -1006,7 +1006,8 @@@ static bool vop_crtc_mode_fixup(struct 
        struct vop *vop = to_vop(crtc);
  
        adjusted_mode->clock =
 -              clk_round_rate(vop->dclk, mode->clock * 1000) / 1000;
 +              DIV_ROUND_UP(clk_round_rate(vop->dclk,
 +                                          adjusted_mode->clock * 1000), 1000);
  
        return true;
  }