* DU channels that have a display PLL can't use the internal
* system clock, and have no internal clock divider.
*/
-
- /*
- * The H3 ES1.x exhibits dot clock duty cycle stability issues.
- * We can work around them by configuring the DPLL to twice the
- * desired frequency, coupled with a /2 post-divider. Restrict
- * the workaround to H3 ES1.x as ES2.0 and all other SoCs have
- * no post-divider when a display PLL is present (as shown by
- * the workaround breaking HDMI output on M3-W during testing).
- */
- if (rcdu->info->quirks & RCAR_DU_QUIRK_H3_ES1_PCLK_STABILITY) {
- target *= 2;
- div = 1;
- }
-
extclk = clk_get_rate(rcrtc->extclock);
rcar_du_dpll_divider(rcrtc, &dpll, extclk, target);
| DPLLCR_N(dpll.n) | DPLLCR_M(dpll.m)
| DPLLCR_STBY;
- if (rcrtc->index == 1) {
+ if (rcrtc->index == 1)
dpllcr |= DPLLCR_PLCS1
| DPLLCR_INCS_DOTCLKIN1;
- } else {
- dpllcr |= DPLLCR_PLCS0_PLL
+ else
+ dpllcr |= DPLLCR_PLCS0
| DPLLCR_INCS_DOTCLKIN0;
- /*
- * On ES2.x we have a single mux controlled via bit 21,
- * which selects between DCLKIN source (bit 21 = 0) and
- * a PLL source (bit 21 = 1), where the PLL is always
- * PLL1.
- *
- * On ES1.x we have an additional mux, controlled
- * via bit 20, for choosing between PLL0 (bit 20 = 0)
- * and PLL1 (bit 20 = 1). We always want to use PLL1,
- * so on ES1.x, in addition to setting bit 21, we need
- * to set the bit 20.
- */
-
- if (rcdu->info->quirks & RCAR_DU_QUIRK_H3_ES1_PLL)
- dpllcr |= DPLLCR_PLCS0_H3ES1X_PLL1;
- }
-
rcar_du_group_write(rcrtc->group, DPLLCR, dpllcr);
escr = ESCR_DCLKSEL_DCLKIN | div;
#include <linux/platform_device.h>
#include <linux/pm.h>
#include <linux/slab.h>
-#include <linux/sys_soc.h>
#include <linux/wait.h>
#include <drm/drm_atomic_helper.h>
.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
- | RCAR_DU_QUIRK_H3_ES1_PLL,
- .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 = {
.gen = 3,
.features = RCAR_DU_FEATURE_CRTC_IRQ
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)
{
static const char * const names[] = {
static int rcar_du_probe(struct platform_device *pdev)
{
- const struct soc_device_attribute *soc_attr;
struct rcar_du_device *rcdu;
unsigned int mask;
int ret;
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);
/* I/O resources */