Unverified Commit 33c773eb authored by Maxime Ripard's avatar Maxime Ripard
Browse files

drm/vc4: hdmi: Introduce resource init and variant



The HDMI controllers found in the BCM2711 has a pretty different clock and
registers areas than found in the older BCM283x SoCs.

Let's create a variant structure to store the various adjustments we'll
need later on, and a function to get the resources needed for one
particular version.

Signed-off-by: default avatarMaxime Ripard <maxime@cerno.tech>
Tested-by: default avatarChanwoo Choi <cw00.choi@samsung.com>
Tested-by: default avatarHoegeun Kwon <hoegeun.kwon@samsung.com>
Tested-by: default avatarStefan Wahren <stefan.wahren@i2se.com>
Reviewed-by: default avatarDave Stevenson <dave.stevenson@raspberrypi.com>
Link: https://patchwork.freedesktop.org/patch/msgid/71cfa3ce3d865bbab52a0e5651bc052dc4893f11.1599120059.git-series.maxime@cerno.tech
parent 0532e5e5
Loading
Loading
Loading
Loading
+41 −20
Original line number Diff line number Diff line
@@ -1178,28 +1178,12 @@ static const struct cec_adap_ops vc4_hdmi_cec_adap_ops = {
};
#endif

static int vc4_hdmi_bind(struct device *dev, struct device *master, void *data)
static int vc4_hdmi_init_resources(struct vc4_hdmi *vc4_hdmi)
{
#ifdef CONFIG_DRM_VC4_HDMI_CEC
	struct cec_connector_info conn_info;
#endif
	struct platform_device *pdev = to_platform_device(dev);
	struct drm_device *drm = dev_get_drvdata(master);
	struct vc4_hdmi *vc4_hdmi;
	struct drm_encoder *encoder;
	struct device_node *ddc_node;
	u32 value;
	struct platform_device *pdev = vc4_hdmi->pdev;
	struct device *dev = &pdev->dev;
	int ret;

	vc4_hdmi = devm_kzalloc(dev, sizeof(*vc4_hdmi), GFP_KERNEL);
	if (!vc4_hdmi)
		return -ENOMEM;

	dev_set_drvdata(dev, vc4_hdmi);
	encoder = &vc4_hdmi->encoder.base.base;
	vc4_hdmi->encoder.base.type = VC4_ENCODER_TYPE_HDMI0;
	vc4_hdmi->pdev = pdev;

	vc4_hdmi->hdmicore_regs = vc4_ioremap_regs(pdev, 0);
	if (IS_ERR(vc4_hdmi->hdmicore_regs))
		return PTR_ERR(vc4_hdmi->hdmicore_regs);
@@ -1211,6 +1195,7 @@ static int vc4_hdmi_bind(struct device *dev, struct device *master, void *data)
	vc4_hdmi->hdmi_regset.base = vc4_hdmi->hdmicore_regs;
	vc4_hdmi->hdmi_regset.regs = hdmi_regs;
	vc4_hdmi->hdmi_regset.nregs = ARRAY_SIZE(hdmi_regs);

	vc4_hdmi->hd_regset.base = vc4_hdmi->hd_regs;
	vc4_hdmi->hd_regset.regs = hd_regs;
	vc4_hdmi->hd_regset.nregs = ARRAY_SIZE(hd_regs);
@@ -1222,12 +1207,44 @@ static int vc4_hdmi_bind(struct device *dev, struct device *master, void *data)
			DRM_ERROR("Failed to get pixel clock\n");
		return ret;
	}

	vc4_hdmi->hsm_clock = devm_clk_get(dev, "hdmi");
	if (IS_ERR(vc4_hdmi->hsm_clock)) {
		DRM_ERROR("Failed to get HDMI state machine clock\n");
		return PTR_ERR(vc4_hdmi->hsm_clock);
	}

	return 0;
}

static int vc4_hdmi_bind(struct device *dev, struct device *master, void *data)
{
#ifdef CONFIG_DRM_VC4_HDMI_CEC
	struct cec_connector_info conn_info;
#endif
	const struct vc4_hdmi_variant *variant = of_device_get_match_data(dev);
	struct platform_device *pdev = to_platform_device(dev);
	struct drm_device *drm = dev_get_drvdata(master);
	struct vc4_hdmi *vc4_hdmi;
	struct drm_encoder *encoder;
	struct device_node *ddc_node;
	u32 value;
	int ret;

	vc4_hdmi = devm_kzalloc(dev, sizeof(*vc4_hdmi), GFP_KERNEL);
	if (!vc4_hdmi)
		return -ENOMEM;

	dev_set_drvdata(dev, vc4_hdmi);
	encoder = &vc4_hdmi->encoder.base.base;
	vc4_hdmi->encoder.base.type = VC4_ENCODER_TYPE_HDMI0;
	vc4_hdmi->pdev = pdev;
	vc4_hdmi->variant = variant;

	ret = variant->init_resources(vc4_hdmi);
	if (ret)
		return ret;

	ddc_node = of_parse_phandle(dev->of_node, "ddc", 0);
	if (!ddc_node) {
		DRM_ERROR("Failed to find ddc node in device tree\n");
@@ -1403,8 +1420,12 @@ static int vc4_hdmi_dev_remove(struct platform_device *pdev)
	return 0;
}

static const struct vc4_hdmi_variant bcm2835_variant = {
	.init_resources		= vc4_hdmi_init_resources,
};

static const struct of_device_id vc4_hdmi_dt_match[] = {
	{ .compatible = "brcm,bcm2835-hdmi" },
	{ .compatible = "brcm,bcm2835-hdmi", .data = &bcm2835_variant },
	{}
};

+10 −0
Original line number Diff line number Diff line
@@ -21,6 +21,15 @@ to_vc4_hdmi_encoder(struct drm_encoder *encoder)
	return container_of(encoder, struct vc4_hdmi_encoder, base.base);
}

struct vc4_hdmi;

struct vc4_hdmi_variant {
	/* Callback to get the resources (memory region, interrupts,
	 * clocks, etc) for that variant.
	 */
	int (*init_resources)(struct vc4_hdmi *vc4_hdmi);
};

/* HDMI audio information */
struct vc4_hdmi_audio {
	struct snd_soc_card card;
@@ -39,6 +48,7 @@ struct vc4_hdmi {
	struct vc4_hdmi_audio audio;

	struct platform_device *pdev;
	const struct vc4_hdmi_variant *variant;

	struct vc4_hdmi_encoder encoder;
	struct drm_connector connector;