Re: [PATCH v5 2/7] dt-bindings: mediatek, dp: Add Display Port binding

2021-10-24 Thread Markus Schneider-Pargmann
On Fri, Oct 22, 2021 at 06:19:13PM -0500, Rob Herring wrote:
> On Thu, 21 Oct 2021 11:27:02 +0200, Markus Schneider-Pargmann wrote:
> > This controller is present on several mediatek hardware. Currently
> > mt8195 and mt8395 have this controller without a functional difference,
> > so only one compatible field is added.
> > 
> > The controller can have two forms, as a normal display port and as an
> > embedded display port.
> > 
> > Signed-off-by: Markus Schneider-Pargmann 
> > ---
> > 
> > Notes:
> > Changes v4 -> v5:
> > - Removed "status" in the example
> > - Remove edp_tx compatible.
> > - Rename dp_tx compatible to dp-tx.
> > 
> >  .../display/mediatek/mediatek,dp.yaml | 87 +++
> >  1 file changed, 87 insertions(+)
> >  create mode 100644 
> > Documentation/devicetree/bindings/display/mediatek/mediatek,dp.yaml
> > 
> 
> Reviewed-by: Rob Herring 
> 
> But can't be applied without the dependent header (or remove the 
> dependency).

Ok, thank you Rob. Maybe I will remove the dependency.

Thanks,
Markus


Re: [PATCH v5 6/7] phy: phy-mtk-dp: Add driver for DP phy

2021-10-22 Thread Markus Schneider-Pargmann
Hi Vinod,

On Fri, Oct 22, 2021 at 10:42:30AM +0530, Vinod Koul wrote:
> On 21-10-21, 11:27, Markus Schneider-Pargmann wrote:
> > This is a new driver that supports the integrated DisplayPort phy for
> > mediatek SoCs, especially the mt8195. The phy is integrated into the
> > DisplayPort controller and will be created by the mtk-dp driver. This
> > driver expects a struct regmap to be able to work on the same registers
> > as the DisplayPort controller. It sets the device data to be the struct
> > phy so that the DisplayPort controller can easily work with it.
> > 
> > The driver does not have any devicetree bindings because the datasheet
> > does not list the controller and the phy as distinct units.
> > 
> > The interaction with the controller can be covered by the configure
> > callback of the phy framework and its displayport parameters.
> > 
> > Signed-off-by: Markus Schneider-Pargmann 
> > ---
> > 
> > Notes:
> > Changes v3 -> v4:
> > - Split DP controller driver and phy driver into separate patches.
> > - Add entry to MAINTAINERS for this phy driver
> > 
> >  MAINTAINERS   |   1 +
> >  drivers/phy/mediatek/Kconfig  |   8 ++
> >  drivers/phy/mediatek/Makefile |   1 +
> >  drivers/phy/mediatek/phy-mtk-dp.c | 219 ++
> >  4 files changed, 229 insertions(+)
> >  create mode 100644 drivers/phy/mediatek/phy-mtk-dp.c
> > 
> > diff --git a/MAINTAINERS b/MAINTAINERS
> > index eeb4c70b3d5b..8a47eb628734 100644
> > --- a/MAINTAINERS
> > +++ b/MAINTAINERS
> > @@ -6276,6 +6276,7 @@ L:linux-media...@lists.infradead.org (moderated 
> > for non-subscribers)
> >  S: Supported
> >  F: Documentation/devicetree/bindings/display/mediatek/
> >  F: drivers/gpu/drm/mediatek/
> > +F: drivers/phy/mediatek/phy-mtk-dp.c
> >  F: drivers/phy/mediatek/phy-mtk-hdmi*
> >  F: drivers/phy/mediatek/phy-mtk-mipi*
> >  
> > diff --git a/drivers/phy/mediatek/Kconfig b/drivers/phy/mediatek/Kconfig
> > index 55f8e6c048ab..f7ec86059049 100644
> > --- a/drivers/phy/mediatek/Kconfig
> > +++ b/drivers/phy/mediatek/Kconfig
> > @@ -55,3 +55,11 @@ config PHY_MTK_MIPI_DSI
> > select GENERIC_PHY
> > help
> >   Support MIPI DSI for Mediatek SoCs.
> > +
> > +config PHY_MTK_DP
> > +   tristate "MediaTek DP-PHY Driver"
> > +   depends on ARCH_MEDIATEK || COMPILE_TEST
> > +   depends on OF
> > +   select GENERIC_PHY
> > +   help
> > + Support DisplayPort PHY for Mediatek SoCs.
> > diff --git a/drivers/phy/mediatek/Makefile b/drivers/phy/mediatek/Makefile
> > index ace660fbed3a..4ba1e0650434 100644
> > --- a/drivers/phy/mediatek/Makefile
> > +++ b/drivers/phy/mediatek/Makefile
> > @@ -3,6 +3,7 @@
> >  # Makefile for the phy drivers.
> >  #
> >  
> > +obj-$(CONFIG_PHY_MTK_DP)   += phy-mtk-dp.o
> >  obj-$(CONFIG_PHY_MTK_TPHY) += phy-mtk-tphy.o
> >  obj-$(CONFIG_PHY_MTK_UFS)  += phy-mtk-ufs.o
> >  obj-$(CONFIG_PHY_MTK_XSPHY)+= phy-mtk-xsphy.o
> > diff --git a/drivers/phy/mediatek/phy-mtk-dp.c 
> > b/drivers/phy/mediatek/phy-mtk-dp.c
> > new file mode 100644
> > index ..296203e319ac
> > --- /dev/null
> > +++ b/drivers/phy/mediatek/phy-mtk-dp.c
> > @@ -0,0 +1,219 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +/*
> > + * Copyright (c) 2021 BayLibre
> > + * Author: Markus Schneider-Pargmann 
> > + */
> > +
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +
> > +#define PHY_OFFSET 0x1000
> > +
> > +#define MTK_DP_PHY_DIG_PLL_CTL_1   (PHY_OFFSET + 0x014)
> > +# define TPLL_SSC_EN   BIT(3)
> > +
> > +#define MTK_DP_PHY_DIG_BIT_RATE(PHY_OFFSET + 0x03C)
> > +# define BIT_RATE_RBR  0
> > +# define BIT_RATE_HBR  1
> > +# define BIT_RATE_HBR2 2
> > +# define BIT_RATE_HBR3 3
> > +
> > +#define MTK_DP_PHY_DIG_SW_RST  (PHY_OFFSET + 0x038)
> > +# define DP_GLB_SW_RST_PHYDBIT(0)
> > +
> > +#define MTK_DP_LANE0_DRIVING_PARAM_3   (PHY_OFFSET + 0x138)
> > +#define MTK_DP_LANE1_DRIVING_PARAM_3   (PHY_OFFSET + 0x238)
> > +#define MTK_DP_LANE2_DRIVING_PARAM_3   

[PATCH v5 7/7] drm/mediatek: Add mt8195 DisplayPort driver

2021-10-21 Thread Markus Schneider-Pargmann
This patch adds a DisplayPort driver for the Mediatek mt8195 SoC and a
according phy driver mediatek-dp-phy.

It supports both functional units on the mt8195, the embedded
DisplayPort as well as the external DisplayPort units. It offers
hot-plug-detection, audio up to 8 channels, and DisplayPort 1.4 with up
to 4 lanes.

The driver creates a child device for the phy. The child device will
never exist without the parent being active. As they are sharing a
register range, the parent passes a regmap pointer to the child so that
both can work with the same register range. The phy driver sets device
data that is read by the parent to get the phy device that can be used
to control the phy properties.

This driver is based on an initial version by
Jason-JH.Lin .

Signed-off-by: Markus Schneider-Pargmann 
---

Notes:
Changes v4 -> v5:
- Remove edp_tx compatible and rename the dp_tx compatible to dp-tx.
- Detect whether it is edp by checking whether a panel is present.

Changes v2 -> v3:
- Solve TODOs and add defines for undescribed registers
- Remove TODOs that were irrelevant

Changes v1 -> v2:
- Fix checkpatch --strict suggestions
- General cleanups of the code.
- Remove all remaining non-atomic functions.
- Remove unused includes and sort them.
- Remove unused select GENERIC_PHY
- Rename phy registers DP_PHY -> MTK_DP_PHY
- Replace usage of delays with usleep_range.
- Split the phy register accesses into a separate phy driver.
- Use a lock to guard access to mtk_dp->edid as it can be 
allocated/used/freed
  in different threads
- use struct dp_sdp for sdp packets.

Changes RFC -> v1:
- Removed unused register definitions.
- Replaced workqueue with threaded irq.
- Removed connector code.
- Move to atomic_* drm functions.
- General cleanups of the code.
- Remove unused select GENERIC_PHY.

 drivers/gpu/drm/mediatek/Kconfig   |7 +
 drivers/gpu/drm/mediatek/Makefile  |2 +
 drivers/gpu/drm/mediatek/mtk_dp.c  | 2813 
 drivers/gpu/drm/mediatek/mtk_dp_reg.h  |  535 +
 drivers/gpu/drm/mediatek/mtk_drm_drv.c |1 +
 drivers/gpu/drm/mediatek/mtk_drm_drv.h |1 +
 6 files changed, 3359 insertions(+)
 create mode 100644 drivers/gpu/drm/mediatek/mtk_dp.c
 create mode 100644 drivers/gpu/drm/mediatek/mtk_dp_reg.h

diff --git a/drivers/gpu/drm/mediatek/Kconfig b/drivers/gpu/drm/mediatek/Kconfig
index 2976d21e9a34..029b94c71613 100644
--- a/drivers/gpu/drm/mediatek/Kconfig
+++ b/drivers/gpu/drm/mediatek/Kconfig
@@ -28,3 +28,10 @@ config DRM_MEDIATEK_HDMI
select PHY_MTK_HDMI
help
  DRM/KMS HDMI driver for Mediatek SoCs
+
+config MTK_DPTX_SUPPORT
+   tristate "DRM DPTX Support for Mediatek SoCs"
+   depends on DRM_MEDIATEK
+   select PHY_MTK_DP
+   help
+ DRM/KMS Display Port driver for Mediatek SoCs.
diff --git a/drivers/gpu/drm/mediatek/Makefile 
b/drivers/gpu/drm/mediatek/Makefile
index 29098d7c8307..d86a6406055e 100644
--- a/drivers/gpu/drm/mediatek/Makefile
+++ b/drivers/gpu/drm/mediatek/Makefile
@@ -21,3 +21,5 @@ mediatek-drm-hdmi-objs := mtk_cec.o \
  mtk_hdmi_ddc.o
 
 obj-$(CONFIG_DRM_MEDIATEK_HDMI) += mediatek-drm-hdmi.o
+
+obj-$(CONFIG_MTK_DPTX_SUPPORT) += mtk_dp.o
diff --git a/drivers/gpu/drm/mediatek/mtk_dp.c 
b/drivers/gpu/drm/mediatek/mtk_dp.c
new file mode 100644
index ..d93adab2d3c5
--- /dev/null
+++ b/drivers/gpu/drm/mediatek/mtk_dp.c
@@ -0,0 +1,2813 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2019 MediaTek Inc.
+ * Copyright (c) 2021 BayLibre
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "mtk_dp_reg.h"
+
+#define MTK_DP_AUX_WAIT_REPLY_COUNT2
+#define MTK_DP_CHECK_SINK_CAP_TIMEOUT_COUNT3
+
+#define MTK_DP_MAX_LANES   4
+#define MTK_DP_MAX_LINK_RATE   MTK_DP_LINKRATE_HBR3
+
+#define MTK_DP_TBC_BUF_READ_START_ADDR 0x08
+
+#define MTK_DP_TRAIN_RETRY_LIMIT   8
+#define MTK_DP_TRAIN_MAX_ITERATIONS5
+
+#define MTK_DP_AUX_WRITE_READ_WAIT_TIME_US 20
+
+#define MTK_DP_DP_VERSION_11   0x11
+
+enum mtk_dp_state {
+   MTK_DP_STATE_INITIAL,
+   MTK_DP_STATE_IDLE,
+   MTK_DP_STATE_PREPARE,
+   MTK_DP_STATE_NORMAL,
+};
+
+enum mtk_dp_train_state {
+   MTK_DP_TRAIN_STATE_STARTUP = 0,
+   MTK_DP_TRAIN_STATE_CHECKCAP,
+   MTK_DP_TRAIN_STATE_CHECKEDID,
+   MTK_DP_TRAIN_STATE_TRAINING_PRE,
+   MTK_DP_TRAIN_STATE_TRAINING,
+   MTK_DP_TRAIN_STATE_CHECKTIMING,
+   MTK_DP_TRAIN_STATE_NORMAL,
+   MTK_DP_TRAIN_STATE_POWERSAVE,
+   MTK_DP_TRAIN_STAT

[PATCH v5 3/7] drm/edid: Add cea_sad helpers for freq/length

2021-10-21 Thread Markus Schneider-Pargmann
This patch adds two helper functions that extract the frequency and word
length from a struct cea_sad.

For these helper functions new defines are added that help translate the
'freq' and 'byte2' fields into real numbers.

Signed-off-by: Markus Schneider-Pargmann 
---

Notes:
Changes v2 -> v3:
- Add DRM_ prefix to the CEA_SAD defines.

Changes v1 -> v2:
- Use const struct pointers.
- Add a check whether the format is actually uncompressed or not.

 drivers/gpu/drm/drm_edid.c | 74 ++
 include/drm/drm_edid.h | 18 --
 2 files changed, 90 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index 6325877c5fd6..c134803e18db 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -4666,6 +4666,80 @@ int drm_edid_to_speaker_allocation(struct edid *edid, u8 
**sadb)
 }
 EXPORT_SYMBOL(drm_edid_to_speaker_allocation);
 
+/**
+ * drm_cea_sad_get_sample_rate - Extract the sample rate from cea_sad
+ * @sad: Pointer to the cea_sad struct
+ *
+ * Extracts the cea_sad frequency field and returns the sample rate in Hz.
+ *
+ * Return: Sample rate in Hz or a negative errno if parsing failed.
+ */
+int drm_cea_sad_get_sample_rate(const struct cea_sad *sad)
+{
+   switch (sad->freq) {
+   case DRM_CEA_SAD_FREQ_32KHZ:
+   return 32000;
+   case DRM_CEA_SAD_FREQ_44KHZ:
+   return 44100;
+   case DRM_CEA_SAD_FREQ_48KHZ:
+   return 48000;
+   case DRM_CEA_SAD_FREQ_88KHZ:
+   return 88200;
+   case DRM_CEA_SAD_FREQ_96KHZ:
+   return 96000;
+   case DRM_CEA_SAD_FREQ_176KHZ:
+   return 176400;
+   case DRM_CEA_SAD_FREQ_192KHZ:
+   return 192000;
+   default:
+   return -EINVAL;
+   }
+}
+EXPORT_SYMBOL(drm_cea_sad_get_sample_rate);
+
+static bool drm_cea_sad_is_uncompressed(const struct cea_sad *sad)
+{
+   switch (sad->format) {
+   case HDMI_AUDIO_CODING_TYPE_STREAM:
+   case HDMI_AUDIO_CODING_TYPE_PCM:
+   return true;
+   default:
+   return false;
+   }
+}
+
+/**
+ * drm_cea_sad_get_uncompressed_word_length - Extract word length
+ * @sad: Pointer to the cea_sad struct
+ *
+ * Extracts the cea_sad byte2 field and returns the word length for an
+ * uncompressed stream.
+ *
+ * Note: This function may only be called for uncompressed audio.
+ *
+ * Return: Word length in bits or a negative errno if parsing failed.
+ */
+int drm_cea_sad_get_uncompressed_word_length(const struct cea_sad *sad)
+{
+   if (!drm_cea_sad_is_uncompressed(sad)) {
+   DRM_WARN("Unable to get the uncompressed word length for a 
compressed format: %u\n",
+sad->format);
+   return -EINVAL;
+   }
+
+   switch (sad->byte2) {
+   case DRM_CEA_SAD_UNCOMPRESSED_WORD_16BIT:
+   return 16;
+   case DRM_CEA_SAD_UNCOMPRESSED_WORD_20BIT:
+   return 20;
+   case DRM_CEA_SAD_UNCOMPRESSED_WORD_24BIT:
+   return 24;
+   default:
+   return -EINVAL;
+   }
+}
+EXPORT_SYMBOL(drm_cea_sad_get_uncompressed_word_length);
+
 /**
  * drm_av_sync_delay - compute the HDMI/DP sink audio-video sync delay
  * @connector: connector associated with the HDMI/DP sink
diff --git a/include/drm/drm_edid.h b/include/drm/drm_edid.h
index deccfd39e6db..9d75df652b17 100644
--- a/include/drm/drm_edid.h
+++ b/include/drm/drm_edid.h
@@ -361,12 +361,24 @@ struct edid {
 
 /* Short Audio Descriptor */
 struct cea_sad {
-   u8 format;
+   u8 format; /* See HDMI_AUDIO_CODING_TYPE_* */
u8 channels; /* max number of channels - 1 */
-   u8 freq;
+   u8 freq; /* See CEA_SAD_FREQ_* */
u8 byte2; /* meaning depends on format */
 };
 
+#define DRM_CEA_SAD_FREQ_32KHZ  BIT(0)
+#define DRM_CEA_SAD_FREQ_44KHZ  BIT(1)
+#define DRM_CEA_SAD_FREQ_48KHZ  BIT(2)
+#define DRM_CEA_SAD_FREQ_88KHZ  BIT(3)
+#define DRM_CEA_SAD_FREQ_96KHZ  BIT(4)
+#define DRM_CEA_SAD_FREQ_176KHZ BIT(5)
+#define DRM_CEA_SAD_FREQ_192KHZ BIT(6)
+
+#define DRM_CEA_SAD_UNCOMPRESSED_WORD_16BIT BIT(0)
+#define DRM_CEA_SAD_UNCOMPRESSED_WORD_20BIT BIT(1)
+#define DRM_CEA_SAD_UNCOMPRESSED_WORD_24BIT BIT(2)
+
 struct drm_encoder;
 struct drm_connector;
 struct drm_connector_state;
@@ -374,6 +386,8 @@ struct drm_display_mode;
 
 int drm_edid_to_sad(struct edid *edid, struct cea_sad **sads);
 int drm_edid_to_speaker_allocation(struct edid *edid, u8 **sadb);
+int drm_cea_sad_get_sample_rate(const struct cea_sad *sad);
+int drm_cea_sad_get_uncompressed_word_length(const struct cea_sad *sad);
 int drm_av_sync_delay(struct drm_connector *connector,
  const struct drm_display_mode *mode);
 
-- 
2.33.0



[PATCH v5 2/7] dt-bindings: mediatek,dp: Add Display Port binding

2021-10-21 Thread Markus Schneider-Pargmann
This controller is present on several mediatek hardware. Currently
mt8195 and mt8395 have this controller without a functional difference,
so only one compatible field is added.

The controller can have two forms, as a normal display port and as an
embedded display port.

Signed-off-by: Markus Schneider-Pargmann 
---

Notes:
Changes v4 -> v5:
- Removed "status" in the example
- Remove edp_tx compatible.
- Rename dp_tx compatible to dp-tx.

 .../display/mediatek/mediatek,dp.yaml | 87 +++
 1 file changed, 87 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/display/mediatek/mediatek,dp.yaml

diff --git 
a/Documentation/devicetree/bindings/display/mediatek/mediatek,dp.yaml 
b/Documentation/devicetree/bindings/display/mediatek/mediatek,dp.yaml
new file mode 100644
index ..068b11d766e2
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,dp.yaml
@@ -0,0 +1,87 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/mediatek/mediatek,dp.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Mediatek Display Port Controller
+
+maintainers:
+  - CK Hu 
+  - Jitao shi 
+
+description: |
+  Device tree bindings for the Mediatek (embedded) Display Port controller
+  present on some Mediatek SoCs.
+
+properties:
+  compatible:
+enum:
+  - mediatek,mt8195-dp-tx
+
+  reg:
+maxItems: 1
+
+  interrupts:
+maxItems: 1
+
+  clocks:
+items:
+  - description: faxi clock
+
+  clock-names:
+items:
+  - const: faxi
+
+  power-domains:
+maxItems: 1
+
+  ports:
+$ref: /schemas/graph.yaml#/properties/ports
+properties:
+  port@0:
+$ref: /schemas/graph.yaml#/properties/port
+description: Input endpoint of the controller, usually dp_intf
+
+  port@1:
+$ref: /schemas/graph.yaml#/properties/port
+description: Output endpoint of the controller
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - ports
+
+additionalProperties: false
+
+examples:
+  - |
+#include 
+#include 
+edp_tx: edp_tx@1c50 {
+compatible = "mediatek,mt8195-dp-tx";
+reg = <0 0x1c50 0 0x8000>;
+interrupts = ;
+power-domains = < MT8195_POWER_DOMAIN_EPD_TX>;
+pinctrl-names = "default";
+pinctrl-0 = <_pin>;
+
+ports {
+#address-cells = <1>;
+#size-cells = <0>;
+
+port@0 {
+reg = <0>;
+edp_in: endpoint {
+remote-endpoint = <_intf0_out>;
+};
+};
+port@1 {
+reg = <1>;
+edp_out: endpoint {
+   remote-endpoint = <_in>;
+};
+};
+};
+};
-- 
2.33.0



[PATCH v5 4/7] video/hdmi: Add audio_infoframe packing for DP

2021-10-21 Thread Markus Schneider-Pargmann
Similar to HDMI, DP uses audio infoframes as well which are structured
very similar to the HDMI ones.

This patch adds a helper function to pack the HDMI audio infoframe for
DP, called hdmi_audio_infoframe_pack_for_dp().
hdmi_audio_infoframe_pack_only() is split into two parts. One of them
packs the payload only and can be used for HDMI and DP.

Signed-off-by: Markus Schneider-Pargmann 
---

Notes:
Changes v1 -> v2:
- Create a define for HB2.
- Use struct dp_sdp to pass data in a better way.

 drivers/video/hdmi.c| 83 -
 include/drm/drm_dp_helper.h |  2 +
 include/linux/hdmi.h|  7 +++-
 3 files changed, 72 insertions(+), 20 deletions(-)

diff --git a/drivers/video/hdmi.c b/drivers/video/hdmi.c
index 947be761dfa4..63e74d9fd210 100644
--- a/drivers/video/hdmi.c
+++ b/drivers/video/hdmi.c
@@ -21,6 +21,7 @@
  * DEALINGS IN THE SOFTWARE.
  */
 
+#include 
 #include 
 #include 
 #include 
@@ -381,12 +382,34 @@ static int hdmi_audio_infoframe_check_only(const struct 
hdmi_audio_infoframe *fr
  *
  * Returns 0 on success or a negative error code on failure.
  */
-int hdmi_audio_infoframe_check(struct hdmi_audio_infoframe *frame)
+int hdmi_audio_infoframe_check(const struct hdmi_audio_infoframe *frame)
 {
return hdmi_audio_infoframe_check_only(frame);
 }
 EXPORT_SYMBOL(hdmi_audio_infoframe_check);
 
+static void
+hdmi_audio_infoframe_pack_payload(const struct hdmi_audio_infoframe *frame,
+ u8 *buffer)
+{
+   u8 channels;
+
+   if (frame->channels >= 2)
+   channels = frame->channels - 1;
+   else
+   channels = 0;
+
+   buffer[0] = ((frame->coding_type & 0xf) << 4) | (channels & 0x7);
+   buffer[1] = ((frame->sample_frequency & 0x7) << 2) |
+(frame->sample_size & 0x3);
+   buffer[2] = frame->coding_type_ext & 0x1f;
+   buffer[3] = frame->channel_allocation;
+   buffer[4] = (frame->level_shift_value & 0xf) << 3;
+
+   if (frame->downmix_inhibit)
+   buffer[4] |= BIT(7);
+}
+
 /**
  * hdmi_audio_infoframe_pack_only() - write HDMI audio infoframe to binary 
buffer
  * @frame: HDMI audio infoframe
@@ -404,7 +427,6 @@ EXPORT_SYMBOL(hdmi_audio_infoframe_check);
 ssize_t hdmi_audio_infoframe_pack_only(const struct hdmi_audio_infoframe 
*frame,
   void *buffer, size_t size)
 {
-   unsigned char channels;
u8 *ptr = buffer;
size_t length;
int ret;
@@ -420,28 +442,13 @@ ssize_t hdmi_audio_infoframe_pack_only(const struct 
hdmi_audio_infoframe *frame,
 
memset(buffer, 0, size);
 
-   if (frame->channels >= 2)
-   channels = frame->channels - 1;
-   else
-   channels = 0;
-
ptr[0] = frame->type;
ptr[1] = frame->version;
ptr[2] = frame->length;
ptr[3] = 0; /* checksum */
 
-   /* start infoframe payload */
-   ptr += HDMI_INFOFRAME_HEADER_SIZE;
-
-   ptr[0] = ((frame->coding_type & 0xf) << 4) | (channels & 0x7);
-   ptr[1] = ((frame->sample_frequency & 0x7) << 2) |
-(frame->sample_size & 0x3);
-   ptr[2] = frame->coding_type_ext & 0x1f;
-   ptr[3] = frame->channel_allocation;
-   ptr[4] = (frame->level_shift_value & 0xf) << 3;
-
-   if (frame->downmix_inhibit)
-   ptr[4] |= BIT(7);
+   hdmi_audio_infoframe_pack_payload(frame,
+ ptr + HDMI_INFOFRAME_HEADER_SIZE);
 
hdmi_infoframe_set_checksum(buffer, length);
 
@@ -479,6 +486,44 @@ ssize_t hdmi_audio_infoframe_pack(struct 
hdmi_audio_infoframe *frame,
 }
 EXPORT_SYMBOL(hdmi_audio_infoframe_pack);
 
+/**
+ * hdmi_audio_infoframe_pack_for_dp - Pack a HDMI Audio infoframe for
+ *displayport
+ *
+ * @frame HDMI Audio infoframe
+ * @sdp secondary data packet for display port. This is filled with the
+ * appropriate data
+ * @dp_version Display Port version to be encoded in the header
+ *
+ * Packs a HDMI Audio Infoframe to be sent over Display Port. This function
+ * fills the secondary data packet to be used for Display Port.
+ *
+ * Return: Number of total written bytes or a negative errno on failure.
+ */
+ssize_t
+hdmi_audio_infoframe_pack_for_dp(const struct hdmi_audio_infoframe *frame,
+struct dp_sdp *sdp, u8 dp_version)
+{
+   int ret;
+
+   ret = hdmi_audio_infoframe_check(frame);
+   if (ret)
+   return ret;
+
+   memset(sdp->db, 0, sizeof(sdp->db));
+
+   // Secondary-data packet header
+   sdp->sdp_header.HB0 = 0;
+   sdp->sdp_header.HB1 = frame->type;
+   sdp->sdp_header.HB2 = DP_SDP_AUDIO_INFOFRAME_HB2;
+   sdp->sdp_header.HB

[PATCH v5 5/7] drm/mediatek: dpi: Add dpintf support

2021-10-21 Thread Markus Schneider-Pargmann
dpintf is the displayport interface hardware unit. This unit is similar
to dpi and can reuse most of the code.

This patch adds support for mt8195-dpintf to this dpi driver. Main
differences are:
 - Some features/functional components are not available for dpintf
   which are now excluded from code execution once is_dpintf is set
 - dpintf can and needs to choose between different clockdividers based
   on the clockspeed. This is done by choosing a different clock parent.
 - There are two additional clocks that need to be managed. These are
   only set for dpintf and will be set to NULL if not supplied. The
   clk_* calls handle these as normal clocks then.
 - Some register contents differ slightly between the two components. To
   work around this I added register bits/masks with a DPINTF_ prefix
   and use them where different.

Based on a separate driver for dpintf created by
Jason-JH.Lin .

Signed-off-by: Markus Schneider-Pargmann 
---

Notes:
Changes v4 -> v5:
- Add several fields to characterize what is supported and what isn't in 
dpintf
  vs dpi.
- Remove false bool field assignments where not necessary.
- Removed specific clocks and reduced them to the standard engine and pixel
  clocks.
- Remove extra set of bridge functions and define output formats for mt8195
- Define register masks to avoid using is_dpintf variable.
- Extract the limits into mtk_dpi_conf to avoid using is_dpintf.

Changes RFC -> v1:
- Remove setting parents and fully rely on the clock tree instead which 
already
  models a mux at the important place.
- Integrated mtk_dpi dpintf changes into the mediatek drm driver.

 drivers/gpu/drm/mediatek/mtk_dpi.c  | 199 +++-
 drivers/gpu/drm/mediatek/mtk_dpi_regs.h |  12 ++
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c |   4 +
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h |   1 +
 drivers/gpu/drm/mediatek/mtk_drm_drv.c  |   5 +-
 include/linux/soc/mediatek/mtk-mmsys.h  |   2 +
 6 files changed, 176 insertions(+), 47 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c 
b/drivers/gpu/drm/mediatek/mtk_dpi.c
index 4554e2de1430..384074f69111 100644
--- a/drivers/gpu/drm/mediatek/mtk_dpi.c
+++ b/drivers/gpu/drm/mediatek/mtk_dpi.c
@@ -125,6 +125,17 @@ struct mtk_dpi_conf {
bool edge_sel_en;
const u32 *output_fmts;
u32 num_output_fmts;
+   bool is_ck_de_pol;
+   bool is_dpintf;
+   bool csc_support;
+   bool swap_input_support;
+   // Mask used for HWIDTH, HPORCH, VSYNC_WIDTH and VSYNC_PORCH (no shift)
+   u32 dimension_mask;
+   // Mask used for HSIZE and VSIZE (no shift)
+   u32 hvsize_mask;
+   u32 channel_swap_shift;
+   u32 yuv422_en_bit;
+   const struct mtk_dpi_yc_limit *limit;
 };
 
 static void mtk_dpi_mask(struct mtk_dpi *dpi, u32 offset, u32 val, u32 mask)
@@ -153,30 +164,30 @@ static void mtk_dpi_disable(struct mtk_dpi *dpi)
 static void mtk_dpi_config_hsync(struct mtk_dpi *dpi,
 struct mtk_dpi_sync_param *sync)
 {
-   mtk_dpi_mask(dpi, DPI_TGEN_HWIDTH,
-sync->sync_width << HPW, HPW_MASK);
-   mtk_dpi_mask(dpi, DPI_TGEN_HPORCH,
-sync->back_porch << HBP, HBP_MASK);
+   mtk_dpi_mask(dpi, DPI_TGEN_HWIDTH, sync->sync_width << HPW,
+dpi->conf->dimension_mask << HPW);
+   mtk_dpi_mask(dpi, DPI_TGEN_HPORCH, sync->back_porch << HBP,
+dpi->conf->dimension_mask << HBP);
mtk_dpi_mask(dpi, DPI_TGEN_HPORCH, sync->front_porch << HFP,
-HFP_MASK);
+dpi->conf->dimension_mask << HFP);
 }
 
 static void mtk_dpi_config_vsync(struct mtk_dpi *dpi,
 struct mtk_dpi_sync_param *sync,
 u32 width_addr, u32 porch_addr)
 {
-   mtk_dpi_mask(dpi, width_addr,
-sync->sync_width << VSYNC_WIDTH_SHIFT,
-VSYNC_WIDTH_MASK);
mtk_dpi_mask(dpi, width_addr,
 sync->shift_half_line << VSYNC_HALF_LINE_SHIFT,
 VSYNC_HALF_LINE_MASK);
+   mtk_dpi_mask(dpi, width_addr,
+sync->sync_width << VSYNC_WIDTH_SHIFT,
+dpi->conf->dimension_mask << VSYNC_WIDTH_SHIFT);
mtk_dpi_mask(dpi, porch_addr,
 sync->back_porch << VSYNC_BACK_PORCH_SHIFT,
-VSYNC_BACK_PORCH_MASK);
+dpi->conf->dimension_mask << VSYNC_BACK_PORCH_SHIFT);
mtk_dpi_mask(dpi, porch_addr,
 sync->front_porch << VSYNC_FRONT_PORCH_SHIFT,
-VSYNC_FRONT_PORCH_MASK);
+dpi->conf->dimension_mask << VSYNC_FRONT_PORCH_SHIFT);
 }
 
 static void mtk_dpi_c

[PATCH v5 6/7] phy: phy-mtk-dp: Add driver for DP phy

2021-10-21 Thread Markus Schneider-Pargmann
This is a new driver that supports the integrated DisplayPort phy for
mediatek SoCs, especially the mt8195. The phy is integrated into the
DisplayPort controller and will be created by the mtk-dp driver. This
driver expects a struct regmap to be able to work on the same registers
as the DisplayPort controller. It sets the device data to be the struct
phy so that the DisplayPort controller can easily work with it.

The driver does not have any devicetree bindings because the datasheet
does not list the controller and the phy as distinct units.

The interaction with the controller can be covered by the configure
callback of the phy framework and its displayport parameters.

Signed-off-by: Markus Schneider-Pargmann 
---

Notes:
Changes v3 -> v4:
- Split DP controller driver and phy driver into separate patches.
- Add entry to MAINTAINERS for this phy driver

 MAINTAINERS   |   1 +
 drivers/phy/mediatek/Kconfig  |   8 ++
 drivers/phy/mediatek/Makefile |   1 +
 drivers/phy/mediatek/phy-mtk-dp.c | 219 ++
 4 files changed, 229 insertions(+)
 create mode 100644 drivers/phy/mediatek/phy-mtk-dp.c

diff --git a/MAINTAINERS b/MAINTAINERS
index eeb4c70b3d5b..8a47eb628734 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -6276,6 +6276,7 @@ L:linux-media...@lists.infradead.org (moderated 
for non-subscribers)
 S: Supported
 F: Documentation/devicetree/bindings/display/mediatek/
 F: drivers/gpu/drm/mediatek/
+F: drivers/phy/mediatek/phy-mtk-dp.c
 F: drivers/phy/mediatek/phy-mtk-hdmi*
 F: drivers/phy/mediatek/phy-mtk-mipi*
 
diff --git a/drivers/phy/mediatek/Kconfig b/drivers/phy/mediatek/Kconfig
index 55f8e6c048ab..f7ec86059049 100644
--- a/drivers/phy/mediatek/Kconfig
+++ b/drivers/phy/mediatek/Kconfig
@@ -55,3 +55,11 @@ config PHY_MTK_MIPI_DSI
select GENERIC_PHY
help
  Support MIPI DSI for Mediatek SoCs.
+
+config PHY_MTK_DP
+   tristate "MediaTek DP-PHY Driver"
+   depends on ARCH_MEDIATEK || COMPILE_TEST
+   depends on OF
+   select GENERIC_PHY
+   help
+ Support DisplayPort PHY for Mediatek SoCs.
diff --git a/drivers/phy/mediatek/Makefile b/drivers/phy/mediatek/Makefile
index ace660fbed3a..4ba1e0650434 100644
--- a/drivers/phy/mediatek/Makefile
+++ b/drivers/phy/mediatek/Makefile
@@ -3,6 +3,7 @@
 # Makefile for the phy drivers.
 #
 
+obj-$(CONFIG_PHY_MTK_DP)   += phy-mtk-dp.o
 obj-$(CONFIG_PHY_MTK_TPHY) += phy-mtk-tphy.o
 obj-$(CONFIG_PHY_MTK_UFS)  += phy-mtk-ufs.o
 obj-$(CONFIG_PHY_MTK_XSPHY)+= phy-mtk-xsphy.o
