* [PATCH v3 073/105] drm/vc4: hdmi: Move accessors to vc4_hdmi
From: Maxime Ripard @ 2020-05-27 15:48 UTC (permalink / raw)
To: Nicolas Saenz Julienne, Eric Anholt
Cc: Tim Gover, Dave Stevenson, linux-kernel, dri-devel,
bcm-kernel-feedback-list, linux-rpi-kernel, Phil Elwell,
linux-arm-kernel, Maxime Ripard
In-Reply-To: <cover.aaf2100bd7da4609f8bcb8216247d4b4e4379639.1590594512.git-series.maxime@cerno.tech>
The current driver only supports a single HDMI controller, and part of
the issue is that the main vc4_dev structure holds a pointer to its
(only) HDMI controller, and the HDMI registers accessors will use it to
retrieve the mapped addresses.
Let's modify those accessors to use directly the vc4_hdmi structure so
that we can eventually get rid of that single global pointer.
Signed-off-by: Maxime Ripard <maxime@cerno.tech>
---
drivers/gpu/drm/vc4/vc4_hdmi.c | 24 +++++++++---------------
drivers/gpu/drm/vc4/vc4_hdmi.h | 8 ++++----
2 files changed, 13 insertions(+), 19 deletions(-)
diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c
index 38a14acf73e7..755b3e99a7af 100644
--- a/drivers/gpu/drm/vc4/vc4_hdmi.c
+++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
@@ -123,6 +123,7 @@ vc4_hdmi_connector_detect(struct drm_connector *connector, bool force)
{
struct drm_device *dev = connector->dev;
struct vc4_dev *vc4 = to_vc4_dev(dev);
+ struct vc4_hdmi *vc4_hdmi = vc4->hdmi;
if (vc4->hdmi->hpd_gpio) {
if (gpio_get_value_cansleep(vc4->hdmi->hpd_gpio) ^
@@ -230,6 +231,7 @@ static int vc4_hdmi_stop_packet(struct drm_encoder *encoder,
{
struct drm_device *dev = encoder->dev;
struct vc4_dev *vc4 = to_vc4_dev(dev);
+ struct vc4_hdmi *vc4_hdmi = vc4->hdmi;
u32 packet_id = type - 0x80;
HDMI_WRITE(VC4_HDMI_RAM_PACKET_CONFIG,
@@ -244,6 +246,7 @@ static void vc4_hdmi_write_infoframe(struct drm_encoder *encoder,
{
struct drm_device *dev = encoder->dev;
struct vc4_dev *vc4 = to_vc4_dev(dev);
+ struct vc4_hdmi *vc4_hdmi = vc4->hdmi;
u32 packet_id = frame->any.type - 0x80;
u32 packet_reg = VC4_HDMI_RAM_PACKET(packet_id);
uint8_t buffer[VC4_HDMI_PACKET_STRIDE];
@@ -623,9 +626,6 @@ static const struct drm_encoder_helper_funcs vc4_hdmi_encoder_helper_funcs = {
/* HDMI audio codec callbacks */
static void vc4_hdmi_audio_set_mai_clock(struct vc4_hdmi *vc4_hdmi)
{
- struct drm_encoder *encoder = &vc4_hdmi->encoder.base.base;
- struct drm_device *drm = encoder->dev;
- struct vc4_dev *vc4 = to_vc4_dev(drm);
u32 hsm_clock = clk_get_rate(vc4_hdmi->hsm_clock);
unsigned long n, m;
@@ -645,8 +645,6 @@ static void vc4_hdmi_set_n_cts(struct vc4_hdmi *vc4_hdmi)
{
struct drm_encoder *encoder = &vc4_hdmi->encoder.base.base;
struct drm_crtc *crtc = encoder->crtc;
- struct drm_device *drm = encoder->dev;
- struct vc4_dev *vc4 = to_vc4_dev(drm);
const struct drm_display_mode *mode = &crtc->state->adjusted_mode;
u32 samplerate = vc4_hdmi->audio.samplerate;
u32 n, cts;
@@ -683,7 +681,6 @@ static int vc4_hdmi_audio_startup(struct snd_pcm_substream *substream,
struct vc4_hdmi *vc4_hdmi = dai_to_hdmi(dai);
struct drm_encoder *encoder = &vc4_hdmi->encoder.base.base;
struct drm_connector *connector = &vc4_hdmi->connector.base;
- struct vc4_dev *vc4 = to_vc4_dev(encoder->dev);
int ret;
if (vc4_hdmi->audio.substream && vc4_hdmi->audio.substream != substream)
@@ -714,9 +711,7 @@ static int vc4_hdmi_audio_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
static void vc4_hdmi_audio_reset(struct vc4_hdmi *vc4_hdmi)
{
struct drm_encoder *encoder = &vc4_hdmi->encoder.base.base;
- struct drm_device *drm = encoder->dev;
struct device *dev = &vc4_hdmi->pdev->dev;
- struct vc4_dev *vc4 = to_vc4_dev(drm);
int ret;
ret = vc4_hdmi_stop_packet(encoder, HDMI_INFOFRAME_TYPE_AUDIO);
@@ -747,10 +742,7 @@ static int vc4_hdmi_audio_hw_params(struct snd_pcm_substream *substream,
struct snd_soc_dai *dai)
{
struct vc4_hdmi *vc4_hdmi = dai_to_hdmi(dai);
- struct drm_encoder *encoder = &vc4_hdmi->encoder.base.base;
- struct drm_device *drm = encoder->dev;
struct device *dev = &vc4_hdmi->pdev->dev;
- struct vc4_dev *vc4 = to_vc4_dev(drm);
u32 audio_packet_config, channel_mask;
u32 channel_map, i;
@@ -821,8 +813,6 @@ static int vc4_hdmi_audio_trigger(struct snd_pcm_substream *substream, int cmd,
{
struct vc4_hdmi *vc4_hdmi = dai_to_hdmi(dai);
struct drm_encoder *encoder = &vc4_hdmi->encoder.base.base;
- struct drm_device *drm = encoder->dev;
- struct vc4_dev *vc4 = to_vc4_dev(drm);
switch (cmd) {
case SNDRV_PCM_TRIGGER_START:
@@ -1082,7 +1072,8 @@ static irqreturn_t vc4_cec_irq_handler_thread(int irq, void *priv)
static void vc4_cec_read_msg(struct vc4_dev *vc4, u32 cntrl1)
{
- struct cec_msg *msg = &vc4->hdmi->cec_rx_msg;
+ struct vc4_hdmi *vc4_hdmi = vc4->hdmi;
+ struct cec_msg *msg = &vc4_hdmi->cec_rx_msg;
unsigned int i;
msg->len = 1 + ((cntrl1 & VC4_HDMI_CEC_REC_WRD_CNT_MASK) >>
@@ -1128,6 +1119,7 @@ static irqreturn_t vc4_cec_irq_handler(int irq, void *priv)
static int vc4_hdmi_cec_adap_enable(struct cec_adapter *adap, bool enable)
{
struct vc4_dev *vc4 = cec_get_drvdata(adap);
+ struct vc4_hdmi *vc4_hdmi = vc4->hdmi;
/* clock period in microseconds */
const u32 usecs = 1000000 / CEC_CLOCK_FREQ;
u32 val = HDMI_READ(VC4_HDMI_CEC_CNTRL_5);
@@ -1171,6 +1163,7 @@ static int vc4_hdmi_cec_adap_enable(struct cec_adapter *adap, bool enable)
static int vc4_hdmi_cec_adap_log_addr(struct cec_adapter *adap, u8 log_addr)
{
struct vc4_dev *vc4 = cec_get_drvdata(adap);
+ struct vc4_hdmi *vc4_hdmi = vc4->hdmi;
HDMI_WRITE(VC4_HDMI_CEC_CNTRL_1,
(HDMI_READ(VC4_HDMI_CEC_CNTRL_1) & ~VC4_HDMI_CEC_ADDR_MASK) |
@@ -1182,6 +1175,7 @@ static int vc4_hdmi_cec_adap_transmit(struct cec_adapter *adap, u8 attempts,
u32 signal_free_time, struct cec_msg *msg)
{
struct vc4_dev *vc4 = cec_get_drvdata(adap);
+ struct vc4_hdmi *vc4_hdmi = vc4->hdmi;
u32 val;
unsigned int i;
@@ -1392,7 +1386,7 @@ static void vc4_hdmi_unbind(struct device *dev, struct device *master,
cec_unregister_adapter(vc4_hdmi->cec_adap);
vc4_hdmi_connector_destroy(&vc4_hdmi->connector.base);
- vc4_hdmi_encoder_destroy(&vc4_hdmi->encoder.base.base);
+ drm_encoder_cleanup(&vc4_hdmi->encoder.base.base);
clk_disable_unprepare(vc4_hdmi->hsm_clock);
pm_runtime_disable(dev);
diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.h b/drivers/gpu/drm/vc4/vc4_hdmi.h
index 17079a39f1b1..cdc9d90f62ac 100644
--- a/drivers/gpu/drm/vc4/vc4_hdmi.h
+++ b/drivers/gpu/drm/vc4/vc4_hdmi.h
@@ -78,9 +78,9 @@ struct vc4_hdmi {
struct debugfs_regset32 hd_regset;
};
-#define HDMI_READ(offset) readl(vc4->hdmi->hdmicore_regs + offset)
-#define HDMI_WRITE(offset, val) writel(val, vc4->hdmi->hdmicore_regs + offset)
-#define HD_READ(offset) readl(vc4->hdmi->hd_regs + offset)
-#define HD_WRITE(offset, val) writel(val, vc4->hdmi->hd_regs + offset)
+#define HDMI_READ(offset) readl(vc4_hdmi->hdmicore_regs + offset)
+#define HDMI_WRITE(offset, val) writel(val, vc4_hdmi->hdmicore_regs + offset)
+#define HD_READ(offset) readl(vc4_hdmi->hd_regs + offset)
+#define HD_WRITE(offset, val) writel(val, vc4_hdmi->hd_regs + offset)
#endif /* _VC4_HDMI_H_ */
--
git-series 0.9.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [PATCH v3 074/105] drm/vc4: hdmi: Use local vc4_hdmi directly
From: Maxime Ripard @ 2020-05-27 15:48 UTC (permalink / raw)
To: Nicolas Saenz Julienne, Eric Anholt
Cc: Tim Gover, Dave Stevenson, linux-kernel, dri-devel,
bcm-kernel-feedback-list, linux-rpi-kernel, Phil Elwell,
linux-arm-kernel, Maxime Ripard
In-Reply-To: <cover.aaf2100bd7da4609f8bcb8216247d4b4e4379639.1590594512.git-series.maxime@cerno.tech>
The function vc4_hdmi_connector_detect access its vc4_hdmi struct by
dereferencing the pointer in the structure vc4_dev. This will cause some
issues when we will have multiple HDMI controllers, so let's just use the
local variable for now instead of dereferencing that pointer all the time,
and we'll fix the local variable later.
Signed-off-by: Maxime Ripard <maxime@cerno.tech>
---
drivers/gpu/drm/vc4/vc4_hdmi.c | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c
index 755b3e99a7af..50c67d674331 100644
--- a/drivers/gpu/drm/vc4/vc4_hdmi.c
+++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
@@ -125,20 +125,20 @@ vc4_hdmi_connector_detect(struct drm_connector *connector, bool force)
struct vc4_dev *vc4 = to_vc4_dev(dev);
struct vc4_hdmi *vc4_hdmi = vc4->hdmi;
- if (vc4->hdmi->hpd_gpio) {
- if (gpio_get_value_cansleep(vc4->hdmi->hpd_gpio) ^
- vc4->hdmi->hpd_active_low)
+ if (vc4_hdmi->hpd_gpio) {
+ if (gpio_get_value_cansleep(vc4_hdmi->hpd_gpio) ^
+ vc4_hdmi->hpd_active_low)
return connector_status_connected;
- cec_phys_addr_invalidate(vc4->hdmi->cec_adap);
+ cec_phys_addr_invalidate(vc4_hdmi->cec_adap);
return connector_status_disconnected;
}
- if (drm_probe_ddc(vc4->hdmi->ddc))
+ if (drm_probe_ddc(vc4_hdmi->ddc))
return connector_status_connected;
if (HDMI_READ(VC4_HDMI_HOTPLUG) & VC4_HDMI_HOTPLUG_CONNECTED)
return connector_status_connected;
- cec_phys_addr_invalidate(vc4->hdmi->cec_adap);
+ cec_phys_addr_invalidate(vc4_hdmi->cec_adap);
return connector_status_disconnected;
}
--
git-series 0.9.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [PATCH v3 072/105] drm/vc4: hdmi: Rename hdmi to vc4_hdmi
From: Maxime Ripard @ 2020-05-27 15:48 UTC (permalink / raw)
To: Nicolas Saenz Julienne, Eric Anholt
Cc: Tim Gover, Dave Stevenson, linux-kernel, dri-devel,
bcm-kernel-feedback-list, linux-rpi-kernel, Phil Elwell,
linux-arm-kernel, Maxime Ripard
In-Reply-To: <cover.aaf2100bd7da4609f8bcb8216247d4b4e4379639.1590594512.git-series.maxime@cerno.tech>
The driver isn't consistent with the name given to the vc4_hdmi
structure pointer in its functions. Make sure to use a consistent name.
Signed-off-by: Maxime Ripard <maxime@cerno.tech>
---
drivers/gpu/drm/vc4/vc4_hdmi.c | 281 +++++++++++++++++-----------------
1 file changed, 141 insertions(+), 140 deletions(-)
diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c
index a2f848632e8d..38a14acf73e7 100644
--- a/drivers/gpu/drm/vc4/vc4_hdmi.c
+++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
@@ -109,11 +109,11 @@ static const struct debugfs_reg32 hd_regs[] = {
static int vc4_hdmi_debugfs_regs(struct seq_file *m, void *unused)
{
struct drm_info_node *node = (struct drm_info_node *)m->private;
- struct vc4_hdmi *hdmi = node->info_ent->data;
+ struct vc4_hdmi *vc4_hdmi = node->info_ent->data;
struct drm_printer p = drm_seq_file_printer(m);
- drm_print_regset32(&p, &hdmi->hdmi_regset);
- drm_print_regset32(&p, &hdmi->hd_regset);
+ drm_print_regset32(&p, &vc4_hdmi->hdmi_regset);
+ drm_print_regset32(&p, &vc4_hdmi->hd_regset);
return 0;
}
@@ -291,8 +291,8 @@ static void vc4_hdmi_set_avi_infoframe(struct drm_encoder *encoder)
{
struct vc4_hdmi_encoder *vc4_encoder = to_vc4_hdmi_encoder(encoder);
struct vc4_dev *vc4 = encoder->dev->dev_private;
- struct vc4_hdmi *hdmi = vc4->hdmi;
- struct drm_connector *connector = &hdmi->connector.base;
+ struct vc4_hdmi *vc4_hdmi = vc4->hdmi;
+ struct drm_connector *connector = &vc4_hdmi->connector.base;
struct drm_connector_state *cstate = connector->state;
struct drm_crtc *crtc = encoder->crtc;
const struct drm_display_mode *mode = &crtc->state->adjusted_mode;
@@ -337,7 +337,7 @@ static void vc4_hdmi_set_audio_infoframe(struct drm_encoder *encoder)
{
struct drm_device *drm = encoder->dev;
struct vc4_dev *vc4 = drm->dev_private;
- struct vc4_hdmi *hdmi = vc4->hdmi;
+ struct vc4_hdmi *vc4_hdmi = vc4->hdmi;
union hdmi_infoframe frame;
int ret;
@@ -346,7 +346,7 @@ static void vc4_hdmi_set_audio_infoframe(struct drm_encoder *encoder)
frame.audio.coding_type = HDMI_AUDIO_CODING_TYPE_STREAM;
frame.audio.sample_frequency = HDMI_AUDIO_SAMPLE_FREQUENCY_STREAM;
frame.audio.sample_size = HDMI_AUDIO_SAMPLE_SIZE_STREAM;
- frame.audio.channels = hdmi->audio.channels;
+ frame.audio.channels = vc4_hdmi->audio.channels;
vc4_hdmi_write_infoframe(encoder, &frame);
}
@@ -361,7 +361,7 @@ static void vc4_hdmi_encoder_disable(struct drm_encoder *encoder)
{
struct drm_device *dev = encoder->dev;
struct vc4_dev *vc4 = to_vc4_dev(dev);
- struct vc4_hdmi *hdmi = vc4->hdmi;
+ struct vc4_hdmi *vc4_hdmi = vc4->hdmi;
int ret;
HDMI_WRITE(VC4_HDMI_RAM_PACKET_CONFIG, 0);
@@ -370,9 +370,9 @@ static void vc4_hdmi_encoder_disable(struct drm_encoder *encoder)
HD_WRITE(VC4_HD_VID_CTL,
HD_READ(VC4_HD_VID_CTL) & ~VC4_HD_VID_CTL_ENABLE);
- clk_disable_unprepare(hdmi->pixel_clock);
+ clk_disable_unprepare(vc4_hdmi->pixel_clock);
- ret = pm_runtime_put(&hdmi->pdev->dev);
+ ret = pm_runtime_put(&vc4_hdmi->pdev->dev);
if (ret < 0)
DRM_ERROR("Failed to release power domain: %d\n", ret);
}
@@ -383,7 +383,7 @@ static void vc4_hdmi_encoder_enable(struct drm_encoder *encoder)
struct vc4_hdmi_encoder *vc4_encoder = to_vc4_hdmi_encoder(encoder);
struct drm_device *dev = encoder->dev;
struct vc4_dev *vc4 = to_vc4_dev(dev);
- struct vc4_hdmi *hdmi = vc4->hdmi;
+ struct vc4_hdmi *vc4_hdmi = vc4->hdmi;
bool debug_dump_regs = false;
bool hsync_pos = mode->flags & DRM_MODE_FLAG_PHSYNC;
bool vsync_pos = mode->flags & DRM_MODE_FLAG_PVSYNC;
@@ -405,13 +405,13 @@ static void vc4_hdmi_encoder_enable(struct drm_encoder *encoder)
u32 csc_ctl;
int ret;
- ret = pm_runtime_get_sync(&hdmi->pdev->dev);
+ ret = pm_runtime_get_sync(&vc4_hdmi->pdev->dev);
if (ret < 0) {
DRM_ERROR("Failed to retain power domain: %d\n", ret);
return;
}
- ret = clk_set_rate(hdmi->pixel_clock,
+ ret = clk_set_rate(vc4_hdmi->pixel_clock,
mode->clock * 1000 *
((mode->flags & DRM_MODE_FLAG_DBLCLK) ? 2 : 1));
if (ret) {
@@ -419,7 +419,7 @@ static void vc4_hdmi_encoder_enable(struct drm_encoder *encoder)
return;
}
- ret = clk_prepare_enable(hdmi->pixel_clock);
+ ret = clk_prepare_enable(vc4_hdmi->pixel_clock);
if (ret) {
DRM_ERROR("Failed to turn on pixel clock: %d\n", ret);
return;
@@ -439,11 +439,11 @@ static void vc4_hdmi_encoder_enable(struct drm_encoder *encoder)
HDMI_WRITE(VC4_HDMI_TX_PHY_RESET_CTL, 0);
if (debug_dump_regs) {
- struct drm_printer p = drm_info_printer(&hdmi->pdev->dev);
+ struct drm_printer p = drm_info_printer(&vc4_hdmi->pdev->dev);
- dev_info(&hdmi->pdev->dev, "HDMI regs before:\n");
- drm_print_regset32(&p, &hdmi->hdmi_regset);
- drm_print_regset32(&p, &hdmi->hd_regset);
+ dev_info(&vc4_hdmi->pdev->dev, "HDMI regs before:\n");
+ drm_print_regset32(&p, &vc4_hdmi->hdmi_regset);
+ drm_print_regset32(&p, &vc4_hdmi->hd_regset);
}
HD_WRITE(VC4_HD_VID_CTL, 0);
@@ -518,11 +518,11 @@ static void vc4_hdmi_encoder_enable(struct drm_encoder *encoder)
HDMI_WRITE(VC4_HDMI_FIFO_CTL, VC4_HDMI_FIFO_CTL_MASTER_SLAVE_N);
if (debug_dump_regs) {
- struct drm_printer p = drm_info_printer(&hdmi->pdev->dev);
+ struct drm_printer p = drm_info_printer(&vc4_hdmi->pdev->dev);
- dev_info(&hdmi->pdev->dev, "HDMI regs after:\n");
- drm_print_regset32(&p, &hdmi->hdmi_regset);
- drm_print_regset32(&p, &hdmi->hd_regset);
+ dev_info(&vc4_hdmi->pdev->dev, "HDMI regs after:\n");
+ drm_print_regset32(&p, &vc4_hdmi->hdmi_regset);
+ drm_print_regset32(&p, &vc4_hdmi->hd_regset);
}
HD_WRITE(VC4_HD_VID_CTL,
@@ -621,15 +621,15 @@ static const struct drm_encoder_helper_funcs vc4_hdmi_encoder_helper_funcs = {
};
/* HDMI audio codec callbacks */
-static void vc4_hdmi_audio_set_mai_clock(struct vc4_hdmi *hdmi)
+static void vc4_hdmi_audio_set_mai_clock(struct vc4_hdmi *vc4_hdmi)
{
- struct drm_encoder *encoder = &hdmi->encoder.base.base;
+ struct drm_encoder *encoder = &vc4_hdmi->encoder.base.base;
struct drm_device *drm = encoder->dev;
struct vc4_dev *vc4 = to_vc4_dev(drm);
- u32 hsm_clock = clk_get_rate(hdmi->hsm_clock);
+ u32 hsm_clock = clk_get_rate(vc4_hdmi->hsm_clock);
unsigned long n, m;
- rational_best_approximation(hsm_clock, hdmi->audio.samplerate,
+ rational_best_approximation(hsm_clock, vc4_hdmi->audio.samplerate,
VC4_HD_MAI_SMP_N_MASK >>
VC4_HD_MAI_SMP_N_SHIFT,
(VC4_HD_MAI_SMP_M_MASK >>
@@ -641,14 +641,14 @@ static void vc4_hdmi_audio_set_mai_clock(struct vc4_hdmi *hdmi)
VC4_SET_FIELD(m - 1, VC4_HD_MAI_SMP_M));
}
-static void vc4_hdmi_set_n_cts(struct vc4_hdmi *hdmi)
+static void vc4_hdmi_set_n_cts(struct vc4_hdmi *vc4_hdmi)
{
- struct drm_encoder *encoder = &hdmi->encoder.base.base;
+ struct drm_encoder *encoder = &vc4_hdmi->encoder.base.base;
struct drm_crtc *crtc = encoder->crtc;
struct drm_device *drm = encoder->dev;
struct vc4_dev *vc4 = to_vc4_dev(drm);
const struct drm_display_mode *mode = &crtc->state->adjusted_mode;
- u32 samplerate = hdmi->audio.samplerate;
+ u32 samplerate = vc4_hdmi->audio.samplerate;
u32 n, cts;
u64 tmp;
@@ -680,16 +680,16 @@ static inline struct vc4_hdmi *dai_to_hdmi(struct snd_soc_dai *dai)
static int vc4_hdmi_audio_startup(struct snd_pcm_substream *substream,
struct snd_soc_dai *dai)
{
- struct vc4_hdmi *hdmi = dai_to_hdmi(dai);
- struct drm_encoder *encoder = &hdmi->encoder.base.base;
- struct drm_connector *connector = &hdmi->connector.base;
+ struct vc4_hdmi *vc4_hdmi = dai_to_hdmi(dai);
+ struct drm_encoder *encoder = &vc4_hdmi->encoder.base.base;
+ struct drm_connector *connector = &vc4_hdmi->connector.base;
struct vc4_dev *vc4 = to_vc4_dev(encoder->dev);
int ret;
- if (hdmi->audio.substream && hdmi->audio.substream != substream)
+ if (vc4_hdmi->audio.substream && vc4_hdmi->audio.substream != substream)
return -EINVAL;
- hdmi->audio.substream = substream;
+ vc4_hdmi->audio.substream = substream;
/*
* If the HDMI encoder hasn't probed, or the encoder is
@@ -711,11 +711,11 @@ static int vc4_hdmi_audio_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
return 0;
}
-static void vc4_hdmi_audio_reset(struct vc4_hdmi *hdmi)
+static void vc4_hdmi_audio_reset(struct vc4_hdmi *vc4_hdmi)
{
- struct drm_encoder *encoder = &hdmi->encoder.base.base;
+ struct drm_encoder *encoder = &vc4_hdmi->encoder.base.base;
struct drm_device *drm = encoder->dev;
- struct device *dev = &hdmi->pdev->dev;
+ struct device *dev = &vc4_hdmi->pdev->dev;
struct vc4_dev *vc4 = to_vc4_dev(drm);
int ret;
@@ -731,14 +731,14 @@ static void vc4_hdmi_audio_reset(struct vc4_hdmi *hdmi)
static void vc4_hdmi_audio_shutdown(struct snd_pcm_substream *substream,
struct snd_soc_dai *dai)
{
- struct vc4_hdmi *hdmi = dai_to_hdmi(dai);
+ struct vc4_hdmi *vc4_hdmi = dai_to_hdmi(dai);
- if (substream != hdmi->audio.substream)
+ if (substream != vc4_hdmi->audio.substream)
return;
- vc4_hdmi_audio_reset(hdmi);
+ vc4_hdmi_audio_reset(vc4_hdmi);
- hdmi->audio.substream = NULL;
+ vc4_hdmi->audio.substream = NULL;
}
/* HDMI audio codec callbacks */
@@ -746,23 +746,23 @@ static int vc4_hdmi_audio_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params,
struct snd_soc_dai *dai)
{
- struct vc4_hdmi *hdmi = dai_to_hdmi(dai);
- struct drm_encoder *encoder = &hdmi->encoder.base.base;
+ struct vc4_hdmi *vc4_hdmi = dai_to_hdmi(dai);
+ struct drm_encoder *encoder = &vc4_hdmi->encoder.base.base;
struct drm_device *drm = encoder->dev;
- struct device *dev = &hdmi->pdev->dev;
+ struct device *dev = &vc4_hdmi->pdev->dev;
struct vc4_dev *vc4 = to_vc4_dev(drm);
u32 audio_packet_config, channel_mask;
u32 channel_map, i;
- if (substream != hdmi->audio.substream)
+ if (substream != vc4_hdmi->audio.substream)
return -EINVAL;
dev_dbg(dev, "%s: %u Hz, %d bit, %d channels\n", __func__,
params_rate(params), params_width(params),
params_channels(params));
- hdmi->audio.channels = params_channels(params);
- hdmi->audio.samplerate = params_rate(params);
+ vc4_hdmi->audio.channels = params_channels(params);
+ vc4_hdmi->audio.samplerate = params_rate(params);
HD_WRITE(VC4_HD_MAI_CTL,
VC4_HD_MAI_CTL_RESET |
@@ -771,23 +771,23 @@ static int vc4_hdmi_audio_hw_params(struct snd_pcm_substream *substream,
VC4_HD_MAI_CTL_ERRORE |
VC4_HD_MAI_CTL_ERRORF);
- vc4_hdmi_audio_set_mai_clock(hdmi);
+ vc4_hdmi_audio_set_mai_clock(vc4_hdmi);
audio_packet_config =
VC4_HDMI_AUDIO_PACKET_ZERO_DATA_ON_SAMPLE_FLAT |
VC4_HDMI_AUDIO_PACKET_ZERO_DATA_ON_INACTIVE_CHANNELS |
VC4_SET_FIELD(0xf, VC4_HDMI_AUDIO_PACKET_B_FRAME_IDENTIFIER);
- channel_mask = GENMASK(hdmi->audio.channels - 1, 0);
+ channel_mask = GENMASK(vc4_hdmi->audio.channels - 1, 0);
audio_packet_config |= VC4_SET_FIELD(channel_mask,
VC4_HDMI_AUDIO_PACKET_CEA_MASK);
/* Set the MAI threshold. This logic mimics the firmware's. */
- if (hdmi->audio.samplerate > 96000) {
+ if (vc4_hdmi->audio.samplerate > 96000) {
HD_WRITE(VC4_HD_MAI_THR,
VC4_SET_FIELD(0x12, VC4_HD_MAI_THR_DREQHIGH) |
VC4_SET_FIELD(0x12, VC4_HD_MAI_THR_DREQLOW));
- } else if (hdmi->audio.samplerate > 48000) {
+ } else if (vc4_hdmi->audio.samplerate > 48000) {
HD_WRITE(VC4_HD_MAI_THR,
VC4_SET_FIELD(0x14, VC4_HD_MAI_THR_DREQHIGH) |
VC4_SET_FIELD(0x12, VC4_HD_MAI_THR_DREQLOW));
@@ -811,7 +811,7 @@ static int vc4_hdmi_audio_hw_params(struct snd_pcm_substream *substream,
HDMI_WRITE(VC4_HDMI_MAI_CHANNEL_MAP, channel_map);
HDMI_WRITE(VC4_HDMI_AUDIO_PACKET_CONFIG, audio_packet_config);
- vc4_hdmi_set_n_cts(hdmi);
+ vc4_hdmi_set_n_cts(vc4_hdmi);
return 0;
}
@@ -819,8 +819,8 @@ static int vc4_hdmi_audio_hw_params(struct snd_pcm_substream *substream,
static int vc4_hdmi_audio_trigger(struct snd_pcm_substream *substream, int cmd,
struct snd_soc_dai *dai)
{
- struct vc4_hdmi *hdmi = dai_to_hdmi(dai);
- struct drm_encoder *encoder = &hdmi->encoder.base.base;
+ struct vc4_hdmi *vc4_hdmi = dai_to_hdmi(dai);
+ struct drm_encoder *encoder = &vc4_hdmi->encoder.base.base;
struct drm_device *drm = encoder->dev;
struct vc4_dev *vc4 = to_vc4_dev(drm);
@@ -831,7 +831,7 @@ static int vc4_hdmi_audio_trigger(struct snd_pcm_substream *substream, int cmd,
HDMI_READ(VC4_HDMI_TX_PHY_CTL0) &
~VC4_HDMI_TX_PHY_RNG_PWRDN);
HD_WRITE(VC4_HD_MAI_CTL,
- VC4_SET_FIELD(hdmi->audio.channels,
+ VC4_SET_FIELD(vc4_hdmi->audio.channels,
VC4_HD_MAI_CTL_CHNUM) |
VC4_HD_MAI_CTL_ENABLE);
break;
@@ -863,8 +863,8 @@ static int vc4_hdmi_audio_eld_ctl_info(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_info *uinfo)
{
struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
- struct vc4_hdmi *hdmi = snd_component_to_hdmi(component);
- struct drm_connector *connector = &hdmi->connector.base;
+ struct vc4_hdmi *vc4_hdmi = snd_component_to_hdmi(component);
+ struct drm_connector *connector = &vc4_hdmi->connector.base;
uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES;
uinfo->count = sizeof(connector->eld);
@@ -876,8 +876,8 @@ static int vc4_hdmi_audio_eld_ctl_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
- struct vc4_hdmi *hdmi = snd_component_to_hdmi(component);
- struct drm_connector *connector = &hdmi->connector.base;
+ struct vc4_hdmi *vc4_hdmi = snd_component_to_hdmi(component);
+ struct drm_connector *connector = &vc4_hdmi->connector.base;
memcpy(ucontrol->value.bytes.data, connector->eld,
sizeof(connector->eld));
@@ -945,9 +945,9 @@ static const struct snd_soc_component_driver vc4_hdmi_audio_cpu_dai_comp = {
static int vc4_hdmi_audio_cpu_dai_probe(struct snd_soc_dai *dai)
{
- struct vc4_hdmi *hdmi = dai_to_hdmi(dai);
+ struct vc4_hdmi *vc4_hdmi = dai_to_hdmi(dai);
- snd_soc_dai_init_dma_data(dai, &hdmi->audio.dma_data, NULL);
+ snd_soc_dai_init_dma_data(dai, &vc4_hdmi->audio.dma_data, NULL);
return 0;
}
@@ -973,11 +973,11 @@ static const struct snd_dmaengine_pcm_config pcm_conf = {
.prepare_slave_config = snd_dmaengine_pcm_prepare_slave_config,
};
-static int vc4_hdmi_audio_init(struct vc4_hdmi *hdmi)
+static int vc4_hdmi_audio_init(struct vc4_hdmi *vc4_hdmi)
{
- struct snd_soc_dai_link *dai_link = &hdmi->audio.link;
- struct snd_soc_card *card = &hdmi->audio.card;
- struct device *dev = &hdmi->pdev->dev;
+ struct snd_soc_dai_link *dai_link = &vc4_hdmi->audio.link;
+ struct snd_soc_card *card = &vc4_hdmi->audio.card;
+ struct device *dev = &vc4_hdmi->pdev->dev;
const __be32 *addr;
int ret;
@@ -995,9 +995,9 @@ static int vc4_hdmi_audio_init(struct vc4_hdmi *hdmi)
* This VC/MMU should probably be exposed to avoid this kind of hacks.
*/
addr = of_get_address(dev->of_node, 1, NULL, NULL);
- hdmi->audio.dma_data.addr = be32_to_cpup(addr) + VC4_HD_MAI_DATA;
- hdmi->audio.dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
- hdmi->audio.dma_data.maxburst = 2;
+ vc4_hdmi->audio.dma_data.addr = be32_to_cpup(addr) + VC4_HD_MAI_DATA;
+ vc4_hdmi->audio.dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
+ vc4_hdmi->audio.dma_data.maxburst = 2;
ret = devm_snd_dmaengine_pcm_register(dev, &pcm_conf, 0);
if (ret) {
@@ -1020,9 +1020,9 @@ static int vc4_hdmi_audio_init(struct vc4_hdmi *hdmi)
return ret;
}
- dai_link->cpus = &hdmi->audio.cpu;
- dai_link->codecs = &hdmi->audio.codec;
- dai_link->platforms = &hdmi->audio.platform;
+ dai_link->cpus = &vc4_hdmi->audio.cpu;
+ dai_link->codecs = &vc4_hdmi->audio.codec;
+ dai_link->platforms = &vc4_hdmi->audio.platform;
dai_link->num_cpus = 1;
dai_link->num_codecs = 1;
@@ -1047,7 +1047,7 @@ static int vc4_hdmi_audio_init(struct vc4_hdmi *hdmi)
* now stored in card->drvdata and should be retrieved with
* snd_soc_card_get_drvdata() if needed.
*/
- snd_soc_card_set_drvdata(card, hdmi);
+ snd_soc_card_set_drvdata(card, vc4_hdmi);
ret = devm_snd_soc_register_card(dev, card);
if (ret)
dev_err(dev, "Could not register sound card: %d\n", ret);
@@ -1060,20 +1060,21 @@ static int vc4_hdmi_audio_init(struct vc4_hdmi *hdmi)
static irqreturn_t vc4_cec_irq_handler_thread(int irq, void *priv)
{
struct vc4_dev *vc4 = priv;
- struct vc4_hdmi *hdmi = vc4->hdmi;
-
- if (hdmi->cec_irq_was_rx) {
- if (hdmi->cec_rx_msg.len)
- cec_received_msg(hdmi->cec_adap, &hdmi->cec_rx_msg);
- } else if (hdmi->cec_tx_ok) {
- cec_transmit_done(hdmi->cec_adap, CEC_TX_STATUS_OK,
+ struct vc4_hdmi *vc4_hdmi = vc4->hdmi;
+
+ if (vc4_hdmi->cec_irq_was_rx) {
+ if (vc4_hdmi->cec_rx_msg.len)
+ cec_received_msg(vc4_hdmi->cec_adap,
+ &vc4_hdmi->cec_rx_msg);
+ } else if (vc4_hdmi->cec_tx_ok) {
+ cec_transmit_done(vc4_hdmi->cec_adap, CEC_TX_STATUS_OK,
0, 0, 0, 0);
} else {
/*
* This CEC implementation makes 1 retry, so if we
* get a NACK, then that means it made 2 attempts.
*/
- cec_transmit_done(hdmi->cec_adap, CEC_TX_STATUS_NACK,
+ cec_transmit_done(vc4_hdmi->cec_adap, CEC_TX_STATUS_NACK,
0, 2, 0, 0);
}
return IRQ_HANDLED;
@@ -1099,23 +1100,23 @@ static void vc4_cec_read_msg(struct vc4_dev *vc4, u32 cntrl1)
static irqreturn_t vc4_cec_irq_handler(int irq, void *priv)
{
struct vc4_dev *vc4 = priv;
- struct vc4_hdmi *hdmi = vc4->hdmi;
+ struct vc4_hdmi *vc4_hdmi = vc4->hdmi;
u32 stat = HDMI_READ(VC4_HDMI_CPU_STATUS);
u32 cntrl1, cntrl5;
if (!(stat & VC4_HDMI_CPU_CEC))
return IRQ_NONE;
- hdmi->cec_rx_msg.len = 0;
+ vc4_hdmi->cec_rx_msg.len = 0;
cntrl1 = HDMI_READ(VC4_HDMI_CEC_CNTRL_1);
cntrl5 = HDMI_READ(VC4_HDMI_CEC_CNTRL_5);
- hdmi->cec_irq_was_rx = cntrl5 & VC4_HDMI_CEC_RX_CEC_INT;
- if (hdmi->cec_irq_was_rx) {
+ vc4_hdmi->cec_irq_was_rx = cntrl5 & VC4_HDMI_CEC_RX_CEC_INT;
+ if (vc4_hdmi->cec_irq_was_rx) {
vc4_cec_read_msg(vc4, cntrl1);
cntrl1 |= VC4_HDMI_CEC_CLEAR_RECEIVE_OFF;
HDMI_WRITE(VC4_HDMI_CEC_CNTRL_1, cntrl1);
cntrl1 &= ~VC4_HDMI_CEC_CLEAR_RECEIVE_OFF;
} else {
- hdmi->cec_tx_ok = cntrl1 & VC4_HDMI_CEC_TX_STATUS_GOOD;
+ vc4_hdmi->cec_tx_ok = cntrl1 & VC4_HDMI_CEC_TX_STATUS_GOOD;
cntrl1 &= ~VC4_HDMI_CEC_START_XMIT_BEGIN;
}
HDMI_WRITE(VC4_HDMI_CEC_CNTRL_1, cntrl1);
@@ -1217,44 +1218,44 @@ static int vc4_hdmi_bind(struct device *dev, struct device *master, void *data)
struct platform_device *pdev = to_platform_device(dev);
struct drm_device *drm = dev_get_drvdata(master);
struct vc4_dev *vc4 = drm->dev_private;
- struct vc4_hdmi *hdmi;
+ struct vc4_hdmi *vc4_hdmi;
struct drm_encoder *encoder;
struct device_node *ddc_node;
u32 value;
int ret;
- hdmi = devm_kzalloc(dev, sizeof(*hdmi), GFP_KERNEL);
- if (!hdmi)
+ vc4_hdmi = devm_kzalloc(dev, sizeof(*vc4_hdmi), GFP_KERNEL);
+ if (!vc4_hdmi)
return -ENOMEM;
- hdmi->pdev = pdev;
- encoder = &hdmi->encoder.base.base;
+ vc4_hdmi->pdev = pdev;
+ encoder = &vc4_hdmi->encoder.base.base;
encoder->base.type = VC4_ENCODER_TYPE_HDMI0;
- hdmi->hdmicore_regs = vc4_ioremap_regs(pdev, 0);
- if (IS_ERR(hdmi->hdmicore_regs))
- return PTR_ERR(hdmi->hdmicore_regs);
+ vc4_hdmi->hdmicore_regs = vc4_ioremap_regs(pdev, 0);
+ if (IS_ERR(vc4_hdmi->hdmicore_regs))
+ return PTR_ERR(vc4_hdmi->hdmicore_regs);
- hdmi->hd_regs = vc4_ioremap_regs(pdev, 1);
- if (IS_ERR(hdmi->hd_regs))
- return PTR_ERR(hdmi->hd_regs);
+ vc4_hdmi->hd_regs = vc4_ioremap_regs(pdev, 1);
+ if (IS_ERR(vc4_hdmi->hd_regs))
+ return PTR_ERR(vc4_hdmi->hd_regs);
- hdmi->hdmi_regset.base = hdmi->hdmicore_regs;
- hdmi->hdmi_regset.regs = hdmi_regs;
- hdmi->hdmi_regset.nregs = ARRAY_SIZE(hdmi_regs);
- hdmi->hd_regset.base = hdmi->hd_regs;
- hdmi->hd_regset.regs = hd_regs;
- hdmi->hd_regset.nregs = ARRAY_SIZE(hd_regs);
+ 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);
- hdmi->pixel_clock = devm_clk_get(dev, "pixel");
- if (IS_ERR(hdmi->pixel_clock)) {
+ vc4_hdmi->pixel_clock = devm_clk_get(dev, "pixel");
+ if (IS_ERR(vc4_hdmi->pixel_clock)) {
DRM_ERROR("Failed to get pixel clock\n");
- return PTR_ERR(hdmi->pixel_clock);
+ return PTR_ERR(vc4_hdmi->pixel_clock);
}
- hdmi->hsm_clock = devm_clk_get(dev, "hdmi");
- if (IS_ERR(hdmi->hsm_clock)) {
+ 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(hdmi->hsm_clock);
+ return PTR_ERR(vc4_hdmi->hsm_clock);
}
ddc_node = of_parse_phandle(dev->of_node, "ddc", 0);
@@ -1263,9 +1264,9 @@ static int vc4_hdmi_bind(struct device *dev, struct device *master, void *data)
return -ENODEV;
}
- hdmi->ddc = of_find_i2c_adapter_by_node(ddc_node);
+ vc4_hdmi->ddc = of_find_i2c_adapter_by_node(ddc_node);
of_node_put(ddc_node);
- if (!hdmi->ddc) {
+ if (!vc4_hdmi->ddc) {
DRM_DEBUG("Failed to get ddc i2c adapter by node\n");
return -EPROBE_DEFER;
}
@@ -1274,13 +1275,13 @@ static int vc4_hdmi_bind(struct device *dev, struct device *master, void *data)
* needs to be a bit higher than the pixel clock rate
* (generally 148.5Mhz).
*/
- ret = clk_set_rate(hdmi->hsm_clock, HSM_CLOCK_FREQ);
+ ret = clk_set_rate(vc4_hdmi->hsm_clock, HSM_CLOCK_FREQ);
if (ret) {
DRM_ERROR("Failed to set HSM clock rate: %d\n", ret);
goto err_put_i2c;
}
- ret = clk_prepare_enable(hdmi->hsm_clock);
+ ret = clk_prepare_enable(vc4_hdmi->hsm_clock);
if (ret) {
DRM_ERROR("Failed to turn on HDMI state machine clock: %d\n",
ret);
@@ -1293,18 +1294,18 @@ static int vc4_hdmi_bind(struct device *dev, struct device *master, void *data)
if (of_find_property(dev->of_node, "hpd-gpios", &value)) {
enum of_gpio_flags hpd_gpio_flags;
- hdmi->hpd_gpio = of_get_named_gpio_flags(dev->of_node,
- "hpd-gpios", 0,
- &hpd_gpio_flags);
- if (hdmi->hpd_gpio < 0) {
- ret = hdmi->hpd_gpio;
+ vc4_hdmi->hpd_gpio = of_get_named_gpio_flags(dev->of_node,
+ "hpd-gpios", 0,
+ &hpd_gpio_flags);
+ if (vc4_hdmi->hpd_gpio < 0) {
+ ret = vc4_hdmi->hpd_gpio;
goto err_unprepare_hsm;
}
- hdmi->hpd_active_low = hpd_gpio_flags & OF_GPIO_ACTIVE_LOW;
+ vc4_hdmi->hpd_active_low = hpd_gpio_flags & OF_GPIO_ACTIVE_LOW;
}
- vc4->hdmi = hdmi;
+ vc4->hdmi = vc4_hdmi;
/* HDMI core must be enabled. */
if (!(HD_READ(VC4_HD_M_CTL) & VC4_HD_M_ENABLE)) {
@@ -1319,21 +1320,21 @@ static int vc4_hdmi_bind(struct device *dev, struct device *master, void *data)
drm_simple_encoder_init(drm, encoder, DRM_MODE_ENCODER_TMDS);
drm_encoder_helper_add(encoder, &vc4_hdmi_encoder_helper_funcs);
- ret = vc4_hdmi_connector_init(drm, hdmi);
+ ret = vc4_hdmi_connector_init(drm, vc4_hdmi);
if (ret)
goto err_destroy_encoder;
#ifdef CONFIG_DRM_VC4_HDMI_CEC
- hdmi->cec_adap = cec_allocate_adapter(&vc4_hdmi_cec_adap_ops,
- vc4, "vc4",
- CEC_CAP_DEFAULTS |
- CEC_CAP_CONNECTOR_INFO, 1);
- ret = PTR_ERR_OR_ZERO(hdmi->cec_adap);
+ vc4_hdmi->cec_adap = cec_allocate_adapter(&vc4_hdmi_cec_adap_ops,
+ vc4, "vc4",
+ CEC_CAP_DEFAULTS |
+ CEC_CAP_CONNECTOR_INFO, 1);
+ ret = PTR_ERR_OR_ZERO(vc4_hdmi->cec_adap);
if (ret < 0)
goto err_destroy_conn;
- cec_fill_conn_info_from_drm(&conn_info, &hdmi->connector.base);
- cec_s_conn_info(hdmi->cec_adap, &conn_info);
+ cec_fill_conn_info_from_drm(&conn_info, &vc4_hdmi->connector.base);
+ cec_s_conn_info(vc4_hdmi->cec_adap, &conn_info);
HDMI_WRITE(VC4_HDMI_CPU_MASK_SET, 0xffffffff);
value = HDMI_READ(VC4_HDMI_CEC_CNTRL_1);
@@ -1352,32 +1353,32 @@ static int vc4_hdmi_bind(struct device *dev, struct device *master, void *data)
"vc4 hdmi cec", vc4);
if (ret)
goto err_delete_cec_adap;
- ret = cec_register_adapter(hdmi->cec_adap, dev);
+ ret = cec_register_adapter(vc4_hdmi->cec_adap, dev);
if (ret < 0)
goto err_delete_cec_adap;
#endif
- ret = vc4_hdmi_audio_init(hdmi);
+ ret = vc4_hdmi_audio_init(vc4_hdmi);
if (ret)
goto err_destroy_encoder;
- vc4_debugfs_add_file(drm, "hdmi_regs", vc4_hdmi_debugfs_regs, hdmi);
+ vc4_debugfs_add_file(drm, "hdmi_regs", vc4_hdmi_debugfs_regs, vc4_hdmi);
return 0;
#ifdef CONFIG_DRM_VC4_HDMI_CEC
err_delete_cec_adap:
- cec_delete_adapter(hdmi->cec_adap);
+ cec_delete_adapter(vc4_hdmi->cec_adap);
err_destroy_conn:
- vc4_hdmi_connector_destroy(&hdmi->connector.base);
+ vc4_hdmi_connector_destroy(&vc4_hdmi->connector.base);
#endif
err_destroy_encoder:
drm_encoder_cleanup(encoder);
err_unprepare_hsm:
- clk_disable_unprepare(hdmi->hsm_clock);
+ clk_disable_unprepare(vc4_hdmi->hsm_clock);
pm_runtime_disable(dev);
err_put_i2c:
- put_device(&hdmi->ddc->dev);
+ put_device(&vc4_hdmi->ddc->dev);
return ret;
}
@@ -1387,16 +1388,16 @@ static void vc4_hdmi_unbind(struct device *dev, struct device *master,
{
struct drm_device *drm = dev_get_drvdata(master);
struct vc4_dev *vc4 = drm->dev_private;
- struct vc4_hdmi *hdmi = vc4->hdmi;
+ struct vc4_hdmi *vc4_hdmi = vc4->hdmi;
- cec_unregister_adapter(hdmi->cec_adap);
- vc4_hdmi_connector_destroy(&hdmi->connector.base);
- drm_encoder_cleanup(&hdmi->encoder.base.base);
+ cec_unregister_adapter(vc4_hdmi->cec_adap);
+ vc4_hdmi_connector_destroy(&vc4_hdmi->connector.base);
+ vc4_hdmi_encoder_destroy(&vc4_hdmi->encoder.base.base);
- clk_disable_unprepare(hdmi->hsm_clock);
+ clk_disable_unprepare(vc4_hdmi->hsm_clock);
pm_runtime_disable(dev);
- put_device(&hdmi->ddc->dev);
+ put_device(&vc4_hdmi->ddc->dev);
vc4->hdmi = NULL;
}
--
git-series 0.9.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [PATCH v3 071/105] drm/vc4: hdmi: Remove DDC argument to connector_init
From: Maxime Ripard @ 2020-05-27 15:48 UTC (permalink / raw)
To: Nicolas Saenz Julienne, Eric Anholt
Cc: Tim Gover, Dave Stevenson, linux-kernel, dri-devel,
bcm-kernel-feedback-list, linux-rpi-kernel, Phil Elwell,
linux-arm-kernel, Maxime Ripard
In-Reply-To: <cover.aaf2100bd7da4609f8bcb8216247d4b4e4379639.1590594512.git-series.maxime@cerno.tech>
Now that we are passing the vc4_hdmi structure to the connector init
function, we can simply use the pointer in that structure instead of
having the pointer as an argument.
Signed-off-by: Maxime Ripard <maxime@cerno.tech>
---
drivers/gpu/drm/vc4/vc4_hdmi.c | 7 +++----
1 file changed, 3 insertions(+), 4 deletions(-)
diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c
index c1cb8790b552..a2f848632e8d 100644
--- a/drivers/gpu/drm/vc4/vc4_hdmi.c
+++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
@@ -192,8 +192,7 @@ static const struct drm_connector_helper_funcs vc4_hdmi_connector_helper_funcs =
};
static int vc4_hdmi_connector_init(struct drm_device *dev,
- struct vc4_hdmi *vc4_hdmi,
- struct i2c_adapter *ddc)
+ struct vc4_hdmi *vc4_hdmi)
{
struct vc4_hdmi_connector *hdmi_connector = &vc4_hdmi->connector;
struct drm_connector *connector = &hdmi_connector->base;
@@ -205,7 +204,7 @@ static int vc4_hdmi_connector_init(struct drm_device *dev,
drm_connector_init_with_ddc(dev, connector,
&vc4_hdmi_connector_funcs,
DRM_MODE_CONNECTOR_HDMIA,
- ddc);
+ vc4_hdmi->ddc);
drm_connector_helper_add(connector, &vc4_hdmi_connector_helper_funcs);
/* Create and attach TV margin props to this connector. */
@@ -1320,7 +1319,7 @@ static int vc4_hdmi_bind(struct device *dev, struct device *master, void *data)
drm_simple_encoder_init(drm, encoder, DRM_MODE_ENCODER_TMDS);
drm_encoder_helper_add(encoder, &vc4_hdmi_encoder_helper_funcs);
- ret = vc4_hdmi_connector_init(drm, hdmi, hdmi->ddc);
+ ret = vc4_hdmi_connector_init(drm, hdmi);
if (ret)
goto err_destroy_encoder;
--
git-series 0.9.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [PATCH v3 070/105] drm/vc4: hdmi: rework connectors and encoders
From: Maxime Ripard @ 2020-05-27 15:48 UTC (permalink / raw)
To: Nicolas Saenz Julienne, Eric Anholt
Cc: Tim Gover, Dave Stevenson, linux-kernel, dri-devel,
bcm-kernel-feedback-list, linux-rpi-kernel, Phil Elwell,
linux-arm-kernel, Maxime Ripard
In-Reply-To: <cover.aaf2100bd7da4609f8bcb8216247d4b4e4379639.1590594512.git-series.maxime@cerno.tech>
the vc4_hdmi driver has some custom structures to hold the data it needs to
associate with the drm_encoder and drm_connector structures.
However, it allocates them separately from the vc4_hdmi structure which
makes it more complicated than it needs to be.
Move those structures to be contained by vc4_hdmi and update the code
accordingly.
Signed-off-by: Maxime Ripard <maxime@cerno.tech>
---
drivers/gpu/drm/vc4/vc4_hdmi.c | 87 ++++++++++++++++-------------------
drivers/gpu/drm/vc4/vc4_hdmi.h | 64 +++++++++++++-------------
2 files changed, 72 insertions(+), 79 deletions(-)
diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c
index 41573fca5a40..c1cb8790b552 100644
--- a/drivers/gpu/drm/vc4/vc4_hdmi.c
+++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
@@ -191,20 +191,15 @@ static const struct drm_connector_helper_funcs vc4_hdmi_connector_helper_funcs =
.get_modes = vc4_hdmi_connector_get_modes,
};
-static struct drm_connector *vc4_hdmi_connector_init(struct drm_device *dev,
- struct drm_encoder *encoder,
- struct i2c_adapter *ddc)
+static int vc4_hdmi_connector_init(struct drm_device *dev,
+ struct vc4_hdmi *vc4_hdmi,
+ struct i2c_adapter *ddc)
{
- struct drm_connector *connector;
- struct vc4_hdmi_connector *hdmi_connector;
+ struct vc4_hdmi_connector *hdmi_connector = &vc4_hdmi->connector;
+ struct drm_connector *connector = &hdmi_connector->base;
+ struct drm_encoder *encoder = &vc4_hdmi->encoder.base.base;
int ret;
- hdmi_connector = devm_kzalloc(dev->dev, sizeof(*hdmi_connector),
- GFP_KERNEL);
- if (!hdmi_connector)
- return ERR_PTR(-ENOMEM);
- connector = &hdmi_connector->base;
-
hdmi_connector->encoder = encoder;
drm_connector_init_with_ddc(dev, connector,
@@ -216,7 +211,7 @@ static struct drm_connector *vc4_hdmi_connector_init(struct drm_device *dev,
/* Create and attach TV margin props to this connector. */
ret = drm_mode_create_tv_margin_properties(dev);
if (ret)
- return ERR_PTR(ret);
+ return ret;
drm_connector_attach_tv_margin_properties(connector);
@@ -228,7 +223,7 @@ static struct drm_connector *vc4_hdmi_connector_init(struct drm_device *dev,
drm_connector_attach_encoder(connector, encoder);
- return connector;
+ return 0;
}
static int vc4_hdmi_stop_packet(struct drm_encoder *encoder,
@@ -298,21 +293,22 @@ static void vc4_hdmi_set_avi_infoframe(struct drm_encoder *encoder)
struct vc4_hdmi_encoder *vc4_encoder = to_vc4_hdmi_encoder(encoder);
struct vc4_dev *vc4 = encoder->dev->dev_private;
struct vc4_hdmi *hdmi = vc4->hdmi;
- struct drm_connector_state *cstate = hdmi->connector->state;
+ struct drm_connector *connector = &hdmi->connector.base;
+ struct drm_connector_state *cstate = connector->state;
struct drm_crtc *crtc = encoder->crtc;
const struct drm_display_mode *mode = &crtc->state->adjusted_mode;
union hdmi_infoframe frame;
int ret;
ret = drm_hdmi_avi_infoframe_from_display_mode(&frame.avi,
- hdmi->connector, mode);
+ connector, mode);
if (ret < 0) {
DRM_ERROR("couldn't fill AVI infoframe\n");
return;
}
drm_hdmi_avi_infoframe_quant_range(&frame.avi,
- hdmi->connector, mode,
+ connector, mode,
vc4_encoder->limited_rgb_range ?
HDMI_QUANTIZATION_RANGE_LIMITED :
HDMI_QUANTIZATION_RANGE_FULL);
@@ -628,7 +624,8 @@ static const struct drm_encoder_helper_funcs vc4_hdmi_encoder_helper_funcs = {
/* HDMI audio codec callbacks */
static void vc4_hdmi_audio_set_mai_clock(struct vc4_hdmi *hdmi)
{
- struct drm_device *drm = hdmi->encoder->dev;
+ struct drm_encoder *encoder = &hdmi->encoder.base.base;
+ struct drm_device *drm = encoder->dev;
struct vc4_dev *vc4 = to_vc4_dev(drm);
u32 hsm_clock = clk_get_rate(hdmi->hsm_clock);
unsigned long n, m;
@@ -647,7 +644,7 @@ static void vc4_hdmi_audio_set_mai_clock(struct vc4_hdmi *hdmi)
static void vc4_hdmi_set_n_cts(struct vc4_hdmi *hdmi)
{
- struct drm_encoder *encoder = hdmi->encoder;
+ struct drm_encoder *encoder = &hdmi->encoder.base.base;
struct drm_crtc *crtc = encoder->crtc;
struct drm_device *drm = encoder->dev;
struct vc4_dev *vc4 = to_vc4_dev(drm);
@@ -685,7 +682,8 @@ static int vc4_hdmi_audio_startup(struct snd_pcm_substream *substream,
struct snd_soc_dai *dai)
{
struct vc4_hdmi *hdmi = dai_to_hdmi(dai);
- struct drm_encoder *encoder = hdmi->encoder;
+ struct drm_encoder *encoder = &hdmi->encoder.base.base;
+ struct drm_connector *connector = &hdmi->connector.base;
struct vc4_dev *vc4 = to_vc4_dev(encoder->dev);
int ret;
@@ -702,8 +700,7 @@ static int vc4_hdmi_audio_startup(struct snd_pcm_substream *substream,
VC4_HDMI_RAM_PACKET_ENABLE))
return -ENODEV;
- ret = snd_pcm_hw_constraint_eld(substream->runtime,
- hdmi->connector->eld);
+ ret = snd_pcm_hw_constraint_eld(substream->runtime, connector->eld);
if (ret)
return ret;
@@ -717,7 +714,7 @@ static int vc4_hdmi_audio_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
static void vc4_hdmi_audio_reset(struct vc4_hdmi *hdmi)
{
- struct drm_encoder *encoder = hdmi->encoder;
+ struct drm_encoder *encoder = &hdmi->encoder.base.base;
struct drm_device *drm = encoder->dev;
struct device *dev = &hdmi->pdev->dev;
struct vc4_dev *vc4 = to_vc4_dev(drm);
@@ -751,7 +748,7 @@ static int vc4_hdmi_audio_hw_params(struct snd_pcm_substream *substream,
struct snd_soc_dai *dai)
{
struct vc4_hdmi *hdmi = dai_to_hdmi(dai);
- struct drm_encoder *encoder = hdmi->encoder;
+ struct drm_encoder *encoder = &hdmi->encoder.base.base;
struct drm_device *drm = encoder->dev;
struct device *dev = &hdmi->pdev->dev;
struct vc4_dev *vc4 = to_vc4_dev(drm);
@@ -824,7 +821,7 @@ static int vc4_hdmi_audio_trigger(struct snd_pcm_substream *substream, int cmd,
struct snd_soc_dai *dai)
{
struct vc4_hdmi *hdmi = dai_to_hdmi(dai);
- struct drm_encoder *encoder = hdmi->encoder;
+ struct drm_encoder *encoder = &hdmi->encoder.base.base;
struct drm_device *drm = encoder->dev;
struct vc4_dev *vc4 = to_vc4_dev(drm);
@@ -868,9 +865,10 @@ static int vc4_hdmi_audio_eld_ctl_info(struct snd_kcontrol *kcontrol,
{
struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
struct vc4_hdmi *hdmi = snd_component_to_hdmi(component);
+ struct drm_connector *connector = &hdmi->connector.base;
uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES;
- uinfo->count = sizeof(hdmi->connector->eld);
+ uinfo->count = sizeof(connector->eld);
return 0;
}
@@ -880,9 +878,10 @@ static int vc4_hdmi_audio_eld_ctl_get(struct snd_kcontrol *kcontrol,
{
struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
struct vc4_hdmi *hdmi = snd_component_to_hdmi(component);
+ struct drm_connector *connector = &hdmi->connector.base;
- memcpy(ucontrol->value.bytes.data, hdmi->connector->eld,
- sizeof(hdmi->connector->eld));
+ memcpy(ucontrol->value.bytes.data, connector->eld,
+ sizeof(connector->eld));
return 0;
}
@@ -1220,7 +1219,7 @@ static int vc4_hdmi_bind(struct device *dev, struct device *master, void *data)
struct drm_device *drm = dev_get_drvdata(master);
struct vc4_dev *vc4 = drm->dev_private;
struct vc4_hdmi *hdmi;
- struct vc4_hdmi_encoder *vc4_hdmi_encoder;
+ struct drm_encoder *encoder;
struct device_node *ddc_node;
u32 value;
int ret;
@@ -1229,14 +1228,10 @@ static int vc4_hdmi_bind(struct device *dev, struct device *master, void *data)
if (!hdmi)
return -ENOMEM;
- vc4_hdmi_encoder = devm_kzalloc(dev, sizeof(*vc4_hdmi_encoder),
- GFP_KERNEL);
- if (!vc4_hdmi_encoder)
- return -ENOMEM;
- vc4_hdmi_encoder->base.type = VC4_ENCODER_TYPE_HDMI0;
- hdmi->encoder = &vc4_hdmi_encoder->base.base;
-
hdmi->pdev = pdev;
+ encoder = &hdmi->encoder.base.base;
+ encoder->base.type = VC4_ENCODER_TYPE_HDMI0;
+
hdmi->hdmicore_regs = vc4_ioremap_regs(pdev, 0);
if (IS_ERR(hdmi->hdmicore_regs))
return PTR_ERR(hdmi->hdmicore_regs);
@@ -1322,15 +1317,13 @@ static int vc4_hdmi_bind(struct device *dev, struct device *master, void *data)
}
pm_runtime_enable(dev);
- drm_simple_encoder_init(drm, hdmi->encoder, DRM_MODE_ENCODER_TMDS);
- drm_encoder_helper_add(hdmi->encoder, &vc4_hdmi_encoder_helper_funcs);
+ drm_simple_encoder_init(drm, encoder, DRM_MODE_ENCODER_TMDS);
+ drm_encoder_helper_add(encoder, &vc4_hdmi_encoder_helper_funcs);
- hdmi->connector =
- vc4_hdmi_connector_init(drm, hdmi->encoder, hdmi->ddc);
- if (IS_ERR(hdmi->connector)) {
- ret = PTR_ERR(hdmi->connector);
+ ret = vc4_hdmi_connector_init(drm, hdmi, hdmi->ddc);
+ if (ret)
goto err_destroy_encoder;
- }
+
#ifdef CONFIG_DRM_VC4_HDMI_CEC
hdmi->cec_adap = cec_allocate_adapter(&vc4_hdmi_cec_adap_ops,
vc4, "vc4",
@@ -1340,7 +1333,7 @@ static int vc4_hdmi_bind(struct device *dev, struct device *master, void *data)
if (ret < 0)
goto err_destroy_conn;
- cec_fill_conn_info_from_drm(&conn_info, hdmi->connector);
+ cec_fill_conn_info_from_drm(&conn_info, &hdmi->connector.base);
cec_s_conn_info(hdmi->cec_adap, &conn_info);
HDMI_WRITE(VC4_HDMI_CPU_MASK_SET, 0xffffffff);
@@ -1377,10 +1370,10 @@ static int vc4_hdmi_bind(struct device *dev, struct device *master, void *data)
err_delete_cec_adap:
cec_delete_adapter(hdmi->cec_adap);
err_destroy_conn:
- vc4_hdmi_connector_destroy(hdmi->connector);
+ vc4_hdmi_connector_destroy(&hdmi->connector.base);
#endif
err_destroy_encoder:
- drm_encoder_cleanup(hdmi->encoder);
+ drm_encoder_cleanup(encoder);
err_unprepare_hsm:
clk_disable_unprepare(hdmi->hsm_clock);
pm_runtime_disable(dev);
@@ -1398,8 +1391,8 @@ static void vc4_hdmi_unbind(struct device *dev, struct device *master,
struct vc4_hdmi *hdmi = vc4->hdmi;
cec_unregister_adapter(hdmi->cec_adap);
- vc4_hdmi_connector_destroy(hdmi->connector);
- drm_encoder_cleanup(hdmi->encoder);
+ vc4_hdmi_connector_destroy(&hdmi->connector.base);
+ drm_encoder_cleanup(&hdmi->encoder.base.base);
clk_disable_unprepare(hdmi->hsm_clock);
pm_runtime_disable(dev);
diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.h b/drivers/gpu/drm/vc4/vc4_hdmi.h
index 5ec5d1f6b1e6..17079a39f1b1 100644
--- a/drivers/gpu/drm/vc4/vc4_hdmi.h
+++ b/drivers/gpu/drm/vc4/vc4_hdmi.h
@@ -8,6 +8,36 @@
#include "vc4_drv.h"
+/* VC4 HDMI encoder KMS struct */
+struct vc4_hdmi_encoder {
+ struct vc4_encoder base;
+ bool hdmi_monitor;
+ bool limited_rgb_range;
+};
+
+static inline struct vc4_hdmi_encoder *
+to_vc4_hdmi_encoder(struct drm_encoder *encoder)
+{
+ return container_of(encoder, struct vc4_hdmi_encoder, base.base);
+}
+
+/* VC4 HDMI connector KMS struct */
+struct vc4_hdmi_connector {
+ struct drm_connector base;
+
+ /* Since the connector is attached to just the one encoder,
+ * this is the reference to it so we can do the best_encoder()
+ * hook.
+ */
+ struct drm_encoder *encoder;
+};
+
+static inline struct vc4_hdmi_connector *
+to_vc4_hdmi_connector(struct drm_connector *connector)
+{
+ return container_of(connector, struct vc4_hdmi_connector, base);
+}
+
/* HDMI audio information */
struct vc4_hdmi_audio {
struct snd_soc_card card;
@@ -25,8 +55,8 @@ struct vc4_hdmi_audio {
struct vc4_hdmi {
struct platform_device *pdev;
- struct drm_encoder *encoder;
- struct drm_connector *connector;
+ struct vc4_hdmi_encoder encoder;
+ struct vc4_hdmi_connector connector;
struct vc4_hdmi_audio audio;
@@ -53,34 +83,4 @@ struct vc4_hdmi {
#define HD_READ(offset) readl(vc4->hdmi->hd_regs + offset)
#define HD_WRITE(offset, val) writel(val, vc4->hdmi->hd_regs + offset)
-/* VC4 HDMI encoder KMS struct */
-struct vc4_hdmi_encoder {
- struct vc4_encoder base;
- bool hdmi_monitor;
- bool limited_rgb_range;
-};
-
-static inline struct vc4_hdmi_encoder *
-to_vc4_hdmi_encoder(struct drm_encoder *encoder)
-{
- return container_of(encoder, struct vc4_hdmi_encoder, base.base);
-}
-
-/* VC4 HDMI connector KMS struct */
-struct vc4_hdmi_connector {
- struct drm_connector base;
-
- /* Since the connector is attached to just the one encoder,
- * this is the reference to it so we can do the best_encoder()
- * hook.
- */
- struct drm_encoder *encoder;
-};
-
-static inline struct vc4_hdmi_connector *
-to_vc4_hdmi_connector(struct drm_connector *connector)
-{
- return container_of(connector, struct vc4_hdmi_connector, base);
-}
-
#endif /* _VC4_HDMI_H_ */
--
git-series 0.9.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [PATCH v3 065/105] drm/vc4: crtc: Move the txp_armed function to the TXP
From: Maxime Ripard @ 2020-05-27 15:48 UTC (permalink / raw)
To: Nicolas Saenz Julienne, Eric Anholt
Cc: Tim Gover, Dave Stevenson, linux-kernel, dri-devel,
bcm-kernel-feedback-list, linux-rpi-kernel, Phil Elwell,
linux-arm-kernel, Maxime Ripard
In-Reply-To: <cover.aaf2100bd7da4609f8bcb8216247d4b4e4379639.1590594512.git-series.maxime@cerno.tech>
The TXP driver is the only place where we need to set the txp_armed flag,
so let's move the function in the TXP driver.
Signed-off-by: Maxime Ripard <maxime@cerno.tech>
---
drivers/gpu/drm/vc4/vc4_crtc.c | 7 -------
drivers/gpu/drm/vc4/vc4_drv.h | 1 -
drivers/gpu/drm/vc4/vc4_txp.c | 9 ++++++++-
3 files changed, 8 insertions(+), 9 deletions(-)
diff --git a/drivers/gpu/drm/vc4/vc4_crtc.c b/drivers/gpu/drm/vc4/vc4_crtc.c
index d284596ec048..fbddd38ba6a9 100644
--- a/drivers/gpu/drm/vc4/vc4_crtc.c
+++ b/drivers/gpu/drm/vc4/vc4_crtc.c
@@ -483,13 +483,6 @@ static void vc4_crtc_atomic_disable(struct drm_crtc *crtc,
}
}
-void vc4_crtc_txp_armed(struct drm_crtc_state *state)
-{
- struct vc4_crtc_state *vc4_state = to_vc4_crtc_state(state);
-
- vc4_state->txp_armed = true;
-}
-
static void vc4_crtc_atomic_enable(struct drm_crtc *crtc,
struct drm_crtc_state *old_state)
{
diff --git a/drivers/gpu/drm/vc4/vc4_drv.h b/drivers/gpu/drm/vc4/vc4_drv.h
index 999841b1edd8..e14ed9799ecc 100644
--- a/drivers/gpu/drm/vc4/vc4_drv.h
+++ b/drivers/gpu/drm/vc4/vc4_drv.h
@@ -831,7 +831,6 @@ void vc4_crtc_destroy_state(struct drm_crtc *crtc,
struct drm_crtc_state *state);
void vc4_crtc_reset(struct drm_crtc *crtc);
void vc4_crtc_handle_vblank(struct vc4_crtc *crtc);
-void vc4_crtc_txp_armed(struct drm_crtc_state *state);
void vc4_crtc_get_margins(struct drm_crtc_state *state,
unsigned int *right, unsigned int *left,
unsigned int *top, unsigned int *bottom);
diff --git a/drivers/gpu/drm/vc4/vc4_txp.c b/drivers/gpu/drm/vc4/vc4_txp.c
index bf720206727f..d9a8ab87ad25 100644
--- a/drivers/gpu/drm/vc4/vc4_txp.c
+++ b/drivers/gpu/drm/vc4/vc4_txp.c
@@ -222,6 +222,13 @@ static const u32 txp_fmts[] = {
TXP_FORMAT_BGRA8888,
};
+static void vc4_txp_armed(struct drm_crtc_state *state)
+{
+ struct vc4_crtc_state *vc4_state = to_vc4_crtc_state(state);
+
+ vc4_state->txp_armed = true;
+}
+
static int vc4_txp_connector_atomic_check(struct drm_connector *conn,
struct drm_atomic_state *state)
{
@@ -256,7 +263,7 @@ static int vc4_txp_connector_atomic_check(struct drm_connector *conn,
if (fb->pitches[0] & GENMASK(3, 0))
return -EINVAL;
- vc4_crtc_txp_armed(crtc_state);
+ vc4_txp_armed(crtc_state);
return 0;
}
--
git-series 0.9.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [PATCH v3 060/105] drm/vc4: crtc: Make state functions public
From: Maxime Ripard @ 2020-05-27 15:48 UTC (permalink / raw)
To: Nicolas Saenz Julienne, Eric Anholt
Cc: Tim Gover, Dave Stevenson, linux-kernel, dri-devel,
bcm-kernel-feedback-list, linux-rpi-kernel, Phil Elwell,
linux-arm-kernel, Maxime Ripard
In-Reply-To: <cover.aaf2100bd7da4609f8bcb8216247d4b4e4379639.1590594512.git-series.maxime@cerno.tech>
We'll need the CRTC state related functions to be exported so that we can
reuse them for the TXP.
Signed-off-by: Maxime Ripard <maxime@cerno.tech>
---
drivers/gpu/drm/vc4/vc4_crtc.c | 21 ++++++++++-----------
drivers/gpu/drm/vc4/vc4_drv.h | 10 ++++++++++
2 files changed, 20 insertions(+), 11 deletions(-)
diff --git a/drivers/gpu/drm/vc4/vc4_crtc.c b/drivers/gpu/drm/vc4/vc4_crtc.c
index a577ed8f929f..4df8cc5387a0 100644
--- a/drivers/gpu/drm/vc4/vc4_crtc.c
+++ b/drivers/gpu/drm/vc4/vc4_crtc.c
@@ -201,7 +201,7 @@ static bool vc4_crtc_get_scanout_position(struct drm_crtc *crtc,
return ret;
}
-static void vc4_crtc_destroy(struct drm_crtc *crtc)
+void vc4_crtc_destroy(struct drm_crtc *crtc)
{
drm_crtc_cleanup(crtc);
}
@@ -803,11 +803,11 @@ static int vc4_async_page_flip(struct drm_crtc *crtc,
return 0;
}
-static int vc4_page_flip(struct drm_crtc *crtc,
- struct drm_framebuffer *fb,
- struct drm_pending_vblank_event *event,
- uint32_t flags,
- struct drm_modeset_acquire_ctx *ctx)
+int vc4_page_flip(struct drm_crtc *crtc,
+ struct drm_framebuffer *fb,
+ struct drm_pending_vblank_event *event,
+ uint32_t flags,
+ struct drm_modeset_acquire_ctx *ctx)
{
if (flags & DRM_MODE_PAGE_FLIP_ASYNC)
return vc4_async_page_flip(crtc, fb, event, flags);
@@ -815,7 +815,7 @@ static int vc4_page_flip(struct drm_crtc *crtc,
return drm_atomic_helper_page_flip(crtc, fb, event, flags, ctx);
}
-static struct drm_crtc_state *vc4_crtc_duplicate_state(struct drm_crtc *crtc)
+struct drm_crtc_state *vc4_crtc_duplicate_state(struct drm_crtc *crtc)
{
struct vc4_crtc_state *vc4_state, *old_vc4_state;
@@ -832,8 +832,8 @@ static struct drm_crtc_state *vc4_crtc_duplicate_state(struct drm_crtc *crtc)
return &vc4_state->base;
}
-static void vc4_crtc_destroy_state(struct drm_crtc *crtc,
- struct drm_crtc_state *state)
+void vc4_crtc_destroy_state(struct drm_crtc *crtc,
+ struct drm_crtc_state *state)
{
struct vc4_dev *vc4 = to_vc4_dev(crtc->dev);
struct vc4_crtc_state *vc4_state = to_vc4_crtc_state(state);
@@ -850,8 +850,7 @@ static void vc4_crtc_destroy_state(struct drm_crtc *crtc,
drm_atomic_helper_crtc_destroy_state(crtc, state);
}
-static void
-vc4_crtc_reset(struct drm_crtc *crtc)
+void vc4_crtc_reset(struct drm_crtc *crtc)
{
if (crtc->state)
vc4_crtc_destroy_state(crtc, crtc->state);
diff --git a/drivers/gpu/drm/vc4/vc4_drv.h b/drivers/gpu/drm/vc4/vc4_drv.h
index 32e9de15262a..da4d2391a4ba 100644
--- a/drivers/gpu/drm/vc4/vc4_drv.h
+++ b/drivers/gpu/drm/vc4/vc4_drv.h
@@ -798,6 +798,16 @@ void vc4_bo_remove_from_purgeable_pool(struct vc4_bo *bo);
/* vc4_crtc.c */
extern struct platform_driver vc4_crtc_driver;
int vc4_crtc_disable_at_boot(struct drm_crtc *crtc);
+void vc4_crtc_destroy(struct drm_crtc *crtc);
+int vc4_page_flip(struct drm_crtc *crtc,
+ struct drm_framebuffer *fb,
+ struct drm_pending_vblank_event *event,
+ uint32_t flags,
+ struct drm_modeset_acquire_ctx *ctx);
+struct drm_crtc_state *vc4_crtc_duplicate_state(struct drm_crtc *crtc);
+void vc4_crtc_destroy_state(struct drm_crtc *crtc,
+ struct drm_crtc_state *state);
+void vc4_crtc_reset(struct drm_crtc *crtc);
void vc4_crtc_handle_vblank(struct vc4_crtc *crtc);
void vc4_crtc_txp_armed(struct drm_crtc_state *state);
void vc4_crtc_get_margins(struct drm_crtc_state *state,
--
git-series 0.9.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [PATCH v3 059/105] drm/vc4: crtc: Add BCM2711 pixelvalves
From: Maxime Ripard @ 2020-05-27 15:48 UTC (permalink / raw)
To: Nicolas Saenz Julienne, Eric Anholt
Cc: Tim Gover, Dave Stevenson, linux-kernel, dri-devel,
bcm-kernel-feedback-list, linux-rpi-kernel, Phil Elwell,
linux-arm-kernel, Maxime Ripard
In-Reply-To: <cover.aaf2100bd7da4609f8bcb8216247d4b4e4379639.1590594512.git-series.maxime@cerno.tech>
The BCM2711 has 5 pixelvalves, so now that our driver is ready, let's add
support for them.
Signed-off-by: Maxime Ripard <maxime@cerno.tech>
---
drivers/gpu/drm/vc4/vc4_crtc.c | 84 ++++++++++++++++++++++++++++++++++-
drivers/gpu/drm/vc4/vc4_regs.h | 6 +++-
2 files changed, 88 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/vc4/vc4_crtc.c b/drivers/gpu/drm/vc4/vc4_crtc.c
index 9efd7cb25590..a577ed8f929f 100644
--- a/drivers/gpu/drm/vc4/vc4_crtc.c
+++ b/drivers/gpu/drm/vc4/vc4_crtc.c
@@ -229,6 +229,13 @@ static u32 vc4_get_fifo_full_level(struct vc4_crtc *vc4_crtc, u32 format)
case PV_CONTROL_FORMAT_24:
case PV_CONTROL_FORMAT_DSIV_24:
default:
+ /*
+ * For some reason, the pixelvalve4 doesn't work with
+ * the usual formula and will only work with 32.
+ */
+ if (vc4_crtc->data->hvs_output == 5)
+ return 32;
+
return fifo_len_bytes - 3 * HVS_FIFO_LATENCY_PIX;
}
}
@@ -237,9 +244,14 @@ static u32 vc4_crtc_get_fifo_full_level_bits(struct vc4_crtc *vc4_crtc,
u32 format)
{
u32 level = vc4_get_fifo_full_level(vc4_crtc, format);
+ u32 ret = 0;
- return VC4_SET_FIELD(level & 0x3f,
- PV_CONTROL_FIFO_LEVEL);
+ if (level > 0x3f)
+ ret |= VC4_SET_FIELD((level >> 6) & 0x3,
+ PV5_CONTROL_FIFO_LEVEL_HIGH);
+
+ return ret | VC4_SET_FIELD(level & 0x3f,
+ PV_CONTROL_FIFO_LEVEL);
}
/*
@@ -277,6 +289,8 @@ static void vc4_crtc_pixelvalve_reset(struct drm_crtc *crtc)
static void vc4_crtc_config_pv(struct drm_crtc *crtc)
{
+ struct drm_device *dev = crtc->dev;
+ struct vc4_dev *vc4 = to_vc4_dev(dev);
struct drm_encoder *encoder = vc4_get_crtc_encoder(crtc);
struct vc4_encoder *vc4_encoder = to_vc4_encoder(encoder);
struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc);
@@ -356,6 +370,10 @@ static void vc4_crtc_config_pv(struct drm_crtc *crtc)
if (is_dsi)
CRTC_WRITE(PV_HACT_ACT, mode->hdisplay * pixel_rep);
+ if (vc4->hvs->hvs5)
+ CRTC_WRITE(PV_MUX_CFG,
+ VC4_SET_FIELD(8, PV_MUX_CFG_RGB_PIXEL_MUX_MODE));
+
CRTC_WRITE(PV_CONTROL, PV_CONTROL_FIFO_CLR |
vc4_crtc_get_fifo_full_level_bits(vc4_crtc, format) |
VC4_SET_FIELD(format, PV_CONTROL_FORMAT) |
@@ -904,10 +922,72 @@ static const struct vc4_crtc_data bcm2835_pv2_data = {
},
};
+static const struct vc4_crtc_data bcm2711_pv0_data = {
+ .debugfs_name = "crtc0_regs",
+ .hvs_available_channels = BIT(0),
+ .hvs_output = 0,
+ .fifo_depth = 64,
+ .pixels_per_clock = 1,
+ .encoder_types = {
+ [0] = VC4_ENCODER_TYPE_DSI0,
+ [1] = VC4_ENCODER_TYPE_DPI,
+ },
+};
+
+static const struct vc4_crtc_data bcm2711_pv1_data = {
+ .debugfs_name = "crtc1_regs",
+ .hvs_available_channels = BIT(0) | BIT(1) | BIT(2),
+ .hvs_output = 3,
+ .fifo_depth = 64,
+ .pixels_per_clock = 1,
+ .encoder_types = {
+ [0] = VC4_ENCODER_TYPE_DSI1,
+ [1] = VC4_ENCODER_TYPE_SMI,
+ },
+};
+
+static const struct vc4_crtc_data bcm2711_pv2_data = {
+ .debugfs_name = "crtc2_regs",
+ .hvs_available_channels = BIT(0) | BIT(1) | BIT(2),
+ .hvs_output = 4,
+ .fifo_depth = 256,
+ .pixels_per_clock = 2,
+ .encoder_types = {
+ [0] = VC4_ENCODER_TYPE_HDMI0,
+ },
+};
+
+static const struct vc4_crtc_data bcm2711_pv3_data = {
+ .debugfs_name = "crtc3_regs",
+ .hvs_available_channels = BIT(1),
+ .hvs_output = 1,
+ .fifo_depth = 64,
+ .pixels_per_clock = 1,
+ .encoder_types = {
+ [0] = VC4_ENCODER_TYPE_VEC,
+ },
+};
+
+static const struct vc4_crtc_data bcm2711_pv4_data = {
+ .debugfs_name = "crtc4_regs",
+ .hvs_available_channels = BIT(0) | BIT(1) | BIT(2),
+ .hvs_output = 5,
+ .fifo_depth = 64,
+ .pixels_per_clock = 2,
+ .encoder_types = {
+ [0] = VC4_ENCODER_TYPE_HDMI1,
+ },
+};
+
static const struct of_device_id vc4_crtc_dt_match[] = {
{ .compatible = "brcm,bcm2835-pixelvalve0", .data = &bcm2835_pv0_data },
{ .compatible = "brcm,bcm2835-pixelvalve1", .data = &bcm2835_pv1_data },
{ .compatible = "brcm,bcm2835-pixelvalve2", .data = &bcm2835_pv2_data },
+ { .compatible = "brcm,bcm2711-pixelvalve0", .data = &bcm2711_pv0_data },
+ { .compatible = "brcm,bcm2711-pixelvalve1", .data = &bcm2711_pv1_data },
+ { .compatible = "brcm,bcm2711-pixelvalve2", .data = &bcm2711_pv2_data },
+ { .compatible = "brcm,bcm2711-pixelvalve3", .data = &bcm2711_pv3_data },
+ { .compatible = "brcm,bcm2711-pixelvalve4", .data = &bcm2711_pv4_data },
{}
};
diff --git a/drivers/gpu/drm/vc4/vc4_regs.h b/drivers/gpu/drm/vc4/vc4_regs.h
index b96ebbb1354b..35279b118d41 100644
--- a/drivers/gpu/drm/vc4/vc4_regs.h
+++ b/drivers/gpu/drm/vc4/vc4_regs.h
@@ -130,6 +130,8 @@
#define V3D_ERRSTAT 0x00f20
#define PV_CONTROL 0x00
+# define PV5_CONTROL_FIFO_LEVEL_HIGH_MASK VC4_MASK(26, 25)
+# define PV5_CONTROL_FIFO_LEVEL_HIGH_SHIFT 25
# define PV_CONTROL_FORMAT_MASK VC4_MASK(23, 21)
# define PV_CONTROL_FORMAT_SHIFT 21
# define PV_CONTROL_FORMAT_24 0
@@ -209,6 +211,10 @@
#define PV_HACT_ACT 0x30
+#define PV_MUX_CFG 0x34
+# define PV_MUX_CFG_RGB_PIXEL_MUX_MODE_MASK VC4_MASK(5, 2)
+# define PV_MUX_CFG_RGB_PIXEL_MUX_MODE_SHIFT 2
+
#define SCALER_CHANNELS_COUNT 3
#define SCALER_DISPCTRL 0x00000000
--
git-series 0.9.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [PATCH v3 058/105] dt-bindings: display: vc4: pv: Add BCM2711 pixel valves
From: Maxime Ripard @ 2020-05-27 15:48 UTC (permalink / raw)
To: Nicolas Saenz Julienne, Eric Anholt
Cc: devicetree, Tim Gover, Dave Stevenson, linux-kernel, dri-devel,
Rob Herring, bcm-kernel-feedback-list, linux-rpi-kernel,
Phil Elwell, linux-arm-kernel, Maxime Ripard
In-Reply-To: <cover.aaf2100bd7da4609f8bcb8216247d4b4e4379639.1590594512.git-series.maxime@cerno.tech>
The BCM2711 comes with other pixelvalves that have different requirements
and capabilities. Let's document their compatible.
Cc: devicetree@vger.kernel.org
Reviewed-by: Rob Herring <robh+dt@kernel.org>
Signed-off-by: Maxime Ripard <maxime@cerno.tech>
---
Documentation/devicetree/bindings/display/brcm,bcm2835-pixelvalve0.yaml | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/Documentation/devicetree/bindings/display/brcm,bcm2835-pixelvalve0.yaml b/Documentation/devicetree/bindings/display/brcm,bcm2835-pixelvalve0.yaml
index e60791db1fa1..4e1ba03f6477 100644
--- a/Documentation/devicetree/bindings/display/brcm,bcm2835-pixelvalve0.yaml
+++ b/Documentation/devicetree/bindings/display/brcm,bcm2835-pixelvalve0.yaml
@@ -15,6 +15,11 @@ properties:
- brcm,bcm2835-pixelvalve0
- brcm,bcm2835-pixelvalve1
- brcm,bcm2835-pixelvalve2
+ - brcm,bcm2711-pixelvalve0
+ - brcm,bcm2711-pixelvalve1
+ - brcm,bcm2711-pixelvalve2
+ - brcm,bcm2711-pixelvalve3
+ - brcm,bcm2711-pixelvalve4
reg:
maxItems: 1
--
git-series 0.9.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [PATCH v3 057/105] drm/vc4: drv: Disable the CRTC at boot time
From: Maxime Ripard @ 2020-05-27 15:48 UTC (permalink / raw)
To: Nicolas Saenz Julienne, Eric Anholt
Cc: Tim Gover, Dave Stevenson, linux-kernel, dri-devel,
bcm-kernel-feedback-list, linux-rpi-kernel, Phil Elwell,
linux-arm-kernel, Maxime Ripard
In-Reply-To: <cover.aaf2100bd7da4609f8bcb8216247d4b4e4379639.1590594512.git-series.maxime@cerno.tech>
In order to prevent issues during the firmware to KMS transition, we need
to make sure the pixelvalve are disabled at boot time so that the DRM state
matches the hardware state.
Signed-off-by: Maxime Ripard <maxime@cerno.tech>
---
drivers/gpu/drm/vc4/vc4_crtc.c | 23 +++++++++++++++++++++++
drivers/gpu/drm/vc4/vc4_drv.c | 4 ++++
drivers/gpu/drm/vc4/vc4_drv.h | 1 +
3 files changed, 28 insertions(+)
diff --git a/drivers/gpu/drm/vc4/vc4_crtc.c b/drivers/gpu/drm/vc4/vc4_crtc.c
index 3d2a31cad7fa..9efd7cb25590 100644
--- a/drivers/gpu/drm/vc4/vc4_crtc.c
+++ b/drivers/gpu/drm/vc4/vc4_crtc.c
@@ -409,6 +409,29 @@ static int vc4_crtc_disable(struct drm_crtc *crtc, unsigned int channel)
return 0;
}
+int vc4_crtc_disable_at_boot(struct drm_crtc *crtc)
+{
+ struct drm_device *dev = crtc->dev;
+ struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc);
+ int channel;
+
+ if (of_device_is_compatible(vc4_crtc->pdev->dev.of_node,
+ "brcm,bcm2835-txp"))
+ return 0;
+
+ if (!(CRTC_READ(PV_CONTROL) & PV_CONTROL_EN))
+ return 0;
+
+ if (!(CRTC_READ(PV_V_CONTROL) & PV_VCONTROL_VIDEN))
+ return 0;
+
+ channel = vc4_hvs_get_fifo_from_output(dev, vc4_crtc->data->hvs_output);
+ if (channel < 0)
+ return 0;
+
+ return vc4_crtc_disable(crtc, channel);
+}
+
static void vc4_crtc_atomic_disable(struct drm_crtc *crtc,
struct drm_crtc_state *old_state)
{
diff --git a/drivers/gpu/drm/vc4/vc4_drv.c b/drivers/gpu/drm/vc4/vc4_drv.c
index ed7893ee188a..ea082b9d3c90 100644
--- a/drivers/gpu/drm/vc4/vc4_drv.c
+++ b/drivers/gpu/drm/vc4/vc4_drv.c
@@ -252,6 +252,7 @@ static int vc4_drm_bind(struct device *dev)
struct drm_device *drm;
struct vc4_dev *vc4;
struct device_node *node;
+ struct drm_crtc *crtc;
int ret = 0;
dev->coherent_dma_mask = DMA_BIT_MASK(32);
@@ -298,6 +299,9 @@ static int vc4_drm_bind(struct device *dev)
if (ret < 0)
goto unbind_all;
+ drm_for_each_crtc(crtc, drm)
+ vc4_crtc_disable_at_boot(crtc);
+
ret = drm_dev_register(drm, 0);
if (ret < 0)
goto unbind_all;
diff --git a/drivers/gpu/drm/vc4/vc4_drv.h b/drivers/gpu/drm/vc4/vc4_drv.h
index 99001f8783aa..32e9de15262a 100644
--- a/drivers/gpu/drm/vc4/vc4_drv.h
+++ b/drivers/gpu/drm/vc4/vc4_drv.h
@@ -797,6 +797,7 @@ void vc4_bo_remove_from_purgeable_pool(struct vc4_bo *bo);
/* vc4_crtc.c */
extern struct platform_driver vc4_crtc_driver;
+int vc4_crtc_disable_at_boot(struct drm_crtc *crtc);
void vc4_crtc_handle_vblank(struct vc4_crtc *crtc);
void vc4_crtc_txp_armed(struct drm_crtc_state *state);
void vc4_crtc_get_margins(struct drm_crtc_state *state,
--
git-series 0.9.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [PATCH v3 056/105] drm/vc4: crtc: Move the CRTC disable out
From: Maxime Ripard @ 2020-05-27 15:48 UTC (permalink / raw)
To: Nicolas Saenz Julienne, Eric Anholt
Cc: Tim Gover, Dave Stevenson, linux-kernel, dri-devel,
bcm-kernel-feedback-list, linux-rpi-kernel, Phil Elwell,
linux-arm-kernel, Maxime Ripard
In-Reply-To: <cover.aaf2100bd7da4609f8bcb8216247d4b4e4379639.1590594512.git-series.maxime@cerno.tech>
We'll need to reuse the part that disables the HVS and PixelValve during
boot too, so let's create a separate function.
Signed-off-by: Maxime Ripard <maxime@cerno.tech>
---
drivers/gpu/drm/vc4/vc4_crtc.c | 34 ++++++++++++++++++++++------------
1 file changed, 22 insertions(+), 12 deletions(-)
diff --git a/drivers/gpu/drm/vc4/vc4_crtc.c b/drivers/gpu/drm/vc4/vc4_crtc.c
index ecb3431470dd..3d2a31cad7fa 100644
--- a/drivers/gpu/drm/vc4/vc4_crtc.c
+++ b/drivers/gpu/drm/vc4/vc4_crtc.c
@@ -382,20 +382,14 @@ static void require_hvs_enabled(struct drm_device *dev)
SCALER_DISPCTRL_ENABLE);
}
-static void vc4_crtc_atomic_disable(struct drm_crtc *crtc,
- struct drm_crtc_state *old_state)
+static int vc4_crtc_disable(struct drm_crtc *crtc, unsigned int channel)
{
- struct drm_device *dev = crtc->dev;
- struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc);
struct drm_encoder *encoder = vc4_get_crtc_encoder(crtc);
struct vc4_encoder *vc4_encoder = to_vc4_encoder(encoder);
+ struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc);
+ struct drm_device *dev = crtc->dev;
int ret;
- require_hvs_enabled(dev);
-
- /* Disable vblank irq handling before crtc is disabled. */
- drm_crtc_vblank_off(crtc);
-
CRTC_WRITE(PV_V_CONTROL,
CRTC_READ(PV_V_CONTROL) & ~PV_VCONTROL_VIDEN);
ret = wait_for(!(CRTC_READ(PV_V_CONTROL) & PV_VCONTROL_VIDEN), 1);
@@ -403,15 +397,31 @@ static void vc4_crtc_atomic_disable(struct drm_crtc *crtc,
mdelay(20);
- if (vc4_encoder->post_crtc_disable)
+ if (vc4_encoder && vc4_encoder->post_crtc_disable)
vc4_encoder->post_crtc_disable(encoder);
vc4_crtc_pixelvalve_reset(crtc);
- vc4_hvs_atomic_disable(crtc, old_state);
+ vc4_hvs_stop_channel(dev, channel);
- if (vc4_encoder->post_crtc_powerdown)
+ if (vc4_encoder && vc4_encoder->post_crtc_powerdown)
vc4_encoder->post_crtc_powerdown(encoder);
+ return 0;
+}
+
+static void vc4_crtc_atomic_disable(struct drm_crtc *crtc,
+ struct drm_crtc_state *old_state)
+{
+ struct vc4_crtc_state *old_vc4_state = to_vc4_crtc_state(old_state);
+ struct drm_device *dev = crtc->dev;
+
+ require_hvs_enabled(dev);
+
+ /* Disable vblank irq handling before crtc is disabled. */
+ drm_crtc_vblank_off(crtc);
+
+ vc4_crtc_disable(crtc, old_vc4_state->assigned_channel);
+
/*
* Make sure we issue a vblank event after disabling the CRTC if
* someone was waiting it.
--
git-series 0.9.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [PATCH v3 053/105] drm/vc4: crtc: Clear the PixelValve FIFO during configuration
From: Maxime Ripard @ 2020-05-27 15:48 UTC (permalink / raw)
To: Nicolas Saenz Julienne, Eric Anholt
Cc: Tim Gover, Dave Stevenson, linux-kernel, dri-devel,
bcm-kernel-feedback-list, linux-rpi-kernel, Phil Elwell,
linux-arm-kernel, Maxime Ripard
In-Reply-To: <cover.aaf2100bd7da4609f8bcb8216247d4b4e4379639.1590594512.git-series.maxime@cerno.tech>
Even though it's not really clear why we need to flush the PV FIFO during
the configuration even though we started by flushing it, experience shows
that without it we get a stale pixel stuck in the FIFO between the HVS and
the PV.
Signed-off-by: Maxime Ripard <maxime@cerno.tech>
---
drivers/gpu/drm/vc4/vc4_crtc.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/vc4/vc4_crtc.c b/drivers/gpu/drm/vc4/vc4_crtc.c
index 61e0945a8697..ecb3431470dd 100644
--- a/drivers/gpu/drm/vc4/vc4_crtc.c
+++ b/drivers/gpu/drm/vc4/vc4_crtc.c
@@ -356,7 +356,7 @@ static void vc4_crtc_config_pv(struct drm_crtc *crtc)
if (is_dsi)
CRTC_WRITE(PV_HACT_ACT, mode->hdisplay * pixel_rep);
- CRTC_WRITE(PV_CONTROL,
+ CRTC_WRITE(PV_CONTROL, PV_CONTROL_FIFO_CLR |
vc4_crtc_get_fifo_full_level_bits(vc4_crtc, format) |
VC4_SET_FIELD(format, PV_CONTROL_FORMAT) |
VC4_SET_FIELD(pixel_rep - 1, PV_CONTROL_PIXEL_REP) |
--
git-series 0.9.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [PATCH v3 054/105] drm/vc4: hvs: Make the stop_channel function public
From: Maxime Ripard @ 2020-05-27 15:48 UTC (permalink / raw)
To: Nicolas Saenz Julienne, Eric Anholt
Cc: Tim Gover, Dave Stevenson, linux-kernel, dri-devel,
bcm-kernel-feedback-list, linux-rpi-kernel, Phil Elwell,
linux-arm-kernel, Maxime Ripard
In-Reply-To: <cover.aaf2100bd7da4609f8bcb8216247d4b4e4379639.1590594512.git-series.maxime@cerno.tech>
During the transition from the firmware to the KMS driver, we need to pay
particular attention to how we deal with the pixelvalves that have already
been enabled, otherwise either timeouts or stuck pixels can occur. We'll
thus need to call the function to stop an HVS channel at boot.
Signed-off-by: Maxime Ripard <maxime@cerno.tech>
---
drivers/gpu/drm/vc4/vc4_drv.h | 1 +
drivers/gpu/drm/vc4/vc4_hvs.c | 2 +-
2 files changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/vc4/vc4_drv.h b/drivers/gpu/drm/vc4/vc4_drv.h
index ba24bad86905..d51b695732e0 100644
--- a/drivers/gpu/drm/vc4/vc4_drv.h
+++ b/drivers/gpu/drm/vc4/vc4_drv.h
@@ -879,6 +879,7 @@ void vc4_irq_reset(struct drm_device *dev);
/* vc4_hvs.c */
extern struct platform_driver vc4_hvs_driver;
+void vc4_hvs_stop_channel(struct drm_device *dev, unsigned int output);
int vc4_hvs_atomic_check(struct drm_crtc *crtc, struct drm_crtc_state *state);
void vc4_hvs_atomic_enable(struct drm_crtc *crtc, struct drm_crtc_state *old_state);
void vc4_hvs_atomic_disable(struct drm_crtc *crtc, struct drm_crtc_state *old_state);
diff --git a/drivers/gpu/drm/vc4/vc4_hvs.c b/drivers/gpu/drm/vc4/vc4_hvs.c
index ec58870acb7b..1785c49534cf 100644
--- a/drivers/gpu/drm/vc4/vc4_hvs.c
+++ b/drivers/gpu/drm/vc4/vc4_hvs.c
@@ -248,7 +248,7 @@ static int vc4_hvs_init_channel(struct vc4_dev *vc4, struct drm_crtc *crtc,
return 0;
}
-static void vc4_hvs_stop_channel(struct drm_device *dev, unsigned int chan)
+void vc4_hvs_stop_channel(struct drm_device *dev, unsigned int chan)
{
struct vc4_dev *vc4 = to_vc4_dev(dev);
--
git-series 0.9.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [PATCH v3 079/105] drm/vc4: hdmi: Introduce resource init and variant
From: Maxime Ripard @ 2020-05-27 15:48 UTC (permalink / raw)
To: Nicolas Saenz Julienne, Eric Anholt
Cc: Tim Gover, Dave Stevenson, linux-kernel, dri-devel,
bcm-kernel-feedback-list, linux-rpi-kernel, Phil Elwell,
linux-arm-kernel, Maxime Ripard
In-Reply-To: <cover.aaf2100bd7da4609f8bcb8216247d4b4e4379639.1590594512.git-series.maxime@cerno.tech>
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: Maxime Ripard <maxime@cerno.tech>
---
drivers/gpu/drm/vc4/vc4_hdmi.c | 67 ++++++++++++++++++++++-------------
drivers/gpu/drm/vc4/vc4_hdmi.h | 10 +++++-
2 files changed, 54 insertions(+), 23 deletions(-)
diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c
index 963be5bc1d5f..2b275585440d 100644
--- a/drivers/gpu/drm/vc4/vc4_hdmi.c
+++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
@@ -1178,38 +1178,23 @@ 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;
- int ret;
-
- vc4_hdmi = devm_kzalloc(dev, sizeof(*vc4_hdmi), GFP_KERNEL);
- if (!vc4_hdmi)
- return -ENOMEM;
-
- vc4_hdmi->pdev = pdev;
- encoder = &vc4_hdmi->encoder.base.base;
- encoder->base.type = VC4_ENCODER_TYPE_HDMI0;
+ struct platform_device *pdev = vc4_hdmi->pdev;
+ struct device *dev = &pdev->dev;
vc4_hdmi->hdmicore_regs = vc4_ioremap_regs(pdev, 0);
if (IS_ERR(vc4_hdmi->hdmicore_regs))
return PTR_ERR(vc4_hdmi->hdmicore_regs);
+ 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_regs = vc4_ioremap_regs(pdev, 1);
if (IS_ERR(vc4_hdmi->hd_regs))
return PTR_ERR(vc4_hdmi->hd_regs);
- 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);
@@ -1219,12 +1204,44 @@ static int vc4_hdmi_bind(struct device *dev, struct device *master, void *data)
DRM_ERROR("Failed to get pixel clock\n");
return PTR_ERR(vc4_hdmi->pixel_clock);
}
+
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
+ struct platform_device *pdev = to_platform_device(dev);
+ struct drm_device *drm = dev_get_drvdata(master);
+ const struct vc4_hdmi_variant *variant;
+ 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;
+
+ vc4_hdmi->pdev = pdev;
+ variant = of_device_get_match_data(dev);
+ vc4_hdmi->variant = variant;
+ vc4_hdmi->encoder.base.type = VC4_ENCODER_TYPE_HDMI0;
+ encoder = &vc4_hdmi->encoder.base.base;
+
+ 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");
@@ -1384,8 +1401,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 },
{}
};
diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.h b/drivers/gpu/drm/vc4/vc4_hdmi.h
index 88794136d2e4..4cd712779ad3 100644
--- a/drivers/gpu/drm/vc4/vc4_hdmi.h
+++ b/drivers/gpu/drm/vc4/vc4_hdmi.h
@@ -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;
@@ -37,6 +46,7 @@ struct vc4_hdmi_audio {
/* General HDMI hardware state. */
struct vc4_hdmi {
struct platform_device *pdev;
+ const struct vc4_hdmi_variant *variant;
struct vc4_hdmi_encoder encoder;
struct drm_connector connector;
--
git-series 0.9.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [PATCH v3 078/105] drm/vc4: hdmi: Remove vc4_hdmi_connector
From: Maxime Ripard @ 2020-05-27 15:48 UTC (permalink / raw)
To: Nicolas Saenz Julienne, Eric Anholt
Cc: Tim Gover, Dave Stevenson, linux-kernel, dri-devel,
bcm-kernel-feedback-list, linux-rpi-kernel, Phil Elwell,
linux-arm-kernel, Maxime Ripard
In-Reply-To: <cover.aaf2100bd7da4609f8bcb8216247d4b4e4379639.1590594512.git-series.maxime@cerno.tech>
The vc4_hdmi_connector was only used to switch between drm_connector to
drm_encoder. However, we can now use vc4_hdmi to do the switch, so that
structure is redundant.
Signed-off-by: Maxime Ripard <maxime@cerno.tech>
---
drivers/gpu/drm/vc4/vc4_hdmi.c | 19 ++++++++-----------
drivers/gpu/drm/vc4/vc4_hdmi.h | 23 ++---------------------
2 files changed, 10 insertions(+), 32 deletions(-)
diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c
index 850111665839..963be5bc1d5f 100644
--- a/drivers/gpu/drm/vc4/vc4_hdmi.c
+++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
@@ -189,13 +189,10 @@ static const struct drm_connector_helper_funcs vc4_hdmi_connector_helper_funcs =
static int vc4_hdmi_connector_init(struct drm_device *dev,
struct vc4_hdmi *vc4_hdmi)
{
- struct vc4_hdmi_connector *hdmi_connector = &vc4_hdmi->connector;
- struct drm_connector *connector = &hdmi_connector->base;
+ struct drm_connector *connector = &vc4_hdmi->connector;
struct drm_encoder *encoder = &vc4_hdmi->encoder.base.base;
int ret;
- hdmi_connector->encoder = encoder;
-
drm_connector_init_with_ddc(dev, connector,
&vc4_hdmi_connector_funcs,
DRM_MODE_CONNECTOR_HDMIA,
@@ -284,7 +281,7 @@ static void vc4_hdmi_set_avi_infoframe(struct drm_encoder *encoder)
{
struct vc4_hdmi *vc4_hdmi = encoder_to_vc4_hdmi(encoder);
struct vc4_hdmi_encoder *vc4_encoder = to_vc4_hdmi_encoder(encoder);
- struct drm_connector *connector = &vc4_hdmi->connector.base;
+ struct drm_connector *connector = &vc4_hdmi->connector;
struct drm_connector_state *cstate = connector->state;
struct drm_crtc *crtc = encoder->crtc;
const struct drm_display_mode *mode = &crtc->state->adjusted_mode;
@@ -663,7 +660,7 @@ static int vc4_hdmi_audio_startup(struct snd_pcm_substream *substream,
{
struct vc4_hdmi *vc4_hdmi = dai_to_hdmi(dai);
struct drm_encoder *encoder = &vc4_hdmi->encoder.base.base;
- struct drm_connector *connector = &vc4_hdmi->connector.base;
+ struct drm_connector *connector = &vc4_hdmi->connector;
int ret;
if (vc4_hdmi->audio.substream && vc4_hdmi->audio.substream != substream)
@@ -837,7 +834,7 @@ static int vc4_hdmi_audio_eld_ctl_info(struct snd_kcontrol *kcontrol,
{
struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
struct vc4_hdmi *vc4_hdmi = snd_component_to_hdmi(component);
- struct drm_connector *connector = &vc4_hdmi->connector.base;
+ struct drm_connector *connector = &vc4_hdmi->connector;
uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES;
uinfo->count = sizeof(connector->eld);
@@ -850,7 +847,7 @@ static int vc4_hdmi_audio_eld_ctl_get(struct snd_kcontrol *kcontrol,
{
struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
struct vc4_hdmi *vc4_hdmi = snd_component_to_hdmi(component);
- struct drm_connector *connector = &vc4_hdmi->connector.base;
+ struct drm_connector *connector = &vc4_hdmi->connector;
memcpy(ucontrol->value.bytes.data, connector->eld,
sizeof(connector->eld));
@@ -1301,7 +1298,7 @@ static int vc4_hdmi_bind(struct device *dev, struct device *master, void *data)
if (ret < 0)
goto err_destroy_conn;
- cec_fill_conn_info_from_drm(&conn_info, &vc4_hdmi->connector.base);
+ cec_fill_conn_info_from_drm(&conn_info, &vc4_hdmi->connector);
cec_s_conn_info(vc4_hdmi->cec_adap, &conn_info);
HDMI_WRITE(VC4_HDMI_CPU_MASK_SET, 0xffffffff);
@@ -1338,7 +1335,7 @@ static int vc4_hdmi_bind(struct device *dev, struct device *master, void *data)
err_delete_cec_adap:
cec_delete_adapter(vc4_hdmi->cec_adap);
err_destroy_conn:
- vc4_hdmi_connector_destroy(&vc4_hdmi->connector.base);
+ vc4_hdmi_connector_destroy(&vc4_hdmi->connector);
#endif
err_destroy_encoder:
drm_encoder_cleanup(encoder);
@@ -1362,7 +1359,7 @@ static void vc4_hdmi_unbind(struct device *dev, struct device *master,
struct vc4_hdmi *vc4_hdmi = snd_soc_card_get_drvdata(card);
cec_unregister_adapter(vc4_hdmi->cec_adap);
- vc4_hdmi_connector_destroy(&vc4_hdmi->connector.base);
+ vc4_hdmi_connector_destroy(&vc4_hdmi->connector);
drm_encoder_cleanup(&vc4_hdmi->encoder.base.base);
clk_disable_unprepare(vc4_hdmi->hsm_clock);
diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.h b/drivers/gpu/drm/vc4/vc4_hdmi.h
index 749a807cd1f3..88794136d2e4 100644
--- a/drivers/gpu/drm/vc4/vc4_hdmi.h
+++ b/drivers/gpu/drm/vc4/vc4_hdmi.h
@@ -21,23 +21,6 @@ to_vc4_hdmi_encoder(struct drm_encoder *encoder)
return container_of(encoder, struct vc4_hdmi_encoder, base.base);
}
-/* VC4 HDMI connector KMS struct */
-struct vc4_hdmi_connector {
- struct drm_connector base;
-
- /* Since the connector is attached to just the one encoder,
- * this is the reference to it so we can do the best_encoder()
- * hook.
- */
- struct drm_encoder *encoder;
-};
-
-static inline struct vc4_hdmi_connector *
-to_vc4_hdmi_connector(struct drm_connector *connector)
-{
- return container_of(connector, struct vc4_hdmi_connector, base);
-}
-
/* HDMI audio information */
struct vc4_hdmi_audio {
struct snd_soc_card card;
@@ -56,7 +39,7 @@ struct vc4_hdmi {
struct platform_device *pdev;
struct vc4_hdmi_encoder encoder;
- struct vc4_hdmi_connector connector;
+ struct drm_connector connector;
struct vc4_hdmi_audio audio;
@@ -81,9 +64,7 @@ struct vc4_hdmi {
static inline struct vc4_hdmi *
connector_to_vc4_hdmi(struct drm_connector *connector)
{
- struct vc4_hdmi_connector *_connector = to_vc4_hdmi_connector(connector);
-
- return container_of(_connector, struct vc4_hdmi, connector);
+ return container_of(connector, struct vc4_hdmi, connector);
}
static inline struct vc4_hdmi *
--
git-series 0.9.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [PATCH v3 069/105] drm/vc4: hdmi: Move structure to header
From: Maxime Ripard @ 2020-05-27 15:48 UTC (permalink / raw)
To: Nicolas Saenz Julienne, Eric Anholt
Cc: Tim Gover, Dave Stevenson, linux-kernel, dri-devel,
bcm-kernel-feedback-list, linux-rpi-kernel, Phil Elwell,
linux-arm-kernel, Maxime Ripard
In-Reply-To: <cover.aaf2100bd7da4609f8bcb8216247d4b4e4379639.1590594512.git-series.maxime@cerno.tech>
We will need to share the vc4_hdmi and related structures with multiple
files, so let's create a header for it.
Signed-off-by: Maxime Ripard <maxime@cerno.tech>
---
drivers/gpu/drm/vc4/vc4_hdmi.c | 76 +-------------------------------
drivers/gpu/drm/vc4/vc4_hdmi.h | 86 +++++++++++++++++++++++++++++++++++-
2 files changed, 87 insertions(+), 75 deletions(-)
create mode 100644 drivers/gpu/drm/vc4/vc4_hdmi.h
diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c
index 38fe942a327b..41573fca5a40 100644
--- a/drivers/gpu/drm/vc4/vc4_hdmi.c
+++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
@@ -49,87 +49,13 @@
#include <sound/soc.h>
#include "media/cec.h"
#include "vc4_drv.h"
+#include "vc4_hdmi.h"
#include "vc4_regs.h"
#define HSM_CLOCK_FREQ 163682864
#define CEC_CLOCK_FREQ 40000
#define CEC_CLOCK_DIV (HSM_CLOCK_FREQ / CEC_CLOCK_FREQ)
-/* HDMI audio information */
-struct vc4_hdmi_audio {
- struct snd_soc_card card;
- struct snd_soc_dai_link link;
- struct snd_soc_dai_link_component cpu;
- struct snd_soc_dai_link_component codec;
- struct snd_soc_dai_link_component platform;
- int samplerate;
- int channels;
- struct snd_dmaengine_dai_dma_data dma_data;
- struct snd_pcm_substream *substream;
-};
-
-/* General HDMI hardware state. */
-struct vc4_hdmi {
- struct platform_device *pdev;
-
- struct drm_encoder *encoder;
- struct drm_connector *connector;
-
- struct vc4_hdmi_audio audio;
-
- struct i2c_adapter *ddc;
- void __iomem *hdmicore_regs;
- void __iomem *hd_regs;
- int hpd_gpio;
- bool hpd_active_low;
-
- struct cec_adapter *cec_adap;
- struct cec_msg cec_rx_msg;
- bool cec_tx_ok;
- bool cec_irq_was_rx;
-
- struct clk *pixel_clock;
- struct clk *hsm_clock;
-
- struct debugfs_regset32 hdmi_regset;
- struct debugfs_regset32 hd_regset;
-};
-
-#define HDMI_READ(offset) readl(vc4->hdmi->hdmicore_regs + offset)
-#define HDMI_WRITE(offset, val) writel(val, vc4->hdmi->hdmicore_regs + offset)
-#define HD_READ(offset) readl(vc4->hdmi->hd_regs + offset)
-#define HD_WRITE(offset, val) writel(val, vc4->hdmi->hd_regs + offset)
-
-/* VC4 HDMI encoder KMS struct */
-struct vc4_hdmi_encoder {
- struct vc4_encoder base;
- bool hdmi_monitor;
- bool limited_rgb_range;
-};
-
-static inline struct vc4_hdmi_encoder *
-to_vc4_hdmi_encoder(struct drm_encoder *encoder)
-{
- return container_of(encoder, struct vc4_hdmi_encoder, base.base);
-}
-
-/* VC4 HDMI connector KMS struct */
-struct vc4_hdmi_connector {
- struct drm_connector base;
-
- /* Since the connector is attached to just the one encoder,
- * this is the reference to it so we can do the best_encoder()
- * hook.
- */
- struct drm_encoder *encoder;
-};
-
-static inline struct vc4_hdmi_connector *
-to_vc4_hdmi_connector(struct drm_connector *connector)
-{
- return container_of(connector, struct vc4_hdmi_connector, base);
-}
-
static const struct debugfs_reg32 hdmi_regs[] = {
VC4_REG32(VC4_HDMI_CORE_REV),
VC4_REG32(VC4_HDMI_SW_RESET_CONTROL),
diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.h b/drivers/gpu/drm/vc4/vc4_hdmi.h
new file mode 100644
index 000000000000..5ec5d1f6b1e6
--- /dev/null
+++ b/drivers/gpu/drm/vc4/vc4_hdmi.h
@@ -0,0 +1,86 @@
+#ifndef _VC4_HDMI_H_
+#define _VC4_HDMI_H_
+
+#include <drm/drm_connector.h>
+#include <media/cec.h>
+#include <sound/dmaengine_pcm.h>
+#include <sound/soc.h>
+
+#include "vc4_drv.h"
+
+/* HDMI audio information */
+struct vc4_hdmi_audio {
+ struct snd_soc_card card;
+ struct snd_soc_dai_link link;
+ struct snd_soc_dai_link_component cpu;
+ struct snd_soc_dai_link_component codec;
+ struct snd_soc_dai_link_component platform;
+ int samplerate;
+ int channels;
+ struct snd_dmaengine_dai_dma_data dma_data;
+ struct snd_pcm_substream *substream;
+};
+
+/* General HDMI hardware state. */
+struct vc4_hdmi {
+ struct platform_device *pdev;
+
+ struct drm_encoder *encoder;
+ struct drm_connector *connector;
+
+ struct vc4_hdmi_audio audio;
+
+ struct i2c_adapter *ddc;
+ void __iomem *hdmicore_regs;
+ void __iomem *hd_regs;
+ int hpd_gpio;
+ bool hpd_active_low;
+
+ struct cec_adapter *cec_adap;
+ struct cec_msg cec_rx_msg;
+ bool cec_tx_ok;
+ bool cec_irq_was_rx;
+
+ struct clk *pixel_clock;
+ struct clk *hsm_clock;
+
+ struct debugfs_regset32 hdmi_regset;
+ struct debugfs_regset32 hd_regset;
+};
+
+#define HDMI_READ(offset) readl(vc4->hdmi->hdmicore_regs + offset)
+#define HDMI_WRITE(offset, val) writel(val, vc4->hdmi->hdmicore_regs + offset)
+#define HD_READ(offset) readl(vc4->hdmi->hd_regs + offset)
+#define HD_WRITE(offset, val) writel(val, vc4->hdmi->hd_regs + offset)
+
+/* VC4 HDMI encoder KMS struct */
+struct vc4_hdmi_encoder {
+ struct vc4_encoder base;
+ bool hdmi_monitor;
+ bool limited_rgb_range;
+};
+
+static inline struct vc4_hdmi_encoder *
+to_vc4_hdmi_encoder(struct drm_encoder *encoder)
+{
+ return container_of(encoder, struct vc4_hdmi_encoder, base.base);
+}
+
+/* VC4 HDMI connector KMS struct */
+struct vc4_hdmi_connector {
+ struct drm_connector base;
+
+ /* Since the connector is attached to just the one encoder,
+ * this is the reference to it so we can do the best_encoder()
+ * hook.
+ */
+ struct drm_encoder *encoder;
+};
+
+static inline struct vc4_hdmi_connector *
+to_vc4_hdmi_connector(struct drm_connector *connector)
+{
+ return container_of(connector, struct vc4_hdmi_connector, base);
+}
+
+#endif /* _VC4_HDMI_H_ */
--
git-series 0.9.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [PATCH v3 067/105] drm/vc4: crtc: Remove the feed_txp tests
From: Maxime Ripard @ 2020-05-27 15:48 UTC (permalink / raw)
To: Nicolas Saenz Julienne, Eric Anholt
Cc: Tim Gover, Dave Stevenson, linux-kernel, dri-devel,
bcm-kernel-feedback-list, linux-rpi-kernel, Phil Elwell,
linux-arm-kernel, Maxime Ripard
In-Reply-To: <cover.aaf2100bd7da4609f8bcb8216247d4b4e4379639.1590594512.git-series.maxime@cerno.tech>
Now that the code in vc4_crtc accessing registers is only meant for the
pixelvalve, it doesn't make sense anymore to test whether we're accessing
the TXP or not and we can safely remove those checks.
Signed-off-by: Maxime Ripard <maxime@cerno.tech>
---
drivers/gpu/drm/vc4/vc4_crtc.c | 31 ++++++++-----------------------
1 file changed, 8 insertions(+), 23 deletions(-)
diff --git a/drivers/gpu/drm/vc4/vc4_crtc.c b/drivers/gpu/drm/vc4/vc4_crtc.c
index d6eca130644d..e15dc1553df9 100644
--- a/drivers/gpu/drm/vc4/vc4_crtc.c
+++ b/drivers/gpu/drm/vc4/vc4_crtc.c
@@ -405,19 +405,16 @@ static void require_hvs_enabled(struct drm_device *dev)
static int vc4_crtc_disable(struct drm_crtc *crtc, unsigned int channel)
{
- struct vc4_crtc_state *vc4_state = to_vc4_crtc_state(crtc->state);
struct drm_encoder *encoder = vc4_get_crtc_encoder(crtc);
struct vc4_encoder *vc4_encoder = to_vc4_encoder(encoder);
struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc);
struct drm_device *dev = crtc->dev;
int ret;
- if (!vc4_state->feed_txp) {
- CRTC_WRITE(PV_V_CONTROL,
- CRTC_READ(PV_V_CONTROL) & ~PV_VCONTROL_VIDEN);
- ret = wait_for(!(CRTC_READ(PV_V_CONTROL) & PV_VCONTROL_VIDEN), 1);
- WARN_ONCE(ret, "Timeout waiting for !PV_VCONTROL_VIDEN\n");
- }
+ CRTC_WRITE(PV_V_CONTROL,
+ CRTC_READ(PV_V_CONTROL) & ~PV_VCONTROL_VIDEN);
+ ret = wait_for(!(CRTC_READ(PV_V_CONTROL) & PV_VCONTROL_VIDEN), 1);
+ WARN_ONCE(ret, "Timeout waiting for !PV_VCONTROL_VIDEN\n");
mdelay(20);
@@ -488,7 +485,6 @@ static void vc4_crtc_atomic_enable(struct drm_crtc *crtc,
{
struct drm_device *dev = crtc->dev;
struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc);
- struct vc4_crtc_state *vc4_state = to_vc4_crtc_state(crtc->state);
struct drm_encoder *encoder = vc4_get_crtc_encoder(crtc);
struct vc4_encoder *vc4_encoder = to_vc4_encoder(encoder);
@@ -504,10 +500,8 @@ static void vc4_crtc_atomic_enable(struct drm_crtc *crtc,
if (vc4_encoder->pre_crtc_configure)
vc4_encoder->pre_crtc_configure(encoder);
- if (!vc4_state->feed_txp) {
- vc4_crtc_config_pv(crtc);
- CRTC_WRITE(PV_CONTROL, CRTC_READ(PV_CONTROL) | PV_CONTROL_EN);
- }
+ vc4_crtc_config_pv(crtc);
+ CRTC_WRITE(PV_CONTROL, CRTC_READ(PV_CONTROL) | PV_CONTROL_EN);
if (vc4_encoder->pre_crtc_enable)
vc4_encoder->pre_crtc_enable(encoder);
@@ -515,9 +509,8 @@ static void vc4_crtc_atomic_enable(struct drm_crtc *crtc,
/* When feeding the transposer block the pixelvalve is unneeded and
* should not be enabled.
*/
- if (!vc4_state->feed_txp)
- CRTC_WRITE(PV_V_CONTROL,
- CRTC_READ(PV_V_CONTROL) | PV_VCONTROL_VIDEN);
+ CRTC_WRITE(PV_V_CONTROL,
+ CRTC_READ(PV_V_CONTROL) | PV_VCONTROL_VIDEN);
if (vc4_encoder->post_crtc_enable)
vc4_encoder->post_crtc_enable(encoder);
@@ -596,10 +589,6 @@ static int vc4_crtc_atomic_check(struct drm_crtc *crtc,
static int vc4_enable_vblank(struct drm_crtc *crtc)
{
struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc);
- struct vc4_crtc_state *vc4_state = to_vc4_crtc_state(crtc->state);
-
- if (vc4_state->feed_txp)
- return 0;
CRTC_WRITE(PV_INTEN, PV_INT_VFP_START);
@@ -609,10 +598,6 @@ static int vc4_enable_vblank(struct drm_crtc *crtc)
static void vc4_disable_vblank(struct drm_crtc *crtc)
{
struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc);
- struct vc4_crtc_state *vc4_state = to_vc4_crtc_state(crtc->state);
-
- if (vc4_state->feed_txp)
- return;
CRTC_WRITE(PV_INTEN, 0);
}
--
git-series 0.9.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [PATCH v3 066/105] drm/vc4: txp: Turn the TXP into a CRTC of its own
From: Maxime Ripard @ 2020-05-27 15:48 UTC (permalink / raw)
To: Nicolas Saenz Julienne, Eric Anholt
Cc: Tim Gover, Dave Stevenson, linux-kernel, dri-devel,
bcm-kernel-feedback-list, linux-rpi-kernel, Phil Elwell,
linux-arm-kernel, Maxime Ripard
In-Reply-To: <cover.aaf2100bd7da4609f8bcb8216247d4b4e4379639.1590594512.git-series.maxime@cerno.tech>
The TXP so far has been leveraging the PixelValve infrastructure in the
driver, that was really two things: the interaction with DRM's CRTC
concept, the setup of the underlying pixelvalve and the setup of the shared
HVS, the pixelvalve part being irrelevant to the TXP since it accesses the
HVS directly.
Now that we have a clear separation between the three parts, we can
represent the TXP as a CRTC of its own, leveraging the common CRTC and HVS
code, but leaving aside the pixelvalve setup.
Signed-off-by: Maxime Ripard <maxime@cerno.tech>
---
drivers/gpu/drm/vc4/vc4_crtc.c | 19 +------
drivers/gpu/drm/vc4/vc4_txp.c | 100 +++++++++++++++++++++++++++++++++-
2 files changed, 99 insertions(+), 20 deletions(-)
diff --git a/drivers/gpu/drm/vc4/vc4_crtc.c b/drivers/gpu/drm/vc4/vc4_crtc.c
index fbddd38ba6a9..d6eca130644d 100644
--- a/drivers/gpu/drm/vc4/vc4_crtc.c
+++ b/drivers/gpu/drm/vc4/vc4_crtc.c
@@ -583,17 +583,6 @@ static int vc4_crtc_atomic_check(struct drm_crtc *crtc,
if (conn_state->crtc != crtc)
continue;
- /* The writeback connector is implemented using the transposer
- * block which is directly taking its data from the HVS FIFO.
- */
- if (conn->connector_type == DRM_MODE_CONNECTOR_WRITEBACK) {
- state->no_vblank = true;
- vc4_state->feed_txp = true;
- } else {
- state->no_vblank = false;
- vc4_state->feed_txp = false;
- }
-
vc4_state->margins.left = conn_state->tv.margins.left;
vc4_state->margins.right = conn_state->tv.margins.right;
vc4_state->margins.top = conn_state->tv.margins.top;
@@ -1017,7 +1006,6 @@ static void vc4_set_crtc_possible_masks(struct drm_device *drm,
struct drm_crtc *crtc)
{
struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc);
- const struct vc4_crtc_data *crtc_data = vc4_crtc_to_vc4_crtc_data(vc4_crtc);
const struct vc4_pv_data *pv_data = vc4_crtc_to_vc4_pv_data(vc4_crtc);
const enum vc4_encoder_type *encoder_types = pv_data->encoder_types;
struct drm_encoder *encoder;
@@ -1026,13 +1014,6 @@ static void vc4_set_crtc_possible_masks(struct drm_device *drm,
struct vc4_encoder *vc4_encoder;
int i;
- /* HVS FIFO2 can feed the TXP IP. */
- if (crtc_data->hvs_output == 2 &&
- encoder->encoder_type == DRM_MODE_ENCODER_VIRTUAL) {
- encoder->possible_crtcs |= drm_crtc_mask(crtc);
- continue;
- }
-
vc4_encoder = to_vc4_encoder(encoder);
for (i = 0; i < ARRAY_SIZE(pv_data->encoder_types); i++) {
if (vc4_encoder->type == encoder_types[i]) {
diff --git a/drivers/gpu/drm/vc4/vc4_txp.c b/drivers/gpu/drm/vc4/vc4_txp.c
index d9a8ab87ad25..849dcafbfff1 100644
--- a/drivers/gpu/drm/vc4/vc4_txp.c
+++ b/drivers/gpu/drm/vc4/vc4_txp.c
@@ -19,6 +19,7 @@
#include <drm/drm_fourcc.h>
#include <drm/drm_panel.h>
#include <drm/drm_probe_helper.h>
+#include <drm/drm_vblank.h>
#include <drm/drm_writeback.h>
#include "vc4_drv.h"
@@ -145,6 +146,8 @@
#define TXP_WRITE(offset, val) writel(val, txp->regs + (offset))
struct vc4_txp {
+ struct vc4_crtc base;
+
struct platform_device *pdev;
struct drm_writeback_connector connector;
@@ -362,23 +365,105 @@ static const struct drm_encoder_helper_funcs vc4_txp_encoder_helper_funcs = {
.disable = vc4_txp_encoder_disable,
};
+static int vc4_txp_enable_vblank(struct drm_crtc *crtc)
+{
+ return 0;
+}
+
+static void vc4_txp_disable_vblank(struct drm_crtc *crtc) {}
+
+static const struct drm_crtc_funcs vc4_txp_crtc_funcs = {
+ .set_config = drm_atomic_helper_set_config,
+ .destroy = vc4_crtc_destroy,
+ .page_flip = vc4_page_flip,
+ .reset = vc4_crtc_reset,
+ .atomic_duplicate_state = vc4_crtc_duplicate_state,
+ .atomic_destroy_state = vc4_crtc_destroy_state,
+ .gamma_set = drm_atomic_helper_legacy_gamma_set,
+ .enable_vblank = vc4_txp_enable_vblank,
+ .disable_vblank = vc4_txp_disable_vblank,
+};
+
+static int vc4_txp_atomic_check(struct drm_crtc *crtc,
+ struct drm_crtc_state *state)
+{
+ struct vc4_crtc_state *vc4_state = to_vc4_crtc_state(state);
+ int ret;
+
+ ret = vc4_hvs_atomic_check(crtc, state);
+ if (ret)
+ return ret;
+
+ state->no_vblank = true;
+ vc4_state->feed_txp = true;
+
+ return 0;
+}
+
+static void vc4_txp_atomic_enable(struct drm_crtc *crtc,
+ struct drm_crtc_state *old_state)
+{
+ drm_crtc_vblank_on(crtc);
+ vc4_hvs_atomic_enable(crtc, old_state);
+}
+
+static void vc4_txp_atomic_disable(struct drm_crtc *crtc,
+ struct drm_crtc_state *old_state)
+{
+ struct drm_device *dev = crtc->dev;
+
+ /* Disable vblank irq handling before crtc is disabled. */
+ drm_crtc_vblank_off(crtc);
+
+ vc4_hvs_atomic_disable(crtc, old_state);
+
+ /*
+ * Make sure we issue a vblank event after disabling the CRTC if
+ * someone was waiting it.
+ */
+ if (crtc->state->event) {
+ unsigned long flags;
+
+ spin_lock_irqsave(&dev->event_lock, flags);
+ drm_crtc_send_vblank_event(crtc, crtc->state->event);
+ crtc->state->event = NULL;
+ spin_unlock_irqrestore(&dev->event_lock, flags);
+ }
+}
+
+static const struct drm_crtc_helper_funcs vc4_txp_crtc_helper_funcs = {
+ .atomic_check = vc4_txp_atomic_check,
+ .atomic_flush = vc4_hvs_atomic_flush,
+ .atomic_enable = vc4_txp_atomic_enable,
+ .atomic_disable = vc4_txp_atomic_disable,
+};
+
static irqreturn_t vc4_txp_interrupt(int irq, void *data)
{
struct vc4_txp *txp = data;
+ struct vc4_crtc *vc4_crtc = &txp->base;
TXP_WRITE(TXP_DST_CTRL, TXP_READ(TXP_DST_CTRL) & ~TXP_EI);
- vc4_crtc_handle_vblank(to_vc4_crtc(txp->connector.base.state->crtc));
+ vc4_crtc_handle_vblank(vc4_crtc);
drm_writeback_signal_completion(&txp->connector, 0);
return IRQ_HANDLED;
}
+static const struct vc4_crtc_data vc4_txp_crtc_data = {
+ .hvs_available_channels = BIT(2),
+ .hvs_output = 2,
+};
+
static int vc4_txp_bind(struct device *dev, struct device *master, void *data)
{
struct platform_device *pdev = to_platform_device(dev);
struct drm_device *drm = dev_get_drvdata(master);
struct vc4_dev *vc4 = to_vc4_dev(drm);
+ struct vc4_crtc *vc4_crtc;
struct vc4_txp *txp;
+ struct drm_crtc *crtc;
+ struct drm_encoder *encoder;
int ret, irq;
irq = platform_get_irq(pdev, 0);
@@ -388,6 +473,11 @@ static int vc4_txp_bind(struct device *dev, struct device *master, void *data)
txp = devm_kzalloc(dev, sizeof(*txp), GFP_KERNEL);
if (!txp)
return -ENOMEM;
+ vc4_crtc = &txp->base;
+ crtc = &vc4_crtc->base;
+
+ vc4_crtc->pdev = pdev;
+ vc4_crtc->data = &vc4_txp_crtc_data;
txp->pdev = pdev;
@@ -407,6 +497,14 @@ static int vc4_txp_bind(struct device *dev, struct device *master, void *data)
if (ret)
return ret;
+ ret = vc4_crtc_init(drm, vc4_crtc,
+ &vc4_txp_crtc_funcs, &vc4_txp_crtc_helper_funcs);
+ if (ret)
+ return ret;
+
+ encoder = &txp->connector.encoder;
+ encoder->possible_crtcs |= drm_crtc_mask(crtc);
+
ret = devm_request_irq(dev, irq, vc4_txp_interrupt, 0,
dev_name(dev), txp);
if (ret)
--
git-series 0.9.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [PATCH v3 068/105] drm/vc4: hdmi: Use debugfs private field
From: Maxime Ripard @ 2020-05-27 15:48 UTC (permalink / raw)
To: Nicolas Saenz Julienne, Eric Anholt
Cc: Tim Gover, Dave Stevenson, linux-kernel, dri-devel,
bcm-kernel-feedback-list, linux-rpi-kernel, Phil Elwell,
linux-arm-kernel, Maxime Ripard
In-Reply-To: <cover.aaf2100bd7da4609f8bcb8216247d4b4e4379639.1590594512.git-series.maxime@cerno.tech>
We're calling vc4_debugfs_add_file with our struct vc4_hdmi pointer set
in the private field, but we don't use that field and go through the
main struct vc4_dev to get it.
Let's use the private field directly, that will save us some trouble
later on.
Signed-off-by: Maxime Ripard <maxime@cerno.tech>
---
drivers/gpu/drm/vc4/vc4_hdmi.c | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c
index 19a0780a14bd..38fe942a327b 100644
--- a/drivers/gpu/drm/vc4/vc4_hdmi.c
+++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
@@ -183,9 +183,7 @@ static const struct debugfs_reg32 hd_regs[] = {
static int vc4_hdmi_debugfs_regs(struct seq_file *m, void *unused)
{
struct drm_info_node *node = (struct drm_info_node *)m->private;
- struct drm_device *dev = node->minor->dev;
- struct vc4_dev *vc4 = to_vc4_dev(dev);
- struct vc4_hdmi *hdmi = vc4->hdmi;
+ struct vc4_hdmi *hdmi = node->info_ent->data;
struct drm_printer p = drm_seq_file_printer(m);
drm_print_regset32(&p, &hdmi->hdmi_regset);
--
git-series 0.9.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [PATCH v3 063/105] drm/vc4: crtc: Move the CRTC initialisation to a separate function
From: Maxime Ripard @ 2020-05-27 15:48 UTC (permalink / raw)
To: Nicolas Saenz Julienne, Eric Anholt
Cc: Tim Gover, Dave Stevenson, linux-kernel, dri-devel,
bcm-kernel-feedback-list, linux-rpi-kernel, Phil Elwell,
linux-arm-kernel, Maxime Ripard
In-Reply-To: <cover.aaf2100bd7da4609f8bcb8216247d4b4e4379639.1590594512.git-series.maxime@cerno.tech>
The upcoming patches to turn the TXP into a full-blown CRTC will have the
same CRTC initialisation code, so let's move it into a separate, public,
function so that we can reuse it later on.
Signed-off-by: Maxime Ripard <maxime@cerno.tech>
---
drivers/gpu/drm/vc4/vc4_crtc.c | 89 ++++++++++++++++++++---------------
drivers/gpu/drm/vc4/vc4_drv.h | 3 +-
2 files changed, 55 insertions(+), 37 deletions(-)
diff --git a/drivers/gpu/drm/vc4/vc4_crtc.c b/drivers/gpu/drm/vc4/vc4_crtc.c
index ee4381c144a5..6d7799ff8f87 100644
--- a/drivers/gpu/drm/vc4/vc4_crtc.c
+++ b/drivers/gpu/drm/vc4/vc4_crtc.c
@@ -1051,16 +1051,59 @@ static void vc4_set_crtc_possible_masks(struct drm_device *drm,
}
}
+int vc4_crtc_init(struct drm_device *drm, struct vc4_crtc *vc4_crtc,
+ const struct drm_crtc_funcs *crtc_funcs,
+ const struct drm_crtc_helper_funcs *crtc_helper_funcs)
+{
+ struct vc4_dev *vc4 = to_vc4_dev(drm);
+ struct drm_crtc *crtc = &vc4_crtc->base;
+ struct drm_plane *primary_plane;
+ unsigned int i;
+
+ /* For now, we create just the primary and the legacy cursor
+ * planes. We should be able to stack more planes on easily,
+ * but to do that we would need to compute the bandwidth
+ * requirement of the plane configuration, and reject ones
+ * that will take too much.
+ */
+ primary_plane = vc4_plane_init(drm, DRM_PLANE_TYPE_PRIMARY);
+ if (IS_ERR(primary_plane)) {
+ dev_err(drm->dev, "failed to construct primary plane\n");
+ return PTR_ERR(primary_plane);
+ }
+
+ drm_crtc_init_with_planes(drm, crtc, primary_plane, NULL,
+ crtc_funcs, NULL);
+ drm_crtc_helper_add(crtc, crtc_helper_funcs);
+
+ if (!vc4->hvs->hvs5) {
+ drm_mode_crtc_set_gamma_size(crtc, ARRAY_SIZE(vc4_crtc->lut_r));
+
+ /* We support CTM, but only for one CRTC at a
+ * time. It's therefore implemented as private driver
+ * state in vc4_kms, not here.
+ */
+ drm_crtc_enable_color_mgmt(crtc, 0, true, crtc->gamma_size);
+ }
+
+ for (i = 0; i < crtc->gamma_size; i++) {
+ vc4_crtc->lut_r[i] = i;
+ vc4_crtc->lut_g[i] = i;
+ vc4_crtc->lut_b[i] = i;
+ }
+
+ return 0;
+}
+
static int vc4_crtc_bind(struct device *dev, struct device *master, void *data)
{
struct platform_device *pdev = to_platform_device(dev);
struct drm_device *drm = dev_get_drvdata(master);
- struct vc4_dev *vc4 = to_vc4_dev(drm);
const struct vc4_pv_data *pv_data;
struct vc4_crtc *vc4_crtc;
struct drm_crtc *crtc;
- struct drm_plane *primary_plane, *destroy_plane, *temp;
- int ret, i;
+ struct drm_plane *destroy_plane, *temp;
+ int ret;
vc4_crtc = devm_kzalloc(dev, sizeof(*vc4_crtc), GFP_KERNEL);
if (!vc4_crtc)
@@ -1081,32 +1124,12 @@ static int vc4_crtc_bind(struct device *dev, struct device *master, void *data)
vc4_crtc->regset.regs = crtc_regs;
vc4_crtc->regset.nregs = ARRAY_SIZE(crtc_regs);
- /* For now, we create just the primary and the legacy cursor
- * planes. We should be able to stack more planes on easily,
- * but to do that we would need to compute the bandwidth
- * requirement of the plane configuration, and reject ones
- * that will take too much.
- */
- primary_plane = vc4_plane_init(drm, DRM_PLANE_TYPE_PRIMARY);
- if (IS_ERR(primary_plane)) {
- dev_err(dev, "failed to construct primary plane\n");
- ret = PTR_ERR(primary_plane);
- goto err;
- }
-
- drm_crtc_init_with_planes(drm, crtc, primary_plane, NULL,
- &vc4_crtc_funcs, NULL);
- drm_crtc_helper_add(crtc, &vc4_crtc_helper_funcs);
-
- if (!vc4->hvs->hvs5) {
- drm_mode_crtc_set_gamma_size(crtc, ARRAY_SIZE(vc4_crtc->lut_r));
+ ret = vc4_crtc_init(drm, vc4_crtc,
+ &vc4_crtc_funcs, &vc4_crtc_helper_funcs);
+ if (ret)
+ return ret;
- /* We support CTM, but only for one CRTC at a
- * time. It's therefore implemented as private driver
- * state in vc4_kms, not here.
- */
- drm_crtc_enable_color_mgmt(crtc, 0, true, crtc->gamma_size);
- }
+ vc4_set_crtc_possible_masks(drm, crtc);
CRTC_WRITE(PV_INTEN, 0);
CRTC_WRITE(PV_INTSTAT, PV_INT_VFP_START);
@@ -1117,14 +1140,6 @@ static int vc4_crtc_bind(struct device *dev, struct device *master, void *data)
if (ret)
goto err_destroy_planes;
- vc4_set_crtc_possible_masks(drm, crtc);
-
- for (i = 0; i < crtc->gamma_size; i++) {
- vc4_crtc->lut_r[i] = i;
- vc4_crtc->lut_g[i] = i;
- vc4_crtc->lut_b[i] = i;
- }
-
platform_set_drvdata(pdev, vc4_crtc);
vc4_debugfs_add_regset32(drm, pv_data->debugfs_name,
@@ -1138,7 +1153,7 @@ static int vc4_crtc_bind(struct device *dev, struct device *master, void *data)
if (destroy_plane->possible_crtcs == drm_crtc_mask(crtc))
destroy_plane->funcs->destroy(destroy_plane);
}
-err:
+
return ret;
}
diff --git a/drivers/gpu/drm/vc4/vc4_drv.h b/drivers/gpu/drm/vc4/vc4_drv.h
index ed09acbc5660..999841b1edd8 100644
--- a/drivers/gpu/drm/vc4/vc4_drv.h
+++ b/drivers/gpu/drm/vc4/vc4_drv.h
@@ -817,6 +817,9 @@ void vc4_bo_remove_from_purgeable_pool(struct vc4_bo *bo);
/* vc4_crtc.c */
extern struct platform_driver vc4_crtc_driver;
int vc4_crtc_disable_at_boot(struct drm_crtc *crtc);
+int vc4_crtc_init(struct drm_device *drm, struct vc4_crtc *vc4_crtc,
+ const struct drm_crtc_funcs *crtc_funcs,
+ const struct drm_crtc_helper_funcs *crtc_helper_funcs);
void vc4_crtc_destroy(struct drm_crtc *crtc);
int vc4_page_flip(struct drm_crtc *crtc,
struct drm_framebuffer *fb,
--
git-series 0.9.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [PATCH v3 064/105] drm/vc4: crtc: Change the HVS5 test for of_device_is_compatible
From: Maxime Ripard @ 2020-05-27 15:48 UTC (permalink / raw)
To: Nicolas Saenz Julienne, Eric Anholt
Cc: Tim Gover, Dave Stevenson, linux-kernel, dri-devel,
bcm-kernel-feedback-list, linux-rpi-kernel, Phil Elwell,
linux-arm-kernel, Maxime Ripard
In-Reply-To: <cover.aaf2100bd7da4609f8bcb8216247d4b4e4379639.1590594512.git-series.maxime@cerno.tech>
The TXP probes before the HVS, so testing the hvs5 flag in the hvs pointer
of the main device structure won't work and result in a null pointer
dereference.
Let's test for the main device compatible instead so that it can work.
Signed-off-by: Maxime Ripard <maxime@cerno.tech>
---
drivers/gpu/drm/vc4/vc4_crtc.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/vc4/vc4_crtc.c b/drivers/gpu/drm/vc4/vc4_crtc.c
index 6d7799ff8f87..d284596ec048 100644
--- a/drivers/gpu/drm/vc4/vc4_crtc.c
+++ b/drivers/gpu/drm/vc4/vc4_crtc.c
@@ -1055,7 +1055,6 @@ int vc4_crtc_init(struct drm_device *drm, struct vc4_crtc *vc4_crtc,
const struct drm_crtc_funcs *crtc_funcs,
const struct drm_crtc_helper_funcs *crtc_helper_funcs)
{
- struct vc4_dev *vc4 = to_vc4_dev(drm);
struct drm_crtc *crtc = &vc4_crtc->base;
struct drm_plane *primary_plane;
unsigned int i;
@@ -1076,7 +1075,7 @@ int vc4_crtc_init(struct drm_device *drm, struct vc4_crtc *vc4_crtc,
crtc_funcs, NULL);
drm_crtc_helper_add(crtc, crtc_helper_funcs);
- if (!vc4->hvs->hvs5) {
+ if (!of_device_is_compatible(drm->dev->of_node, "brcm,bcm2711-vc5")) {
drm_mode_crtc_set_gamma_size(crtc, ARRAY_SIZE(vc4_crtc->lut_r));
/* We support CTM, but only for one CRTC at a
--
git-series 0.9.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [PATCH v3 061/105] drm/vc4: crtc: Split CRTC data in two
From: Maxime Ripard @ 2020-05-27 15:48 UTC (permalink / raw)
To: Nicolas Saenz Julienne, Eric Anholt
Cc: Tim Gover, Dave Stevenson, linux-kernel, dri-devel,
bcm-kernel-feedback-list, linux-rpi-kernel, Phil Elwell,
linux-arm-kernel, Maxime Ripard
In-Reply-To: <cover.aaf2100bd7da4609f8bcb8216247d4b4e4379639.1590594512.git-series.maxime@cerno.tech>
The vc4_crtc_data structure is currently storing data related to both the
general CRTC information needed by the rest of the vc4 driver (like HVS
output and available FIFOs) and some related to the pixelvalve attached to
that CRTC. Let's split this into two structures so that we can reuse the
CRTC part into the TXP later on.
Signed-off-by: Maxime Ripard <maxime@cerno.tech>
---
drivers/gpu/drm/vc4/vc4_crtc.c | 84 +++++++++++++++++++++--------------
drivers/gpu/drm/vc4/vc4_drv.h | 25 ++++++++--
2 files changed, 74 insertions(+), 35 deletions(-)
diff --git a/drivers/gpu/drm/vc4/vc4_crtc.c b/drivers/gpu/drm/vc4/vc4_crtc.c
index 4df8cc5387a0..f82e3b0e11bd 100644
--- a/drivers/gpu/drm/vc4/vc4_crtc.c
+++ b/drivers/gpu/drm/vc4/vc4_crtc.c
@@ -208,7 +208,9 @@ void vc4_crtc_destroy(struct drm_crtc *crtc)
static u32 vc4_get_fifo_full_level(struct vc4_crtc *vc4_crtc, u32 format)
{
- u32 fifo_len_bytes = vc4_crtc->data->fifo_depth;
+ const struct vc4_crtc_data *crtc_data = vc4_crtc_to_vc4_crtc_data(vc4_crtc);
+ const struct vc4_pv_data *pv_data = vc4_crtc_to_vc4_pv_data(vc4_crtc);
+ u32 fifo_len_bytes = pv_data->fifo_depth;
/*
* Pixels are pulled from the HVS if the number of bytes is
@@ -233,7 +235,7 @@ static u32 vc4_get_fifo_full_level(struct vc4_crtc *vc4_crtc, u32 format)
* For some reason, the pixelvalve4 doesn't work with
* the usual formula and will only work with 32.
*/
- if (vc4_crtc->data->hvs_output == 5)
+ if (crtc_data->hvs_output == 5)
return 32;
return fifo_len_bytes - 3 * HVS_FIFO_LATENCY_PIX;
@@ -294,6 +296,7 @@ static void vc4_crtc_config_pv(struct drm_crtc *crtc)
struct drm_encoder *encoder = vc4_get_crtc_encoder(crtc);
struct vc4_encoder *vc4_encoder = to_vc4_encoder(encoder);
struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc);
+ const struct vc4_pv_data *pv_data = vc4_crtc_to_vc4_pv_data(vc4_crtc);
struct drm_crtc_state *state = crtc->state;
struct drm_display_mode *mode = &state->adjusted_mode;
bool interlace = mode->flags & DRM_MODE_FLAG_INTERLACE;
@@ -301,7 +304,7 @@ static void vc4_crtc_config_pv(struct drm_crtc *crtc)
bool is_dsi = (vc4_encoder->type == VC4_ENCODER_TYPE_DSI0 ||
vc4_encoder->type == VC4_ENCODER_TYPE_DSI1);
u32 format = is_dsi ? PV_CONTROL_FORMAT_DSIV_24 : PV_CONTROL_FORMAT_24;
- u8 ppc = vc4_crtc->data->pixels_per_clock;
+ u8 ppc = pv_data->pixels_per_clock;
bool debug_dump_regs = false;
if (debug_dump_regs) {
@@ -885,9 +888,11 @@ static const struct drm_crtc_helper_funcs vc4_crtc_helper_funcs = {
.get_scanout_position = vc4_crtc_get_scanout_position,
};
-static const struct vc4_crtc_data bcm2835_pv0_data = {
- .hvs_available_channels = BIT(0),
- .hvs_output = 0,
+static const struct vc4_pv_data bcm2835_pv0_data = {
+ .base = {
+ .hvs_available_channels = BIT(0),
+ .hvs_output = 0,
+ },
.debugfs_name = "crtc0_regs",
.fifo_depth = 64,
.pixels_per_clock = 1,
@@ -897,9 +902,11 @@ static const struct vc4_crtc_data bcm2835_pv0_data = {
},
};
-static const struct vc4_crtc_data bcm2835_pv1_data = {
- .hvs_available_channels = BIT(2),
- .hvs_output = 2,
+static const struct vc4_pv_data bcm2835_pv1_data = {
+ .base = {
+ .hvs_available_channels = BIT(2),
+ .hvs_output = 2,
+ },
.debugfs_name = "crtc1_regs",
.fifo_depth = 64,
.pixels_per_clock = 1,
@@ -909,9 +916,11 @@ static const struct vc4_crtc_data bcm2835_pv1_data = {
},
};
-static const struct vc4_crtc_data bcm2835_pv2_data = {
- .hvs_available_channels = BIT(1),
- .hvs_output = 1,
+static const struct vc4_pv_data bcm2835_pv2_data = {
+ .base = {
+ .hvs_available_channels = BIT(1),
+ .hvs_output = 1,
+ },
.debugfs_name = "crtc2_regs",
.fifo_depth = 64,
.pixels_per_clock = 1,
@@ -921,10 +930,12 @@ static const struct vc4_crtc_data bcm2835_pv2_data = {
},
};
-static const struct vc4_crtc_data bcm2711_pv0_data = {
+static const struct vc4_pv_data bcm2711_pv0_data = {
+ .base = {
+ .hvs_available_channels = BIT(0),
+ .hvs_output = 0,
+ },
.debugfs_name = "crtc0_regs",
- .hvs_available_channels = BIT(0),
- .hvs_output = 0,
.fifo_depth = 64,
.pixels_per_clock = 1,
.encoder_types = {
@@ -933,10 +944,12 @@ static const struct vc4_crtc_data bcm2711_pv0_data = {
},
};
-static const struct vc4_crtc_data bcm2711_pv1_data = {
+static const struct vc4_pv_data bcm2711_pv1_data = {
+ .base = {
+ .hvs_available_channels = BIT(0) | BIT(1) | BIT(2),
+ .hvs_output = 3,
+ },
.debugfs_name = "crtc1_regs",
- .hvs_available_channels = BIT(0) | BIT(1) | BIT(2),
- .hvs_output = 3,
.fifo_depth = 64,
.pixels_per_clock = 1,
.encoder_types = {
@@ -945,10 +958,12 @@ static const struct vc4_crtc_data bcm2711_pv1_data = {
},
};
-static const struct vc4_crtc_data bcm2711_pv2_data = {
+static const struct vc4_pv_data bcm2711_pv2_data = {
+ .base = {
+ .hvs_available_channels = BIT(0) | BIT(1) | BIT(2),
+ .hvs_output = 4,
+ },
.debugfs_name = "crtc2_regs",
- .hvs_available_channels = BIT(0) | BIT(1) | BIT(2),
- .hvs_output = 4,
.fifo_depth = 256,
.pixels_per_clock = 2,
.encoder_types = {
@@ -956,10 +971,12 @@ static const struct vc4_crtc_data bcm2711_pv2_data = {
},
};
-static const struct vc4_crtc_data bcm2711_pv3_data = {
+static const struct vc4_pv_data bcm2711_pv3_data = {
+ .base = {
+ .hvs_available_channels = BIT(1),
+ .hvs_output = 1,
+ },
.debugfs_name = "crtc3_regs",
- .hvs_available_channels = BIT(1),
- .hvs_output = 1,
.fifo_depth = 64,
.pixels_per_clock = 1,
.encoder_types = {
@@ -967,10 +984,12 @@ static const struct vc4_crtc_data bcm2711_pv3_data = {
},
};
-static const struct vc4_crtc_data bcm2711_pv4_data = {
+static const struct vc4_pv_data bcm2711_pv4_data = {
+ .base = {
+ .hvs_available_channels = BIT(0) | BIT(1) | BIT(2),
+ .hvs_output = 5,
+ },
.debugfs_name = "crtc4_regs",
- .hvs_available_channels = BIT(0) | BIT(1) | BIT(2),
- .hvs_output = 5,
.fifo_depth = 64,
.pixels_per_clock = 2,
.encoder_types = {
@@ -994,8 +1013,9 @@ static void vc4_set_crtc_possible_masks(struct drm_device *drm,
struct drm_crtc *crtc)
{
struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc);
- const struct vc4_crtc_data *crtc_data = vc4_crtc->data;
- const enum vc4_encoder_type *encoder_types = crtc_data->encoder_types;
+ const struct vc4_crtc_data *crtc_data = vc4_crtc_to_vc4_crtc_data(vc4_crtc);
+ const struct vc4_pv_data *pv_data = vc4_crtc_to_vc4_pv_data(vc4_crtc);
+ const enum vc4_encoder_type *encoder_types = pv_data->encoder_types;
struct drm_encoder *encoder;
drm_for_each_encoder(encoder, drm) {
@@ -1010,7 +1030,7 @@ static void vc4_set_crtc_possible_masks(struct drm_device *drm,
}
vc4_encoder = to_vc4_encoder(encoder);
- for (i = 0; i < ARRAY_SIZE(crtc_data->encoder_types); i++) {
+ for (i = 0; i < ARRAY_SIZE(pv_data->encoder_types); i++) {
if (vc4_encoder->type == encoder_types[i]) {
vc4_encoder->clock_select = i;
encoder->possible_crtcs |= drm_crtc_mask(crtc);
@@ -1025,7 +1045,7 @@ static int vc4_crtc_bind(struct device *dev, struct device *master, void *data)
struct platform_device *pdev = to_platform_device(dev);
struct drm_device *drm = dev_get_drvdata(master);
struct vc4_dev *vc4 = to_vc4_dev(drm);
- const struct vc4_crtc_data *pv_data;
+ const struct vc4_pv_data *pv_data;
struct vc4_crtc *vc4_crtc;
struct drm_crtc *crtc;
struct drm_plane *primary_plane, *destroy_plane, *temp;
@@ -1039,7 +1059,7 @@ static int vc4_crtc_bind(struct device *dev, struct device *master, void *data)
pv_data = of_device_get_match_data(dev);
if (!pv_data)
return -ENODEV;
- vc4_crtc->data = pv_data;
+ vc4_crtc->data = &pv_data->base;
vc4_crtc->pdev = pdev;
vc4_crtc->regs = vc4_ioremap_regs(pdev, 0);
diff --git a/drivers/gpu/drm/vc4/vc4_drv.h b/drivers/gpu/drm/vc4/vc4_drv.h
index da4d2391a4ba..ed09acbc5660 100644
--- a/drivers/gpu/drm/vc4/vc4_drv.h
+++ b/drivers/gpu/drm/vc4/vc4_drv.h
@@ -458,20 +458,25 @@ to_vc4_encoder(struct drm_encoder *encoder)
}
struct vc4_crtc_data {
- /* Depth of the PixelValve FIFO in bytes */
- unsigned int fifo_depth;
-
/* Which channels of the HVS can the output source from */
unsigned int hvs_available_channels;
/* Which output of the HVS this pixelvalve sources from. */
int hvs_output;
+};
+
+struct vc4_pv_data {
+ struct vc4_crtc_data base;
+
+ /* Depth of the PixelValve FIFO in bytes */
+ unsigned int fifo_depth;
/* Number of pixels output per clock period */
u8 pixels_per_clock;
enum vc4_encoder_type encoder_types[4];
const char *debugfs_name;
+
};
struct vc4_crtc {
@@ -498,6 +503,20 @@ to_vc4_crtc(struct drm_crtc *crtc)
return (struct vc4_crtc *)crtc;
}
+static inline const struct vc4_crtc_data *
+vc4_crtc_to_vc4_crtc_data(const struct vc4_crtc *crtc)
+{
+ return crtc->data;
+}
+
+static inline const struct vc4_pv_data *
+vc4_crtc_to_vc4_pv_data(const struct vc4_crtc *crtc)
+{
+ const struct vc4_crtc_data *data = vc4_crtc_to_vc4_crtc_data(crtc);
+
+ return container_of(data, struct vc4_pv_data, base);
+}
+
struct vc4_crtc_state {
struct drm_crtc_state base;
/* Dlist area for this CRTC configuration. */
--
git-series 0.9.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [PATCH v3 062/105] drm/vc4: crtc: Only access the PixelValve registers if we have to
From: Maxime Ripard @ 2020-05-27 15:48 UTC (permalink / raw)
To: Nicolas Saenz Julienne, Eric Anholt
Cc: Tim Gover, Dave Stevenson, linux-kernel, dri-devel,
bcm-kernel-feedback-list, linux-rpi-kernel, Phil Elwell,
linux-arm-kernel, Maxime Ripard
In-Reply-To: <cover.aaf2100bd7da4609f8bcb8216247d4b4e4379639.1590594512.git-series.maxime@cerno.tech>
The CRTC hooks are called both for the TXP and the pixelvalve, yet some
will read / write the registers as if the device was a pixelvalve, which
won't really work.
Let's make sure we only access those registers if we are running on a
PixelValve.
Signed-off-by: Maxime Ripard <maxime@cerno.tech>
---
drivers/gpu/drm/vc4/vc4_crtc.c | 25 ++++++++++++++++++-------
1 file changed, 18 insertions(+), 7 deletions(-)
diff --git a/drivers/gpu/drm/vc4/vc4_crtc.c b/drivers/gpu/drm/vc4/vc4_crtc.c
index f82e3b0e11bd..ee4381c144a5 100644
--- a/drivers/gpu/drm/vc4/vc4_crtc.c
+++ b/drivers/gpu/drm/vc4/vc4_crtc.c
@@ -405,16 +405,19 @@ static void require_hvs_enabled(struct drm_device *dev)
static int vc4_crtc_disable(struct drm_crtc *crtc, unsigned int channel)
{
+ struct vc4_crtc_state *vc4_state = to_vc4_crtc_state(crtc->state);
struct drm_encoder *encoder = vc4_get_crtc_encoder(crtc);
struct vc4_encoder *vc4_encoder = to_vc4_encoder(encoder);
struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc);
struct drm_device *dev = crtc->dev;
int ret;
- CRTC_WRITE(PV_V_CONTROL,
- CRTC_READ(PV_V_CONTROL) & ~PV_VCONTROL_VIDEN);
- ret = wait_for(!(CRTC_READ(PV_V_CONTROL) & PV_VCONTROL_VIDEN), 1);
- WARN_ONCE(ret, "Timeout waiting for !PV_VCONTROL_VIDEN\n");
+ if (!vc4_state->feed_txp) {
+ CRTC_WRITE(PV_V_CONTROL,
+ CRTC_READ(PV_V_CONTROL) & ~PV_VCONTROL_VIDEN);
+ ret = wait_for(!(CRTC_READ(PV_V_CONTROL) & PV_VCONTROL_VIDEN), 1);
+ WARN_ONCE(ret, "Timeout waiting for !PV_VCONTROL_VIDEN\n");
+ }
mdelay(20);
@@ -508,10 +511,10 @@ static void vc4_crtc_atomic_enable(struct drm_crtc *crtc,
if (vc4_encoder->pre_crtc_configure)
vc4_encoder->pre_crtc_configure(encoder);
- if (!vc4_state->feed_txp)
+ if (!vc4_state->feed_txp) {
vc4_crtc_config_pv(crtc);
-
- CRTC_WRITE(PV_CONTROL, CRTC_READ(PV_CONTROL) | PV_CONTROL_EN);
+ CRTC_WRITE(PV_CONTROL, CRTC_READ(PV_CONTROL) | PV_CONTROL_EN);
+ }
if (vc4_encoder->pre_crtc_enable)
vc4_encoder->pre_crtc_enable(encoder);
@@ -611,6 +614,10 @@ static int vc4_crtc_atomic_check(struct drm_crtc *crtc,
static int vc4_enable_vblank(struct drm_crtc *crtc)
{
struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc);
+ struct vc4_crtc_state *vc4_state = to_vc4_crtc_state(crtc->state);
+
+ if (vc4_state->feed_txp)
+ return 0;
CRTC_WRITE(PV_INTEN, PV_INT_VFP_START);
@@ -620,6 +627,10 @@ static int vc4_enable_vblank(struct drm_crtc *crtc)
static void vc4_disable_vblank(struct drm_crtc *crtc)
{
struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc);
+ struct vc4_crtc_state *vc4_state = to_vc4_crtc_state(crtc->state);
+
+ if (vc4_state->feed_txp)
+ return;
CRTC_WRITE(PV_INTEN, 0);
}
--
git-series 0.9.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [PATCH v3 055/105] drm/vc4: hvs: Introduce a function to get the assigned FIFO
From: Maxime Ripard @ 2020-05-27 15:48 UTC (permalink / raw)
To: Nicolas Saenz Julienne, Eric Anholt
Cc: Tim Gover, Dave Stevenson, linux-kernel, dri-devel,
bcm-kernel-feedback-list, linux-rpi-kernel, Phil Elwell,
linux-arm-kernel, Maxime Ripard
In-Reply-To: <cover.aaf2100bd7da4609f8bcb8216247d4b4e4379639.1590594512.git-series.maxime@cerno.tech>
At boot time, if we detect that a pixelvalve has been enabled, we need to
be able to retrieve the HVS channel it has been assigned to so that we can
disable that channel too. Let's create that function that returns the FIFO
or an error from a given output.
Signed-off-by: Maxime Ripard <maxime@cerno.tech>
---
drivers/gpu/drm/vc4/vc4_drv.h | 1 +-
drivers/gpu/drm/vc4/vc4_hvs.c | 51 ++++++++++++++++++++++++++++++++++++-
2 files changed, 52 insertions(+)
diff --git a/drivers/gpu/drm/vc4/vc4_drv.h b/drivers/gpu/drm/vc4/vc4_drv.h
index d51b695732e0..99001f8783aa 100644
--- a/drivers/gpu/drm/vc4/vc4_drv.h
+++ b/drivers/gpu/drm/vc4/vc4_drv.h
@@ -880,6 +880,7 @@ void vc4_irq_reset(struct drm_device *dev);
/* vc4_hvs.c */
extern struct platform_driver vc4_hvs_driver;
void vc4_hvs_stop_channel(struct drm_device *dev, unsigned int output);
+int vc4_hvs_get_fifo_from_output(struct drm_device *dev, unsigned int output);
int vc4_hvs_atomic_check(struct drm_crtc *crtc, struct drm_crtc_state *state);
void vc4_hvs_atomic_enable(struct drm_crtc *crtc, struct drm_crtc_state *old_state);
void vc4_hvs_atomic_disable(struct drm_crtc *crtc, struct drm_crtc_state *old_state);
diff --git a/drivers/gpu/drm/vc4/vc4_hvs.c b/drivers/gpu/drm/vc4/vc4_hvs.c
index 1785c49534cf..56657959778f 100644
--- a/drivers/gpu/drm/vc4/vc4_hvs.c
+++ b/drivers/gpu/drm/vc4/vc4_hvs.c
@@ -19,6 +19,7 @@
* each CRTC.
*/
+#include <linux/bitfield.h>
#include <linux/clk.h>
#include <linux/component.h>
#include <linux/platform_device.h>
@@ -196,6 +197,56 @@ static void vc4_hvs_update_gamma_lut(struct drm_crtc *crtc)
vc4_hvs_lut_load(crtc);
}
+int vc4_hvs_get_fifo_from_output(struct drm_device *dev, unsigned int output)
+{
+ struct vc4_dev *vc4 = to_vc4_dev(dev);
+ u32 reg;
+ int ret;
+
+ switch (output) {
+ case 0:
+ return 0;
+
+ case 1:
+ return 1;
+
+ case 2:
+ reg = HVS_READ(SCALER_DISPECTRL);
+ ret = FIELD_GET(SCALER_DISPECTRL_DSP2_MUX_MASK, reg);
+ if (ret == 0)
+ return 2;
+
+ return 0;
+
+ case 3:
+ reg = HVS_READ(SCALER_DISPCTRL);
+ ret = FIELD_GET(SCALER_DISPCTRL_DSP3_MUX_MASK, reg);
+ if (ret == 3)
+ return -EPIPE;
+
+ return ret;
+
+ case 4:
+ reg = HVS_READ(SCALER_DISPEOLN);
+ ret = FIELD_GET(SCALER_DISPEOLN_DSP4_MUX_MASK, reg);
+ if (ret == 3)
+ return -EPIPE;
+
+ return ret;
+
+ case 5:
+ reg = HVS_READ(SCALER_DISPDITHER);
+ ret = FIELD_GET(SCALER_DISPDITHER_DSP5_MUX_MASK, reg);
+ if (ret == 3)
+ return -EPIPE;
+
+ return ret;
+
+ default:
+ return -EPIPE;
+ }
+}
+
static int vc4_hvs_init_channel(struct vc4_dev *vc4, struct drm_crtc *crtc,
struct drm_display_mode *mode, bool oneshot)
{
--
git-series 0.9.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [PATCH v3 052/105] drm/vc4: crtc: Clear the PixelValve FIFO on disable
From: Maxime Ripard @ 2020-05-27 15:48 UTC (permalink / raw)
To: Nicolas Saenz Julienne, Eric Anholt
Cc: Tim Gover, Dave Stevenson, linux-kernel, dri-devel,
bcm-kernel-feedback-list, linux-rpi-kernel, Phil Elwell,
linux-arm-kernel, Maxime Ripard
In-Reply-To: <cover.aaf2100bd7da4609f8bcb8216247d4b4e4379639.1590594512.git-series.maxime@cerno.tech>
In order to avoid a stale pixel getting stuck on mode change or a disable
/ enable cycle, we need to make sure to flush the PV FIFO on disable.
Signed-off-by: Maxime Ripard <maxime@cerno.tech>
---
drivers/gpu/drm/vc4/vc4_crtc.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/vc4/vc4_crtc.c b/drivers/gpu/drm/vc4/vc4_crtc.c
index dee8dc7b9409..61e0945a8697 100644
--- a/drivers/gpu/drm/vc4/vc4_crtc.c
+++ b/drivers/gpu/drm/vc4/vc4_crtc.c
@@ -406,8 +406,7 @@ static void vc4_crtc_atomic_disable(struct drm_crtc *crtc,
if (vc4_encoder->post_crtc_disable)
vc4_encoder->post_crtc_disable(encoder);
- CRTC_WRITE(PV_CONTROL, CRTC_READ(PV_CONTROL) & ~PV_CONTROL_EN);
-
+ vc4_crtc_pixelvalve_reset(crtc);
vc4_hvs_atomic_disable(crtc, old_state);
if (vc4_encoder->post_crtc_powerdown)
--
git-series 0.9.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox