Merge tag 'drm/tegra/for-5.6-rc1' of git://anongit.freedesktop.org/tegra/linux into drm-next

drm/tegra: Changes for v5.6-rc1

This contains a small set of mostly fixes and some minor improvements.

Signed-off-by: Dave Airlie <airlied@redhat.com>

From: Thierry Reding <thierry.reding@gmail.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20200111004835.2412858-1-thierry.reding@gmail.com
This commit is contained in:
Dave Airlie
2020-01-15 16:21:22 +10:00
17 changed files with 598 additions and 357 deletions

View File

@@ -2255,7 +2255,7 @@ static void tegra_sor_hdmi_disable(struct drm_encoder *encoder)
if (err < 0)
dev_err(sor->dev, "failed to power off I/O pad: %d\n", err);
pm_runtime_put(sor->dev);
host1x_client_suspend(&sor->client);
}
static void tegra_sor_hdmi_enable(struct drm_encoder *encoder)
@@ -2276,7 +2276,11 @@ static void tegra_sor_hdmi_enable(struct drm_encoder *encoder)
mode = &encoder->crtc->state->adjusted_mode;
pclk = mode->clock * 1000;
pm_runtime_get_sync(sor->dev);
err = host1x_client_resume(&sor->client);
if (err < 0) {
dev_err(sor->dev, "failed to resume: %d\n", err);
return;
}
/* switch to safe parent clock */
err = tegra_sor_set_parent_clock(sor, sor->clk_safe);
@@ -2722,7 +2726,7 @@ static void tegra_sor_dp_disable(struct drm_encoder *encoder)
if (output->panel)
drm_panel_unprepare(output->panel);
pm_runtime_put(sor->dev);
host1x_client_suspend(&sor->client);
}
static void tegra_sor_dp_enable(struct drm_encoder *encoder)
@@ -2742,7 +2746,11 @@ static void tegra_sor_dp_enable(struct drm_encoder *encoder)
mode = &encoder->crtc->state->adjusted_mode;
info = &output->connector.display_info;
pm_runtime_get_sync(sor->dev);
err = host1x_client_resume(&sor->client);
if (err < 0) {
dev_err(sor->dev, "failed to resume: %d\n", err);
return;
}
/* switch to safe parent clock */
err = tegra_sor_set_parent_clock(sor, sor->clk_safe);
@@ -3053,7 +3061,7 @@ static const struct tegra_sor_ops tegra_sor_dp_ops = {
static int tegra_sor_init(struct host1x_client *client)
{
struct drm_device *drm = dev_get_drvdata(client->parent);
struct drm_device *drm = dev_get_drvdata(client->host);
const struct drm_encoder_helper_funcs *helpers = NULL;
struct tegra_sor *sor = host1x_client_to_sor(client);
int connector = DRM_MODE_CONNECTOR_Unknown;
@@ -3190,9 +3198,80 @@ static int tegra_sor_exit(struct host1x_client *client)
return 0;
}
static int tegra_sor_runtime_suspend(struct host1x_client *client)
{
struct tegra_sor *sor = host1x_client_to_sor(client);
struct device *dev = client->dev;
int err;
if (sor->rst) {
err = reset_control_assert(sor->rst);
if (err < 0) {
dev_err(dev, "failed to assert reset: %d\n", err);
return err;
}
reset_control_release(sor->rst);
}
usleep_range(1000, 2000);
clk_disable_unprepare(sor->clk);
pm_runtime_put_sync(dev);
return 0;
}
static int tegra_sor_runtime_resume(struct host1x_client *client)
{
struct tegra_sor *sor = host1x_client_to_sor(client);
struct device *dev = client->dev;
int err;
err = pm_runtime_get_sync(dev);
if (err < 0) {
dev_err(dev, "failed to get runtime PM: %d\n", err);
return err;
}
err = clk_prepare_enable(sor->clk);
if (err < 0) {
dev_err(dev, "failed to enable clock: %d\n", err);
goto put_rpm;
}
usleep_range(1000, 2000);
if (sor->rst) {
err = reset_control_acquire(sor->rst);
if (err < 0) {
dev_err(dev, "failed to acquire reset: %d\n", err);
goto disable_clk;
}
err = reset_control_deassert(sor->rst);
if (err < 0) {
dev_err(dev, "failed to deassert reset: %d\n", err);
goto release_reset;
}
}
return 0;
release_reset:
reset_control_release(sor->rst);
disable_clk:
clk_disable_unprepare(sor->clk);
put_rpm:
pm_runtime_put_sync(dev);
return err;
}
static const struct host1x_client_ops sor_client_ops = {
.init = tegra_sor_init,
.exit = tegra_sor_exit,
.suspend = tegra_sor_runtime_suspend,
.resume = tegra_sor_runtime_resume,
};
static const u8 tegra124_sor_xbar_cfg[5] = {
@@ -3843,10 +3922,9 @@ static int tegra_sor_probe(struct platform_device *pdev)
if (!sor->clk_pad) {
char *name;
err = pm_runtime_get_sync(&pdev->dev);
err = host1x_client_resume(&sor->client);
if (err < 0) {
dev_err(&pdev->dev, "failed to get runtime PM: %d\n",
err);
dev_err(sor->dev, "failed to resume: %d\n", err);
goto remove;
}
@@ -3857,7 +3935,7 @@ static int tegra_sor_probe(struct platform_device *pdev)
}
sor->clk_pad = tegra_clk_sor_pad_register(sor, name);
pm_runtime_put(&pdev->dev);
host1x_client_suspend(&sor->client);
}
if (IS_ERR(sor->clk_pad)) {
@@ -3913,76 +3991,29 @@ static int tegra_sor_remove(struct platform_device *pdev)
return 0;
}
static int tegra_sor_runtime_suspend(struct device *dev)
static int __maybe_unused tegra_sor_suspend(struct device *dev)
{
struct tegra_sor *sor = dev_get_drvdata(dev);
int err;
if (sor->rst) {
err = reset_control_assert(sor->rst);
if (err < 0) {
dev_err(dev, "failed to assert reset: %d\n", err);
return err;
}
reset_control_release(sor->rst);
}
usleep_range(1000, 2000);
clk_disable_unprepare(sor->clk);
return 0;
}
static int tegra_sor_runtime_resume(struct device *dev)
{
struct tegra_sor *sor = dev_get_drvdata(dev);
int err;
err = clk_prepare_enable(sor->clk);
err = tegra_output_suspend(&sor->output);
if (err < 0) {
dev_err(dev, "failed to enable clock: %d\n", err);
dev_err(dev, "failed to suspend output: %d\n", err);
return err;
}
usleep_range(1000, 2000);
if (sor->rst) {
err = reset_control_acquire(sor->rst);
if (err < 0) {
dev_err(dev, "failed to acquire reset: %d\n", err);
clk_disable_unprepare(sor->clk);
return err;
}
err = reset_control_deassert(sor->rst);
if (err < 0) {
dev_err(dev, "failed to deassert reset: %d\n", err);
reset_control_release(sor->rst);
clk_disable_unprepare(sor->clk);
return err;
}
}
return 0;
}
static int tegra_sor_suspend(struct device *dev)
{
struct tegra_sor *sor = dev_get_drvdata(dev);
int err;
if (sor->hdmi_supply) {
err = regulator_disable(sor->hdmi_supply);
if (err < 0)
if (err < 0) {
tegra_output_resume(&sor->output);
return err;
}
}
return 0;
}
static int tegra_sor_resume(struct device *dev)
static int __maybe_unused tegra_sor_resume(struct device *dev)
{
struct tegra_sor *sor = dev_get_drvdata(dev);
int err;
@@ -3993,12 +4024,20 @@ static int tegra_sor_resume(struct device *dev)
return err;
}
err = tegra_output_resume(&sor->output);
if (err < 0) {
dev_err(dev, "failed to resume output: %d\n", err);
if (sor->hdmi_supply)
regulator_disable(sor->hdmi_supply);
return err;
}
return 0;
}
static const struct dev_pm_ops tegra_sor_pm_ops = {
SET_RUNTIME_PM_OPS(tegra_sor_runtime_suspend, tegra_sor_runtime_resume,
NULL)
SET_SYSTEM_SLEEP_PM_OPS(tegra_sor_suspend, tegra_sor_resume)
};