diff --git a/drivers/phy/mediatek/phy-mtk-dp.c 
b/drivers/phy/mediatek/phy-mtk-dp.c
new file mode 100644
index ..296203e319ac
--- /dev/null
+++ b/drivers/phy/mediatek/phy-mtk-dp.c
@@ -0,0 +1,219 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2021 BayLibre
+ * Author: Markus Schneider-Pargmann 
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define PHY_OFFSET 0x1000
+
+#define MTK_DP_PHY_DIG_PLL_CTL_1   (PHY_OFFSET + 0x014)
+# define TPLL_SSC_EN   BIT(3)
+
+#define MTK_DP_PHY_DIG_BIT_RATE(PHY_OFFSET + 0x03C)
+# define BIT_RATE_RBR  0
+# define BIT_RATE_HBR  1
+# define BIT_RATE_HBR2 2
+# define BIT_RATE_HBR3 3
+
+#define MTK_DP_PHY_DIG_SW_RST  (PHY_OFFSET + 0x038)
+# define DP_GLB_SW_RST_PHYDBIT(0)
+
+#define MTK_DP_LANE0_DRIVING_PARAM_3   (PHY_OFFSET + 0x138)
+#define MTK_DP_LANE1_DRIVING_PARAM_3   (PHY_OFFSET + 0x238)
+#define MTK_DP_LANE2_DRIVING_PARAM_3   (PHY_OFFSET + 0x338)
+#define MTK_DP_LANE3_DRIVING_PARAM_3   (PHY_OFFSET + 0x438)
+# define XTP_LN_TX_LCTXC0_SW0_PRE0_DEFAULT 0x10
+# define XTP_LN_TX_LCTXC0_SW0_PRE1_DEFAULT (0x14 << 8)
+# define XTP_LN_TX_LCTXC0_SW0_PRE2_DEFAULT (0x18 << 16)
+# define XTP_LN_TX_LCTXC0_SW0_PRE3_DEFAULT (0x20 << 24)
+# define DRIVING_PARAM_3_DEFAULT   
(XTP_LN_TX_LCTXC0_SW0_PRE0_DEFAULT | \
+
XTP_LN_TX_LCTXC0_SW0_PRE1_DEFAULT | \
+
XTP_LN_TX_LCTXC0_SW0_PRE2_DEFAULT | \
+
XTP_LN_TX_LCTXC0_SW0_PRE3_DEFAULT)
+
+#define MTK_DP_LANE0_DRIVING_PARAM_4   (PHY_OFFSET + 0x13C)
+#define MTK_DP_LANE1_DRIVING_PARAM_4   (PHY_OFFSET + 0x23C)
+#define MTK_DP_LANE2_DRIVING_PARAM_4   (PHY_OFFSET + 0x33C)
+#define MTK_DP_LANE3_DRIVING_PARAM_4   (PHY_OFFSET + 0x43C)
+# define XTP_LN_TX_LCTXC0_SW1_PRE0_DEFAULT 0x18
+# define XTP_LN_TX_LCTXC0_SW1_PRE1_DEFAULT (0x1e << 8)
+# define XTP_LN_TX_LCTXC0_SW1_PRE2_DEFAULT (0x24 << 16)
+# define XTP_LN_TX_LCTXC0_

[PATCH v5 0/7] drm/mediatek: Add mt8195 DisplayPort driver

2021-10-21 Thread Markus Schneider-Pargmann
Hi everyone,

this series is built around the DisplayPort driver. The dpi/dpintf
driver and the added helper functions are required for the DisplayPort
driver to work.

In v5 I reworked the mtk-dpi so that dpintf is only using the same three clocks
as dpi does. This lead to the removal of the separate dpintf binding document.
Also there are minor updates to the mtk-dp binding and driver.

The series is based on v5.15-rc1 but also applies cleanly on linux-next.
Note: This patch series is currently tested on v5.10 and I am still
working on testing it on v5.15.

Thanks in advance for any feedback and comments.

Best,
Markus


Functional dependencies are:
- Add Mediatek Soc DRM (vdosys0) support for mt8195
  
https://lore.kernel.org/linux-mediatek/20210921155218.10387-1-jason-jh@mediatek.com/
- Add MediaTek SoC DRM (vdosys1) support for mt8195
  
https://lore.kernel.org/linux-mediatek/20211004062140.29803-1-nancy@mediatek.com/

Older revisions:
RFC - 
https://lore.kernel.org/linux-mediatek/20210816192523.1739365-1-...@baylibre.com/
v1  - 
https://lore.kernel.org/linux-mediatek/20210906193529.718845-1-...@baylibre.com/
v2  - 
https://lore.kernel.org/linux-mediatek/20210920084424.231825-1-...@baylibre.com/
v3  - 
https://lore.kernel.org/linux-mediatek/20211001094443.2770169-1-...@baylibre.com/
v4  - 
https://lore.kernel.org/linux-mediatek/20211011094624.3416029-1-...@baylibre.com/


Markus Schneider-Pargmann (7):
  dt-bindings: mediatek,dpi: Add DP_INTF compatible
  dt-bindings: mediatek,dp: Add Display Port binding
  drm/edid: Add cea_sad helpers for freq/length
  video/hdmi: Add audio_infoframe packing for DP
  drm/mediatek: dpi: Add dpintf support
  phy: phy-mtk-dp: Add driver for DP phy
  drm/mediatek: Add mt8195 DisplayPort driver

 .../display/mediatek/mediatek,dp.yaml |   87 +
 .../display/mediatek/mediatek,dpi.yaml|   11 +-
 MAINTAINERS   |1 +
 drivers/gpu/drm/drm_edid.c|   74 +
 drivers/gpu/drm/mediatek/Kconfig  |7 +
 drivers/gpu/drm/mediatek/Makefile |2 +
 drivers/gpu/drm/mediatek/mtk_dp.c | 2813 +
 drivers/gpu/drm/mediatek/mtk_dp_reg.h |  535 
 drivers/gpu/drm/mediatek/mtk_dpi.c|  199 +-
 drivers/gpu/drm/mediatek/mtk_dpi_regs.h   |   12 +
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c   |4 +
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h   |1 +
 drivers/gpu/drm/mediatek/mtk_drm_drv.c|6 +-
 drivers/gpu/drm/mediatek/mtk_drm_drv.h|1 +
 drivers/phy/mediatek/Kconfig  |8 +
 drivers/phy/mediatek/Makefile |1 +
 drivers/phy/mediatek/phy-mtk-dp.c |  219 ++
 drivers/video/hdmi.c  |   83 +-
 include/drm/drm_dp_helper.h   |2 +
 include/drm/drm_edid.h|   18 +-
 include/linux/hdmi.h  |7 +-
 include/linux/soc/mediatek/mtk-mmsys.h|2 +
 22 files changed, 4019 insertions(+), 74 deletions(-)
 create mode 100644 
Documentation/devicetree/bindings/display/mediatek/mediatek,dp.yaml
 create mode 100644 drivers/gpu/drm/mediatek/mtk_dp.c
 create mode 100644 drivers/gpu/drm/mediatek/mtk_dp_reg.h
 create mode 100644 drivers/phy/mediatek/phy-mtk-dp.c

-- 
2.33.0



[PATCH v5 1/7] dt-bindings: mediatek,dpi: Add DP_INTF compatible

2021-10-21 Thread Markus Schneider-Pargmann
DP_INTF is similar to DPI but does not have the exact same feature set
or register layouts.

DP_INTF is the sink of the display pipeline that is connected to the
DisplayPort controller and encoder unit. It takes the same clocks as
DPI.

Signed-off-by: Markus Schneider-Pargmann 
---

Notes:
Changes v4 -> v5:
- Newly created patch after realizing that the specific clocks for dpintf 
were
  the same as engine and pixel clocks.

 .../bindings/display/mediatek/mediatek,dpi.yaml   | 11 ++-
 1 file changed, 6 insertions(+), 5 deletions(-)

diff --git 
a/Documentation/devicetree/bindings/display/mediatek/mediatek,dpi.yaml 
b/Documentation/devicetree/bindings/display/mediatek/mediatek,dpi.yaml
index dd2896a40ff0..53acf9a84f7f 100644
--- a/Documentation/devicetree/bindings/display/mediatek/mediatek,dpi.yaml
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,dpi.yaml
@@ -4,16 +4,16 @@
 $id: http://devicetree.org/schemas/display/mediatek/mediatek,dpi.yaml#
 $schema: http://devicetree.org/meta-schemas/core.yaml#
 
-title: mediatek DPI Controller Device Tree Bindings
+title: mediatek DPI/DP_INTF Controller Device Tree Bindings
 
 maintainers:
   - CK Hu 
   - Jitao shi 
 
 description: |
-  The Mediatek DPI function block is a sink of the display subsystem and
-  provides 8-bit RGB/YUV444 or 8/10/10-bit YUV422 pixel data on a parallel
-  output bus.
+  The Mediatek DPI and DP_INTF function blocks are a sink of the display
+  subsystem and provides 8-bit RGB/YUV444 or 8/10/10-bit YUV422 pixel data on a
+  parallel output bus.
 
 properties:
   compatible:
@@ -23,6 +23,7 @@ properties:
   - mediatek,mt8173-dpi
   - mediatek,mt8183-dpi
   - mediatek,mt8192-dpi
+  - mediatek,mt8195-dpintf
 
   reg:
 maxItems: 1
@@ -54,7 +55,7 @@ properties:
 $ref: /schemas/graph.yaml#/properties/port
 description:
   Output port node. This port should be connected to the input port of an
-  attached HDMI or LVDS encoder chip.
+  attached HDMI, LVDS or DisplayPort encoder chip.
 
 required:
   - compatible
-- 
2.33.0



Re: [PATCH v4 2/7] dt-bindings: mediatek, dp: Add Display Port binding

2021-10-20 Thread Markus Schneider-Pargmann
Hi Rob,

On Mon, Oct 18, 2021 at 02:38:33PM -0500, Rob Herring wrote:
> On Mon, Oct 18, 2021 at 9:19 AM Markus Schneider-Pargmann
>  wrote:
> >
> > Hi Rob,
> >
> > On Mon, Oct 11, 2021 at 07:43:16PM -0500, Rob Herring wrote:
> > > On Mon, Oct 11, 2021 at 11:46:19AM +0200, Markus Schneider-Pargmann wrote:
> > > > This controller is present on several mediatek hardware. Currently
> > > > mt8195 and mt8395 have this controller without a functional difference,
> > > > so only one compatible field is added.
> > > >
> > > > The controller can have two forms, as a normal display port and as an
> > > > embedded display port.
> > > >
> > > > Signed-off-by: Markus Schneider-Pargmann 
> > > > ---
> > > >  .../display/mediatek/mediatek,dp.yaml | 89 +++
> > > >  1 file changed, 89 insertions(+)
> > > >  create mode 100644 
> > > > Documentation/devicetree/bindings/display/mediatek/mediatek,dp.yaml
> > > >
> > > > diff --git 
> > > > a/Documentation/devicetree/bindings/display/mediatek/mediatek,dp.yaml 
> > > > b/Documentation/devicetree/bindings/display/mediatek/mediatek,dp.yaml
> > > > new file mode 100644
> > > > index ..f7a35962c23b
> > > > --- /dev/null
> > > > +++ 
> > > > b/Documentation/devicetree/bindings/display/mediatek/mediatek,dp.yaml
> > > > @@ -0,0 +1,89 @@
> > > > +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> > > > +%YAML 1.2
> > > > +---
> > > > +$id: http://devicetree.org/schemas/display/mediatek/mediatek,dp.yaml#
> > > > +$schema: http://devicetree.org/meta-schemas/core.yaml#
> > > > +
> > > > +title: Mediatek Display Port Controller
> > > > +
> > > > +maintainers:
> > > > +  - CK Hu 
> > > > +  - Jitao shi 
> > > > +
> > > > +description: |
> > > > +  Device tree bindings for the Mediatek (embedded) Display Port 
> > > > controller
> > > > +  present on some Mediatek SoCs.
> > > > +
> > > > +properties:
> > > > +  compatible:
> > > > +enum:
> > > > +  - mediatek,mt8195-edp_tx
> > > > +  - mediatek,mt8195-dp_tx
> > >
> > > Are these blocks different?
> >
> > Good point, the registers of these blocks are described in its own
> > chapter each. Also I do need to distinguish between both in the driver.
> > Would you suggest making this distinction differently or keep it as two
> > compatibles?
> 
> If the registers are all the same, then it should be the same
> compatible. If you still need to distinguish, then you should have a
> panel or connector node that will let you do that.

Thank you. Good idea to check with the connector node, I have changed it
as you suggested.

> 
> Also, s/_/-/ in the compatible string.

Done.

Thanks,
Markus


Re: [PATCH v4 1/7] dt-bindings: mediatek,dpintf: Add DP_INTF binding

2021-10-20 Thread Markus Schneider-Pargmann
Hi Rob,

On Mon, Oct 11, 2021 at 06:44:53PM -0500, Rob Herring wrote:
> On Mon, 11 Oct 2021 11:46:18 +0200, Markus Schneider-Pargmann wrote:
> > DP_INTF is a similar functional block to mediatek,dpi but is different
> > in that it serves the DisplayPort controller on mediatek SoCs and uses
> > different clocks. Therefore this patch creates a new binding file for
> > this functional block.
> > 
> > Signed-off-by: Markus Schneider-Pargmann 
> > ---
> > 
> > Notes:
> > Changes v3 -> v4:
> > - Fixed clock names in the example as the clock patch series is merged 
> > into
> >   next now
> > - Add missing ports decleration to the example
> > 
> > Changes v1 -> v2:
> > - Move the devicetree binding from mediatek,dpi into its own binding 
> > file.
> > 
> >  .../display/mediatek/mediatek,dpintf.yaml | 86 +++
> >  1 file changed, 86 insertions(+)
> >  create mode 100644 
> > Documentation/devicetree/bindings/display/mediatek/mediatek,dpintf.yaml
> > 
> 
> Reviewed-by: Rob Herring 

Thanks a lot for reviewing. However I am going to recombine dpintf with
dpi as Chun-Kuang helped me realize that the fdp clock is a parent of
the pixel clock and therefore not a different clock. In the end the
clocks are the same now for both dpi and dpintf, so no need for a
separate document.

Best,
Markus


Re: [PATCH v3 5/6] drm/mediatek: dpi: Add dpintf support

2021-10-20 Thread Markus Schneider-Pargmann
Hi Chun-Kuang,

