mirror of
https://github.com/raspberrypi/linux.git
synced 2025-12-06 10:00:17 +00:00
drm: rcar-du: Add quirk for H3 ES1.x pclk workaround
[ Upstream commit 4f548bc48a ]
rcar_du_crtc.c does a soc_device_match() in
rcar_du_crtc_set_display_timing() to find out if the SoC is H3 ES1.x, and
if so, apply a workaround.
We will need another H3 ES1.x check in the following patch, so rather than
adding more soc_device_match() calls, let's add a rcar_du_device_info
entry for the ES1, and a quirk flag,
RCAR_DU_QUIRK_H3_ES1_PCLK_STABILITY, for the workaround.
Signed-off-by: Tomi Valkeinen <tomi.valkeinen+renesas@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:
committed by
Greg Kroah-Hartman
parent
25a6499b1a
commit
afc9da1352
@@ -10,7 +10,6 @@
|
|||||||
#include <linux/clk.h>
|
#include <linux/clk.h>
|
||||||
#include <linux/mutex.h>
|
#include <linux/mutex.h>
|
||||||
#include <linux/platform_device.h>
|
#include <linux/platform_device.h>
|
||||||
#include <linux/sys_soc.h>
|
|
||||||
|
|
||||||
#include <drm/drm_atomic.h>
|
#include <drm/drm_atomic.h>
|
||||||
#include <drm/drm_atomic_helper.h>
|
#include <drm/drm_atomic_helper.h>
|
||||||
@@ -204,11 +203,6 @@ static void rcar_du_escr_divider(struct clk *clk, unsigned long target,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct soc_device_attribute rcar_du_r8a7795_es1[] = {
|
|
||||||
{ .soc_id = "r8a7795", .revision = "ES1.*" },
|
|
||||||
{ /* sentinel */ }
|
|
||||||
};
|
|
||||||
|
|
||||||
static void rcar_du_crtc_set_display_timing(struct rcar_du_crtc *rcrtc)
|
static void rcar_du_crtc_set_display_timing(struct rcar_du_crtc *rcrtc)
|
||||||
{
|
{
|
||||||
const struct drm_display_mode *mode = &rcrtc->crtc.state->adjusted_mode;
|
const struct drm_display_mode *mode = &rcrtc->crtc.state->adjusted_mode;
|
||||||
@@ -238,7 +232,7 @@ static void rcar_du_crtc_set_display_timing(struct rcar_du_crtc *rcrtc)
|
|||||||
* no post-divider when a display PLL is present (as shown by
|
* no post-divider when a display PLL is present (as shown by
|
||||||
* the workaround breaking HDMI output on M3-W during testing).
|
* the workaround breaking HDMI output on M3-W during testing).
|
||||||
*/
|
*/
|
||||||
if (soc_device_match(rcar_du_r8a7795_es1)) {
|
if (rcdu->info->quirks & RCAR_DU_QUIRK_H3_ES1_PCLK_STABILITY) {
|
||||||
target *= 2;
|
target *= 2;
|
||||||
div = 1;
|
div = 1;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,6 +16,7 @@
|
|||||||
#include <linux/platform_device.h>
|
#include <linux/platform_device.h>
|
||||||
#include <linux/pm.h>
|
#include <linux/pm.h>
|
||||||
#include <linux/slab.h>
|
#include <linux/slab.h>
|
||||||
|
#include <linux/sys_soc.h>
|
||||||
#include <linux/wait.h>
|
#include <linux/wait.h>
|
||||||
|
|
||||||
#include <drm/drm_atomic_helper.h>
|
#include <drm/drm_atomic_helper.h>
|
||||||
@@ -386,6 +387,42 @@ static const struct rcar_du_device_info rcar_du_r8a7795_info = {
|
|||||||
.dpll_mask = BIT(2) | BIT(1),
|
.dpll_mask = BIT(2) | BIT(1),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const struct rcar_du_device_info rcar_du_r8a7795_es1_info = {
|
||||||
|
.gen = 3,
|
||||||
|
.features = RCAR_DU_FEATURE_CRTC_IRQ
|
||||||
|
| RCAR_DU_FEATURE_CRTC_CLOCK
|
||||||
|
| RCAR_DU_FEATURE_VSP1_SOURCE
|
||||||
|
| RCAR_DU_FEATURE_INTERLACED
|
||||||
|
| RCAR_DU_FEATURE_TVM_SYNC,
|
||||||
|
.quirks = RCAR_DU_QUIRK_H3_ES1_PCLK_STABILITY,
|
||||||
|
.channels_mask = BIT(3) | BIT(2) | BIT(1) | BIT(0),
|
||||||
|
.routes = {
|
||||||
|
/*
|
||||||
|
* R8A7795 has one RGB output, two HDMI outputs and one
|
||||||
|
* LVDS output.
|
||||||
|
*/
|
||||||
|
[RCAR_DU_OUTPUT_DPAD0] = {
|
||||||
|
.possible_crtcs = BIT(3),
|
||||||
|
.port = 0,
|
||||||
|
},
|
||||||
|
[RCAR_DU_OUTPUT_HDMI0] = {
|
||||||
|
.possible_crtcs = BIT(1),
|
||||||
|
.port = 1,
|
||||||
|
},
|
||||||
|
[RCAR_DU_OUTPUT_HDMI1] = {
|
||||||
|
.possible_crtcs = BIT(2),
|
||||||
|
.port = 2,
|
||||||
|
},
|
||||||
|
[RCAR_DU_OUTPUT_LVDS0] = {
|
||||||
|
.possible_crtcs = BIT(0),
|
||||||
|
.port = 3,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
.num_lvds = 1,
|
||||||
|
.num_rpf = 5,
|
||||||
|
.dpll_mask = BIT(2) | BIT(1),
|
||||||
|
};
|
||||||
|
|
||||||
static const struct rcar_du_device_info rcar_du_r8a7796_info = {
|
static const struct rcar_du_device_info rcar_du_r8a7796_info = {
|
||||||
.gen = 3,
|
.gen = 3,
|
||||||
.features = RCAR_DU_FEATURE_CRTC_IRQ
|
.features = RCAR_DU_FEATURE_CRTC_IRQ
|
||||||
@@ -554,6 +591,11 @@ static const struct of_device_id rcar_du_of_table[] = {
|
|||||||
|
|
||||||
MODULE_DEVICE_TABLE(of, rcar_du_of_table);
|
MODULE_DEVICE_TABLE(of, rcar_du_of_table);
|
||||||
|
|
||||||
|
static const struct soc_device_attribute rcar_du_soc_table[] = {
|
||||||
|
{ .soc_id = "r8a7795", .revision = "ES1.*", .data = &rcar_du_r8a7795_es1_info },
|
||||||
|
{ /* sentinel */ }
|
||||||
|
};
|
||||||
|
|
||||||
const char *rcar_du_output_name(enum rcar_du_output output)
|
const char *rcar_du_output_name(enum rcar_du_output output)
|
||||||
{
|
{
|
||||||
static const char * const names[] = {
|
static const char * const names[] = {
|
||||||
@@ -645,6 +687,7 @@ static void rcar_du_shutdown(struct platform_device *pdev)
|
|||||||
|
|
||||||
static int rcar_du_probe(struct platform_device *pdev)
|
static int rcar_du_probe(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
|
const struct soc_device_attribute *soc_attr;
|
||||||
struct rcar_du_device *rcdu;
|
struct rcar_du_device *rcdu;
|
||||||
unsigned int mask;
|
unsigned int mask;
|
||||||
int ret;
|
int ret;
|
||||||
@@ -659,8 +702,13 @@ static int rcar_du_probe(struct platform_device *pdev)
|
|||||||
return PTR_ERR(rcdu);
|
return PTR_ERR(rcdu);
|
||||||
|
|
||||||
rcdu->dev = &pdev->dev;
|
rcdu->dev = &pdev->dev;
|
||||||
|
|
||||||
rcdu->info = of_device_get_match_data(rcdu->dev);
|
rcdu->info = of_device_get_match_data(rcdu->dev);
|
||||||
|
|
||||||
|
soc_attr = soc_device_match(rcar_du_soc_table);
|
||||||
|
if (soc_attr)
|
||||||
|
rcdu->info = soc_attr->data;
|
||||||
|
|
||||||
platform_set_drvdata(pdev, rcdu);
|
platform_set_drvdata(pdev, rcdu);
|
||||||
|
|
||||||
/* I/O resources */
|
/* I/O resources */
|
||||||
|
|||||||
@@ -34,6 +34,7 @@ struct rcar_du_device;
|
|||||||
#define RCAR_DU_FEATURE_NO_BLENDING BIT(5) /* PnMR.SPIM does not have ALP nor EOR bits */
|
#define RCAR_DU_FEATURE_NO_BLENDING BIT(5) /* PnMR.SPIM does not have ALP nor EOR bits */
|
||||||
|
|
||||||
#define RCAR_DU_QUIRK_ALIGN_128B BIT(0) /* Align pitches to 128 bytes */
|
#define RCAR_DU_QUIRK_ALIGN_128B BIT(0) /* Align pitches to 128 bytes */
|
||||||
|
#define RCAR_DU_QUIRK_H3_ES1_PCLK_STABILITY BIT(1) /* H3 ES1 has pclk stability issue */
|
||||||
|
|
||||||
enum rcar_du_output {
|
enum rcar_du_output {
|
||||||
RCAR_DU_OUTPUT_DPAD0,
|
RCAR_DU_OUTPUT_DPAD0,
|
||||||
|
|||||||
Reference in New Issue
Block a user