mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-08-23 09:19:51 +00:00
drm/tegra: Fixes for v4.8-rc4
This contains one fix for DSI runtime power management support that was introduced in v4.8-rc1. This is slightly more elaborate than I would've wished, but there are a few corner cases that needed fixing. -----BEGIN PGP SIGNATURE----- Version: GnuPG v2 iQIwBAABCAAaBQJXvaiSExx0cmVkaW5nQG52aWRpYS5jb20ACgkQ3SOs138+s6Hv jg/6AnYkczQYraAb8Oy2YO3dIfz3r0TLGEEnY3AKudur867mNG0V59JcUXHQYKin FL7z4iIEx21RAtA9gUEc7xz9gitXP2W/GqRG6v1u0wLn+GS72TuNZCsqUVPQ6Glr yg0uLPoxsFyLa3rsTgif5jXxpsbSd6OV2NdkpImqt1EQLaOWYSNqLLq/YNvMsvCK QivRvvJEYznIyJayIN/PDekfYY3L5esMQNdDEI9jJKdJrTykQThx2eOIbsgY4MyC sdp/h9R23O1ZFvfGONrQHOOzDGumhDJtsRfew+q9JoBaOOgztk2LmPpRZFQsIrmV 1rv1ahQh3boPWw3cSoQMCE8E3Eu2wD/zNrWYbKyhjChx/HTaSPyQGwk0v2WycizA KnNo3eQOTT/5Wb/KvhCaef4Q+yc4LbcAC8T3pkYyGVy+yhUOXr4SGOQLh4Za0Sag uaM20wk3TPYAiyUKZFE7RZ1WHtOp56gOIHbS5eV5ppuR2lmoCh4vK5yCojaz4gww DAHzldegReurS3du613KrV63lue1r3nwX1f0kKDsWd4yN0FH/74g/QC1jXKqJmmk ZevqKCQ1eoaPyOMQI2G0rvRL4B63s800oHO2L760e5SdbM1/Oraxzc+FobGZz9KW Y55SyNnn3QT5HcH6dntmisnuSbZVXVNonEJaPJWFLH/ChgI= =lyq1 -----END PGP SIGNATURE----- Merge tag 'drm/tegra/for-4.8-rc4' of git://anongit.freedesktop.org/tegra/linux into drm-fixes drm/tegra: Fixes for v4.8-rc4 This contains one fix for DSI runtime power management support that was introduced in v4.8-rc1. This is slightly more elaborate than I would've wished, but there are a few corner cases that needed fixing. * tag 'drm/tegra/for-4.8-rc4' of git://anongit.freedesktop.org/tegra/linux: drm/tegra: dsi: Enhance runtime power management
This commit is contained in:
commit
30bffd1b44
3 changed files with 70 additions and 40 deletions
|
@ -840,6 +840,21 @@ static const struct drm_encoder_funcs tegra_dsi_encoder_funcs = {
|
|||
.destroy = tegra_output_encoder_destroy,
|
||||
};
|
||||
|
||||
static void tegra_dsi_unprepare(struct tegra_dsi *dsi)
|
||||
{
|
||||
int err;
|
||||
|
||||
if (dsi->slave)
|
||||
tegra_dsi_unprepare(dsi->slave);
|
||||
|
||||
err = tegra_mipi_disable(dsi->mipi);
|
||||
if (err < 0)
|
||||
dev_err(dsi->dev, "failed to disable MIPI calibration: %d\n",
|
||||
err);
|
||||
|
||||
pm_runtime_put(dsi->dev);
|
||||
}
|
||||
|
||||
static void tegra_dsi_encoder_disable(struct drm_encoder *encoder)
|
||||
{
|
||||
struct tegra_output *output = encoder_to_output(encoder);
|
||||
|
@ -876,7 +891,26 @@ static void tegra_dsi_encoder_disable(struct drm_encoder *encoder)
|
|||
|
||||
tegra_dsi_disable(dsi);
|
||||
|
||||
pm_runtime_put(dsi->dev);
|
||||
tegra_dsi_unprepare(dsi);
|
||||
}
|
||||
|
||||
static void tegra_dsi_prepare(struct tegra_dsi *dsi)
|
||||
{
|
||||
int err;
|
||||
|
||||
pm_runtime_get_sync(dsi->dev);
|
||||
|
||||
err = tegra_mipi_enable(dsi->mipi);
|
||||
if (err < 0)
|
||||
dev_err(dsi->dev, "failed to enable MIPI calibration: %d\n",
|
||||
err);
|
||||
|
||||
err = tegra_dsi_pad_calibrate(dsi);
|
||||
if (err < 0)
|
||||
dev_err(dsi->dev, "MIPI calibration failed: %d\n", err);
|
||||
|
||||
if (dsi->slave)
|
||||
tegra_dsi_prepare(dsi->slave);
|
||||
}
|
||||
|
||||
static void tegra_dsi_encoder_enable(struct drm_encoder *encoder)
|
||||
|
@ -887,13 +921,8 @@ static void tegra_dsi_encoder_enable(struct drm_encoder *encoder)
|
|||
struct tegra_dsi *dsi = to_dsi(output);
|
||||
struct tegra_dsi_state *state;
|
||||
u32 value;
|
||||
int err;
|
||||
|
||||
pm_runtime_get_sync(dsi->dev);
|
||||
|
||||
err = tegra_dsi_pad_calibrate(dsi);
|
||||
if (err < 0)
|
||||
dev_err(dsi->dev, "MIPI calibration failed: %d\n", err);
|
||||
tegra_dsi_prepare(dsi);
|
||||
|
||||
state = tegra_dsi_get_state(dsi);
|
||||
|
||||
|
|
|
@ -242,20 +242,6 @@ struct tegra_mipi_device *tegra_mipi_request(struct device *device)
|
|||
dev->pads = args.args[0];
|
||||
dev->device = device;
|
||||
|
||||
mutex_lock(&dev->mipi->lock);
|
||||
|
||||
if (dev->mipi->usage_count++ == 0) {
|
||||
err = tegra_mipi_power_up(dev->mipi);
|
||||
if (err < 0) {
|
||||
dev_err(dev->mipi->dev,
|
||||
"failed to power up MIPI bricks: %d\n",
|
||||
err);
|
||||
return ERR_PTR(err);
|
||||
}
|
||||
}
|
||||
|
||||
mutex_unlock(&dev->mipi->lock);
|
||||
|
||||
return dev;
|
||||
|
||||
put:
|
||||
|
@ -270,30 +256,43 @@ EXPORT_SYMBOL(tegra_mipi_request);
|
|||
|
||||
void tegra_mipi_free(struct tegra_mipi_device *device)
|
||||
{
|
||||
int err;
|
||||
|
||||
mutex_lock(&device->mipi->lock);
|
||||
|
||||
if (--device->mipi->usage_count == 0) {
|
||||
err = tegra_mipi_power_down(device->mipi);
|
||||
if (err < 0) {
|
||||
/*
|
||||
* Not much that can be done here, so an error message
|
||||
* will have to do.
|
||||
*/
|
||||
dev_err(device->mipi->dev,
|
||||
"failed to power down MIPI bricks: %d\n",
|
||||
err);
|
||||
}
|
||||
}
|
||||
|
||||
mutex_unlock(&device->mipi->lock);
|
||||
|
||||
platform_device_put(device->pdev);
|
||||
kfree(device);
|
||||
}
|
||||
EXPORT_SYMBOL(tegra_mipi_free);
|
||||
|
||||
int tegra_mipi_enable(struct tegra_mipi_device *dev)
|
||||
{
|
||||
int err = 0;
|
||||
|
||||
mutex_lock(&dev->mipi->lock);
|
||||
|
||||
if (dev->mipi->usage_count++ == 0)
|
||||
err = tegra_mipi_power_up(dev->mipi);
|
||||
|
||||
mutex_unlock(&dev->mipi->lock);
|
||||
|
||||
return err;
|
||||
|
||||
}
|
||||
EXPORT_SYMBOL(tegra_mipi_enable);
|
||||
|
||||
int tegra_mipi_disable(struct tegra_mipi_device *dev)
|
||||
{
|
||||
int err = 0;
|
||||
|
||||
mutex_lock(&dev->mipi->lock);
|
||||
|
||||
if (--dev->mipi->usage_count == 0)
|
||||
err = tegra_mipi_power_down(dev->mipi);
|
||||
|
||||
mutex_unlock(&dev->mipi->lock);
|
||||
|
||||
return err;
|
||||
|
||||
}
|
||||
EXPORT_SYMBOL(tegra_mipi_disable);
|
||||
|
||||
static int tegra_mipi_wait(struct tegra_mipi *mipi)
|
||||
{
|
||||
unsigned long timeout = jiffies + msecs_to_jiffies(250);
|
||||
|
|
|
@ -304,6 +304,8 @@ struct tegra_mipi_device;
|
|||
|
||||
struct tegra_mipi_device *tegra_mipi_request(struct device *device);
|
||||
void tegra_mipi_free(struct tegra_mipi_device *device);
|
||||
int tegra_mipi_enable(struct tegra_mipi_device *device);
|
||||
int tegra_mipi_disable(struct tegra_mipi_device *device);
|
||||
int tegra_mipi_calibrate(struct tegra_mipi_device *device);
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in a new issue