Skip to content

Commit

Permalink
drm/rockchip: Use the helpers for PSR
Browse files Browse the repository at this point in the history
Instead of rolling our own implementation for tracking when PSR should
be [in]active, use the new self refresh helpers to do the heavy lifting.

Changes in v2:
- updated to reflect changes made in the helpers
Changes in v3:
- use the new atomic hooks to inspect crtc state instead of needing conn state (Daniel)
Changes in v4:
- Use Laurent's get_new_connector_for_encoder helper (Daniel)
- Exit vop disable early if it's already off
Changes in v5:
- Rebase on latest drm-misc-next
- Resolve conflict with s/edp_vsc_psr/dp_sdp/ rename
- Resolve conflict with drm_atomic.h header inclusion

Link to v1: https://patchwork.freedesktop.org/patch/msgid/20190228210939.83386-4-sean@poorly.run
Link to v2: https://patchwork.freedesktop.org/patch/msgid/20190326204509.96515-3-sean@poorly.run
Link to v3: https://patchwork.freedesktop.org/patch/msgid/20190502194956.218441-9-sean@poorly.run
Link to v4: https://patchwork.freedesktop.org/patch/msgid/20190508160920.144739-9-sean@poorly.run

Cc: Zain Wang <wzz@rock-chips.com>
Cc: Tomasz Figa <tfiga@chromium.org>
Cc: Daniel Vetter <daniel@ffwll.ch>
Cc: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Tested-by: Heiko Stuebner <heiko@sntech.de>
Reviewed-by: Heiko Stuebner <heiko@sntech.de>
[seanpaul resolved some conflicts with drmP.h work and Helen's async fixes]
Signed-off-by: Sean Paul <seanpaul@chromium.org>
Link: https://patchwork.freedesktop.org/patch/msgid/20190611160844.257498-9-sean@poorly.run
  • Loading branch information
atseanpaul committed Jul 26, 2019
1 parent ad30928 commit 6c836d9
Show file tree
Hide file tree
Showing 9 changed files with 295 additions and 458 deletions.
291 changes: 207 additions & 84 deletions drivers/gpu/drm/bridge/analogix/analogix_dp_core.c

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion drivers/gpu/drm/bridge/analogix/analogix_dp_core.h
Original file line number Diff line number Diff line change
Expand Up @@ -171,8 +171,8 @@ struct analogix_dp_device {
int dpms_mode;
struct gpio_desc *hpd_gpiod;
bool force_hpd;
bool psr_enable;
bool fast_train_enable;
bool psr_supported;

struct mutex panel_lock;
bool panel_is_modeset;
Expand Down
3 changes: 1 addition & 2 deletions drivers/gpu/drm/rockchip/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,7 @@
# Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher.

rockchipdrm-y := rockchip_drm_drv.o rockchip_drm_fb.o \
rockchip_drm_gem.o rockchip_drm_psr.o \
rockchip_drm_vop.o rockchip_vop_reg.o
rockchip_drm_gem.o rockchip_drm_vop.o rockchip_vop_reg.o
rockchipdrm-$(CONFIG_DRM_FBDEV_EMULATION) += rockchip_drm_fbdev.o

rockchipdrm-$(CONFIG_ROCKCHIP_ANALOGIX_DP) += analogix_dp-rockchip.o
Expand Down
106 changes: 56 additions & 50 deletions drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,15 @@
#include <video/of_videomode.h>
#include <video/videomode.h>

#include <drm/drm_atomic.h>
#include <drm/drm_atomic_helper.h>
#include <drm/bridge/analogix_dp.h>
#include <drm/drm_dp_helper.h>
#include <drm/drm_of.h>
#include <drm/drm_panel.h>
#include <drm/drm_probe_helper.h>

#include "rockchip_drm_drv.h"
#include "rockchip_drm_psr.h"
#include "rockchip_drm_vop.h"

#define RK3288_GRF_SOC_CON6 0x25c
Expand Down Expand Up @@ -71,29 +72,6 @@ struct rockchip_dp_device {
struct analogix_dp_plat_data plat_data;
};

static int analogix_dp_psr_set(struct drm_encoder *encoder, bool enabled)
{
struct rockchip_dp_device *dp = to_dp(encoder);
int ret;

if (!analogix_dp_psr_enabled(dp->adp))
return 0;

DRM_DEV_DEBUG(dp->dev, "%s PSR...\n", enabled ? "Entry" : "Exit");

ret = rockchip_drm_wait_vact_end(dp->encoder.crtc,
PSR_WAIT_LINE_FLAG_TIMEOUT_MS);
if (ret) {
DRM_DEV_ERROR(dp->dev, "line flag interrupt did not arrive\n");
return -ETIMEDOUT;
}

if (enabled)
return analogix_dp_enable_psr(dp->adp);
else
return analogix_dp_disable_psr(dp->adp);
}

static int rockchip_dp_pre_init(struct rockchip_dp_device *dp)
{
reset_control_assert(dp->rst);
Expand Down Expand Up @@ -124,21 +102,9 @@ static int rockchip_dp_poweron_start(struct analogix_dp_plat_data *plat_data)
return ret;
}

static int rockchip_dp_poweron_end(struct analogix_dp_plat_data *plat_data)
{
struct rockchip_dp_device *dp = to_dp(plat_data);

return rockchip_drm_psr_inhibit_put(&dp->encoder);
}

static int rockchip_dp_powerdown(struct analogix_dp_plat_data *plat_data)
{
struct rockchip_dp_device *dp = to_dp(plat_data);
int ret;

ret = rockchip_drm_psr_inhibit_get(&dp->encoder);
if (ret != 0)
return ret;

clk_disable_unprepare(dp->pclk);

Expand Down Expand Up @@ -178,12 +144,42 @@ static void rockchip_dp_drm_encoder_mode_set(struct drm_encoder *encoder,
/* do nothing */
}

static void rockchip_dp_drm_encoder_enable(struct drm_encoder *encoder)
static
struct drm_crtc *rockchip_dp_drm_get_new_crtc(struct drm_encoder *encoder,
struct drm_atomic_state *state)
{
struct drm_connector *connector;
struct drm_connector_state *conn_state;

connector = drm_atomic_get_new_connector_for_encoder(state, encoder);
if (!connector)
return NULL;

conn_state = drm_atomic_get_new_connector_state(state, connector);
if (!conn_state)
return NULL;

return conn_state->crtc;
}

static void rockchip_dp_drm_encoder_enable(struct drm_encoder *encoder,
struct drm_atomic_state *state)
{
struct rockchip_dp_device *dp = to_dp(encoder);
struct drm_crtc *crtc;
struct drm_crtc_state *old_crtc_state;
int ret;
u32 val;

crtc = rockchip_dp_drm_get_new_crtc(encoder, state);
if (!crtc)
return;

old_crtc_state = drm_atomic_get_old_crtc_state(state, crtc);
/* Coming back from self refresh, nothing to do */
if (old_crtc_state && old_crtc_state->self_refresh_active)
return;

ret = drm_of_encoder_active_endpoint_id(dp->dev->of_node, encoder);
if (ret < 0)
return;
Expand All @@ -208,9 +204,27 @@ static void rockchip_dp_drm_encoder_enable(struct drm_encoder *encoder)
clk_disable_unprepare(dp->grfclk);
}

static void rockchip_dp_drm_encoder_nop(struct drm_encoder *encoder)
static void rockchip_dp_drm_encoder_disable(struct drm_encoder *encoder,
struct drm_atomic_state *state)
{
/* do nothing */
struct rockchip_dp_device *dp = to_dp(encoder);
struct drm_crtc *crtc;
struct drm_crtc_state *new_crtc_state = NULL;
int ret;

crtc = rockchip_dp_drm_get_new_crtc(encoder, state);
/* No crtc means we're doing a full shutdown */
if (!crtc)
return;

new_crtc_state = drm_atomic_get_new_crtc_state(state, crtc);
/* If we're not entering self-refresh, no need to wait for vact */
if (!new_crtc_state || !new_crtc_state->self_refresh_active)
return;

ret = rockchip_drm_wait_vact_end(crtc, PSR_WAIT_LINE_FLAG_TIMEOUT_MS);
if (ret)
DRM_DEV_ERROR(dp->dev, "line flag irq timed out\n");
}

static int
Expand Down Expand Up @@ -239,8 +253,8 @@ rockchip_dp_drm_encoder_atomic_check(struct drm_encoder *encoder,
static struct drm_encoder_helper_funcs rockchip_dp_encoder_helper_funcs = {
.mode_fixup = rockchip_dp_drm_encoder_mode_fixup,
.mode_set = rockchip_dp_drm_encoder_mode_set,
.enable = rockchip_dp_drm_encoder_enable,
.disable = rockchip_dp_drm_encoder_nop,
.atomic_enable = rockchip_dp_drm_encoder_enable,
.atomic_disable = rockchip_dp_drm_encoder_disable,
.atomic_check = rockchip_dp_drm_encoder_atomic_check,
};

Expand Down Expand Up @@ -332,23 +346,16 @@ static int rockchip_dp_bind(struct device *dev, struct device *master,

dp->plat_data.dev_type = dp->data->chip_type;
dp->plat_data.power_on_start = rockchip_dp_poweron_start;
dp->plat_data.power_on_end = rockchip_dp_poweron_end;
dp->plat_data.power_off = rockchip_dp_powerdown;
dp->plat_data.get_modes = rockchip_dp_get_modes;

ret = rockchip_drm_psr_register(&dp->encoder, analogix_dp_psr_set);
if (ret < 0)
goto err_cleanup_encoder;

dp->adp = analogix_dp_bind(dev, dp->drm_dev, &dp->plat_data);
if (IS_ERR(dp->adp)) {
ret = PTR_ERR(dp->adp);
goto err_unreg_psr;
goto err_cleanup_encoder;
}

return 0;
err_unreg_psr:
rockchip_drm_psr_unregister(&dp->encoder);
err_cleanup_encoder:
dp->encoder.funcs->destroy(&dp->encoder);
return ret;
Expand All @@ -360,7 +367,6 @@ static void rockchip_dp_unbind(struct device *dev, struct device *master,
struct rockchip_dp_device *dp = dev_get_drvdata(dev);

analogix_dp_unbind(dp->adp);
rockchip_drm_psr_unregister(&dp->encoder);
dp->encoder.funcs->destroy(&dp->encoder);

dp->adp = ERR_PTR(-ENODEV);
Expand Down
5 changes: 0 additions & 5 deletions drivers/gpu/drm/rockchip/rockchip_drm_fb.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
#include "rockchip_drm_drv.h"
#include "rockchip_drm_fb.h"
#include "rockchip_drm_gem.h"
#include "rockchip_drm_psr.h"

static const struct drm_framebuffer_funcs rockchip_drm_fb_funcs = {
.destroy = drm_gem_fb_destroy,
Expand Down Expand Up @@ -111,17 +110,13 @@ rockchip_atomic_helper_commit_tail_rpm(struct drm_atomic_state *old_state)
{
struct drm_device *dev = old_state->dev;

rockchip_drm_psr_inhibit_get_state(old_state);

drm_atomic_helper_commit_modeset_disables(dev, old_state);

drm_atomic_helper_commit_modeset_enables(dev, old_state);

drm_atomic_helper_commit_planes(dev, old_state,
DRM_PLANE_COMMIT_ACTIVE_ONLY);

rockchip_drm_psr_inhibit_put_state(old_state);

drm_atomic_helper_commit_hw_done(old_state);

drm_atomic_helper_wait_for_vblanks(dev, old_state);
Expand Down
Loading

0 comments on commit 6c836d9

Please sign in to comment.