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:
@@ -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)
|
||||
};
|
||||
|
||||
|
Reference in New Issue
Block a user