On Fri, Oct 15, 2021 at 12:04:10AM +0800, Chun-Kuang Hu wrote:
> Hi, Markus:
> 
> Markus Schneider-Pargmann  於 2021年10月1日 週五 下午5:44寫道:
> >
> > dpintf is the displayport interface hardware unit. This unit is similar
> > to dpi and can reuse most of the code.
> >
> > This patch adds support for mt8195-dpintf to this dpi driver. Main
> > differences are:
> >  - Some features/functional components are not available for dpintf
> >which are now excluded from code execution once is_dpintf is set
> >  - dpintf can and needs to choose between different clockdividers based
> >on the clockspeed. This is done by choosing a different clock parent.
> >  - There are two additional clocks that need to be managed. These are
> >only set for dpintf and will be set to NULL if not supplied. The
> >clk_* calls handle these as normal clocks then.
> >  - Some register contents differ slightly between the two components. To
> >work around this I added register bits/masks with a DPINTF_ prefix
> >and use them where different.
> >
> > Based on a separate driver for dpintf created by
> > Jason-JH.Lin .
> >
> > Signed-off-by: Markus Schneider-Pargmann 
> > ---
> >
> > Notes:
> > Changes RFC -> v1:
> > - Remove setting parents and fully rely on the clock tree instead which 
> > already
> >   models a mux at the important place.
> > - Integrated mtk_dpi dpintf changes into the mediatek drm driver.
> >
> >  drivers/gpu/drm/mediatek/mtk_dpi.c  | 248 
> >  drivers/gpu/drm/mediatek/mtk_dpi_regs.h |  12 +
> >  drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c |   4 +
> >  drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h |   1 +
> >  drivers/gpu/drm/mediatek/mtk_drm_drv.c  |   5 +-
> >  5 files changed, 218 insertions(+), 52 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c 
> > b/drivers/gpu/drm/mediatek/mtk_dpi.c
> > index 4554e2de1430..87961ebf5d35 100644
> > --- a/drivers/gpu/drm/mediatek/mtk_dpi.c
> > +++ b/drivers/gpu/drm/mediatek/mtk_dpi.c
> > @@ -71,6 +71,8 @@ struct mtk_dpi {
> > void __iomem *regs;
> > struct device *dev;
> > struct clk *engine_clk;
> > +   struct clk *hf_fmm_clk;
> > +   struct clk *hf_fdp_clk;
> > struct clk *pixel_clk;
> > struct clk *tvd_clk;
> > int irq;
> > @@ -125,6 +127,7 @@ struct mtk_dpi_conf {
> > bool edge_sel_en;
> > const u32 *output_fmts;
> > u32 num_output_fmts;
> > +   bool is_dpintf;
> >  };
> >
> >  static void mtk_dpi_mask(struct mtk_dpi *dpi, u32 offset, u32 val, u32 
> > mask)
> > @@ -153,30 +156,52 @@ static void mtk_dpi_disable(struct mtk_dpi *dpi)
> >  static void mtk_dpi_config_hsync(struct mtk_dpi *dpi,
> >  struct mtk_dpi_sync_param *sync)
> >  {
> > -   mtk_dpi_mask(dpi, DPI_TGEN_HWIDTH,
> > -sync->sync_width << HPW, HPW_MASK);
> > -   mtk_dpi_mask(dpi, DPI_TGEN_HPORCH,
> > -sync->back_porch << HBP, HBP_MASK);
> > -   mtk_dpi_mask(dpi, DPI_TGEN_HPORCH, sync->front_porch << HFP,
> > -HFP_MASK);
> > +   if (dpi->conf->is_dpintf) {
> > +   mtk_dpi_mask(dpi, DPI_TGEN_HWIDTH,
> > +sync->sync_width << HPW, DPINTF_HPW_MASK);
> > +   mtk_dpi_mask(dpi, DPI_TGEN_HPORCH,
> > +sync->back_porch << HBP, DPINTF_HBP_MASK);
> > +   mtk_dpi_mask(dpi, DPI_TGEN_HPORCH, sync->front_porch << HFP,
> > +DPINTF_HFP_MASK);
> 
> define dpi->conf->hpw_mask
> define dpi->conf->hbp_mask
> define dpi->conf->hfp_mask

Thanks, I defined a dpi->conf->dimension_mask instead which I now use
for HWIDTH/HPORCH as well as VSYNC_WIDTH and VSYNC_PORCH as the only
difference is the width of the masks, not their positions. Hope that's
fine.

> 
> > +   } else {
> > +   mtk_dpi_mask(dpi, DPI_TGEN_HWIDTH,
> > +sync->sync_width << HPW, HPW_MASK);
> > +   mtk_dpi_mask(dpi, DPI_TGEN_HPORCH,
> > +sync->back_porch << HBP, HBP_MASK);
> > +   mtk_dpi_mask(dpi, DPI_TGEN_HPORCH, sync->front_porch << HFP,
> > +HFP_MASK);
> > +   }
> >  }
> >
> >  stat

Re: [PATCH v4 2/7] dt-bindings: mediatek, dp: Add Display Port binding

2021-10-18 Thread Markus Schneider-Pargmann
Hi Rob,

On Mon, Oct 11, 2021 at 07:43:16PM -0500, Rob Herring wrote:
> On Mon, Oct 11, 2021 at 11:46:19AM +0200, Markus Schneider-Pargmann wrote:
> > This controller is present on several mediatek hardware. Currently
> > mt8195 and mt8395 have this controller without a functional difference,
> > so only one compatible field is added.
> > 
> > The controller can have two forms, as a normal display port and as an
> > embedded display port.
> > 
> > Signed-off-by: Markus Schneider-Pargmann 
> > ---
> >  .../display/mediatek/mediatek,dp.yaml | 89 +++
> >  1 file changed, 89 insertions(+)
> >  create mode 100644 
> > Documentation/devicetree/bindings/display/mediatek/mediatek,dp.yaml
> > 
> > diff --git 
> > a/Documentation/devicetree/bindings/display/mediatek/mediatek,dp.yaml 
> > b/Documentation/devicetree/bindings/display/mediatek/mediatek,dp.yaml
> > new file mode 100644
> > index ..f7a35962c23b
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,dp.yaml
> > @@ -0,0 +1,89 @@
> > +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> > +%YAML 1.2
> > +---
> > +$id: http://devicetree.org/schemas/display/mediatek/mediatek,dp.yaml#
> > +$schema: http://devicetree.org/meta-schemas/core.yaml#
> > +
> > +title: Mediatek Display Port Controller
> > +
> > +maintainers:
> > +  - CK Hu 
> > +  - Jitao shi 
> > +
> > +description: |
> > +  Device tree bindings for the Mediatek (embedded) Display Port controller
> > +  present on some Mediatek SoCs.
> > +
> > +properties:
> > +  compatible:
> > +enum:
> > +  - mediatek,mt8195-edp_tx
> > +  - mediatek,mt8195-dp_tx
> 
> Are these blocks different?

Good point, the registers of these blocks are described in its own
chapter each. Also I do need to distinguish between both in the driver.
Would you suggest making this distinction differently or keep it as two
compatibles?

> 
> > +
> > +  reg:
> > +maxItems: 1
> > +
> > +  interrupts:
> > +maxItems: 1
> > +
> > +  clocks:
> > +items:
> > +  - description: faxi clock
> > +
> > +  clock-names:
> > +items:
> > +  - const: faxi
> > +
> > +  power-domains:
> > +maxItems: 1
> > +
> > +  ports:
> > +$ref: /schemas/graph.yaml#/properties/ports
> > +properties:
> > +  port@0:
> > +$ref: /schemas/graph.yaml#/properties/port
> > +description: Input endpoint of the controller, usually dp_intf
> > +
> > +  port@1:
> > +$ref: /schemas/graph.yaml#/properties/port
> > +description: Output endpoint of the controller
> > +
> > +required:
> > +  - compatible
> > +  - reg
> > +  - interrupts
> > +  - ports
> > +
> > +additionalProperties: false
> > +
> > +examples:
> > +  - |
> > +#include 
> > +#include 
> > +dp_tx: edp_tx@1c50 {
> > +compatible = "mediatek,mt8195-edp_tx";
> > +reg = <0 0x1c50 0 0x8000>;
> > +interrupts = ;
> > +power-domains = < MT8195_POWER_DOMAIN_EPD_TX>;
> > +pinctrl-names = "default";
> > +pinctrl-0 = <_pin>;
> > +status = "okay";
> 
> Don't show status in examples.

Fixed.

Thank you Rob.

Best,
Markus

> 
> > +
> > +ports {
> > +#address-cells = <1>;
> > +#size-cells = <0>;
> > +
> > +port@0 {
> > +reg = <0>;
> > +edp_in: endpoint {
> > +remote-endpoint = <_intf0_out>;
> > +};
> > +};
> > +port@1 {
> > +reg = <1>;
> > +edp_out: endpoint {
> > +   remote-endpoint = <_in>;
> > +};
> > +};
> > +};
> > +};
> > -- 
> > 2.33.0
> > 
> > 


Re: [PATCH v4 2/7] dt-bindings: mediatek, dp: Add Display Port binding

2021-10-11 Thread Markus Schneider-Pargmann
Hi,

On Mon, Oct 11, 2021 at 08:36:18AM -0500, Rob Herring wrote:
> On Mon, 11 Oct 2021 11:46:19 +0200, Markus Schneider-Pargmann wrote:
> > This controller is present on several mediatek hardware. Currently
> > mt8195 and mt8395 have this controller without a functional difference,
> > so only one compatible field is added.
> > 
> > The controller can have two forms, as a normal display port and as an
> > embedded display port.
> > 
> > Signed-off-by: Markus Schneider-Pargmann 
> > ---
> >  .../display/mediatek/mediatek,dp.yaml | 89 +++
> >  1 file changed, 89 insertions(+)
> >  create mode 100644 
> > Documentation/devicetree/bindings/display/mediatek/mediatek,dp.yaml
> > 
> 
> My bot found errors running 'make DT_CHECKER_FLAGS=-m dt_binding_check'
> on your patch (DT_CHECKER_FLAGS is new in v5.13):
> 
> yamllint warnings/errors:
> 
> dtschema/dtc warnings/errors:
> Documentation/devicetree/bindings/display/mediatek/mediatek,dp.example.dts:20:18:
>  fatal error: dt-bindings/power/mt8195-power.h: No such file or directory
>20 | #include 
>   |  ^~
> compilation terminated.
> make[1]: *** [scripts/Makefile.lib:385: 
> Documentation/devicetree/bindings/display/mediatek/mediatek,dp.example.dt.yaml]
>  Error 1
> make[1]: *** Waiting for unfinished jobs
> make: *** [Makefile:1441: dt_binding_check] Error 2

Yes, mt8195-power.h is unfortunately not merged yet.

Thanks,
Markus

> 
> doc reference errors (make refcheckdocs):
> 
> See https://patchwork.ozlabs.org/patch/1539195
> 
> This check can fail if there are any dependencies. The base for a patch
> series is generally the most recent rc1.
> 
> If you already ran 'make dt_binding_check' and didn't see the above
> error(s), then make sure 'yamllint' is installed and dt-schema is up to
> date:
> 
> pip3 install dtschema --upgrade
> 
> Please check and re-submit.
> 


Re: [PATCH v4 1/7] dt-bindings: mediatek,dpintf: Add DP_INTF binding

2021-10-11 Thread Markus Schneider-Pargmann
Hi,

On Mon, Oct 11, 2021 at 08:36:18AM -0500, Rob Herring wrote:
> On Mon, 11 Oct 2021 11:46:18 +0200, Markus Schneider-Pargmann wrote:
> > DP_INTF is a similar functional block to mediatek,dpi but is different
> > in that it serves the DisplayPort controller on mediatek SoCs and uses
> > different clocks. Therefore this patch creates a new binding file for
> > this functional block.
> > 
> > Signed-off-by: Markus Schneider-Pargmann 
> > ---
> > 
> > Notes:
> > Changes v3 -> v4:
> > - Fixed clock names in the example as the clock patch series is merged 
> > into
> >   next now
> > - Add missing ports decleration to the example
> > 
> > Changes v1 -> v2:
> > - Move the devicetree binding from mediatek,dpi into its own binding 
> > file.
> > 
> >  .../display/mediatek/mediatek,dpintf.yaml | 86 +++
> >  1 file changed, 86 insertions(+)
> >  create mode 100644 
> > Documentation/devicetree/bindings/display/mediatek/mediatek,dpintf.yaml
> > 
> 
> My bot found errors running 'make DT_CHECKER_FLAGS=-m dt_binding_check'
> on your patch (DT_CHECKER_FLAGS is new in v5.13):
> 
> yamllint warnings/errors:
> 
> dtschema/dtc warnings/errors:
> Documentation/devicetree/bindings/display/mediatek/mediatek,dpintf.example.dts:21:18:
>  fatal error: dt-bindings/clock/mt8195-clk.h: No such file or directory
>21 | #include 
>   |  ^~~~

The mt8195 clock series was already merged and is available in
linux-next. I checked with make dt_binding_check before sending.

Thanks,
Markus

> compilation terminated.
> make[1]: *** [scripts/Makefile.lib:385: 
> Documentation/devicetree/bindings/display/mediatek/mediatek,dpintf.example.dt.yaml]
>  Error 1
> make[1]: *** Waiting for unfinished jobs
> make: *** [Makefile:1441: dt_binding_check] Error 2
> 
> doc reference errors (make refcheckdocs):
> 
> See https://patchwork.ozlabs.org/patch/1539196
> 
> This check can fail if there are any dependencies. The base for a patch
> series is generally the most recent rc1.
> 
> If you already ran 'make dt_binding_check' and didn't see the above
> error(s), then make sure 'yamllint' is installed and dt-schema is up to
> date:
> 
> pip3 install dtschema --upgrade
> 
> Please check and re-submit.
> 


[PATCH v4 0/7] drm/mediatek: Add mt8195 DisplayPort driver

2021-10-11 Thread Markus Schneider-Pargmann
Hi everyone,

this series is built around the DisplayPort driver. The dpi/dpintf
driver and the added helper functions are required for the DisplayPort
driver to work.

In v4 I split the phy driver and dp driver into two patches as
requested. Also I added an entry for phy-mtk-dp in MAINTAINERS and made
tiny fixups to the binding files.

The series is based on v5.15-rc1 but also applies cleanly on linux-next.
Note: This patch series is currently tested on v5.10 and I am still
working on testing it on v5.15.

Thanks in advance for any feedback and comments.

Best,
Markus


Functional dependencies are:
- Add Mediatek Soc DRM (vdosys0) support for mt8195
  
https://lore.kernel.org/linux-mediatek/20210921155218.10387-1-jason-jh@mediatek.com/
- Add MediaTek SoC DRM (vdosys1) support for mt8195
  
https://lore.kernel.org/linux-mediatek/20211004062140.29803-1-nancy@mediatek.com/

Older revisions:
RFC - 
https://lore.kernel.org/linux-mediatek/20210816192523.1739365-1-...@baylibre.com/
v1  - 
https://lore.kernel.org/linux-mediatek/20210906193529.718845-1-...@baylibre.com/
v2  - 
https://lore.kernel.org/linux-mediatek/20210920084424.231825-1-...@baylibre.com/
v3  - 
https://lore.kernel.org/linux-mediatek/20211001094443.2770169-1-...@baylibre.com/


Markus Schneider-Pargmann (7):
  dt-bindings: mediatek,dpintf: Add DP_INTF binding
  dt-bindings: mediatek,dp: Add Display Port binding
  drm/edid: Add cea_sad helpers for freq/length
  video/hdmi: Add audio_infoframe packing for DP
  drm/mediatek: dpi: Add dpintf support
  phy: phy-mtk-dp: Add driver for DP phy
  drm/mediatek: Add mt8195 DisplayPort driver


 .../display/mediatek/mediatek,dp.yaml |   89 +
 .../display/mediatek/mediatek,dpintf.yaml |   86 +
 MAINTAINERS   |1 +
 drivers/gpu/drm/drm_edid.c|   74 +
 drivers/gpu/drm/mediatek/Kconfig  |7 +
 drivers/gpu/drm/mediatek/Makefile |2 +
 drivers/gpu/drm/mediatek/mtk_dp.c | 2825 +
 drivers/gpu/drm/mediatek/mtk_dp_reg.h |  535 
 drivers/gpu/drm/mediatek/mtk_dpi.c|  248 +-
 drivers/gpu/drm/mediatek/mtk_dpi_regs.h   |   12 +
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c   |4 +
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h   |1 +
 drivers/gpu/drm/mediatek/mtk_drm_drv.c|6 +-
 drivers/gpu/drm/mediatek/mtk_drm_drv.h|1 +
 drivers/phy/mediatek/Kconfig  |8 +
 drivers/phy/mediatek/Makefile |1 +
 drivers/phy/mediatek/phy-mtk-dp.c |  218 ++
 drivers/video/hdmi.c  |   83 +-
 include/drm/drm_dp_helper.h   |2 +
 include/drm/drm_edid.h|   18 +-
 include/linux/hdmi.h  |7 +-
 include/linux/soc/mediatek/mtk-mmsys.h|2 +
 22 files changed, 4156 insertions(+), 74 deletions(-)
 create mode 100644 
Documentation/devicetree/bindings/display/mediatek/mediatek,dp.yaml
 create mode 100644 
Documentation/devicetree/bindings/display/mediatek/mediatek,dpintf.yaml
 create mode 100644 drivers/gpu/drm/mediatek/mtk_dp.c
 create mode 100644 drivers/gpu/drm/mediatek/mtk_dp_reg.h
 create mode 100644 drivers/phy/mediatek/phy-mtk-dp.c

-- 
2.33.0



[PATCH v4 7/7] drm/mediatek: Add mt8195 DisplayPort driver

2021-10-11 Thread Markus Schneider-Pargmann
This patch adds a DisplayPort driver for the Mediatek mt8195 SoC and a
according phy driver mediatek-dp-phy.

It supports both functional units on the mt8195, the embedded
DisplayPort as well as the external DisplayPort units. It offers
hot-plug-detection, audio up to 8 channels, and DisplayPort 1.4 with up
to 4 lanes.

The driver creates a child device for the phy. The child device will
never exist without the parent being active. As they are sharing a
register range, the parent passes a regmap pointer to the child so that
both can work with the same register range. The phy driver sets device
data that is read by the parent to get the phy device that can be used
to control the phy properties.

This driver is based on an initial version by
Jason-JH.Lin .

Signed-off-by: Markus Schneider-Pargmann 
---

Notes:
Changes v2 -> v3:
- Solve TODOs and add defines for undescribed registers
- Remove TODOs that were irrelevant

Changes v1 -> v2:
- Fix checkpatch --strict suggestions
- General cleanups of the code.
- Remove all remaining non-atomic functions.
- Remove unused includes and sort them.
- Remove unused select GENERIC_PHY
- Rename phy registers DP_PHY -> MTK_DP_PHY
- Replace usage of delays with usleep_range.
- Split the phy register accesses into a separate phy driver.
- Use a lock to guard access to mtk_dp->edid as it can be 
allocated/used/freed
  in different threads
- use struct dp_sdp for sdp packets.

Changes RFC -> v1:
- Removed unused register definitions.
- Replaced workqueue with threaded irq.
- Removed connector code.
- Move to atomic_* drm functions.
- General cleanups of the code.
- Remove unused select GENERIC_PHY.

 drivers/gpu/drm/mediatek/Kconfig   |7 +
 drivers/gpu/drm/mediatek/Makefile  |2 +
 drivers/gpu/drm/mediatek/mtk_dp.c  | 2825 
 drivers/gpu/drm/mediatek/mtk_dp_reg.h  |  535 +
 drivers/gpu/drm/mediatek/mtk_drm_drv.c |1 +
 drivers/gpu/drm/mediatek/mtk_drm_drv.h |1 +
 6 files changed, 3371 insertions(+)
 create mode 100644 drivers/gpu/drm/mediatek/mtk_dp.c
 create mode 100644 drivers/gpu/drm/mediatek/mtk_dp_reg.h

diff --git a/drivers/gpu/drm/mediatek/Kconfig b/drivers/gpu/drm/mediatek/Kconfig
index 2976d21e9a34..029b94c71613 100644
--- a/drivers/gpu/drm/mediatek/Kconfig
+++ b/drivers/gpu/drm/mediatek/Kconfig
@@ -28,3 +28,10 @@ config DRM_MEDIATEK_HDMI
select PHY_MTK_HDMI
help
  DRM/KMS HDMI driver for Mediatek SoCs
+
+config MTK_DPTX_SUPPORT
+   tristate "DRM DPTX Support for Mediatek SoCs"
+   depends on DRM_MEDIATEK
+   select PHY_MTK_DP
+   help
+ DRM/KMS Display Port driver for Mediatek SoCs.
diff --git a/drivers/gpu/drm/mediatek/Makefile 
b/drivers/gpu/drm/mediatek/Makefile
index 29098d7c8307..d86a6406055e 100644
--- a/drivers/gpu/drm/mediatek/Makefile
+++ b/drivers/gpu/drm/mediatek/Makefile
@@ -21,3 +21,5 @@ mediatek-drm-hdmi-objs := mtk_cec.o \
  mtk_hdmi_ddc.o
 
 obj-$(CONFIG_DRM_MEDIATEK_HDMI) += mediatek-drm-hdmi.o
+
+obj-$(CONFIG_MTK_DPTX_SUPPORT) += mtk_dp.o
diff --git a/drivers/gpu/drm/mediatek/mtk_dp.c 
b/drivers/gpu/drm/mediatek/mtk_dp.c
new file mode 100644
index ..8a5d03b8c5ff
--- /dev/null
+++ b/drivers/gpu/drm/mediatek/mtk_dp.c
@@ -0,0 +1,2825 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2019 MediaTek Inc.
+ * Copyright (c) 2021 BayLibre
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "mtk_dp_reg.h"
+
+#define MTK_DP_AUX_WAIT_REPLY_COUNT2
+#define MTK_DP_CHECK_SINK_CAP_TIMEOUT_COUNT3
+
+#define MTK_DP_MAX_LANES   4
+#define MTK_DP_MAX_LINK_RATE   MTK_DP_LINKRATE_HBR3
+
+#define MTK_DP_TBC_BUF_READ_START_ADDR 0x08
+
+#define MTK_DP_TRAIN_RETRY_LIMIT   8
+#define MTK_DP_TRAIN_MAX_ITERATIONS5
+
+#define MTK_DP_AUX_WRITE_READ_WAIT_TIME_US 20
+
+#define MTK_DP_DP_VERSION_11   0x11
+
+enum mtk_dp_state {
+   MTK_DP_STATE_INITIAL,
+   MTK_DP_STATE_IDLE,
+   MTK_DP_STATE_PREPARE,
+   MTK_DP_STATE_NORMAL,
+};
+
+enum mtk_dp_train_state {
+   MTK_DP_TRAIN_STATE_STARTUP = 0,
+   MTK_DP_TRAIN_STATE_CHECKCAP,
+   MTK_DP_TRAIN_STATE_CHECKEDID,
+   MTK_DP_TRAIN_STATE_TRAINING_PRE,
+   MTK_DP_TRAIN_STATE_TRAINING,
+   MTK_DP_TRAIN_STATE_CHECKTIMING,
+   MTK_DP_TRAIN_STATE_NORMAL,
+   MTK_DP_TRAIN_STATE_POWERSAVE,
+   MTK_DP_TRAIN_STATE_DPIDLE,
+};
+
+struct mtk_dp_timings {
+   struct videomode vm;
+
+   u16 htotal;
+   u16 vtotal;
+   u8 frame_rate;
+   u32 pix_rate_khz;
+};
+
+struct mt

[PATCH v4 6/7] phy: phy-mtk-dp: Add driver for DP phy

2021-10-11 Thread Markus Schneider-Pargmann
This is a new driver that supports the integrated DisplayPort phy for
mediatek SoCs, especially the mt8195. The phy is integrated into the
DisplayPort controller and will be created by the mtk-dp driver. This
driver expects a struct regmap to be able to work on the same registers
as the DisplayPort controller. It sets the device data to be the struct
phy so that the DisplayPort controller can easily work with it.

The driver does not have any devicetree bindings because the datasheet
does not list the controller and the phy as distinct units.

The interaction with the controller can be covered by the configure
callback of the phy framework and its displayport parameters.

Signed-off-by: Markus Schneider-Pargmann 
---

Notes:
Changes v3 -> v4:
- Split DP controller driver and phy driver into separate patches.
- Add entry to MAINTAINERS for this phy driver

 MAINTAINERS   |   1 +
 drivers/phy/mediatek/Kconfig  |   8 ++
 drivers/phy/mediatek/Makefile |   1 +
 drivers/phy/mediatek/phy-mtk-dp.c | 218 ++
 4 files changed, 228 insertions(+)
 create mode 100644 drivers/phy/mediatek/phy-mtk-dp.c

diff --git a/MAINTAINERS b/MAINTAINERS
index eeb4c70b3d5b..8a47eb628734 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -6276,6 +6276,7 @@ L:linux-media...@lists.infradead.org (moderated 
for non-subscribers)
 S: Supported
 F: Documentation/devicetree/bindings/display/mediatek/
 F: drivers/gpu/drm/mediatek/
+F: drivers/phy/mediatek/phy-mtk-dp.c
 F: drivers/phy/mediatek/phy-mtk-hdmi*
 F: drivers/phy/mediatek/phy-mtk-mipi*
 
diff --git a/drivers/phy/mediatek/Kconfig b/drivers/phy/mediatek/Kconfig
index 55f8e6c048ab..f7ec86059049 100644
--- a/drivers/phy/mediatek/Kconfig
+++ b/drivers/phy/mediatek/Kconfig
@@ -55,3 +55,11 @@ config PHY_MTK_MIPI_DSI
select GENERIC_PHY
help
  Support MIPI DSI for Mediatek SoCs.
+
+config PHY_MTK_DP
+   tristate "MediaTek DP-PHY Driver"
+   depends on ARCH_MEDIATEK || COMPILE_TEST
+   depends on OF
+   select GENERIC_PHY
+   help
+ Support DisplayPort PHY for Mediatek SoCs.
diff --git a/drivers/phy/mediatek/Makefile b/drivers/phy/mediatek/Makefile
index ace660fbed3a..4ba1e0650434 100644
--- a/drivers/phy/mediatek/Makefile
+++ b/drivers/phy/mediatek/Makefile
@@ -3,6 +3,7 @@
 # Makefile for the phy drivers.
 #
 
+obj-$(CONFIG_PHY_MTK_DP)   += phy-mtk-dp.o
 obj-$(CONFIG_PHY_MTK_TPHY) += phy-mtk-tphy.o
 obj-$(CONFIG_PHY_MTK_UFS)  += phy-mtk-ufs.o
 obj-$(CONFIG_PHY_MTK_XSPHY)+= phy-mtk-xsphy.o
diff --git a/drivers/phy/mediatek/phy-mtk-dp.c 
b/drivers/phy/mediatek/phy-mtk-dp.c
new file mode 100644
index ..7a1141715ea2
--- /dev/null
+++ b/drivers/phy/mediatek/phy-mtk-dp.c
@@ -0,0 +1,218 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2021 BayLibre
+ * Author: Markus Schneider-Pargmann 
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define PHY_OFFSET 0x1000
+
+#define MTK_DP_PHY_DIG_PLL_CTL_1   (PHY_OFFSET + 0x014)
+# define TPLL_SSC_EN   BIT(3)
+
+#define MTK_DP_PHY_DIG_BIT_RATE(PHY_OFFSET + 0x03C)
+# define BIT_RATE_RBR  0
+# define BIT_RATE_HBR  1
+# define BIT_RATE_HBR2 2
+# define BIT_RATE_HBR3 3
+
+#define MTK_DP_PHY_DIG_SW_RST  (PHY_OFFSET + 0x038)
+# define DP_GLB_SW_RST_PHYDBIT(0)
+
+#define MTK_DP_LANE0_DRIVING_PARAM_3   (PHY_OFFSET + 0x138)
+#define MTK_DP_LANE1_DRIVING_PARAM_3   (PHY_OFFSET + 0x238)
+#define MTK_DP_LANE2_DRIVING_PARAM_3   (PHY_OFFSET + 0x338)
+#define MTK_DP_LANE3_DRIVING_PARAM_3   (PHY_OFFSET + 0x438)
+# define XTP_LN_TX_LCTXC0_SW0_PRE0_DEFAULT 0x10
+# define XTP_LN_TX_LCTXC0_SW0_PRE1_DEFAULT (0x14 << 8)
+# define XTP_LN_TX_LCTXC0_SW0_PRE2_DEFAULT (0x18 << 16)
+# define XTP_LN_TX_LCTXC0_SW0_PRE3_DEFAULT (0x20 << 24)
+# define DRIVING_PARAM_3_DEFAULT   
(XTP_LN_TX_LCTXC0_SW0_PRE0_DEFAULT | \
+
XTP_LN_TX_LCTXC0_SW0_PRE1_DEFAULT | \
+
XTP_LN_TX_LCTXC0_SW0_PRE2_DEFAULT | \
+
XTP_LN_TX_LCTXC0_SW0_PRE3_DEFAULT)
+
+#define MTK_DP_LANE0_DRIVING_PARAM_4   (PHY_OFFSET + 0x13C)
+#define MTK_DP_LANE1_DRIVING_PARAM_4   (PHY_OFFSET + 0x23C)
+#define MTK_DP_LANE2_DRIVING_PARAM_4   (PHY_OFFSET + 0x33C)
+#define MTK_DP_LANE3_DRIVING_PARAM_4   (PHY_OFFSET + 0x43C)
+# define XTP_LN_TX_LCTXC0_SW1_PRE0_DEFAULT 0x18
+# define XTP_LN_TX_LCTXC0_SW1_PRE1_DEFAULT (0x1e << 8)
+# define XTP_LN_TX_LCTXC0_SW1_PRE2_DEFAULT (0x24 << 16)
+# define XTP_LN_TX_LCTXC0_

[PATCH v4 5/7] drm/mediatek: dpi: Add dpintf support

2021-10-11 Thread Markus Schneider-Pargmann
dpintf is the displayport interface hardware unit. This unit is similar
to dpi and can reuse most of the code.

This patch adds support for mt8195-dpintf to this dpi driver. Main
differences are:
 - Some features/functional components are not available for dpintf
   which are now excluded from code execution once is_dpintf is set
 - dpintf can and needs to choose between different clockdividers based
   on the clockspeed. This is done by choosing a different clock parent.
 - There are two additional clocks that need to be managed. These are
   only set for dpintf and will be set to NULL if not supplied. The
   clk_* calls handle these as normal clocks then.
 - Some register contents differ slightly between the two components. To
   work around this I added register bits/masks with a DPINTF_ prefix
   and use them where different.

Based on a separate driver for dpintf created by
Jason-JH.Lin .

Signed-off-by: Markus Schneider-Pargmann 
---

Notes:
Changes RFC -> v1:
- Remove setting parents and fully rely on the clock tree instead which 
already
  models a mux at the important place.
- Integrated mtk_dpi dpintf changes into the mediatek drm driver.

 drivers/gpu/drm/mediatek/mtk_dpi.c  | 248 
 drivers/gpu/drm/mediatek/mtk_dpi_regs.h |  12 +
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c |   4 +
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h |   1 +
 drivers/gpu/drm/mediatek/mtk_drm_drv.c  |   5 +-
 include/linux/soc/mediatek/mtk-mmsys.h  |   2 +
 6 files changed, 220 insertions(+), 52 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c 
b/drivers/gpu/drm/mediatek/mtk_dpi.c
index 4554e2de1430..87961ebf5d35 100644
--- a/drivers/gpu/drm/mediatek/mtk_dpi.c
+++ b/drivers/gpu/drm/mediatek/mtk_dpi.c
@@ -71,6 +71,8 @@ struct mtk_dpi {
void __iomem *regs;
struct device *dev;
struct clk *engine_clk;
+   struct clk *hf_fmm_clk;
+   struct clk *hf_fdp_clk;
struct clk *pixel_clk;
struct clk *tvd_clk;
int irq;
@@ -125,6 +127,7 @@ struct mtk_dpi_conf {
bool edge_sel_en;
const u32 *output_fmts;
u32 num_output_fmts;
+   bool is_dpintf;
 };
 
 static void mtk_dpi_mask(struct mtk_dpi *dpi, u32 offset, u32 val, u32 mask)
@@ -153,30 +156,52 @@ static void mtk_dpi_disable(struct mtk_dpi *dpi)
 static void mtk_dpi_config_hsync(struct mtk_dpi *dpi,
 struct mtk_dpi_sync_param *sync)
 {
-   mtk_dpi_mask(dpi, DPI_TGEN_HWIDTH,
-sync->sync_width << HPW, HPW_MASK);
-   mtk_dpi_mask(dpi, DPI_TGEN_HPORCH,
-sync->back_porch << HBP, HBP_MASK);
-   mtk_dpi_mask(dpi, DPI_TGEN_HPORCH, sync->front_porch << HFP,
-HFP_MASK);
+   if (dpi->conf->is_dpintf) {
+   mtk_dpi_mask(dpi, DPI_TGEN_HWIDTH,
+sync->sync_width << HPW, DPINTF_HPW_MASK);
+   mtk_dpi_mask(dpi, DPI_TGEN_HPORCH,
+sync->back_porch << HBP, DPINTF_HBP_MASK);
+   mtk_dpi_mask(dpi, DPI_TGEN_HPORCH, sync->front_porch << HFP,
+DPINTF_HFP_MASK);
+   } else {
+   mtk_dpi_mask(dpi, DPI_TGEN_HWIDTH,
+sync->sync_width << HPW, HPW_MASK);
+   mtk_dpi_mask(dpi, DPI_TGEN_HPORCH,
+sync->back_porch << HBP, HBP_MASK);
+   mtk_dpi_mask(dpi, DPI_TGEN_HPORCH, sync->front_porch << HFP,
+HFP_MASK);
+   }
 }
 
 static void mtk_dpi_config_vsync(struct mtk_dpi *dpi,
 struct mtk_dpi_sync_param *sync,
 u32 width_addr, u32 porch_addr)
 {
-   mtk_dpi_mask(dpi, width_addr,
-sync->sync_width << VSYNC_WIDTH_SHIFT,
-VSYNC_WIDTH_MASK);
mtk_dpi_mask(dpi, width_addr,
 sync->shift_half_line << VSYNC_HALF_LINE_SHIFT,
 VSYNC_HALF_LINE_MASK);
-   mtk_dpi_mask(dpi, porch_addr,
-sync->back_porch << VSYNC_BACK_PORCH_SHIFT,
-VSYNC_BACK_PORCH_MASK);
-   mtk_dpi_mask(dpi, porch_addr,
-sync->front_porch << VSYNC_FRONT_PORCH_SHIFT,
-VSYNC_FRONT_PORCH_MASK);
+
+   if (dpi->conf->is_dpintf) {
+   mtk_dpi_mask(dpi, width_addr,
+sync->sync_width << VSYNC_WIDTH_SHIFT,
+DPINTF_VSYNC_WIDTH_MASK);
+   mtk_dpi_mask(dpi, porch_addr,
+sync->back_porch << VSYNC_BACK_PORCH_SHIFT,
+DPINTF_VSYNC_BACK_PORCH_MASK);
+   mtk_dpi_mask(dpi, porch_addr,
+sync->front_por

[PATCH v4 3/7] drm/edid: Add cea_sad helpers for freq/length

2021-10-11 Thread Markus Schneider-Pargmann
This patch adds two helper functions that extract the frequency and word
length from a struct cea_sad.

For these helper functions new defines are added that help translate the
'freq' and 'byte2' fields into real numbers.

Signed-off-by: Markus Schneider-Pargmann 
---

Notes:
Changes v2 -> v3:
- Add DRM_ prefix to the CEA_SAD defines.

Changes v1 -> v2:
- Use const struct pointers.
- Add a check whether the format is actually uncompressed or not.

 drivers/gpu/drm/drm_edid.c | 74 ++
 include/drm/drm_edid.h | 18 --
 2 files changed, 90 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index 6325877c5fd6..c134803e18db 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -4666,6 +4666,80 @@ int drm_edid_to_speaker_allocation(struct edid *edid, u8 
**sadb)
 }
 EXPORT_SYMBOL(drm_edid_to_speaker_allocation);
 
+/**
+ * drm_cea_sad_get_sample_rate - Extract the sample rate from cea_sad
+ * @sad: Pointer to the cea_sad struct
+ *
+ * Extracts the cea_sad frequency field and returns the sample rate in Hz.
+ *
+ * Return: Sample rate in Hz or a negative errno if parsing failed.
+ */
+int drm_cea_sad_get_sample_rate(const struct cea_sad *sad)
+{
+   switch (sad->freq) {
+   case DRM_CEA_SAD_FREQ_32KHZ:
+   return 32000;
+   case DRM_CEA_SAD_FREQ_44KHZ:
+   return 44100;
+   case DRM_CEA_SAD_FREQ_48KHZ:
+   return 48000;
+   case DRM_CEA_SAD_FREQ_88KHZ:
+   return 88200;
+   case DRM_CEA_SAD_FREQ_96KHZ:
+   return 96000;
+   case DRM_CEA_SAD_FREQ_176KHZ:
+   return 176400;
+   case DRM_CEA_SAD_FREQ_192KHZ:
+   return 192000;
+   default:
+   return -EINVAL;
+   }
+}
+EXPORT_SYMBOL(drm_cea_sad_get_sample_rate);
+
+static bool drm_cea_sad_is_uncompressed(const struct cea_sad *sad)
+{
+   switch (sad->format) {
+   case HDMI_AUDIO_CODING_TYPE_STREAM:
+   case HDMI_AUDIO_CODING_TYPE_PCM:
+   return true;
+   default:
+   return false;
+   }
+}
+
+/**
+ * drm_cea_sad_get_uncompressed_word_length - Extract word length
+ * @sad: Pointer to the cea_sad struct
+ *
+ * Extracts the cea_sad byte2 field and returns the word length for an
+ * uncompressed stream.
+ *
+ * Note: This function may only be called for uncompressed audio.
+ *
+ * Return: Word length in bits or a negative errno if parsing failed.
+ */
+int drm_cea_sad_get_uncompressed_word_length(const struct cea_sad *sad)
+{
+   if (!drm_cea_sad_is_uncompressed(sad)) {
+   DRM_WARN("Unable to get the uncompressed word length for a 
compressed format: %u\n",
+sad->format);
+   return -EINVAL;
+   }
+
+   switch (sad->byte2) {
+   case DRM_CEA_SAD_UNCOMPRESSED_WORD_16BIT:
+   return 16;
+   case DRM_CEA_SAD_UNCOMPRESSED_WORD_20BIT:
+   return 20;
+   case DRM_CEA_SAD_UNCOMPRESSED_WORD_24BIT:
+   return 24;
+   default:
+   return -EINVAL;
+   }
+}
+EXPORT_SYMBOL(drm_cea_sad_get_uncompressed_word_length);
+
 /**
  * drm_av_sync_delay - compute the HDMI/DP sink audio-video sync delay
  * @connector: connector associated with the HDMI/DP sink
diff --git a/include/drm/drm_edid.h b/include/drm/drm_edid.h
index deccfd39e6db..9d75df652b17 100644
--- a/include/drm/drm_edid.h
+++ b/include/drm/drm_edid.h
@@ -361,12 +361,24 @@ struct edid {
 
 /* Short Audio Descriptor */
 struct cea_sad {
-   u8 format;
+   u8 format; /* See HDMI_AUDIO_CODING_TYPE_* */
u8 channels; /* max number of channels - 1 */
-   u8 freq;
+   u8 freq; /* See CEA_SAD_FREQ_* */
u8 byte2; /* meaning depends on format */
 };
 
+#define DRM_CEA_SAD_FREQ_32KHZ  BIT(0)
+#define DRM_CEA_SAD_FREQ_44KHZ  BIT(1)
+#define DRM_CEA_SAD_FREQ_48KHZ  BIT(2)
+#define DRM_CEA_SAD_FREQ_88KHZ  BIT(3)
+#define DRM_CEA_SAD_FREQ_96KHZ  BIT(4)
+#define DRM_CEA_SAD_FREQ_176KHZ BIT(5)
+#define DRM_CEA_SAD_FREQ_192KHZ BIT(6)
+
+#define DRM_CEA_SAD_UNCOMPRESSED_WORD_16BIT BIT(0)
+#define DRM_CEA_SAD_UNCOMPRESSED_WORD_20BIT BIT(1)
+#define DRM_CEA_SAD_UNCOMPRESSED_WORD_24BIT BIT(2)
+
 struct drm_encoder;
 struct drm_connector;
 struct drm_connector_state;
@@ -374,6 +386,8 @@ struct drm_display_mode;
 
 int drm_edid_to_sad(struct edid *edid, struct cea_sad **sads);
 int drm_edid_to_speaker_allocation(struct edid *edid, u8 **sadb);
+int drm_cea_sad_get_sample_rate(const struct cea_sad *sad);
+int drm_cea_sad_get_uncompressed_word_length(const struct cea_sad *sad);
 int drm_av_sync_delay(struct drm_connector *connector,
  const struct drm_display_mode *mode);
 
-- 
2.33.0



[PATCH v4 4/7] video/hdmi: Add audio_infoframe packing for DP

2021-10-11 Thread Markus Schneider-Pargmann
Similar to HDMI, DP uses audio infoframes as well which are structured
very similar to the HDMI ones.

This patch adds a helper function to pack the HDMI audio infoframe for
DP, called hdmi_audio_infoframe_pack_for_dp().
hdmi_audio_infoframe_pack_only() is split into two parts. One of them
packs the payload only and can be used for HDMI and DP.

Signed-off-by: Markus Schneider-Pargmann 
---

Notes:
Changes v1 -> v2:
- Create a define for HB2.
- Use struct dp_sdp to pass data in a better way.

 drivers/video/hdmi.c| 83 -
 include/drm/drm_dp_helper.h |  2 +
 include/linux/hdmi.h|  7 +++-
 3 files changed, 72 insertions(+), 20 deletions(-)

diff --git a/drivers/video/hdmi.c b/drivers/video/hdmi.c
index 947be761dfa4..63e74d9fd210 100644
--- a/drivers/video/hdmi.c
+++ b/drivers/video/hdmi.c
@@ -21,6 +21,7 @@
  * DEALINGS IN THE SOFTWARE.
  */
 
+#include 
 #include 
 #include 
 #include 
@@ -381,12 +382,34 @@ static int hdmi_audio_infoframe_check_only(const struct 
hdmi_audio_infoframe *fr
  *
  * Returns 0 on success or a negative error code on failure.
  */
-int hdmi_audio_infoframe_check(struct hdmi_audio_infoframe *frame)
+int hdmi_audio_infoframe_check(const struct hdmi_audio_infoframe *frame)
 {
return hdmi_audio_infoframe_check_only(frame);
 }
 EXPORT_SYMBOL(hdmi_audio_infoframe_check);
 
+static void
+hdmi_audio_infoframe_pack_payload(const struct hdmi_audio_infoframe *frame,
+ u8 *buffer)
+{
+   u8 channels;
+
+   if (frame->channels >= 2)
+   channels = frame->channels - 1;
+   else
+   channels = 0;
+
+   buffer[0] = ((frame->coding_type & 0xf) << 4) | (channels & 0x7);
+   buffer[1] = ((frame->sample_frequency & 0x7) << 2) |
+(frame->sample_size & 0x3);
+   buffer[2] = frame->coding_type_ext & 0x1f;
+   buffer[3] = frame->channel_allocation;
+   buffer[4] = (frame->level_shift_value & 0xf) << 3;
+
+   if (frame->downmix_inhibit)
+   buffer[4] |= BIT(7);
+}
+
 /**
  * hdmi_audio_infoframe_pack_only() - write HDMI audio infoframe to binary 
buffer
  * @frame: HDMI audio infoframe
@@ -404,7 +427,6 @@ EXPORT_SYMBOL(hdmi_audio_infoframe_check);
 ssize_t hdmi_audio_infoframe_pack_only(const struct hdmi_audio_infoframe 
*frame,
   void *buffer, size_t size)
 {
-   unsigned char channels;
u8 *ptr = buffer;
size_t length;
int ret;
@@ -420,28 +442,13 @@ ssize_t hdmi_audio_infoframe_pack_only(const struct 
hdmi_audio_infoframe *frame,
 
memset(buffer, 0, size);
 
-   if (frame->channels >= 2)
-   channels = frame->channels - 1;
-   else
-   channels = 0;
-
ptr[0] = frame->type;
ptr[1] = frame->version;
ptr[2] = frame->length;
ptr[3] = 0; /* checksum */
 
-   /* start infoframe payload */
-   ptr += HDMI_INFOFRAME_HEADER_SIZE;
-
-   ptr[0] = ((frame->coding_type & 0xf) << 4) | (channels & 0x7);
-   ptr[1] = ((frame->sample_frequency & 0x7) << 2) |
-(frame->sample_size & 0x3);
-   ptr[2] = frame->coding_type_ext & 0x1f;
-   ptr[3] = frame->channel_allocation;
-   ptr[4] = (frame->level_shift_value & 0xf) << 3;
-
-   if (frame->downmix_inhibit)
-   ptr[4] |= BIT(7);
+   hdmi_audio_infoframe_pack_payload(frame,
+ ptr + HDMI_INFOFRAME_HEADER_SIZE);
 
hdmi_infoframe_set_checksum(buffer, length);
 
@@ -479,6 +486,44 @@ ssize_t hdmi_audio_infoframe_pack(struct 
hdmi_audio_infoframe *frame,
 }
 EXPORT_SYMBOL(hdmi_audio_infoframe_pack);
 
+/**
+ * hdmi_audio_infoframe_pack_for_dp - Pack a HDMI Audio infoframe for
+ *displayport
+ *
+ * @frame HDMI Audio infoframe
+ * @sdp secondary data packet for display port. This is filled with the
+ * appropriate data
+ * @dp_version Display Port version to be encoded in the header
+ *
+ * Packs a HDMI Audio Infoframe to be sent over Display Port. This function
+ * fills the secondary data packet to be used for Display Port.
+ *
+ * Return: Number of total written bytes or a negative errno on failure.
+ */
+ssize_t
+hdmi_audio_infoframe_pack_for_dp(const struct hdmi_audio_infoframe *frame,
+struct dp_sdp *sdp, u8 dp_version)
+{
+   int ret;
+
+   ret = hdmi_audio_infoframe_check(frame);
+   if (ret)
+   return ret;
+
+   memset(sdp->db, 0, sizeof(sdp->db));
+
+   // Secondary-data packet header
+   sdp->sdp_header.HB0 = 0;
+   sdp->sdp_header.HB1 = frame->type;
+   sdp->sdp_header.HB2 = DP_SDP_AUDIO_INFOFRAME_HB2;
+   sdp->sdp_header.HB

[PATCH v4 2/7] dt-bindings: mediatek,dp: Add Display Port binding

2021-10-11 Thread Markus Schneider-Pargmann
This controller is present on several mediatek hardware. Currently
mt8195 and mt8395 have this controller without a functional difference,
so only one compatible field is added.

The controller can have two forms, as a normal display port and as an
embedded display port.

Signed-off-by: Markus Schneider-Pargmann 
---
 .../display/mediatek/mediatek,dp.yaml | 89 +++
 1 file changed, 89 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/display/mediatek/mediatek,dp.yaml

diff --git 
a/Documentation/devicetree/bindings/display/mediatek/mediatek,dp.yaml 
b/Documentation/devicetree/bindings/display/mediatek/mediatek,dp.yaml
new file mode 100644
index ..f7a35962c23b
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,dp.yaml
@@ -0,0 +1,89 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/mediatek/mediatek,dp.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Mediatek Display Port Controller
+
+maintainers:
+  - CK Hu 
+  - Jitao shi 
+
+description: |
+  Device tree bindings for the Mediatek (embedded) Display Port controller
+  present on some Mediatek SoCs.
+
+properties:
+  compatible:
+enum:
+  - mediatek,mt8195-edp_tx
+  - mediatek,mt8195-dp_tx
+
+  reg:
+maxItems: 1
+
+  interrupts:
+maxItems: 1
+
+  clocks:
+items:
+  - description: faxi clock
+
+  clock-names:
+items:
+  - const: faxi
+
+  power-domains:
+maxItems: 1
+
+  ports:
+$ref: /schemas/graph.yaml#/properties/ports
+properties:
+  port@0:
+$ref: /schemas/graph.yaml#/properties/port
+description: Input endpoint of the controller, usually dp_intf
+
+  port@1:
+$ref: /schemas/graph.yaml#/properties/port
+description: Output endpoint of the controller
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - ports
+
+additionalProperties: false
+
+examples:
+  - |
+#include 
+#include 
+dp_tx: edp_tx@1c50 {
+compatible = "mediatek,mt8195-edp_tx";
+reg = <0 0x1c50 0 0x8000>;
+interrupts = ;
+power-domains = < MT8195_POWER_DOMAIN_EPD_TX>;
+pinctrl-names = "default";
+pinctrl-0 = <_pin>;
+status = "okay";
+
+ports {
+#address-cells = <1>;
+#size-cells = <0>;
+
+port@0 {
+reg = <0>;
+edp_in: endpoint {
+remote-endpoint = <_intf0_out>;
+};
+};
+port@1 {
+reg = <1>;
+edp_out: endpoint {
+   remote-endpoint = <_in>;
+};
+};
+};
+};
-- 
2.33.0



[PATCH v4 1/7] dt-bindings: mediatek,dpintf: Add DP_INTF binding

2021-10-11 Thread Markus Schneider-Pargmann
DP_INTF is a similar functional block to mediatek,dpi but is different
in that it serves the DisplayPort controller on mediatek SoCs and uses
different clocks. Therefore this patch creates a new binding file for
this functional block.

Signed-off-by: Markus Schneider-Pargmann 
---

Notes:
Changes v3 -> v4:
- Fixed clock names in the example as the clock patch series is merged into
  next now
- Add missing ports decleration to the example

Changes v1 -> v2:
- Move the devicetree binding from mediatek,dpi into its own binding file.

 .../display/mediatek/mediatek,dpintf.yaml | 86 +++
 1 file changed, 86 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/display/mediatek/mediatek,dpintf.yaml

diff --git 
a/Documentation/devicetree/bindings/display/mediatek/mediatek,dpintf.yaml 
b/Documentation/devicetree/bindings/display/mediatek/mediatek,dpintf.yaml
new file mode 100644
index ..3b5e0c148c97
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,dpintf.yaml
@@ -0,0 +1,86 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/mediatek/mediatek,dpintf.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Mediatek DP_INTF Controller Device Tree Bindings
+
+maintainers:
+  - CK Hu 
+  - Jitao shi 
+
+description: |
+  The Mediatek DP_INTF function block is a sink of the display subsystem
+  connected to the display port controller.
+
+properties:
+  compatible:
+enum:
+  - mediatek,mt8195-dpintf
+
+  reg:
+maxItems: 1
+
+  interrupts:
+maxItems: 1
+
+  clocks:
+items:
+  - description: hf_fmm Clock
+  - description: hf_fdp Clock
+  - description: Pixel Clock
+  - description: DP_INTF PLL
+
+  clock-names:
+items:
+  - const: hf_fmm
+  - const: hf_fdp
+  - const: pixel
+  - const: pll
+
+  port:
+$ref: /schemas/graph.yaml#/properties/port
+description:
+  Output port node. This port should be connected to the input port of an
+  attached display port controller.
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - clocks
+  - clock-names
+  - port
+
+additionalProperties: false
+
+examples:
+  - |
+#include 
+#include 
+#include 
+
+dp_intf1: dp_intf1@1c113000 {
+compatible = "mediatek,mt8195-dpintf";
+reg = <0 0x1c113000 0 0x1000>;
+interrupts = ;
+clocks = < CLK_VDO1_DP_INTF0_MM>,
+ < CLK_VDO1_DPINTF>,
+ < CLK_TOP_DP>,
+ < CLK_APMIXED_TVDPLL2>;
+clock-names = "hf_fmm",
+  "hf_fdp",
+  "pixel",
+  "pll";
+
+ports {
+port {
+dpintf1_out: endpoint {
+remote-endpoint = <_in>;
+};
+};
+};
+};
+
+...
-- 
2.33.0



Re: [PATCH v3 6/6] drm/mediatek: Add mt8195 DisplayPort driver

2021-10-05 Thread Markus Schneider-Pargmann
Hi Chun-Kuang,

On Sat, Oct 02, 2021 at 12:16:26AM +0800, Chun-Kuang Hu wrote:
> Hi, Markus:
> [...]
> >
> >  drivers/gpu/drm/mediatek/Kconfig   |7 +
> >  drivers/gpu/drm/mediatek/Makefile  |2 +
> >  drivers/gpu/drm/mediatek/mtk_dp.c  | 2825 
> >  drivers/gpu/drm/mediatek/mtk_dp_reg.h  |  535 +
> >  drivers/gpu/drm/mediatek/mtk_drm_drv.c |1 +
> >  drivers/gpu/drm/mediatek/mtk_drm_drv.h |1 +
> >  drivers/phy/mediatek/Kconfig   |8 +
> >  drivers/phy/mediatek/Makefile  |1 +
> >  drivers/phy/mediatek/phy-mtk-dp.c  |  218 ++
> 
> Separate the phy driver to another patch because phy driver would go
> into different maintainer's tree.

Oh of course. Thank you. I fixed it for the next version.

Best,
Markus


[PATCH v3 6/6] drm/mediatek: Add mt8195 DisplayPort driver

2021-10-01 Thread Markus Schneider-Pargmann
This patch adds a DisplayPort driver for the Mediatek mt8195 SoC and a
according phy driver mediatek-dp-phy.

It supports both functional units on the mt8195, the embedded
DisplayPort as well as the external DisplayPort units. It offers
hot-plug-detection, audio up to 8 channels, and DisplayPort 1.4 with up
to 4 lanes.

The driver creates a child device for the phy. The child device will
never exist without the parent being active. As they are sharing a
register range, the parent passes a regmap pointer to the child so that
both can work with the same register range. The phy driver sets device
data that is read by the parent to get the phy device that can be used
to control the phy properties.

This driver is based on an initial version by
Jason-JH.Lin .

Signed-off-by: Markus Schneider-Pargmann 
---

Notes:
Changes v2 -> v3:
- Solve TODOs and add defines for undescribed registers
- Remove TODOs that were irrelevant

Changes v1 -> v2:
- Fix checkpatch --strict suggestions
- General cleanups of the code.
- Remove all remaining non-atomic functions.
- Remove unused includes and sort them.
- Remove unused select GENERIC_PHY
- Rename phy registers DP_PHY -> MTK_DP_PHY
- Replace usage of delays with usleep_range.
- Split the phy register accesses into a separate phy driver.
- Use a lock to guard access to mtk_dp->edid as it can be 
allocated/used/freed
  in different threads
- use struct dp_sdp for sdp packets.

Changes RFC -> v1:
- Removed unused register definitions.
- Replaced workqueue with threaded irq.
- Removed connector code.
- Move to atomic_* drm functions.
- General cleanups of the code.
- Remove unused select GENERIC_PHY.

 drivers/gpu/drm/mediatek/Kconfig   |7 +
 drivers/gpu/drm/mediatek/Makefile  |2 +
 drivers/gpu/drm/mediatek/mtk_dp.c  | 2825 
 drivers/gpu/drm/mediatek/mtk_dp_reg.h  |  535 +
 drivers/gpu/drm/mediatek/mtk_drm_drv.c |1 +
 drivers/gpu/drm/mediatek/mtk_drm_drv.h |1 +
 drivers/phy/mediatek/Kconfig   |8 +
 drivers/phy/mediatek/Makefile  |1 +
 drivers/phy/mediatek/phy-mtk-dp.c  |  218 ++
 include/linux/soc/mediatek/mtk-mmsys.h |2 +
 10 files changed, 3600 insertions(+)
 create mode 100644 drivers/gpu/drm/mediatek/mtk_dp.c
 create mode 100644 drivers/gpu/drm/mediatek/mtk_dp_reg.h
 create mode 100644 drivers/phy/mediatek/phy-mtk-dp.c

diff --git a/drivers/gpu/drm/mediatek/Kconfig b/drivers/gpu/drm/mediatek/Kconfig
index 2976d21e9a34..029b94c71613 100644
--- a/drivers/gpu/drm/mediatek/Kconfig
+++ b/drivers/gpu/drm/mediatek/Kconfig
@@ -28,3 +28,10 @@ config DRM_MEDIATEK_HDMI
select PHY_MTK_HDMI
help
  DRM/KMS HDMI driver for Mediatek SoCs
+
+config MTK_DPTX_SUPPORT
+   tristate "DRM DPTX Support for Mediatek SoCs"
+   depends on DRM_MEDIATEK
+   select PHY_MTK_DP
+   help
+ DRM/KMS Display Port driver for Mediatek SoCs.
diff --git a/drivers/gpu/drm/mediatek/Makefile 
b/drivers/gpu/drm/mediatek/Makefile
index 29098d7c8307..d86a6406055e 100644
--- a/drivers/gpu/drm/mediatek/Makefile
+++ b/drivers/gpu/drm/mediatek/Makefile
@@ -21,3 +21,5 @@ mediatek-drm-hdmi-objs := mtk_cec.o \
  mtk_hdmi_ddc.o
 
 obj-$(CONFIG_DRM_MEDIATEK_HDMI) += mediatek-drm-hdmi.o
+
+obj-$(CONFIG_MTK_DPTX_SUPPORT) += mtk_dp.o
diff --git a/drivers/gpu/drm/mediatek/mtk_dp.c 
b/drivers/gpu/drm/mediatek/mtk_dp.c
new file mode 100644
index ..8a5d03b8c5ff
--- /dev/null
+++ b/drivers/gpu/drm/mediatek/mtk_dp.c
@@ -0,0 +1,2825 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2019 MediaTek Inc.
+ * Copyright (c) 2021 BayLibre
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "mtk_dp_reg.h"
+
+#define MTK_DP_AUX_WAIT_REPLY_COUNT2
+#define MTK_DP_CHECK_SINK_CAP_TIMEOUT_COUNT3
+
+#define MTK_DP_MAX_LANES   4
+#define MTK_DP_MAX_LINK_RATE   MTK_DP_LINKRATE_HBR3
+
+#define MTK_DP_TBC_BUF_READ_START_ADDR 0x08
+
+#define MTK_DP_TRAIN_RETRY_LIMIT   8
+#define MTK_DP_TRAIN_MAX_ITERATIONS5
+
+#define MTK_DP_AUX_WRITE_READ_WAIT_TIME_US 20
+
+#define MTK_DP_DP_VERSION_11   0x11
+
+enum mtk_dp_state {
+   MTK_DP_STATE_INITIAL,
+   MTK_DP_STATE_IDLE,
+   MTK_DP_STATE_PREPARE,
+   MTK_DP_STATE_NORMAL,
+};
+
+enum mtk_dp_train_state {
+   MTK_DP_TRAIN_STATE_STARTUP = 0,
+   MTK_DP_TRAIN_STATE_CHECKCAP,
+   MTK_DP_TRAIN_STATE_CHECKEDID,
+   MTK_DP_TRAIN_STATE_TRAINING_PRE,
+   MTK_DP_TRAIN_STATE_TRAINING,
+   MTK_DP_TRAIN_STATE_CHECKTIMING

[PATCH v3 5/6] drm/mediatek: dpi: Add dpintf support

2021-10-01 Thread Markus Schneider-Pargmann
dpintf is the displayport interface hardware unit. This unit is similar
to dpi and can reuse most of the code.

This patch adds support for mt8195-dpintf to this dpi driver. Main
differences are:
 - Some features/functional components are not available for dpintf
   which are now excluded from code execution once is_dpintf is set
 - dpintf can and needs to choose between different clockdividers based
   on the clockspeed. This is done by choosing a different clock parent.
 - There are two additional clocks that need to be managed. These are
   only set for dpintf and will be set to NULL if not supplied. The
   clk_* calls handle these as normal clocks then.
 - Some register contents differ slightly between the two components. To
   work around this I added register bits/masks with a DPINTF_ prefix
   and use them where different.

Based on a separate driver for dpintf created by
Jason-JH.Lin .

Signed-off-by: Markus Schneider-Pargmann 
---

Notes:
Changes RFC -> v1:
- Remove setting parents and fully rely on the clock tree instead which 
already
  models a mux at the important place.
- Integrated mtk_dpi dpintf changes into the mediatek drm driver.

 drivers/gpu/drm/mediatek/mtk_dpi.c  | 248 
 drivers/gpu/drm/mediatek/mtk_dpi_regs.h |  12 +
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c |   4 +
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h |   1 +
 drivers/gpu/drm/mediatek/mtk_drm_drv.c  |   5 +-
 5 files changed, 218 insertions(+), 52 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c 
b/drivers/gpu/drm/mediatek/mtk_dpi.c
index 4554e2de1430..87961ebf5d35 100644
--- a/drivers/gpu/drm/mediatek/mtk_dpi.c
+++ b/drivers/gpu/drm/mediatek/mtk_dpi.c
@@ -71,6 +71,8 @@ struct mtk_dpi {
void __iomem *regs;
struct device *dev;
struct clk *engine_clk;
+   struct clk *hf_fmm_clk;
+   struct clk *hf_fdp_clk;
struct clk *pixel_clk;
struct clk *tvd_clk;
int irq;
@@ -125,6 +127,7 @@ struct mtk_dpi_conf {
bool edge_sel_en;
const u32 *output_fmts;
u32 num_output_fmts;
+   bool is_dpintf;
 };
 
 static void mtk_dpi_mask(struct mtk_dpi *dpi, u32 offset, u32 val, u32 mask)
@@ -153,30 +156,52 @@ static void mtk_dpi_disable(struct mtk_dpi *dpi)
 static void mtk_dpi_config_hsync(struct mtk_dpi *dpi,
 struct mtk_dpi_sync_param *sync)
 {
-   mtk_dpi_mask(dpi, DPI_TGEN_HWIDTH,
-sync->sync_width << HPW, HPW_MASK);
-   mtk_dpi_mask(dpi, DPI_TGEN_HPORCH,
-sync->back_porch << HBP, HBP_MASK);
-   mtk_dpi_mask(dpi, DPI_TGEN_HPORCH, sync->front_porch << HFP,
-HFP_MASK);
+   if (dpi->conf->is_dpintf) {
+   mtk_dpi_mask(dpi, DPI_TGEN_HWIDTH,
+sync->sync_width << HPW, DPINTF_HPW_MASK);
+   mtk_dpi_mask(dpi, DPI_TGEN_HPORCH,
+sync->back_porch << HBP, DPINTF_HBP_MASK);
+   mtk_dpi_mask(dpi, DPI_TGEN_HPORCH, sync->front_porch << HFP,
+DPINTF_HFP_MASK);
+   } else {
+   mtk_dpi_mask(dpi, DPI_TGEN_HWIDTH,
+sync->sync_width << HPW, HPW_MASK);
+   mtk_dpi_mask(dpi, DPI_TGEN_HPORCH,
+sync->back_porch << HBP, HBP_MASK);
+   mtk_dpi_mask(dpi, DPI_TGEN_HPORCH, sync->front_porch << HFP,
+HFP_MASK);
+   }
 }
 
 static void mtk_dpi_config_vsync(struct mtk_dpi *dpi,
 struct mtk_dpi_sync_param *sync,
 u32 width_addr, u32 porch_addr)
 {
-   mtk_dpi_mask(dpi, width_addr,
-sync->sync_width << VSYNC_WIDTH_SHIFT,
-VSYNC_WIDTH_MASK);
mtk_dpi_mask(dpi, width_addr,
 sync->shift_half_line << VSYNC_HALF_LINE_SHIFT,
 VSYNC_HALF_LINE_MASK);
-   mtk_dpi_mask(dpi, porch_addr,
-sync->back_porch << VSYNC_BACK_PORCH_SHIFT,
-VSYNC_BACK_PORCH_MASK);
-   mtk_dpi_mask(dpi, porch_addr,
-sync->front_porch << VSYNC_FRONT_PORCH_SHIFT,
-VSYNC_FRONT_PORCH_MASK);
+
+   if (dpi->conf->is_dpintf) {
+   mtk_dpi_mask(dpi, width_addr,
+sync->sync_width << VSYNC_WIDTH_SHIFT,
+DPINTF_VSYNC_WIDTH_MASK);
+   mtk_dpi_mask(dpi, porch_addr,
+sync->back_porch << VSYNC_BACK_PORCH_SHIFT,
+DPINTF_VSYNC_BACK_PORCH_MASK);
+   mtk_dpi_mask(dpi, porch_addr,
+sync->front_porch << VSYNC_FRONT_PORCH_SHIFT,
+DP

[PATCH v3 4/6] video/hdmi: Add audio_infoframe packing for DP

2021-10-01 Thread Markus Schneider-Pargmann
Similar to HDMI, DP uses audio infoframes as well which are structured
very similar to the HDMI ones.

This patch adds a helper function to pack the HDMI audio infoframe for
DP, called hdmi_audio_infoframe_pack_for_dp().
hdmi_audio_infoframe_pack_only() is split into two parts. One of them
packs the payload only and can be used for HDMI and DP.

Signed-off-by: Markus Schneider-Pargmann 
---

Notes:
Changes v1 -> v2:
- Create a define for HB2.
- Use struct dp_sdp to pass data in a better way.

 drivers/video/hdmi.c| 83 -
 include/drm/drm_dp_helper.h |  2 +
 include/linux/hdmi.h|  7 +++-
 3 files changed, 72 insertions(+), 20 deletions(-)

diff --git a/drivers/video/hdmi.c b/drivers/video/hdmi.c
index 947be761dfa4..63e74d9fd210 100644
--- a/drivers/video/hdmi.c
+++ b/drivers/video/hdmi.c
@@ -21,6 +21,7 @@
  * DEALINGS IN THE SOFTWARE.
  */
 
+#include 
 #include 
 #include 
 #include 
@@ -381,12 +382,34 @@ static int hdmi_audio_infoframe_check_only(const struct 
hdmi_audio_infoframe *fr
  *
  * Returns 0 on success or a negative error code on failure.
  */
-int hdmi_audio_infoframe_check(struct hdmi_audio_infoframe *frame)
+int hdmi_audio_infoframe_check(const struct hdmi_audio_infoframe *frame)
 {
return hdmi_audio_infoframe_check_only(frame);
 }
 EXPORT_SYMBOL(hdmi_audio_infoframe_check);
 
+static void
+hdmi_audio_infoframe_pack_payload(const struct hdmi_audio_infoframe *frame,
+ u8 *buffer)
+{
+   u8 channels;
+
+   if (frame->channels >= 2)
+   channels = frame->channels - 1;
+   else
+   channels = 0;
+
+   buffer[0] = ((frame->coding_type & 0xf) << 4) | (channels & 0x7);
+   buffer[1] = ((frame->sample_frequency & 0x7) << 2) |
+(frame->sample_size & 0x3);
+   buffer[2] = frame->coding_type_ext & 0x1f;
+   buffer[3] = frame->channel_allocation;
+   buffer[4] = (frame->level_shift_value & 0xf) << 3;
+
+   if (frame->downmix_inhibit)
+   buffer[4] |= BIT(7);
+}
+
 /**
  * hdmi_audio_infoframe_pack_only() - write HDMI audio infoframe to binary 
buffer
  * @frame: HDMI audio infoframe
@@ -404,7 +427,6 @@ EXPORT_SYMBOL(hdmi_audio_infoframe_check);
 ssize_t hdmi_audio_infoframe_pack_only(const struct hdmi_audio_infoframe 
*frame,
   void *buffer, size_t size)
 {
-   unsigned char channels;
u8 *ptr = buffer;
size_t length;
int ret;
@@ -420,28 +442,13 @@ ssize_t hdmi_audio_infoframe_pack_only(const struct 
hdmi_audio_infoframe *frame,
 
memset(buffer, 0, size);
 
-   if (frame->channels >= 2)
-   channels = frame->channels - 1;
-   else
-   channels = 0;
-
ptr[0] = frame->type;
ptr[1] = frame->version;
ptr[2] = frame->length;
ptr[3] = 0; /* checksum */
 
-   /* start infoframe payload */
-   ptr += HDMI_INFOFRAME_HEADER_SIZE;
-
-   ptr[0] = ((frame->coding_type & 0xf) << 4) | (channels & 0x7);
-   ptr[1] = ((frame->sample_frequency & 0x7) << 2) |
-(frame->sample_size & 0x3);
-   ptr[2] = frame->coding_type_ext & 0x1f;
-   ptr[3] = frame->channel_allocation;
-   ptr[4] = (frame->level_shift_value & 0xf) << 3;
-
-   if (frame->downmix_inhibit)
-   ptr[4] |= BIT(7);
+   hdmi_audio_infoframe_pack_payload(frame,
+ ptr + HDMI_INFOFRAME_HEADER_SIZE);
 
hdmi_infoframe_set_checksum(buffer, length);
 
@@ -479,6 +486,44 @@ ssize_t hdmi_audio_infoframe_pack(struct 
hdmi_audio_infoframe *frame,
 }
 EXPORT_SYMBOL(hdmi_audio_infoframe_pack);
 
+/**
+ * hdmi_audio_infoframe_pack_for_dp - Pack a HDMI Audio infoframe for
+ *displayport
+ *
+ * @frame HDMI Audio infoframe
+ * @sdp secondary data packet for display port. This is filled with the
+ * appropriate data
+ * @dp_version Display Port version to be encoded in the header
+ *
+ * Packs a HDMI Audio Infoframe to be sent over Display Port. This function
+ * fills the secondary data packet to be used for Display Port.
+ *
+ * Return: Number of total written bytes or a negative errno on failure.
+ */
+ssize_t
+hdmi_audio_infoframe_pack_for_dp(const struct hdmi_audio_infoframe *frame,
+struct dp_sdp *sdp, u8 dp_version)
+{
+   int ret;
+
+   ret = hdmi_audio_infoframe_check(frame);
+   if (ret)
+   return ret;
+
+   memset(sdp->db, 0, sizeof(sdp->db));
+
+   // Secondary-data packet header
+   sdp->sdp_header.HB0 = 0;
+   sdp->sdp_header.HB1 = frame->type;
+   sdp->sdp_header.HB2 = DP_SDP_AUDIO_INFOFRAME_HB2;
+   sdp->sdp_header.HB

[PATCH v3 3/6] drm/edid: Add cea_sad helpers for freq/length

2021-10-01 Thread Markus Schneider-Pargmann
This patch adds two helper functions that extract the frequency and word
length from a struct cea_sad.

For these helper functions new defines are added that help translate the
'freq' and 'byte2' fields into real numbers.

Signed-off-by: Markus Schneider-Pargmann 
---

Notes:
Changes v2 -> v3:
- Add DRM_ prefix to the CEA_SAD defines.

Changes v1 -> v2:
- Use const struct pointers.
- Add a check whether the format is actually uncompressed or not.

 drivers/gpu/drm/drm_edid.c | 74 ++
 include/drm/drm_edid.h | 18 --
 2 files changed, 90 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index 6325877c5fd6..c134803e18db 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -4666,6 +4666,80 @@ int drm_edid_to_speaker_allocation(struct edid *edid, u8 
**sadb)
 }
 EXPORT_SYMBOL(drm_edid_to_speaker_allocation);
 
+/**
+ * drm_cea_sad_get_sample_rate - Extract the sample rate from cea_sad
+ * @sad: Pointer to the cea_sad struct
+ *
+ * Extracts the cea_sad frequency field and returns the sample rate in Hz.
+ *
+ * Return: Sample rate in Hz or a negative errno if parsing failed.
+ */
+int drm_cea_sad_get_sample_rate(const struct cea_sad *sad)
+{
+   switch (sad->freq) {
+   case DRM_CEA_SAD_FREQ_32KHZ:
+   return 32000;
+   case DRM_CEA_SAD_FREQ_44KHZ:
+   return 44100;
+   case DRM_CEA_SAD_FREQ_48KHZ:
+   return 48000;
+   case DRM_CEA_SAD_FREQ_88KHZ:
+   return 88200;
+   case DRM_CEA_SAD_FREQ_96KHZ:
+   return 96000;
+   case DRM_CEA_SAD_FREQ_176KHZ:
+   return 176400;
+   case DRM_CEA_SAD_FREQ_192KHZ:
+   return 192000;
+   default:
+   return -EINVAL;
+   }
+}
+EXPORT_SYMBOL(drm_cea_sad_get_sample_rate);
+
+static bool drm_cea_sad_is_uncompressed(const struct cea_sad *sad)
+{
+   switch (sad->format) {
+   case HDMI_AUDIO_CODING_TYPE_STREAM:
+   case HDMI_AUDIO_CODING_TYPE_PCM:
+   return true;
+   default:
+   return false;
+   }
+}
+
+/**
+ * drm_cea_sad_get_uncompressed_word_length - Extract word length
+ * @sad: Pointer to the cea_sad struct
+ *
+ * Extracts the cea_sad byte2 field and returns the word length for an
+ * uncompressed stream.
+ *
+ * Note: This function may only be called for uncompressed audio.
+ *
+ * Return: Word length in bits or a negative errno if parsing failed.
+ */
+int drm_cea_sad_get_uncompressed_word_length(const struct cea_sad *sad)
+{
+   if (!drm_cea_sad_is_uncompressed(sad)) {
+   DRM_WARN("Unable to get the uncompressed word length for a 
compressed format: %u\n",
+sad->format);
+   return -EINVAL;
+   }
+
+   switch (sad->byte2) {
+   case DRM_CEA_SAD_UNCOMPRESSED_WORD_16BIT:
+   return 16;
+   case DRM_CEA_SAD_UNCOMPRESSED_WORD_20BIT:
+   return 20;
+   case DRM_CEA_SAD_UNCOMPRESSED_WORD_24BIT:
+   return 24;
+   default:
+   return -EINVAL;
+   }
+}
+EXPORT_SYMBOL(drm_cea_sad_get_uncompressed_word_length);
+
 /**
  * drm_av_sync_delay - compute the HDMI/DP sink audio-video sync delay
  * @connector: connector associated with the HDMI/DP sink
diff --git a/include/drm/drm_edid.h b/include/drm/drm_edid.h
index deccfd39e6db..9d75df652b17 100644
--- a/include/drm/drm_edid.h
+++ b/include/drm/drm_edid.h
@@ -361,12 +361,24 @@ struct edid {
 
 /* Short Audio Descriptor */
 struct cea_sad {
-   u8 format;
+   u8 format; /* See HDMI_AUDIO_CODING_TYPE_* */
u8 channels; /* max number of channels - 1 */
-   u8 freq;
+   u8 freq; /* See CEA_SAD_FREQ_* */
u8 byte2; /* meaning depends on format */
 };
 
+#define DRM_CEA_SAD_FREQ_32KHZ  BIT(0)
+#define DRM_CEA_SAD_FREQ_44KHZ  BIT(1)
+#define DRM_CEA_SAD_FREQ_48KHZ  BIT(2)
+#define DRM_CEA_SAD_FREQ_88KHZ  BIT(3)
+#define DRM_CEA_SAD_FREQ_96KHZ  BIT(4)
+#define DRM_CEA_SAD_FREQ_176KHZ BIT(5)
+#define DRM_CEA_SAD_FREQ_192KHZ BIT(6)
+
+#define DRM_CEA_SAD_UNCOMPRESSED_WORD_16BIT BIT(0)
+#define DRM_CEA_SAD_UNCOMPRESSED_WORD_20BIT BIT(1)
+#define DRM_CEA_SAD_UNCOMPRESSED_WORD_24BIT BIT(2)
+
 struct drm_encoder;
 struct drm_connector;
 struct drm_connector_state;
@@ -374,6 +386,8 @@ struct drm_display_mode;
 
 int drm_edid_to_sad(struct edid *edid, struct cea_sad **sads);
 int drm_edid_to_speaker_allocation(struct edid *edid, u8 **sadb);
+int drm_cea_sad_get_sample_rate(const struct cea_sad *sad);
+int drm_cea_sad_get_uncompressed_word_length(const struct cea_sad *sad);
 int drm_av_sync_delay(struct drm_connector *connector,
  const struct drm_display_mode *mode);
 
-- 
2.33.0



[PATCH v3 2/6] dt-bindings: mediatek,dp: Add Display Port binding

2021-10-01 Thread Markus Schneider-Pargmann
This controller is present on several mediatek hardware. Currently
mt8195 and mt8395 have this controller without a functional difference,
so only one compatible field is added.

The controller can have two forms, as a normal display port and as an
embedded display port.

Signed-off-by: Markus Schneider-Pargmann 
---
 .../display/mediatek/mediatek,dp.yaml | 89 +++
 1 file changed, 89 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/display/mediatek/mediatek,dp.yaml

diff --git 
a/Documentation/devicetree/bindings/display/mediatek/mediatek,dp.yaml 
b/Documentation/devicetree/bindings/display/mediatek/mediatek,dp.yaml
new file mode 100644
index ..f7a35962c23b
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,dp.yaml
@@ -0,0 +1,89 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/mediatek/mediatek,dp.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Mediatek Display Port Controller
+
+maintainers:
+  - CK Hu 
+  - Jitao shi 
+
+description: |
+  Device tree bindings for the Mediatek (embedded) Display Port controller
+  present on some Mediatek SoCs.
+
+properties:
+  compatible:
+enum:
+  - mediatek,mt8195-edp_tx
+  - mediatek,mt8195-dp_tx
+
+  reg:
+maxItems: 1
+
+  interrupts:
+maxItems: 1
+
+  clocks:
+items:
+  - description: faxi clock
+
+  clock-names:
+items:
+  - const: faxi
+
+  power-domains:
+maxItems: 1
+
+  ports:
+$ref: /schemas/graph.yaml#/properties/ports
+properties:
+  port@0:
+$ref: /schemas/graph.yaml#/properties/port
+description: Input endpoint of the controller, usually dp_intf
+
+  port@1:
+$ref: /schemas/graph.yaml#/properties/port
+description: Output endpoint of the controller
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - ports
+
+additionalProperties: false
+
+examples:
+  - |
+#include 
+#include 
+dp_tx: edp_tx@1c50 {
+compatible = "mediatek,mt8195-edp_tx";
+reg = <0 0x1c50 0 0x8000>;
+interrupts = ;
+power-domains = < MT8195_POWER_DOMAIN_EPD_TX>;
+pinctrl-names = "default";
+pinctrl-0 = <_pin>;
+status = "okay";
+
+ports {
+#address-cells = <1>;
+#size-cells = <0>;
+
+port@0 {
+reg = <0>;
+edp_in: endpoint {
+remote-endpoint = <_intf0_out>;
+};
+};
+port@1 {
+reg = <1>;
+edp_out: endpoint {
+   remote-endpoint = <_in>;
+};
+};
+};
+};
-- 
2.33.0



[PATCH v3 1/6] dt-bindings: mediatek,dpintf: Add DP_INTF binding

2021-10-01 Thread Markus Schneider-Pargmann
DP_INTF is a similar functional block to mediatek,dpi but is different
in that it serves the DisplayPort controller on mediatek SoCs and uses
different clocks. Therefore this patch creates a new binding file for
this functional block.

Signed-off-by: Markus Schneider-Pargmann 
---

Notes:
Changes v1 -> v2:
- Move the devicetree binding from mediatek,dpi into its own binding file.

 .../display/mediatek/mediatek,dpintf.yaml | 78 +++
 1 file changed, 78 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/display/mediatek/mediatek,dpintf.yaml

diff --git 
a/Documentation/devicetree/bindings/display/mediatek/mediatek,dpintf.yaml 
b/Documentation/devicetree/bindings/display/mediatek/mediatek,dpintf.yaml
new file mode 100644
index ..ac1fd93327e6
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,dpintf.yaml
@@ -0,0 +1,78 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/mediatek/mediatek,dpintf.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Mediatek DP_INTF Controller Device Tree Bindings
+
+maintainers:
+  - CK Hu 
+  - Jitao shi 
+
+description: |
+  The Mediatek DP_INTF function block is a sink of the display subsystem
+  connected to the display port controller.
+
+properties:
+  compatible:
+enum:
+  - mediatek,mt8195-dpintf
+
+  reg:
+maxItems: 1
+
+  interrupts:
+maxItems: 1
+
+  clocks:
+items:
+  - description: hf_fmm Clock
+  - description: hf_fdp Clock
+  - description: Pixel Clock
+  - description: DP_INTF PLL
+
+  clock-names:
+items:
+  - const: hf_fmm
+  - const: hf_fdp
+  - const: pixel
+  - const: pll
+
+  port:
+$ref: /schemas/graph.yaml#/properties/port
+description:
+  Output port node. This port should be connected to the input port of an
+  attached display port controller.
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - clocks
+  - clock-names
+  - port
+
+additionalProperties: false
+
+examples:
+  - |
+#include 
+#include 
+#include 
+
+   dp_intf1: dp_intf1@1c113000 {
+   compatible = "mediatek,mt8195-dpintf";
+   reg = <0 0x1c113000 0 0x1000>;
+   interrupts = ;
+   clocks = < CLK_VDO1_DP_INTF0_MM>,
+< CLK_VDO1_DPINTF>,
+< CLK_TOP_DP_SEL>,
+< CLK_TOP_TVDPLL2>;
+   clock-names = "hf_fmm",
+ "hf_fdp",
+ "pixel",
+ "pll";
+   };
+
+...
-- 
2.33.0



[PATCH v3 0/6] drm/mediatek: Add mt8195 DisplayPort driver

2021-10-01 Thread Markus Schneider-Pargmann
Hi everyone,

this series is built around the DisplayPort driver. The dpi/dpintf driver and
the added helper functions are required for the DisplayPort driver to work.

For v3 I fixed/removed obsolete TODOs in the driver code and fixed one feedback
comment regarding a 'DRM_' prefix for the CEA_SAD defines.

The series is still based on v5.15-rc1 but also applies cleanly on linux-next
at the moment. There still is a functional dependency on many different patches
pulled in through the main two dependencies, vdosys0 and vdosys1, but I still
don't have a stable and clean base with these.

Note: This patch series is currently tested on v5.10 and I am still working on
testing it on v5.15.

Dependencies:
- Add Mediatek Soc DRM (vdosys0) support for mt8195
  
https://lore.kernel.org/linux-mediatek/20210825144833.7757-1-jason-jh@mediatek.com/
- Add MediaTek SoC DRM (vdosys1) support for mt8195
  
https://lore.kernel.org/linux-mediatek/20210825100531.5653-1-nancy@mediatek.com/

Older revisions:
RFC - 
https://lore.kernel.org/linux-mediatek/20210816192523.1739365-1-...@baylibre.com/
v1  - 
https://lore.kernel.org/linux-mediatek/20210906193529.718845-1-...@baylibre.com/
v2  - 
https://lore.kernel.org/linux-mediatek/20210920084424.231825-1-...@baylibre.com/

Thanks in advance for any feedback and comments.

Best,
Markus


Markus Schneider-Pargmann (6):
  dt-bindings: mediatek,dpintf: Add DP_INTF binding
  dt-bindings: mediatek,dp: Add Display Port binding
  drm/edid: Add cea_sad helpers for freq/length
  video/hdmi: Add audio_infoframe packing for DP
  drm/mediatek: dpi: Add dpintf support
  drm/mediatek: Add mt8195 DisplayPort driver

 .../display/mediatek/mediatek,dp.yaml |   89 +
 .../display/mediatek/mediatek,dpintf.yaml |   78 +
 drivers/gpu/drm/drm_edid.c|   74 +
 drivers/gpu/drm/mediatek/Kconfig  |7 +
 drivers/gpu/drm/mediatek/Makefile |2 +
 drivers/gpu/drm/mediatek/mtk_dp.c | 2825 +
 drivers/gpu/drm/mediatek/mtk_dp_reg.h |  535 
 drivers/gpu/drm/mediatek/mtk_dpi.c|  248 +-
 drivers/gpu/drm/mediatek/mtk_dpi_regs.h   |   12 +
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c   |4 +
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h   |1 +
 drivers/gpu/drm/mediatek/mtk_drm_drv.c|6 +-
 drivers/gpu/drm/mediatek/mtk_drm_drv.h|1 +
 drivers/phy/mediatek/Kconfig  |8 +
 drivers/phy/mediatek/Makefile |1 +
 drivers/phy/mediatek/phy-mtk-dp.c |  218 ++
 drivers/video/hdmi.c  |   83 +-
 include/drm/drm_dp_helper.h   |2 +
 include/drm/drm_edid.h|   18 +-
 include/linux/hdmi.h  |7 +-
 include/linux/soc/mediatek/mtk-mmsys.h|2 +
 21 files changed, 4147 insertions(+), 74 deletions(-)
 create mode 100644 
Documentation/devicetree/bindings/display/mediatek/mediatek,dp.yaml
 create mode 100644 
Documentation/devicetree/bindings/display/mediatek/mediatek,dpintf.yaml
 create mode 100644 drivers/gpu/drm/mediatek/mtk_dp.c
 create mode 100644 drivers/gpu/drm/mediatek/mtk_dp_reg.h
 create mode 100644 drivers/phy/mediatek/phy-mtk-dp.c

-- 
2.33.0



Re: [PATCH v2 3/6] drm/edid: Add cea_sad helpers for freq/length

2021-09-21 Thread Markus Schneider-Pargmann
Hi Jani,

On Tue, Sep 21, 2021 at 12:49:31PM +0300, Jani Nikula wrote:
> On Mon, 20 Sep 2021, Markus Schneider-Pargmann  wrote:
> > This patch adds two helper functions that extract the frequency and word
> > length from a struct cea_sad.
> >
> > For these helper functions new defines are added that help translate the
> > 'freq' and 'byte2' fields into real numbers.
> >
> > Signed-off-by: Markus Schneider-Pargmann 
> > ---
> >
> > Notes:
> > Changes v1 -> v2:
> > - Use const struct pointers.
> > - Add a check whether the format is actually uncompressed or not.
> >
> >  drivers/gpu/drm/drm_edid.c | 74 ++
> >  include/drm/drm_edid.h | 18 --
> >  2 files changed, 90 insertions(+), 2 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
> > index 6325877c5fd6..28df422fbc03 100644
> > --- a/drivers/gpu/drm/drm_edid.c
> > +++ b/drivers/gpu/drm/drm_edid.c
> > @@ -4666,6 +4666,80 @@ int drm_edid_to_speaker_allocation(struct edid 
> > *edid, u8 **sadb)
> >  }
> >  EXPORT_SYMBOL(drm_edid_to_speaker_allocation);
> >  
> > +/**
> > + * drm_cea_sad_get_sample_rate - Extract the sample rate from cea_sad
> > + * @sad: Pointer to the cea_sad struct
> > + *
> > + * Extracts the cea_sad frequency field and returns the sample rate in Hz.
> > + *
> > + * Return: Sample rate in Hz or a negative errno if parsing failed.
> > + */
> > +int drm_cea_sad_get_sample_rate(const struct cea_sad *sad)
> > +{
> > +   switch (sad->freq) {
> > +   case CEA_SAD_FREQ_32KHZ:
> > +   return 32000;
> > +   case CEA_SAD_FREQ_44KHZ:
> > +   return 44100;
> > +   case CEA_SAD_FREQ_48KHZ:
> > +   return 48000;
> > +   case CEA_SAD_FREQ_88KHZ:
> > +   return 88200;
> > +   case CEA_SAD_FREQ_96KHZ:
> > +   return 96000;
> > +   case CEA_SAD_FREQ_176KHZ:
> > +   return 176400;
> > +   case CEA_SAD_FREQ_192KHZ:
> > +   return 192000;
> > +   default:
> > +   return -EINVAL;
> > +   }
> > +}
> > +EXPORT_SYMBOL(drm_cea_sad_get_sample_rate);
> > +
> > +static bool drm_cea_sad_is_uncompressed(const struct cea_sad *sad)
> > +{
> > +   switch (sad->format) {
> > +   case HDMI_AUDIO_CODING_TYPE_STREAM:
> > +   case HDMI_AUDIO_CODING_TYPE_PCM:
> > +   return true;
> > +   default:
> > +   return false;
> > +   }
> > +}
> > +
> > +/**
> > + * drm_cea_sad_get_uncompressed_word_length - Extract word length
> > + * @sad: Pointer to the cea_sad struct
> > + *
> > + * Extracts the cea_sad byte2 field and returns the word length for an
> > + * uncompressed stream.
> > + *
> > + * Note: This function may only be called for uncompressed audio.
> > + *
> > + * Return: Word length in bits or a negative errno if parsing failed.
> > + */
> > +int drm_cea_sad_get_uncompressed_word_length(const struct cea_sad *sad)
> > +{
> > +   if (!drm_cea_sad_is_uncompressed(sad)) {
> > +   DRM_WARN("Unable to get the uncompressed word length for a 
> > compressed format: %u\n",
> > +sad->format);
> > +   return -EINVAL;
> > +   }
> > +
> > +   switch (sad->byte2) {
> > +   case CEA_SAD_UNCOMPRESSED_WORD_16BIT:
> > +   return 16;
> > +   case CEA_SAD_UNCOMPRESSED_WORD_20BIT:
> > +   return 20;
> > +   case CEA_SAD_UNCOMPRESSED_WORD_24BIT:
> > +   return 24;
> > +   default:
> > +   return -EINVAL;
> > +   }
> > +}
> > +EXPORT_SYMBOL(drm_cea_sad_get_uncompressed_word_length);
> > +
> >  /**
> >   * drm_av_sync_delay - compute the HDMI/DP sink audio-video sync delay
> >   * @connector: connector associated with the HDMI/DP sink
> > diff --git a/include/drm/drm_edid.h b/include/drm/drm_edid.h
> > index deccfd39e6db..7b7d71a7154d 100644
> > --- a/include/drm/drm_edid.h
> > +++ b/include/drm/drm_edid.h
> > @@ -361,12 +361,24 @@ struct edid {
> >  
> >  /* Short Audio Descriptor */
> >  struct cea_sad {
> > -   u8 format;
> > +   u8 format; /* See HDMI_AUDIO_CODING_TYPE_* */
> > u8 channels; /* max number of channels - 1 */
> > -   u8 freq;
> > +   u8 freq; /* See CEA_SAD_FREQ_* */
> > u8 byte2; /* meaning depends on format */
> >  };
> >  
> > +#define CEA_SAD_FREQ_32KHZ  BIT(0)
> > +#defin

Re: [PATCH v2 6/6] drm/mediatek: Add mt8195 DisplayPort driver

2021-09-20 Thread Markus Schneider-Pargmann
Hi,

I just noticed that I left some partly old TODOs in the code. Just
ignore these for now. I don't expect this to be the last version so I
will fix/remove them in the next version.

Best,
Markus

On Mon, Sep 20, 2021 at 10:44:24AM +0200, Markus Schneider-Pargmann wrote:
> This patch adds a DisplayPort driver for the Mediatek mt8195 SoC and a
> according phy driver mediatek-dp-phy.
> 
> It supports both functional units on the mt8195, the embedded
> DisplayPort as well as the external DisplayPort units. It offers
> hot-plug-detection, audio up to 8 channels, and DisplayPort 1.4 with up
> to 4 lanes.
> 
> The driver creates a child device for the phy. The child device will
> never exist without the parent being active. As they are sharing a
> register range, the parent passes a regmap pointer to the child so that
> both can work with the same register range. The phy driver sets device
> data that is read by the parent to get the phy device that can be used
> to control the phy properties.
> 
> This driver is based on an initial version by
> Jason-JH.Lin .
> 
> Signed-off-by: Markus Schneider-Pargmann 
> ---
> 
> Notes:
> Changes v1 -> v2:
> - Fix checkpatch --strict suggestions
> - General cleanups of the code.
> - Remove all remaining non-atomic functions.
> - Remove unused includes and sort them.
> - Remove unused select GENERIC_PHY
> - Rename phy registers DP_PHY -> MTK_DP_PHY
> - Replace usage of delays with usleep_range.
> - Split the phy register accesses into a separate phy driver.
> - Use a lock to guard access to mtk_dp->edid as it can be 
> allocated/used/freed
>   in different threads
> - use struct dp_sdp for sdp packets.
> 
> Changes RFC -> v1:
> - Removed unused register definitions.
> - Replaced workqueue with threaded irq.
> - Removed connector code.
> - Move to atomic_* drm functions.
> - General cleanups of the code.
> - Remove unused select GENERIC_PHY.
> 
>  drivers/gpu/drm/mediatek/Kconfig   |7 +
>  drivers/gpu/drm/mediatek/Makefile  |2 +
>  drivers/gpu/drm/mediatek/mtk_dp.c  | 2855 
>  drivers/gpu/drm/mediatek/mtk_dp_reg.h  |  498 +
>  drivers/gpu/drm/mediatek/mtk_drm_drv.c |1 +
>  drivers/gpu/drm/mediatek/mtk_drm_drv.h |1 +
>  drivers/phy/mediatek/Kconfig   |8 +
>  drivers/phy/mediatek/Makefile  |1 +
>  drivers/phy/mediatek/phy-mtk-dp.c  |  218 ++
>  include/linux/soc/mediatek/mtk-mmsys.h |2 +
>  10 files changed, 3593 insertions(+)
>  create mode 100644 drivers/gpu/drm/mediatek/mtk_dp.c
>  create mode 100644 drivers/gpu/drm/mediatek/mtk_dp_reg.h
>  create mode 100644 drivers/phy/mediatek/phy-mtk-dp.c
> 
> diff --git a/drivers/gpu/drm/mediatek/Kconfig 
> b/drivers/gpu/drm/mediatek/Kconfig
> index 2976d21e9a34..029b94c71613 100644
> --- a/drivers/gpu/drm/mediatek/Kconfig
> +++ b/drivers/gpu/drm/mediatek/Kconfig
> @@ -28,3 +28,10 @@ config DRM_MEDIATEK_HDMI
>   select PHY_MTK_HDMI
>   help
> DRM/KMS HDMI driver for Mediatek SoCs
> +
> +config MTK_DPTX_SUPPORT
> + tristate "DRM DPTX Support for Mediatek SoCs"
> + depends on DRM_MEDIATEK
> + select PHY_MTK_DP
> + help
> +   DRM/KMS Display Port driver for Mediatek SoCs.
> diff --git a/drivers/gpu/drm/mediatek/Makefile 
> b/drivers/gpu/drm/mediatek/Makefile
> index 29098d7c8307..d86a6406055e 100644
> --- a/drivers/gpu/drm/mediatek/Makefile
> +++ b/drivers/gpu/drm/mediatek/Makefile
> @@ -21,3 +21,5 @@ mediatek-drm-hdmi-objs := mtk_cec.o \
> mtk_hdmi_ddc.o
>  
>  obj-$(CONFIG_DRM_MEDIATEK_HDMI) += mediatek-drm-hdmi.o
> +
> +obj-$(CONFIG_MTK_DPTX_SUPPORT) += mtk_dp.o
> diff --git a/drivers/gpu/drm/mediatek/mtk_dp.c 
> b/drivers/gpu/drm/mediatek/mtk_dp.c
> new file mode 100644
> index ..5d95ff68b0df
> --- /dev/null
> +++ b/drivers/gpu/drm/mediatek/mtk_dp.c
> @@ -0,0 +1,2855 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright (c) 2019 MediaTek Inc.
> + * Copyright (c) 2021 BayLibre
> + */
> +
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +
> +#include "mtk_dp_reg.h"
> +
> +#define MTK_DP_AUX_WAIT_REPLY_COUNT  2
> +#define MTK_DP_CHECK_SINK_CAP_TIMEOUT_COUNT  3
> +
> +#define MTK_DP_MAX_LANES 

Re: [PATCH] doc: gpu: drm-internals: Create reference to DRM mm

2021-09-20 Thread Markus Schneider-Pargmann
Hi Jani,

On Mon, Sep 20, 2021 at 02:01:57PM +0300, Jani Nikula wrote:
> On Mon, 20 Sep 2021, Markus Schneider-Pargmann  wrote:
> > This short sentence references nothing for details about memory manager.
> > Replace it with the documentation file for DRM memory management.
> >
> > Cc: Jani Nikula 
> > Signed-off-by: Markus Schneider-Pargmann 
> > ---
> >  Documentation/gpu/drm-internals.rst | 4 ++--
> >  1 file changed, 2 insertions(+), 2 deletions(-)
> >
> > diff --git a/Documentation/gpu/drm-internals.rst 
> > b/Documentation/gpu/drm-internals.rst
> > index 06af044c882f..bdcdfc4ede04 100644
> > --- a/Documentation/gpu/drm-internals.rst
> > +++ b/Documentation/gpu/drm-internals.rst
> > @@ -126,8 +126,8 @@ Memory Manager Initialization
> >  Every DRM driver requires a memory manager which must be initialized at
> >  load time. DRM currently contains two memory managers, the Translation
> >  Table Manager (TTM) and the Graphics Execution Manager (GEM). This
> > -document describes the use of the GEM memory manager only. See ? for
> > -details.
> > +document describes the use of the GEM memory manager only. See
> > +Documentation/gpu/drm-mm.rst for details.
> 
> Please use rst references instead of a file reference.

Thanks for your comment. Could you please explain it a bit more to me?

I am new to the kernel sphinx documentation so I looked it up in
Documentation/doc-guide/sphinx.rst 'Cross-referencing'. It is listed as
the preferred way to reference other documents if I understand it
correctly.

Should the doc-guide be updated then if a rst reference is preferred?

Best,
Markus


[PATCH] doc: gpu: drm-internals: Create reference to DRM mm

2021-09-20 Thread Markus Schneider-Pargmann
This short sentence references nothing for details about memory manager.
Replace it with the documentation file for DRM memory management.

Cc: Jani Nikula 
Signed-off-by: Markus Schneider-Pargmann 
---
 Documentation/gpu/drm-internals.rst | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/Documentation/gpu/drm-internals.rst 
b/Documentation/gpu/drm-internals.rst
index 06af044c882f..bdcdfc4ede04 100644
--- a/Documentation/gpu/drm-internals.rst
+++ b/Documentation/gpu/drm-internals.rst
@@ -126,8 +126,8 @@ Memory Manager Initialization
 Every DRM driver requires a memory manager which must be initialized at
 load time. DRM currently contains two memory managers, the Translation
 Table Manager (TTM) and the Graphics Execution Manager (GEM). This
-document describes the use of the GEM memory manager only. See ? for
-details.
+document describes the use of the GEM memory manager only. See
+Documentation/gpu/drm-mm.rst for details.
 
 Miscellaneous Device Configuration
 ~~
-- 
2.33.0



[PATCH v2 5/6] drm/mediatek: dpi: Add dpintf support

2021-09-20 Thread Markus Schneider-Pargmann
dpintf is the displayport interface hardware unit. This unit is similar
to dpi and can reuse most of the code.

This patch adds support for mt8195-dpintf to this dpi driver. Main
differences are:
 - Some features/functional components are not available for dpintf
   which are now excluded from code execution once is_dpintf is set
 - dpintf can and needs to choose between different clockdividers based
   on the clockspeed. This is done by choosing a different clock parent.
 - There are two additional clocks that need to be managed. These are
   only set for dpintf and will be set to NULL if not supplied. The
   clk_* calls handle these as normal clocks then.
 - Some register contents differ slightly between the two components. To
   work around this I added register bits/masks with a DPINTF_ prefix
   and use them where different.

Based on a separate driver for dpintf created by
Jason-JH.Lin .

Signed-off-by: Markus Schneider-Pargmann 
---

Notes:
Changes RFC -> v1:
- Remove setting parents and fully rely on the clock tree instead which 
already
  models a mux at the important place.
- Integrated mtk_dpi dpintf changes into the mediatek drm driver.

 drivers/gpu/drm/mediatek/mtk_dpi.c  | 248 
 drivers/gpu/drm/mediatek/mtk_dpi_regs.h |  12 +
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c |   4 +
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h |   1 +
 drivers/gpu/drm/mediatek/mtk_drm_drv.c  |   5 +-
 5 files changed, 218 insertions(+), 52 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c 
b/drivers/gpu/drm/mediatek/mtk_dpi.c
index 4554e2de1430..87961ebf5d35 100644
--- a/drivers/gpu/drm/mediatek/mtk_dpi.c
+++ b/drivers/gpu/drm/mediatek/mtk_dpi.c
@@ -71,6 +71,8 @@ struct mtk_dpi {
void __iomem *regs;
struct device *dev;
struct clk *engine_clk;
+   struct clk *hf_fmm_clk;
+   struct clk *hf_fdp_clk;
struct clk *pixel_clk;
struct clk *tvd_clk;
int irq;
@@ -125,6 +127,7 @@ struct mtk_dpi_conf {
bool edge_sel_en;
const u32 *output_fmts;
u32 num_output_fmts;
+   bool is_dpintf;
 };
 
 static void mtk_dpi_mask(struct mtk_dpi *dpi, u32 offset, u32 val, u32 mask)
@@ -153,30 +156,52 @@ static void mtk_dpi_disable(struct mtk_dpi *dpi)
 static void mtk_dpi_config_hsync(struct mtk_dpi *dpi,
 struct mtk_dpi_sync_param *sync)
 {
-   mtk_dpi_mask(dpi, DPI_TGEN_HWIDTH,
-sync->sync_width << HPW, HPW_MASK);
-   mtk_dpi_mask(dpi, DPI_TGEN_HPORCH,
-sync->back_porch << HBP, HBP_MASK);
-   mtk_dpi_mask(dpi, DPI_TGEN_HPORCH, sync->front_porch << HFP,
-HFP_MASK);
+   if (dpi->conf->is_dpintf) {
+   mtk_dpi_mask(dpi, DPI_TGEN_HWIDTH,
+sync->sync_width << HPW, DPINTF_HPW_MASK);
+   mtk_dpi_mask(dpi, DPI_TGEN_HPORCH,
+sync->back_porch << HBP, DPINTF_HBP_MASK);
+   mtk_dpi_mask(dpi, DPI_TGEN_HPORCH, sync->front_porch << HFP,
+DPINTF_HFP_MASK);
+   } else {
+   mtk_dpi_mask(dpi, DPI_TGEN_HWIDTH,
+sync->sync_width << HPW, HPW_MASK);
+   mtk_dpi_mask(dpi, DPI_TGEN_HPORCH,
+sync->back_porch << HBP, HBP_MASK);
+   mtk_dpi_mask(dpi, DPI_TGEN_HPORCH, sync->front_porch << HFP,
+HFP_MASK);
+   }
 }
 
 static void mtk_dpi_config_vsync(struct mtk_dpi *dpi,
 struct mtk_dpi_sync_param *sync,
 u32 width_addr, u32 porch_addr)
 {
-   mtk_dpi_mask(dpi, width_addr,
-sync->sync_width << VSYNC_WIDTH_SHIFT,
-VSYNC_WIDTH_MASK);
mtk_dpi_mask(dpi, width_addr,
 sync->shift_half_line << VSYNC_HALF_LINE_SHIFT,
 VSYNC_HALF_LINE_MASK);
-   mtk_dpi_mask(dpi, porch_addr,
-sync->back_porch << VSYNC_BACK_PORCH_SHIFT,
-VSYNC_BACK_PORCH_MASK);
-   mtk_dpi_mask(dpi, porch_addr,
-sync->front_porch << VSYNC_FRONT_PORCH_SHIFT,
-VSYNC_FRONT_PORCH_MASK);
+
+   if (dpi->conf->is_dpintf) {
+   mtk_dpi_mask(dpi, width_addr,
+sync->sync_width << VSYNC_WIDTH_SHIFT,
+DPINTF_VSYNC_WIDTH_MASK);
+   mtk_dpi_mask(dpi, porch_addr,
+sync->back_porch << VSYNC_BACK_PORCH_SHIFT,
+DPINTF_VSYNC_BACK_PORCH_MASK);
+   mtk_dpi_mask(dpi, porch_addr,
+sync->front_porch << VSYNC_FRONT_PORCH_SHIFT,
+DP

[PATCH v2 4/6] video/hdmi: Add audio_infoframe packing for DP

2021-09-20 Thread Markus Schneider-Pargmann
Similar to HDMI, DP uses audio infoframes as well which are structured
very similar to the HDMI ones.

This patch adds a helper function to pack the HDMI audio infoframe for
DP, called hdmi_audio_infoframe_pack_for_dp().
hdmi_audio_infoframe_pack_only() is split into two parts. One of them
packs the payload only and can be used for HDMI and DP.

Signed-off-by: Markus Schneider-Pargmann 
---

Notes:
Changes v1 -> v2:
- Create a define for HB2.
- Use struct dp_sdp to pass data in a better way.

 drivers/video/hdmi.c| 83 -
 include/drm/drm_dp_helper.h |  2 +
 include/linux/hdmi.h|  7 +++-
 3 files changed, 72 insertions(+), 20 deletions(-)

diff --git a/drivers/video/hdmi.c b/drivers/video/hdmi.c
index 947be761dfa4..63e74d9fd210 100644
--- a/drivers/video/hdmi.c
+++ b/drivers/video/hdmi.c
@@ -21,6 +21,7 @@
  * DEALINGS IN THE SOFTWARE.
  */
 
+#include 
 #include 
 #include 
 #include 
@@ -381,12 +382,34 @@ static int hdmi_audio_infoframe_check_only(const struct 
hdmi_audio_infoframe *fr
  *
  * Returns 0 on success or a negative error code on failure.
  */
-int hdmi_audio_infoframe_check(struct hdmi_audio_infoframe *frame)
+int hdmi_audio_infoframe_check(const struct hdmi_audio_infoframe *frame)
 {
return hdmi_audio_infoframe_check_only(frame);
 }
 EXPORT_SYMBOL(hdmi_audio_infoframe_check);
 
+static void
+hdmi_audio_infoframe_pack_payload(const struct hdmi_audio_infoframe *frame,
+ u8 *buffer)
+{
+   u8 channels;
+
+   if (frame->channels >= 2)
+   channels = frame->channels - 1;
+   else
+   channels = 0;
+
+   buffer[0] = ((frame->coding_type & 0xf) << 4) | (channels & 0x7);
+   buffer[1] = ((frame->sample_frequency & 0x7) << 2) |
+(frame->sample_size & 0x3);
+   buffer[2] = frame->coding_type_ext & 0x1f;
+   buffer[3] = frame->channel_allocation;
+   buffer[4] = (frame->level_shift_value & 0xf) << 3;
+
+   if (frame->downmix_inhibit)
+   buffer[4] |= BIT(7);
+}
+
 /**
  * hdmi_audio_infoframe_pack_only() - write HDMI audio infoframe to binary 
buffer
  * @frame: HDMI audio infoframe
@@ -404,7 +427,6 @@ EXPORT_SYMBOL(hdmi_audio_infoframe_check);
 ssize_t hdmi_audio_infoframe_pack_only(const struct hdmi_audio_infoframe 
*frame,
   void *buffer, size_t size)
 {
-   unsigned char channels;
u8 *ptr = buffer;
size_t length;
int ret;
@@ -420,28 +442,13 @@ ssize_t hdmi_audio_infoframe_pack_only(const struct 
hdmi_audio_infoframe *frame,
 
memset(buffer, 0, size);
 
-   if (frame->channels >= 2)
-   channels = frame->channels - 1;
-   else
-   channels = 0;
-
ptr[0] = frame->type;
ptr[1] = frame->version;
ptr[2] = frame->length;
ptr[3] = 0; /* checksum */
 
-   /* start infoframe payload */
-   ptr += HDMI_INFOFRAME_HEADER_SIZE;
-
-   ptr[0] = ((frame->coding_type & 0xf) << 4) | (channels & 0x7);
-   ptr[1] = ((frame->sample_frequency & 0x7) << 2) |
-(frame->sample_size & 0x3);
-   ptr[2] = frame->coding_type_ext & 0x1f;
-   ptr[3] = frame->channel_allocation;
-   ptr[4] = (frame->level_shift_value & 0xf) << 3;
-
-   if (frame->downmix_inhibit)
-   ptr[4] |= BIT(7);
+   hdmi_audio_infoframe_pack_payload(frame,
+ ptr + HDMI_INFOFRAME_HEADER_SIZE);
 
hdmi_infoframe_set_checksum(buffer, length);
 
@@ -479,6 +486,44 @@ ssize_t hdmi_audio_infoframe_pack(struct 
hdmi_audio_infoframe *frame,
 }
 EXPORT_SYMBOL(hdmi_audio_infoframe_pack);
 
+/**
+ * hdmi_audio_infoframe_pack_for_dp - Pack a HDMI Audio infoframe for
+ *displayport
+ *
+ * @frame HDMI Audio infoframe
+ * @sdp secondary data packet for display port. This is filled with the
+ * appropriate data
+ * @dp_version Display Port version to be encoded in the header
+ *
+ * Packs a HDMI Audio Infoframe to be sent over Display Port. This function
+ * fills the secondary data packet to be used for Display Port.
+ *
+ * Return: Number of total written bytes or a negative errno on failure.
+ */
+ssize_t
+hdmi_audio_infoframe_pack_for_dp(const struct hdmi_audio_infoframe *frame,
+struct dp_sdp *sdp, u8 dp_version)
+{
+   int ret;
+
+   ret = hdmi_audio_infoframe_check(frame);
+   if (ret)
+   return ret;
+
+   memset(sdp->db, 0, sizeof(sdp->db));
+
+   // Secondary-data packet header
+   sdp->sdp_header.HB0 = 0;
+   sdp->sdp_header.HB1 = frame->type;
+   sdp->sdp_header.HB2 = DP_SDP_AUDIO_INFOFRAME_HB2;
+   sdp->sdp_header.HB

[PATCH v2 3/6] drm/edid: Add cea_sad helpers for freq/length

2021-09-20 Thread Markus Schneider-Pargmann
This patch adds two helper functions that extract the frequency and word
length from a struct cea_sad.

For these helper functions new defines are added that help translate the
'freq' and 'byte2' fields into real numbers.

Signed-off-by: Markus Schneider-Pargmann 
---

Notes:
Changes v1 -> v2:
- Use const struct pointers.
- Add a check whether the format is actually uncompressed or not.

 drivers/gpu/drm/drm_edid.c | 74 ++
 include/drm/drm_edid.h | 18 --
 2 files changed, 90 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index 6325877c5fd6..28df422fbc03 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -4666,6 +4666,80 @@ int drm_edid_to_speaker_allocation(struct edid *edid, u8 
**sadb)
 }
 EXPORT_SYMBOL(drm_edid_to_speaker_allocation);
 
+/**
+ * drm_cea_sad_get_sample_rate - Extract the sample rate from cea_sad
+ * @sad: Pointer to the cea_sad struct
+ *
+ * Extracts the cea_sad frequency field and returns the sample rate in Hz.
+ *
+ * Return: Sample rate in Hz or a negative errno if parsing failed.
+ */
+int drm_cea_sad_get_sample_rate(const struct cea_sad *sad)
+{
+   switch (sad->freq) {
+   case CEA_SAD_FREQ_32KHZ:
+   return 32000;
+   case CEA_SAD_FREQ_44KHZ:
+   return 44100;
+   case CEA_SAD_FREQ_48KHZ:
+   return 48000;
+   case CEA_SAD_FREQ_88KHZ:
+   return 88200;
+   case CEA_SAD_FREQ_96KHZ:
+   return 96000;
+   case CEA_SAD_FREQ_176KHZ:
+   return 176400;
+   case CEA_SAD_FREQ_192KHZ:
+   return 192000;
+   default:
+   return -EINVAL;
+   }
+}
+EXPORT_SYMBOL(drm_cea_sad_get_sample_rate);
+
+static bool drm_cea_sad_is_uncompressed(const struct cea_sad *sad)
+{
+   switch (sad->format) {
+   case HDMI_AUDIO_CODING_TYPE_STREAM:
+   case HDMI_AUDIO_CODING_TYPE_PCM:
+   return true;
+   default:
+   return false;
+   }
+}
+
+/**
+ * drm_cea_sad_get_uncompressed_word_length - Extract word length
+ * @sad: Pointer to the cea_sad struct
+ *
+ * Extracts the cea_sad byte2 field and returns the word length for an
+ * uncompressed stream.
+ *
+ * Note: This function may only be called for uncompressed audio.
+ *
+ * Return: Word length in bits or a negative errno if parsing failed.
+ */
+int drm_cea_sad_get_uncompressed_word_length(const struct cea_sad *sad)
+{
+   if (!drm_cea_sad_is_uncompressed(sad)) {
+   DRM_WARN("Unable to get the uncompressed word length for a 
compressed format: %u\n",
+sad->format);
+   return -EINVAL;
+   }
+
+   switch (sad->byte2) {
+   case CEA_SAD_UNCOMPRESSED_WORD_16BIT:
+   return 16;
+   case CEA_SAD_UNCOMPRESSED_WORD_20BIT:
+   return 20;
+   case CEA_SAD_UNCOMPRESSED_WORD_24BIT:
+   return 24;
+   default:
+   return -EINVAL;
+   }
+}
+EXPORT_SYMBOL(drm_cea_sad_get_uncompressed_word_length);
+
 /**
  * drm_av_sync_delay - compute the HDMI/DP sink audio-video sync delay
  * @connector: connector associated with the HDMI/DP sink
diff --git a/include/drm/drm_edid.h b/include/drm/drm_edid.h
index deccfd39e6db..7b7d71a7154d 100644
--- a/include/drm/drm_edid.h
+++ b/include/drm/drm_edid.h
@@ -361,12 +361,24 @@ struct edid {
 
 /* Short Audio Descriptor */
 struct cea_sad {
-   u8 format;
+   u8 format; /* See HDMI_AUDIO_CODING_TYPE_* */
u8 channels; /* max number of channels - 1 */
-   u8 freq;
+   u8 freq; /* See CEA_SAD_FREQ_* */
u8 byte2; /* meaning depends on format */
 };
 
+#define CEA_SAD_FREQ_32KHZ  BIT(0)
+#define CEA_SAD_FREQ_44KHZ  BIT(1)
+#define CEA_SAD_FREQ_48KHZ  BIT(2)
+#define CEA_SAD_FREQ_88KHZ  BIT(3)
+#define CEA_SAD_FREQ_96KHZ  BIT(4)
+#define CEA_SAD_FREQ_176KHZ BIT(5)
+#define CEA_SAD_FREQ_192KHZ BIT(6)
+
+#define CEA_SAD_UNCOMPRESSED_WORD_16BIT BIT(0)
+#define CEA_SAD_UNCOMPRESSED_WORD_20BIT BIT(1)
+#define CEA_SAD_UNCOMPRESSED_WORD_24BIT BIT(2)
+
 struct drm_encoder;
 struct drm_connector;
 struct drm_connector_state;
@@ -374,6 +386,8 @@ struct drm_display_mode;
 
 int drm_edid_to_sad(struct edid *edid, struct cea_sad **sads);
 int drm_edid_to_speaker_allocation(struct edid *edid, u8 **sadb);
+int drm_cea_sad_get_sample_rate(const struct cea_sad *sad);
+int drm_cea_sad_get_uncompressed_word_length(const struct cea_sad *sad);
 int drm_av_sync_delay(struct drm_connector *connector,
  const struct drm_display_mode *mode);
 
-- 
2.33.0



[PATCH v2 6/6] drm/mediatek: Add mt8195 DisplayPort driver

2021-09-20 Thread Markus Schneider-Pargmann
This patch adds a DisplayPort driver for the Mediatek mt8195 SoC and a
according phy driver mediatek-dp-phy.

It supports both functional units on the mt8195, the embedded
DisplayPort as well as the external DisplayPort units. It offers
hot-plug-detection, audio up to 8 channels, and DisplayPort 1.4 with up
to 4 lanes.

The driver creates a child device for the phy. The child device will
never exist without the parent being active. As they are sharing a
register range, the parent passes a regmap pointer to the child so that
both can work with the same register range. The phy driver sets device
data that is read by the parent to get the phy device that can be used
to control the phy properties.

This driver is based on an initial version by
Jason-JH.Lin .

Signed-off-by: Markus Schneider-Pargmann 
---

Notes:
Changes v1 -> v2:
- Fix checkpatch --strict suggestions
- General cleanups of the code.
- Remove all remaining non-atomic functions.
- Remove unused includes and sort them.
- Remove unused select GENERIC_PHY
- Rename phy registers DP_PHY -> MTK_DP_PHY
- Replace usage of delays with usleep_range.
- Split the phy register accesses into a separate phy driver.
- Use a lock to guard access to mtk_dp->edid as it can be 
allocated/used/freed
  in different threads
- use struct dp_sdp for sdp packets.

Changes RFC -> v1:
- Removed unused register definitions.
- Replaced workqueue with threaded irq.
- Removed connector code.
- Move to atomic_* drm functions.
- General cleanups of the code.
- Remove unused select GENERIC_PHY.

 drivers/gpu/drm/mediatek/Kconfig   |7 +
 drivers/gpu/drm/mediatek/Makefile  |2 +
 drivers/gpu/drm/mediatek/mtk_dp.c  | 2855 
 drivers/gpu/drm/mediatek/mtk_dp_reg.h  |  498 +
 drivers/gpu/drm/mediatek/mtk_drm_drv.c |1 +
 drivers/gpu/drm/mediatek/mtk_drm_drv.h |1 +
 drivers/phy/mediatek/Kconfig   |8 +
 drivers/phy/mediatek/Makefile  |1 +
 drivers/phy/mediatek/phy-mtk-dp.c  |  218 ++
 include/linux/soc/mediatek/mtk-mmsys.h |2 +
 10 files changed, 3593 insertions(+)
 create mode 100644 drivers/gpu/drm/mediatek/mtk_dp.c
 create mode 100644 drivers/gpu/drm/mediatek/mtk_dp_reg.h
 create mode 100644 drivers/phy/mediatek/phy-mtk-dp.c

diff --git a/drivers/gpu/drm/mediatek/Kconfig b/drivers/gpu/drm/mediatek/Kconfig
index 2976d21e9a34..029b94c71613 100644
--- a/drivers/gpu/drm/mediatek/Kconfig
+++ b/drivers/gpu/drm/mediatek/Kconfig
@@ -28,3 +28,10 @@ config DRM_MEDIATEK_HDMI
select PHY_MTK_HDMI
help
  DRM/KMS HDMI driver for Mediatek SoCs
+
+config MTK_DPTX_SUPPORT
+   tristate "DRM DPTX Support for Mediatek SoCs"
+   depends on DRM_MEDIATEK
+   select PHY_MTK_DP
+   help
+ DRM/KMS Display Port driver for Mediatek SoCs.
diff --git a/drivers/gpu/drm/mediatek/Makefile 
b/drivers/gpu/drm/mediatek/Makefile
index 29098d7c8307..d86a6406055e 100644
--- a/drivers/gpu/drm/mediatek/Makefile
+++ b/drivers/gpu/drm/mediatek/Makefile
@@ -21,3 +21,5 @@ mediatek-drm-hdmi-objs := mtk_cec.o \
  mtk_hdmi_ddc.o
 
 obj-$(CONFIG_DRM_MEDIATEK_HDMI) += mediatek-drm-hdmi.o
+
+obj-$(CONFIG_MTK_DPTX_SUPPORT) += mtk_dp.o
diff --git a/drivers/gpu/drm/mediatek/mtk_dp.c 
b/drivers/gpu/drm/mediatek/mtk_dp.c
new file mode 100644
index ..5d95ff68b0df
--- /dev/null
+++ b/drivers/gpu/drm/mediatek/mtk_dp.c
@@ -0,0 +1,2855 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2019 MediaTek Inc.
+ * Copyright (c) 2021 BayLibre
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "mtk_dp_reg.h"
+
+#define MTK_DP_AUX_WAIT_REPLY_COUNT2
+#define MTK_DP_CHECK_SINK_CAP_TIMEOUT_COUNT3
+
+#define MTK_DP_MAX_LANES   4
+#define MTK_DP_MAX_LINK_RATE   MTK_DP_LINKRATE_HBR3
+
+#define MTK_DP_TBC_BUF_READ_START_ADDR 0x08
+
+#define MTK_DP_TRAIN_RETRY_LIMIT   8
+#define MTK_DP_TRAIN_MAX_ITERATIONS5
+
+#define MTK_DP_AUX_WRITE_READ_WAIT_TIME_US 20
+
+#define MTK_DP_DP_VERSION_11   0x11
+
+enum mtk_dp_state {
+   MTK_DP_STATE_INITIAL,
+   MTK_DP_STATE_IDLE,
+   MTK_DP_STATE_PREPARE,
+   MTK_DP_STATE_NORMAL,
+};
+
+enum mtk_dp_train_state {
+   MTK_DP_TRAIN_STATE_STARTUP = 0,
+   MTK_DP_TRAIN_STATE_CHECKCAP,
+   MTK_DP_TRAIN_STATE_CHECKEDID,
+   MTK_DP_TRAIN_STATE_TRAINING_PRE,
+   MTK_DP_TRAIN_STATE_TRAINING,
+   MTK_DP_TRAIN_STATE_CHECKTIMING,
+   MTK_DP_TRAIN_STATE_NORMAL,
+   MTK_DP_TRAIN_STATE_POWERSAVE,
+   MTK_DP_TRAIN_STATE_DPIDLE,
+};
+
+struct mtk_dp_timings {
+   struct vi

[PATCH v2 2/6] dt-bindings: mediatek,dp: Add Display Port binding

2021-09-20 Thread Markus Schneider-Pargmann
This controller is present on several mediatek hardware. Currently
mt8195 and mt8395 have this controller without a functional difference,
so only one compatible field is added.

The controller can have two forms, as a normal display port and as an
embedded display port.

Signed-off-by: Markus Schneider-Pargmann 
---
 .../display/mediatek/mediatek,dp.yaml | 89 +++
 1 file changed, 89 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/display/mediatek/mediatek,dp.yaml

diff --git 
a/Documentation/devicetree/bindings/display/mediatek/mediatek,dp.yaml 
b/Documentation/devicetree/bindings/display/mediatek/mediatek,dp.yaml
new file mode 100644
index ..f7a35962c23b
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,dp.yaml
@@ -0,0 +1,89 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/mediatek/mediatek,dp.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Mediatek Display Port Controller
+
+maintainers:
+  - CK Hu 
+  - Jitao shi 
+
+description: |
+  Device tree bindings for the Mediatek (embedded) Display Port controller
+  present on some Mediatek SoCs.
+
+properties:
+  compatible:
+enum:
+  - mediatek,mt8195-edp_tx
+  - mediatek,mt8195-dp_tx
+
+  reg:
+maxItems: 1
+
+  interrupts:
+maxItems: 1
+
+  clocks:
+items:
+  - description: faxi clock
+
+  clock-names:
+items:
+  - const: faxi
+
+  power-domains:
+maxItems: 1
+
+  ports:
+$ref: /schemas/graph.yaml#/properties/ports
+properties:
+  port@0:
+$ref: /schemas/graph.yaml#/properties/port
+description: Input endpoint of the controller, usually dp_intf
+
+  port@1:
+$ref: /schemas/graph.yaml#/properties/port
+description: Output endpoint of the controller
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - ports
+
+additionalProperties: false
+
+examples:
+  - |
+#include 
+#include 
+dp_tx: edp_tx@1c50 {
+compatible = "mediatek,mt8195-edp_tx";
+reg = <0 0x1c50 0 0x8000>;
+interrupts = ;
+power-domains = < MT8195_POWER_DOMAIN_EPD_TX>;
+pinctrl-names = "default";
+pinctrl-0 = <_pin>;
+status = "okay";
+
+ports {
+#address-cells = <1>;
+#size-cells = <0>;
+
+port@0 {
+reg = <0>;
+edp_in: endpoint {
+remote-endpoint = <_intf0_out>;
+};
+};
+port@1 {
+reg = <1>;
+edp_out: endpoint {
+   remote-endpoint = <_in>;
+};
+};
+};
+};
-- 
2.33.0



[PATCH v2 1/6] dt-bindings: mediatek,dpintf: Add DP_INTF binding

2021-09-20 Thread Markus Schneider-Pargmann
DP_INTF is a similar functional block to mediatek,dpi but is different
in that it serves the DisplayPort controller on mediatek SoCs and uses
different clocks. Therefore this patch creates a new binding file for
this functional block.

Signed-off-by: Markus Schneider-Pargmann 
---

Notes:
Changes v1 -> v2:
- Move the devicetree binding from mediatek,dpi into its own binding file.

 .../display/mediatek/mediatek,dpintf.yaml | 78 +++
 1 file changed, 78 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/display/mediatek/mediatek,dpintf.yaml

diff --git 
a/Documentation/devicetree/bindings/display/mediatek/mediatek,dpintf.yaml 
b/Documentation/devicetree/bindings/display/mediatek/mediatek,dpintf.yaml
new file mode 100644
index ..ac1fd93327e6
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,dpintf.yaml
@@ -0,0 +1,78 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/mediatek/mediatek,dpintf.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Mediatek DP_INTF Controller Device Tree Bindings
+
+maintainers:
+  - CK Hu 
+  - Jitao shi 
+
+description: |
+  The Mediatek DP_INTF function block is a sink of the display subsystem
+  connected to the display port controller.
+
+properties:
+  compatible:
+enum:
+  - mediatek,mt8195-dpintf
+
+  reg:
+maxItems: 1
+
+  interrupts:
+maxItems: 1
+
+  clocks:
+items:
+  - description: hf_fmm Clock
+  - description: hf_fdp Clock
+  - description: Pixel Clock
+  - description: DP_INTF PLL
+
+  clock-names:
+items:
+  - const: hf_fmm
+  - const: hf_fdp
+  - const: pixel
+  - const: pll
+
+  port:
+$ref: /schemas/graph.yaml#/properties/port
+description:
+  Output port node. This port should be connected to the input port of an
+  attached display port controller.
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - clocks
+  - clock-names
+  - port
+
+additionalProperties: false
+
+examples:
+  - |
+#include 
+#include 
+#include 
+
+   dp_intf1: dp_intf1@1c113000 {
+   compatible = "mediatek,mt8195-dpintf";
+   reg = <0 0x1c113000 0 0x1000>;
+   interrupts = ;
+   clocks = < CLK_VDO1_DP_INTF0_MM>,
+< CLK_VDO1_DPINTF>,
+< CLK_TOP_DP_SEL>,
+< CLK_TOP_TVDPLL2>;
+   clock-names = "hf_fmm",
+ "hf_fdp",
+ "pixel",
+ "pll";
+   };
+
+...
-- 
2.33.0



[PATCH v2 0/6] drm/mediatek: Add mt8195 DisplayPort driver

2021-09-20 Thread Markus Schneider-Pargmann
Hi everyone,

this series is built around the DisplayPort driver. The dpi/dpintf driver and
the added helper functions are required for the DisplayPort driver to work.

For v2 I rebased the series on top of v5.15-rc1. There still is a functional
dependency on many different patches pulled in through the main two
dependencies, vdosys0 and vdosys1, but I wasn't able to get a clean base with
these patches yet so to continue improving this series in the meantime, I
decided to go with v5.15-rc1 as a base. The main potential merge-conflict
points of this series with other series are mtk_drm_drv.c and
mtk_drm_ddp_comp.* etc. which should be easy to resolve later on.

Note: This patch series is currently tested on v5.10 and I am still working on
testing it on v5.15.

Dependencies:
- Add Mediatek Soc DRM (vdosys0) support for mt8195
  
https://lore.kernel.org/linux-mediatek/20210825144833.7757-1-jason-jh@mediatek.com/
- Add MediaTek SoC DRM (vdosys1) support for mt8195
  
https://lore.kernel.org/linux-mediatek/20210825100531.5653-1-nancy@mediatek.com/

Older revisions:
RFC - 
https://lore.kernel.org/linux-mediatek/20210816192523.1739365-1-...@baylibre.com/
v1  - 
https://lore.kernel.org/linux-mediatek/20210906193529.718845-1-...@baylibre.com/

Thanks in advance for any feedback and comments.

Best,
Markus


Markus Schneider-Pargmann (6):
  dt-bindings: mediatek,dpintf: Add DP_INTF binding
  dt-bindings: mediatek,dp: Add Display Port binding
  drm/edid: Add cea_sad helpers for freq/length
  video/hdmi: Add audio_infoframe packing for DP
  drm/mediatek: dpi: Add dpintf support
  drm/mediatek: Add mt8195 DisplayPort driver

 .../display/mediatek/mediatek,dp.yaml |   89 +
 .../display/mediatek/mediatek,dpintf.yaml |   78 +
 drivers/gpu/drm/drm_edid.c|   74 +
 drivers/gpu/drm/mediatek/Kconfig  |7 +
 drivers/gpu/drm/mediatek/Makefile |2 +
 drivers/gpu/drm/mediatek/mtk_dp.c | 2855 +
 drivers/gpu/drm/mediatek/mtk_dp_reg.h |  498 +++
 drivers/gpu/drm/mediatek/mtk_dpi.c|  248 +-
 drivers/gpu/drm/mediatek/mtk_dpi_regs.h   |   12 +
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c   |4 +
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h   |1 +
 drivers/gpu/drm/mediatek/mtk_drm_drv.c|6 +-
 drivers/gpu/drm/mediatek/mtk_drm_drv.h|1 +
 drivers/phy/mediatek/Kconfig  |8 +
 drivers/phy/mediatek/Makefile |1 +
 drivers/phy/mediatek/phy-mtk-dp.c |  218 ++
 drivers/video/hdmi.c  |   83 +-
 include/drm/drm_dp_helper.h   |2 +
 include/drm/drm_edid.h|   18 +-
 include/linux/hdmi.h  |7 +-
 include/linux/soc/mediatek/mtk-mmsys.h|2 +
 21 files changed, 4140 insertions(+), 74 deletions(-)
 create mode 100644 
Documentation/devicetree/bindings/display/mediatek/mediatek,dp.yaml
 create mode 100644 
Documentation/devicetree/bindings/display/mediatek/mediatek,dpintf.yaml
 create mode 100644 drivers/gpu/drm/mediatek/mtk_dp.c
 create mode 100644 drivers/gpu/drm/mediatek/mtk_dp_reg.h
 create mode 100644 drivers/phy/mediatek/phy-mtk-dp.c

-- 
2.33.0



Re: [PATCH v5 00/16] Add MediaTek SoC DRM (vdosys1) support for mt8195

2021-09-18 Thread Markus Schneider-Pargmann
Hi Nancy,

On Mon, Sep 06, 2021 at 03:15:23PM +0800, Nancy.Lin wrote:
> The hardware path of vdosys1 with DPTx output need to go through by several 
> modules, such as, OVL_ADAPTOR and MERGE.
> 
> Add DRM and these modules support by the patches below:
> 
> Changes in v5:
> - add mmsys reset controller reference.
> 
> Changes in v4:
> - use merge common driver for merge1~4.
> - refine ovl_adaptor rdma driver.
> - use ovl_adaptor ddp_comp function instead of ethdr.
> - modify for reviewer's comment in v3.
> 
> Changes in v3:
> - modify for reviewer's comment in v2.
> - add vdosys1 2 pixels align limit.
> - add mixer odd offset support.
> 
> Changes in v2:
> - Merge PSEUDO_OVL and ETHDR into one DRM component.
> - Add mmsys config API for vdosys1 hardware setting.
> - Add mmsys reset control using linux reset framework.
> 
> Signed-off-by: Nancy.Lin 
> 
> This series are based on the following patch:
> [1] arm64: dts: Add Mediatek SoC MT8195 and evaluation board dts and Makefile
> 
> https://patchwork.kernel.org/project/linux-mediatek/patch/20210601075350.31515-2-seiya.w...@mediatek.com/
> [2] arm64: dts: mt8195: add IOMMU and smi nodes
> 
> https://patchwork.kernel.org/project/linux-mediatek/patch/20210615173233.26682-15-tinghan.s...@mediatek.com/
> [3] [01/24] dt-bindings: mediatek: mt8195: Add binding for MM IOMMU
> 
> https://patchwork.kernel.org/project/linux-mediatek/patch/20210630023504.18177-2-yong...@mediatek.com/
> [4] Add gce support for mt8195
> https://patchwork.kernel.org/project/linux-mediatek/list/?series=537069
> [5] Add MediaTek SoC DRM (vdosys0) support for mt8195
> https://patchwork.kernel.org/project/linux-mediatek/list/?series=537225
> [6] [v8,1/2] dt-bindings: reset: mt8195: add toprgu reset-controller header 
> file
> 
> https://patchwork.kernel.org/project/linux-mediatek/patch/20210806023606.16867-2-christine@mediatek.com/
> [7] [v3,2/7] dt-bindings: mediatek: Add #reset-cells to mmsys system 
> controller
> 
> https://patchwork.kernel.org/project/linux-mediatek/patch/20210825122613.v3.2.I3f7f1c9a8e46be07d1757ddf4e0097535f3a7d41@changeid/
> [8] [v3,6/7] soc: mediatek: mmsys: Add reset controller support
> 
> https://patchwork.kernel.org/project/linux-mediatek/patch/20210825122613.v3.6.I15e2419141a69b2e5c7e700c34d92a69df47e04d@changeid/

My work is currently based on this patch series. Unfortunately with 5.15
I have a bit of trouble picking all the dependencies and run into many
merge conflicts (probably I am missing pieces). I am trying to pick
everything so that I have a good base for my patch. Do you by any chance
have a public git branch with your patch series vdosys1 and all its
dependencies on 5.15? That would make it a lot easier for me to work on
top of it.

Thanks,
Markus

> 
> Nancy.Lin (16):
>   dt-bindings: mediatek: add vdosys1 RDMA definition for mt8195
>   dt-bindings: mediatek: add vdosys1 MERGE property for mt8195
>   dt-bindings: mediatek: add ethdr definition for mt8195
>   dt-bindings: reset: mt8195: add vdosys1 reset control bit
>   arm64: dts: mt8195: add display node for vdosys1
>   soc: mediatek: add mtk-mmsys support for mt8195 vdosys1
>   soc: mediatek: add mtk-mmsys config API for mt8195 vdosys1
>   soc: mediatek: add cmdq support of mtk-mmsys config API for mt8195
> vdosys1
>   soc: mediatek: mmsys: modify reset controller for MT8195 vdosys1
>   soc: mediatek: add mtk-mutex support for mt8195 vdosys1
>   drm/mediatek: add display MDP RDMA support for MT8195
>   drm/mediatek: add display merge api support for MT8195
>   drm/mediatek: add ETHDR support for MT8195
>   drm/mediatek: add ovl_adaptor support for MT8195
>   drm/mediatek: modify mediatek-drm for mt8195 multi mmsys support
>   drm/mediatek: add mediatek-drm of vdosys1 support for MT8195
> 
>  .../display/mediatek/mediatek,ethdr.yaml  | 144 ++
>  .../display/mediatek/mediatek,mdp-rdma.yaml   |  77 
>  .../display/mediatek/mediatek,merge.yaml  |   3 +
>  arch/arm64/boot/dts/mediatek/mt8195.dtsi  | 221 +
>  drivers/gpu/drm/mediatek/Makefile |   5 +-
>  drivers/gpu/drm/mediatek/mtk_disp_drv.h   |  29 ++
>  drivers/gpu/drm/mediatek/mtk_disp_merge.c |  78 +++-
>  .../gpu/drm/mediatek/mtk_disp_ovl_adaptor.c   | 408 +
>  drivers/gpu/drm/mediatek/mtk_drm_crtc.c   |  25 +-
>  drivers/gpu/drm/mediatek/mtk_drm_crtc.h   |   3 +-
>  drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c   |  15 +
>  drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h   |   1 +
>  drivers/gpu/drm/mediatek/mtk_drm_drv.c| 377 +---
>  drivers/gpu/drm/mediatek/mtk_drm_drv.h|   9 +-
>  drivers/gpu/drm/mediatek/mtk_ethdr.c  | 424 ++
>  drivers/gpu/drm/mediatek/mtk_ethdr.h  |  25 ++
>  drivers/gpu/drm/mediatek/mtk_mdp_rdma.c   | 301 +
>  drivers/gpu/drm/mediatek/mtk_mdp_rdma.h   |  37 ++
>  drivers/soc/mediatek/mt8195-mmsys.h   | 199 
>  

Re: [PATCH v1 6/6] drm/mediatek: Add mt8195 DisplayPort driver

2021-09-17 Thread Markus Schneider-Pargmann
Hi Chun-Kuang,

On Tue, Sep 14, 2021 at 07:25:48AM +0800, Chun-Kuang Hu wrote:
> Hi, Markus:
> 
> Markus Schneider-Pargmann  於 2021年9月10日 週五 下午1:36寫道:
> >
> > Hi Chun-Kuang,
> >
> > On Fri, Sep 10, 2021 at 07:37:50AM +0800, Chun-Kuang Hu wrote:
> > > Hi, Markus:
> > >
> > > Markus Schneider-Pargmann  於 2021年9月7日 週二 上午3:37寫道:
> > > >
> > > > This patch adds a DisplayPort driver for the Mediatek mt8195 SoC.
> > > >
> > > > It supports both functional units on the mt8195, the embedded
> > > > DisplayPort as well as the external DisplayPort units. It offers
> > > > hot-plug-detection, audio up to 8 channels, and DisplayPort 1.4 with up
> > > > to 4 lanes.
> > > >
> > > > This driver is based on an initial version by
> > > > Jason-JH.Lin .
> > > >
> > > > Signed-off-by: Markus Schneider-Pargmann 
> > > > ---
> > > >
> > > > Notes:
> > > > Changes RFC -> v1:
> > > > - Removed unused register definitions.
> > > > - Replaced workqueue with threaded irq.
> > > > - Removed connector code.
> > > > - Move to atomic_* drm functions.
> > > > - General cleanups of the code.
> > > > - Remove unused select GENERIC_PHY.
> > > >
> > > >  drivers/gpu/drm/mediatek/Kconfig  |6 +
> > > >  drivers/gpu/drm/mediatek/Makefile |2 +
> > > >  drivers/gpu/drm/mediatek/mtk_dp.c | 2881 +
> > > >  drivers/gpu/drm/mediatek/mtk_dp_reg.h |  580 +
> > > >  4 files changed, 3469 insertions(+)
> > > >  create mode 100644 drivers/gpu/drm/mediatek/mtk_dp.c
> > > >  create mode 100644 drivers/gpu/drm/mediatek/mtk_dp_reg.h
> > > >
> >
> > ...
> >
> > > > +#define TOP_OFFSET 0x2000
> > > > +#define ENC0_OFFSET0x3000
> > > > +#define ENC1_OFFSET0x3200
> > > > +#define TRANS_OFFSET   0x3400
> > > > +#define AUX_OFFSET 0x3600
> > > > +#define SEC_OFFSET 0x4000
> >
> > ...
> >
> > > > +
> > > > +#define DP_PHY_DIG_PLL_CTL_1   0x1014
> > > > +# define TPLL_SSC_EN   BIT(3)
> > >
> > > It seems that register 0x1000 ~ 0x1fff is to control phy and 0x2000 ~
> > > 0x4fff is to control non-phy part. For mipi and hdmi, the phy part is
> > > an independent device [1] and the phy driver is independent [2] , so I
> > > would like this phy to be an independent device.
> > >
> > > [1] 
> > > https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/arch/arm64/boot/dts/mediatek/mt8173.dtsi?h=v5.14
> > > [2] 
> > > https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/phy/mediatek?h=v5.14
> >
> > Thanks for your feedback. I looked into both mipi and hdmi phy drivers
> > that you referenced. It looks like both are really separate units in
> > their SoCs having their own registerspaces located at a completely
> > different range than the units using the phy.
> >
> > For this displayport driver, the phy registers are listed as part of the
> > (e)DP_TX unit in the datasheet. Next to the phy registers all the other
> > parts are listed as well in the same overall register ranges (see
> > above), e.g. TOP_OFFSET, ENC_OFFSET or SEC_OFFSET. Also I would like to
> > avoid splitting it up into a separate unit in the devicetree as the
> > datasheet handles it as a single unit (including the phy registers).
> 
> OK, according to the datasheet, let it to be a single device.
> 
> >
> > From a practical perspective there is also not much to these PHY
> > registers. The only things that would be done in the driver are:
> > - initializing the lane driving parameters with static values
> > - setup the bitrate
> > - enable/disable SSC
> > - do a reset
> > Exporting these four used functions over a driver boundary wouldn't help
> > clarity I think and the code probably can't be reused by any other
> > component anyways.
> 
> Use mmsys device [1] as an example. mmsys has both clock control
> function and other function including routing function. The main
> driver [2] is placed in soc folder, and the clock control part [3] is
> separated to clk folder but the clock control part just simply control
> clock gating.
> 
&

Re: [PATCH v1 6/6] drm/mediatek: Add mt8195 DisplayPort driver

2021-09-09 Thread Markus Schneider-Pargmann
Hi Chun-Kuang,

On Fri, Sep 10, 2021 at 07:37:50AM +0800, Chun-Kuang Hu wrote:
> Hi, Markus:
> 
> Markus Schneider-Pargmann  於 2021年9月7日 週二 上午3:37寫道:
> >
> > This patch adds a DisplayPort driver for the Mediatek mt8195 SoC.
> >
> > It supports both functional units on the mt8195, the embedded
> > DisplayPort as well as the external DisplayPort units. It offers
> > hot-plug-detection, audio up to 8 channels, and DisplayPort 1.4 with up
> > to 4 lanes.
> >
> > This driver is based on an initial version by
> > Jason-JH.Lin .
> >
> > Signed-off-by: Markus Schneider-Pargmann 
> > ---
> >
> > Notes:
> > Changes RFC -> v1:
> > - Removed unused register definitions.
> > - Replaced workqueue with threaded irq.
> > - Removed connector code.
> > - Move to atomic_* drm functions.
> > - General cleanups of the code.
> > - Remove unused select GENERIC_PHY.
> >
> >  drivers/gpu/drm/mediatek/Kconfig  |6 +
> >  drivers/gpu/drm/mediatek/Makefile |2 +
> >  drivers/gpu/drm/mediatek/mtk_dp.c | 2881 +
> >  drivers/gpu/drm/mediatek/mtk_dp_reg.h |  580 +
> >  4 files changed, 3469 insertions(+)
> >  create mode 100644 drivers/gpu/drm/mediatek/mtk_dp.c
> >  create mode 100644 drivers/gpu/drm/mediatek/mtk_dp_reg.h
> >

...

> > +#define TOP_OFFSET 0x2000
> > +#define ENC0_OFFSET0x3000
> > +#define ENC1_OFFSET0x3200
> > +#define TRANS_OFFSET   0x3400
> > +#define AUX_OFFSET 0x3600
> > +#define SEC_OFFSET 0x4000

...

> > +
> > +#define DP_PHY_DIG_PLL_CTL_1   0x1014
> > +# define TPLL_SSC_EN   BIT(3)
> 
> It seems that register 0x1000 ~ 0x1fff is to control phy and 0x2000 ~
> 0x4fff is to control non-phy part. For mipi and hdmi, the phy part is
> an independent device [1] and the phy driver is independent [2] , so I
> would like this phy to be an independent device.
> 
> [1] 
> https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/arch/arm64/boot/dts/mediatek/mt8173.dtsi?h=v5.14
> [2] 
> https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/phy/mediatek?h=v5.14

Thanks for your feedback. I looked into both mipi and hdmi phy drivers
that you referenced. It looks like both are really separate units in
their SoCs having their own registerspaces located at a completely
different range than the units using the phy.

For this displayport driver, the phy registers are listed as part of the
(e)DP_TX unit in the datasheet. Next to the phy registers all the other
parts are listed as well in the same overall register ranges (see
above), e.g. TOP_OFFSET, ENC_OFFSET or SEC_OFFSET. Also I would like to
avoid splitting it up into a separate unit in the devicetree as the
datasheet handles it as a single unit (including the phy registers).

>From a practical perspective there is also not much to these PHY
registers. The only things that would be done in the driver are:
- initializing the lane driving parameters with static values
- setup the bitrate
- enable/disable SSC
- do a reset
Exporting these four used functions over a driver boundary wouldn't help
clarity I think and the code probably can't be reused by any other
component anyways.

So I personally would prefer keeping it as part of the whole driver
because of the above mentioned reasons. What do you think?

Thanks,
Markus

> 
> Regards,
> Chun-Kuang.
> 
> > +
> > +#define DP_PHY_DIG_BIT_RATE0x103C
> > +# define BIT_RATE_RBR  0
> > +# define BIT_RATE_HBR  1
> > +# define BIT_RATE_HBR2 2
> > +# define BIT_RATE_HBR3 3
> > +
> > +#define DP_PHY_DIG_SW_RST  0x1038
> > +# define DP_GLB_SW_RST_PHYDBIT(0)
> > +
> > +#define MTK_DP_LANE0_DRIVING_PARAM_3   0x1138
> > +#define MTK_DP_LANE1_DRIVING_PARAM_3   0x1238
> > +#define MTK_DP_LANE2_DRIVING_PARAM_3   0x1338
> > +#define MTK_DP_LANE3_DRIVING_PARAM_3   0x1438
> > +# define XTP_LN_TX_LCTXC0_SW0_PRE0_DEFAULT 0x10
> > +# define XTP_LN_TX_LCTXC0_SW0_PRE1_DEFAULT (0x14 << 8)
> > +# define XTP_LN_TX_LCTXC0_SW0_PRE2_DEFAULT (0x18 << 16)
&

Re: [PATCH v1 1/6] dt-bindings: mediatek,dpi: Add mt8195 dpintf

2021-09-09 Thread Markus Schneider-Pargmann
Hi Sam,

On Mon, Sep 06, 2021 at 10:14:05PM +0200, Sam Ravnborg wrote:
> Hi Markus,
> 
> On Mon, Sep 06, 2021 at 09:35:24PM +0200, Markus Schneider-Pargmann wrote:
> > DP_INTF is similar to the actual dpi. They differ in some points
> > regarding registers and what needs to be set but the function blocks
> > itself are similar in design.
> > 
> > Signed-off-by: Markus Schneider-Pargmann 
> 
> I fail to see why they share the same dt-schema as the main content in
> the schema is the clocks and they differ.
> 
> A new mediatek,dpintf schema seems more appropriate.

Good idea, I will do that. Thank you.

Best,
Markus

> 
> I recall I though so when reading the RFC variant but failed to comment on it.
> 
>   Sam
> 
> > ---
> >  .../display/mediatek/mediatek,dpi.yaml| 43 ---
> >  1 file changed, 37 insertions(+), 6 deletions(-)
> > 
> > diff --git 
> > a/Documentation/devicetree/bindings/display/mediatek/mediatek,dpi.yaml 
> > b/Documentation/devicetree/bindings/display/mediatek/mediatek,dpi.yaml
> > index dd2896a40ff0..1a158b719ce6 100644
> > --- a/Documentation/devicetree/bindings/display/mediatek/mediatek,dpi.yaml
> > +++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,dpi.yaml
> > @@ -4,7 +4,7 @@
> >  $id: http://devicetree.org/schemas/display/mediatek/mediatek,dpi.yaml#
> >  $schema: http://devicetree.org/meta-schemas/core.yaml#
> >  
> > -title: mediatek DPI Controller Device Tree Bindings
> > +title: mediatek DPI/DP_INTF Controller Device Tree Bindings
> >  
> >  maintainers:
> >- CK Hu 
> > @@ -13,7 +13,8 @@ maintainers:
> >  description: |
> >The Mediatek DPI function block is a sink of the display subsystem and
> >provides 8-bit RGB/YUV444 or 8/10/10-bit YUV422 pixel data on a parallel
> > -  output bus.
> > +  output bus. The Mediatek DP_INTF is a similar function block that is
> > +  connected to the (embedded) display port function block.
> >  
> >  properties:
> >compatible:
> > @@ -23,6 +24,7 @@ properties:
> >- mediatek,mt8173-dpi
> >- mediatek,mt8183-dpi
> >- mediatek,mt8192-dpi
> > +  - mediatek,mt8195-dpintf
> >  
> >reg:
> >  maxItems: 1
> > @@ -37,10 +39,11 @@ properties:
> >- description: DPI PLL
> >  
> >clock-names:
> > -items:
> > -  - const: pixel
> > -  - const: engine
> > -  - const: pll
> > +description:
> > +  For dpi clocks pixel, engine and pll are required. For dpintf pixel,
> > +  hf_fmm and hf_fdp are required.
> > +minItems: 3
> > +maxItems: 3
> >  
> >pinctrl-0: true
> >pinctrl-1: true
> > @@ -64,6 +67,34 @@ required:
> >- clock-names
> >- port
> >  
> > +allOf:
> > +  - if:
> > +  properties:
> > +compatible:
> > +  contains:
> > +enum:
> > +  - mediatek,mt8195-dpintf
> > +then:
> > +  properties:
> > +clocks:
> > +  minItems: 3
> > +  maxItems: 3
> > +clock-names:
> > +  items:
> > +- const: pixel
> > +- const: hf_fmm
> > +- const: hf_fdp
> > +else:
> > +  properties:
> > +clocks:
> > +  minItems: 3
> > +  maxItems: 3
> > +clock-names:
> > +  items:
> > +- const: pixel
> > +- const: engine
> > +- const: pll
> > +
> >  additionalProperties: false
> >  
> >  examples:
> > -- 
> > 2.33.0


Re: [PATCH v1 6/6] drm/mediatek: Add mt8195 DisplayPort driver

2021-09-09 Thread Markus Schneider-Pargmann
Hi Sam,

On Mon, Sep 06, 2021 at 10:39:21PM +0200, Sam Ravnborg wrote:
> Hi Markus,
> 
> On Mon, Sep 06, 2021 at 09:35:29PM +0200, Markus Schneider-Pargmann wrote:
> > This patch adds a DisplayPort driver for the Mediatek mt8195 SoC.
> > 
> > It supports both functional units on the mt8195, the embedded
> > DisplayPort as well as the external DisplayPort units. It offers
> > hot-plug-detection, audio up to 8 channels, and DisplayPort 1.4 with up
> > to 4 lanes.
> > 
> > This driver is based on an initial version by
> > Jason-JH.Lin .
> > 
> > Signed-off-by: Markus Schneider-Pargmann 
> > ---
> > 
> > Notes:
> > Changes RFC -> v1:
> > - Removed unused register definitions.
> > - Replaced workqueue with threaded irq.
> > - Removed connector code.
> > - Move to atomic_* drm functions.
> > - General cleanups of the code.
> > - Remove unused select GENERIC_PHY.
> > 
> >  drivers/gpu/drm/mediatek/Kconfig  |6 +
> >  drivers/gpu/drm/mediatek/Makefile |2 +
> >  drivers/gpu/drm/mediatek/mtk_dp.c | 2881 +
> >  drivers/gpu/drm/mediatek/mtk_dp_reg.h |  580 +
> >  4 files changed, 3469 insertions(+)
> >  create mode 100644 drivers/gpu/drm/mediatek/mtk_dp.c
> >  create mode 100644 drivers/gpu/drm/mediatek/mtk_dp_reg.h
> > 
> 
> 
> > +
> > +static const struct drm_bridge_funcs mtk_dp_bridge_funcs = {
> > +   .atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state,
> > +   .atomic_destroy_state = drm_atomic_helper_bridge_destroy_state,
> > +   .atomic_reset = drm_atomic_helper_bridge_reset,
> > +   .attach = mtk_dp_bridge_attach,
> > +   .detach = mtk_dp_bridge_detach,
> > +   .pre_enable = mtk_dp_bridge_pre_enable,
> Use the atomic variant here as pre_enable is deprecated.
> 
> > +   .atomic_enable = mtk_dp_bridge_atomic_enable,
> > +   .atomic_disable = mtk_dp_bridge_atomic_disable,
> > +   .post_disable = mtk_dp_bridge_post_disable,
> Use the atomic variant here as .post_disable is deprecated.

Thanks, I got rid of both pre_enable and post_disable as well now.

> 
> > +   .get_edid = mtk_dp_get_edid,
> > +   .detect = mtk_dp_bdg_detect,
> > +};
> 
> Everything else I skimmed looked fine. But it was a quick skim so..

Thanks for taking the time to have a look.

Best,
Markus


Re: [PATCH v1 6/6] drm/mediatek: Add mt8195 DisplayPort driver

2021-09-09 Thread Markus Schneider-Pargmann
Hi Philipp,

On Tue, Sep 07, 2021 at 10:47:41AM +0200, Philipp Zabel wrote:
> Hi Markus,
> 
> On Mon, 2021-09-06 at 21:35 +0200, Markus Schneider-Pargmann wrote:
> > This patch adds a DisplayPort driver for the Mediatek mt8195 SoC.
> > 
> > It supports both functional units on the mt8195, the embedded
> > DisplayPort as well as the external DisplayPort units. It offers
> > hot-plug-detection, audio up to 8 channels, and DisplayPort 1.4 with up
> > to 4 lanes.
> > 
> > This driver is based on an initial version by
> > Jason-JH.Lin .
> > 
> > Signed-off-by: Markus Schneider-Pargmann 
> > ---
> [...]
> > diff --git a/drivers/gpu/drm/mediatek/mtk_dp.c 
> > b/drivers/gpu/drm/mediatek/mtk_dp.c
> > new file mode 100644
> > index ..1bd07c8d2f69
> > --- /dev/null
> > +++ b/drivers/gpu/drm/mediatek/mtk_dp.c
> > @@ -0,0 +1,2881 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +/*
> > + * Copyright (c) 2019 MediaTek Inc.
> > + * Copyright (c) 2021 BayLibre
> > + */
> > +
> [...]
> > +#include 
> [...]
> > +#include 
> > +#include 
> [...]
> > +#include 
> > +#include 
> [...]
> > +#include 
> > +#include 
> [...]
> > +#include 
> 
> The list of included headers could be pruned a bit, from a quick look it
> seems like neither of these are actually used.

Thank you. I fixed the includes for the next version.

> 
> [...]
> > +static void mtk_dp_ssc_enable(struct mtk_dp *mtk_dp, bool enable)
> > +{
> > +   mtk_dp_update_bits(mtk_dp, MTK_DP_TOP_PWR_STATE, DP_PWR_STATE_BANDGAP,
> > +  DP_PWR_STATE_MASK);
> > +   mtk_dp_update_bits(mtk_dp, DP_PHY_DIG_PLL_CTL_1,
> > +  enable ? TPLL_SSC_EN : 0, TPLL_SSC_EN);
> > +   mtk_dp_update_bits(mtk_dp, MTK_DP_TOP_PWR_STATE,
> > +  DP_PWR_STATE_BANDGAP_TPLL_LANE, DP_PWR_STATE_MASK);
> > +
> > +   udelay(50);
> 
> Can usleep_range() be used here? Same for the other delays.

Yes, thanks, I replaced it here and everywhere else.

> 
> [...]
> > +static void mtk_dp_hpd_sink_event(struct mtk_dp *mtk_dp)
> > +{
> [...]
> > +
> > +   if (DP_GET_SINK_COUNT(sink_count) &&
> > +   (link_status[2] & DP_DOWNSTREAM_PORT_STATUS_CHANGED)) {
> > +   mtk_dp->train_info.check_cap_count = 0;
> > +   kfree(mtk_dp->edid);
> > +   mtk_dp->edid = NULL;
> 
> Should this be protect by a lock? This looks like it could race with the
> access in mtk_dp_edid_parse_audio_capabilities() or mtk_dp_get_edid()

Completely right, I guarded all edid accesses with a mutex now. Thanks.

> 
> [...]
> > +static int mtk_dp_train_handler(struct mtk_dp *mtk_dp)
> > +{
> > +   int ret = 0;
> > +
> > +   ret = mtk_dp_train_hpd_handle(mtk_dp);
> > +
> > +   if (!mtk_dp->train_info.cable_plugged_in)
> > +   return -ENODEV;
> > +
> > +   if (mtk_dp->train_state == MTK_DP_TRAIN_STATE_NORMAL)
> > +   return ret;
> > +
> > +   switch (mtk_dp->train_state) {
> [...]
> > +   case MTK_DP_TRAIN_STATE_TRAINING:
> > +   ret = mtk_dp_train_start(mtk_dp);
> > +   if (!ret) {
> > +   mtk_dp_video_mute(mtk_dp, true);
> > +   mtk_dp_audio_mute(mtk_dp, true);
> > +   mtk_dp->train_state = MTK_DP_TRAIN_STATE_CHECKTIMING;
> > +   mtk_dp_fec_enable(mtk_dp, mtk_dp->has_fec);
> > +   }  else if (ret != -EAGAIN)
> > +   mtk_dp->train_state = MTK_DP_TRAIN_STATE_DPIDLE;
> 
> A small whitespace issue and missing braces.

Thanks for spotting, fixed.

> 
> Consider running this through checkpatch.pl --strict once for style
> issues.

Thanks for the tip, I didn't know about --strict. I now added it to my
editor tooling. Interesting thing: It picked up the missing braces as
well as all the udelays, but not the extra space before else.

> 
> [...]
> > +static irqreturn_t mtk_dp_hpd_event(int hpd, void *dev)
> > +{
> > +   struct mtk_dp *mtk_dp = dev;
> > +   uint32_t irq_status;
> > +
> > +   irq_status = mtk_dp_read(mtk_dp, MTK_DP_TOP_IRQ_STATUS);
> > +
> > +   if (!irq_status)
> > +   return IRQ_HANDLED;
> 
> This check seems superfluous given that only the
> RGS_IRQ_STATUS_TRANSMITTER bit is checked right below:

Thanks, I removed it.

> 
> > +   if (irq_status & RGS_IRQ_STATUS_TRANSMITTER)
> > +   return mtk_dp_hpd_isr_handler(mtk_dp);
> > +
> > +   return IRQ_HANDLED;
> > +}
> [...]
> > +static struct edid *mtk_dp_get_edid(struct drm_bridge *bridge,
> > +   struct drm_connector *connector)
> > +{
> > +   struct mtk_dp *mtk_dp = mtk_dp_from_bridge(bridge);
> > +   bool pre_enabled = mtk_dp->pre_enabled;
> > +
> > +   if (mtk_dp->edid)
> > +   kfree(mtk_dp->edid);
> 
> Unnecessary check, kfree() accepts NULL.

Fixed.

Thank you Philipp for the review.

Best,
Markus


Re: [PATCH v1 4/6] video/hdmi: Add audio_infoframe packing for DP

2021-09-07 Thread Markus Schneider-Pargmann
Hi Sam,

On Mon, Sep 06, 2021 at 10:30:26PM +0200, Sam Ravnborg wrote:
> Hi Markus,
> 
> On Mon, Sep 06, 2021 at 09:35:27PM +0200, Markus Schneider-Pargmann wrote:
> > Similar to HDMI, DP uses audio infoframes as well which are structured
> > very similar to the HDMI ones.
> > 
> > This patch adds a helper function to pack the HDMI audio infoframe for
> > DP, called hdmi_audio_infoframe_pack_for_dp().
> > hdmi_audio_infoframe_pack_only() is split into two parts. One of them
> > packs the payload only and can be used for HDMI and DP.
> > 
> > Signed-off-by: Markus Schneider-Pargmann 
> > ---
> >  drivers/video/hdmi.c | 87 +++-
> >  include/linux/hdmi.h |  4 ++
> >  2 files changed, 73 insertions(+), 18 deletions(-)
> > 
> > diff --git a/drivers/video/hdmi.c b/drivers/video/hdmi.c
> > index 947be761dfa4..59c4341549e4 100644
> > --- a/drivers/video/hdmi.c
> > +++ b/drivers/video/hdmi.c
> > @@ -387,6 +387,28 @@ int hdmi_audio_infoframe_check(struct 
> > hdmi_audio_infoframe *frame)
> >  }
> >  EXPORT_SYMBOL(hdmi_audio_infoframe_check);
> >  
> > +static void
> > +hdmi_audio_infoframe_pack_payload(const struct hdmi_audio_infoframe *frame,
> > + u8 *buffer)
> > +{
> > +   u8 channels;
> > +
> > +   if (frame->channels >= 2)
> > +   channels = frame->channels - 1;
> > +   else
> > +   channels = 0;
> > +
> > +   buffer[0] = ((frame->coding_type & 0xf) << 4) | (channels & 0x7);
> > +   buffer[1] = ((frame->sample_frequency & 0x7) << 2) |
> > +(frame->sample_size & 0x3);
> > +   buffer[2] = frame->coding_type_ext & 0x1f;
> > +   buffer[3] = frame->channel_allocation;
> > +   buffer[4] = (frame->level_shift_value & 0xf) << 3;
> > +
> > +   if (frame->downmix_inhibit)
> > +   buffer[4] |= BIT(7);
> > +}
> > +
> >  /**
> >   * hdmi_audio_infoframe_pack_only() - write HDMI audio infoframe to binary 
> > buffer
> >   * @frame: HDMI audio infoframe
> > @@ -404,7 +426,6 @@ EXPORT_SYMBOL(hdmi_audio_infoframe_check);
> >  ssize_t hdmi_audio_infoframe_pack_only(const struct hdmi_audio_infoframe 
> > *frame,
> >void *buffer, size_t size)
> >  {
> > -   unsigned char channels;
> > u8 *ptr = buffer;
> > size_t length;
> > int ret;
> > @@ -420,28 +441,13 @@ ssize_t hdmi_audio_infoframe_pack_only(const struct 
> > hdmi_audio_infoframe *frame,
> >  
> > memset(buffer, 0, size);
> >  
> > -   if (frame->channels >= 2)
> > -   channels = frame->channels - 1;
> > -   else
> > -   channels = 0;
> > -
> > ptr[0] = frame->type;
> > ptr[1] = frame->version;
> > ptr[2] = frame->length;
> > ptr[3] = 0; /* checksum */
> >  
> > -   /* start infoframe payload */
> > -   ptr += HDMI_INFOFRAME_HEADER_SIZE;
> > -
> > -   ptr[0] = ((frame->coding_type & 0xf) << 4) | (channels & 0x7);
> > -   ptr[1] = ((frame->sample_frequency & 0x7) << 2) |
> > -(frame->sample_size & 0x3);
> > -   ptr[2] = frame->coding_type_ext & 0x1f;
> > -   ptr[3] = frame->channel_allocation;
> > -   ptr[4] = (frame->level_shift_value & 0xf) << 3;
> > -
> > -   if (frame->downmix_inhibit)
> > -   ptr[4] |= BIT(7);
> > +   hdmi_audio_infoframe_pack_payload(frame,
> > + ptr + HDMI_INFOFRAME_HEADER_SIZE);
> >  
> > hdmi_infoframe_set_checksum(buffer, length);
> >  
> > @@ -479,6 +485,51 @@ ssize_t hdmi_audio_infoframe_pack(struct 
> > hdmi_audio_infoframe *frame,
> >  }
> >  EXPORT_SYMBOL(hdmi_audio_infoframe_pack);
> >  
> > +/**
> > + * hdmi_audio_infoframe_pack_for_dp - Pack a HDMI Audio infoframe for
> > + *displayport
> > + *
> > + * @frame HDMI Audio infoframe
> > + * @header Header buffer to be used
> > + * @header_size Size of header buffer
> > + * @data Data buffer to be used
> > + * @data_size Size of data buffer
> > + * @dp_version Display Port version to be encoded in the header
> > + *
> > + * Packs a HDMI Audio Infoframe to be sent over Display Port. This function
> > + * fills both header and data buffer with the required data.
> > + *
> > + * Return: Number of total written 

Re: [PATCH v1 3/6] drm/edid: Add cea_sad helpers for freq/length

2021-09-07 Thread Markus Schneider-Pargmann
Hi Sam,

On Mon, Sep 06, 2021 at 10:19:00PM +0200, Sam Ravnborg wrote:
> Hi Markus,
> 
> On Mon, Sep 06, 2021 at 09:35:26PM +0200, Markus Schneider-Pargmann wrote:
> > This patch adds two helper functions that extract the frequency and word
> > length from a struct cea_sad.
> > 
> > For these helper functions new defines are added that help translate the
> > 'freq' and 'byte2' fields into real numbers.
> > 
> > Signed-off-by: Markus Schneider-Pargmann 
> > ---
> >  drivers/gpu/drm/drm_edid.c | 57 ++
> >  include/drm/drm_edid.h | 18 ++--
> >  2 files changed, 73 insertions(+), 2 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
> > index 81d5f2524246..2389d34ce10e 100644
> > --- a/drivers/gpu/drm/drm_edid.c
> > +++ b/drivers/gpu/drm/drm_edid.c
> > @@ -4666,6 +4666,63 @@ int drm_edid_to_speaker_allocation(struct edid 
> > *edid, u8 **sadb)
> >  }
> >  EXPORT_SYMBOL(drm_edid_to_speaker_allocation);
> >  
> > +/**
> > + * drm_cea_sad_get_sample_rate - Extract the sample rate from cea_sad
> > + * @sad: Pointer to the cea_sad struct
> > + *
> > + * Extracts the cea_sad frequency field and returns the sample rate in Hz.
> > + *
> > + * Return: Sample rate in Hz or a negative errno if parsing failed.
> > + */
> > +int drm_cea_sad_get_sample_rate(struct cea_sad *sad)
> 
> It would be nice to use const struct cea_sad *sad here.

Thanks, fixing it for the next version.

> 
> > +{
> > +   switch (sad->freq) {
> > +   case CEA_SAD_FREQ_32KHZ:
> > +   return 32000;
> > +   case CEA_SAD_FREQ_44KHZ:
> > +   return 44100;
> > +   case CEA_SAD_FREQ_48KHZ:
> > +   return 48000;
> > +   case CEA_SAD_FREQ_88KHZ:
> > +   return 88200;
> > +   case CEA_SAD_FREQ_96KHZ:
> > +   return 96000;
> > +   case CEA_SAD_FREQ_176KHZ:
> > +   return 176400;
> > +   case CEA_SAD_FREQ_192KHZ:
> > +   return 192000;
> > +   default:
> > +   return -EINVAL;
> > +   }
> > +}
> > +EXPORT_SYMBOL(drm_cea_sad_get_sample_rate);
> > +
> > +/**
> > + * drm_cea_sad_get_uncompressed_word_length - Extract word length
> > + * @sad: Pointer to the cea_sad struct
> > + *
> > + * Extracts the cea_sad byte2 field and returns the word length for an
> > + * uncompressed stream.
> > + *
> > + * Note: This function may only be called for uncompressed audio.
> Can you check or this and WARN (or drm_WARN) if this is not the case?

Good idea, I added a check, a DRM_WARN and return -EINVAL now.

Thanks,
Markus

> 
> > + *
> > + * Return: Word length in bits or a negative errno if parsing failed.
> > + */
> > +int drm_cea_sad_get_uncompressed_word_length(struct cea_sad *sad)
> Again, consider to use const.
> 
>   Sam
> 
> > +{
> > +   switch (sad->byte2) {
> > +   case CEA_SAD_UNCOMPRESSED_WORD_16BIT:
> > +   return 16;
> > +   case CEA_SAD_UNCOMPRESSED_WORD_20BIT:
> > +   return 20;
> > +   case CEA_SAD_UNCOMPRESSED_WORD_24BIT:
> > +   return 24;
> > +   default:
> > +   return -EINVAL;
> > +   }
> > +}
> > +EXPORT_SYMBOL(drm_cea_sad_get_uncompressed_word_length);
> > +
> >  /**
> >   * drm_av_sync_delay - compute the HDMI/DP sink audio-video sync delay
> >   * @connector: connector associated with the HDMI/DP sink
> > diff --git a/include/drm/drm_edid.h b/include/drm/drm_edid.h
> > index 759328a5eeb2..bed091a749ef 100644
> > --- a/include/drm/drm_edid.h
> > +++ b/include/drm/drm_edid.h
> > @@ -361,12 +361,24 @@ struct edid {
> >  
> >  /* Short Audio Descriptor */
> >  struct cea_sad {
> > -   u8 format;
> > +   u8 format; /* See HDMI_AUDIO_CODING_TYPE_* */
> > u8 channels; /* max number of channels - 1 */
> > -   u8 freq;
> > +   u8 freq; /* See CEA_SAD_FREQ_* */
> > u8 byte2; /* meaning depends on format */
> >  };
> >  
> > +#define CEA_SAD_FREQ_32KHZ  BIT(0)
> > +#define CEA_SAD_FREQ_44KHZ  BIT(1)
> > +#define CEA_SAD_FREQ_48KHZ  BIT(2)
> > +#define CEA_SAD_FREQ_88KHZ  BIT(3)
> > +#define CEA_SAD_FREQ_96KHZ  BIT(4)
> > +#define CEA_SAD_FREQ_176KHZ BIT(5)
> > +#define CEA_SAD_FREQ_192KHZ BIT(6)
> > +
> > +#define CEA_SAD_UNCOMPRESSED_WORD_16BIT BIT(0)
> > +#define CEA_SAD_UNCOMPRESSED_WORD_20BIT BIT(1)
> > +#define CEA_SAD_UNCOMPRESSED_WORD_24BIT BIT(2)
> > +
> >  struct drm_encoder;
> >  struct drm_connector;
> >  struct drm_connector_state;
> > @@ -374,6 +386,8 @@ struct drm_display_mode;
> >  
> >  int drm_edid_to_sad(struct edid *edid, struct cea_sad **sads);
> >  int drm_edid_to_speaker_allocation(struct edid *edid, u8 **sadb);
> > +int drm_cea_sad_get_sample_rate(struct cea_sad *sad);
> > +int drm_cea_sad_get_uncompressed_word_length(struct cea_sad *sad);
> >  int drm_av_sync_delay(struct drm_connector *connector,
> >   const struct drm_display_mode *mode);
> >  
> > -- 
> > 2.33.0


[PATCH v1 6/6] drm/mediatek: Add mt8195 DisplayPort driver

2021-09-06 Thread Markus Schneider-Pargmann
This patch adds a DisplayPort driver for the Mediatek mt8195 SoC.

It supports both functional units on the mt8195, the embedded
DisplayPort as well as the external DisplayPort units. It offers
hot-plug-detection, audio up to 8 channels, and DisplayPort 1.4 with up
to 4 lanes.

This driver is based on an initial version by
Jason-JH.Lin .

Signed-off-by: Markus Schneider-Pargmann 
---

Notes:
Changes RFC -> v1:
- Removed unused register definitions.
- Replaced workqueue with threaded irq.
- Removed connector code.
- Move to atomic_* drm functions.
- General cleanups of the code.
- Remove unused select GENERIC_PHY.

 drivers/gpu/drm/mediatek/Kconfig  |6 +
 drivers/gpu/drm/mediatek/Makefile |2 +
 drivers/gpu/drm/mediatek/mtk_dp.c | 2881 +
 drivers/gpu/drm/mediatek/mtk_dp_reg.h |  580 +
 4 files changed, 3469 insertions(+)
 create mode 100644 drivers/gpu/drm/mediatek/mtk_dp.c
 create mode 100644 drivers/gpu/drm/mediatek/mtk_dp_reg.h

diff --git a/drivers/gpu/drm/mediatek/Kconfig b/drivers/gpu/drm/mediatek/Kconfig
index 2976d21e9a34..6d6a5b5872f2 100644
--- a/drivers/gpu/drm/mediatek/Kconfig
+++ b/drivers/gpu/drm/mediatek/Kconfig
@@ -28,3 +28,9 @@ config DRM_MEDIATEK_HDMI
select PHY_MTK_HDMI
help
  DRM/KMS HDMI driver for Mediatek SoCs
+
+config MTK_DPTX_SUPPORT
+   tristate "DRM DPTX Support for Mediatek SoCs"
+   depends on DRM_MEDIATEK
+   help
+ DRM/KMS Display Port driver for Mediatek SoCs.
diff --git a/drivers/gpu/drm/mediatek/Makefile 
b/drivers/gpu/drm/mediatek/Makefile
index 3abd27d7c91d..ba6e2228bbf8 100644
--- a/drivers/gpu/drm/mediatek/Makefile
+++ b/drivers/gpu/drm/mediatek/Makefile
@@ -25,3 +25,5 @@ mediatek-drm-hdmi-objs := mtk_cec.o \
  mtk_hdmi_ddc.o
 
 obj-$(CONFIG_DRM_MEDIATEK_HDMI) += mediatek-drm-hdmi.o
+
+obj-$(CONFIG_MTK_DPTX_SUPPORT) += mtk_dp.o
diff --git a/drivers/gpu/drm/mediatek/mtk_dp.c 
b/drivers/gpu/drm/mediatek/mtk_dp.c
new file mode 100644
index ..1bd07c8d2f69
--- /dev/null
+++ b/drivers/gpu/drm/mediatek/mtk_dp.c
@@ -0,0 +1,2881 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2019 MediaTek Inc.
+ * Copyright (c) 2021 BayLibre
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "mtk_dp_reg.h"
+
+#define MTK_DP_AUX_WAIT_REPLY_COUNT2
+#define MTK_DP_CHECK_SINK_CAP_TIMEOUT_COUNT3
+
+#define MTK_DP_MAX_LANES   4
+#define MTK_DP_MAX_LINK_RATE   MTK_DP_LINKRATE_HBR3
+
+#define MTK_DP_TBC_BUF_READ_START_ADDR 0x08
+
+#define MTK_DP_TRAIN_RETRY_LIMIT   8
+#define MTK_DP_TRAIN_MAX_ITERATIONS5
+
+#define MTK_DP_AUX_WRITE_READ_WAIT_TIME_US 20
+
+#define MTK_DP_DP_VERSION_11   0x11
+
+enum mtk_dp_state {
+   MTK_DP_STATE_INITIAL,
+   MTK_DP_STATE_IDLE,
+   MTK_DP_STATE_PREPARE,
+   MTK_DP_STATE_NORMAL,
+};
+
+enum mtk_dp_train_state {
+   MTK_DP_TRAIN_STATE_STARTUP = 0,
+   MTK_DP_TRAIN_STATE_CHECKCAP,
+   MTK_DP_TRAIN_STATE_CHECKEDID,
+   MTK_DP_TRAIN_STATE_TRAINING_PRE,
+   MTK_DP_TRAIN_STATE_TRAINING,
+   MTK_DP_TRAIN_STATE_CHECKTIMING,
+   MTK_DP_TRAIN_STATE_NORMAL,
+   MTK_DP_TRAIN_STATE_POWERSAVE,
+   MTK_DP_TRAIN_STATE_DPIDLE,
+};
+
+struct mtk_dp_timings {
+   struct videomode vm;
+
+   u16 htotal;
+   u16 vtotal;
+   u8 frame_rate;
+   u32 pix_rate_khz;
+};
+
+struct mtk_dp_train_info {
+   bool tps3;
+   bool tps4;
+   bool sink_ssc;
+   bool cable_plugged_in;
+   bool cable_state_change;
+   bool cr_done;
+   bool eq_done;
+
+   // link_rate is in multiple of 0.27Gbps
+   int link_rate;
+   int lane_count;
+
+   int irq_status;
+   int check_cap_count;
+};
+
+// Same values as used by the DP Spec for MISC0 bits 1 and 2
+enum mtk_dp_color_format {
+   MTK_DP_COLOR_FORMAT_RGB_444 = 0,
+   MTK_DP_COLOR_FORMAT_YUV_422 = 1,
+   MTK_DP_COLOR_FORMAT_YUV_444 = 2,
+   MTK_DP_COLOR_FORMAT_YUV_420 = 3,
+   MTK_DP_COLOR_FORMAT_YONLY   = 4,
+   MTK_DP_COLOR_FORMAT_RAW = 5,
+   MTK_DP_COLOR_FORMAT_RESERVED= 6,
+   MTK_DP_COLOR_FORMAT_DEFAULT = MTK_DP_COLOR_FORMAT_RGB_444,
+   MTK_DP_COLOR_FORMAT_UNKNOWN = 15,
+};
+
+// Multiple of 0.27Gbps
+enum mtk_dp_linkrate {
+   MTK_DP_LINKRATE_RBR =  0x6,
+   MTK_DP_LINKRATE_HBR =  0xA,
+   MTK_DP_LINKRATE_HBR2= 0x14,
+   MTK_DP_LINKRATE_HBR25   = 0x19,
+   MTK_DP_LINKRATE_HBR3= 0x1E,
+};
+
+// Same val

[PATCH v1 2/6] dt-bindings: mediatek,dp: Add Display Port binding

2021-09-06 Thread Markus Schneider-Pargmann
This controller is present on different mediatek hardware. Currently
mt8195 and mt8395 have this controller without a functional difference,
so only one compatible is added.

The controller can be in two forms, for a normal display port and for
embedded display port.

Signed-off-by: Markus Schneider-Pargmann 
---

Notes:
I added the mediatek maintainers in the list of maintainers as I wasn't sure
whom I should put there. Please let me know if I am supposed to add my mail
there.

 .../display/mediatek/mediatek,dp.yaml | 89 +++
 1 file changed, 89 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/display/mediatek/mediatek,dp.yaml

diff --git 
a/Documentation/devicetree/bindings/display/mediatek/mediatek,dp.yaml 
b/Documentation/devicetree/bindings/display/mediatek/mediatek,dp.yaml
new file mode 100644
index ..f7a35962c23b
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,dp.yaml
@@ -0,0 +1,89 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/mediatek/mediatek,dp.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Mediatek Display Port Controller
+
+maintainers:
+  - CK Hu 
+  - Jitao shi 
+
+description: |
+  Device tree bindings for the Mediatek (embedded) Display Port controller
+  present on some Mediatek SoCs.
+
+properties:
+  compatible:
+enum:
+  - mediatek,mt8195-edp_tx
+  - mediatek,mt8195-dp_tx
+
+  reg:
+maxItems: 1
+
+  interrupts:
+maxItems: 1
+
+  clocks:
+items:
+  - description: faxi clock
+
+  clock-names:
+items:
+  - const: faxi
+
+  power-domains:
+maxItems: 1
+
+  ports:
+$ref: /schemas/graph.yaml#/properties/ports
+properties:
+  port@0:
+$ref: /schemas/graph.yaml#/properties/port
+description: Input endpoint of the controller, usually dp_intf
+
+  port@1:
+$ref: /schemas/graph.yaml#/properties/port
+description: Output endpoint of the controller
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - ports
+
+additionalProperties: false
+
+examples:
+  - |
+#include 
+#include 
+dp_tx: edp_tx@1c50 {
+compatible = "mediatek,mt8195-edp_tx";
+reg = <0 0x1c50 0 0x8000>;
+interrupts = ;
+power-domains = < MT8195_POWER_DOMAIN_EPD_TX>;
+pinctrl-names = "default";
+pinctrl-0 = <_pin>;
+status = "okay";
+
+ports {
+#address-cells = <1>;
+#size-cells = <0>;
+
+port@0 {
+reg = <0>;
+edp_in: endpoint {
+remote-endpoint = <_intf0_out>;
+};
+};
+port@1 {
+reg = <1>;
+edp_out: endpoint {
+   remote-endpoint = <_in>;
+};
+};
+};
+};
-- 
2.33.0



[PATCH v1 1/6] dt-bindings: mediatek,dpi: Add mt8195 dpintf

2021-09-06 Thread Markus Schneider-Pargmann
DP_INTF is similar to the actual dpi. They differ in some points
regarding registers and what needs to be set but the function blocks
itself are similar in design.

Signed-off-by: Markus Schneider-Pargmann 
---
 .../display/mediatek/mediatek,dpi.yaml| 43 ---
 1 file changed, 37 insertions(+), 6 deletions(-)

diff --git 
a/Documentation/devicetree/bindings/display/mediatek/mediatek,dpi.yaml 
b/Documentation/devicetree/bindings/display/mediatek/mediatek,dpi.yaml
index dd2896a40ff0..1a158b719ce6 100644
--- a/Documentation/devicetree/bindings/display/mediatek/mediatek,dpi.yaml
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,dpi.yaml
@@ -4,7 +4,7 @@
 $id: http://devicetree.org/schemas/display/mediatek/mediatek,dpi.yaml#
 $schema: http://devicetree.org/meta-schemas/core.yaml#
 
-title: mediatek DPI Controller Device Tree Bindings
+title: mediatek DPI/DP_INTF Controller Device Tree Bindings
 
 maintainers:
   - CK Hu 
@@ -13,7 +13,8 @@ maintainers:
 description: |
   The Mediatek DPI function block is a sink of the display subsystem and
   provides 8-bit RGB/YUV444 or 8/10/10-bit YUV422 pixel data on a parallel
-  output bus.
+  output bus. The Mediatek DP_INTF is a similar function block that is
+  connected to the (embedded) display port function block.
 
 properties:
   compatible:
@@ -23,6 +24,7 @@ properties:
   - mediatek,mt8173-dpi
   - mediatek,mt8183-dpi
   - mediatek,mt8192-dpi
+  - mediatek,mt8195-dpintf
 
   reg:
 maxItems: 1
@@ -37,10 +39,11 @@ properties:
   - description: DPI PLL
 
   clock-names:
-items:
-  - const: pixel
-  - const: engine
-  - const: pll
+description:
+  For dpi clocks pixel, engine and pll are required. For dpintf pixel,
+  hf_fmm and hf_fdp are required.
+minItems: 3
+maxItems: 3
 
   pinctrl-0: true
   pinctrl-1: true
@@ -64,6 +67,34 @@ required:
   - clock-names
   - port
 
+allOf:
+  - if:
+  properties:
+compatible:
+  contains:
+enum:
+  - mediatek,mt8195-dpintf
+then:
+  properties:
+clocks:
+  minItems: 3
+  maxItems: 3
+clock-names:
+  items:
+- const: pixel
+- const: hf_fmm
+- const: hf_fdp
+else:
+  properties:
+clocks:
+  minItems: 3
+  maxItems: 3
+clock-names:
+  items:
+- const: pixel
+- const: engine
+- const: pll
+
 additionalProperties: false
 
 examples:
-- 
2.33.0



[PATCH v1 5/6] drm/mediatek: dpi: Add dpintf support

2021-09-06 Thread Markus Schneider-Pargmann
dpintf is the displayport interface hardware unit. This unit is similar
to dpi and can reuse most of the code.

This patch adds support for mt8195-dpintf to this dpi driver. Main
differences are:
 - Some features/functional components are not available for dpintf
   which are now excluded from code execution once is_dpintf is set
 - dpintf can and needs to choose between different clockdividers based
   on the clockspeed. This is done by choosing a different clock parent.
 - There are two additional clocks that need to be managed. These are
   only set for dpintf and will be set to NULL if not supplied. The
   clk_* calls handle these as normal clocks then.
 - Some register contents differ slightly between the two components. To
   work around this I added register bits/masks with a DPINTF_ prefix
   and use them where different.

Based on a separate driver for dpintf created by
Jason-JH.Lin .

Signed-off-by: Markus Schneider-Pargmann 
---

Notes:
Changes RFC -> v1:
- Remove setting parents and fully rely on the clock tree instead which 
already
  models a mux at the important place.
- Integrated mtk_dpi dpintf changes into the mediatek drm driver.

 drivers/gpu/drm/mediatek/mtk_dpi.c  | 248 
 drivers/gpu/drm/mediatek/mtk_dpi_regs.h |  12 +
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c |   4 +
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h |   1 +
 drivers/gpu/drm/mediatek/mtk_drm_drv.c  |   3 +
 5 files changed, 217 insertions(+), 51 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c 
b/drivers/gpu/drm/mediatek/mtk_dpi.c
index e94738fe4db8..986c7f72483f 100644
--- a/drivers/gpu/drm/mediatek/mtk_dpi.c
+++ b/drivers/gpu/drm/mediatek/mtk_dpi.c
@@ -71,6 +71,8 @@ struct mtk_dpi {
void __iomem *regs;
struct device *dev;
struct clk *engine_clk;
+   struct clk *hf_fmm_clk;
+   struct clk *hf_fdp_clk;
struct clk *pixel_clk;
struct clk *tvd_clk;
int irq;
@@ -125,6 +127,7 @@ struct mtk_dpi_conf {
bool edge_sel_en;
const u32 *output_fmts;
u32 num_output_fmts;
+   bool is_dpintf;
 };
 
 static void mtk_dpi_mask(struct mtk_dpi *dpi, u32 offset, u32 val, u32 mask)
@@ -153,30 +156,52 @@ static void mtk_dpi_disable(struct mtk_dpi *dpi)
 static void mtk_dpi_config_hsync(struct mtk_dpi *dpi,
 struct mtk_dpi_sync_param *sync)
 {
-   mtk_dpi_mask(dpi, DPI_TGEN_HWIDTH,
-sync->sync_width << HPW, HPW_MASK);
-   mtk_dpi_mask(dpi, DPI_TGEN_HPORCH,
-sync->back_porch << HBP, HBP_MASK);
-   mtk_dpi_mask(dpi, DPI_TGEN_HPORCH, sync->front_porch << HFP,
-HFP_MASK);
+   if (dpi->conf->is_dpintf) {
+   mtk_dpi_mask(dpi, DPI_TGEN_HWIDTH,
+sync->sync_width << HPW, DPINTF_HPW_MASK);
+   mtk_dpi_mask(dpi, DPI_TGEN_HPORCH,
+sync->back_porch << HBP, DPINTF_HBP_MASK);
+   mtk_dpi_mask(dpi, DPI_TGEN_HPORCH, sync->front_porch << HFP,
+DPINTF_HFP_MASK);
+   } else {
+   mtk_dpi_mask(dpi, DPI_TGEN_HWIDTH,
+sync->sync_width << HPW, HPW_MASK);
+   mtk_dpi_mask(dpi, DPI_TGEN_HPORCH,
+sync->back_porch << HBP, HBP_MASK);
+   mtk_dpi_mask(dpi, DPI_TGEN_HPORCH, sync->front_porch << HFP,
+HFP_MASK);
+   }
 }
 
 static void mtk_dpi_config_vsync(struct mtk_dpi *dpi,
 struct mtk_dpi_sync_param *sync,
 u32 width_addr, u32 porch_addr)
 {
-   mtk_dpi_mask(dpi, width_addr,
-sync->sync_width << VSYNC_WIDTH_SHIFT,
-VSYNC_WIDTH_MASK);
mtk_dpi_mask(dpi, width_addr,
 sync->shift_half_line << VSYNC_HALF_LINE_SHIFT,
 VSYNC_HALF_LINE_MASK);
-   mtk_dpi_mask(dpi, porch_addr,
-sync->back_porch << VSYNC_BACK_PORCH_SHIFT,
-VSYNC_BACK_PORCH_MASK);
-   mtk_dpi_mask(dpi, porch_addr,
-sync->front_porch << VSYNC_FRONT_PORCH_SHIFT,
-VSYNC_FRONT_PORCH_MASK);
+
+   if (dpi->conf->is_dpintf) {
+   mtk_dpi_mask(dpi, width_addr,
+sync->sync_width << VSYNC_WIDTH_SHIFT,
+DPINTF_VSYNC_WIDTH_MASK);
+   mtk_dpi_mask(dpi, porch_addr,
+sync->back_porch << VSYNC_BACK_PORCH_SHIFT,
+DPINTF_VSYNC_BACK_PORCH_MASK);
+   mtk_dpi_mask(dpi, porch_addr,
+sync->front_porch << VSYNC_FRONT_PORCH_SHIFT,
+DP

[PATCH v1 3/6] drm/edid: Add cea_sad helpers for freq/length

2021-09-06 Thread Markus Schneider-Pargmann
This patch adds two helper functions that extract the frequency and word
length from a struct cea_sad.

For these helper functions new defines are added that help translate the
'freq' and 'byte2' fields into real numbers.

Signed-off-by: Markus Schneider-Pargmann 
---
 drivers/gpu/drm/drm_edid.c | 57 ++
 include/drm/drm_edid.h | 18 ++--
 2 files changed, 73 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index 81d5f2524246..2389d34ce10e 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -4666,6 +4666,63 @@ int drm_edid_to_speaker_allocation(struct edid *edid, u8 
**sadb)
 }
 EXPORT_SYMBOL(drm_edid_to_speaker_allocation);
 
+/**
+ * drm_cea_sad_get_sample_rate - Extract the sample rate from cea_sad
+ * @sad: Pointer to the cea_sad struct
+ *
+ * Extracts the cea_sad frequency field and returns the sample rate in Hz.
+ *
+ * Return: Sample rate in Hz or a negative errno if parsing failed.
+ */
+int drm_cea_sad_get_sample_rate(struct cea_sad *sad)
+{
+   switch (sad->freq) {
+   case CEA_SAD_FREQ_32KHZ:
+   return 32000;
+   case CEA_SAD_FREQ_44KHZ:
+   return 44100;
+   case CEA_SAD_FREQ_48KHZ:
+   return 48000;
+   case CEA_SAD_FREQ_88KHZ:
+   return 88200;
+   case CEA_SAD_FREQ_96KHZ:
+   return 96000;
+   case CEA_SAD_FREQ_176KHZ:
+   return 176400;
+   case CEA_SAD_FREQ_192KHZ:
+   return 192000;
+   default:
+   return -EINVAL;
+   }
+}
+EXPORT_SYMBOL(drm_cea_sad_get_sample_rate);
+
+/**
+ * drm_cea_sad_get_uncompressed_word_length - Extract word length
+ * @sad: Pointer to the cea_sad struct
+ *
+ * Extracts the cea_sad byte2 field and returns the word length for an
+ * uncompressed stream.
+ *
+ * Note: This function may only be called for uncompressed audio.
+ *
+ * Return: Word length in bits or a negative errno if parsing failed.
+ */
+int drm_cea_sad_get_uncompressed_word_length(struct cea_sad *sad)
+{
+   switch (sad->byte2) {
+   case CEA_SAD_UNCOMPRESSED_WORD_16BIT:
+   return 16;
+   case CEA_SAD_UNCOMPRESSED_WORD_20BIT:
+   return 20;
+   case CEA_SAD_UNCOMPRESSED_WORD_24BIT:
+   return 24;
+   default:
+   return -EINVAL;
+   }
+}
+EXPORT_SYMBOL(drm_cea_sad_get_uncompressed_word_length);
+
 /**
  * drm_av_sync_delay - compute the HDMI/DP sink audio-video sync delay
  * @connector: connector associated with the HDMI/DP sink
diff --git a/include/drm/drm_edid.h b/include/drm/drm_edid.h
index 759328a5eeb2..bed091a749ef 100644
--- a/include/drm/drm_edid.h
+++ b/include/drm/drm_edid.h
@@ -361,12 +361,24 @@ struct edid {
 
 /* Short Audio Descriptor */
 struct cea_sad {
-   u8 format;
+   u8 format; /* See HDMI_AUDIO_CODING_TYPE_* */
u8 channels; /* max number of channels - 1 */
-   u8 freq;
+   u8 freq; /* See CEA_SAD_FREQ_* */
u8 byte2; /* meaning depends on format */
 };
 
+#define CEA_SAD_FREQ_32KHZ  BIT(0)
+#define CEA_SAD_FREQ_44KHZ  BIT(1)
+#define CEA_SAD_FREQ_48KHZ  BIT(2)
+#define CEA_SAD_FREQ_88KHZ  BIT(3)
+#define CEA_SAD_FREQ_96KHZ  BIT(4)
+#define CEA_SAD_FREQ_176KHZ BIT(5)
+#define CEA_SAD_FREQ_192KHZ BIT(6)
+
+#define CEA_SAD_UNCOMPRESSED_WORD_16BIT BIT(0)
+#define CEA_SAD_UNCOMPRESSED_WORD_20BIT BIT(1)
+#define CEA_SAD_UNCOMPRESSED_WORD_24BIT BIT(2)
+
 struct drm_encoder;
 struct drm_connector;
 struct drm_connector_state;
@@ -374,6 +386,8 @@ struct drm_display_mode;
 
 int drm_edid_to_sad(struct edid *edid, struct cea_sad **sads);
 int drm_edid_to_speaker_allocation(struct edid *edid, u8 **sadb);
+int drm_cea_sad_get_sample_rate(struct cea_sad *sad);
+int drm_cea_sad_get_uncompressed_word_length(struct cea_sad *sad);
 int drm_av_sync_delay(struct drm_connector *connector,
  const struct drm_display_mode *mode);
 
-- 
2.33.0



[PATCH v1 4/6] video/hdmi: Add audio_infoframe packing for DP

2021-09-06 Thread Markus Schneider-Pargmann
Similar to HDMI, DP uses audio infoframes as well which are structured
very similar to the HDMI ones.

This patch adds a helper function to pack the HDMI audio infoframe for
DP, called hdmi_audio_infoframe_pack_for_dp().
hdmi_audio_infoframe_pack_only() is split into two parts. One of them
packs the payload only and can be used for HDMI and DP.

Signed-off-by: Markus Schneider-Pargmann 
---
 drivers/video/hdmi.c | 87 +++-
 include/linux/hdmi.h |  4 ++
 2 files changed, 73 insertions(+), 18 deletions(-)

diff --git a/drivers/video/hdmi.c b/drivers/video/hdmi.c
index 947be761dfa4..59c4341549e4 100644
--- a/drivers/video/hdmi.c
+++ b/drivers/video/hdmi.c
@@ -387,6 +387,28 @@ int hdmi_audio_infoframe_check(struct hdmi_audio_infoframe 
*frame)
 }
 EXPORT_SYMBOL(hdmi_audio_infoframe_check);
 
+static void
+hdmi_audio_infoframe_pack_payload(const struct hdmi_audio_infoframe *frame,
+ u8 *buffer)
+{
+   u8 channels;
+
+   if (frame->channels >= 2)
+   channels = frame->channels - 1;
+   else
+   channels = 0;
+
+   buffer[0] = ((frame->coding_type & 0xf) << 4) | (channels & 0x7);
+   buffer[1] = ((frame->sample_frequency & 0x7) << 2) |
+(frame->sample_size & 0x3);
+   buffer[2] = frame->coding_type_ext & 0x1f;
+   buffer[3] = frame->channel_allocation;
+   buffer[4] = (frame->level_shift_value & 0xf) << 3;
+
+   if (frame->downmix_inhibit)
+   buffer[4] |= BIT(7);
+}
+
 /**
  * hdmi_audio_infoframe_pack_only() - write HDMI audio infoframe to binary 
buffer
  * @frame: HDMI audio infoframe
@@ -404,7 +426,6 @@ EXPORT_SYMBOL(hdmi_audio_infoframe_check);
 ssize_t hdmi_audio_infoframe_pack_only(const struct hdmi_audio_infoframe 
*frame,
   void *buffer, size_t size)
 {
-   unsigned char channels;
u8 *ptr = buffer;
size_t length;
int ret;
@@ -420,28 +441,13 @@ ssize_t hdmi_audio_infoframe_pack_only(const struct 
hdmi_audio_infoframe *frame,
 
memset(buffer, 0, size);
 
-   if (frame->channels >= 2)
-   channels = frame->channels - 1;
-   else
-   channels = 0;
-
ptr[0] = frame->type;
ptr[1] = frame->version;
ptr[2] = frame->length;
ptr[3] = 0; /* checksum */
 
-   /* start infoframe payload */
-   ptr += HDMI_INFOFRAME_HEADER_SIZE;
-
-   ptr[0] = ((frame->coding_type & 0xf) << 4) | (channels & 0x7);
-   ptr[1] = ((frame->sample_frequency & 0x7) << 2) |
-(frame->sample_size & 0x3);
-   ptr[2] = frame->coding_type_ext & 0x1f;
-   ptr[3] = frame->channel_allocation;
-   ptr[4] = (frame->level_shift_value & 0xf) << 3;
-
-   if (frame->downmix_inhibit)
-   ptr[4] |= BIT(7);
+   hdmi_audio_infoframe_pack_payload(frame,
+ ptr + HDMI_INFOFRAME_HEADER_SIZE);
 
hdmi_infoframe_set_checksum(buffer, length);
 
@@ -479,6 +485,51 @@ ssize_t hdmi_audio_infoframe_pack(struct 
hdmi_audio_infoframe *frame,
 }
 EXPORT_SYMBOL(hdmi_audio_infoframe_pack);
 
+/**
+ * hdmi_audio_infoframe_pack_for_dp - Pack a HDMI Audio infoframe for
+ *displayport
+ *
+ * @frame HDMI Audio infoframe
+ * @header Header buffer to be used
+ * @header_size Size of header buffer
+ * @data Data buffer to be used
+ * @data_size Size of data buffer
+ * @dp_version Display Port version to be encoded in the header
+ *
+ * Packs a HDMI Audio Infoframe to be sent over Display Port. This function
+ * fills both header and data buffer with the required data.
+ *
+ * Return: Number of total written bytes or a negative errno on failure.
+ */
+ssize_t hdmi_audio_infoframe_pack_for_dp(struct hdmi_audio_infoframe *frame,
+void *header, size_t header_size,
+void *data, size_t data_size,
+u8 dp_version)
+{
+   int ret;
+   u8 *hdr_ptr = header;
+
+   ret = hdmi_audio_infoframe_check(frame);
+   if (ret)
+   return ret;
+
+   if (header_size < 4 || data_size < frame->length)
+   return -ENOSPC;
+
+   memset(header, 0, header_size);
+   memset(data, 0, data_size);
+
+   // Secondary-data packet header
+   hdr_ptr[1] = frame->type;
+   hdr_ptr[2] = 0x1B;  // As documented by DP spec for Secondary-data 
Packets
+   hdr_ptr[3] = (dp_version & 0x3f) << 2;
+
+   hdmi_audio_infoframe_pack_payload(frame, data);
+
+   return frame->length + 4;
+}
+EXPORT_SYMBOL(hdmi_audio_infoframe_pack_for_dp);
+
 /**
  * hdmi_vendor_infoframe_init() - initialize an HDMI vendor infoframe
  * @f

[PATCH v1 0/6] drm/mediatek: Add mt8195 DisplayPort driver

2021-09-06 Thread Markus Schneider-Pargmann
Hi everyone,

this series is built around the DisplayPort driver. The dpi/dpintf driver and
the added helper functions are required for the DisplayPort driver to work.

It is version 1 of the patch series following the RFC version:
https://lore.kernel.org/linux-mediatek/20210816192523.1739365-1-...@baylibre.com/

Note: This patch series is currently tested on v5.10 and I am currently working
on testing it on v5.14.

The series is now based on these patch series and its dependencies:
- Add Mediatek Soc DRM (vdosys0) support for mt8195
  
https://lore.kernel.org/linux-mediatek/20210825144833.7757-1-jason-jh@mediatek.com/
- Add MediaTek SoC DRM (vdosys1) support for mt8195
  
https://lore.kernel.org/linux-mediatek/20210825100531.5653-1-nancy@mediatek.com/

Changes in v1:
- Added DP binding documentation.
- Addressed feedback from the RFC.
- General cleanups in DPI and DP drivers.
- See individual patches for details on the changes done.

Thanks in advance for any feedback and comments.

Best,
Markus


Markus Schneider-Pargmann (6):
  dt-bindings: mediatek,dpi: Add mt8195 dpintf
  dt-bindings: mediatek,dp: Add Display Port binding
  drm/edid: Add cea_sad helpers for freq/length
  video/hdmi: Add audio_infoframe packing for DP
  drm/mediatek: dpi: Add dpintf support
  drm/mediatek: Add mt8195 DisplayPort driver

 .../display/mediatek/mediatek,dp.yaml |   89 +
 .../display/mediatek/mediatek,dpi.yaml|   43 +-
 drivers/gpu/drm/drm_edid.c|   57 +
 drivers/gpu/drm/mediatek/Kconfig  |6 +
 drivers/gpu/drm/mediatek/Makefile |2 +
 drivers/gpu/drm/mediatek/mtk_dp.c | 2881 +
 drivers/gpu/drm/mediatek/mtk_dp_reg.h |  580 
 drivers/gpu/drm/mediatek/mtk_dpi.c|  248 +-
 drivers/gpu/drm/mediatek/mtk_dpi_regs.h   |   12 +
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c   |4 +
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h   |1 +
 drivers/gpu/drm/mediatek/mtk_drm_drv.c|3 +
 drivers/video/hdmi.c  |   87 +-
 include/drm/drm_edid.h|   18 +-
 include/linux/hdmi.h  |4 +
 15 files changed, 3958 insertions(+), 77 deletions(-)
 create mode 100644 
Documentation/devicetree/bindings/display/mediatek/mediatek,dp.yaml
 create mode 100644 drivers/gpu/drm/mediatek/mtk_dp.c
 create mode 100644 drivers/gpu/drm/mediatek/mtk_dp_reg.h

-- 
2.33.0



Re: [RFC PATCH 1/5] dt-bindings: mediatek,dpi: Add mt8195 dpintf

2021-08-18 Thread Markus Schneider-Pargmann
Hi,

On Wed, Aug 18, 2021 at 12:45:46PM +0800, CK Hu wrote:
> Hi, Markus:
> 
> On Mon, 2021-08-16 at 21:25 +0200, Markus Schneider-Pargmann wrote:
> > DP_INTF is similar to the actual dpi. They differ in some points
> > regarding registers and what needs to be set but the function blocks
> > itself are similar in design.
> > 
> > Signed-off-by: Markus Schneider-Pargmann 
> > ---
> >  .../display/mediatek/mediatek,dpi.yaml| 48 ---
> >  1 file changed, 42 insertions(+), 6 deletions(-)
> > 
> > diff --git 
> > a/Documentation/devicetree/bindings/display/mediatek/mediatek,dpi.yaml 
> > b/Documentation/devicetree/bindings/display/mediatek/mediatek,dpi.yaml
> > index dd2896a40ff0..de4bdacd83ac 100644
> > --- a/Documentation/devicetree/bindings/display/mediatek/mediatek,dpi.yaml
> > +++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,dpi.yaml
> > @@ -4,7 +4,7 @@
> >  $id: 
> > https://urldefense.com/v3/__http://devicetree.org/schemas/display/mediatek/mediatek,dpi.yaml*__;Iw!!CTRNKA9wMg0ARbw!z5TyPvbq3ZLHjRPscOHigUMlikjhtJMFrEQqemcjQZa4NaXBE9tzMnDFMa1qYg$
> >  
> >  $schema: 
> > https://urldefense.com/v3/__http://devicetree.org/meta-schemas/core.yaml*__;Iw!!CTRNKA9wMg0ARbw!z5TyPvbq3ZLHjRPscOHigUMlikjhtJMFrEQqemcjQZa4NaXBE9tzMnAjuBCxsg$
> >  
> > 
> > -title: mediatek DPI Controller Device Tree Bindings
> > +title: mediatek DPI/DP_INTF Controller Device Tree Bindings
> >  
> >  maintainers:
> >- CK Hu 
> > @@ -13,7 +13,8 @@ maintainers:
> >  description: |
> >The Mediatek DPI function block is a sink of the display subsystem and
> >provides 8-bit RGB/YUV444 or 8/10/10-bit YUV422 pixel data on a parallel
> > -  output bus.
> > +  output bus. The Mediatek DP_INTF is a similar function block that is
> > +  connected to the (embedded) display port function block.
> >  
> >  properties:
> >compatible:
> > @@ -23,6 +24,7 @@ properties:
> >- mediatek,mt8173-dpi
> >- mediatek,mt8183-dpi
> >- mediatek,mt8192-dpi
> > +  - mediatek,mt8195-dpintf
> 
> I've reviewed the modification in driver, it seems that dpintf is almost
> the same as dpi. Why use the name "dpintf"? I could accept this name
> only it's defined by hardware data sheet.

Yes the data sheet makes a distinction between DPI and DP_INTF. mt8195
has a DPI unit as well. DP_INTF has a slightly different feature set and
also uses slightly different register bits.

Best,
Markus

> 
> Regards,
> CK
> 
> >  
> >reg:
> >  maxItems: 1
> > @@ -37,10 +39,11 @@ properties:
> >- description: DPI PLL
> >  
> >clock-names:
> > -items:
> > -  - const: pixel
> > -  - const: engine
> > -  - const: pll
> > +description:
> > +  For dpi clocks pixel, engine and pll are required. For dpintf pixel, 
> > pll,
> > +  pll_d2, pll_d4, pll_d8, pll_d16, hf_fmm, hf_fdp are required.
> > +minItems: 3
> > +maxItems: 8
> >  
> >pinctrl-0: true
> >pinctrl-1: true
> > @@ -64,6 +67,39 @@ required:
> >- clock-names
> >- port
> >  
> > +allOf:
> > +  - if:
> > +  properties:
> > +compatible:
> > +  contains:
> > +enum:
> > +  - mediatek,mt8195-dpintf
> > +then:
> > +  properties:
> > +clocks:
> > +  minItems: 8
> > +  maxItems: 8
> > +clock-names:
> > +  items:
> > +- const: pixel
> > +- const: pll
> > +- const: pll_d2
> > +- const: pll_d4
> > +- const: pll_d8
> > +- const: pll_d16
> > +- const: hf_fmm
> > +- const: hf_fdp
> > +else:
> > +  properties:
> > +clocks:
> > +  minItems: 3
> > +  maxItems: 3
> > +clock-names:
> > +  items:
> > +- const: pixel
> > +- const: engine
> > +- const: pll
> > +
> >  additionalProperties: false
> >  
> >  examples:
> 


Re: [RFC PATCH 2/5] drm/mediatek: dpi: Add dpintf support

2021-08-18 Thread Markus Schneider-Pargmann
Hi,

On Tue, Aug 17, 2021 at 05:50:44PM +0800, CK Hu wrote:
> Hi, Markus:
> 
> On Mon, 2021-08-16 at 21:25 +0200, Markus Schneider-Pargmann wrote:
> > dpintf is the displayport interface hardware unit. This unit is similar
> > to dpi and can reuse most of the code.
> > 
> > This patch adds support for mt8195-dpintf to this dpi driver. Main
> > differences are:
> >  - Some features/functional components are not available for dpintf
> >which are now excluded from code execution once is_dpintf is set
> >  - dpintf can and needs to choose between different clockdividers based
> >on the clockspeed. This is done by choosing a different clock parent.
> >  - There are two additional clocks that need to be managed. These are
> >only set for dpintf and will be set to NULL if not supplied. The
> >clk_* calls handle these as normal clocks then.
> >  - Some register contents differ slightly between the two components. To
> >work around this I added register bits/masks with a DPINTF_ prefix
> >and use them where different.
> > 
> > Based on a separate driver for dpintf created by
> > Jason-JH.Lin .
> > 
> > Signed-off-by: Markus Schneider-Pargmann 
> > ---
> >  drivers/gpu/drm/mediatek/mtk_dpi.c  | 282 
> >  drivers/gpu/drm/mediatek/mtk_dpi_regs.h |  12 +
> >  2 files changed, 247 insertions(+), 47 deletions(-)
> > 
> 
> [snip]
> 
> >  
> > +static void mtk_dpi_set_pixel_clk_parent(struct mtk_dpi *dpi,
> > +unsigned int factor)
> > +{
> > +   struct clk *new_parent;
> > +
> > +   switch (factor) {
> > +   case 16:
> > +   new_parent = dpi->tvd_clks[MTK_DPI_TVDPLL_D16].clk;
> > +   break;
> > +   case 8:
> > +   new_parent = dpi->tvd_clks[MTK_DPI_TVDPLL_D8].clk;
> > +   break;
> > +   case 4:
> > +   new_parent = dpi->tvd_clks[MTK_DPI_TVDPLL_D4].clk;
> > +   break;
> > +   case 2:
> > +   new_parent = dpi->tvd_clks[MTK_DPI_TVDPLL_D2].clk;
> > +   break;
> > +   default:
> > +   new_parent = NULL;
> > +   }
> > +   if (new_parent)
> > +   clk_set_parent(dpi->pixel_clk, new_parent);
> 
> I prefer that dpi->pixel_clk provide set_rate() interface, and let clock
> driver to control the parent of dpi->pixel_clk.

Good point, will do that, thanks.

Best,
Markus

> 
> Regards,
> CK
> 
> > +}
> > +
> >  static int mtk_dpi_set_display_mode(struct mtk_dpi *dpi,
> > struct drm_display_mode *mode)
> >  {
> > @@ -465,6 +568,8 @@ static int mtk_dpi_set_display_mode(struct mtk_dpi *dpi,
> > drm_display_mode_to_videomode(mode, );
> > pll_rate = vm.pixelclock * factor;
> >  
> > +   mtk_dpi_set_pixel_clk_parent(dpi, factor);
> > +
> > dev_dbg(dpi->dev, "Want PLL %lu Hz, pixel clock %lu Hz\n",
> > pll_rate, vm.pixelclock);
> >  
> 
> 


Re: [RFC PATCH 5/5] drm/mediatek: Add mt8195 DisplayPort driver

2021-08-17 Thread Markus Schneider-Pargmann
Hi,

On Tue, Aug 17, 2021 at 01:36:45PM +0800, CK Hu wrote:
> Hi, Markus:
> 
> On Mon, 2021-08-16 at 21:25 +0200, Markus Schneider-Pargmann wrote:
> > This patch adds a DisplayPort driver for the Mediatek mt8195 SoC.
> > 
> > It supports both functional units on the mt8195, the embedded
> > DisplayPort as well as the external DisplayPort units. It offers
> > hot-plug-detection, audio up to 8 channels, and DisplayPort 1.4 with up
> > to 4 lanes.
> > 
> > This driver is based on an initial version by
> > Jason-JH.Lin .
> > 
> > Signed-off-by: Markus Schneider-Pargmann 
> > ---
> 
> [snip]
> 
> > +
> > +static const struct of_device_id mtk_dp_of_match[] = {
> > +   {
> > +   .compatible = "mediatek,mt8195-dp_tx",
> 
> Where is the binding document of "mediatek,mt8195-dp_tx"?
> 
> > +   .data = _dp_driver_data,
> > +   },
> > +   {
> > +   .compatible = "mediatek,mt8195-edp_tx",
> 
> Where is the binding document of "mediatek,mt8195-edp_tx"?

I didn't include the bindings in this RFC, but will include them in the
next version.

> 
> > +   .data = _edp_driver_data,
> > +   },
> > +   {},
> > +};
> > +MODULE_DEVICE_TABLE(of, mtk_dp_of_match);
> > +
> > +struct platform_driver mtk_dp_driver = {
> > +   .probe = mtk_dp_probe,
> > +   .remove = mtk_dp_remove,
> > +   .driver = {
> > +   .name = "mediatek-drm-dp",
> > +   .of_match_table = mtk_dp_of_match,
> > +   .pm = _dp_pm_ops,
> > +   },
> > +};
> > +
> > diff --git a/drivers/gpu/drm/mediatek/mtk_dp_reg.h 
> > b/drivers/gpu/drm/mediatek/mtk_dp_reg.h
> > new file mode 100644
> > index ..83afc79d98ff
> > --- /dev/null
> > +++ b/drivers/gpu/drm/mediatek/mtk_dp_reg.h
> > @@ -0,0 +1,3095 @@
> > +/* SPDX-License-Identifier: GPL-2.0 */
> > +/*
> > + * Copyright (c) 2019 MediaTek Inc.
> > + * Copyright (c) 2021 BayLibre
> > + */
> > +#ifndef _MTK_DP_REG_H_
> > +#define _MTK_DP_REG_H_
> > +
> > +#define MTK_DP_SIP_CONTROL_AARCH32 0x82000523
> > +# define MTK_DP_SIP_ATF_VIDEO_UNMUTE 0x20
> > +# define MTK_DP_SIP_ATF_EDP_VIDEO_UNMUTE 0x21
> > +# define MTK_DP_SIP_ATF_REG_WRITE 0x22
> > +# define MTK_DP_SIP_ATF_REG_READ 0x23
> > +# define MTK_DP_SIP_ATF_CMD_COUNT 0x24
> > +
> > +#define TOP_OFFSET 0x2000
> > +#define ENC0_OFFSET0x3000
> > +#define ENC1_OFFSET0x3200
> > +#define TRANS_OFFSET   0x3400
> > +#define AUX_OFFSET 0x3600
> > +#define SEC_OFFSET 0x4000
> > +
> > +#define MTK_DP_HPD_DISCONNECT  BIT(1)
> > +#define MTK_DP_HPD_CONNECT BIT(2)
> > +#define MTK_DP_HPD_INTERRUPT   BIT(3)
> > +
> > +#define MTK_DP_ENC0_P0_3000  (ENC0_OFFSET + 0x000)
> > +# define LANE_NUM_DP_ENC0_P0_MASK  0x3
> > +# define LANE_NUM_DP_ENC0_P0_SHIFT 0
> > +# define VIDEO_MUTE_SW_DP_ENC0_P0_MASK 0x4
> > +# define VIDEO_MUTE_SW_DP_ENC0_P0_SHIFT2
> > +# define VIDEO_MUTE_SEL_DP_ENC0_P0_MASK0x8
> > +# define VIDEO_MUTE_SEL_DP_ENC0_P0_SHIFT   3
> > +# define ENHANCED_FRAME_EN_DP_ENC0_P0_MASK 0x10
> > +# define ENHANCED_FRAME_EN_DP_ENC0_P0_SHIFT4
> > +# define HDCP_FRAME_EN_DP_ENC0_P0_MASK 0x20
> > +# define HDCP_FRAME_EN_DP_ENC0_P0_SHIFT5
> > +# define IDP_EN_DP_ENC0_P0_MASK0x40
> 
> Remove useless definition.

Ok, will do. Thanks for the feedback.

Best,
Markus

> 
> Regards,
> CK.
> 
> > +# define IDP_EN_DP_ENC0_P0_SHIFT   6
> > +# define BS_SYMBOL_CNT_RESET_DP_ENC0_P0_MASK   0x80
> > +# define BS_SYMBOL_CNT_RESET_DP_ENC0_P0_SHIFT  7
> > +# define MIXER_DUMMY_DATA_DP_ENC0_P0_MASK  
> > 0xff00
> > +# define MIXER_DUMMY_DATA_DP_ENC0_P0_SHIFT 8
> > +
> 
> > +
> > +#endif /*_MTK_DP_REG_H_*/
> 


Re: [RFC PATCH 5/5] drm/mediatek: Add mt8195 DisplayPort driver

2021-08-17 Thread Markus Schneider-Pargmann
Hi Sam,

On Mon, Aug 16, 2021 at 11:36:13PM +0200, Sam Ravnborg wrote:
> Hi Markus,
> 
> A few general things in the following. This is what I look for first in
> a bridge driver - and I had no time today to review the driver in full.
> Please address these, then cc: me on next revision where I hopefully
> have more time.

Thanks for taking the time and giving me the tips, will fix it and send
a new version.

Best,
Markus

> 
>   Sam
> 
> > +static int mtk_dp_bridge_attach(struct drm_bridge *bridge,
> > +   enum drm_bridge_attach_flags flags)
> > +{
> > +   struct mtk_dp *mtk_dp = mtk_dp_from_bridge(bridge);
> > +   int ret;
> > +
> > +   mtk_dp_poweron(mtk_dp);
> > +
> > +   if (mtk_dp->next_bridge) {
> > +   ret = drm_bridge_attach(bridge->encoder, 
> > mtk_dp->next_bridge,
> > +   _dp->bridge, flags);
> > +   if (ret) {
> > +   drm_warn(mtk_dp->drm_dev,
> > +"Failed to attach external bridge: %d\n", 
> > ret);
> > +   return ret;
> > +   }
> > +   }
> > +
> > +   if (flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR) {
> > +   drm_err(mtk_dp->drm_dev,
> > +   "Fix bridge driver to make connector optional!");
> > +   return 0;
> > +   }
> 
> This driver is only used by mediatek, and I thought all of mediatek is
> converted so the display driver creates the connector.
> 
> It would be better to migrate mediatek over to always let the display
> driver create the connector and drop the connector support in this
> driver.
> 
> 
> > + struct drm_bridge_funcs mtk_dp_bridge_funcs = {
> > +   .attach = mtk_dp_bridge_attach,
> > +   .mode_fixup = mtk_dp_bridge_mode_fixup,
> > +   .disable = mtk_dp_bridge_disable,
> > +   .post_disable = mtk_dp_bridge_post_disable,
> > +   .mode_set = mtk_dp_bridge_mode_set,
> > +   .pre_enable = mtk_dp_bridge_pre_enable,
> > +   .enable = mtk_dp_bridge_enable,
> > +   .get_edid = mtk_get_edid,
> > +   .detect = mtk_dp_bdg_detect,
> > +};
> 
> 
> For new drivers please avoid the recently deprecated functions.
> 
> - Use the atomic versions of pre_enable, enable, disable and post_disable.
> 
> - Merge mode_set with atomic_enable - as there is no need for the mode_Set
>   operation.
> 
> - Use atomic_check in favour of mode_fixup, albeit the rules for
>   atomic_check is at best vauge at the moment.
>  
> 


[RFC PATCH 4/5] video/hdmi: Add audio_infoframe packing for DP

2021-08-16 Thread Markus Schneider-Pargmann
Similar to HDMI, DP uses audio infoframes as well which are structured
very similar to the HDMI ones.

This patch adds a helper function to pack the HDMI audio infoframe for
DP, called hdmi_audio_infoframe_pack_for_dp().
hdmi_audio_infoframe_pack_only() is split into two parts. One of them
packs the payload only and can be used for HDMI and DP.

Signed-off-by: Markus Schneider-Pargmann 
---
 drivers/video/hdmi.c | 87 +++-
 include/linux/hdmi.h |  4 ++
 2 files changed, 73 insertions(+), 18 deletions(-)

diff --git a/drivers/video/hdmi.c b/drivers/video/hdmi.c
index 947be761dfa4..59c4341549e4 100644
--- a/drivers/video/hdmi.c
+++ b/drivers/video/hdmi.c
@@ -387,6 +387,28 @@ int hdmi_audio_infoframe_check(struct hdmi_audio_infoframe 
*frame)
 }
 EXPORT_SYMBOL(hdmi_audio_infoframe_check);
 
+static void
+hdmi_audio_infoframe_pack_payload(const struct hdmi_audio_infoframe *frame,
+ u8 *buffer)
+{
+   u8 channels;
+
+   if (frame->channels >= 2)
+   channels = frame->channels - 1;
+   else
+   channels = 0;
+
+   buffer[0] = ((frame->coding_type & 0xf) << 4) | (channels & 0x7);
+   buffer[1] = ((frame->sample_frequency & 0x7) << 2) |
+(frame->sample_size & 0x3);
+   buffer[2] = frame->coding_type_ext & 0x1f;
+   buffer[3] = frame->channel_allocation;
+   buffer[4] = (frame->level_shift_value & 0xf) << 3;
+
+   if (frame->downmix_inhibit)
+   buffer[4] |= BIT(7);
+}
+
 /**
  * hdmi_audio_infoframe_pack_only() - write HDMI audio infoframe to binary 
buffer
  * @frame: HDMI audio infoframe
@@ -404,7 +426,6 @@ EXPORT_SYMBOL(hdmi_audio_infoframe_check);
 ssize_t hdmi_audio_infoframe_pack_only(const struct hdmi_audio_infoframe 
*frame,
   void *buffer, size_t size)
 {
-   unsigned char channels;
u8 *ptr = buffer;
size_t length;
int ret;
@@ -420,28 +441,13 @@ ssize_t hdmi_audio_infoframe_pack_only(const struct 
hdmi_audio_infoframe *frame,
 
memset(buffer, 0, size);
 
-   if (frame->channels >= 2)
-   channels = frame->channels - 1;
-   else
-   channels = 0;
-
ptr[0] = frame->type;
ptr[1] = frame->version;
ptr[2] = frame->length;
ptr[3] = 0; /* checksum */
 
-   /* start infoframe payload */
-   ptr += HDMI_INFOFRAME_HEADER_SIZE;
-
-   ptr[0] = ((frame->coding_type & 0xf) << 4) | (channels & 0x7);
-   ptr[1] = ((frame->sample_frequency & 0x7) << 2) |
-(frame->sample_size & 0x3);
-   ptr[2] = frame->coding_type_ext & 0x1f;
-   ptr[3] = frame->channel_allocation;
-   ptr[4] = (frame->level_shift_value & 0xf) << 3;
-
-   if (frame->downmix_inhibit)
-   ptr[4] |= BIT(7);
+   hdmi_audio_infoframe_pack_payload(frame,
+ ptr + HDMI_INFOFRAME_HEADER_SIZE);
 
hdmi_infoframe_set_checksum(buffer, length);
 
@@ -479,6 +485,51 @@ ssize_t hdmi_audio_infoframe_pack(struct 
hdmi_audio_infoframe *frame,
 }
 EXPORT_SYMBOL(hdmi_audio_infoframe_pack);
 
+/**
+ * hdmi_audio_infoframe_pack_for_dp - Pack a HDMI Audio infoframe for
+ *displayport
+ *
+ * @frame HDMI Audio infoframe
+ * @header Header buffer to be used
+ * @header_size Size of header buffer
+ * @data Data buffer to be used
+ * @data_size Size of data buffer
+ * @dp_version Display Port version to be encoded in the header
+ *
+ * Packs a HDMI Audio Infoframe to be sent over Display Port. This function
+ * fills both header and data buffer with the required data.
+ *
+ * Return: Number of total written bytes or a negative errno on failure.
+ */
+ssize_t hdmi_audio_infoframe_pack_for_dp(struct hdmi_audio_infoframe *frame,
+void *header, size_t header_size,
+void *data, size_t data_size,
+u8 dp_version)
+{
+   int ret;
+   u8 *hdr_ptr = header;
+
+   ret = hdmi_audio_infoframe_check(frame);
+   if (ret)
+   return ret;
+
+   if (header_size < 4 || data_size < frame->length)
+   return -ENOSPC;
+
+   memset(header, 0, header_size);
+   memset(data, 0, data_size);
+
+   // Secondary-data packet header
+   hdr_ptr[1] = frame->type;
+   hdr_ptr[2] = 0x1B;  // As documented by DP spec for Secondary-data 
Packets
+   hdr_ptr[3] = (dp_version & 0x3f) << 2;
+
+   hdmi_audio_infoframe_pack_payload(frame, data);
+
+   return frame->length + 4;
+}
+EXPORT_SYMBOL(hdmi_audio_infoframe_pack_for_dp);
+
 /**
  * hdmi_vendor_infoframe_init() - initialize an HDMI vendor infoframe
  * @f

[RFC PATCH 2/5] drm/mediatek: dpi: Add dpintf support

2021-08-16 Thread Markus Schneider-Pargmann
dpintf is the displayport interface hardware unit. This unit is similar
to dpi and can reuse most of the code.

This patch adds support for mt8195-dpintf to this dpi driver. Main
differences are:
 - Some features/functional components are not available for dpintf
   which are now excluded from code execution once is_dpintf is set
 - dpintf can and needs to choose between different clockdividers based
   on the clockspeed. This is done by choosing a different clock parent.
 - There are two additional clocks that need to be managed. These are
   only set for dpintf and will be set to NULL if not supplied. The
   clk_* calls handle these as normal clocks then.
 - Some register contents differ slightly between the two components. To
   work around this I added register bits/masks with a DPINTF_ prefix
   and use them where different.

Based on a separate driver for dpintf created by
Jason-JH.Lin .

Signed-off-by: Markus Schneider-Pargmann 
---
 drivers/gpu/drm/mediatek/mtk_dpi.c  | 282 
 drivers/gpu/drm/mediatek/mtk_dpi_regs.h |  12 +
 2 files changed, 247 insertions(+), 47 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c 
b/drivers/gpu/drm/mediatek/mtk_dpi.c
index bced555648b0..4ad6d1fc6bde 100644
--- a/drivers/gpu/drm/mediatek/mtk_dpi.c
+++ b/drivers/gpu/drm/mediatek/mtk_dpi.c
@@ -63,6 +63,14 @@ enum mtk_dpi_out_color_format {
MTK_DPI_COLOR_FORMAT_YCBCR_422_FULL
 };
 
+enum mtk_dpi_tvdpll_clk {
+   MTK_DPI_TVDPLL_D2 = 0,
+   MTK_DPI_TVDPLL_D4 = 1,
+   MTK_DPI_TVDPLL_D8 = 2,
+   MTK_DPI_TVDPLL_D16 = 3,
+   MTK_DPI_TVDPLL_NUM_CLKS = 4
+};
+
 struct mtk_dpi {
struct drm_encoder encoder;
struct drm_bridge bridge;
@@ -71,8 +79,11 @@ struct mtk_dpi {
void __iomem *regs;
struct device *dev;
struct clk *engine_clk;
+   struct clk *hf_fmm_clk;
+   struct clk *hf_fdp_clk;
struct clk *pixel_clk;
struct clk *tvd_clk;
+   struct clk_bulk_data tvd_clks[MTK_DPI_TVDPLL_NUM_CLKS];
int irq;
struct drm_display_mode mode;
const struct mtk_dpi_conf *conf;
@@ -125,6 +136,7 @@ struct mtk_dpi_conf {
bool edge_sel_en;
const u32 *output_fmts;
u32 num_output_fmts;
+   bool is_dpintf;
 };
 
 static void mtk_dpi_mask(struct mtk_dpi *dpi, u32 offset, u32 val, u32 mask)
@@ -153,30 +165,52 @@ static void mtk_dpi_disable(struct mtk_dpi *dpi)
 static void mtk_dpi_config_hsync(struct mtk_dpi *dpi,
 struct mtk_dpi_sync_param *sync)
 {
-   mtk_dpi_mask(dpi, DPI_TGEN_HWIDTH,
-sync->sync_width << HPW, HPW_MASK);
-   mtk_dpi_mask(dpi, DPI_TGEN_HPORCH,
-sync->back_porch << HBP, HBP_MASK);
-   mtk_dpi_mask(dpi, DPI_TGEN_HPORCH, sync->front_porch << HFP,
-HFP_MASK);
+   if (dpi->conf->is_dpintf) {
+   mtk_dpi_mask(dpi, DPI_TGEN_HWIDTH,
+sync->sync_width << HPW, DPINTF_HPW_MASK);
+   mtk_dpi_mask(dpi, DPI_TGEN_HPORCH,
+sync->back_porch << HBP, DPINTF_HBP_MASK);
+   mtk_dpi_mask(dpi, DPI_TGEN_HPORCH, sync->front_porch << HFP,
+DPINTF_HFP_MASK);
+   } else {
+   mtk_dpi_mask(dpi, DPI_TGEN_HWIDTH,
+sync->sync_width << HPW, HPW_MASK);
+   mtk_dpi_mask(dpi, DPI_TGEN_HPORCH,
+sync->back_porch << HBP, HBP_MASK);
+   mtk_dpi_mask(dpi, DPI_TGEN_HPORCH, sync->front_porch << HFP,
+HFP_MASK);
+   }
 }
 
 static void mtk_dpi_config_vsync(struct mtk_dpi *dpi,
 struct mtk_dpi_sync_param *sync,
 u32 width_addr, u32 porch_addr)
 {
-   mtk_dpi_mask(dpi, width_addr,
-sync->sync_width << VSYNC_WIDTH_SHIFT,
-VSYNC_WIDTH_MASK);
mtk_dpi_mask(dpi, width_addr,
 sync->shift_half_line << VSYNC_HALF_LINE_SHIFT,
 VSYNC_HALF_LINE_MASK);
-   mtk_dpi_mask(dpi, porch_addr,
-sync->back_porch << VSYNC_BACK_PORCH_SHIFT,
-VSYNC_BACK_PORCH_MASK);
-   mtk_dpi_mask(dpi, porch_addr,
-sync->front_porch << VSYNC_FRONT_PORCH_SHIFT,
-VSYNC_FRONT_PORCH_MASK);
+
+   if (dpi->conf->is_dpintf) {
+   mtk_dpi_mask(dpi, width_addr,
+sync->sync_width << VSYNC_WIDTH_SHIFT,
+DPINTF_VSYNC_WIDTH_MASK);
+   mtk_dpi_mask(dpi, porch_addr,
+sync->back_porch << VSYNC_BACK_PORCH_SHIFT,
+DPINTF_VSYNC_BACK_PORCH_MASK);
+   mtk_dpi_mask(dpi

[RFC PATCH 1/5] dt-bindings: mediatek,dpi: Add mt8195 dpintf

2021-08-16 Thread Markus Schneider-Pargmann
DP_INTF is similar to the actual dpi. They differ in some points
regarding registers and what needs to be set but the function blocks
itself are similar in design.

Signed-off-by: Markus Schneider-Pargmann 
---
 .../display/mediatek/mediatek,dpi.yaml| 48 ---
 1 file changed, 42 insertions(+), 6 deletions(-)

diff --git 
a/Documentation/devicetree/bindings/display/mediatek/mediatek,dpi.yaml 
b/Documentation/devicetree/bindings/display/mediatek/mediatek,dpi.yaml
index dd2896a40ff0..de4bdacd83ac 100644
--- a/Documentation/devicetree/bindings/display/mediatek/mediatek,dpi.yaml
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,dpi.yaml
@@ -4,7 +4,7 @@
 $id: http://devicetree.org/schemas/display/mediatek/mediatek,dpi.yaml#
 $schema: http://devicetree.org/meta-schemas/core.yaml#
 
-title: mediatek DPI Controller Device Tree Bindings
+title: mediatek DPI/DP_INTF Controller Device Tree Bindings
 
 maintainers:
   - CK Hu 
@@ -13,7 +13,8 @@ maintainers:
 description: |
   The Mediatek DPI function block is a sink of the display subsystem and
   provides 8-bit RGB/YUV444 or 8/10/10-bit YUV422 pixel data on a parallel
-  output bus.
+  output bus. The Mediatek DP_INTF is a similar function block that is
+  connected to the (embedded) display port function block.
 
 properties:
   compatible:
@@ -23,6 +24,7 @@ properties:
   - mediatek,mt8173-dpi
   - mediatek,mt8183-dpi
   - mediatek,mt8192-dpi
+  - mediatek,mt8195-dpintf
 
   reg:
 maxItems: 1
@@ -37,10 +39,11 @@ properties:
   - description: DPI PLL
 
   clock-names:
-items:
-  - const: pixel
-  - const: engine
-  - const: pll
+description:
+  For dpi clocks pixel, engine and pll are required. For dpintf pixel, pll,
+  pll_d2, pll_d4, pll_d8, pll_d16, hf_fmm, hf_fdp are required.
+minItems: 3
+maxItems: 8
 
   pinctrl-0: true
   pinctrl-1: true
@@ -64,6 +67,39 @@ required:
   - clock-names
   - port
 
+allOf:
+  - if:
+  properties:
+compatible:
+  contains:
+enum:
+  - mediatek,mt8195-dpintf
+then:
+  properties:
+clocks:
+  minItems: 8
+  maxItems: 8
+clock-names:
+  items:
+- const: pixel
+- const: pll
+- const: pll_d2
+- const: pll_d4
+- const: pll_d8
+- const: pll_d16
+- const: hf_fmm
+- const: hf_fdp
+else:
+  properties:
+clocks:
+  minItems: 3
+  maxItems: 3
+clock-names:
+  items:
+- const: pixel
+- const: engine
+- const: pll
+
 additionalProperties: false
 
 examples:
-- 
2.32.0



[RFC PATCH 3/5] drm/edid: Add cea_sad helpers for freq/length

2021-08-16 Thread Markus Schneider-Pargmann
This patch adds two helper functions that extract the frequency and word
length from a struct cea_sad.

For these helper functions new defines are added that help translate the
'freq' and 'byte2' fields into real numbers.

Signed-off-by: Markus Schneider-Pargmann 
---
 drivers/gpu/drm/drm_edid.c | 57 ++
 include/drm/drm_edid.h | 18 ++--
 2 files changed, 73 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index 81d5f2524246..2389d34ce10e 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -4666,6 +4666,63 @@ int drm_edid_to_speaker_allocation(struct edid *edid, u8 
**sadb)
 }
 EXPORT_SYMBOL(drm_edid_to_speaker_allocation);
 
+/**
+ * drm_cea_sad_get_sample_rate - Extract the sample rate from cea_sad
+ * @sad: Pointer to the cea_sad struct
+ *
+ * Extracts the cea_sad frequency field and returns the sample rate in Hz.
+ *
+ * Return: Sample rate in Hz or a negative errno if parsing failed.
+ */
+int drm_cea_sad_get_sample_rate(struct cea_sad *sad)
+{
+   switch (sad->freq) {
+   case CEA_SAD_FREQ_32KHZ:
+   return 32000;
+   case CEA_SAD_FREQ_44KHZ:
+   return 44100;
+   case CEA_SAD_FREQ_48KHZ:
+   return 48000;
+   case CEA_SAD_FREQ_88KHZ:
+   return 88200;
+   case CEA_SAD_FREQ_96KHZ:
+   return 96000;
+   case CEA_SAD_FREQ_176KHZ:
+   return 176400;
+   case CEA_SAD_FREQ_192KHZ:
+   return 192000;
+   default:
+   return -EINVAL;
+   }
+}
+EXPORT_SYMBOL(drm_cea_sad_get_sample_rate);
+
+/**
+ * drm_cea_sad_get_uncompressed_word_length - Extract word length
+ * @sad: Pointer to the cea_sad struct
+ *
+ * Extracts the cea_sad byte2 field and returns the word length for an
+ * uncompressed stream.
+ *
+ * Note: This function may only be called for uncompressed audio.
+ *
+ * Return: Word length in bits or a negative errno if parsing failed.
+ */
+int drm_cea_sad_get_uncompressed_word_length(struct cea_sad *sad)
+{
+   switch (sad->byte2) {
+   case CEA_SAD_UNCOMPRESSED_WORD_16BIT:
+   return 16;
+   case CEA_SAD_UNCOMPRESSED_WORD_20BIT:
+   return 20;
+   case CEA_SAD_UNCOMPRESSED_WORD_24BIT:
+   return 24;
+   default:
+   return -EINVAL;
+   }
+}
+EXPORT_SYMBOL(drm_cea_sad_get_uncompressed_word_length);
+
 /**
  * drm_av_sync_delay - compute the HDMI/DP sink audio-video sync delay
  * @connector: connector associated with the HDMI/DP sink
diff --git a/include/drm/drm_edid.h b/include/drm/drm_edid.h
index 759328a5eeb2..bed091a749ef 100644
--- a/include/drm/drm_edid.h
+++ b/include/drm/drm_edid.h
@@ -361,12 +361,24 @@ struct edid {
 
 /* Short Audio Descriptor */
 struct cea_sad {
-   u8 format;
+   u8 format; /* See HDMI_AUDIO_CODING_TYPE_* */
u8 channels; /* max number of channels - 1 */
-   u8 freq;
+   u8 freq; /* See CEA_SAD_FREQ_* */
u8 byte2; /* meaning depends on format */
 };
 
+#define CEA_SAD_FREQ_32KHZ  BIT(0)
+#define CEA_SAD_FREQ_44KHZ  BIT(1)
+#define CEA_SAD_FREQ_48KHZ  BIT(2)
+#define CEA_SAD_FREQ_88KHZ  BIT(3)
+#define CEA_SAD_FREQ_96KHZ  BIT(4)
+#define CEA_SAD_FREQ_176KHZ BIT(5)
+#define CEA_SAD_FREQ_192KHZ BIT(6)
+
+#define CEA_SAD_UNCOMPRESSED_WORD_16BIT BIT(0)
+#define CEA_SAD_UNCOMPRESSED_WORD_20BIT BIT(1)
+#define CEA_SAD_UNCOMPRESSED_WORD_24BIT BIT(2)
+
 struct drm_encoder;
 struct drm_connector;
 struct drm_connector_state;
@@ -374,6 +386,8 @@ struct drm_display_mode;
 
 int drm_edid_to_sad(struct edid *edid, struct cea_sad **sads);
 int drm_edid_to_speaker_allocation(struct edid *edid, u8 **sadb);
+int drm_cea_sad_get_sample_rate(struct cea_sad *sad);
+int drm_cea_sad_get_uncompressed_word_length(struct cea_sad *sad);
 int drm_av_sync_delay(struct drm_connector *connector,
  const struct drm_display_mode *mode);
 
-- 
2.32.0



[RFC PATCH 0/5] drm/mediatek: Add mt8195 DisplayPort driver

2021-08-16 Thread Markus Schneider-Pargmann
Hi everyone,

this series is built around the DisplayPort driver. The dpi/dpintf driver and
the added helper functions are required for the DisplayPort.

Note that this is an RFC. I would like to have your opinion on the driver and
what needs to change. The driver itself has its rough edges that I am currently
still working on, especially the training and powerup/down need some work in
my opinion. Also the code compiles without an issue but is not fully tested
yet.

However I already wanted to reach out for some feedback to see what can and
should be improved. I am happy about every comment, thanks for taking the
time.

The series is currently based on v5.14-rc5 but it requires other patches to
actually work on mt8195 (clock, etc.). A binding documentation is not included
yet.

Thanks,
Markus

Markus Schneider-Pargmann (5):
  dt-bindings: mediatek,dpi: Add mt8195 dpintf
  drm/mediatek: dpi: Add dpintf support
  drm/edid: Add cea_sad helpers for freq/length
  video/hdmi: Add audio_infoframe packing for DP
  drm/mediatek: Add mt8195 DisplayPort driver

 .../display/mediatek/mediatek,dpi.yaml|   48 +-
 drivers/gpu/drm/drm_edid.c|   57 +
 drivers/gpu/drm/mediatek/Kconfig  |7 +
 drivers/gpu/drm/mediatek/Makefile |2 +
 drivers/gpu/drm/mediatek/mtk_dp.c | 3025 
 drivers/gpu/drm/mediatek/mtk_dp_reg.h | 3095 +
 drivers/gpu/drm/mediatek/mtk_dpi.c|  282 +-
 drivers/gpu/drm/mediatek/mtk_dpi_regs.h   |   12 +
 drivers/video/hdmi.c  |   87 +-
 include/drm/drm_edid.h|   18 +-
 include/linux/hdmi.h  |4 +
 11 files changed, 6564 insertions(+), 73 deletions(-)
 create mode 100644 drivers/gpu/drm/mediatek/mtk_dp.c
 create mode 100644 drivers/gpu/drm/mediatek/mtk_dp_reg.h

-- 
2.32.0