diff --git a/patch/kernel/archive/meson-5.15/m8-m8b-m8m2-Support-HDMI.patch b/patch/kernel/archive/meson-5.15/m8-m8b-m8m2-Support-HDMI.patch index 74de18e20..2339ee514 100644 --- a/patch/kernel/archive/meson-5.15/m8-m8b-m8m2-Support-HDMI.patch +++ b/patch/kernel/archive/meson-5.15/m8-m8b-m8m2-Support-HDMI.patch @@ -14,7 +14,6 @@ Special thank. arch/arm/boot/dts/meson8m2.dtsi | 4 + drivers/clk/meson/meson8b.c | 163 +- drivers/clk/meson/meson8b.h | 26 +- - drivers/gpu/drm/bridge/display-connector.c | 86 + drivers/gpu/drm/meson/Kconfig | 8 + drivers/gpu/drm/meson/Makefile | 3 +- drivers/gpu/drm/meson/meson_drv.c | 290 ++- @@ -28,13 +27,13 @@ Special thank. drivers/gpu/drm/meson/meson_vclk.c | 146 ++ drivers/gpu/drm/meson/meson_venc.c | 45 +- drivers/gpu/drm/meson/meson_venc_cvbs.c | 293 --- - drivers/gpu/drm/meson/meson_viu.c | 38 +- + drivers/gpu/drm/meson/meson_viu.c | 18 +- drivers/phy/amlogic/Kconfig | 20 + drivers/phy/amlogic/Makefile | 2 + drivers/phy/amlogic/phy-meson-cvbs-dac.c | 310 ++++ drivers/phy/amlogic/phy-meson8-hdmi-tx.c | 160 ++ include/dt-bindings/clock/meson8b-clkc.h | 10 + - 29 files changed, 4203 insertions(+), 476 deletions(-) + 28 files changed, 4101 insertions(+), 472 deletions(-) create mode 100644 Documentation/devicetree/bindings/phy/amlogic,meson-cvbs-dac-phy.yaml create mode 100644 Documentation/devicetree/bindings/phy/amlogic,meson8-hdmi-tx-phy.yaml create mode 100644 drivers/gpu/drm/meson/meson_encoder_cvbs.c @@ -751,7 +750,7 @@ index 6725dd9fd825..fcb2ad976098 100644 compatible = "amlogic,meson8m2-wdt", "amlogic,meson8b-wdt"; }; diff --git a/drivers/clk/meson/meson8b.c b/drivers/clk/meson/meson8b.c -index a844d35b553a..cd0f5bae24d4 100644 +index 809a0bfb670d..12e9b6618dbb 100644 --- a/drivers/clk/meson/meson8b.c +++ b/drivers/clk/meson/meson8b.c @@ -118,6 +118,56 @@ static struct clk_regmap meson8b_fixed_pll = { @@ -1308,114 +1307,6 @@ index b1a5074cf148..ce62ed47cbfc 100644 /* * include the CLKID and RESETID that have -diff --git a/drivers/gpu/drm/bridge/display-connector.c b/drivers/gpu/drm/bridge/display-connector.c -index 847a0dce7f1d..d24f5b90feab 100644 ---- a/drivers/gpu/drm/bridge/display-connector.c -+++ b/drivers/gpu/drm/bridge/display-connector.c -@@ -13,6 +13,7 @@ - #include - #include - -+#include - #include - #include - -@@ -87,10 +88,95 @@ static struct edid *display_connector_get_edid(struct drm_bridge *bridge, - return drm_get_edid(connector, conn->bridge.ddc); - } - -+/* -+ * Since this bridge is tied to the connector, it acts like a passthrough, -+ * so concerning the output bus formats, either pass the bus formats from the -+ * previous bridge or return fallback data like done in the bridge function: -+ * drm_atomic_bridge_chain_select_bus_fmts(). -+ * This supports negotiation if the bridge chain has all bits in place. -+ */ -+static u32 *display_connector_get_output_bus_fmts(struct drm_bridge *bridge, -+ struct drm_bridge_state *bridge_state, -+ struct drm_crtc_state *crtc_state, -+ struct drm_connector_state *conn_state, -+ unsigned int *num_output_fmts) -+{ -+ struct drm_bridge *prev_bridge = drm_bridge_get_prev_bridge(bridge); -+ struct drm_bridge_state *prev_bridge_state; -+ -+ if (!prev_bridge || !prev_bridge->funcs->atomic_get_output_bus_fmts) { -+ struct drm_connector *conn = conn_state->connector; -+ u32 *out_bus_fmts; -+ -+ *num_output_fmts = 1; -+ out_bus_fmts = kmalloc(sizeof(*out_bus_fmts), GFP_KERNEL); -+ if (!out_bus_fmts) -+ return NULL; -+ -+ if (conn->display_info.num_bus_formats && -+ conn->display_info.bus_formats) -+ out_bus_fmts[0] = conn->display_info.bus_formats[0]; -+ else -+ out_bus_fmts[0] = MEDIA_BUS_FMT_FIXED; -+ -+ return out_bus_fmts; -+ } -+ -+ prev_bridge_state = drm_atomic_get_new_bridge_state(crtc_state->state, -+ prev_bridge); -+ -+ return prev_bridge->funcs->atomic_get_output_bus_fmts(prev_bridge, prev_bridge_state, -+ crtc_state, conn_state, -+ num_output_fmts); -+} -+ -+/* -+ * Since this bridge is tied to the connector, it acts like a passthrough, -+ * so concerning the input bus formats, either pass the bus formats from the -+ * previous bridge or MEDIA_BUS_FMT_FIXED (like select_bus_fmt_recursive()) -+ * when atomic_get_input_bus_fmts is not supported. -+ * This supports negotiation if the bridge chain has all bits in place. -+ */ -+static u32 *display_connector_get_input_bus_fmts(struct drm_bridge *bridge, -+ struct drm_bridge_state *bridge_state, -+ struct drm_crtc_state *crtc_state, -+ struct drm_connector_state *conn_state, -+ u32 output_fmt, -+ unsigned int *num_input_fmts) -+{ -+ struct drm_bridge *prev_bridge = drm_bridge_get_prev_bridge(bridge); -+ struct drm_bridge_state *prev_bridge_state; -+ -+ if (!prev_bridge || !prev_bridge->funcs->atomic_get_input_bus_fmts) { -+ u32 *in_bus_fmts; -+ -+ *num_input_fmts = 1; -+ in_bus_fmts = kmalloc(sizeof(*in_bus_fmts), GFP_KERNEL); -+ if (!in_bus_fmts) -+ return NULL; -+ -+ in_bus_fmts[0] = MEDIA_BUS_FMT_FIXED; -+ -+ return in_bus_fmts; -+ } -+ -+ prev_bridge_state = drm_atomic_get_new_bridge_state(crtc_state->state, -+ prev_bridge); -+ -+ return prev_bridge->funcs->atomic_get_input_bus_fmts(prev_bridge, prev_bridge_state, -+ crtc_state, conn_state, output_fmt, -+ num_input_fmts); -+} -+ - static const struct drm_bridge_funcs display_connector_bridge_funcs = { - .attach = display_connector_attach, - .detect = display_connector_detect, - .get_edid = display_connector_get_edid, -+ .atomic_get_output_bus_fmts = display_connector_get_output_bus_fmts, -+ .atomic_get_input_bus_fmts = display_connector_get_input_bus_fmts, -+ .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, - }; - - static irqreturn_t display_connector_hpd_irq(int irq, void *arg) diff --git a/drivers/gpu/drm/meson/Kconfig b/drivers/gpu/drm/meson/Kconfig index a4e1ed96e5e8..2023bc2b4dec 100644 --- a/drivers/gpu/drm/meson/Kconfig @@ -1448,7 +1339,7 @@ index 523fce45f16b..817a5270aee6 100644 obj-$(CONFIG_DRM_MESON_DW_HDMI) += meson_dw_hdmi.o +obj-$(CONFIG_DRM_MESON_TRANSWITCH_HDMI) += meson_transwitch_hdmi.o diff --git a/drivers/gpu/drm/meson/meson_drv.c b/drivers/gpu/drm/meson/meson_drv.c -index a56607501d36..0df139d8df8f 100644 +index 6e37de4fcb46..71d4cdc57d58 100644 --- a/drivers/gpu/drm/meson/meson_drv.c +++ b/drivers/gpu/drm/meson/meson_drv.c @@ -12,6 +12,7 @@ @@ -1827,9 +1718,9 @@ index a56607501d36..0df139d8df8f 100644 } if (count && !match) -@@ -520,6 +634,18 @@ static int meson_drv_probe(struct platform_device *pdev) +@@ -527,6 +641,18 @@ static int meson_drv_remove(struct platform_device *pdev) return 0; - }; + } +static struct meson_drm_match_data meson_drm_m8_data = { + .compat = VPU_COMPATIBLE_M8, @@ -1846,7 +1737,7 @@ index a56607501d36..0df139d8df8f 100644 static struct meson_drm_match_data meson_drm_gxbb_data = { .compat = VPU_COMPATIBLE_GXBB, }; -@@ -539,6 +665,12 @@ static struct meson_drm_match_data meson_drm_g12a_data = { +@@ -546,6 +672,12 @@ static struct meson_drm_match_data meson_drm_g12a_data = { }; static const struct of_device_id dt_match[] = { @@ -2342,7 +2233,7 @@ index a7692584487c..62c5cde59224 100644 pdev = of_find_device_by_node(remote); of_node_put(remote); diff --git a/drivers/gpu/drm/meson/meson_plane.c b/drivers/gpu/drm/meson/meson_plane.c -index 8640a8a8a469..456e2f421713 100644 +index 44aa52629443..c835e6d35568 100644 --- a/drivers/gpu/drm/meson/meson_plane.c +++ b/drivers/gpu/drm/meson/meson_plane.c @@ -199,8 +199,11 @@ static void meson_plane_atomic_update(struct drm_plane *plane, @@ -5091,37 +4982,10 @@ index f1747fde1fe0..000000000000 - return 0; -} diff --git a/drivers/gpu/drm/meson/meson_viu.c b/drivers/gpu/drm/meson/meson_viu.c -index bb7e109534de..406498ba2f79 100644 +index cd399b0b7181..bdfa342c4ca1 100644 --- a/drivers/gpu/drm/meson/meson_viu.c +++ b/drivers/gpu/drm/meson/meson_viu.c -@@ -436,10 +436,22 @@ void meson_viu_init(struct meson_drm *priv) - - /* Initialize OSD1 fifo control register */ - reg = VIU_OSD_DDR_PRIORITY_URGENT | -- VIU_OSD_HOLD_FIFO_LINES(31) | -- VIU_OSD_FIFO_DEPTH_VAL(32) | /* fifo_depth_val: 32*8=256 */ -- VIU_OSD_WORDS_PER_BURST(4) | /* 4 words in 1 burst */ -- VIU_OSD_FIFO_LIMITS(2); /* fifo_lim: 2*16=32 */ -+ VIU_OSD_FIFO_DEPTH_VAL(32) | /* fifo_depth_val: 32*8=256 */ -+ VIU_OSD_WORDS_PER_BURST(4) | /* 4 words in 1 burst */ -+ VIU_OSD_FIFO_LIMITS(2); /* fifo_lim: 2*16=32 */ -+ -+ /* -+ * When using AFBC on newer SoCs the AFBC encoder has to be reset. To -+ * leave time for that we need hold more lines to avoid glitches. -+ * On the 32-bit SoCs however we need to hold fewer lines because -+ * otherwise screen tearing can occur (for example in kmscube). -+ */ -+ if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_M8) || -+ meson_vpu_is_compatible(priv, VPU_COMPATIBLE_M8B) || -+ meson_vpu_is_compatible(priv, VPU_COMPATIBLE_M8M2)) -+ reg |= VIU_OSD_HOLD_FIFO_LINES(12); -+ else -+ reg |= VIU_OSD_HOLD_FIFO_LINES(31); - - if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_G12A)) - reg |= VIU_OSD_BURST_LENGTH_32; -@@ -449,13 +461,17 @@ void meson_viu_init(struct meson_drm *priv) +@@ -448,13 +448,17 @@ void meson_viu_init(struct meson_drm *priv) writel_relaxed(reg, priv->io_base + _REG(VIU_OSD1_FIFO_CTRL_STAT)); writel_relaxed(reg, priv->io_base + _REG(VIU_OSD2_FIFO_CTRL_STAT)); diff --git a/patch/kernel/archive/meson-6.1/0001-m8-m8b-m8m2-Support-HDMI.patch b/patch/kernel/archive/meson-6.1/0001-m8-m8b-m8m2-Support-HDMI.patch index 6276d6dce..d4a74968f 100644 --- a/patch/kernel/archive/meson-6.1/0001-m8-m8b-m8m2-Support-HDMI.patch +++ b/patch/kernel/archive/meson-6.1/0001-m8-m8b-m8m2-Support-HDMI.patch @@ -22,11 +22,11 @@ Special thank to Martin Blumenstingl. drivers/gpu/drm/meson/meson_transwitch_hdmi.h | 536 ++++++ drivers/gpu/drm/meson/meson_vclk.c | 146 ++ drivers/gpu/drm/meson/meson_venc.c | 44 +- - drivers/gpu/drm/meson/meson_viu.c | 38 +- + drivers/gpu/drm/meson/meson_viu.c | 18 +- drivers/phy/amlogic/Kconfig | 10 + drivers/phy/amlogic/Makefile | 1 + drivers/phy/amlogic/phy-meson-cvbs-dac.c | 375 ++++ - 21 files changed, 3593 insertions(+), 130 deletions(-) + 21 files changed, 3577 insertions(+), 126 deletions(-) create mode 100644 Documentation/devicetree/bindings/phy/amlogic,meson-cvbs-dac-phy.yaml create mode 100644 drivers/gpu/drm/meson/meson_transwitch_hdmi.c create mode 100644 drivers/gpu/drm/meson/meson_transwitch_hdmi.h @@ -1265,7 +1265,7 @@ index c62ee358456..fe0a8f8762f 100644 struct { bool osd1_enabled; diff --git a/drivers/gpu/drm/meson/meson_encoder_cvbs.c b/drivers/gpu/drm/meson/meson_encoder_cvbs.c -index 5675bc2a92c..3e40bd45c90 100644 +index 3f73b211fa8..833f701fe27 100644 --- a/drivers/gpu/drm/meson/meson_encoder_cvbs.c +++ b/drivers/gpu/drm/meson/meson_encoder_cvbs.c @@ -11,6 +11,7 @@ @@ -1318,7 +1318,7 @@ index 5675bc2a92c..3e40bd45c90 100644 static int meson_encoder_cvbs_get_modes(struct drm_bridge *bridge, struct drm_connector *connector) { -@@ -147,6 +159,7 @@ static void meson_encoder_cvbs_atomic_enable(struct drm_bridge *bridge, +@@ -148,6 +160,7 @@ static void meson_encoder_cvbs_atomic_enable(struct drm_bridge *bridge, struct drm_connector_state *conn_state; struct drm_crtc_state *crtc_state; struct drm_connector *connector; @@ -1326,7 +1326,7 @@ index 5675bc2a92c..3e40bd45c90 100644 connector = drm_atomic_get_new_connector_for_encoder(state, bridge->encoder); if (WARN_ON(!connector)) -@@ -176,16 +189,13 @@ static void meson_encoder_cvbs_atomic_enable(struct drm_bridge *bridge, +@@ -177,16 +190,13 @@ static void meson_encoder_cvbs_atomic_enable(struct drm_bridge *bridge, writel_bits_relaxed(VENC_VDAC_SEL_ATV_DMD, 0, priv->io_base + _REG(VENC_VDAC_DACSEL0)); @@ -1350,7 +1350,7 @@ index 5675bc2a92c..3e40bd45c90 100644 } } -@@ -195,19 +205,22 @@ static void meson_encoder_cvbs_atomic_disable(struct drm_bridge *bridge, +@@ -196,19 +206,22 @@ static void meson_encoder_cvbs_atomic_disable(struct drm_bridge *bridge, struct meson_encoder_cvbs *meson_encoder_cvbs = bridge_to_meson_encoder_cvbs(bridge); struct meson_drm *priv = meson_encoder_cvbs->priv; @@ -3959,37 +3959,10 @@ index 3c55ed00335..009882bda7b 100644 /* Disable HDMI */ writel_bits_relaxed(VPU_HDMI_ENCI_DATA_TO_HDMI | diff --git a/drivers/gpu/drm/meson/meson_viu.c b/drivers/gpu/drm/meson/meson_viu.c -index d4b907889a2..836dac22c8e 100644 +index cd399b0b718..bdfa342c4ca 100644 --- a/drivers/gpu/drm/meson/meson_viu.c +++ b/drivers/gpu/drm/meson/meson_viu.c -@@ -436,10 +436,22 @@ void meson_viu_init(struct meson_drm *priv) - - /* Initialize OSD1 fifo control register */ - reg = VIU_OSD_DDR_PRIORITY_URGENT | -- VIU_OSD_HOLD_FIFO_LINES(31) | -- VIU_OSD_FIFO_DEPTH_VAL(32) | /* fifo_depth_val: 32*8=256 */ -- VIU_OSD_WORDS_PER_BURST(4) | /* 4 words in 1 burst */ -- VIU_OSD_FIFO_LIMITS(2); /* fifo_lim: 2*16=32 */ -+ VIU_OSD_FIFO_DEPTH_VAL(32) | /* fifo_depth_val: 32*8=256 */ -+ VIU_OSD_WORDS_PER_BURST(4) | /* 4 words in 1 burst */ -+ VIU_OSD_FIFO_LIMITS(2); /* fifo_lim: 2*16=32 */ -+ -+ /* -+ * When using AFBC on newer SoCs the AFBC encoder has to be reset. To -+ * leave time for that we need hold more lines to avoid glitches. -+ * On the 32-bit SoCs however we need to hold fewer lines because -+ * otherwise screen tearing can occur (for example in kmscube). -+ */ -+ if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_M8) || -+ meson_vpu_is_compatible(priv, VPU_COMPATIBLE_M8B) || -+ meson_vpu_is_compatible(priv, VPU_COMPATIBLE_M8M2)) -+ reg |= VIU_OSD_HOLD_FIFO_LINES(12); -+ else -+ reg |= VIU_OSD_HOLD_FIFO_LINES(31); - - if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_G12A)) - reg |= VIU_OSD_BURST_LENGTH_32; -@@ -449,13 +461,17 @@ void meson_viu_init(struct meson_drm *priv) +@@ -448,13 +448,17 @@ void meson_viu_init(struct meson_drm *priv) writel_relaxed(reg, priv->io_base + _REG(VIU_OSD1_FIFO_CTRL_STAT)); writel_relaxed(reg, priv->io_base + _REG(VIU_OSD2_FIFO_CTRL_STAT));